(self["webpackChunkremotion_video_skill"] = self["webpackChunkremotion_video_skill"] || []).push([[517],{

/***/ 3638
(__unused_webpack_module, exports) {

"use strict";

/**
 * Inlined from https://github.com/Jam3/audiobuffer-to-wav/commit/2272eb09bd46a05e50a6d684d908aa6f13c58f63#diff-e727e4bdf3657fd1d798edcd6b099d6e092f8573cba266154583a746bba0f346
 */
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.audioBufferToWav = audioBufferToWav;
function interleave(inputL, inputR) {
    const length = inputL.length + inputR.length;
    const result = new Float32Array(length);
    let index = 0;
    let inputIndex = 0;
    while (index < length) {
        result[index++] = inputL[inputIndex];
        result[index++] = inputR[inputIndex];
        inputIndex++;
    }
    return result;
}
function writeFloat32(output, offset, input) {
    for (let i = 0; i < input.length; i++, offset += 4) {
        output.setFloat32(offset, input[i], true);
    }
}
function floatTo16BitPCM(output, offset, input) {
    for (let i = 0; i < input.length; i++, offset += 2) {
        const s = Math.max(-1, Math.min(1, input[i]));
        output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7fff, true);
    }
}
function writeString(view, offset, string) {
    for (let i = 0; i < string.length; i++) {
        view.setUint8(offset + i, string.charCodeAt(i));
    }
}
function encodeWAV({ samples, format, sampleRate, numChannels, bitDepth, }) {
    const bytesPerSample = bitDepth / 8;
    const blockAlign = numChannels * bytesPerSample;
    const buffer = new ArrayBuffer(44 + samples.length * bytesPerSample);
    const view = new DataView(buffer);
    /* RIFF identifier */
    writeString(view, 0, 'RIFF');
    /* RIFF chunk length */
    view.setUint32(4, 36 + samples.length * bytesPerSample, true);
    /* RIFF type */
    writeString(view, 8, 'WAVE');
    /* format chunk identifier */
    writeString(view, 12, 'fmt ');
    /* format chunk length */
    view.setUint32(16, 16, true);
    /* sample format (raw) */
    view.setUint16(20, format, true);
    /* channel count */
    view.setUint16(22, numChannels, true);
    /* sample rate */
    view.setUint32(24, sampleRate, true);
    /* byte rate (sample rate * block align) */
    view.setUint32(28, sampleRate * blockAlign, true);
    /* block align (channel count * bytes per sample) */
    view.setUint16(32, blockAlign, true);
    /* bits per sample */
    view.setUint16(34, bitDepth, true);
    /* data chunk identifier */
    writeString(view, 36, 'data');
    /* data chunk length */
    view.setUint32(40, samples.length * bytesPerSample, true);
    if (format === 1) {
        // Raw PCM
        floatTo16BitPCM(view, 44, samples);
    }
    else {
        writeFloat32(view, 44, samples);
    }
    return buffer;
}
function audioBufferToWav(buffer, opt) {
    const numChannels = buffer.numberOfChannels;
    const { sampleRate } = buffer;
    const format = opt.float32 ? 3 : 1;
    const bitDepth = format === 3 ? 32 : 16;
    let result;
    if (numChannels === 2) {
        result = interleave(buffer.getChannelData(0), buffer.getChannelData(1));
    }
    else {
        result = buffer.getChannelData(0);
    }
    return encodeWAV({
        samples: result,
        format,
        sampleRate,
        numChannels,
        bitDepth,
    });
}


/***/ },

/***/ 7996
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.audioBufferToDataUrl = void 0;
const audio_buffer_to_wav_1 = __webpack_require__(3638);
/*
 * @description Takes an AudioBuffer instance and converts it to a Base 64 Data URL so it can be passed to an <Html5Audio /> tag.
 * @see [Documentation](https://remotion.dev/docs/audio-buffer-to-data-url)
 */
const audioBufferToDataUrl = (buffer) => {
    const wavAsArrayBuffer = (0, audio_buffer_to_wav_1.audioBufferToWav)(buffer, {
        float32: true,
    });
    let binary = '';
    const bytes = new Uint8Array(wavAsArrayBuffer);
    const len = bytes.byteLength;
    for (let i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i]);
    }
    return 'data:audio/wav;base64,' + window.btoa(binary);
};
exports.audioBufferToDataUrl = audioBufferToDataUrl;


/***/ },

/***/ 1546
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.combineFloat32Arrays = void 0;
const combineFloat32Arrays = (arrays) => {
    if (arrays.length === 0) {
        return new Float32Array([]);
    }
    if (arrays.length === 1) {
        return arrays[0];
    }
    let totalLength = 0;
    for (const array of arrays) {
        totalLength += array.length;
    }
    const result = new Float32Array(totalLength);
    let offset = 0;
    for (const array of arrays) {
        result.set(array, offset);
        offset += array.length;
    }
    return result;
};
exports.combineFloat32Arrays = combineFloat32Arrays;


/***/ },

/***/ 9144
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.createSmoothSvgPath = void 0;
const line = (pointA, pointB) => {
    const lengthX = pointB.x - pointA.x;
    const lengthY = pointB.y - pointA.y;
    return {
        length: Math.sqrt(lengthX ** 2 + lengthY ** 2),
        angle: Math.atan2(lengthY, lengthX),
    };
};
const controlPoint = ({ current, previous, next, reverse, }) => {
    const p = previous || current;
    const n = next || current;
    // The smoothing ratio
    const smoothing = 0.2;
    // Properties of the opposed-line
    const o = line(p, n);
    const angle = o.angle + (reverse ? Math.PI : 0);
    const length = o.length * smoothing;
    const x = current.x + Math.cos(angle) * length;
    const y = current.y + Math.sin(angle) * length;
    return { x, y };
};
const createSmoothSvgPath = ({ points }) => {
    return points.reduce((acc, current, i, a) => {
        if (i === 0) {
            return `M ${current.x},${current.y}`;
        }
        const { x, y } = current;
        const previous = a[i - 1];
        const twoPrevious = a[i - 2];
        const next = a[i + 1];
        const { x: cp1x, y: cp1y } = controlPoint({
            current: previous,
            previous: twoPrevious,
            next: current,
            reverse: false,
        });
        const { x: cp2x, y: cp2y } = controlPoint({
            current,
            previous,
            next,
            reverse: true,
        });
        return `${acc} C ${cp1x},${cp1y} ${cp2x},${cp2y} ${x},${y}`;
    }, '');
};
exports.createSmoothSvgPath = createSmoothSvgPath;


/***/ },

/***/ 5633
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.fetchWithCorsCatch = void 0;
const fetchWithCorsCatch = async (src, init) => {
    try {
        const response = await fetch(src, {
            mode: 'cors',
            referrerPolicy: 'no-referrer-when-downgrade',
            ...init,
        });
        return response;
    }
    catch (err) {
        const error = err;
        if (
        // Chrome
        error.message.includes('Failed to fetch') ||
            // Safari
            error.message.includes('Load failed') ||
            // Firefox
            error.message.includes('NetworkError when attempting to fetch resource')) {
            throw new TypeError(`Failed to read from ${src}: ${error.message}. Does the resource support CORS?`);
        }
        throw err;
    }
};
exports.fetchWithCorsCatch = fetchWithCorsCatch;


/***/ },

/***/ 1603
(__unused_webpack_module, exports) {

"use strict";

// Adapted from node-fft project by Joshua Wong and Ben Bryan
// https://github.com/vail-systems/node-fft
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.complexMagnitude = exports.complexMultiply = exports.complexSubtract = exports.complexAdd = void 0;
const complexAdd = function (a, b) {
    return [a[0] + b[0], a[1] + b[1]];
};
exports.complexAdd = complexAdd;
const complexSubtract = function (a, b) {
    return [a[0] - b[0], a[1] - b[1]];
};
exports.complexSubtract = complexSubtract;
const complexMultiply = function (a, b) {
    return [a[0] * b[0] - a[1] * b[1], a[0] * b[1] + a[1] * b[0]];
};
exports.complexMultiply = complexMultiply;
const complexMagnitude = function (c) {
    return Math.sqrt(c[0] * c[0] + c[1] * c[1]);
};
exports.complexMagnitude = complexMagnitude;


/***/ },

/***/ 5372
(__unused_webpack_module, exports) {

"use strict";

// Adapted from node-fft project by Joshua Wong and Ben Bryan
// https://github.com/vail-systems/node-fft
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.exponent = void 0;
const mapExponent = {};
const exponent = function (k, N) {
    const x = -2 * Math.PI * (k / N);
    mapExponent[N] = mapExponent[N] || {};
    mapExponent[N][k] = mapExponent[N][k] || [Math.cos(x), Math.sin(x)]; // [Real, Imaginary]
    return mapExponent[N][k];
};
exports.exponent = exponent;


/***/ },

/***/ 4750
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

// Adapted from node-fft project by Joshua Wong and Ben Bryan
// https://github.com/vail-systems/node-fft
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.fftAccurate = void 0;
const complex_1 = __webpack_require__(1603);
const exponent_1 = __webpack_require__(5372);
const fftAccurate = function (vector) {
    const X = [];
    const N = vector.length;
    // Base case is X = x + 0i since our input is assumed to be real only.
    if (N === 1) {
        if (Array.isArray(vector[0])) {
            // If input vector contains complex numbers
            return [[vector[0][0], vector[0][1]]];
        }
        return [[vector[0], 0]];
    }
    // Recurse: all even samples
    const X_evens = (0, exports.fftAccurate)(vector.filter((_, ix) => ix % 2 === 0));
    // Recurse: all odd samples
    const X_odds = (0, exports.fftAccurate)(vector.filter((__, ix) => ix % 2 === 1));
    // Now, perform N/2 operations!
    for (let k = 0; k < N / 2; k++) {
        // t is a complex number!
        const t = X_evens[k];
        const e = (0, complex_1.complexMultiply)((0, exponent_1.exponent)(k, N), X_odds[k]);
        X[k] = (0, complex_1.complexAdd)(t, e);
        X[k + N / 2] = (0, complex_1.complexSubtract)(t, e);
    }
    return X;
};
exports.fftAccurate = fftAccurate;


/***/ },

/***/ 5226
(__unused_webpack_module, exports) {

"use strict";

// https://pastebin.com/raw/D42RbPe5
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.fftFast = void 0;
// Function to reverse bits in an integer
function reverseBits(num, numBits) {
    let result = 0;
    for (let i = 0; i < numBits; i++) {
        result = (result << 1) | ((num >> i) & 1);
    }
    return result;
}
// Hamming window function
function hammingWindow(N) {
    const win = new Array(N);
    for (let i = 0; i < N; i++) {
        win[i] = 0.8 - 0.46 * Math.cos((2 * Math.PI * i) / (N - 1));
    }
    return win;
}
// Function to calculate the bit-reversed permutation indices
function bitReversePermutation(N) {
    const bitReversed = new Array(N);
    for (let i = 0; i < N; i++) {
        bitReversed[i] = reverseBits(i, Math.log2(N));
    }
    return bitReversed;
}
const fftFast = function (vector) {
    const N = vector.length;
    const X = new Array(N);
    if (N <= 1) {
        for (let i = 0; i < vector.length; i++) {
            const value = vector[i];
            X[i] = [value * 2, 0];
        }
        return X;
    }
    // Apply a windowing function to the input data
    const window = hammingWindow(N); // You can choose a different window function if needed
    for (let i = 0; i < N; i++) {
        X[i] = [vector[i] * window[i], 0];
    }
    // Bit-Reversal Permutation
    const bitReversed = bitReversePermutation(N);
    for (let i = 0; i < N; i++) {
        X[i] = [vector[bitReversed[i]], 0];
    }
    // Cooley-Tukey FFT
    for (let s = 1; s <= Math.log2(N); s++) {
        const m = 1 << s; // Number of elements in each subarray
        const mHalf = m / 2; // Half the number of elements in each subarray
        const angleIncrement = (2 * Math.PI) / m;
        for (let k = 0; k < N; k += m) {
            let omegaReal = 1.0;
            let omegaImag = 0.0;
            for (let j = 0; j < mHalf; j++) {
                const tReal = omegaReal * X[k + j + mHalf][0] - omegaImag * X[k + j + mHalf][1];
                const tImag = omegaReal * X[k + j + mHalf][1] + omegaImag * X[k + j + mHalf][0];
                const uReal = X[k + j][0];
                const uImag = X[k + j][1];
                X[k + j] = [uReal + tReal, uImag + tImag];
                X[k + j + mHalf] = [uReal - tReal, uImag - tImag];
                // Twiddle factor update
                const tempReal = omegaReal * Math.cos(angleIncrement) -
                    omegaImag * Math.sin(angleIncrement);
                omegaImag =
                    omegaReal * Math.sin(angleIncrement) +
                        omegaImag * Math.cos(angleIncrement);
                omegaReal = tempReal;
            }
        }
    }
    return X;
};
exports.fftFast = fftFast;


/***/ },

/***/ 9894
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

// Adapted from node-fft project by Joshua Wong and Ben Bryan
// https://github.com/vail-systems/node-fft
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getVisualization = void 0;
const fft_accurate_1 = __webpack_require__(4750);
const fft_fast_1 = __webpack_require__(5226);
const mag_1 = __webpack_require__(8764);
const smoothing_1 = __webpack_require__(7557);
const to_int_16_1 = __webpack_require__(1868);
const getVisualization = ({ sampleSize, data, sampleRate, frame, fps, maxInt, optimizeFor, dataOffsetInSeconds, }) => {
    const isPowerOfTwo = sampleSize > 0 && (sampleSize & (sampleSize - 1)) === 0;
    if (!isPowerOfTwo) {
        throw new TypeError(`The argument "bars" must be a power of two. For example: 64, 128. Got instead: ${sampleSize}`);
    }
    if (!fps) {
        throw new TypeError('The argument "fps" was not provided');
    }
    if (data.length < sampleSize) {
        throw new TypeError('Audio data is not big enough to provide ' + sampleSize + ' bars.');
    }
    const start = Math.floor((frame / fps - dataOffsetInSeconds) * sampleRate);
    const actualStart = Math.max(0, start - sampleSize / 2);
    const ints = new Int16Array({
        length: sampleSize,
    });
    ints.set(data.subarray(actualStart, actualStart + sampleSize).map((x) => (0, to_int_16_1.toInt16)(x)));
    const alg = optimizeFor === 'accuracy' ? fft_accurate_1.fftAccurate : fft_fast_1.fftFast;
    const phasors = alg(ints);
    const magnitudes = (0, mag_1.fftMag)(phasors).map((p) => p);
    return (0, smoothing_1.smoothen)(magnitudes).map((m) => m / (sampleSize / 2) / maxInt);
};
exports.getVisualization = getVisualization;


/***/ },

/***/ 8764
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

// Adapted from node-fft project by Joshua Wong and Ben Bryan
// https://github.com/vail-systems/node-fft
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.fftMag = void 0;
const complex_1 = __webpack_require__(1603);
const fftMag = function (fftBins) {
    const ret = fftBins.map((f) => (0, complex_1.complexMagnitude)(f));
    return ret.slice(0, ret.length / 2);
};
exports.fftMag = fftMag;


/***/ },

/***/ 2268
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

// Adapted from node-fft project by Joshua Wong and Ben Bryan
// https://github.com/vail-systems/node-fft
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getMaxPossibleMagnitude = void 0;
const to_int_16_1 = __webpack_require__(1868);
const getMax = (array) => {
    let max = 0;
    for (let i = 0; i < array.length; i++) {
        const val = array[i];
        if (val > max) {
            max = val;
        }
    }
    return max;
};
const cache = {};
const getMaxPossibleMagnitude = (metadata) => {
    if (cache[metadata.resultId]) {
        return cache[metadata.resultId];
    }
    const result = (0, to_int_16_1.toInt16)(getMax(metadata.channelWaveforms[0]));
    cache[metadata.resultId] = result;
    return result;
};
exports.getMaxPossibleMagnitude = getMaxPossibleMagnitude;


/***/ },

/***/ 7557
(__unused_webpack_module, exports) {

"use strict";

// Adapted from node-fft project by Joshua Wong and Ben Bryan
// https://github.com/vail-systems/node-fft
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.smoothen = void 0;
const smoothingPasses = 3;
const smoothingPoints = 3;
const smoothen = function (array) {
    let lastArray = array;
    const newArr = [];
    for (let pass = 0; pass < smoothingPasses; pass++) {
        const sidePoints = Math.floor(smoothingPoints / 2); // our window is centered so this is both nL and nR
        const cn = 1 / (2 * sidePoints + 1); // constant
        for (let i = 0; i < sidePoints; i++) {
            newArr[i] = lastArray[i];
            newArr[lastArray.length - i - 1] = lastArray[lastArray.length - i - 1];
        }
        for (let i = sidePoints; i < lastArray.length - sidePoints; i++) {
            let sum = 0;
            for (let n = -sidePoints; n <= sidePoints; n++) {
                sum += cn * lastArray[i + n] + n;
            }
            newArr[i] = sum;
        }
        lastArray = newArr;
    }
    return newArr;
};
exports.smoothen = smoothen;


/***/ },

/***/ 1868
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.toInt16 = void 0;
const toInt16 = (x) => (x > 0 ? x * 0x7fff : x * 0x8000);
exports.toInt16 = toInt16;


/***/ },

/***/ 5576
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getAudioData = void 0;
const fetch_with_cors_catch_1 = __webpack_require__(5633);
const is_remote_asset_1 = __webpack_require__(5448);
const p_limit_1 = __webpack_require__(1082);
const metadataCache = {};
const limit = (0, p_limit_1.pLimit)(3);
const fn = async (src, options) => {
    var _a;
    if (metadataCache[src]) {
        return metadataCache[src];
    }
    if (typeof document === 'undefined') {
        throw new Error('getAudioData() is only available in the browser.');
    }
    const audioContext = new AudioContext({
        sampleRate: (_a = options === null || options === void 0 ? void 0 : options.sampleRate) !== null && _a !== void 0 ? _a : 48000,
    });
    const response = await (0, fetch_with_cors_catch_1.fetchWithCorsCatch)(src);
    if (!response.ok) {
        throw new Error(`Failed to fetch audio data from ${src}: ${response.status} ${response.statusText}`);
    }
    const arrayBuffer = await response.arrayBuffer();
    const wave = await audioContext.decodeAudioData(arrayBuffer);
    const channelWaveforms = new Array(wave.numberOfChannels)
        .fill(true)
        .map((_, channel) => {
        return wave.getChannelData(channel);
    });
    const metadata = {
        channelWaveforms,
        sampleRate: wave.sampleRate,
        durationInSeconds: wave.duration,
        numberOfChannels: wave.numberOfChannels,
        resultId: String(Math.random()),
        isRemote: (0, is_remote_asset_1.isRemoteAsset)(src),
    };
    metadataCache[src] = metadata;
    return metadata;
};
/*
 * @description Takes an audio or video src, loads it and returns data and metadata for the specified source.
 * @see [Documentation](https://remotion.dev/docs/get-audio-data)
 */
const getAudioData = (src, options) => {
    return limit(fn, src, options);
};
exports.getAudioData = getAudioData;


/***/ },

/***/ 7970
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getAudioDuration = exports.getAudioDurationInSeconds = void 0;
/* eslint-disable @typescript-eslint/no-use-before-define */
const media_tag_error_handling_1 = __webpack_require__(4970);
const p_limit_1 = __webpack_require__(1082);
const limit = (0, p_limit_1.pLimit)(3);
const metadataCache = {};
const fn = (src) => {
    if (metadataCache[src]) {
        return Promise.resolve(metadataCache[src]);
    }
    if (typeof document === 'undefined') {
        throw new Error('getAudioDuration() is only available in the browser.');
    }
    const audio = document.createElement('audio');
    audio.src = src;
    return new Promise((resolve, reject) => {
        const onError = () => {
            (0, media_tag_error_handling_1.onMediaError)({
                error: audio.error,
                src,
                cleanup,
                reject,
                api: 'getAudioDurationInSeconds()',
            });
        };
        const onLoadedMetadata = () => {
            metadataCache[src] = audio.duration;
            resolve(audio.duration);
            cleanup();
        };
        const cleanup = () => {
            audio.removeEventListener('loadedmetadata', onLoadedMetadata);
            audio.removeEventListener('error', onError);
            audio.remove();
        };
        audio.addEventListener('loadedmetadata', onLoadedMetadata, { once: true });
        audio.addEventListener('error', onError, { once: true });
    });
};
/**
 * @description Gets the duration in seconds of an audio source by creating an invisible `<audio>` tag, loading the audio, and returning the duration.
 * @see [Documentation](https://remotion.dev/docs/get-audio-duration-in-seconds)
 * @deprecated Use `parseMedia()` instead: https://www.remotion.dev/docs/media-parser/parse-media
 */
const getAudioDurationInSeconds = (src) => {
    return limit(fn, src);
};
exports.getAudioDurationInSeconds = getAudioDurationInSeconds;
/**
 * @deprecated Renamed to `getAudioDurationInSeconds`
 */
const getAudioDuration = (src) => (0, exports.getAudioDurationInSeconds)(src);
exports.getAudioDuration = getAudioDuration;


/***/ },

/***/ 9196
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getImageDimensions = getImageDimensions;
const p_limit_1 = __webpack_require__(1082);
const imageDimensionsCache = {};
const limit = (0, p_limit_1.pLimit)(3);
const fn = async (src) => {
    if (imageDimensionsCache[src]) {
        return imageDimensionsCache[src];
    }
    if (typeof document === 'undefined') {
        throw new Error('getImageDimensions() is only available in the browser.');
    }
    const imageDimensions = await new Promise((resolved, reject) => {
        const image = new Image();
        image.onload = () => {
            const { width, height } = image;
            resolved({ width, height });
        };
        image.onerror = reject;
        image.src = src;
    });
    imageDimensionsCache[src] = imageDimensions;
    return imageDimensions;
};
/*
 * @description Takes an image src, retrieves the dimensions of an image.
 * @see [Documentation](https://remotion.dev/docs/get-image-dimensions)
 */
function getImageDimensions(src) {
    return limit(fn, src);
}


/***/ },

/***/ 5624
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getPartialAudioData = void 0;
const mediabunny_1 = __webpack_require__(3742);
// Audio frames might have dependencies on previous and next frames so we need to decode a bit more and then discard it.
// The worst case seems to be FLAC files with a 65'535 sample window, which would be 1486.0ms at 44.1Khz.
// So let's set a threshold of 1.5 seconds.
const EXTRA_THRESHOLD_IN_SECONDS = 1.5;
const getPartialAudioData = async ({ track, fromSeconds, toSeconds, channelIndex, signal, isMatroska = false, }) => {
    if (signal.aborted) {
        throw new Error('Operation was aborted');
    }
    const audioSamples = [];
    // matroska must be decoded from the start due to limitation
    // https://www.remotion.dev/docs/media/support#matroska-limitation
    // Also request extra data beforehand to handle audio frame dependencies
    const actualFromSeconds = isMatroska
        ? 0
        : Math.max(0, fromSeconds - EXTRA_THRESHOLD_IN_SECONDS);
    // mediabunny docs: constructing the sink is virtually free and does not perform any media data reads.
    const sink = new mediabunny_1.AudioBufferSink(track);
    const iterator = sink.buffers(actualFromSeconds, toSeconds);
    for await (const { buffer, timestamp, duration } of iterator) {
        if (signal.aborted) {
            break;
        }
        const channelData = buffer.getChannelData(channelIndex);
        const bufferStartSeconds = timestamp;
        const bufferEndSeconds = timestamp + duration;
        const overlapStartSecond = Math.max(bufferStartSeconds, fromSeconds);
        const overlapEndSecond = Math.min(bufferEndSeconds, toSeconds);
        if (overlapStartSecond >= overlapEndSecond) {
            continue;
        }
        const startSampleInBuffer = Math.floor((overlapStartSecond - bufferStartSeconds) * buffer.sampleRate);
        const endSampleInBuffer = Math.ceil((overlapEndSecond - bufferStartSeconds) * buffer.sampleRate);
        const trimmedData = channelData.slice(startSampleInBuffer, endSampleInBuffer);
        audioSamples.push(trimmedData);
    }
    await iterator.return();
    const totalSamples = audioSamples.reduce((sum, sample) => sum + sample.length, 0);
    const result = new Float32Array(totalSamples);
    let offset = 0;
    for (const audioSample of audioSamples) {
        result.set(audioSample, offset);
        offset += audioSample.length;
    }
    return result;
};
exports.getPartialAudioData = getPartialAudioData;


/***/ },

/***/ 1994
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getVideoMetadata = void 0;
/* eslint-disable @typescript-eslint/no-use-before-define */
const is_remote_asset_1 = __webpack_require__(5448);
const media_tag_error_handling_1 = __webpack_require__(4970);
const p_limit_1 = __webpack_require__(1082);
const cache = {};
const limit = (0, p_limit_1.pLimit)(3);
const fn = (src) => {
    if (cache[src]) {
        return Promise.resolve(cache[src]);
    }
    if (typeof document === 'undefined') {
        throw new Error('getVideoMetadata() is only available in the browser.');
    }
    const video = document.createElement('video');
    video.src = src;
    return new Promise((resolve, reject) => {
        const onError = () => {
            (0, media_tag_error_handling_1.onMediaError)({
                error: video.error,
                src,
                cleanup,
                reject,
                api: 'getVideoMetadata()',
            });
        };
        const onLoadedMetadata = () => {
            const pixels = video.videoHeight * video.videoWidth;
            if (pixels === 0) {
                reject(new Error(`Unable to determine video metadata for ${src}`));
                return;
            }
            if (!Number.isFinite(video.duration)) {
                reject(new Error(`Unable to determine video duration for ${src} - got Infinity. Re-encoding this video may fix this issue.`));
                return;
            }
            const metadata = {
                durationInSeconds: video.duration,
                width: video.videoWidth,
                height: video.videoHeight,
                aspectRatio: video.videoWidth / video.videoHeight,
                isRemote: (0, is_remote_asset_1.isRemoteAsset)(src),
            };
            resolve(metadata);
            cache[src] = metadata;
            cleanup();
        };
        const cleanup = () => {
            video.removeEventListener('loadedmetadata', onLoadedMetadata);
            video.removeEventListener('error', onError);
            video.remove();
        };
        video.addEventListener('loadedmetadata', onLoadedMetadata, { once: true });
        video.addEventListener('error', onError, { once: true });
    });
};
/**
 * @description Takes a src to a video, loads it and returns metadata for the specified source.
 * @see [Documentation](https://remotion.dev/docs/get-video-metadata)
 * @deprecated Use `parseMedia()` instead: https://www.remotion.dev/docs/miscellaneous/parse-media-vs-get-video-metadata
 */
const getVideoMetadata = (src) => {
    return limit(fn, src);
};
exports.getVideoMetadata = getVideoMetadata;


/***/ },

/***/ 7761
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getWaveformSamples = void 0;
const normalize_data_1 = __webpack_require__(5332);
const getWaveformSamples = ({ audioBuffer, numberOfSamples, outputRange, normalize, }) => {
    const blockSize = Math.floor(audioBuffer.length / numberOfSamples); // the number of samples in each subdivision
    if (blockSize === 0) {
        return [];
    }
    const filteredData = [];
    for (let i = 0; i < numberOfSamples; i++) {
        const blockStart = blockSize * i; // the location of the first sample in the block
        let sum = 0;
        for (let j = 0; j < blockSize; j++) {
            sum += Math.abs(audioBuffer[blockStart + j]); // find the sum of all the samples in the block
        }
        filteredData.push(sum / blockSize); // divide the sum by the block size to get the average
    }
    if (normalize) {
        if (outputRange === 'minus-one-to-one') {
            return (0, normalize_data_1.normalizeData)(filteredData).map((n, i) => {
                if (i % 2 === 0) {
                    return n * -1;
                }
                return n;
            });
        }
        return (0, normalize_data_1.normalizeData)(filteredData);
    }
    if (outputRange === 'minus-one-to-one') {
        return filteredData.map((n, i) => {
            if (i % 2 === 0) {
                return n * -1;
            }
            return n;
        });
    }
    return filteredData;
};
exports.getWaveformSamples = getWaveformSamples;


/***/ },

/***/ 1235
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getWaveformPortion = void 0;
const no_react_1 = __webpack_require__(9382);
const get_wave_form_samples_1 = __webpack_require__(7761);
const validate_channel_1 = __webpack_require__(6746);
const concatArrays = (arrays) => {
    // sum of individual array lengths
    const totalLength = arrays.reduce((acc, value) => acc + value.length, 0);
    const result = new Float32Array(totalLength);
    // for each array - copy it over result
    // next array is copied right after the previous one
    let length = 0;
    for (const array of arrays) {
        result.set(array, length);
        length += array.length;
    }
    return result;
};
/*
 * @description Takes bulky waveform data (for example fetched by getAudioData()) and returns a trimmed and simplified version of it, for simpler visualization
 * @see [Documentation](https://remotion.dev/docs/get-waveform-portion)
 */
const getWaveformPortion = ({ audioData, startTimeInSeconds, durationInSeconds, numberOfSamples, channel = 0, outputRange = 'zero-to-one', dataOffsetInSeconds, normalize = true, }) => {
    (0, validate_channel_1.validateChannel)(channel, audioData.numberOfChannels);
    const waveform = audioData.channelWaveforms[channel];
    const startSample = Math.floor((startTimeInSeconds - (dataOffsetInSeconds !== null && dataOffsetInSeconds !== void 0 ? dataOffsetInSeconds : 0)) * audioData.sampleRate);
    const endSample = Math.floor((startTimeInSeconds - (dataOffsetInSeconds !== null && dataOffsetInSeconds !== void 0 ? dataOffsetInSeconds : 0) + durationInSeconds) *
        audioData.sampleRate);
    const samplesBeforeStart = 0 - startSample;
    const samplesAfterEnd = endSample - waveform.length;
    const clampedStart = Math.max(startSample, 0);
    const clampedEnd = Math.min(waveform.length, endSample);
    const padStart = samplesBeforeStart > 0
        ? new Float32Array(samplesBeforeStart).fill(0)
        : null;
    const padEnd = samplesAfterEnd > 0 ? new Float32Array(samplesAfterEnd).fill(0) : null;
    const arrs = [
        padStart,
        waveform.slice(clampedStart, clampedEnd),
        padEnd,
    ].filter(no_react_1.NoReactInternals.truthy);
    const audioBuffer = arrs.length === 1 ? arrs[0] : concatArrays(arrs);
    return (0, get_wave_form_samples_1.getWaveformSamples)({
        audioBuffer,
        numberOfSamples,
        outputRange,
        normalize,
    }).map((w, i) => {
        return {
            index: i,
            amplitude: w,
        };
    });
};
exports.getWaveformPortion = getWaveformPortion;


/***/ },

/***/ 6996
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.visualizeAudioWaveform = exports.visualizeAudio = exports.useWindowedAudioData = exports.useAudioData = exports.getWaveformPortion = exports.getVideoMetadata = exports.getImageDimensions = exports.getAudioDurationInSeconds = exports.getAudioDuration = exports.getAudioData = exports.createSmoothSvgPath = exports.audioBufferToDataUrl = void 0;
const audio_url_helpers_1 = __webpack_require__(7996);
Object.defineProperty(exports, "audioBufferToDataUrl", ({ enumerable: true, get: function () { return audio_url_helpers_1.audioBufferToDataUrl; } }));
const create_smooth_svg_path_1 = __webpack_require__(9144);
Object.defineProperty(exports, "createSmoothSvgPath", ({ enumerable: true, get: function () { return create_smooth_svg_path_1.createSmoothSvgPath; } }));
const get_audio_data_1 = __webpack_require__(5576);
Object.defineProperty(exports, "getAudioData", ({ enumerable: true, get: function () { return get_audio_data_1.getAudioData; } }));
const get_audio_duration_in_seconds_1 = __webpack_require__(7970);
Object.defineProperty(exports, "getAudioDuration", ({ enumerable: true, get: function () { return get_audio_duration_in_seconds_1.getAudioDuration; } }));
Object.defineProperty(exports, "getAudioDurationInSeconds", ({ enumerable: true, get: function () { return get_audio_duration_in_seconds_1.getAudioDurationInSeconds; } }));
const get_image_dimensions_1 = __webpack_require__(9196);
Object.defineProperty(exports, "getImageDimensions", ({ enumerable: true, get: function () { return get_image_dimensions_1.getImageDimensions; } }));
const get_video_metadata_1 = __webpack_require__(1994);
Object.defineProperty(exports, "getVideoMetadata", ({ enumerable: true, get: function () { return get_video_metadata_1.getVideoMetadata; } }));
const get_waveform_portion_1 = __webpack_require__(1235);
Object.defineProperty(exports, "getWaveformPortion", ({ enumerable: true, get: function () { return get_waveform_portion_1.getWaveformPortion; } }));
__exportStar(__webpack_require__(5169), exports);
const use_audio_data_1 = __webpack_require__(205);
Object.defineProperty(exports, "useAudioData", ({ enumerable: true, get: function () { return use_audio_data_1.useAudioData; } }));
const use_windowed_audio_data_1 = __webpack_require__(1447);
Object.defineProperty(exports, "useWindowedAudioData", ({ enumerable: true, get: function () { return use_windowed_audio_data_1.useWindowedAudioData; } }));
const visualize_audio_1 = __webpack_require__(8717);
Object.defineProperty(exports, "visualizeAudio", ({ enumerable: true, get: function () { return visualize_audio_1.visualizeAudio; } }));
const visualize_audio_waveform_1 = __webpack_require__(4853);
Object.defineProperty(exports, "visualizeAudioWaveform", ({ enumerable: true, get: function () { return visualize_audio_waveform_1.visualizeAudioWaveform; } }));


/***/ },

/***/ 5448
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.isRemoteAsset = void 0;
const isRemoteAsset = (asset) => !asset.startsWith(window.origin) && !asset.startsWith('data');
exports.isRemoteAsset = isRemoteAsset;


/***/ },

/***/ 4970
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.onMediaError = void 0;
async function fetchWithTimeout(url, options, timeout = 3000) {
    const controller = new AbortController();
    const id = setTimeout(() => controller.abort(), timeout);
    options.signal = controller.signal;
    try {
        const response = await fetch(url, options);
        clearTimeout(id);
        return response;
    }
    catch (_a) {
        clearTimeout(id);
        throw new Error(`Fetch timed out after ${timeout}ms`);
    }
}
const checkFor404 = (src) => {
    return fetchWithTimeout(src, {
        method: 'HEAD',
        mode: 'no-cors',
    }).then((res) => res.status);
};
const checkFor404OrSkip = async ({ suspecting404, sameOrigin, src, }) => {
    if (!suspecting404) {
        return Promise.resolve(null);
    }
    if (!sameOrigin) {
        return Promise.resolve(null);
    }
    try {
        return await checkFor404(src);
    }
    catch (_a) {
        return Promise.resolve(null);
    }
};
const onMediaError = ({ error, src, reject, cleanup, api, }) => {
    const suspecting404 = error.MEDIA_ERR_SRC_NOT_SUPPORTED === error.code;
    const isSrcSameOriginAsCurrent = new URL(src, window.location.origin)
        .toString()
        .startsWith(window.location.origin);
    checkFor404OrSkip({
        suspecting404,
        sameOrigin: isSrcSameOriginAsCurrent,
        src,
    })
        .then((status) => {
        const err = status === 404
            ? new Error([
                `Failed to execute ${api}: Received a 404 error loading "${src}".`,
                'Correct the URL of the file.',
            ].join(' '))
            : new Error([
                `Failed to execute ${api}, Received a MediaError loading "${src}". Consider using parseMedia() instead which supports more codecs: https://www.remotion.dev/docs/miscellaneous/parse-media-vs-get-video-metadata`,
                status === null
                    ? null
                    : `HTTP Status code of the file: ${status}.`,
                error.message
                    ? `Browser error message: ${error.message}`
                    : null,
                'Check the path of the file and if it is a valid video.',
            ]
                .filter(Boolean)
                .join(' '));
        reject(err);
        cleanup();
    })
        .catch((e) => {
        reject(e);
        cleanup();
    });
};
exports.onMediaError = onMediaError;


/***/ },

/***/ 5332
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.normalizeData = void 0;
const normalizeData = (filteredData) => {
    const max = Math.max(...filteredData);
    const multiplier = max === 0 ? 0 : max ** -1;
    return filteredData.map((n) => n * multiplier);
};
exports.normalizeData = normalizeData;


/***/ },

/***/ 1082
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.pLimit = void 0;
const pLimit = (concurrency) => {
    const queue = [];
    let activeCount = 0;
    const next = () => {
        var _a;
        activeCount--;
        if (queue.length > 0) {
            (_a = queue.shift()) === null || _a === void 0 ? void 0 : _a();
        }
    };
    const run = async (fn, resolve, ...args) => {
        activeCount++;
        // eslint-disable-next-line require-await
        const result = (async () => fn(...args))();
        resolve(result);
        try {
            await result;
        }
        catch (_a) { }
        next();
    };
    const enqueue = (fn, resolve, ...args) => {
        queue.push(() => run(fn, resolve, ...args));
        (async () => {
            var _a;
            // This function needs to wait until the next microtask before comparing
            // `activeCount` to `concurrency`, because `activeCount` is updated asynchronously
            // when the run function is dequeued and called. The comparison in the if-statement
            // needs to happen asynchronously as well to get an up-to-date value for `activeCount`.
            await Promise.resolve();
            if (activeCount < concurrency && queue.length > 0) {
                (_a = queue.shift()) === null || _a === void 0 ? void 0 : _a();
            }
        })();
    };
    const generator = (fn, ...args) => new Promise((resolve) => {
        enqueue(fn, resolve, ...args);
    });
    Object.defineProperties(generator, {
        activeCount: {
            get: () => activeCount,
        },
        pendingCount: {
            get: () => queue.length,
        },
        clearQueue: {
            value: () => {
                queue.length = 0;
            },
        },
    });
    return generator;
};
exports.pLimit = pLimit;


/***/ },

/***/ 5169
(__unused_webpack_module, exports) {

"use strict";

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


/***/ },

/***/ 205
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.useAudioData = void 0;
const react_1 = __webpack_require__(6540);
const remotion_1 = __webpack_require__(3947);
const get_audio_data_1 = __webpack_require__(5576);
/*
 * @description Wraps the getAudioData() function into a hook and does three things: keeps the audio data in a state, wraps the function in a delayRender() / continueRender() pattern, and handles the case where the component gets unmounted while fetching is in progress to prevent React errors.
 * @see [Documentation](https://www.remotion.dev/docs/use-audio-data)
 */
const useAudioData = (src) => {
    if (!src) {
        throw new TypeError("useAudioData requires a 'src' parameter");
    }
    const mountState = (0, react_1.useRef)({ isMounted: true });
    (0, react_1.useEffect)(() => {
        const { current } = mountState;
        current.isMounted = true;
        return () => {
            current.isMounted = false;
        };
    }, []);
    const [metadata, setMetadata] = (0, react_1.useState)(null);
    const { delayRender, continueRender } = (0, remotion_1.useDelayRender)();
    const fetchMetadata = (0, react_1.useCallback)(async () => {
        const handle = delayRender(`Waiting for audio metadata with src="${src}" to be loaded`);
        try {
            const data = await (0, get_audio_data_1.getAudioData)(src);
            if (mountState.current.isMounted) {
                setMetadata(data);
            }
        }
        catch (err) {
            (0, remotion_1.cancelRender)(err);
        }
        continueRender(handle);
    }, [src, delayRender, continueRender]);
    (0, react_1.useLayoutEffect)(() => {
        fetchMetadata();
    }, [fetchMetadata]);
    return metadata;
};
exports.useAudioData = useAudioData;


/***/ },

/***/ 1447
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.useWindowedAudioData = void 0;
const mediabunny_1 = __webpack_require__(3742);
const react_1 = __webpack_require__(6540);
const remotion_1 = __webpack_require__(3947);
const combine_float32_arrays_1 = __webpack_require__(1546);
const get_partial_audio_data_1 = __webpack_require__(5624);
const is_remote_asset_1 = __webpack_require__(5448);
const warnedMatroska = {};
const useWindowedAudioData = ({ src, frame, fps, windowInSeconds, channelIndex = 0, }) => {
    const isMounted = (0, react_1.useRef)(true);
    const [audioUtils, setAudioUtils] = (0, react_1.useState)(null);
    const [waveFormMap, setWaveformMap] = (0, react_1.useState)({});
    const requests = (0, react_1.useRef)({});
    const [initialWindowInSeconds] = (0, react_1.useState)(windowInSeconds);
    if (windowInSeconds !== initialWindowInSeconds) {
        throw new Error('windowInSeconds cannot be changed dynamically');
    }
    (0, react_1.useEffect)(() => {
        isMounted.current = true;
        return () => {
            isMounted.current = false;
            Object.values(requests.current).forEach((controller) => {
                if (controller) {
                    controller.abort();
                }
            });
            requests.current = {};
            setWaveformMap({});
            if (audioUtils) {
                audioUtils.input.dispose();
            }
        };
    }, [audioUtils]);
    const { delayRender, continueRender } = (0, remotion_1.useDelayRender)();
    const fetchMetadata = (0, react_1.useCallback)(async (signal) => {
        const handle = delayRender(`Waiting for audio metadata with src="${src}" to be loaded`);
        const cont = () => {
            continueRender(handle);
        };
        signal.addEventListener('abort', cont, { once: true });
        const input = new mediabunny_1.Input({
            formats: mediabunny_1.ALL_FORMATS,
            source: new mediabunny_1.UrlSource(src),
        });
        const onAbort = () => {
            input.dispose();
        };
        signal.addEventListener('abort', onAbort, { once: true });
        try {
            const durationInSeconds = await input.computeDuration();
            const audioTrack = await input.getPrimaryAudioTrack();
            if (!audioTrack) {
                throw new Error('No audio track found');
            }
            const canDecode = await audioTrack.canDecode();
            if (!canDecode) {
                throw new Error('Audio track cannot be decoded');
            }
            if (channelIndex >= audioTrack.numberOfChannels || channelIndex < 0) {
                throw new Error(`Invalid channel index ${channelIndex} for audio with ${audioTrack.numberOfChannels} channels`);
            }
            const { numberOfChannels, sampleRate } = audioTrack;
            const format = await input.getFormat();
            const isMatroska = format === mediabunny_1.MATROSKA || format === mediabunny_1.WEBM;
            if (isMounted.current) {
                setAudioUtils({
                    input,
                    track: audioTrack,
                    metadata: {
                        durationInSeconds,
                        numberOfChannels,
                        sampleRate,
                    },
                    isMatroska,
                });
            }
            continueRender(handle);
        }
        catch (err) {
            (0, remotion_1.cancelRender)(err);
        }
        finally {
            signal.removeEventListener('abort', cont);
            signal.removeEventListener('abort', onAbort);
        }
    }, [src, delayRender, continueRender, channelIndex]);
    (0, react_1.useLayoutEffect)(() => {
        const controller = new AbortController();
        fetchMetadata(controller.signal);
        return () => {
            controller.abort();
        };
    }, [fetchMetadata]);
    const currentTime = frame / fps;
    const currentWindowIndex = Math.floor(currentTime / windowInSeconds);
    const windowsToFetch = (0, react_1.useMemo)(() => {
        if (!(audioUtils === null || audioUtils === void 0 ? void 0 : audioUtils.metadata)) {
            return [];
        }
        const maxWindowIndex = Math.floor(
        // If an audio is exactly divisible by windowInSeconds, we need to
        // subtract 0.000000000001 to avoid fetching an extra window.
        audioUtils.metadata.durationInSeconds / windowInSeconds - 0.000000000001);
        // needs to be in order because we rely on the concatenation below
        return [
            currentWindowIndex === 0 ? null : currentWindowIndex - 1,
            currentWindowIndex,
            currentWindowIndex + 1 > maxWindowIndex ? null : currentWindowIndex + 1,
        ]
            .filter((i) => i !== null)
            .filter((i) => i >= 0);
    }, [currentWindowIndex, audioUtils, windowInSeconds]);
    const fetchAndSetWaveformData = (0, react_1.useCallback)(async (windowIndex) => {
        if (!(audioUtils === null || audioUtils === void 0 ? void 0 : audioUtils.metadata) || !audioUtils) {
            throw new Error('MediaBunny context is not loaded yet');
        }
        // Cancel any existing request for this window, we don't want to over-fetch
        const existingController = requests.current[windowIndex];
        if (existingController) {
            existingController.abort();
        }
        const controller = new AbortController();
        requests.current[windowIndex] = controller;
        if (controller.signal.aborted) {
            return;
        }
        const fromSeconds = windowIndex * windowInSeconds;
        const toSeconds = (windowIndex + 1) * windowInSeconds;
        // if both fromSeconds and toSeconds are outside of the audio duration, skip fetching
        if (fromSeconds >= audioUtils.metadata.durationInSeconds ||
            toSeconds <= 0) {
            return;
        }
        try {
            const { isMatroska } = audioUtils;
            if (isMatroska && !warnedMatroska[src]) {
                warnedMatroska[src] = true;
                remotion_1.Internals.Log.warn({ logLevel: 'info', tag: '@remotion/media-utils' }, `[useWindowedAudioData] Matroska/WebM file detected at "${src}".\n\nDue to format limitation, audio decoding must start from the beginning of the file, which may lead to increased memory usage and slower performance for large files. Consider converting the audio to a more suitable format like MP3 or AAC for better performance.`);
            }
            const partialWaveData = await (0, get_partial_audio_data_1.getPartialAudioData)({
                track: audioUtils.track,
                fromSeconds,
                toSeconds,
                channelIndex,
                signal: controller.signal,
                isMatroska,
            });
            if (!controller.signal.aborted) {
                setWaveformMap((prev) => {
                    const entries = Object.keys(prev);
                    const windowsToClear = entries.filter((entry) => !windowsToFetch.includes(Number(entry)));
                    return {
                        ...prev,
                        ...windowsToClear.reduce((acc, key) => {
                            acc[key] = null;
                            return acc;
                        }, {}),
                        [windowIndex]: partialWaveData,
                    };
                });
            }
        }
        catch (err) {
            if (controller.signal.aborted) {
                return;
            }
            if (err instanceof mediabunny_1.InputDisposedError) {
                return;
            }
            throw err;
        }
        finally {
            if (requests.current[windowIndex] === controller) {
                requests.current[windowIndex] = null;
            }
        }
    }, [channelIndex, audioUtils, windowInSeconds, windowsToFetch, src]);
    (0, react_1.useEffect)(() => {
        if (!(audioUtils === null || audioUtils === void 0 ? void 0 : audioUtils.metadata)) {
            return;
        }
        const windowsToClear = Object.keys(requests.current).filter((entry) => !windowsToFetch.includes(Number(entry)));
        for (const windowIndex of windowsToClear) {
            const controller = requests.current[windowIndex];
            if (controller) {
                controller.abort();
                requests.current[windowIndex] = null;
            }
        }
        // Only fetch windows that don't already exist
        const windowsToActuallyFetch = windowsToFetch.filter((windowIndex) => !waveFormMap[windowIndex] && !requests.current[windowIndex]);
        if (windowsToActuallyFetch.length === 0) {
            return;
        }
        // Prioritize the current window where playback is at.
        // On slow connections, this ensures the most important window loads first.
        const currentWindowNeedsFetch = windowsToActuallyFetch.includes(currentWindowIndex);
        const otherWindowsToFetch = windowsToActuallyFetch.filter((w) => w !== currentWindowIndex);
        const fetchWindows = async () => {
            // First, load the current window where playback is at
            if (currentWindowNeedsFetch) {
                await fetchAndSetWaveformData(currentWindowIndex);
            }
            // Then load the surrounding windows in parallel
            if (otherWindowsToFetch.length > 0) {
                await Promise.all(otherWindowsToFetch.map((windowIndex) => {
                    return fetchAndSetWaveformData(windowIndex);
                }));
            }
        };
        fetchWindows().catch((err) => {
            var _a, _b, _c, _d, _e;
            if ((_a = err.stack) === null || _a === void 0 ? void 0 : _a.includes('Cancelled')) {
                return;
            }
            if ((_c = (_b = err.stack) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === null || _c === void 0 ? void 0 : _c.includes('aborted')) {
                return;
            }
            // firefox
            if ((_e = (_d = err.message) === null || _d === void 0 ? void 0 : _d.toLowerCase()) === null || _e === void 0 ? void 0 : _e.includes('aborted')) {
                return;
            }
            (0, remotion_1.cancelRender)(err);
        });
    }, [
        fetchAndSetWaveformData,
        audioUtils,
        windowsToFetch,
        waveFormMap,
        currentWindowIndex,
    ]);
    // Calculate available windows for reuse
    const availableWindows = (0, react_1.useMemo)(() => {
        return windowsToFetch.filter((i) => waveFormMap[i]);
    }, [windowsToFetch, waveFormMap]);
    const currentAudioData = (0, react_1.useMemo)(() => {
        if (!(audioUtils === null || audioUtils === void 0 ? void 0 : audioUtils.metadata)) {
            return null;
        }
        if (availableWindows.length === 0) {
            return null;
        }
        const windows = availableWindows.map((i) => waveFormMap[i]);
        const data = (0, combine_float32_arrays_1.combineFloat32Arrays)(windows);
        return {
            channelWaveforms: [data],
            durationInSeconds: audioUtils.metadata.durationInSeconds,
            isRemote: (0, is_remote_asset_1.isRemoteAsset)(src),
            numberOfChannels: 1,
            resultId: `${src}-windows-${availableWindows.join(',')}`,
            sampleRate: audioUtils.metadata.sampleRate,
        };
    }, [src, waveFormMap, audioUtils, availableWindows]);
    const isBeyondAudioDuration = audioUtils
        ? currentTime >= audioUtils.metadata.durationInSeconds
        : false;
    (0, react_1.useLayoutEffect)(() => {
        if (currentAudioData) {
            return;
        }
        if (isBeyondAudioDuration) {
            return;
        }
        const handle = delayRender(`Waiting for audio data with src="${src}" to be loaded`);
        return () => {
            continueRender(handle);
        };
    }, [
        currentAudioData,
        src,
        delayRender,
        continueRender,
        isBeyondAudioDuration,
    ]);
    const audioData = isBeyondAudioDuration ? null : currentAudioData;
    return {
        audioData,
        dataOffsetInSeconds: availableWindows.length > 0 ? availableWindows[0] * windowInSeconds : 0,
    };
};
exports.useWindowedAudioData = useWindowedAudioData;


/***/ },

/***/ 6746
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.validateChannel = void 0;
const validateChannel = (channel, numberOfChannels) => {
    if (typeof channel !== 'number') {
        throw new TypeError(`"channel" must be a number`);
    }
    if (channel % 1 !== 0) {
        throw new TypeError(`"channel" must an integer, got ${channel}`);
    }
    if (Number.isNaN(channel)) {
        throw new TypeError(`The channel parameter is NaN.`);
    }
    if (channel < 0) {
        throw new TypeError('"channel" cannot be negative');
    }
    if (channel > numberOfChannels - 1) {
        throw new TypeError(`"channel" must be ${numberOfChannels - 1} or lower. The audio has ${numberOfChannels} channels`);
    }
};
exports.validateChannel = validateChannel;


/***/ },

/***/ 4853
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.visualizeAudioWaveform = void 0;
const get_waveform_portion_1 = __webpack_require__(1235);
const cache = {};
const visualizeAudioWaveformFrame = ({ audioData, frame, fps, numberOfSamples, windowInSeconds, channel, dataOffsetInSeconds, normalize = false, }) => {
    if (windowInSeconds * audioData.sampleRate < numberOfSamples) {
        throw new TypeError(windowInSeconds +
            's audiodata does not have ' +
            numberOfSamples +
            ' bars. Increase windowInSeconds or decrease numberOfSamples');
    }
    const cacheKey = audioData.resultId +
        frame +
        fps +
        numberOfSamples +
        'waveform' +
        dataOffsetInSeconds;
    if (cache[cacheKey]) {
        return cache[cacheKey];
    }
    const time = frame / fps;
    const startTimeInSeconds = time - windowInSeconds / 2;
    return (0, get_waveform_portion_1.getWaveformPortion)({
        audioData,
        startTimeInSeconds,
        durationInSeconds: windowInSeconds,
        numberOfSamples,
        outputRange: 'minus-one-to-one',
        channel,
        dataOffsetInSeconds,
        normalize,
    });
};
const visualizeAudioWaveform = (parameters) => {
    const data = visualizeAudioWaveformFrame(parameters);
    return data.map((value) => value.amplitude);
};
exports.visualizeAudioWaveform = visualizeAudioWaveform;


/***/ },

/***/ 8717
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.visualizeAudio = void 0;
const no_react_1 = __webpack_require__(9382);
const get_visualization_1 = __webpack_require__(9894);
const max_value_cached_1 = __webpack_require__(2268);
const cache = {};
/**
 * @description Takes in AudioData (preferably fetched by the useAudioData() hook) and processes it in a way that makes visualizing the audio that is playing at the current frame easy.
 * @description part of @remotion/media-utils
 * @see [Documentation](https://www.remotion.dev/docs/visualize-audio)
 */
const visualizeAudioFrame = ({ audioData, frame, fps, numberOfSamples, optimizeFor, dataOffsetInSeconds, }) => {
    const cacheKey = audioData.resultId + frame + fps + numberOfSamples;
    if (cache[cacheKey]) {
        return cache[cacheKey];
    }
    const maxInt = (0, max_value_cached_1.getMaxPossibleMagnitude)(audioData);
    return (0, get_visualization_1.getVisualization)({
        sampleSize: numberOfSamples * 2,
        data: audioData.channelWaveforms[0],
        frame,
        fps,
        sampleRate: audioData.sampleRate,
        maxInt,
        optimizeFor,
        dataOffsetInSeconds,
    });
};
const visualizeAudio = ({ smoothing = true, optimizeFor = no_react_1.NoReactInternals.ENABLE_V5_BREAKING_CHANGES
    ? 'speed'
    : 'accuracy', dataOffsetInSeconds = 0, ...parameters }) => {
    if (!smoothing) {
        return visualizeAudioFrame({
            ...parameters,
            optimizeFor,
            dataOffsetInSeconds,
            smoothing,
        });
    }
    const toSmooth = [
        parameters.frame - 1,
        parameters.frame,
        parameters.frame + 1,
    ];
    const all = toSmooth.map((s) => {
        return visualizeAudioFrame({
            ...parameters,
            frame: s,
            dataOffsetInSeconds,
            optimizeFor,
            smoothing,
        });
    });
    return new Array(parameters.numberOfSamples).fill(true).map((_x, i) => {
        return (new Array(toSmooth.length)
            .fill(true)
            .map((_, j) => {
            return all[j][i];
        })
            .reduce((a, b) => a + b, 0) / toSmooth.length);
    });
};
exports.visualizeAudio = visualizeAudio;


/***/ },

/***/ 9057
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.stripAnsi = void 0;
exports.splitAnsi = splitAnsi;
const ansiRegex = () => {
    const pattern = [
        '[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)',
        '(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))',
    ].join('|');
    return new RegExp(pattern, 'g');
};
function splitAnsi(str) {
    const parts = str.match(ansiRegex());
    if (!parts)
        return [str];
    const result = [];
    let offset = 0;
    let ptr = 0;
    for (let i = 0; i < parts.length; i++) {
        offset = str.indexOf(parts[i], offset);
        if (offset === -1)
            throw new Error('Could not split string');
        if (ptr !== offset)
            result.push(str.slice(ptr, offset));
        if (ptr === offset && result.length) {
            result[result.length - 1] += parts[i];
        }
        else {
            if (offset === 0)
                result.push('');
            result.push(parts[i]);
        }
        ptr = offset + parts[i].length;
    }
    result.push(str.slice(ptr));
    return result;
}
const stripAnsi = (str) => {
    if (typeof str !== 'string') {
        throw new TypeError(`Expected a \`string\`, got \`${typeof str}\``);
    }
    return str.replace(ansiRegex(), '');
};
exports.stripAnsi = stripAnsi;


/***/ },

/***/ 3507
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS = void 0;
exports.DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS = 300;


/***/ },

/***/ 9567
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.formatBytes = void 0;
const BYTE_UNITS = ['B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const BIBYTE_UNITS = [
    'B',
    'kiB',
    'MiB',
    'GiB',
    'TiB',
    'PiB',
    'EiB',
    'ZiB',
    'YiB',
];
const BIT_UNITS = [
    'b',
    'kbit',
    'Mbit',
    'Gbit',
    'Tbit',
    'Pbit',
    'Ebit',
    'Zbit',
    'Ybit',
];
const BIBIT_UNITS = [
    'b',
    'kibit',
    'Mibit',
    'Gibit',
    'Tibit',
    'Pibit',
    'Eibit',
    'Zibit',
    'Yibit',
];
/*
Formats the given number using `Number#toLocaleString`.
- If locale is a string, the value is expected to be a locale-key (for example: `de`).
- If locale is true, the system default locale is used for translation.
- If no value for locale is specified, the number is returned unmodified.
*/
const toLocaleString = (number, locale, options) => {
    if (typeof locale === 'string' || Array.isArray(locale)) {
        return number.toLocaleString(locale, options);
    }
    if (locale === true || options !== undefined) {
        return number.toLocaleString(undefined, options);
    }
    return String(number);
};
const formatBytes = (number, options = {
    locale: 'en-US',
    signed: false,
    maximumFractionDigits: 1,
}) => {
    if (!Number.isFinite(number)) {
        throw new TypeError(`Expected a finite number, got ${typeof number}: ${number}`);
    }
    options = { bits: false, binary: false, ...options };
    const UNITS = options.bits
        ? options.binary
            ? BIBIT_UNITS
            : BIT_UNITS
        : options.binary
            ? BIBYTE_UNITS
            : BYTE_UNITS;
    if (options.signed && number === 0) {
        return `0 $ {
            UNITS[0]
        }`;
    }
    const isNegative = number < 0;
    const prefix = isNegative ? '-' : options.signed ? '+' : '';
    if (isNegative) {
        number = -number;
    }
    let localeOptions;
    if (options.minimumFractionDigits !== undefined) {
        localeOptions = {
            minimumFractionDigits: options.minimumFractionDigits,
        };
    }
    if (options.maximumFractionDigits !== undefined) {
        localeOptions = {
            maximumFractionDigits: options.maximumFractionDigits,
            ...localeOptions,
        };
    }
    if (number < 1) {
        const numString = toLocaleString(number, options.locale, localeOptions);
        return prefix + numString + ' ' + UNITS[0];
    }
    const exponent = Math.min(Math.floor(options.binary
        ? Math.log(number) / Math.log(1024)
        : Math.log10(number) / 3), UNITS.length - 1);
    number /= (options.binary ? 1024 : 1000) ** exponent;
    const numberString = toLocaleString(Number(number), options.locale, localeOptions);
    const unit = UNITS[exponent];
    return prefix + numberString + ' ' + unit;
};
exports.formatBytes = formatBytes;


/***/ },

/***/ 3953
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getDefaultOutLocation = void 0;
const hasFileExtension = (location) => {
    var _a;
    const lastSegment = (_a = location.split('/').pop()) !== null && _a !== void 0 ? _a : location;
    return lastSegment.includes('.');
};
const getDefaultOutLocation = ({ compositionName, defaultExtension, type, compositionDefaultOutName, outputLocation, }) => {
    if (outputLocation && hasFileExtension(outputLocation)) {
        return outputLocation;
    }
    const base = outputLocation !== null && outputLocation !== void 0 ? outputLocation : 'out';
    const dir = base.endsWith('/') ? base : `${base}/`;
    const nameToUse = compositionDefaultOutName !== null && compositionDefaultOutName !== void 0 ? compositionDefaultOutName : compositionName;
    if (type === 'sequence') {
        return `${dir}${nameToUse}`;
    }
    return `${dir}${nameToUse}.${defaultExtension}`;
};
exports.getDefaultOutLocation = getDefaultOutLocation;


/***/ },

/***/ 885
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getLocationFromBuildError = void 0;
const no_react_1 = __webpack_require__(9382);
const getLocationFromBuildError = (err) => {
    var _a;
    if (!err.stack) {
        return null;
    }
    if (!err.stack.startsWith('Error: Module build failed') &&
        !err.stack.startsWith('Error: Cannot find module')) {
        return null;
    }
    const split = err.stack.split('\n');
    return ((_a = split
        .map((s) => {
        if (s.startsWith('Error')) {
            return null;
        }
        const matchWebpackOrEsbuild = s.match(/(.*):([0-9]+):([0-9]+): (.*)/);
        if (matchWebpackOrEsbuild) {
            return {
                fileName: matchWebpackOrEsbuild[1],
                lineNumber: Number(matchWebpackOrEsbuild[2]),
                columnNumber: Number(matchWebpackOrEsbuild[3]),
                message: matchWebpackOrEsbuild[4],
            };
        }
        const matchMissingModule = s.match(/\s+at(.*)\s\((.*)\)/);
        if (!matchMissingModule) {
            return null;
        }
        if (s.includes('webpackMissingModule')) {
            return null;
        }
        const [, filename] = matchMissingModule;
        return {
            columnNumber: 0,
            lineNumber: 1,
            message: split[0],
            fileName: filename.trim(),
        };
    })
        .filter(no_react_1.NoReactInternals.truthy)[0]) !== null && _a !== void 0 ? _a : null);
};
exports.getLocationFromBuildError = getLocationFromBuildError;


/***/ },

/***/ 2754
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.getProjectName = void 0;
const getProjectName = ({ gitSource, resolvedRemotionRoot, basename, }) => {
    // Directory name
    if (!gitSource) {
        return basename(resolvedRemotionRoot);
    }
    // Subfolder name of a Git repo, e.g `example`
    if (gitSource.relativeFromGitRoot.trim()) {
        return basename(gitSource.relativeFromGitRoot.trim());
    }
    // Name of the repo
    return gitSource.name;
};
exports.getProjectName = getProjectName;


/***/ },

/***/ 3356
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.hotMiddlewareOptions = void 0;
exports.hotMiddlewareOptions = {
    path: '/__webpack_hmr',
    timeout: 20 * 1000,
    reload: true,
    warn: true,
    heartbeat: 10 * 1000,
};


/***/ },

/***/ 6588
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";
var __webpack_unused_export__;

__webpack_unused_export__ = ({ value: true });
__webpack_unused_export__ = exports.fC = __webpack_unused_export__ = exports.W3 = exports.IJ = exports.eH = exports.aO = exports.n3 = __webpack_unused_export__ = __webpack_unused_export__ = exports.Ug = exports.LE = exports.z3 = __webpack_unused_export__ = __webpack_unused_export__ = __webpack_unused_export__ = void 0;
const ansi_1 = __webpack_require__(9057);
__webpack_unused_export__ = ({ enumerable: true, get: function () { return ansi_1.splitAnsi; } });
__webpack_unused_export__ = ({ enumerable: true, get: function () { return ansi_1.stripAnsi; } });
const default_buffer_state_delay_in_milliseconds_1 = __webpack_require__(3507);
__webpack_unused_export__ = ({ enumerable: true, get: function () { return default_buffer_state_delay_in_milliseconds_1.DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS; } });
const format_bytes_1 = __webpack_require__(9567);
Object.defineProperty(exports, "z3", ({ enumerable: true, get: function () { return format_bytes_1.formatBytes; } }));
const get_default_out_name_1 = __webpack_require__(3953);
Object.defineProperty(exports, "LE", ({ enumerable: true, get: function () { return get_default_out_name_1.getDefaultOutLocation; } }));
const get_location_from_build_error_1 = __webpack_require__(885);
Object.defineProperty(exports, "Ug", ({ enumerable: true, get: function () { return get_location_from_build_error_1.getLocationFromBuildError; } }));
const get_project_name_1 = __webpack_require__(2754);
__webpack_unused_export__ = ({ enumerable: true, get: function () { return get_project_name_1.getProjectName; } });
const hot_middleware_1 = __webpack_require__(3356);
__webpack_unused_export__ = ({ enumerable: true, get: function () { return hot_middleware_1.hotMiddlewareOptions; } });
const max_timeline_tracks_1 = __webpack_require__(8769);
Object.defineProperty(exports, "n3", ({ enumerable: true, get: function () { return max_timeline_tracks_1.DEFAULT_TIMELINE_TRACKS; } }));
const package_info_1 = __webpack_require__(1337);
Object.defineProperty(exports, "aO", ({ enumerable: true, get: function () { return package_info_1.apiDocs; } }));
Object.defineProperty(exports, "eH", ({ enumerable: true, get: function () { return package_info_1.descriptions; } }));
Object.defineProperty(exports, "IJ", ({ enumerable: true, get: function () { return package_info_1.extraPackages; } }));
Object.defineProperty(exports, "W3", ({ enumerable: true, get: function () { return package_info_1.installableMap; } }));
__webpack_unused_export__ = ({ enumerable: true, get: function () { return package_info_1.packages; } });
const source_map_endpoint_1 = __webpack_require__(8188);
Object.defineProperty(exports, "fC", ({ enumerable: true, get: function () { return source_map_endpoint_1.SOURCE_MAP_ENDPOINT; } }));
const stringify_default_props_1 = __webpack_require__(6266);
__webpack_unused_export__ = ({ enumerable: true, get: function () { return stringify_default_props_1.stringifyDefaultProps; } });


/***/ },

/***/ 8769
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.DEFAULT_TIMELINE_TRACKS = void 0;
exports.DEFAULT_TIMELINE_TRACKS = 90;


/***/ },

/***/ 1337
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.apiDocs = exports.installableMap = exports.descriptions = exports.extraPackages = exports.packages = void 0;
exports.packages = [
    'svg-3d-engine',
    'animation-utils',
    'animated-emoji',
    'astro-example',
    'babel-loader',
    'bugs',
    'bundler',
    'cli',
    'cloudrun',
    'compositor-darwin-arm64',
    'compositor-darwin-x64',
    'compositor-linux-arm64-gnu',
    'compositor-linux-arm64-musl',
    'compositor-linux-x64-gnu',
    'compositor-linux-x64-musl',
    'compositor-win32-x64-msvc',
    'core',
    'create-video',
    'discord-poster',
    'docusaurus-plugin',
    'docs',
    'enable-scss',
    'eslint-config',
    'eslint-config-flat',
    'eslint-config-internal',
    'eslint-plugin',
    'example-without-zod',
    'example',
    'fonts',
    'gif',
    'google-fonts',
    'install-whisper-cpp',
    'it-tests',
    'react18-tests',
    'lambda-go-example',
    'lambda-go',
    'lambda-php',
    'lambda-ruby',
    'lambda-python',
    'lambda',
    'lambda-client',
    'layout-utils',
    'rounded-text-box',
    'licensing',
    'lottie',
    'mcp',
    'media-utils',
    'motion-blur',
    'noise',
    'paths',
    'player-example',
    'player',
    'preload',
    'renderer',
    'rive',
    'shapes',
    'skia',
    'promo-pages',
    'streaming',
    'serverless',
    'serverless-client',
    'skills',
    'studio-server',
    'studio-shared',
    'studio',
    'tailwind',
    'tailwind-v4',
    'test-utils',
    'three',
    'transitions',
    'media-parser',
    'zod-types',
    'zod-types-v3',
    'webcodecs',
    'convert',
    'captions',
    'openai-whisper',
    'compositor',
    'example-videos',
    'whisper-web',
    'media',
    'web-renderer',
    'design',
    'light-leaks',
    'vercel',
    'sfx',
];
exports.extraPackages = [
    {
        name: 'mediabunny',
        version: '1.34.5',
        description: 'Multimedia library used by Remotion',
        docsUrl: 'https://www.remotion.dev/docs/mediabunny/version',
    },
    {
        name: '@mediabunny/ac3',
        version: '1.34.5',
        description: 'AC-3 and E-AC-3 audio codec support for Mediabunny',
        docsUrl: 'https://www.remotion.dev/docs/mediabunny/formats#ac-3-and-e-ac-3',
    },
    {
        name: 'zod',
        version: '4.3.6',
        description: 'TypeScript-first schema validation',
        docsUrl: 'https://zod.dev',
    },
];
exports.descriptions = {
    compositor: 'Rust binary for Remotion',
    player: 'React component for embedding a Remotion preview into your app',
    cloudrun: 'Render Remotion videos on Google Cloud Run',
    renderer: 'Render Remotion videos using Node.js or Bun',
    cli: 'Control Remotion features using the `npx remotion` command',
    core: 'Make videos programmatically',
    lambda: 'Render Remotion videos on AWS Lambda',
    bundler: 'Bundle Remotion compositions using Webpack',
    'studio-server': 'Run a Remotion Studio with a server backend',
    'install-whisper-cpp': 'Helpers for installing and using Whisper.cpp',
    'whisper-web': 'Helpers for using Whisper.cpp in browser using WASM',
    'google-fonts': 'Use Google Fonts in Remotion',
    mcp: "Remotion's Model Context Protocol",
    'media-utils': 'Utilities for working with media files',
    lottie: 'Include Lottie animations in Remotion',
    licensing: 'Manage your Remotion.pro license',
    'layout-utils': 'Utilities for working with layouts',
    'rounded-text-box': 'Create a TikTok-like multiline text box SVG path with rounded corners',
    noise: 'Noise generation functions',
    'motion-blur': 'Motion blur effect for Remotion',
    preload: 'Preloads assets for use in Remotion',
    shapes: 'Generate SVG shapes',
    'zod-types': 'Zod types for Remotion',
    'zod-types-v3': 'Zod 3.22.3 types for Remotion',
    gif: 'Embed GIFs in a Remotion video',
    'eslint-plugin': 'Rules for writing Remotion code',
    'eslint-config': 'Default configuration for Remotion templates (ESLint <= 8)',
    'eslint-config-flat': 'Default configuration for Remotion templates (ESLint >= 9)',
    'compositor-linux-x64-gnu': 'Linux x64 binary for the Remotion Rust code',
    'compositor-linux-x64-musl': 'Linux x64 binary for the Remotion Rust code',
    'compositor-darwin-x64': 'MacOS x64 binary for the Remotion Rust code',
    'compositor-darwin-arm64': 'MacOS Apple Silicon binary for the Remotion Rust code',
    'compositor-linux-arm64-gnu': 'Linux ARM64 binary for the Remotion Rust code',
    'compositor-linux-arm64-musl': 'Linux ARM64 binary for the Remotion Rust code',
    'babel-loader': 'Babel loader for Remotion',
    fonts: 'Helpers for loading local fonts into Remotion',
    transitions: 'Library for creating transitions in Remotion',
    'enable-scss': 'Enable SCSS support in Remotion',
    'create-video': 'Create a new Remotion project',
    'studio-shared': 'Internal package for shared objects between the Studio backend and frontend',
    tailwind: 'Enable TailwindCSS support in Remotion (TailwindCSS v3)',
    'tailwind-v4': 'Enable TailwindCSS support in Remotion (TailwindCSS v4)',
    streaming: 'Utilities for streaming data between programs',
    'media-parser': 'A pure JavaScript library for parsing video files',
    rive: 'Embed Rive animations in a Remotion video',
    paths: 'Utilities for working with SVG paths',
    studio: 'APIs for interacting with the Remotion Studio',
    skia: 'Include React Native Skia components in a Remotion video',
    three: 'Include React Three Fiber components in a Remotion video',
    'astro-example': null,
    'lambda-go-example': null,
    'compositor-win32-x64-msvc': null,
    'animation-utils': 'Helpers for animating CSS properties',
    'test-utils': null,
    'example-without-zod': null,
    'lambda-go': null,
    example: null,
    'lambda-php': null,
    'lambda-client': null,
    bugs: null,
    docs: null,
    'it-tests': null,
    'react18-tests': null,
    'lambda-python': null,
    'lambda-ruby': null,
    'player-example': null,
    skills: null,
    'discord-poster': null,
    'docusaurus-plugin': null,
    'animated-emoji': 'Google Fonts Animated Emojis as Remotion components',
    serverless: 'A runtime for distributed rendering',
    webcodecs: 'Media conversion in the browser',
    convert: 'Video conversion tool - convert.remotion.dev',
    captions: 'Primitives for dealing with captions',
    'openai-whisper': 'Work with the output of the OpenAI Whisper API',
    'eslint-config-internal': "ESLint condig for Remotion's internal packages",
    'example-videos': null,
    'promo-pages': null,
    'svg-3d-engine': '3D SVG extrusion effects',
    'serverless-client': null,
    media: 'Experimental WebCodecs-based media tags',
    'web-renderer': 'Render videos in the browser (not yet released)',
    design: 'Design system',
    'light-leaks': 'Light leak effects for Remotion',
    vercel: 'Render Remotion videos on Vercel Sandbox',
    sfx: 'Sound effect library',
};
exports.installableMap = {
    'svg-3d-engine': false,
    'animation-utils': true,
    'animated-emoji': true,
    'astro-example': false,
    'babel-loader': false,
    bugs: false,
    bundler: false,
    cli: false,
    cloudrun: true,
    'lambda-client': false,
    'serverless-client': false,
    'compositor-darwin-arm64': false,
    'compositor-darwin-x64': false,
    'compositor-linux-arm64-gnu': false,
    'compositor-linux-arm64-musl': false,
    'compositor-linux-x64-gnu': false,
    'compositor-linux-x64-musl': false,
    'compositor-win32-x64-msvc': false,
    core: false,
    'create-video': false,
    'discord-poster': false,
    'docusaurus-plugin': false,
    docs: false,
    'enable-scss': true,
    'eslint-config': false,
    'eslint-config-flat': false,
    'eslint-config-internal': false,
    'eslint-plugin': false,
    'example-without-zod': false,
    example: false,
    fonts: true,
    gif: true,
    'google-fonts': true,
    'install-whisper-cpp': true,
    'whisper-web': true,
    'it-tests': false,
    'react18-tests': false,
    'lambda-go-example': false,
    'lambda-go': false,
    'lambda-php': false,
    'lambda-ruby': false,
    'lambda-python': false,
    lambda: true,
    mcp: true,
    'layout-utils': true,
    'rounded-text-box': true,
    licensing: true,
    lottie: true,
    'media-utils': true,
    'motion-blur': true,
    noise: true,
    paths: true,
    'player-example': false,
    player: true,
    preload: true,
    renderer: true,
    rive: true,
    shapes: true,
    skia: true,
    skills: false,
    'promo-pages': false,
    streaming: false,
    serverless: false,
    'studio-server': false,
    'studio-shared': false,
    studio: true,
    tailwind: true,
    'tailwind-v4': true,
    'test-utils': false,
    three: true,
    transitions: true,
    'media-parser': true,
    'zod-types': true,
    'zod-types-v3': true,
    webcodecs: true,
    convert: false,
    captions: true,
    'openai-whisper': true,
    compositor: false,
    'example-videos': false,
    media: true,
    'web-renderer': false,
    design: false,
    'light-leaks': true,
    vercel: true,
    sfx: true,
};
exports.apiDocs = {
    player: 'https://www.remotion.dev/docs/player',
    cloudrun: 'https://www.remotion.dev/docs/cloudrun',
    renderer: 'https://www.remotion.dev/docs/renderer',
    cli: 'https://www.remotion.dev/docs/cli',
    core: 'https://www.remotion.dev/docs/remotion',
    lambda: 'https://www.remotion.dev/docs/lambda',
    bundler: 'https://www.remotion.dev/docs/bundler',
    'lambda-client': null,
    'serverless-client': null,
    'studio-server': null,
    'install-whisper-cpp': 'https://www.remotion.dev/docs/install-whisper-cpp',
    'whisper-web': 'https://www.remotion.dev/docs/whisper-web',
    'google-fonts': 'https://www.remotion.dev/docs/google-fonts',
    'media-utils': 'https://www.remotion.dev/docs/media-utils',
    lottie: 'https://www.remotion.dev/docs/lottie',
    licensing: 'https://www.remotion.dev/docs/licensing',
    'layout-utils': 'https://www.remotion.dev/docs/layout-utils',
    'rounded-text-box': 'https://www.remotion.dev/docs/rounded-text-box',
    noise: 'https://www.remotion.dev/docs/noise',
    mcp: 'https://www.remotion.dev/docs/ai/mcp',
    'motion-blur': 'https://www.remotion.dev/docs/motion-blur',
    preload: 'https://www.remotion.dev/docs/preload',
    shapes: 'https://www.remotion.dev/docs/shapes',
    'zod-types': 'https://www.remotion.dev/docs/zod-types',
    'zod-types-v3': 'https://www.remotion.dev/docs/zod-types/v3',
    gif: 'https://www.remotion.dev/docs/gif',
    'eslint-plugin': 'https://www.remotion.dev/docs/brownfield#install-the-eslint-plugin',
    'eslint-config': 'https://www.remotion.dev/docs/brownfield#install-the-eslint-plugin',
    'eslint-config-flat': 'https://www.remotion.dev/docs/brownfield#install-the-eslint-plugin',
    'compositor-linux-x64-gnu': null,
    'compositor-linux-x64-musl': null,
    'compositor-darwin-x64': null,
    'discord-poster': null,
    'docusaurus-plugin': null,
    'animation-utils': 'https://www.remotion.dev/docs/animation-utils/',
    'example-without-zod': null,
    'lambda-go': null,
    example: null,
    'lambda-php': null,
    bugs: null,
    docs: null,
    'it-tests': null,
    'react18-tests': null,
    'lambda-python': null,
    'lambda-ruby': 'https://www.remotion.dev/docs/lambda/ruby',
    'player-example': null,
    'astro-example': null,
    'lambda-go-example': null,
    'test-utils': null,
    'babel-loader': 'https://www.remotion.dev/docs/legacy-babel',
    'compositor-darwin-arm64': null,
    'compositor-linux-arm64-gnu': null,
    'compositor-linux-arm64-musl': null,
    'compositor-win32-x64-msvc': null,
    'enable-scss': 'https://www.remotion.dev/docs/enable-scss/overview',
    'create-video': 'https://remotion.dev/templates',
    'studio-shared': null,
    'media-parser': 'https://www.remotion.dev/docs/media-parser',
    fonts: 'https://www.remotion.dev/docs/fonts-api',
    paths: 'https://www.remotion.dev/paths',
    rive: 'https://www.remotion.dev/docs/rive',
    tailwind: 'https://www.remotion.dev/docs/tailwind/tailwind',
    'tailwind-v4': 'https://www.remotion.dev/docs/tailwind/tailwind',
    skia: 'https://www.remotion.dev/docs/skia',
    three: 'https://www.remotion.dev/docs/three',
    streaming: null,
    serverless: null,
    skills: null,
    studio: 'https://www.remotion.dev/docs/studio/api',
    transitions: 'https://www.remotion.dev/transitions',
    'animated-emoji': 'https://www.remotion.dev/docs/animated-emoji',
    webcodecs: 'https://remotion.dev/webcodecs',
    convert: 'https://convert.remotion.dev',
    captions: 'https://remotion.dev/docs/captions/api',
    'openai-whisper': 'https://www.remotion.dev/docs/openai-whisper',
    'eslint-config-internal': null,
    compositor: null,
    'example-videos': null,
    'promo-pages': null,
    'svg-3d-engine': null,
    media: 'https://remotion.dev/docs/media',
    'web-renderer': 'https://www.remotion.dev/docs/web-renderer/',
    design: 'https://www.remotion.dev/design',
    'light-leaks': 'https://www.remotion.dev/docs/light-leaks',
    vercel: 'https://www.remotion.dev/docs/vercel/api',
    sfx: 'https://www.remotion.dev/docs/sfx',
};


/***/ },

/***/ 8188
(__unused_webpack_module, exports) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.SOURCE_MAP_ENDPOINT = void 0;
exports.SOURCE_MAP_ENDPOINT = '/source-map-helper.wasm';


/***/ },

/***/ 6266
(__unused_webpack_module, exports, __webpack_require__) {

"use strict";

Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.stringifyDefaultProps = void 0;
const no_react_1 = __webpack_require__(9382);
function replacerWithPath(replacer) {
    const m = new Map();
    return function (field, value) {
        const path = [m.get(this), field].flat(1);
        if (value === Object(value)) {
            m.set(value, path);
        }
        return replacer.call(this, field, value, path.filter((item) => typeof item !== 'undefined' && item !== ''));
    };
}
const doesMatchPath = (path1, enumPaths) => {
    return enumPaths.some((p) => 
    // especially 0 for root!
    path1.length === p.length &&
        path1.every((item, index) => {
            if (p[index] === '[]' && !Number.isNaN(Number(item))) {
                return true;
            }
            if (p[index] === '{}' && typeof item === 'string') {
                return true;
            }
            return item === p[index];
        }));
};
const stringifyDefaultProps = ({ props, enumPaths, }) => {
    return JSON.stringify(props, replacerWithPath(function (key, value, path) {
        /* Don't replace with arrow function! This function uses `this` */
        const item = this[key];
        if (typeof item === 'string' && doesMatchPath(path, enumPaths)) {
            return `${item}__ADD_AS_CONST__`;
        }
        // For zMatrix()
        if (doesMatchPath(path, enumPaths)) {
            return `__REMOVEQUOTE__${JSON.stringify(item)}__ADD_AS_LITERAL_CONST__`;
        }
        if (typeof item === 'string' &&
            item.startsWith(no_react_1.NoReactInternals.FILE_TOKEN)) {
            return `__REMOVEQUOTE____WRAP_IN_STATIC_FILE_START__${decodeURIComponent(item.replace(no_react_1.NoReactInternals.FILE_TOKEN, ''))}__WRAP_IN_STATIC_FILE_END____REMOVEQUOTE__`;
        }
        if (typeof item === 'string' &&
            item.startsWith(no_react_1.NoReactInternals.DATE_TOKEN)) {
            return `__REMOVEQUOTE____WRAP_IN_DATE_START__${decodeURIComponent(item.replace(no_react_1.NoReactInternals.DATE_TOKEN, ''))}__WRAP_IN_DATE_END____REMOVEQUOTE__`;
        }
        return value;
    }))
        .replace(/"__REMOVEQUOTE__/g, '')
        .replace(/__REMOVEQUOTE__"/g, '')
        .replace(/__ADD_AS_CONST__"/g, '" as const')
        .replace(/__ADD_AS_LITERAL_CONST__"/g, ' as const')
        .replace(/__WRAP_IN_STATIC_FILE_START__/g, 'staticFile("')
        .replace(/__WRAP_IN_STATIC_FILE_END__/g, '")')
        .replace(/__WRAP_IN_DATE_START__/g, 'new Date("')
        .replace(/__WRAP_IN_DATE_END__/g, '")');
};
exports.stringifyDefaultProps = stringifyDefaultProps;


/***/ },

/***/ 2517
(module, __webpack_exports__, __webpack_require__) {

"use strict";
var __webpack_internal_module__ = module;
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   StudioInternals: () => (/* binding */ StudioInternals)
/* harmony export */ });
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6540);
/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(961);
/* harmony import */ var remotion__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(3947);
/* harmony import */ var _remotion_player__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4229);
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4848);
/* harmony import */ var remotion_no_react__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(9382);
/* harmony import */ var _remotion_studio_shared__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(6588);
/* harmony import */ var mediabunny__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(4709);
/* harmony import */ var mediabunny__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(2912);
/* harmony import */ var mediabunny__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(2030);
/* harmony import */ var _remotion_media_utils__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(6996);
/* harmony import */ var _remotion_media_utils__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(_remotion_media_utils__WEBPACK_IMPORTED_MODULE_10__);
/* harmony import */ var source_map__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(9665);
/* harmony import */ var _remotion_web_renderer__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(9249);
/* harmony import */ var mediabunny__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(388);
/* harmony import */ var _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(2896);
/* harmony import */ var _remotion_renderer_pure__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(1891);


// src/Studio.tsx




// src/components/Editor.tsx




// src/helpers/colors.ts
var BACKGROUND = "rgb(31,36,40)";
var BACKGROUND__TRANSPARENT = "rgba(31,36,40, 0)";
var INPUT_BACKGROUND = "#2f363d";
var BORDER_COLOR = "#000";
var LIGHT_COLOR = "#ddd";
var SELECTED_BACKGROUND = "hsla(0, 0%, 100%, 0.15)";
var LIGHT_TEXT = "#A6A7A9";
var RULER_COLOR = "#808080";
var VERY_LIGHT_TEXT = "rgba(255, 255, 255, 0.3)";
var SELECTED_HOVER_BACKGROUND = "hsla(0, 0%, 100%, 0.25)";
var CLEAR_HOVER = "rgba(255, 255, 255, 0.06)";
var INPUT_BORDER_COLOR_UNHOVERED = "rgba(0, 0, 0, 0.6)";
var INPUT_BORDER_COLOR_HOVERED = "rgba(255, 255, 255, 0.05)";
var TIMELINE_BACKGROUND = "#111";
var FAIL_COLOR = "#ff3232";
var TEXT_COLOR = "#fff";
var WARNING_COLOR = "#f1c40f";
var BLUE = "#0b84f3";
var BLUE_DISABLED = "#284f73";
var LIGHT_TRANSPARENT = "rgba(255, 255, 255, 0.7)";
var UNSELECTED_GUIDE = "#7e1219";
var SELECTED_GUIDE = "#d22d3a";
var LINE_COLOR = "#363A3E";
var TIMELINE_TRACK_SEPARATOR = "rgba(0, 0, 0, 0.3)";
var getBackgroundFromHoverState = ({
  selected,
  hovered
}) => {
  if (selected) {
    if (hovered) {
      return SELECTED_HOVER_BACKGROUND;
    }
    return SELECTED_BACKGROUND;
  }
  if (hovered) {
    return CLEAR_HOVER;
  }
  return "transparent";
};

// src/helpers/noop.ts
var noop = () => {
  return;
};

// src/state/canvas-ref.ts

var canvasRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.createRef)();
var drawRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.createRef)();

// src/state/timeline-zoom.tsx


// src/components/Timeline/imperative-state.ts
var currentFrame = 0;
var currentZoom = 1;
var currentDuration = 1;
var currentFps = 1;
var getCurrentZoom = () => {
  return currentZoom;
};
var setCurrentZoom = (z) => {
  currentZoom = z;
};
var getCurrentFrame = () => {
  return currentFrame;
};
var setCurrentFrame = (f) => {
  currentFrame = f;
};
var getCurrentDuration = () => {
  return currentDuration;
};
var setCurrentDuration = (d) => {
  currentDuration = d;
};
var getCurrentFps = () => {
  return currentFps;
};
var setCurrentFps = (d) => {
  currentFps = d;
};

// src/components/Timeline/timeline-scroll-logic.ts


// src/components/RenderModal/SchemaEditor/zod-schema-type.ts
var zodSafeParse = (schema, data) => {
  return schema.safeParse(data);
};
var getZodDef = (schema) => {
  if (schema._def)
    return schema._def;
  if (schema._zod)
    return schema._zod.def;
  throw new Error("Invalid zod schema: missing _def and _zod");
};
var v3TypeNameMap = {
  ZodString: "string",
  ZodNumber: "number",
  ZodBoolean: "boolean",
  ZodObject: "object",
  ZodArray: "array",
  ZodEnum: "enum",
  ZodUnion: "union",
  ZodDiscriminatedUnion: "discriminatedUnion",
  ZodOptional: "optional",
  ZodNullable: "nullable",
  ZodDefault: "default",
  ZodTuple: "tuple",
  ZodDate: "date",
  ZodAny: "any",
  ZodUnknown: "unknown",
  ZodBigInt: "bigint",
  ZodNull: "null",
  ZodUndefined: "undefined",
  ZodEffects: "effects",
  ZodLiteral: "literal",
  ZodRecord: "record",
  ZodNever: "never",
  ZodVoid: "void",
  ZodNaN: "nan",
  ZodSymbol: "symbol",
  ZodIntersection: "intersection",
  ZodMap: "map",
  ZodSet: "set",
  ZodLazy: "lazy",
  ZodFunction: "function",
  ZodNativeEnum: "nativeEnum",
  ZodCatch: "catch",
  ZodPromise: "promise",
  ZodBranded: "branded",
  ZodPipeline: "pipeline"
};
var isZodV3Schema = (schema) => {
  const def = getZodDef(schema);
  return "typeName" in def;
};
var getZodSchemaType = (schema) => {
  const def = getZodDef(schema);
  if ("typeName" in def) {
    const { typeName } = def;
    return v3TypeNameMap[typeName] ?? typeName;
  }
  const { type } = def;
  if (type === "union" && def.discriminator !== undefined) {
    return "discriminatedUnion";
  }
  return type;
};
var getZodSchemaDescription = (schema) => {
  if (isZodV3Schema(schema)) {
    return getZodDef(schema).description;
  }
  return schema.description;
};
var getObjectShape = (schema) => {
  const { shape } = getZodDef(schema);
  return typeof shape === "function" ? shape() : shape;
};
var getArrayElement = (schema) => {
  const def = getZodDef(schema);
  return isZodV3Schema(schema) ? def.type : def.element;
};
var getInnerType = (schema) => {
  return getZodDef(schema).innerType;
};
var getEffectsInner = (schema) => {
  return getZodDef(schema).schema;
};
var getLiteralValue = (schema) => {
  const def = getZodDef(schema);
  if (isZodV3Schema(schema)) {
    return def.value;
  }
  return def.values?.[0];
};
var getEnumValues = (schema) => {
  const def = getZodDef(schema);
  if (isZodV3Schema(schema)) {
    return def.values;
  }
  const { entries } = def;
  return Object.values(entries);
};
var getFirstEnumValue = (schema) => {
  const def = getZodDef(schema);
  if (isZodV3Schema(schema)) {
    if (def.typeName === "ZodNativeEnum") {
      const vals = Object.values(def.values);
      return vals[0];
    }
    return def.values[0];
  }
  const { entries } = def;
  const pairs = Object.entries(entries);
  const hasReverseMapping = pairs.some(([key, value]) => key !== String(value));
  if (hasReverseMapping) {
    const forwardPairs = pairs.filter(([key]) => Number.isNaN(Number(key)));
    if (forwardPairs.length > 0) {
      return forwardPairs[0][1];
    }
  }
  return Object.values(entries)[0];
};
var getUnionOptions = (schema) => {
  return getZodDef(schema).options;
};
var getDefaultValue = (schema) => {
  const dv = getZodDef(schema).defaultValue;
  return typeof dv === "function" ? dv() : dv;
};
var getDiscriminator = (schema) => {
  return getZodDef(schema).discriminator;
};
var getDiscriminatedOptionKeys = (schema) => {
  const def = getZodDef(schema);
  const discriminator = getDiscriminator(schema);
  if (isZodV3Schema(schema) && def.optionsMap) {
    return [...def.optionsMap.keys()];
  }
  const options = getUnionOptions(schema);
  return options.map((option) => {
    const shape = getObjectShape(option);
    const discriminatorSchema = shape[discriminator];
    return getLiteralValue(discriminatorSchema);
  });
};
var getDiscriminatedOption = (schema, discriminatorValue) => {
  const def = getZodDef(schema);
  const discriminator = getDiscriminator(schema);
  if (isZodV3Schema(schema) && def.optionsMap) {
    return def.optionsMap.get(discriminatorValue);
  }
  const options = getUnionOptions(schema);
  return options.find((option) => {
    const shape = getObjectShape(option);
    const discriminatorSchema = shape[discriminator];
    return getLiteralValue(discriminatorSchema) === discriminatorValue;
  });
};
var getIntersectionSchemas = (schema) => {
  const def = getZodDef(schema);
  return { left: def.left, right: def.right };
};
var getTupleItems = (schema) => {
  return getZodDef(schema).items;
};
var getRecordValueType = (schema) => {
  return getZodDef(schema).valueType;
};
var getRecordKeyType = (schema) => {
  return getZodDef(schema).keyType;
};
var getPipelineOutput = (schema) => {
  return getZodDef(schema).out;
};
var getPipelineInput = (schema) => {
  return getZodDef(schema).in;
};
var getBrandedInner = (schema) => {
  return isZodV3Schema(schema) ? getZodDef(schema).type : schema;
};

// src/helpers/timeline-layout.ts
var TIMELINE_PADDING = 16;
var TIMELINE_BORDER = 1;
var TIMELINE_ITEM_BORDER_BOTTOM = 1;
var TIMELINE_TRACK_EXPANDED_HEIGHT = 100;
var SCHEMA_FIELD_ROW_HEIGHT = 26;
var UNSUPPORTED_FIELD_ROW_HEIGHT = 26;
var SUPPORTED_SCHEMA_TYPES = new Set([
  "number",
  "string",
  "boolean",
  "enum",
  "date",
  "array",
  "object",
  "optional",
  "nullable",
  "default"
]);
var getSchemaFields = (controls) => {
  if (!controls) {
    return null;
  }
  const shape = getObjectShape(controls.schema);
  return Object.entries(shape).map(([key, fieldSchema]) => {
    const typeName = getZodSchemaType(fieldSchema);
    const supported = SUPPORTED_SCHEMA_TYPES.has(typeName);
    return {
      key,
      typeName,
      supported,
      rowHeight: supported ? SCHEMA_FIELD_ROW_HEIGHT : UNSUPPORTED_FIELD_ROW_HEIGHT,
      currentValue: controls.currentValue[key],
      fieldSchema
    };
  });
};
var getExpandedTrackHeight = (controls) => {
  const fields = getSchemaFields(controls);
  if (!fields || fields.length === 0) {
    return TIMELINE_TRACK_EXPANDED_HEIGHT;
  }
  return fields.reduce((sum, f) => sum + f.rowHeight, 0);
};
var getTimelineLayerHeight = (type) => {
  if (type === "video") {
    return 50;
  }
  return 25;
};

// src/components/Timeline/timeline-refs.ts

var sliderAreaRef = react__WEBPACK_IMPORTED_MODULE_0__.createRef();
var scrollableRef = react__WEBPACK_IMPORTED_MODULE_0__.createRef();
var timelineVerticalScroll = react__WEBPACK_IMPORTED_MODULE_0__.createRef();

// src/components/Timeline/TimelineSlider.tsx



// src/helpers/get-left-of-timeline-slider.ts
var getXPositionOfItemInTimelineImperatively = (frame, duration, width) => {
  const proportion = frame / (duration - 1);
  return proportion * (width - TIMELINE_PADDING * 2) + TIMELINE_PADDING;
};

// src/components/Timeline/TimelineSliderHandle.tsx

var container = {
  width: 20,
  height: 20,
  position: "fixed",
  marginLeft: -8
};
var TimelineSliderHandle = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: container,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      width: 17,
      viewBox: "0 0 159 212",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        d: "M17.0234375,1.07763419 L143.355469,1.07763419 C151.63974,1.07763419 158.355469,7.79336295 158.355469,16.0776342 L158.355469,69.390507 C158.355469,73.7938677 156.420655,77.9748242 153.064021,80.8248415 L89.3980057,134.881757 C83.7986799,139.635978 75.5802263,139.635978 69.9809005,134.881757 L6.66764807,81.1243622 C3.0872392,78.0843437 1.0234375,73.6246568 1.0234375,68.9277387 L1.0234375,17.0776342 C1.0234375,8.2410782 8.1868815,1.07763419 17.0234375,1.07763419 Z",
        fill: "#f02c00"
      })
    })
  });
};

// src/components/Timeline/TimelineWidthProvider.tsx



var TimelineWidthContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)(null);
var TimelineWidthProvider = ({ children }) => {
  const size = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.useElementSize(sliderAreaRef, {
    triggerOnWindowResize: false,
    shouldApplyCssTransforms: true
  });
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineWidthContext.Provider, {
    value: size?.width ?? null,
    children
  });
};

// src/components/Timeline/TimelineSlider.tsx

var container2 = {
  position: "absolute",
  bottom: 0,
  top: 0,
  pointerEvents: "none"
};
var line = {
  height: "100vh",
  width: 1,
  position: "fixed",
  backgroundColor: "#f02c00"
};
var redrawTimelineSliderFast = (0,react__WEBPACK_IMPORTED_MODULE_0__.createRef)();
var TimelineSlider = () => {
  const videoConfig = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useUnsafeVideoConfig();
  const timelineWidth = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(TimelineWidthContext);
  if (videoConfig === null || timelineWidth === null) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Inner, {});
};
var Inner = () => {
  const videoConfig = (0,remotion__WEBPACK_IMPORTED_MODULE_2__.useVideoConfig)();
  const timelinePosition = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.Timeline.useTimelinePosition();
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const timelineWidth = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(TimelineWidthContext);
  if (timelineWidth === null) {
    throw new Error("Unexpectedly did not have timeline width");
  }
  const style = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const left = getXPositionOfItemInTimelineImperatively(timelinePosition, videoConfig.durationInFrames, timelineWidth);
    return {
      ...container2,
      transform: `translateX(${left}px)`
    };
  }, [timelinePosition, videoConfig.durationInFrames, timelineWidth]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(redrawTimelineSliderFast, () => {
    return {
      draw: (frame, width) => {
        const { current } = ref;
        if (!current) {
          throw new Error("unexpectedly did not have ref to timelineslider");
        }
        current.style.transform = `translateX(${getXPositionOfItemInTimelineImperatively(frame, getCurrentDuration(), width ?? sliderAreaRef.current?.clientWidth ?? 0)}px)`;
      }
    };
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const currentRef = ref.current;
    if (!currentRef) {
      return;
    }
    const { current } = timelineVerticalScroll;
    if (!current) {
      return;
    }
    const onScroll = () => {
      currentRef.style.top = current.scrollTop + "px";
    };
    current.addEventListener("scroll", onScroll);
    return () => {
      current.removeEventListener("scroll", onScroll);
    };
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    ref,
    style,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: line
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineSliderHandle, {})
    ]
  });
};

// src/components/Timeline/timeline-scroll-logic.ts
var canScrollTimelineIntoDirection = () => {
  const current = scrollableRef.current;
  const { scrollWidth, scrollLeft, clientWidth } = current;
  const canScrollRight = scrollWidth - scrollLeft - clientWidth > TIMELINE_PADDING;
  const canScrollLeft = scrollLeft > TIMELINE_PADDING;
  return { canScrollRight, canScrollLeft };
};
var SCROLL_INCREMENT = 200;
var calculateFrameWhileScrollingRight = ({
  durationInFrames,
  width,
  scrollLeft
}) => {
  return getFrameFromX({
    clientX: scrollLeft,
    durationInFrames,
    width,
    extrapolate: "clamp"
  }) + Math.ceil((scrollableRef.current?.clientWidth - TIMELINE_PADDING) / getFrameIncrement(durationInFrames));
};
var getFrameWhileScrollingLeft = ({
  durationInFrames,
  width
}) => {
  const nextFrame = getFrameFromX({
    clientX: scrollableRef.current?.scrollLeft - SCROLL_INCREMENT,
    durationInFrames,
    width,
    extrapolate: "clamp"
  });
  const currentFrame2 = getFrameFromX({
    clientX: scrollableRef.current?.scrollLeft,
    durationInFrames,
    width,
    extrapolate: "clamp"
  });
  return Math.max(0, Math.min(currentFrame2 - 1, nextFrame));
};
var isCursorInViewport = ({
  frame,
  durationInFrames
}) => {
  const width = scrollableRef.current?.scrollWidth ?? 0;
  const scrollLeft = scrollableRef.current?.scrollLeft ?? 0;
  const scrollPosOnRightEdge = getScrollPositionForCursorOnRightEdge({
    nextFrame: frame,
    durationInFrames
  });
  const scrollPosOnLeftEdge = getScrollPositionForCursorOnLeftEdge({
    nextFrame: frame,
    durationInFrames
  });
  const currentFrameRight = calculateFrameWhileScrollingRight({
    durationInFrames,
    scrollLeft,
    width
  });
  return !(scrollPosOnRightEdge >= getScrollPositionForCursorOnRightEdge({
    nextFrame: currentFrameRight,
    durationInFrames
  }) || scrollPosOnLeftEdge < scrollLeft);
};
var ensureFrameIsInViewport = ({
  direction,
  durationInFrames,
  frame
}) => {
  redrawTimelineSliderFast.current?.draw(frame);
  const width = scrollableRef.current?.scrollWidth ?? 0;
  const scrollLeft = scrollableRef.current?.scrollLeft ?? 0;
  if (direction === "fit-left") {
    const currentFrameLeft = getFrameFromX({
      clientX: scrollLeft,
      durationInFrames,
      width,
      extrapolate: "clamp"
    });
    const scrollPos = getScrollPositionForCursorOnLeftEdge({
      nextFrame: frame,
      durationInFrames
    });
    const needsToScrollLeft = scrollPos <= getScrollPositionForCursorOnLeftEdge({
      nextFrame: currentFrameLeft,
      durationInFrames
    });
    if (needsToScrollLeft) {
      scrollToTimelineXOffset(scrollPos);
    }
  }
  if (direction === "fit-right") {
    const currentFrameRight = calculateFrameWhileScrollingRight({
      durationInFrames,
      scrollLeft,
      width
    });
    const scrollPos = getScrollPositionForCursorOnRightEdge({
      nextFrame: frame,
      durationInFrames
    });
    const needsToScrollRight = scrollPos >= getScrollPositionForCursorOnRightEdge({
      nextFrame: currentFrameRight,
      durationInFrames
    });
    if (needsToScrollRight) {
      scrollToTimelineXOffset(scrollPos);
    }
  }
  if (direction === "page-right" || direction === "page-left") {
    if (!isCursorInViewport({ frame, durationInFrames })) {
      scrollToTimelineXOffset(direction === "page-left" ? getScrollPositionForCursorOnRightEdge({
        nextFrame: frame,
        durationInFrames
      }) : getScrollPositionForCursorOnLeftEdge({
        nextFrame: frame,
        durationInFrames
      }));
    }
  }
  if (direction === "center") {
    const scrollPosOnRightEdge = getScrollPositionForCursorOnRightEdge({
      nextFrame: frame,
      durationInFrames
    });
    const scrollPosOnLeftEdge = getScrollPositionForCursorOnLeftEdge({
      nextFrame: frame,
      durationInFrames
    });
    scrollToTimelineXOffset((scrollPosOnLeftEdge + scrollPosOnRightEdge) / 2);
  }
};
var scrollToTimelineXOffset = (scrollPos) => {
  scrollableRef.current?.scroll({
    left: scrollPos
  });
};
var getScrollPositionForCursorOnLeftEdge = ({
  nextFrame,
  durationInFrames
}) => {
  const frameIncrement = getFrameIncrement(durationInFrames);
  const scrollPos = frameIncrement * nextFrame;
  return scrollPos;
};
var getScrollPositionForCursorOnRightEdge = ({
  nextFrame,
  durationInFrames
}) => {
  const frameIncrement = getFrameIncrement(durationInFrames);
  const framesRemaining = durationInFrames - 1 - nextFrame;
  const fromRight = framesRemaining * frameIncrement + TIMELINE_PADDING;
  const scrollPos = scrollableRef.current?.scrollWidth - fromRight - scrollableRef.current?.clientWidth + TIMELINE_PADDING + 4;
  return scrollPos;
};
var getFrameIncrement = (durationInFrames) => {
  const width = scrollableRef.current?.scrollWidth ?? 0;
  return getFrameIncrementFromWidth(durationInFrames, width);
};
var getFrameIncrementFromWidth = (durationInFrames, width) => {
  return (width - TIMELINE_PADDING * 2) / (durationInFrames - 1);
};
var getFrameWhileScrollingRight = ({
  durationInFrames,
  width
}) => {
  const nextFrame = calculateFrameWhileScrollingRight({
    durationInFrames,
    width,
    scrollLeft: scrollableRef.current?.scrollLeft + SCROLL_INCREMENT
  });
  const currentFrame2 = calculateFrameWhileScrollingRight({
    durationInFrames,
    width,
    scrollLeft: scrollableRef.current?.scrollLeft
  });
  return Math.min(durationInFrames - 1, Math.max(nextFrame, currentFrame2 + 1));
};
var getFrameFromX = ({
  clientX,
  durationInFrames,
  width,
  extrapolate
}) => {
  const pos = clientX - TIMELINE_PADDING;
  const frame = Math.round((0,remotion__WEBPACK_IMPORTED_MODULE_2__.interpolate)(pos, [0, width - TIMELINE_PADDING * 2], [0, durationInFrames - 1], {
    extrapolateLeft: extrapolate,
    extrapolateRight: extrapolate
  }));
  return frame;
};
var zoomAndPreserveCursor = ({
  oldZoom,
  newZoom,
  currentFrame: currentFrame2,
  currentDurationInFrames
}) => {
  const ratio = newZoom / oldZoom;
  if (ratio === 1) {
    return;
  }
  const { current } = scrollableRef;
  if (!current) {
    return;
  }
  const frameIncrement = getFrameIncrement(currentDurationInFrames);
  const prevCursorPosition = frameIncrement * currentFrame2 + TIMELINE_PADDING;
  const newCursorPosition = ratio * (prevCursorPosition - TIMELINE_PADDING) + TIMELINE_PADDING;
  current.scrollLeft += newCursorPosition - prevCursorPosition;
  redrawTimelineSliderFast.current?.draw(currentFrame2, (scrollableRef.current?.clientWidth ?? 0) * ratio);
};

// src/components/ZoomPersistor.tsx



// src/helpers/url-state.ts
var getUrlHandlingType = () => {
  if (window.remotion_isReadOnlyStudio) {
    return "query-string";
  }
  return "spa";
};
var pushUrl = (url) => {
  if (getUrlHandlingType() === "query-string") {
    window.history.pushState({}, "Studio", `${window.location.pathname}?${url}`);
  } else {
    window.history.pushState({}, "Studio", url);
  }
};
var clearUrl = () => {
  window.location.href = window.location.pathname;
};
var reloadUrl = () => {
  window.location.reload();
};
var getRoute = () => {
  if (getUrlHandlingType() === "query-string") {
    return window.location.search.substring(1);
  }
  return window.location.pathname;
};

// src/components/load-canvas-content-from-url.ts
var deriveCanvasContentFromUrl = () => {
  const route = getRoute();
  const substrings = route.split("/").filter(Boolean);
  const lastPart = substrings[substrings.length - 1];
  if (substrings[0] === "assets") {
    return {
      type: "asset",
      asset: decodeURIComponent(route.substring("/assets/".length))
    };
  }
  if (substrings[0] === "outputs") {
    return {
      type: "output",
      path: decodeURIComponent(route.substring("/outputs/".length))
    };
  }
  if (lastPart) {
    return {
      type: "composition",
      compositionId: decodeURIComponent(lastPart)
    };
  }
  return null;
};

// src/components/ZoomPersistor.tsx
var makeKey = () => {
  return `remotion.zoom-map`;
};
var persistCurrentZoom = (zoom) => {
  localStorage.setItem(makeKey(), JSON.stringify(zoom));
};
var getZoomFromLocalStorage = () => {
  const zoom = localStorage.getItem(makeKey());
  return zoom ? JSON.parse(zoom) : {};
};
var ZoomPersistor = () => {
  const [playing] = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.Timeline.usePlayingState();
  const { zoom } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(TimelineZoomCtx);
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const urlState = deriveCanvasContentFromUrl();
  const isActive = urlState && urlState.type === "composition" && canvasContent && canvasContent.type === "composition" && urlState.compositionId === canvasContent.compositionId;
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!isActive) {
      return;
    }
    persistCurrentZoom(zoom);
  }, [zoom, isActive, playing, urlState]);
  return null;
};

// src/state/timeline-zoom.tsx

var TIMELINE_MIN_ZOOM = 1;
var TIMELINE_MAX_ZOOM = 5;
var TimelineZoomCtx = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  zoom: {},
  setZoom: () => {
    throw new Error("has no context");
  }
});
var TimelineZoomContext = ({ children }) => {
  const [zoom, setZoom] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => getZoomFromLocalStorage());
  const value = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      zoom,
      setZoom: (compositionId, callback) => {
        setZoom((prevZoomMap) => {
          const newZoomWithFloatingPointErrors = Math.min(TIMELINE_MAX_ZOOM, Math.max(TIMELINE_MIN_ZOOM, callback(prevZoomMap[compositionId] ?? TIMELINE_MIN_ZOOM)));
          const newZoom = Math.round(newZoomWithFloatingPointErrors * 10) / 10;
          zoomAndPreserveCursor({
            oldZoom: prevZoomMap[compositionId] ?? TIMELINE_MIN_ZOOM,
            newZoom,
            currentDurationInFrames: getCurrentDuration(),
            currentFrame: getCurrentFrame()
          });
          return { ...prevZoomMap, [compositionId]: newZoom };
        });
      }
    };
  }, [zoom]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineZoomCtx.Provider, {
    value,
    children
  });
};

// src/state/z-index.tsx


// src/helpers/use-keybinding.ts


// src/state/keybindings.tsx


var KeybindingContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  registerKeybinding: () => {
    throw new Error("Has no keybinding context");
  },
  unregisterKeybinding: () => {
    return;
  },
  unregisterPane: () => {
    return;
  }
});
var KeybindingContextProvider = ({ children }) => {
  const registered = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)([]);
  const registerKeybinding = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((binding) => {
    registered.current = [...registered.current, binding];
    window.addEventListener(binding.event, binding.callback);
  }, []);
  const unregisterKeybinding = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((binding) => {
    registered.current = registered.current.filter((r) => {
      if (r.id === binding.id) {
        window.removeEventListener(binding.event, binding.callback);
        return false;
      }
      return true;
    });
  }, []);
  const unregisterPane = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((paneId) => {
    const matchedKeybindings = registered.current.filter((r) => r.registeredFromPane === paneId);
    for (const matched of matchedKeybindings) {
      unregisterKeybinding(matched);
    }
  }, [unregisterKeybinding]);
  const value = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      registerKeybinding,
      unregisterKeybinding,
      unregisterPane
    };
  }, [registerKeybinding, unregisterKeybinding, unregisterPane]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(KeybindingContext.Provider, {
    value,
    children
  });
};

// src/helpers/use-keybinding.ts
if (false) // removed by dead control flow
{}
var areKeyboardShortcutsDisabled = () => {
  return !true;
};
var useKeybinding = () => {
  const [paneId] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => String(Math.random()));
  const context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(KeybindingContext);
  const { isHighestContext } = useZIndex();
  const registerKeybinding = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((options) => {
    if (false) // removed by dead control flow
{}
    if (!isHighestContext && !options.keepRegisteredWhenNotHighestContext) {
      return {
        unregister: () => {
          return;
        }
      };
    }
    const listener = (e) => {
      const commandKey = window.navigator.platform.startsWith("Mac") ? e.metaKey : e.ctrlKey;
      if (!e.key) {
        return;
      }
      if (e.key.toLowerCase() === options.key.toLowerCase() && options.commandCtrlKey === commandKey) {
        if (!options.triggerIfInputFieldFocused) {
          const { activeElement } = document;
          if (activeElement instanceof HTMLInputElement) {
            return;
          }
          if (activeElement instanceof HTMLTextAreaElement) {
            return;
          }
        }
        options.callback(e);
        if (options.preventDefault) {
          e.preventDefault();
        }
      }
    };
    const toRegister = {
      registeredFromPane: paneId,
      event: options.event,
      key: options.key,
      callback: listener,
      id: String(Math.random())
    };
    context.registerKeybinding(toRegister);
    return {
      unregister: () => context.unregisterKeybinding(toRegister)
    };
  }, [context, isHighestContext, paneId]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    return () => {
      context.unregisterPane(paneId);
    };
  }, [context, paneId]);
  return (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => ({ registerKeybinding, isHighestContext }), [registerKeybinding, isHighestContext]);
};

// src/state/highest-z-index.tsx


var HighestZIndexContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  highestIndex: 0,
  registerZIndex: () => {
    return;
  },
  unregisterZIndex: () => {
    return;
  }
});
var HighestZIndexProvider = ({ children }) => {
  const [zIndexes, setZIndexes] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]);
  const registerZIndex = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newIndex) => {
    setZIndexes((prev) => [...prev, newIndex]);
  }, []);
  const unregisterZIndex = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newIndex) => {
    setZIndexes((prev) => {
      const index = prev.indexOf(newIndex);
      if (index === -1) {
        throw new Error("did not find z-index " + newIndex);
      }
      return prev.filter((_n, i) => i !== index);
    });
  }, []);
  const highestIndex = Math.max(...zIndexes);
  const value = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      highestIndex,
      registerZIndex,
      unregisterZIndex
    };
  }, [registerZIndex, unregisterZIndex, highestIndex]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(HighestZIndexContext.Provider, {
    value,
    children
  });
};

// src/state/input-dragger-click-lock.ts
var clickLock = false;
var getClickLock = () => clickLock;
var setClickLock = (lock) => {
  clickLock = lock;
};

// src/state/z-index.tsx

var ZIndexContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  currentIndex: 0
});
var margin = {
  margin: "auto"
};
var EscapeHook = ({ onEscape }) => {
  const keybindings = useKeybinding();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const escape = keybindings.registerKeybinding({
      event: "keydown",
      key: "Escape",
      callback: onEscape,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: true,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      escape.unregister();
    };
  }, [keybindings, onEscape]);
  return null;
};
var HigherZIndex = ({ children, onEscape, onOutsideClick, disabled }) => {
  const context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ZIndexContext);
  const highestContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(HighestZIndexContext);
  const containerRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const currentIndex = disabled ? context.currentIndex : context.currentIndex + 1;
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (disabled) {
      return;
    }
    highestContext.registerZIndex(currentIndex);
    return () => highestContext.unregisterZIndex(currentIndex);
  }, [currentIndex, highestContext, disabled]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (disabled) {
      return;
    }
    let onUp = null;
    const listener = (downEvent) => {
      const outsideClick = !containerRef.current?.contains(downEvent.target);
      if (!outsideClick) {
        return;
      }
      onUp = (upEvent) => {
        if (highestContext.highestIndex === currentIndex && !getClickLock() && document.contains(upEvent.target)) {
          upEvent.stopPropagation();
          onOutsideClick(upEvent.target);
        }
      };
      window.addEventListener("pointerup", onUp, { once: true });
    };
    requestAnimationFrame(() => {
      window.addEventListener("pointerdown", listener);
    });
    return () => {
      if (onUp) {
        window.removeEventListener("pointerup", onUp, { once: true });
      }
      onUp = null;
      return window.removeEventListener("pointerdown", listener);
    };
  }, [currentIndex, disabled, highestContext.highestIndex, onOutsideClick]);
  const value = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      currentIndex
    };
  }, [currentIndex]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(ZIndexContext.Provider, {
    value,
    children: [
      disabled ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(EscapeHook, {
        onEscape
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        ref: containerRef,
        style: margin,
        children
      })
    ]
  });
};
var useZIndex = () => {
  const context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ZIndexContext);
  const highestContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(HighestZIndexContext);
  const isHighestContext = highestContext.highestIndex === context.currentIndex;
  return (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => ({
    currentZIndex: context.currentIndex,
    highestZIndex: highestContext.highestIndex,
    isHighestContext,
    tabIndex: isHighestContext ? 0 : -1
  }), [context.currentIndex, highestContext.highestIndex, isHighestContext]);
};

// src/components/EditorContent.tsx



// src/helpers/is-current-selected-still.ts



// src/helpers/is-composition-still.ts
var isCompositionStill = (comp) => {
  if (!comp) {
    return false;
  }
  return comp.durationInFrames === 1;
};

// src/helpers/is-current-selected-still.ts
var useIsStill = () => {
  const resolved = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useResolvedVideoConfig(null);
  if (!resolved || resolved.type !== "success") {
    return false;
  }
  return isCompositionStill(resolved.result);
};
var useIsVideoComposition = () => {
  const isStill = useIsStill();
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  if (canvasContent === null) {
    return false;
  }
  if (isStill) {
    return false;
  }
  return canvasContent.type === "composition";
};

// src/components/InitialCompositionLoader.tsx



// src/helpers/mobile-layout.ts

var breakpoint = 900;
function getIsMobile() {
  return window.innerWidth < breakpoint;
}
var useMobileLayout = () => {
  const [isMobile, setIsMobile] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(getIsMobile());
  const isMobileRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(isMobile);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    function handleResize() {
      if (getIsMobile() !== isMobileRef.current) {
        setIsMobile(getIsMobile());
      }
      isMobileRef.current = getIsMobile();
    }
    window.addEventListener("resize", handleResize);
    return () => {
      return window.removeEventListener("resize", handleResize);
    };
  }, []);
  return isMobile;
};

// src/state/folders.tsx


// src/helpers/persist-open-folders.tsx

var openFolderKey = ({
  folderName,
  parentName
}) => {
  return [parentName ?? "no-parent", folderName].join("/");
};
var localStorageKey = (type) => type === "compositions" ? "remotion.expandedFolders" : "remotion.expandedAssetFolders";
var persistExpandedFolders = (type, state) => {
  window.localStorage.setItem(localStorageKey(type), JSON.stringify(state));
};
var loadExpandedFolders = (type) => {
  const item = window.localStorage.getItem(localStorageKey(type));
  if (item === null) {
    return {};
  }
  return JSON.parse(item);
};
var ExpandedFoldersContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  toggleFolder: () => {},
  foldersExpanded: {},
  setFoldersExpanded: () => {}
});

// src/state/folders.tsx

var FolderContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  compositionFoldersExpanded: {},
  setCompositionFoldersExpanded: () => {
    throw new Error("default state");
  },
  assetFoldersExpanded: {},
  setAssetFoldersExpanded: () => {
    throw new Error("default state");
  }
});
var FolderContextProvider = ({ children }) => {
  const [compositionFoldersExpanded, setCompositionFoldersExpanded] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => loadExpandedFolders("compositions"));
  const [assetFoldersExpanded, setAssetFoldersExpanded] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => loadExpandedFolders("assets"));
  const value = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      compositionFoldersExpanded,
      setCompositionFoldersExpanded,
      assetFoldersExpanded,
      setAssetFoldersExpanded
    };
  }, [assetFoldersExpanded, compositionFoldersExpanded]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FolderContext.Provider, {
    value,
    children
  });
};

// src/state/sidebar.tsx


var storageKey = (sidebar) => {
  if (sidebar === "right") {
    return "remotion.sidebarRightCollapsing";
  }
  return "remotion.sidebarCollapsing";
};
var getSavedCollapsedStateLeft = (isMobileLayout = false) => {
  const state = window.localStorage.getItem(storageKey("left"));
  if (isMobileLayout) {
    return "collapsed";
  }
  if (state === "collapsed") {
    return "collapsed";
  }
  if (state === "expanded") {
    return "expanded";
  }
  return "responsive";
};
var getSavedCollapsedStateRight = (isMobileLayout = false) => {
  const state = window.localStorage.getItem(storageKey("right"));
  if (isMobileLayout) {
    return "collapsed";
  }
  if (state === "expanded") {
    return "expanded";
  }
  return "collapsed";
};
var saveCollapsedState = (type, sidebar) => {
  window.localStorage.setItem(storageKey(sidebar), type);
};
var SidebarContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  sidebarCollapsedStateLeft: "collapsed",
  setSidebarCollapsedState: () => {
    throw new Error("sidebar collapsed state");
  },
  sidebarCollapsedStateRight: "collapsed"
});
var SidebarContextProvider = ({ children }) => {
  const isMobileLayout = useMobileLayout();
  const [sidebarCollapsedState, setSidebarCollapsedState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => ({
    left: getSavedCollapsedStateLeft(isMobileLayout),
    right: getSavedCollapsedStateRight(isMobileLayout)
  }));
  const value = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      sidebarCollapsedStateLeft: sidebarCollapsedState.left,
      sidebarCollapsedStateRight: sidebarCollapsedState.right,
      setSidebarCollapsedState: (options) => {
        const { left, right } = options;
        setSidebarCollapsedState((f) => {
          const copied = { ...f };
          if (left) {
            const updatedLeft = typeof left === "function" ? left(f.left) : left;
            saveCollapsedState(updatedLeft, "left");
            copied.left = updatedLeft;
          }
          if (right) {
            const updatedRight = typeof right === "function" ? right(f.right) : right;
            saveCollapsedState(updatedRight, "right");
            copied.right = updatedRight;
          }
          return copied;
        });
      }
    };
  }, [sidebarCollapsedState]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SidebarContext.Provider, {
    value,
    children
  });
};

// src/components/CompositionSelector.tsx



// src/helpers/create-folder-tree.ts
var buildAssetFolderStructure = (files, parentFolderName, foldersExpanded) => {
  const notInFolder = files.filter((f) => !f.name.includes("/"));
  const inFolder = files.filter((f) => f.name.includes("/"));
  const groupedByFolder = {};
  for (const item of inFolder) {
    const folderName = item.name.split("/")[0];
    if (!groupedByFolder[folderName]) {
      groupedByFolder[folderName] = [];
    }
    groupedByFolder[folderName].push(item);
  }
  return {
    files: notInFolder,
    folders: Object.keys(groupedByFolder).map((folderName) => {
      const filesInFolder = groupedByFolder[folderName];
      const filesWithoutFolderName = filesInFolder.map((f) => {
        return {
          ...f,
          name: f.name.substring(folderName.length + 1)
        };
      });
      const key = [parentFolderName, folderName].filter(Boolean).join("/");
      const isExpanded = foldersExpanded[key] ?? false;
      return {
        name: folderName,
        items: buildAssetFolderStructure(filesWithoutFolderName, [parentFolderName, folderName].filter(Boolean).join("/"), foldersExpanded),
        expanded: isExpanded
      };
    })
  };
};
var splitParentIntoNameAndParent = (name) => {
  if (name === null) {
    return {
      name: null,
      parent: null
    };
  }
  const splitted = name.split("/");
  const lastName = splitted[splitted.length - 1];
  const parentParentArray = splitted.slice(0, splitted.length - 1);
  const parentParent = parentParentArray.length === 0 ? null : parentParentArray.join("/");
  return {
    name: lastName,
    parent: parentParent
  };
};
var doesFolderExist = (items, folderName, parentName) => {
  for (const item of items) {
    if (item.type === "folder") {
      if (item.folderName === folderName && item.parentName === parentName) {
        return item.items;
      }
      const found = doesFolderExist(item.items, folderName, parentName);
      if (found !== false) {
        return found;
      }
    }
  }
  return false;
};
var findItemListToPush = (items, folderName, parentName) => {
  if (folderName === null) {
    return items;
  }
  const folder = doesFolderExist(items, folderName, parentName);
  if (!folder) {
    console.log({ items, folderName, parentName });
    throw new Error("did not find folder " + folderName);
  }
  return folder;
};
var createFolderIfDoesNotExist = (items, availableFolders, folderItem, foldersExpanded) => {
  if (doesFolderExist(items, folderItem.name, folderItem.parent)) {
    return;
  }
  const splitted = splitParentIntoNameAndParent(folderItem.parent);
  if (folderItem.parent) {
    const parent = availableFolders.find((f) => f.name === splitted.name && f.parent === splitted.parent);
    if (!parent) {
      throw new Error("unexpectedly did not have parent");
    }
    createFolderIfDoesNotExist(items, availableFolders, parent, foldersExpanded);
  }
  const itemList = findItemListToPush(items, splitted.name, splitted.parent);
  if (!itemList) {
    throw new Error("why did folder not exist? " + folderItem.name);
  }
  itemList.push({
    type: "folder",
    folderName: folderItem.name,
    items: [],
    key: folderItem.name,
    expanded: foldersExpanded[openFolderKey({
      folderName: folderItem.name,
      parentName: folderItem.parent
    })] ?? false,
    parentName: folderItem.parent
  });
};
var createFolderTree = (comps, folders, foldersExpanded) => {
  const items = [];
  const uniqueFolderKeys = [];
  for (const folder of folders) {
    const folderKey = openFolderKey({
      folderName: folder.name,
      parentName: folder.parent
    });
    if (uniqueFolderKeys.includes(folderKey)) {
      if (folder.parent) {
        throw new Error(`Multiple folders with the name ${folder.name} inside the folder ${folder.parent} exist. Folder names must be unique.`);
      }
      throw new Error("Multiple folders with the name " + folder.name + " exist. Folder names must be unique.");
    }
    uniqueFolderKeys.push(folderKey);
    createFolderIfDoesNotExist(items, folders, folder, foldersExpanded);
  }
  for (const item of comps) {
    const toPush = {
      type: "composition",
      composition: item,
      key: item.id
    };
    const list = findItemListToPush(items, item.folderName, item.parentFolderName);
    list.push(toPush);
  }
  return items;
};

// src/components/CompositionSelectorItem.tsx


// src/icons/folder.tsx

var CollapsedFolderIcon = ({ color, ...props }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    viewBox: "0 0 512 512",
    ...props,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: color,
      d: "M447.1 96H272L226.7 50.75C214.7 38.74 198.5 32 181.5 32H63.1c-35.35 0-64 28.65-64 64v320c0 35.35 28.65 64 64 64h384c35.35 0 64-28.65 64-64V160C511.1 124.7 483.3 96 447.1 96zM480 416c0 17.64-14.36 32-32 32H64c-17.64 0-32-14.36-32-32V96c0-17.64 14.36-32 32-32h117.5c8.549 0 16.58 3.328 22.63 9.375L258.7 128H448c17.64 0 32 14.36 32 32V416z"
    })
  });
};
var ExpandedFolderIcon = ({ color, ...props }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    viewBox: "0 0 576 512",
    ...props,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: color,
      d: "M566.6 211.6C557.5 199.1 543.4 192 527.1 192H134.2C114.3 192 96.2 204.5 89.23 223.1L32 375.8V96c0-17.64 14.36-32 32-32h117.5c8.549 0 16.58 3.328 22.63 9.375L258.7 128H448c17.64 0 32 14.36 32 32h32c0-35.35-28.65-64-64-64H272L226.7 50.75C214.7 38.74 198.5 32 181.5 32H64C28.65 32 0 60.65 0 96v320c0 35.35 28.65 64 64 64h403.1c21.11 0 39.53-13.53 45.81-33.69l60-192C578.4 239.6 575.8 224 566.6 211.6zM543.2 244.8l-60 192C481.1 443.5 475 448 467.1 448H64c-3.322 0-6.357-.9551-9.373-1.898c-2.184-1.17-4.109-2.832-5.596-4.977c-3.031-4.375-3.703-9.75-1.828-14.73l72-192C121.5 228.2 127.5 224 134.2 224h393.8c5.141 0 9.844 2.375 12.89 6.516C543.9 234.7 544.8 239.9 543.2 244.8z"
    })
  });
};
var ExpandedFolderIconSolid = ({ color, ...props }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    viewBox: "0 0 576 512",
    ...props,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: color,
      d: "M384 480h48c11.4 0 21.9-6 27.6-15.9l112-192c5.8-9.9 5.8-22.1 .1-32.1S555.5 224 544 224H144c-11.4 0-21.9 6-27.6 15.9L48 357.1V96c0-8.8 7.2-16 16-16H181.5c4.2 0 8.3 1.7 11.3 4.7l26.5 26.5c21 21 49.5 32.8 79.2 32.8H416c8.8 0 16 7.2 16 16v32h48V160c0-35.3-28.7-64-64-64H298.5c-17 0-33.3-6.7-45.3-18.7L226.7 50.7c-12-12-28.3-18.7-45.3-18.7H64C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H87.7 384z"
    })
  });
};

// src/icons/still.tsx

var StillIcon = ({ color, ...props }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    ...props,
    viewBox: "0 0 512 512",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: color,
      d: "M144 288C144 226.1 194.1 176 256 176C317.9 176 368 226.1 368 288C368 349.9 317.9 400 256 400C194.1 400 144 349.9 144 288zM256 208C211.8 208 176 243.8 176 288C176 332.2 211.8 368 256 368C300.2 368 336 332.2 336 288C336 243.8 300.2 208 256 208zM362.9 64.82L373.3 96H448C483.3 96 512 124.7 512 160V416C512 451.3 483.3 480 448 480H64C28.65 480 0 451.3 0 416V160C0 124.7 28.65 96 64 96H138.7L149.1 64.82C155.6 45.22 173.9 32 194.6 32H317.4C338.1 32 356.4 45.22 362.9 64.82H362.9zM64 128C46.33 128 32 142.3 32 160V416C32 433.7 46.33 448 64 448H448C465.7 448 480 433.7 480 416V160C480 142.3 465.7 128 448 128H350.3L332.6 74.94C330.4 68.41 324.3 64 317.4 64H194.6C187.7 64 181.6 68.41 179.4 74.94L161.7 128H64z"
    })
  });
};

// src/icons/video.tsx

var FilmIcon = ({ color, ...props }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    ...props,
    xmlns: "http://www.w3.org/2000/svg",
    viewBox: "0 0 512 512",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: color,
      d: "M448 32H64C28.65 32 0 60.65 0 96v320c0 35.35 28.65 64 64 64h384c35.35 0 64-28.65 64-64V96C512 60.65 483.3 32 448 32zM384 64v176H128V64H384zM32 96c0-17.64 14.36-32 32-32h32v80H32V96zM32 176h64v64H32V176zM32 272h64v64H32V272zM64 448c-17.64 0-32-14.36-32-32v-48h64V448H64zM128 448V272h256V448H128zM480 416c0 17.64-14.36 32-32 32h-32v-80h64V416zM480 336h-64v-64h64V336zM480 240h-64v-64h64V240zM480 144h-64V64h32c17.64 0 32 14.36 32 32V144z"
    })
  });
};

// src/state/modals.ts

var ModalsContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  selectedModal: null,
  setSelectedModal: () => {
    return;
  }
});

// src/components/CompositionContextButton.tsx


// src/helpers/client-id.tsx



// src/components/Notifications/NotificationCenter.tsx


// src/components/Notifications/Notification.tsx


var notification = {
  backgroundColor: "#111111",
  color: "white",
  fontFamily: "Arial, Helvetica, sans-serif",
  display: "inline-flex",
  padding: "8px 14px",
  borderRadius: 4,
  fontSize: 15,
  border: "0.25px solid rgba(255, 255, 255, 0.1)",
  boxShadow: "0 2px 3px rgba(0, 0, 0, 1)",
  marginTop: 3,
  marginBottom: 3,
  alignItems: "center"
};
var Notification = ({ children, id, duration, created, onRemove }) => {
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (duration === null) {
      return;
    }
    const timeout = setTimeout(() => {
      onRemove(id);
    }, duration - (Date.now() - created));
    return () => {
      clearTimeout(timeout);
    };
  }, [created, duration, id, onRemove]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    className: "css-reset",
    style: notification,
    children
  });
};

// src/components/Notifications/NotificationCenter.tsx

var container3 = {
  position: "absolute",
  justifyContent: "center",
  alignItems: "center",
  display: "flex",
  width: "100%",
  flexDirection: "column",
  paddingTop: 20,
  pointerEvents: "none",
  backgroundColor: "transparent"
};
var notificationCenter = (0,react__WEBPACK_IMPORTED_MODULE_0__.createRef)();
var showNotification = (content, durationInMs) => {
  return notificationCenter.current.addNotification({
    content,
    duration: durationInMs,
    created: Date.now(),
    id: String(Math.random()).replace("0.", "")
  });
};
var NotificationCenter = () => {
  const [notifications, setNotifications] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)([]);
  const onRemove = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((id) => {
    setNotifications((not) => {
      return not.filter((n) => n.id !== id);
    });
  }, []);
  const addNotification = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((notification2) => {
    setNotifications((previousNotifications) => {
      return [...previousNotifications, notification2];
    });
    return {
      replaceContent: (newContent, durationInMs) => {
        setNotifications((oldNotifications) => {
          return oldNotifications.map((notificationToMap) => {
            if (notificationToMap.id === notification2.id) {
              return {
                ...notificationToMap,
                duration: durationInMs,
                content: newContent,
                created: Date.now()
              };
            }
            return notificationToMap;
          });
        });
      }
    };
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(notificationCenter, () => {
    return {
      addNotification
    };
  }, [addNotification]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: container3,
    children: notifications.map((n) => {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Notification, {
        created: n.created,
        duration: n.duration,
        id: n.id,
        onRemove,
        children: n.content
      }, n.id);
    })
  });
};

// src/components/PlayBeepSound.tsx
var beeped = {};
var playBeepSound = async (renderId) => {
  if (beeped[renderId]) {
    return;
  }
  beeped[renderId] = true;
  const beepAudio = new Audio("/beep.wav");
  try {
    await beepAudio.play();
  } catch (error) {
    console.error("Error playing beep sound:", error);
    throw error;
  }
};
var PlayBeepSound_default = playBeepSound;

// src/components/RenderQueue/context.tsx


// src/components/RenderQueue/client-render-queue.ts
var compositionRegistry = new Map;
var registerCompositionForJob = (jobId, compositionRef) => {
  compositionRegistry.set(jobId, compositionRef);
};
var getCompositionForJob = (jobId) => {
  return compositionRegistry.get(jobId);
};
var cleanupCompositionForJob = (jobId) => {
  compositionRegistry.delete(jobId);
};
var generateJobId = () => {
  return `client-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`;
};
var clientJobAbortControllers = new Map;
var getAbortController = (jobId) => {
  let controller = clientJobAbortControllers.get(jobId);
  if (!controller) {
    controller = new AbortController;
    clientJobAbortControllers.set(jobId, controller);
  }
  return controller;
};
var deleteAbortController = (jobId) => {
  clientJobAbortControllers.delete(jobId);
};
var cancelAbortController = (jobId) => {
  const controller = clientJobAbortControllers.get(jobId);
  if (controller) {
    controller.abort();
  }
};

// src/components/RenderQueue/context.tsx

var restorePersistedClientRenders = () => {
  const persisted = window.remotion_initialClientRenders ?? [];
  return persisted.map((r) => ({ ...r, status: "done" }));
};
var isClientRenderJob = (job) => {
  return job.type === "client-still" || job.type === "client-video";
};
var noopString = () => "";
var noop2 = () => {
  return;
};
var RenderQueueContext = react__WEBPACK_IMPORTED_MODULE_0__.createContext({
  jobs: [],
  serverJobs: [],
  clientJobs: [],
  addClientStillJob: noopString,
  addClientVideoJob: noopString,
  updateClientJobProgress: noop2,
  markClientJobSaving: noop2,
  markClientJobDone: noop2,
  markClientJobFailed: noop2,
  markClientJobCancelled: noop2,
  removeClientJob: noop2,
  cancelClientJob: noop2,
  setProcessJobCallback: noop2,
  getAbortController: () => new AbortController,
  getCompositionForJob: () => {
    return;
  }
});
var renderJobsRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.createRef)();
var RenderQueueContextProvider = ({ children }) => {
  const [serverJobs, setServerJobs] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(window.remotion_initialRenderQueue ?? []);
  const [clientJobs, setClientJobs] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(restorePersistedClientRenders);
  const [currentlyProcessing, setCurrentlyProcessing] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const processJobCallbackRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (currentlyProcessing) {
      return;
    }
    const nextJob = clientJobs.find((job) => job.status === "idle");
    if (!nextJob || !processJobCallbackRef.current) {
      return;
    }
    setCurrentlyProcessing(nextJob.id);
    setClientJobs((prev) => prev.map((job) => job.id === nextJob.id ? {
      ...job,
      status: "running",
      progress: { encodedFrames: 0, totalFrames: 0 }
    } : job));
    processJobCallbackRef.current(nextJob);
  }, [clientJobs, currentlyProcessing]);
  const addClientStillJob = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((params, compositionRef) => {
    const id = generateJobId();
    registerCompositionForJob(id, compositionRef);
    const newJob = {
      ...params,
      id,
      startedAt: Date.now(),
      status: "idle"
    };
    setClientJobs((prev) => [...prev, newJob]);
    return id;
  }, []);
  const addClientVideoJob = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((params, compositionRef) => {
    const id = generateJobId();
    registerCompositionForJob(id, compositionRef);
    const newJob = {
      ...params,
      id,
      startedAt: Date.now(),
      status: "idle"
    };
    setClientJobs((prev) => [...prev, newJob]);
    return id;
  }, []);
  const updateClientJobProgress = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((jobId, progress) => {
    setClientJobs((prev) => prev.map((job) => job.id === jobId ? { ...job, status: "running", progress } : job));
  }, []);
  const markClientJobSaving = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((jobId) => {
    setClientJobs((prev) => prev.map((job) => job.id === jobId ? { ...job, status: "saving" } : job));
  }, []);
  const markClientJobDone = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((jobId, metadata, getBlob) => {
    deleteAbortController(jobId);
    cleanupCompositionForJob(jobId);
    setClientJobs((prev) => prev.map((job) => job.id === jobId ? { ...job, status: "done", metadata, getBlob } : job));
    setCurrentlyProcessing(null);
  }, []);
  const markClientJobFailed = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((jobId, error) => {
    deleteAbortController(jobId);
    cleanupCompositionForJob(jobId);
    setClientJobs((prev) => prev.map((job) => job.id === jobId ? {
      ...job,
      status: "failed",
      error: { message: error.message, stack: error.stack }
    } : job));
    setCurrentlyProcessing(null);
  }, []);
  const markClientJobCancelled = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((jobId) => {
    deleteAbortController(jobId);
    cleanupCompositionForJob(jobId);
    setClientJobs((prev) => prev.map((job) => job.id === jobId ? {
      ...job,
      status: "cancelled"
    } : job));
    setCurrentlyProcessing(null);
  }, []);
  const removeClientJob = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((jobId) => {
    setClientJobs((prev) => {
      const jobToRemove = prev.find((j) => j.id === jobId);
      if (jobToRemove?.status === "running") {
        return prev;
      }
      deleteAbortController(jobId);
      cleanupCompositionForJob(jobId);
      return prev.filter((job) => job.id !== jobId);
    });
  }, []);
  const cancelClientJob = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((jobId) => {
    cancelAbortController(jobId);
  }, []);
  const setProcessJobCallback = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((callback) => {
    processJobCallbackRef.current = callback;
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(renderJobsRef, () => ({
    updateRenderJobs: (newJobs) => {
      setServerJobs(newJobs);
    },
    updateClientRenders: (renders) => {
      setClientJobs((prev) => {
        const existingIds = new Set(prev.map((j) => j.id));
        const updatedPrev = prev.map((job) => {
          const updated = renders.find((r) => r.id === job.id);
          if (updated && job.status === "done") {
            return {
              ...job,
              deletedOutputLocation: updated.deletedOutputLocation,
              metadata: updated.metadata
            };
          }
          return job;
        });
        const newJobs = renders.filter((r) => !existingIds.has(r.id)).map((r) => ({ ...r, status: "done" }));
        return [...updatedPrev, ...newJobs];
      });
    }
  }), []);
  const value = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      jobs: [...serverJobs, ...clientJobs].sort((a, b) => a.startedAt - b.startedAt),
      serverJobs,
      clientJobs,
      addClientStillJob,
      addClientVideoJob,
      updateClientJobProgress,
      markClientJobSaving,
      markClientJobDone,
      markClientJobFailed,
      markClientJobCancelled,
      removeClientJob,
      cancelClientJob,
      setProcessJobCallback,
      getAbortController,
      getCompositionForJob
    };
  }, [
    serverJobs,
    clientJobs,
    addClientStillJob,
    addClientVideoJob,
    updateClientJobProgress,
    markClientJobSaving,
    markClientJobDone,
    markClientJobFailed,
    markClientJobCancelled,
    removeClientJob,
    cancelClientJob,
    setProcessJobCallback
  ]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueueContext.Provider, {
    value,
    children
  });
};

// src/helpers/client-id.tsx

var StudioServerConnectionCtx = react__WEBPACK_IMPORTED_MODULE_0__.createContext({
  previewServerState: {
    type: "init"
  },
  subscribeToEvent: () => {
    throw new Error("Context not initalized");
  }
});
var PreviewServerConnection = ({ children, readOnlyStudio }) => {
  const listeners = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)([]);
  const subscribeToEvent = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((type, listener) => {
    listeners.current.push({ type, listener });
    return () => {
      listeners.current = listeners.current.filter((l) => l.type !== type || l.listener !== listener);
    };
  }, []);
  const openEventSource = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    const source = new EventSource("/events");
    source.addEventListener("message", (event) => {
      const newEvent = JSON.parse(event.data);
      if (newEvent.type === "new-input-props" || newEvent.type === "new-env-variables") {
        reloadUrl();
      }
      if (newEvent.type === "init") {
        setState({
          type: "connected",
          clientId: newEvent.clientId
        });
      }
      if (newEvent.type === "render-queue-updated") {
        renderJobsRef.current?.updateRenderJobs(newEvent.queue);
        for (const job of newEvent.queue) {
          if (job.status === "done" && job.beepOnFinish) {
            PlayBeepSound_default(job.id);
          }
        }
      }
      if (newEvent.type === "client-renders-updated") {
        renderJobsRef.current?.updateClientRenders(newEvent.renders);
      }
      if (newEvent.type === "render-job-failed") {
        showNotification(`Rendering "${newEvent.compositionId}" failed`, 2000);
      }
      if (newEvent.type === "new-public-folder") {
        const payload = {
          files: newEvent.files
        };
        window.remotion_staticFiles = newEvent.files;
        window.remotion_publicFolderExists = newEvent.folderExists;
        window.dispatchEvent(new CustomEvent(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.WATCH_REMOTION_STATIC_FILES, {
          detail: payload
        }));
      }
      listeners.current.forEach((l) => {
        if (l.type === newEvent.type) {
          l.listener(newEvent);
        }
      });
    });
    source.addEventListener("open", () => {
      source.addEventListener("error", () => {
        setState({ type: "disconnected" });
        source?.close();
        setTimeout(() => {
          openEventSource();
        }, 1000);
      }, { once: true });
    });
    const close = () => {
      source.close();
    };
    return {
      close
    };
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (readOnlyStudio) {
      return;
    }
    const { close } = openEventSource();
    return () => {
      close();
    };
  }, [openEventSource, readOnlyStudio]);
  const [state, setState] = react__WEBPACK_IMPORTED_MODULE_0__.useState({
    type: "init"
  });
  const context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      previewServerState: state,
      subscribeToEvent
    };
  }, [state, subscribeToEvent]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(StudioServerConnectionCtx.Provider, {
    value: context,
    children
  });
};

// src/icons/ellipsis.tsx

var EllipsisIcon = (props) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    ...props.svgProps,
    viewBox: "0 0 448 512",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: props.fill,
      d: "M8 256a56 56 0 1 1 112 0A56 56 0 1 1 8 256zm160 0a56 56 0 1 1 112 0 56 56 0 1 1 -112 0zm216-56a56 56 0 1 1 0 112 56 56 0 1 1 0-112z"
    })
  });
};

// src/components/InlineDropdown.tsx




// src/components/InlineAction.tsx


var InlineAction = ({
  renderAction,
  onClick,
  disabled,
  title
}) => {
  const { tabIndex } = useZIndex();
  const [hovered, setHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(true);
  }, []);
  const onPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(false);
  }, []);
  const style = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      border: "none",
      background: disabled ? "transparent" : getBackgroundFromHoverState({ hovered, selected: false }),
      height: 24,
      width: 24,
      display: "inline-flex",
      justifyContent: "center",
      alignItems: "center",
      borderRadius: 3,
      pointerEvents: disabled ? "none" : "auto"
    };
  }, [disabled, hovered]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
    type: "button",
    onPointerEnter,
    onPointerLeave,
    onClick,
    style,
    tabIndex,
    title,
    children: renderAction(hovered ? "white" : LIGHT_TEXT)
  });
};

// src/components/Menu/portals.ts
var portals = [
  document.getElementById("menuportal-0"),
  document.getElementById("menuportal-1"),
  document.getElementById("menuportal-2"),
  document.getElementById("menuportal-3"),
  document.getElementById("menuportal-4"),
  document.getElementById("menuportal-5")
];
var getPortal = (i) => {
  return portals[i];
};

// src/components/Menu/styles.ts
var MENU_VERTICAL_PADDING = 4;
var SUBMENU_LEFT_INSET = -8;
var MAX_MENU_WIDTH = 400;
var MAX_MOBILE_MENU_WIDTH = 300;
var menuContainer = {
  backgroundColor: BACKGROUND,
  position: "fixed",
  color: "white",
  userSelect: "none",
  WebkitUserSelect: "none"
};
var SHADOW_TOWARDS_BOTTOM = "0 2px 8px rgba(0, 0, 0, 0.5)";
var SHADOW_TOWARDS_TOP = "0 -2px 8px rgba(0, 0, 0, 0.5)";
var menuContainerTowardsBottom = {
  ...menuContainer,
  boxShadow: SHADOW_TOWARDS_BOTTOM
};
var menuContainerTowardsTop = {
  ...menuContainer,
  boxShadow: SHADOW_TOWARDS_TOP
};
var fullScreenOverlay = {
  position: "fixed",
  top: 0,
  left: 0,
  right: 0,
  bottom: 0
};
var outerPortal = {
  position: "fixed"
};
var inlineCodeSnippet = {
  fontSize: 14,
  color: BLUE,
  fontFamily: "monospace"
};

// src/components/NewComposition/MenuContent.tsx


// src/components/Menu/is-menu-item.tsx
var MENU_INITIATOR_CLASSNAME = "__remotion-studio-menu-initiator";
var MENU_ITEM_CLASSNAME = "__remotion-studio-menu-item";
var HORIZONTAL_SCROLLBAR_CLASSNAME = "__remotion-horizontal-scrollbar";
var VERTICAL_SCROLLBAR_CLASSNAME = "__remotion-vertical-scrollbar";
var isMenuItem = (el) => {
  return Boolean(el.classList.contains(MENU_ITEM_CLASSNAME) || el.closest(`.${MENU_ITEM_CLASSNAME}`) || el.classList.contains(MENU_INITIATOR_CLASSNAME) || el.closest(`.${MENU_INITIATOR_CLASSNAME}`));
};

// src/components/Menu/MenuDivider.tsx

var menuDivider = {
  marginTop: 4,
  marginBottom: 4,
  height: 1,
  backgroundColor: INPUT_BORDER_COLOR_HOVERED
};
var MenuDivider = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: menuDivider
  });
};

// src/components/Menu/MenuSubItem.tsx




// src/icons/caret.tsx


var caret = {
  height: 12
};
var caretDown = {
  width: 10
};
var angleDown = {
  width: 10
};
var CaretRight = () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
  viewBox: "0 0 192 512",
  style: caret,
  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
    fill: "currentColor",
    d: "M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"
  })
});
var CaretDown = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    viewBox: "0 0 320 512",
    style: caretDown,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: "currentColor",
      d: "M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
    })
  });
};
var AngleDown = ({ down }) => {
  const style = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...angleDown,
      transform: down ? "rotate(180deg)" : "rotate(0deg)",
      marginTop: 1
    };
  }, [down]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    style,
    viewBox: "0 0 448 512",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: LIGHT_TEXT,
      d: "M201.4 342.6c12.5 12.5 32.8 12.5 45.3 0l160-160c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L224 274.7 86.6 137.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l160 160z"
    })
  });
};

// src/components/layout.tsx


var SPACING_UNIT = 8;
var Spacing = ({ x = 0, y = 0, block = false }) => {
  const style = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      display: block ? "block" : "inline-block",
      width: x * SPACING_UNIT,
      height: y * SPACING_UNIT,
      flexShrink: 0
    };
  }, [block, x, y]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style
  });
};
var flexCss = { flex: 1 };
var Flex = ({ children }) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
  style: flexCss,
  children
});
var Row = ({ children, justify, className, align, flex, style = {}, ...other }) => {
  const finalStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...style,
      display: "flex",
      flexDirection: "row",
      justifyContent: justify ?? "flex-start",
      alignItems: align ?? "flex-start",
      flex: flex ?? undefined
    };
  }, [align, flex, justify, style]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    className,
    style: finalStyle,
    ...other,
    children
  });
};
var Column = ({ children, justify, className, align, style = {} }) => {
  const finalStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...style,
      display: "flex",
      flexDirection: "column",
      justifyContent: justify ?? "flex-start",
      alignItems: align ?? "flex-start"
    };
  }, [align, justify, style]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    className,
    style: finalStyle,
    children
  });
};

// src/components/Menu/SubMenu.tsx


var SubMenuComponent = ({
  portalStyle,
  subMenuActivated,
  subMenu,
  onQuitFullMenu,
  onQuitSubMenu
}) => {
  const mobileLayout = useMobileLayout();
  const onOutsideClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (portals.find((p) => p.contains(e)) || mobileLayout) {
      onQuitSubMenu();
    } else {
      onQuitFullMenu();
    }
  }, [mobileLayout, onQuitFullMenu, onQuitSubMenu]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(HigherZIndex, {
    onEscape: onQuitFullMenu,
    onOutsideClick,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: portalStyle,
      className: "css-reset",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MenuContent, {
        onNextMenu: noop,
        onPreviousMenu: onQuitSubMenu,
        values: subMenu.items,
        onHide: onQuitFullMenu,
        leaveLeftSpace: subMenu.leaveLeftSpace,
        preselectIndex: subMenuActivated === "without-mouse" && typeof subMenu.preselectIndex === "number" ? subMenu.preselectIndex : false,
        topItemCanBeUnselected: false,
        fixedHeight: null
      })
    })
  });
};

// src/components/Menu/MenuSubItem.tsx

var container4 = {
  paddingTop: 8,
  paddingBottom: 8,
  paddingLeft: 12,
  paddingRight: 8,
  cursor: "default"
};
var labelStyle = {
  fontSize: 13,
  overflow: "hidden",
  textOverflow: "ellipsis",
  whiteSpace: "nowrap",
  flex: 1
};
var keyHintCss = {
  flexDirection: "row",
  color: LIGHT_TEXT,
  fontSize: 13
};
var leftSpace = {
  width: 24,
  marginLeft: -6,
  display: "inline-flex",
  justifyContent: "center",
  alignItems: "center"
};
var MenuSubItem = ({
  label,
  leaveLeftSpace,
  leftItem,
  onActionChosen,
  id,
  selected,
  onItemSelected,
  keyHint,
  subMenu,
  onQuitMenu,
  subMenuActivated,
  setSubMenuActivated,
  disabled
}) => {
  const [hovered, setHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const size = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.useElementSize(ref, {
    triggerOnWindowResize: true,
    shouldApplyCssTransforms: true
  });
  const mobileLayout = useMobileLayout();
  const { currentZIndex } = useZIndex();
  const style = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...container4,
      backgroundColor: selected && !disabled ? CLEAR_HOVER : "transparent",
      opacity: disabled ? 0.5 : 1,
      cursor: disabled ? "not-allowed" : "default"
    };
  }, [selected, disabled]);
  const onPointerUp = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (disabled) {
      return;
    }
    if (subMenu) {
      setSubMenuActivated("with-mouse");
      setHovered(true);
      return;
    }
    onActionChosen(id, e);
  }, [disabled, id, onActionChosen, setSubMenuActivated, subMenu]);
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (disabled) {
      return;
    }
    onItemSelected(id);
    setHovered(true);
  }, [disabled, id, onItemSelected]);
  const onPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(false);
  }, []);
  const onQuitSubmenu = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSubMenuActivated(false);
  }, [setSubMenuActivated]);
  const portalStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!selected || !size || !subMenu || !subMenuActivated) {
      return null;
    }
    const left = size.left + size.width + SUBMENU_LEFT_INSET;
    return {
      ...menuContainerTowardsBottom,
      left: mobileLayout ? left * 0.7 : left,
      top: size.top - MENU_VERTICAL_PADDING
    };
  }, [mobileLayout, selected, size, subMenu, subMenuActivated]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!hovered || !subMenu) {
      return;
    }
    const hi = setTimeout(() => {
      setSubMenuActivated("with-mouse");
    }, 100);
    return () => clearTimeout(hi);
  }, [hovered, selected, setSubMenuActivated, subMenu]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (selected) {
      ref.current?.scrollIntoView({
        block: "nearest"
      });
    }
  }, [selected]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    ref,
    onPointerEnter,
    onPointerLeave,
    style,
    onPointerUp,
    role: "button",
    className: MENU_ITEM_CLASSNAME,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
      align: "center",
      children: [
        leaveLeftSpace ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
          children: [
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              style: leftSpace,
              children: leftItem
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
              x: 1
            })
          ]
        }) : null,
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: labelStyle,
          ...{ title: typeof label === "string" ? label : undefined },
          children: label
        }),
        " ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
          x: 2
        }),
        subMenu ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CaretRight, {}) : null,
        keyHint && !areKeyboardShortcutsDisabled() ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
          style: keyHintCss,
          children: keyHint
        }) : null,
        portalStyle && subMenu ? react_dom__WEBPACK_IMPORTED_MODULE_1__.createPortal(/* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SubMenuComponent, {
          onQuitFullMenu: onQuitMenu,
          subMenu,
          onQuitSubMenu: onQuitSubmenu,
          portalStyle,
          subMenuActivated
        }), getPortal(currentZIndex)) : null
      ]
    })
  });
};

// src/components/NewComposition/MenuContent.tsx

var BORDER_SIZE = 1;
var container5 = {
  paddingTop: MENU_VERTICAL_PADDING,
  paddingBottom: MENU_VERTICAL_PADDING,
  border: `${BORDER_SIZE}px solid ${INPUT_BORDER_COLOR_UNHOVERED}`,
  marginLeft: 0 - BORDER_SIZE,
  overflowY: "auto",
  overflowX: "hidden",
  minWidth: 200,
  maxWidth: MAX_MENU_WIDTH
};
var MenuContent = ({
  onHide,
  values,
  preselectIndex,
  onNextMenu,
  onPreviousMenu,
  leaveLeftSpace,
  topItemCanBeUnselected,
  fixedHeight
}) => {
  const keybindings = useKeybinding();
  const containerRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const isMobileLayout = useMobileLayout();
  const [subMenuActivated, setSubMenuActivated] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  if (values[0].type === "divider") {
    throw new Error("first value cant be divide");
  }
  const [selectedItem, setSelectedItem] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(typeof preselectIndex === "number" && preselectIndex >= 0 ? values[preselectIndex].id : null);
  const onEscape = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onHide();
  }, [onHide]);
  const onItemSelected = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((id) => {
    setSelectedItem(id);
  }, []);
  const isItemSelectable = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((v) => {
    return v.type !== "divider" && !v.disabled;
  }, []);
  const onArrowUp = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSelectedItem((prevItem) => {
      if (prevItem === null) {
        return null;
      }
      const index = values.findIndex((val) => val.id === prevItem);
      if (topItemCanBeUnselected && index === 0 || prevItem === null) {
        return null;
      }
      const previousItems = values.filter((v, i) => i < index && isItemSelectable(v));
      if (previousItems.length > 0) {
        return previousItems[previousItems.length - 1].id;
      }
      const firstSelectable = values.find((v) => isItemSelectable(v));
      if (firstSelectable) {
        return firstSelectable.id;
      }
      throw new Error("could not find previous item");
    });
  }, [topItemCanBeUnselected, values, isItemSelectable]);
  const onArrowDown = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSelectedItem((prevItem) => {
      const index = values.findIndex((val) => val.id === prevItem);
      const nextItem = values.find((v, i) => i > index && isItemSelectable(v));
      if (nextItem) {
        return nextItem.id;
      }
      const lastSelectable = values.slice().reverse().find((v) => isItemSelectable(v));
      if (lastSelectable) {
        return lastSelectable.id;
      }
      throw new Error("could not find next item");
    });
  }, [values, isItemSelectable]);
  const onEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (selectedItem === null) {
      return onHide();
    }
    const item = values.find((i) => i.id === selectedItem);
    if (!item) {
      throw new Error("cannot find item");
    }
    if (item.type === "divider") {
      throw new Error("cannot find divider");
    }
    if (item.disabled) {
      return;
    }
    if (item.subMenu) {
      return setSubMenuActivated("without-mouse");
    }
    onHide();
    item.onClick(item.id, null);
  }, [onHide, selectedItem, values]);
  const onArrowRight = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (selectedItem === null) {
      return onNextMenu();
    }
    const item = values.find((i) => i.id === selectedItem);
    if (!item) {
      throw new Error("cannot find item");
    }
    if (item.type === "divider") {
      throw new Error("cannot find divider");
    }
    if (!item.subMenu) {
      return onNextMenu();
    }
    setSubMenuActivated("without-mouse");
  }, [onNextMenu, selectedItem, values]);
  const containerWithHeight = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const containerStyles = { ...container5 };
    if (fixedHeight === null) {
      containerStyles.maxHeight = 600;
    } else {
      containerStyles.maxHeight = fixedHeight;
    }
    if (isMobileLayout) {
      containerStyles.maxWidth = MAX_MOBILE_MENU_WIDTH;
    }
    return containerStyles;
  }, [fixedHeight, isMobileLayout]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const escapeBinding = keybindings.registerKeybinding({
      event: "keydown",
      key: "Escape",
      callback: onEscape,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const rightBinding = keybindings.registerKeybinding({
      event: "keydown",
      key: "ArrowRight",
      commandCtrlKey: false,
      callback: onArrowRight,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const leftBinding = keybindings.registerKeybinding({
      event: "keydown",
      commandCtrlKey: false,
      key: "ArrowLeft",
      callback: onPreviousMenu,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const downBinding = keybindings.registerKeybinding({
      event: "keydown",
      key: "ArrowDown",
      commandCtrlKey: false,
      callback: onArrowDown,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const upBinding = keybindings.registerKeybinding({
      event: "keydown",
      key: "ArrowUp",
      callback: onArrowUp,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const enterBinding = keybindings.registerKeybinding({
      event: "keydown",
      key: "Enter",
      callback: onEnter,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const spaceBinding = keybindings.registerKeybinding({
      event: "keyup",
      key: " ",
      callback: onEnter,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      escapeBinding.unregister();
      leftBinding.unregister();
      rightBinding.unregister();
      downBinding.unregister();
      upBinding.unregister();
      enterBinding.unregister();
      spaceBinding.unregister();
    };
  }, [
    keybindings,
    onEscape,
    onNextMenu,
    onPreviousMenu,
    onArrowDown,
    onArrowUp,
    onEnter,
    onArrowRight
  ]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!subMenuActivated) {
      return;
    }
    if (selectedItem === null) {
      return setSubMenuActivated(false);
    }
    const item = values.find((i) => i.id === selectedItem);
    if (!item) {
      return;
    }
    if (item.type === "divider") {
      throw new Error("should not select divider");
    }
    if (!item.subMenu && subMenuActivated) {
      setSubMenuActivated(false);
    }
  }, [selectedItem, subMenuActivated, values]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const { current } = containerRef;
    if (!current) {
      return;
    }
    const onPointerLeave = () => {
      if (subMenuActivated) {
        return;
      }
      setSelectedItem(null);
    };
    current.addEventListener("pointerleave", onPointerLeave);
    return () => current.removeEventListener("pointerleave", onPointerLeave);
  }, [onHide, subMenuActivated]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    ref: containerRef,
    style: containerWithHeight,
    className: VERTICAL_SCROLLBAR_CLASSNAME,
    children: values.map((item) => {
      if (item.type === "divider") {
        return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MenuDivider, {}, item.id);
      }
      const onClick = (id, e) => {
        item.onClick(id, e);
        if (item.subMenu) {
          return null;
        }
        onHide();
      };
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MenuSubItem, {
        selected: item.id === selectedItem,
        onActionChosen: onClick,
        onItemSelected,
        label: item.label,
        id: item.id,
        keyHint: item.keyHint,
        leaveLeftSpace,
        leftItem: item.leftItem,
        subMenu: item.subMenu,
        onQuitMenu: onHide,
        onNextMenu,
        subMenuActivated,
        setSubMenuActivated,
        disabled: item.disabled
      }, item.id);
    })
  });
};

// src/components/InlineDropdown.tsx

var InlineDropdown = ({
  values,
  ...props
}) => {
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const [opened, setOpened] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({ type: "not-open" });
  const { currentZIndex } = useZIndex();
  const size = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.useElementSize(ref, {
    triggerOnWindowResize: true,
    shouldApplyCssTransforms: true
  });
  const isMobileLayout = useMobileLayout();
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.preventDefault();
    e.stopPropagation();
    setOpened({ type: "open", left: e.clientX, top: e.clientY });
  }, []);
  const spaceToBottom = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (size && opened.type === "open") {
      return size.windowSize.height - opened.top;
    }
    return 0;
  }, [opened, size]);
  const spaceToTop = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (size && opened.type === "open") {
      return opened.top;
    }
    return 0;
  }, [opened, size]);
  const portalStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (opened.type === "not-open") {
      return;
    }
    if (!size) {
      return;
    }
    const spaceToRight = size.windowSize.width - size.left;
    const spaceToLeft = size.left + size.width;
    const minSpaceRequired = isMobileLayout ? MAX_MOBILE_MENU_WIDTH : MAX_MENU_WIDTH;
    const verticalLayout = spaceToTop > spaceToBottom ? "bottom" : "top";
    const canOpenOnLeft = spaceToLeft >= minSpaceRequired;
    const canOpenOnRight = spaceToRight >= minSpaceRequired;
    const horizontalLayout = canOpenOnRight ? "left" : "right";
    return {
      ...menuContainerTowardsTop,
      ...verticalLayout === "top" ? {
        top: opened.top
      } : {
        bottom: size.windowSize.height - opened.top
      },
      ...horizontalLayout === "left" ? {
        left: opened.left
      } : {
        right: canOpenOnLeft ? size.windowSize.width - opened.left : 0
      }
    };
  }, [opened, size, isMobileLayout, spaceToTop, spaceToBottom]);
  const onHide = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setOpened({ type: "not-open" });
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        ref,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
          onClick,
          ...props
        })
      }),
      portalStyle ? react_dom__WEBPACK_IMPORTED_MODULE_1__.createPortal(/* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: fullScreenOverlay,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: outerPortal,
          className: "css-reset",
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(HigherZIndex, {
            onOutsideClick: onHide,
            onEscape: onHide,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              style: portalStyle,
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MenuContent, {
                onNextMenu: noop,
                onPreviousMenu: noop,
                values,
                onHide,
                leaveLeftSpace: true,
                preselectIndex: false,
                topItemCanBeUnselected: false,
                fixedHeight: null
              })
            })
          })
        })
      }), getPortal(currentZIndex)) : null
    ]
  });
};

// src/components/CompositionContextButton.tsx

var CompositionContextButton = ({ visible, values }) => {
  const iconStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      style: {
        height: 12
      }
    };
  }, []);
  const connectionStatus = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx).previewServerState.type;
  const renderAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(EllipsisIcon, {
      fill: color,
      svgProps: iconStyle
    });
  }, [iconStyle]);
  if (!visible || connectionStatus !== "connected") {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineDropdown, {
    renderAction,
    values
  });
};

// src/components/ContextMenu.tsx




var ContextMenu = ({ children, values }) => {
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const [opened, setOpened] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({ type: "not-open" });
  const { currentZIndex } = useZIndex();
  const style = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {};
  }, []);
  const size = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.useElementSize(ref, {
    triggerOnWindowResize: true,
    shouldApplyCssTransforms: true
  });
  const isMobileLayout = useMobileLayout();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const { current } = ref;
    if (!current) {
      return;
    }
    const onClick = (e) => {
      e.preventDefault();
      e.stopPropagation();
      setOpened({ type: "open", left: e.clientX, top: e.clientY });
      return false;
    };
    current.addEventListener("contextmenu", onClick);
    return () => {
      current.removeEventListener("contextmenu", onClick);
    };
  }, [size]);
  const spaceToBottom = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (size && opened.type === "open") {
      return size.windowSize.height - opened.top;
    }
    return 0;
  }, [opened, size]);
  const spaceToTop = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (size && opened.type === "open") {
      return opened.top;
    }
    return 0;
  }, [opened, size]);
  const portalStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (opened.type === "not-open") {
      return;
    }
    if (!size) {
      return;
    }
    const spaceToRight = size.windowSize.width - size.left;
    const spaceToLeft = size.left + size.width;
    const minSpaceRequired = isMobileLayout ? MAX_MOBILE_MENU_WIDTH : MAX_MENU_WIDTH;
    const verticalLayout = spaceToTop > spaceToBottom ? "bottom" : "top";
    const canOpenOnLeft = spaceToLeft >= minSpaceRequired;
    const canOpenOnRight = spaceToRight >= minSpaceRequired;
    const horizontalLayout = canOpenOnRight ? "left" : "right";
    return {
      ...menuContainerTowardsTop,
      ...verticalLayout === "top" ? {
        top: opened.top
      } : {
        bottom: size.windowSize.height - opened.top
      },
      ...horizontalLayout === "left" ? {
        left: opened.left
      } : {
        right: canOpenOnLeft ? size.windowSize.width - opened.left : 0
      }
    };
  }, [opened, size, isMobileLayout, spaceToTop, spaceToBottom]);
  const onHide = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setOpened({ type: "not-open" });
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        ref,
        onContextMenu: () => false,
        style,
        children
      }),
      portalStyle ? react_dom__WEBPACK_IMPORTED_MODULE_1__.createPortal(/* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: fullScreenOverlay,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: outerPortal,
          className: "css-reset",
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(HigherZIndex, {
            onOutsideClick: onHide,
            onEscape: onHide,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              style: portalStyle,
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MenuContent, {
                onNextMenu: noop,
                onPreviousMenu: noop,
                values,
                onHide,
                leaveLeftSpace: true,
                preselectIndex: false,
                topItemCanBeUnselected: false,
                fixedHeight: null
              })
            })
          })
        })
      }), getPortal(currentZIndex)) : null
    ]
  });
};

// src/components/SidebarRenderButton.tsx



// src/icons/render.tsx

var ThinRenderIcon = (props) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    ...props.svgProps,
    xmlns: "http://www.w3.org/2000/svg",
    viewBox: "0 0 512 512",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: props.fill,
      d: "M188.9 372l-50.4-50.4c18.6-42.6 61.7-137.7 95.1-187C304.6 30.1 409 24.6 475.7 36.3c11.7 66.7 6.2 171.1-98.4 242c-49.4 33.5-145.5 75.6-188.4 93.7zm-79.9-62.8c-5.2 11.9-2.5 25.7 6.7 34.9l50.7 50.7c9.1 9.1 22.7 11.9 34.5 6.9c6.5-2.7 14.3-6 23-9.8L224 496c0 5.5 2.9 10.7 7.6 13.6s10.6 3.2 15.6 .7l101.5-50.7c21.7-10.8 35.4-33 35.4-57.2V312.1c4-2.5 7.7-4.9 11.3-7.3C516.1 222.9 520.1 100.9 506.7 28.1c-2.1-11.6-11.2-20.6-22.8-22.8C411.1-8.1 289.1-4.1 207.2 116.7c-2.4 3.6-4.9 7.3-7.3 11.3l-90.2 0c-24.2 0-46.4 13.7-57.2 35.4L1.7 264.8c-2.5 5-2.2 10.8 .7 15.6s8.1 7.6 13.6 7.6H118.5c-3.6 8-6.8 15.2-9.4 21.2zM256 470.1l0-92.5c30.3-13.7 65.4-30.3 96-47v71.7c0 12.1-6.8 23.2-17.7 28.6L256 470.1zM109.7 160h71.5c-16.9 30.7-34 65.8-48.1 96H41.9L81 177.7c5.4-10.8 16.5-17.7 28.6-17.7zM392 144a24 24 0 1 1 -48 0 24 24 0 1 1 48 0zM368 88a56 56 0 1 0 0 112 56 56 0 1 0 0-112z"
    })
  });
};

// src/components/SidebarRenderButton.tsx

var SidebarRenderButton = ({ composition, visible }) => {
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const { setSidebarCollapsedState } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SidebarContext);
  const isMobileLayout = useMobileLayout();
  const iconStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      style: {
        height: 12
      }
    };
  }, []);
  const connectionStatus = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx).previewServerState.type;
  const { props } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.EditorPropsContext);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    const defaults = window.remotion_renderDefaults;
    if (!defaults) {
      throw new Error("expected defaults");
    }
    e.stopPropagation();
    setSelectedModal({
      type: "server-render",
      compositionId: composition.id,
      initialFrame: 0,
      initialVideoImageFormat: defaults.videoImageFormat,
      initialStillImageFormat: defaults.stillImageFormat,
      initialJpegQuality: defaults.jpegQuality,
      initialScale: defaults.scale,
      initialLogLevel: defaults.logLevel,
      initialConcurrency: defaults.concurrency,
      maxConcurrency: defaults.maxConcurrency,
      minConcurrency: defaults.minConcurrency,
      initialMuted: defaults.muted,
      initialEnforceAudioTrack: defaults.enforceAudioTrack,
      initialProResProfile: defaults.proResProfile,
      initialx264Preset: defaults.x264Preset,
      initialPixelFormat: null,
      initialAudioBitrate: defaults.audioBitrate,
      initialVideoBitrate: defaults.videoBitrate,
      initialEveryNthFrame: defaults.everyNthFrame,
      initialNumberOfGifLoops: defaults.numberOfGifLoops,
      initialDelayRenderTimeout: defaults.delayRenderTimeout,
      defaultConfigurationAudioCodec: defaults.audioCodec,
      initialEnvVariables: window.process.env,
      initialDisableWebSecurity: defaults.disableWebSecurity,
      initialOpenGlRenderer: defaults.openGlRenderer,
      initialHeadless: defaults.headless,
      initialOffthreadVideoCacheSizeInBytes: defaults.offthreadVideoCacheSizeInBytes,
      initialOffthreadVideoThreads: defaults.offthreadVideoThreads,
      initialIgnoreCertificateErrors: defaults.ignoreCertificateErrors,
      defaultProps: props[composition.id] ?? composition.defaultProps,
      inFrameMark: null,
      outFrameMark: null,
      initialColorSpace: defaults.colorSpace,
      initialMultiProcessOnLinux: defaults.multiProcessOnLinux,
      defaultConfigurationVideoCodec: defaults.codec,
      initialEncodingBufferSize: defaults.encodingBufferSize,
      initialEncodingMaxRate: defaults.encodingMaxRate,
      initialUserAgent: defaults.userAgent,
      initialBeep: defaults.beepOnFinish,
      initialRepro: defaults.repro,
      initialForSeamlessAacConcatenation: defaults.forSeamlessAacConcatenation,
      renderTypeOfLastRender: null,
      defaulMetadata: defaults.metadata,
      initialHardwareAcceleration: defaults.hardwareAcceleration,
      initialChromeMode: defaults.chromeMode,
      initialMediaCacheSizeInBytes: defaults.mediaCacheSizeInBytes,
      renderDefaults: defaults,
      initialDarkMode: defaults.darkMode
    });
    if (isMobileLayout) {
      setSidebarCollapsedState({ left: "collapsed", right: "collapsed" });
    }
  }, [
    composition.defaultProps,
    composition.id,
    isMobileLayout,
    props,
    setSelectedModal,
    setSidebarCollapsedState
  ]);
  const renderAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ThinRenderIcon, {
      fill: color,
      svgProps: iconStyle
    });
  }, [iconStyle]);
  if (!visible || connectionStatus !== "connected") {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
    renderAction,
    onClick
  });
};

// src/components/CompositionSelectorItem.tsx

var COMPOSITION_ITEM_HEIGHT = 32;
var itemStyle = {
  paddingRight: 10,
  paddingTop: 6,
  paddingBottom: 6,
  fontSize: 13,
  display: "flex",
  textDecoration: "none",
  cursor: "default",
  alignItems: "center",
  marginBottom: 1,
  appearance: "none",
  border: "none",
  width: "100%",
  textAlign: "left",
  backgroundColor: BACKGROUND,
  height: COMPOSITION_ITEM_HEIGHT
};
var labelStyle2 = {
  textAlign: "left",
  textDecoration: "none",
  fontSize: 13,
  flex: 1,
  whiteSpace: "nowrap",
  overflow: "hidden",
  textOverflow: "ellipsis"
};
var iconStyle = {
  width: 18,
  height: 18,
  flexShrink: 0
};
var CompositionSelectorItem = ({
  item,
  level,
  currentComposition,
  tabIndex,
  selectComposition,
  toggleFolder
}) => {
  const selected = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (item.type === "composition") {
      return currentComposition === item.composition.id;
    }
    return false;
  }, [item, currentComposition]);
  const [hovered, setHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(true);
  }, []);
  const onPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(false);
  }, []);
  const style = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...itemStyle,
      backgroundColor: getBackgroundFromHoverState({ hovered, selected }),
      paddingLeft: 12 + level * 8
    };
  }, [hovered, level, selected]);
  const label = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...labelStyle2,
      color: selected || hovered ? "white" : LIGHT_TEXT
    };
  }, [hovered, selected]);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((evt) => {
    evt.preventDefault();
    if (item.type === "composition") {
      selectComposition(item.composition, true);
    } else {
      toggleFolder(item.folderName, item.parentName);
    }
  }, [item, selectComposition, toggleFolder]);
  const onKeyPress = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((evt) => {
    if (evt.key === "Enter") {
      onClick(evt);
    }
  }, [onClick]);
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const contextMenu = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (item.type === "composition") {
      return [
        {
          id: "duplicate",
          keyHint: null,
          label: `Duplicate...`,
          leftItem: null,
          onClick: () => {
            setSelectedModal({
              type: "duplicate-comp",
              compositionId: item.composition.id,
              compositionType: item.composition.durationInFrames === 1 ? "still" : "composition"
            });
          },
          quickSwitcherLabel: null,
          subMenu: null,
          type: "item",
          value: "duplicate"
        },
        {
          id: "rename",
          keyHint: null,
          label: `Rename...`,
          leftItem: null,
          onClick: () => {
            setSelectedModal({
              type: "rename-comp",
              compositionId: item.composition.id
            });
          },
          quickSwitcherLabel: null,
          subMenu: null,
          type: "item",
          value: "rename"
        },
        {
          id: "delete",
          keyHint: null,
          label: `Delete...`,
          leftItem: null,
          onClick: () => {
            setSelectedModal({
              type: "delete-comp",
              compositionId: item.composition.id
            });
          },
          quickSwitcherLabel: null,
          subMenu: null,
          type: "item",
          value: "delete"
        },
        {
          type: "divider",
          id: "copy-id-divider"
        },
        {
          id: "copy-id",
          keyHint: null,
          label: `Copy ID`,
          leftItem: null,
          onClick: () => {
            navigator.clipboard.writeText(item.composition.id).catch((err) => {
              showNotification(`Could not copy to clipboard: ${err.message}`, 1000);
            }).then(() => {
              showNotification("Copied to clipboard", 1000);
            });
          },
          quickSwitcherLabel: null,
          subMenu: null,
          type: "item",
          value: "remove"
        }
      ];
    }
    return [];
  }, [item, setSelectedModal]);
  if (item.type === "folder") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("button", {
          style,
          onPointerEnter,
          onPointerLeave,
          tabIndex,
          onClick,
          type: "button",
          title: item.folderName,
          children: [
            item.expanded ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ExpandedFolderIcon, {
              style: iconStyle,
              color: hovered || selected ? "white" : LIGHT_TEXT
            }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CollapsedFolderIcon, {
              color: hovered || selected ? "white" : LIGHT_TEXT,
              style: iconStyle
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
              x: 1
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              style: label,
              children: item.folderName
            })
          ]
        }),
        item.expanded ? item.items.map((childItem) => {
          return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CompositionSelectorItem, {
            currentComposition,
            selectComposition,
            item: childItem,
            tabIndex,
            level: level + 1,
            toggleFolder
          }, childItem.key + childItem.type);
        }) : null
      ]
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ContextMenu, {
    values: contextMenu,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Row, {
      align: "center",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("a", {
        style,
        onPointerEnter,
        onPointerLeave,
        tabIndex,
        onClick,
        onKeyPress,
        type: "button",
        title: item.composition.id,
        className: "__remotion-composition",
        "data-compname": item.composition.id,
        children: [
          isCompositionStill(item.composition) ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(StillIcon, {
            color: hovered || selected ? "white" : LIGHT_TEXT,
            style: iconStyle
          }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FilmIcon, {
            color: hovered || selected ? "white" : LIGHT_TEXT,
            style: iconStyle
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 1
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: label,
            children: item.composition.id
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 0.5
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CompositionContextButton, {
            values: contextMenu,
            visible: hovered
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SidebarRenderButton, {
            visible: hovered,
            composition: item.composition
          })
        ]
      })
    })
  });
};

// src/components/CurrentComposition.tsx


// src/state/render-frame.ts
var renderFrame = (frame, fps) => {
  const hours = Math.floor(frame / fps / 3600);
  const remainingMinutes = frame - hours * fps * 3600;
  const minutes = Math.floor(remainingMinutes / 60 / fps);
  const remainingSec = frame - hours * fps * 3600 - minutes * fps * 60;
  const seconds = Math.floor(remainingSec / fps);
  const frameAfterSec = Math.round(frame % fps);
  const hoursStr = String(hours);
  const minutesStr = String(minutes).padStart(2, "0");
  const secondsStr = String(seconds).padStart(2, "0");
  const frameStr = String(frameAfterSec).padStart(2, "0");
  if (hours > 0) {
    return `${hoursStr}:${minutesStr}:${secondsStr}.${frameStr}`;
  }
  return `${minutesStr}:${secondsStr}.${frameStr}`;
};

// src/components/CurrentComposition.tsx

var CURRENT_COMPOSITION_HEIGHT = 80;
var container6 = {
  height: CURRENT_COMPOSITION_HEIGHT,
  display: "block",
  borderBottom: `1px solid ${BORDER_COLOR}`,
  padding: 12,
  color: "white",
  backgroundColor: BACKGROUND
};
var title = {
  fontWeight: "bold",
  fontSize: 12,
  whiteSpace: "nowrap",
  lineHeight: "18px",
  backgroundColor: BACKGROUND
};
var subtitle = {
  fontSize: 12,
  opacity: 0.8,
  whiteSpace: "nowrap",
  lineHeight: "18px",
  backgroundColor: BACKGROUND
};
var row = {
  display: "flex",
  flexDirection: "row",
  lineHeight: "18px",
  backgroundColor: BACKGROUND
};
var CurrentComposition = () => {
  const video = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useVideo();
  if (!video) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: container6
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: container6,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: row,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: title,
            children: video.id
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: subtitle,
            children: [
              video.width,
              "x",
              video.height,
              isCompositionStill(video) ? null : `, ${video.fps} FPS`
            ]
          }),
          isCompositionStill(video) ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: subtitle,
            children: "Still"
          }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: subtitle,
            children: [
              "Duration ",
              renderFrame(video.durationInFrames, video.fps)
            ]
          })
        ]
      })
    })
  });
};

// src/components/CompositionSelector.tsx

var useCompositionNavigation = () => {
  const { compositions, canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const selectComposition = useSelectComposition();
  const navigateToNextComposition = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (!canvasContent || canvasContent.type !== "composition" || compositions.length <= 1) {
      return;
    }
    const currentIndex = compositions.findIndex((c) => c.id === canvasContent.compositionId);
    if (currentIndex === -1) {
      return;
    }
    const nextIndex = (currentIndex + 1) % compositions.length;
    const nextComposition = compositions[nextIndex];
    selectComposition(nextComposition, true);
  }, [canvasContent, compositions, selectComposition]);
  const navigateToPreviousComposition = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (!canvasContent || canvasContent.type !== "composition" || compositions.length <= 1) {
      return;
    }
    const currentIndex = compositions.findIndex((c) => c.id === canvasContent.compositionId);
    if (currentIndex === -1) {
      return;
    }
    const previousIndex = (currentIndex - 1 + compositions.length) % compositions.length;
    const previousComposition = compositions[previousIndex];
    selectComposition(previousComposition, true);
  }, [canvasContent, compositions, selectComposition]);
  return (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => ({
    navigateToNextComposition,
    navigateToPreviousComposition
  }), [navigateToNextComposition, navigateToPreviousComposition]);
};
var container7 = {
  display: "flex",
  flexDirection: "column",
  flex: 1,
  overflow: "hidden",
  backgroundColor: BACKGROUND
};
var getKeysToExpand = (initialFolderName, parentFolderName, initial = []) => {
  initial.push(openFolderKey({
    folderName: initialFolderName,
    parentName: parentFolderName
  }));
  const { name, parent } = splitParentIntoNameAndParent(parentFolderName);
  if (!name) {
    return initial;
  }
  return getKeysToExpand(name, parent, initial);
};
var CompositionSelector = () => {
  const { compositions, canvasContent, folders } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const { foldersExpanded } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ExpandedFoldersContext);
  const { tabIndex } = useZIndex();
  const selectComposition = useSelectComposition();
  const items = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return createFolderTree(compositions, folders, foldersExpanded);
  }, [compositions, folders, foldersExpanded]);
  const showCurrentComposition = canvasContent && canvasContent.type === "composition";
  const list = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      height: showCurrentComposition ? `calc(100% - ${CURRENT_COMPOSITION_HEIGHT}px)` : "100%",
      overflowY: "auto"
    };
  }, [showCurrentComposition]);
  const toggleFolder = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((folderName, parentName) => {
    remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.compositionSelectorRef.current?.toggleFolder(folderName, parentName);
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container7,
    children: [
      showCurrentComposition ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CurrentComposition, {}) : null,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        className: "__remotion-vertical-scrollbar",
        style: list,
        children: items.map((c) => {
          return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CompositionSelectorItem, {
            level: 0,
            currentComposition: showCurrentComposition ? canvasContent.compositionId : null,
            selectComposition,
            toggleFolder,
            tabIndex,
            item: c
          }, c.key + c.type);
        })
      })
    ]
  });
};

// src/components/ExplorerPanel.tsx


// src/components/AssetSelector.tsx



// src/api/write-static-file.ts
var writeStaticFile = async ({
  contents,
  filePath
}) => {
  if (window.remotion_isReadOnlyStudio) {
    throw new Error("writeStaticFile() is not available in read-only Studio");
  }
  const url = new URL(`${window.remotion_staticBase}/api/add-asset`, window.location.origin);
  if (filePath.includes("\\")) {
    return Promise.reject(new Error("File path cannot contain backslashes"));
  }
  url.search = new URLSearchParams({
    filePath
  }).toString();
  const response = await fetch(url, {
    method: "POST",
    body: contents
  });
  if (!response.ok) {
    const jsonResponse = await response.json();
    throw new Error(jsonResponse.error);
  }
};

// src/helpers/use-asset-drag-events.ts


function useAssetDragEvents({
  name,
  parentFolder,
  dropLocation,
  setDropLocation
}) {
  const dragDepthRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(0);
  const combinedParents = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return [parentFolder, name].filter(remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.truthy).join("/");
  }, [name, parentFolder]);
  const isDropDiv = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return dropLocation === combinedParents;
  }, [combinedParents, dropLocation]);
  const onDragEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (dragDepthRef.current === 0) {
      setDropLocation((currentDropLocation) => currentDropLocation?.includes(combinedParents) ? currentDropLocation : combinedParents);
    }
    dragDepthRef.current++;
  }, [combinedParents, dragDepthRef, setDropLocation]);
  const onDragLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    dragDepthRef.current--;
    if (dragDepthRef.current === 0) {
      setDropLocation((currentPath) => currentPath === combinedParents ? parentFolder : currentPath);
    }
  }, [combinedParents, dragDepthRef, parentFolder, setDropLocation]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (dropLocation === null) {
      dragDepthRef.current = 0;
    }
  }, [dropLocation]);
  return {
    isDropDiv,
    onDragEnter,
    onDragLeave
  };
}
var use_asset_drag_events_default = useAssetDragEvents;

// src/components/AssetSelectorItem.tsx




// src/helpers/copy-text.ts
var copyText = (cmd) => {
  const permissionName = "clipboard-write";
  return new Promise((resolve, reject) => {
    navigator.permissions.query({ name: permissionName }).then((result) => {
      if (result.state === "granted" || result.state === "prompt") {
        navigator.clipboard.writeText(cmd);
        resolve();
      } else {
        reject(new Error("Permission to copy not granted"));
      }
    }).catch((err) => {
      reject(err);
    });
  });
};

// src/icons/clipboard.tsx

var ClipboardIcon = ({ color, ...props }) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
  viewBox: "0 0 384 512",
  ...props,
  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
    fill: color,
    d: "M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm144 418c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V118c0-3.3 2.7-6 6-6h42v36c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-36h42c3.3 0 6 2.7 6 6z"
  })
});

// src/icons/file.tsx

var FileIcon = ({
  color,
  ...props
}) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
  xmlns: "http://www.w3.org/2000/svg",
  viewBox: "0 0 384 512",
  ...props,
  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
    fill: color ?? "currentColor",
    d: "M0 64C0 28.65 28.65 0 64 0h156.1c12.7 0 25 5.057 34 14.06L369.9 129.9c9 9 14.1 21.3 14.1 34V448c0 35.3-28.7 64-64 64H64c-35.35 0-64-28.7-64-64V64zm352 128H240c-26.5 0-48-21.5-48-48V32H64c-17.67 0-32 14.33-32 32v384c0 17.7 14.33 32 32 32h256c17.7 0 32-14.3 32-32V192zm-4.7-39.4L231.4 36.69c-2-2.07-4.6-3.51-7.4-4.21V144c0 8.8 7.2 16 16 16h111.5c-.7-2.8-2.1-5.4-4.2-7.4z"
  })
});

// src/components/RenderQueue/actions.ts


// src/components/call-api.ts
var callApi = (endpoint, body, signal) => {
  return new Promise((resolve, reject) => {
    fetch(endpoint, {
      method: "post",
      headers: {
        "content-type": "application/json"
      },
      signal,
      body: JSON.stringify(body)
    }).then((res) => res.json()).then((data) => {
      if (data.success) {
        resolve(data.data);
      } else {
        reject(new Error(data.error));
      }
    }).catch((err) => {
      reject(err);
    });
  });
};

// src/components/RenderQueue/actions.ts
var addStillRenderJob = ({
  compositionId,
  outName,
  imageFormat,
  jpegQuality,
  frame,
  scale,
  logLevel,
  chromiumOptions,
  delayRenderTimeout,
  envVariables,
  inputProps,
  offthreadVideoCacheSizeInBytes,
  offthreadVideoThreads,
  multiProcessOnLinux,
  beepOnFinish,
  metadata,
  chromeMode,
  mediaCacheSizeInBytes
}) => {
  return callApi("/api/render", {
    compositionId,
    type: "still",
    outName,
    imageFormat,
    jpegQuality,
    frame,
    scale,
    logLevel,
    chromiumOptions,
    delayRenderTimeout,
    envVariables,
    serializedInputPropsWithCustomSchema: remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.serializeJSONWithSpecialTypes({
      data: inputProps,
      staticBase: window.remotion_staticBase,
      indent: undefined
    }).serializedString,
    offthreadVideoCacheSizeInBytes,
    offthreadVideoThreads,
    multiProcessOnLinux,
    beepOnFinish,
    metadata,
    chromeMode,
    mediaCacheSizeInBytes
  });
};
var addSequenceRenderJob = ({
  compositionId,
  outName,
  imageFormat,
  startFrame,
  endFrame,
  scale,
  logLevel,
  chromiumOptions,
  delayRenderTimeout,
  envVariables,
  inputProps,
  concurrency,
  offthreadVideoCacheSizeInBytes,
  offthreadVideoThreads,
  jpegQuality,
  disallowParallelEncoding,
  multiProcessOnLinux,
  beepOnFinish,
  repro,
  metadata,
  chromeMode,
  mediaCacheSizeInBytes
}) => {
  return callApi("/api/render", {
    compositionId,
    type: "sequence",
    outName,
    imageFormat,
    jpegQuality,
    scale,
    startFrame,
    endFrame,
    logLevel,
    chromiumOptions,
    delayRenderTimeout,
    envVariables,
    concurrency,
    serializedInputPropsWithCustomSchema: remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.serializeJSONWithSpecialTypes({
      data: inputProps,
      staticBase: window.remotion_staticBase,
      indent: undefined
    }).serializedString,
    offthreadVideoCacheSizeInBytes,
    offthreadVideoThreads,
    disallowParallelEncoding,
    multiProcessOnLinux,
    beepOnFinish,
    repro,
    metadata,
    chromeMode,
    mediaCacheSizeInBytes
  });
};
var addVideoRenderJob = ({
  compositionId,
  outName,
  imageFormat,
  jpegQuality,
  scale,
  logLevel,
  codec,
  concurrency,
  crf,
  startFrame,
  endFrame,
  muted,
  enforceAudioTrack,
  proResProfile,
  x264Preset,
  pixelFormat,
  audioBitrate,
  videoBitrate,
  everyNthFrame,
  numberOfGifLoops,
  delayRenderTimeout,
  audioCodec,
  disallowParallelEncoding,
  chromiumOptions,
  envVariables,
  inputProps,
  offthreadVideoCacheSizeInBytes,
  offthreadVideoThreads,
  colorSpace,
  multiProcessOnLinux,
  encodingMaxRate,
  encodingBufferSize,
  beepOnFinish,
  repro,
  forSeamlessAacConcatenation,
  separateAudioTo,
  metadata,
  hardwareAcceleration,
  chromeMode,
  mediaCacheSizeInBytes
}) => {
  return callApi("/api/render", {
    compositionId,
    type: "video",
    outName,
    imageFormat,
    jpegQuality,
    scale,
    logLevel,
    codec,
    concurrency,
    crf,
    endFrame,
    startFrame,
    muted,
    enforceAudioTrack,
    proResProfile,
    x264Preset,
    pixelFormat,
    audioBitrate,
    videoBitrate,
    everyNthFrame,
    numberOfGifLoops,
    delayRenderTimeout,
    audioCodec,
    disallowParallelEncoding,
    chromiumOptions,
    envVariables,
    serializedInputPropsWithCustomSchema: remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.serializeJSONWithSpecialTypes({
      data: inputProps,
      staticBase: window.remotion_staticBase,
      indent: undefined
    }).serializedString,
    offthreadVideoCacheSizeInBytes,
    offthreadVideoThreads,
    colorSpace,
    multiProcessOnLinux,
    encodingBufferSize,
    encodingMaxRate,
    beepOnFinish,
    repro,
    forSeamlessAacConcatenation,
    separateAudioTo,
    metadata,
    hardwareAcceleration,
    chromeMode,
    mediaCacheSizeInBytes
  });
};
var unsubscribeFromFileExistenceWatcher = ({
  file,
  clientId
}) => {
  return callApi("/api/unsubscribe-from-file-existence", { file, clientId });
};
var subscribeToFileExistenceWatcher = async ({
  file,
  clientId
}) => {
  const { exists } = await callApi("/api/subscribe-to-file-existence", {
    file,
    clientId
  });
  return exists;
};
var openInFileExplorer = ({ directory }) => {
  const body = {
    directory
  };
  return callApi("/api/open-in-file-explorer", body);
};
var applyCodemod = ({
  codemod,
  dryRun,
  signal
}) => {
  const body = {
    codemod,
    dryRun
  };
  return callApi("/api/apply-codemod", body, signal);
};
var removeRenderJob = (job) => {
  return callApi("/api/remove-render", {
    jobId: job.id
  });
};
var cancelRenderJob = (job) => {
  return callApi("/api/cancel", {
    jobId: job.id
  });
};
var updateAvailable = (signal) => {
  return callApi("/api/update-available", {}, signal);
};
var getProjectInfo = (signal) => {
  return callApi("/api/project-info", {}, signal);
};
var callUpdateDefaultPropsApi = (compositionId, defaultProps, enumPaths) => {
  return callApi("/api/update-default-props", {
    compositionId,
    defaultProps: remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.serializeJSONWithSpecialTypes({
      data: defaultProps,
      indent: undefined,
      staticBase: window.remotion_staticBase
    }).serializedString,
    enumPaths
  });
};
var canUpdateDefaultProps = (compositionId, readOnlyStudio) => {
  if (readOnlyStudio) {
    return Promise.resolve({
      canUpdate: false,
      reason: "Read-only studio"
    });
  }
  return callApi("/api/can-update-default-props", {
    compositionId
  });
};
var applyVisualControlChange = ({
  fileName,
  changes
}) => {
  return callApi("/api/apply-visual-control-change", {
    fileName,
    changes
  });
};

// src/components/AssetSelectorItem.tsx

var ASSET_ITEM_HEIGHT = 32;
var iconStyle2 = {
  width: 18,
  height: 18,
  flexShrink: 0
};
var itemStyle2 = {
  paddingRight: 10,
  paddingTop: 6,
  paddingBottom: 6,
  fontSize: 13,
  display: "flex",
  textDecoration: "none",
  cursor: "default",
  alignItems: "center",
  marginBottom: 1,
  appearance: "none",
  border: "none",
  width: "100%",
  textAlign: "left",
  backgroundColor: BACKGROUND,
  height: ASSET_ITEM_HEIGHT,
  userSelect: "none",
  WebkitUserSelect: "none"
};
var labelStyle3 = {
  textAlign: "left",
  textDecoration: "none",
  fontSize: 13,
  flex: "1 1 0%",
  whiteSpace: "nowrap",
  overflow: "hidden",
  textOverflow: "ellipsis"
};
var revealIconStyle = {
  height: 12,
  color: "currentColor"
};
var AssetFolderItem = ({
  tabIndex,
  item,
  level,
  parentFolder,
  toggleFolder,
  dropLocation,
  setDropLocation,
  readOnlyStudio
}) => {
  const [hovered, setHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const openFolderTimerRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const { isDropDiv, onDragEnter, onDragLeave } = use_asset_drag_events_default({
    name: item.name,
    parentFolder,
    dropLocation,
    setDropLocation
  });
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(true);
  }, []);
  const onPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(false);
  }, []);
  const folderStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...itemStyle2,
      paddingLeft: 4 + level * 8,
      backgroundColor: hovered ? CLEAR_HOVER : "transparent"
    };
  }, [hovered, level]);
  const label = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...labelStyle3,
      color: hovered ? "white" : LIGHT_TEXT
    };
  }, [hovered]);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    toggleFolder(item.name, parentFolder);
  }, [item.name, parentFolder, toggleFolder]);
  const Icon = item.expanded ? ExpandedFolderIcon : CollapsedFolderIcon;
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    onDragEnter,
    onDragLeave,
    style: {
      backgroundColor: isDropDiv ? CLEAR_HOVER : BACKGROUND
    },
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: folderStyle,
        onPointerEnter,
        onPointerLeave,
        tabIndex,
        title: item.name,
        onClick,
        onDragEnter: () => {
          if (!item.expanded) {
            openFolderTimerRef.current = window.setTimeout(() => {
              toggleFolder(item.name, parentFolder);
            }, 1000);
          }
        },
        onDragLeave: () => {
          if (openFolderTimerRef.current) {
            clearTimeout(openFolderTimerRef.current);
          }
        },
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
          children: [
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Icon, {
              style: iconStyle2,
              color: hovered ? "white" : LIGHT_TEXT
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
              x: 1
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              style: label,
              children: item.name
            })
          ]
        })
      }),
      item.expanded ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(AssetFolderTree, {
        item: item.items,
        name: item.name,
        level,
        parentFolder,
        tabIndex,
        toggleFolder,
        dropLocation,
        setDropLocation,
        readOnlyStudio
      }, item.name) : null
    ]
  });
};
var AssetFolderTree = ({
  item,
  level,
  name,
  parentFolder,
  toggleFolder,
  tabIndex,
  dropLocation,
  setDropLocation,
  readOnlyStudio
}) => {
  const combinedParents = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return [parentFolder, name].filter(remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.truthy).join("/");
  }, [name, parentFolder]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    children: [
      item.folders.map((folder) => {
        return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(AssetFolderItem, {
          item: folder,
          tabIndex,
          level: level + 1,
          parentFolder: combinedParents,
          toggleFolder,
          dropLocation,
          setDropLocation,
          readOnlyStudio
        }, folder.name);
      }),
      item.files.map((file) => {
        return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(AssetSelectorItem, {
          item: file,
          tabIndex,
          level,
          parentFolder: combinedParents,
          readOnlyStudio
        }, file.src);
      })
    ]
  });
};
var AssetSelectorItem = ({ item, tabIndex, level, parentFolder, readOnlyStudio }) => {
  const isMobileLayout = useMobileLayout();
  const [hovered, setHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const { setSidebarCollapsedState } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SidebarContext);
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(true);
  }, []);
  const { setCanvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionSetters);
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const selected = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (canvasContent && canvasContent.type === "asset") {
      const nameWOParent = canvasContent.asset.split("/").pop();
      return nameWOParent === item.name;
    }
    return false;
  }, [canvasContent, item.name]);
  const onPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(false);
  }, []);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    const relativePath = parentFolder ? parentFolder + "/" + item.name : item.name;
    setCanvasContent({ type: "asset", asset: relativePath });
    pushUrl(`/assets/${relativePath}`);
    if (isMobileLayout) {
      setSidebarCollapsedState({ left: "collapsed", right: "collapsed" });
    }
  }, [
    isMobileLayout,
    item.name,
    parentFolder,
    setCanvasContent,
    setSidebarCollapsedState
  ]);
  const style = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...itemStyle2,
      color: hovered || selected ? "white" : LIGHT_TEXT,
      backgroundColor: hovered ? selected ? SELECTED_BACKGROUND : CLEAR_HOVER : selected ? SELECTED_BACKGROUND : "transparent",
      paddingLeft: 12 + level * 8
    };
  }, [hovered, level, selected]);
  const label = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...labelStyle3,
      color: hovered || selected ? "white" : LIGHT_TEXT
    };
  }, [hovered, selected]);
  const renderFileExplorerAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ExpandedFolderIcon, {
      style: revealIconStyle,
      color
    });
  }, []);
  const renderCopyAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ClipboardIcon, {
      style: revealIconStyle,
      color
    });
  }, []);
  const revealInExplorer = react__WEBPACK_IMPORTED_MODULE_0__.useCallback((e) => {
    e.stopPropagation();
    openInFileExplorer({
      directory: window.remotion_publicFolderExists + "/" + parentFolder + "/" + item.name
    }).catch((err) => {
      showNotification(`Could not open file: ${err.message}`, 2000);
    });
  }, [item.name, parentFolder]);
  const copyToClipboard = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.stopPropagation();
    const content = `staticFile("${[parentFolder, item.name].join("/")}")`;
    copyText(content).then(() => {
      showNotification(`Copied '${content}' to clipboard`, 1000);
    }).catch((err) => {
      showNotification(`Could not copy: ${err.message}`, 2000);
    });
  }, [item.name, parentFolder]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Row, {
    align: "center",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
      style,
      onPointerEnter,
      onPointerLeave,
      onClick,
      tabIndex,
      title: item.name,
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FileIcon, {
          style: iconStyle2,
          color: LIGHT_TEXT
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
          x: 1
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: label,
          children: item.name
        }),
        hovered ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
          children: [
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
              x: 0.5
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
              title: "Copy staticFile() name",
              renderAction: renderCopyAction,
              onClick: copyToClipboard
            }),
            readOnlyStudio ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
              children: [
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                  x: 0.5
                }),
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
                  title: "Open in Explorer",
                  renderAction: renderFileExplorerAction,
                  onClick: revealInExplorer
                })
              ]
            })
          ]
        }) : null
      ]
    })
  });
};

// src/components/CurrentAsset.tsx





// src/components/use-static-files.ts



// src/api/get-static-files.ts
var warnedServer = false;
var warnedPlayer = false;
var warnServerOnce = () => {
  if (warnedServer) {
    return;
  }
  warnedServer = true;
  console.warn("Called getStaticFiles() on the server. The API is only available in the browser. An empty array was returned.");
};
var warnPlayerOnce = () => {
  if (warnedPlayer) {
    return;
  }
  warnedPlayer = true;
  console.warn("Called getStaticFiles() while using the Remotion Player. The API is only available while using the Remotion Studio. An empty array was returned.");
};
var getStaticFiles = () => {
  if (typeof document === "undefined") {
    warnServerOnce();
    return [];
  }
  if (window.remotion_isPlayer) {
    warnPlayerOnce();
    return [];
  }
  return window.remotion_staticFiles;
};

// src/api/watch-public-folder.ts

var WATCH_REMOTION_STATIC_FILES = "remotion_staticFilesChanged";
var watchPublicFolder = (callback) => {
  if (!(0,remotion__WEBPACK_IMPORTED_MODULE_2__.getRemotionEnvironment)().isStudio) {
    console.warn("The watchPublicFolder() API is only available while using the Remotion Studio.");
    return { cancel: () => {
      return;
    } };
  }
  if (window.remotion_isReadOnlyStudio) {
    throw new Error("watchPublicFolder() is not available in read-only Studio");
  }
  const emitUpdate = () => {
    callback(getStaticFiles());
  };
  window.addEventListener(WATCH_REMOTION_STATIC_FILES, emitUpdate);
  const cancel = () => {
    return window.removeEventListener(WATCH_REMOTION_STATIC_FILES, emitUpdate);
  };
  return { cancel };
};

// src/components/use-static-files.ts
var StaticFilesContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)([]);
var StaticFilesProvider = ({ children }) => {
  const [files, setFiles] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => getStaticFiles());
  const env = (0,remotion__WEBPACK_IMPORTED_MODULE_2__.useRemotionEnvironment)();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!env.isStudio) {
      return;
    }
    if (env.isReadOnlyStudio) {
      return;
    }
    const { cancel } = watchPublicFolder((newFiles) => {
      setFiles(newFiles);
    });
    return cancel;
  }, [env.isStudio, env.isReadOnlyStudio]);
  return react__WEBPACK_IMPORTED_MODULE_0__.createElement(StaticFilesContext.Provider, { value: files }, children);
};
var useStaticFiles = () => {
  return (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StaticFilesContext);
};

// src/components/CurrentAsset.tsx

var CURRENT_ASSET_HEIGHT = 80;
var container8 = {
  height: CURRENT_ASSET_HEIGHT,
  display: "block",
  borderBottom: `1px solid ${BORDER_COLOR}`,
  padding: 12,
  color: "white",
  backgroundColor: BACKGROUND
};
var title2 = {
  fontWeight: "bold",
  fontSize: 12,
  whiteSpace: "nowrap",
  lineHeight: "18px",
  backgroundColor: BACKGROUND
};
var subtitle2 = {
  fontSize: 12,
  opacity: 0.8,
  whiteSpace: "nowrap",
  lineHeight: "18px",
  backgroundColor: BACKGROUND
};
var row2 = {
  display: "flex",
  flexDirection: "row",
  lineHeight: "18px",
  backgroundColor: BACKGROUND
};
var formatDuration = (seconds) => {
  const h = Math.floor(seconds / 3600);
  const m = Math.floor(seconds % 3600 / 60);
  const s = seconds % 60;
  const sFixed = s.toFixed(2).padStart(5, "0");
  if (h > 0) {
    return `${h}:${String(m).padStart(2, "0")}:${sFixed}`;
  }
  return `${String(m).padStart(2, "0")}:${sFixed}`;
};
var CurrentAsset = () => {
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const assetName = canvasContent?.type === "asset" ? canvasContent.asset : null;
  const staticFiles = useStaticFiles();
  const sizeInBytes = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!assetName) {
      return null;
    }
    const file = staticFiles.find((f) => f.name === assetName);
    return file?.sizeInBytes ?? null;
  }, [assetName, staticFiles]);
  const [mediaMetadata, setMediaMetadata] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    setMediaMetadata(null);
    if (!assetName) {
      return;
    }
    const url = (0,remotion__WEBPACK_IMPORTED_MODULE_2__.staticFile)(assetName);
    const input = new mediabunny__WEBPACK_IMPORTED_MODULE_9__/* .Input */ .p({
      formats: mediabunny__WEBPACK_IMPORTED_MODULE_8__/* .ALL_FORMATS */ .XE,
      source: new mediabunny__WEBPACK_IMPORTED_MODULE_7__/* .UrlSource */ .Ts(url)
    });
    Promise.all([
      input.computeDuration(),
      input.getFormat(),
      input.getPrimaryVideoTrack()
    ]).then(([duration, format, videoTrack]) => {
      setMediaMetadata({
        duration,
        format: format.name,
        width: videoTrack?.displayWidth ?? null,
        height: videoTrack?.displayHeight ?? null
      });
    }).catch(() => {});
    return () => {
      input.dispose();
    };
  }, [assetName]);
  if (!assetName) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: container8
    });
  }
  const fileName = assetName.split("/").pop() ?? assetName;
  const subtitleParts = [];
  if (sizeInBytes !== null) {
    subtitleParts.push((0,_remotion_studio_shared__WEBPACK_IMPORTED_MODULE_6__/* .formatBytes */ .z3)(sizeInBytes));
  }
  if (mediaMetadata) {
    subtitleParts.push(mediaMetadata.format);
    if (mediaMetadata.width !== null && mediaMetadata.height !== null) {
      subtitleParts.push(`${mediaMetadata.width}x${mediaMetadata.height}`);
    }
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: container8,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: row2,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: title2,
            children: fileName
          }),
          subtitleParts.length > 0 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: subtitle2,
            children: subtitleParts.join(" · ")
          }) : null,
          mediaMetadata ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: subtitle2,
            children: formatDuration(mediaMetadata.duration)
          }) : null
        ]
      })
    })
  });
};

// src/components/AssetSelector.tsx

var container9 = {
  display: "flex",
  flexDirection: "column",
  flex: 1,
  overflow: "hidden",
  backgroundColor: BACKGROUND
};
var emptyState = {
  display: "flex",
  flex: 1,
  justifyContent: "center",
  alignItems: "center",
  textAlign: "center",
  padding: "0 12px"
};
var label = {
  color: LIGHT_TEXT,
  lineHeight: 1.5,
  fontSize: 14
};
var baseList = {
  overflowY: "auto"
};
var AssetSelector = ({ readOnlyStudio }) => {
  const { tabIndex } = useZIndex();
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const { assetFoldersExpanded, setAssetFoldersExpanded } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(FolderContext);
  const [dropLocation, setDropLocation] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const connectionStatus = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx).previewServerState.type;
  const shouldAllowUpload = connectionStatus === "connected" && !readOnlyStudio;
  const showCurrentAsset = canvasContent?.type === "asset";
  const list = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...baseList,
      height: showCurrentAsset ? `calc(100% - ${CURRENT_ASSET_HEIGHT}px)` : "100%"
    };
  }, [showCurrentAsset]);
  const staticFiles = useStaticFiles();
  const publicFolderExists = window.remotion_publicFolderExists;
  const assetTree = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return buildAssetFolderStructure(staticFiles, null, assetFoldersExpanded);
  }, [assetFoldersExpanded, staticFiles]);
  const toggleFolder = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((folderName, parentName) => {
    setAssetFoldersExpanded((p) => {
      const key = [parentName, folderName].filter(Boolean).join("/");
      const prev = p[key] ?? false;
      const foldersExpandedState = {
        ...p,
        [key]: !prev
      };
      persistExpandedFolders("assets", foldersExpandedState);
      return foldersExpandedState;
    });
  }, [setAssetFoldersExpanded]);
  const { isDropDiv, onDragEnter, onDragLeave } = use_asset_drag_events_default({
    name: null,
    parentFolder: null,
    dropLocation,
    setDropLocation
  });
  const onDragOver = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.preventDefault();
  }, []);
  const onDrop = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(async (e) => {
    try {
      e.preventDefault();
      e.stopPropagation();
      const { files } = e.dataTransfer;
      const assetPath = dropLocation ?? null;
      const makePath = (file) => {
        return [assetPath, file.name].filter(Boolean).join("/");
      };
      for (const file of files) {
        const body = await file.arrayBuffer();
        await writeStaticFile({
          contents: body,
          filePath: makePath(file)
        });
      }
      if (files.length === 1) {
        showNotification(`Created ${makePath(files[0])}`, 3000);
      } else {
        showNotification(`Added ${files.length} files to ${assetPath}`, 3000);
      }
    } catch (error) {
      showNotification(`Error during upload: ${error}`, 3000);
    } finally {
      setDropLocation(null);
    }
  }, [dropLocation]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container9,
    onDragOver: shouldAllowUpload ? onDragOver : undefined,
    onDrop: shouldAllowUpload ? onDrop : undefined,
    children: [
      showCurrentAsset ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CurrentAsset, {}) : null,
      staticFiles.length === 0 ? publicFolderExists ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: emptyState,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
          style: label,
          children: [
            "To add assets, place a file in the",
            " ",
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
              style: inlineCodeSnippet,
              children: "public"
            }),
            " folder of your project or drag and drop a file here."
          ]
        })
      }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: emptyState,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
          style: label,
          children: [
            "To add assets, create a folder called",
            " ",
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
              style: inlineCodeSnippet,
              children: "public"
            }),
            " in the root of your project and place a file in it."
          ]
        })
      }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        className: "__remotion-vertical-scrollbar",
        style: {
          ...list,
          backgroundColor: isDropDiv ? CLEAR_HOVER : BACKGROUND
        },
        onDragEnter,
        onDragLeave,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(AssetFolderTree, {
          item: assetTree,
          level: 0,
          parentFolder: null,
          name: null,
          tabIndex,
          toggleFolder,
          dropLocation,
          setDropLocation,
          readOnlyStudio
        })
      })
    ]
  });
};

// src/components/CompSelectorRef.tsx



var CompSelectorRef = ({ children }) => {
  const { compositions } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const [foldersExpanded, setFoldersExpanded] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(loadExpandedFolders("compositions"));
  const selectComposition = useSelectComposition();
  const toggleFolder = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((folderName, parentName) => {
    setFoldersExpanded((p) => {
      const key = openFolderKey({ folderName, parentName });
      const prev = p[key] ?? false;
      const foldersExpandedState = {
        ...p,
        [key]: !prev
      };
      persistExpandedFolders("compositions", foldersExpandedState);
      return foldersExpandedState;
    });
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.compositionSelectorRef, () => {
    return {
      expandComposition: (compName) => {
        const compositionToExpand = compositions.find((c) => c.id === compName);
        if (!compositionToExpand) {
          return;
        }
        const { folderName, parentFolderName } = compositionToExpand;
        if (folderName === null) {
          return;
        }
        setFoldersExpanded((previousState) => {
          const foldersExpandedState = {
            ...previousState
          };
          const currentFolder = folderName;
          const currentParentName = parentFolderName;
          const key = openFolderKey({
            folderName: currentFolder,
            parentName: currentParentName
          });
          const splitted = key.split("/");
          for (let i = 0;i < splitted.length - 1; i++) {
            const allExceptLast = i === 0 ? openFolderKey({
              folderName: splitted.filter((s) => s !== "no-parent")[0],
              parentName: null
            }) : splitted.slice(0, i + 1).join("/");
            foldersExpandedState[allExceptLast] = true;
          }
          persistExpandedFolders("compositions", foldersExpandedState);
          return foldersExpandedState;
        });
      },
      selectComposition: (compName) => {
        const comp = compositions.find((c) => c.id === compName);
        if (!comp) {
          throw new Error(`Composition ${compName} not found`);
        }
        selectComposition(comp, true);
      },
      toggleFolder: (folderName, parentName) => {
        toggleFolder(folderName, parentName);
      }
    };
  }, [compositions, selectComposition, toggleFolder]);
  const contextValue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      foldersExpanded,
      setFoldersExpanded,
      toggleFolder
    };
  }, [foldersExpanded, setFoldersExpanded, toggleFolder]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ExpandedFoldersContext.Provider, {
    value: contextValue,
    children
  });
};

// src/components/Tabs/index.tsx


var tabsContainer = {
  display: "flex",
  flexDirection: "row"
};
var Tabs = ({ children, style }) => {
  const definiteStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...tabsContainer,
      ...style
    };
  }, [style]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: definiteStyle,
    children
  });
};
var selectorButton = {
  border: "none",
  flex: 1,
  padding: 4,
  height: 40,
  paddingLeft: 16,
  display: "flex",
  flexDirection: "row",
  fontSize: 14,
  color: "inherit",
  alignItems: "center",
  cursor: "default",
  userSelect: "none",
  WebkitUserSelect: "none"
};
var Tab = ({ children, onClick, style, selected }) => {
  const [hovered, setHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const { tabIndex } = useZIndex();
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(true);
  }, []);
  const onPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(false);
  }, []);
  const definiteStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => ({
    ...selectorButton,
    backgroundColor: selected ? BACKGROUND : hovered ? CLEAR_HOVER : INPUT_BACKGROUND,
    color: selected ? "white" : LIGHT_TEXT,
    borderTop: selected ? "2px solid " + BLUE : "2px solid transparent",
    boxShadow: selected ? "none" : undefined,
    ...style
  }), [hovered, selected, style]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: definiteStyle,
    role: "button",
    onClick,
    tabIndex,
    onPointerLeave,
    onPointerEnter,
    children
  });
};

// src/components/ExplorerPanel.tsx

var container10 = {
  height: "100%",
  width: "100%",
  maxWidth: "100%",
  display: "flex",
  flexDirection: "column",
  flex: 1
};
var localStorageKey2 = "remotion.sidebarPanel";
var getSelectedPanel = () => {
  const panel = localStorage.getItem(localStorageKey2);
  if (panel === "assets") {
    return "assets";
  }
  return "compositions";
};
var tabsContainer2 = {
  backgroundColor: BACKGROUND
};
var persistSelectedOptionsSidebarPanel = (panel) => {
  localStorage.setItem(localStorageKey2, panel);
};
var explorerSidebarTabs = (0,react__WEBPACK_IMPORTED_MODULE_0__.createRef)();
var ExplorerPanel = ({ readOnlyStudio }) => {
  const [panel, setPanel] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => getSelectedPanel());
  const onCompositionsSelected = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setPanel("compositions");
    persistSelectedOptionsSidebarPanel("compositions");
  }, []);
  const onAssetsSelected = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setPanel("assets");
    persistSelectedOptionsSidebarPanel("assets");
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(explorerSidebarTabs, () => {
    return {
      selectAssetsPanel: () => {
        setPanel("assets");
        persistSelectedOptionsSidebarPanel("assets");
      },
      selectCompositionPanel: () => {
        setPanel("compositions");
        persistSelectedOptionsSidebarPanel("compositions");
      }
    };
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CompSelectorRef, {
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
      style: container10,
      className: "css-reset",
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: tabsContainer2,
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Tabs, {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Tab, {
                selected: panel === "compositions",
                onClick: onCompositionsSelected,
                children: "Compositions"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Tab, {
                selected: panel === "assets",
                onClick: onAssetsSelected,
                children: "Assets"
              })
            ]
          })
        }),
        panel === "compositions" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CompositionSelector, {}) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(AssetSelector, {
          readOnlyStudio
        })
      ]
    })
  });
};

// src/components/InitialCompositionLoader.tsx
var useSelectAsset = () => {
  const { setCanvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionSetters);
  const { setAssetFoldersExpanded } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(FolderContext);
  return (asset) => {
    setCanvasContent({ type: "asset", asset });
    explorerSidebarTabs.current?.selectAssetsPanel();
    setAssetFoldersExpanded((ex) => {
      const split = asset.split("/");
      const keysToExpand = split.map((_, i) => {
        return split.slice(0, i).join("/");
      });
      const newState = {
        ...ex
      };
      for (const key of keysToExpand) {
        newState[key] = true;
      }
      return newState;
    });
  };
};
var useSelectComposition = () => {
  const { setCompositionFoldersExpanded } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(FolderContext);
  const { setCanvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionSetters);
  const isMobileLayout = useMobileLayout();
  const { setSidebarCollapsedState } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SidebarContext);
  return (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((c, push) => {
    if (push) {
      pushUrl(`/${c.id}`);
    }
    explorerSidebarTabs.current?.selectCompositionPanel();
    setCanvasContent({ type: "composition", compositionId: c.id });
    const { folderName, parentFolderName } = c;
    if (folderName !== null) {
      setCompositionFoldersExpanded((ex) => {
        const keysToExpand = getKeysToExpand(folderName, parentFolderName);
        const newState = {
          ...ex
        };
        for (const key of keysToExpand) {
          newState[key] = true;
        }
        return newState;
      });
      if (isMobileLayout) {
        setSidebarCollapsedState({ left: "collapsed", right: "collapsed" });
      }
    }
  }, [
    isMobileLayout,
    setCanvasContent,
    setCompositionFoldersExpanded,
    setSidebarCollapsedState
  ]);
};
var InitialCompositionLoader = () => {
  const { compositions, canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const { setCanvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionSetters);
  const selectComposition = useSelectComposition();
  const selectAsset = useSelectAsset();
  const staticFiles = useStaticFiles();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const canvasContentFromUrl = deriveCanvasContentFromUrl();
    if (canvasContent) {
      if (canvasContentFromUrl && canvasContentFromUrl.type === "composition" && canvasContent.type === "composition" && canvasContentFromUrl.compositionId !== canvasContent.compositionId) {
        const exists = compositions.find((c) => c.id === canvasContentFromUrl.compositionId);
        if (exists) {
          selectComposition(exists, false);
        }
      }
      return;
    }
    if (canvasContentFromUrl && canvasContentFromUrl.type === "composition") {
      const exists = compositions.find((c) => c.id === canvasContentFromUrl.compositionId);
      if (exists) {
        selectComposition(exists, false);
      }
      return;
    }
    if (canvasContentFromUrl && canvasContentFromUrl.type === "asset") {
      selectAsset(canvasContentFromUrl.asset);
      return;
    }
    if (canvasContentFromUrl && canvasContentFromUrl.type === "output") {
      setCanvasContent(canvasContentFromUrl);
      return;
    }
    if (compositions.length > 0) {
      selectComposition(compositions[0], true);
    }
  }, [
    compositions,
    canvasContent,
    selectComposition,
    setCanvasContent,
    selectAsset
  ]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const onchange = () => {
      const newCanvas = deriveCanvasContentFromUrl();
      if (newCanvas && newCanvas.type === "composition") {
        const newComp = getRoute().substring(1);
        const exists = compositions.find((c) => c.id === newComp);
        if (exists) {
          selectComposition(exists, false);
        }
        return;
      }
      if (newCanvas && newCanvas.type === "asset") {
        const exists = staticFiles.find((file) => {
          return file.name === newCanvas.asset;
        });
        if (exists) {
          setCanvasContent(newCanvas);
        }
        return;
      }
      setCanvasContent(newCanvas);
    };
    window.addEventListener("popstate", onchange);
    return () => window.removeEventListener("popstate", onchange);
  }, [compositions, selectComposition, setCanvasContent, staticFiles]);
  return null;
};

// src/components/MenuToolbar.tsx


// src/helpers/use-menu-structure.tsx




// src/api/restart-studio.ts

var restartStudio = () => {
  if (!(0,remotion__WEBPACK_IMPORTED_MODULE_2__.getRemotionEnvironment)().isStudio) {
    throw new Error("restartStudio() is only available in the Studio");
  }
  if (window.remotion_isReadOnlyStudio) {
    throw new Error("restartStudio() is not available in read-only Studio");
  }
  return callApi("/api/restart-studio", {});
};

// src/components/AskAiModal.tsx



// src/components/ModalContainer.tsx

var padding = 20;
var getMaxModalWidth = (width) => {
  return `min(calc(100vw - ${padding * 2}px), calc(${width}px - ${padding * 2}px))`;
};
var getMaxModalHeight = (height) => {
  return `min(calc(100vh - ${padding * 2}px), calc(${height}px - ${padding * 2}px))`;
};
var backgroundOverlay = {
  backgroundColor: "rgba(255, 255, 255, 0.2)",
  backdropFilter: `blur(1px)`,
  position: "fixed",
  height: "100%",
  width: "100%",
  display: "flex",
  padding
};
var panel = {
  backgroundColor: BACKGROUND,
  boxShadow: "0 0 4px black",
  color: "white",
  margin: "auto"
};
var ModalContainer = ({ children, onEscape, onOutsideClick, noZIndex }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    className: "css-reset",
    style: backgroundOverlay,
    role: "dialog",
    "aria-modal": "true",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(HigherZIndex, {
      disabled: noZIndex,
      onOutsideClick,
      onEscape,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: panel,
        children
      })
    })
  });
};

// src/components/ModalHeader.tsx


// src/components/NewComposition/CancelButton.tsx

var style = {
  appearance: "none",
  border: "none",
  backgroundColor: "transparent",
  color: "white",
  cursor: "pointer",
  display: "inline-flex",
  justifyContent: "center",
  alignItems: "center"
};
var CancelButton = ({ onPress, ...props }) => {
  const { tabIndex } = useZIndex();
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
    tabIndex,
    style,
    type: "button",
    onClick: onPress,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      viewBox: "0 0 320 512",
      ...props,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        fill: "currentColor",
        d: "M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"
      })
    })
  });
};

// src/components/ModalHeader.tsx

var container11 = {
  display: "flex",
  flexDirection: "row",
  alignItems: "center",
  padding: "12px 16px",
  width: "100%",
  borderBottom: "1px solid black"
};
var titleStyle = {
  fontSize: 14,
  color: "white"
};
var icon = {
  height: 20,
  width: 20
};
var ModalHeader = ({ title: title3, onClose }) => {
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const onPress = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSelectedModal(null);
  }, [setSelectedModal]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container11,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: titleStyle,
        children: title3
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CancelButton, {
        style: icon,
        onPress: onClose ?? onPress
      })
    ]
  });
};

// src/components/AskAiModal.tsx

var container12 = {
  height: "calc(100vh - 100px)",
  width: "calc(100vw - 160px)",
  maxWidth: 800,
  maxHeight: 900,
  display: "block"
};
var askAiModalRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.createRef)();
var AskAiModal = () => {
  const [state, setState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)("never-opened");
  const iframe = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(askAiModalRef, () => ({
    toggle: () => {
      setState((s) => {
        if (s === "visible") {
          iframe.current?.blur();
          iframe.current?.contentWindow?.blur();
        }
        return s === "visible" ? "hidden" : "visible";
      });
    }
  }), []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const onMessage = (event) => {
      try {
        const json = typeof event.data === "string" ? JSON.parse(event.data) : event.data;
        if (json.type === "cmd-i") {
          askAiModalRef.current?.toggle();
        }
      } catch {}
    };
    window.addEventListener("message", onMessage);
    return () => {
      window.removeEventListener("message", onMessage);
    };
  }, []);
  const onQuit = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setState("hidden");
  }, [setState]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!iframe.current) {
      return;
    }
    if (state === "visible") {
      iframe.current.contentWindow?.postMessage({
        type: "focus"
      }, "*");
    }
  }, [state]);
  if (state === "never-opened") {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_2__.AbsoluteFill, {
    style: { display: state === "visible" ? "block" : "none" },
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(ModalContainer, {
      noZIndex: state === "hidden",
      onOutsideClick: onQuit,
      onEscape: onQuit,
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalHeader, {
          title: "Ask AI",
          onClose: onQuit
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("iframe", {
          ref: iframe,
          frameBorder: 0,
          style: container12,
          src: "https://www.remotion.dev/ai-embed",
          allow: "clipboard-read; clipboard-write"
        })
      ]
    })
  });
};

// src/components/SizeSelector.tsx



// src/icons/Checkmark.tsx

var style2 = {
  width: 14,
  height: 14
};
var Checkmark = () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
  focusable: "false",
  role: "img",
  viewBox: "0 0 512 512",
  style: style2,
  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
    fill: "currentColor",
    d: "M435.848 83.466L172.804 346.51l-96.652-96.652c-4.686-4.686-12.284-4.686-16.971 0l-28.284 28.284c-4.686 4.686-4.686 12.284 0 16.971l133.421 133.421c4.686 4.686 12.284 4.686 16.971 0l299.813-299.813c4.686-4.686 4.686-12.284 0-16.971l-28.284-28.284c-4.686-4.686-12.284-4.686-16.97 0z"
  })
});

// src/components/ControlButton.tsx


var CONTROL_BUTTON_PADDING = 6;
var ControlButton = (props) => {
  const style3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      opacity: props.disabled ? 0.5 : 1,
      display: "inline-flex",
      background: "none",
      border: "none",
      padding: CONTROL_BUTTON_PADDING
    };
  }, [props.disabled]);
  const { tabIndex } = useZIndex();
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
    type: "button",
    tabIndex,
    ...props,
    style: style3
  });
};

// src/components/NewComposition/ComboBox.tsx




var container13 = {
  padding: "8px 10px",
  display: "inline-block",
  backgroundColor: INPUT_BACKGROUND,
  borderWidth: 1,
  borderStyle: "solid",
  maxWidth: "100%"
};
var label2 = {
  flex: 1,
  overflow: "hidden",
  textOverflow: "ellipsis",
  fontSize: 14,
  textAlign: "left"
};
var Combobox = ({ values, selectedId, style: customStyle, title: title3 }) => {
  const [hovered, setIsHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const [opened, setOpened] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const { tabIndex, currentZIndex } = useZIndex();
  const size = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.useElementSize(ref, {
    triggerOnWindowResize: true,
    shouldApplyCssTransforms: true
  });
  const refresh = size?.refresh;
  const onHide = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setOpened(false);
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const { current } = ref;
    if (!current) {
      return;
    }
    const onMouseEnter = () => setIsHovered(true);
    const onMouseLeave = () => setIsHovered(false);
    const onPointerDown = () => {
      return setOpened((o) => {
        if (!o) {
          refresh?.();
        }
        return !o;
      });
    };
    const onClick = (e) => {
      e.stopPropagation();
      const isKeyboardInitiated = e.detail === 0;
      if (!isKeyboardInitiated) {
        return;
      }
      return setOpened((o) => {
        if (!o) {
          refresh?.();
          window.addEventListener("pointerup", (evt) => {
            if (!isMenuItem(evt.target)) {
              setOpened(false);
            }
          }, {
            once: true
          });
        }
        return !o;
      });
    };
    current.addEventListener("mouseenter", onMouseEnter);
    current.addEventListener("mouseleave", onMouseLeave);
    current.addEventListener("pointerdown", onPointerDown);
    current.addEventListener("click", onClick);
    return () => {
      current.removeEventListener("mouseenter", onMouseEnter);
      current.removeEventListener("mouseleave", onMouseLeave);
      current.removeEventListener("pointerdown", onPointerDown);
      current.removeEventListener("click", onClick);
    };
  }, [refresh]);
  const spaceToBottom = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const margin2 = 10;
    if (size && opened) {
      return size.windowSize.height - (size.top + size.height) - margin2;
    }
    return 0;
  }, [opened, size]);
  const spaceToTop = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const margin2 = 10;
    if (size && opened) {
      return size.top - margin2;
    }
    return 0;
  }, [opened, size]);
  const derivedMaxHeight = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return spaceToTop > spaceToBottom ? spaceToTop : spaceToBottom;
  }, [spaceToBottom, spaceToTop]);
  const isMobileLayout = useMobileLayout();
  const portalStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!opened || !size) {
      return null;
    }
    const spaceToRight = size.windowSize.width - size.left;
    const spaceToLeft = size.left + size.width;
    const minSpaceRequired = isMobileLayout ? MAX_MOBILE_MENU_WIDTH : MAX_MENU_WIDTH;
    const verticalLayout = spaceToTop > spaceToBottom ? "bottom" : "top";
    const canOpenOnLeft = spaceToLeft >= minSpaceRequired;
    const canOpenOnRight = spaceToRight >= minSpaceRequired;
    const horizontalLayout = canOpenOnRight ? "left" : "right";
    return {
      ...verticalLayout === "top" ? {
        ...menuContainerTowardsBottom,
        top: size.top + size.height
      } : {
        ...menuContainerTowardsTop,
        bottom: size.windowSize.height - size.top
      },
      ...horizontalLayout === "left" ? {
        left: size.left
      } : canOpenOnLeft ? {
        right: size.windowSize.width - size.left - size.width
      } : { left: 0 }
    };
  }, [isMobileLayout, opened, size, spaceToBottom, spaceToTop]);
  const selected = values.find((v) => v.id === selectedId);
  const style3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...container13,
      ...customStyle ?? {},
      userSelect: "none",
      WebkitUserSelect: "none",
      color: "white",
      display: "inline-flex",
      flexDirection: "row",
      alignItems: "center",
      borderColor: opened ? SELECTED_BACKGROUND : hovered ? INPUT_BORDER_COLOR_HOVERED : INPUT_BORDER_COLOR_UNHOVERED
    };
  }, [customStyle, hovered, opened]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("button", {
        ref,
        title: title3,
        tabIndex,
        type: "button",
        style: style3,
        className: MENU_INITIATOR_CLASSNAME,
        children: [
          selected ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            title: typeof selected.label === "string" ? selected.label : undefined,
            style: label2,
            children: selected?.label
          }) : null,
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 1
          }),
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CaretDown, {})
        ]
      }),
      portalStyle ? react_dom__WEBPACK_IMPORTED_MODULE_1__.createPortal(/* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: fullScreenOverlay,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: outerPortal,
          className: "css-reset",
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(HigherZIndex, {
            onOutsideClick: onHide,
            onEscape: onHide,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              style: portalStyle,
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MenuContent, {
                onNextMenu: noop,
                onPreviousMenu: noop,
                values,
                onHide,
                leaveLeftSpace: true,
                preselectIndex: values.findIndex((v) => selected && v.id === selected.id),
                topItemCanBeUnselected: false,
                fixedHeight: derivedMaxHeight
              })
            })
          })
        })
      }), getPortal(currentZIndex)) : null
    ]
  });
};

// src/components/Preview.tsx




// src/helpers/checkerboard-background.ts
var getCheckerboardBackgroundSize = (size) => `${size}px ${size}px`;
var getCheckerboardBackgroundPos = (size) => `0 0, ${size / 2}px 0, ${size / 2}px -${size / 2}px, 0px ${size / 2}px`;
var checkerboardBackgroundColor = (checkerboard) => {
  if (checkerboard) {
    return "white";
  }
  return "black";
};
var checkerboardBackgroundImage = (checkerboard) => {
  if (checkerboard) {
    return `
     linear-gradient(
        45deg,
        rgba(0, 0, 0, 0.1) 25%,
        transparent 25%
      ),
      linear-gradient(135deg, rgba(0, 0, 0, 0.1) 25%, transparent 25%),
      linear-gradient(45deg, transparent 75%, rgba(0, 0, 0, 0.1) 75%),
      linear-gradient(135deg, transparent 75%, rgba(0, 0, 0, 0.1) 75%)
    `;
  }
  return;
};

// src/state/checkerboard.ts

var persistCheckerboardOption = (option) => {
  localStorage.setItem("option", String(option));
};
var loadCheckerboardOption = () => {
  const item = localStorage.getItem("option");
  return item !== "false";
};
var CheckerboardContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  checkerboard: loadCheckerboardOption(),
  setCheckerboard: () => {
    return;
  }
});

// src/components/RenderPreview.tsx


// src/helpers/get-asset-metadata.ts


var remotion_outputsBase = window.remotion_staticBase.replace("static", "outputs");
var getSrcFromCanvasContent = (canvasContent) => {
  if (canvasContent.type === "asset") {
    return (0,remotion__WEBPACK_IMPORTED_MODULE_2__.staticFile)(canvasContent.asset);
  }
  return remotion_outputsBase + canvasContent.path;
};
var getAssetMetadata = async (canvasContent, addTime) => {
  if (canvasContent.type === "output-blob") {
    return {
      type: "found",
      size: canvasContent.sizeInBytes,
      dimensions: { width: canvasContent.width, height: canvasContent.height },
      fetchedAt: Date.now()
    };
  }
  if (canvasContent.type === "composition") {
    throw new Error("cannot get dimensions for composition");
  }
  const src = getSrcFromCanvasContent(canvasContent);
  const file = await fetch(src, {
    method: "HEAD"
  });
  if (file.status === 404) {
    return { type: "not-found" };
  }
  if (file.status !== 200) {
    throw new Error(`Expected status code 200 or 404 for file, got ${file.status}`);
  }
  const size = file.headers.get("content-length");
  if (!size) {
    throw new Error("Unexpected error: content-length is null");
  }
  const fetchedAt = Date.now();
  const srcWithTime = addTime ? `${src}?date=${fetchedAt}` : src;
  const fileType = getPreviewFileType(src);
  if (fileType === "video") {
    const resolution = await (0,_remotion_media_utils__WEBPACK_IMPORTED_MODULE_10__.getVideoMetadata)(srcWithTime);
    return {
      type: "found",
      size: Number(size),
      dimensions: { width: resolution.width, height: resolution.height },
      fetchedAt
    };
  }
  if (fileType === "image") {
    const resolution = await new Promise((resolve, reject) => {
      const img = new Image;
      img.onload = () => {
        resolve({
          type: "found",
          size: Number(size),
          dimensions: { width: img.width, height: img.height },
          fetchedAt
        });
      };
      img.onerror = () => {
        reject(new Error("Failed to load image"));
      };
      img.src = srcWithTime;
    });
    return resolution;
  }
  return {
    type: "found",
    dimensions: "none",
    size: Number(size),
    fetchedAt
  };
};

// src/components/FilePreview.tsx


// src/components/JSONViewer.tsx


// src/components/NewComposition/RemTextarea.tsx


// src/components/NewComposition/RemInput.tsx


var INPUT_HORIZONTAL_PADDING = 8;
var aligner = {
  marginRight: -INPUT_HORIZONTAL_PADDING
};
var RightAlignInput = ({ children }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: aligner,
    children
  });
};
var inputBaseStyle = {
  padding: `${INPUT_HORIZONTAL_PADDING}px 10px`,
  color: "white",
  borderStyle: "solid",
  borderWidth: 1,
  fontSize: 14
};
var getInputBorderColor = ({
  status,
  isFocused,
  isHovered
}) => status === "warning" ? WARNING_COLOR : status === "error" ? FAIL_COLOR : isFocused ? SELECTED_BACKGROUND : isHovered ? INPUT_BORDER_COLOR_HOVERED : INPUT_BORDER_COLOR_UNHOVERED;
var RemInputForwardRef = ({ status, rightAlign, ...props }, ref) => {
  const [isFocused, setIsFocused] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const [isHovered, setIsHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const inputRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const { tabIndex } = useZIndex();
  const style3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      backgroundColor: INPUT_BACKGROUND,
      ...inputBaseStyle,
      width: "100%",
      borderColor: getInputBorderColor({ isFocused, isHovered, status }),
      textAlign: rightAlign ? "right" : "left",
      ...props.style ?? {}
    };
  }, [isFocused, isHovered, rightAlign, props.style, status]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(ref, () => {
    return inputRef.current;
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!inputRef.current) {
      return;
    }
    const { current } = inputRef;
    const onFocus = () => setIsFocused(true);
    const onBlur = () => setIsFocused(false);
    const onMouseEnter = () => setIsHovered(true);
    const onMouseLeave = () => setIsHovered(false);
    current.addEventListener("focus", onFocus);
    current.addEventListener("blur", onBlur);
    current.addEventListener("mouseenter", onMouseEnter);
    current.addEventListener("mouseleave", onMouseLeave);
    return () => {
      current.removeEventListener("focus", onFocus);
      current.removeEventListener("blur", onBlur);
      current.removeEventListener("mouseenter", onMouseEnter);
      current.removeEventListener("mouseleave", onMouseLeave);
    };
  }, [inputRef]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("input", {
    ref: inputRef,
    tabIndex,
    ...props,
    style: style3
  });
};
var RemotionInput = (0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(RemInputForwardRef);

// src/components/NewComposition/RemTextarea.tsx

var inputBaseStyle2 = {
  padding: `${INPUT_HORIZONTAL_PADDING}px 10px`,
  color: "white",
  borderStyle: "solid",
  borderWidth: 1,
  fontSize: 14,
  resize: "none",
  overflowX: "hidden"
};
var RemTextareaFRFunction = ({ status, ...props }, ref) => {
  const [isFocused, setIsFocused] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const [isHovered, setIsHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const inputRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const { tabIndex } = useZIndex();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(ref, () => {
    return inputRef.current;
  }, []);
  const style3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      backgroundColor: INPUT_BACKGROUND,
      ...inputBaseStyle2,
      width: "100%",
      borderColor: getInputBorderColor({ isFocused, isHovered, status }),
      ...props.style ?? {}
    };
  }, [isFocused, isHovered, props.style, status]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!inputRef.current) {
      return;
    }
    const { current } = inputRef;
    const onFocus = () => setIsFocused(true);
    const onBlur = () => setIsFocused(false);
    const onMouseEnter = () => setIsHovered(true);
    const onMouseLeave = () => setIsHovered(false);
    const onKeyDown = (e) => {
      if (!inputRef.current) {
        return;
      }
      if (inputRef.current !== document.activeElement) {
        return;
      }
      if (e.code === "Tab") {
        e.preventDefault();
        document.execCommand("insertText", false, " ".repeat(2));
      }
      if (e.code === "Enter") {
        e.preventDefault();
        const { selectionStart, selectionEnd, value } = inputRef.current;
        if (selectionStart !== selectionEnd) {
          return;
        }
        let prevNewline = selectionStart;
        for (let i = selectionStart - 1;i >= 0; i--) {
          if (value[i] === `
`) {
            break;
          }
          prevNewline = i;
        }
        const currentLine = value.substring(prevNewline, selectionStart);
        const trimmed = currentLine.trim();
        const difference = currentLine.length - trimmed.length;
        document.execCommand("insertText", false, `
` + " ".repeat(difference));
      }
    };
    current.addEventListener("focus", onFocus);
    current.addEventListener("blur", onBlur);
    current.addEventListener("mouseenter", onMouseEnter);
    current.addEventListener("mouseleave", onMouseLeave);
    current.addEventListener("keydown", onKeyDown);
    return () => {
      current.removeEventListener("focus", onFocus);
      current.removeEventListener("blur", onBlur);
      current.removeEventListener("mouseenter", onMouseEnter);
      current.removeEventListener("mouseleave", onMouseLeave);
      current.removeEventListener("keydown", onKeyDown);
    };
  }, [inputRef]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("textarea", {
    ref: inputRef,
    tabIndex,
    ...props,
    className: VERTICAL_SCROLLBAR_CLASSNAME,
    style: style3
  });
};
var RemTextarea = (0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(RemTextareaFRFunction);

// src/components/JSONViewer.tsx

var jsonStyle = {
  marginTop: 14,
  marginBottom: 14,
  fontFamily: "monospace",
  flex: 1
};
var JSONViewer = ({ src }) => {
  const [json, setJson] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    fetch(src).then((res) => res.json()).then((jsonRes) => {
      setJson(JSON.stringify(jsonRes, null, 2));
    });
  }, [src]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemTextarea, {
    value: json ?? undefined,
    status: "ok",
    onChange: () => {
      return null;
    },
    style: jsonStyle
  });
};

// src/components/TextViewer.tsx


var textStyle = {
  margin: 14,
  fontFamily: "monospace",
  flex: 1,
  color: "white",
  whiteSpace: "pre-wrap"
};
var TextViewer = ({ src }) => {
  const [txt, setTxt] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)("");
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    fetch(src).then(async (res) => {
      if (!res.ok || !res.body) {
        return;
      }
      const text = await res.text();
      setTxt(text);
    });
  }, [src]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: textStyle,
    children: [
      txt,
      " "
    ]
  });
};

// src/components/FilePreview.tsx

var msgStyle = {
  fontSize: 13,
  color: "white",
  fontFamily: "sans-serif",
  display: "flex",
  justifyContent: "center"
};
var FilePreview = ({ fileType, src, currentAsset, assetMetadata }) => {
  if (!assetMetadata) {
    throw new Error("expected to have assetMetadata");
  }
  if (assetMetadata.type === "not-found") {
    throw new Error('expected to have assetMetadata, got "not-found"');
  }
  if (fileType === "audio") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("audio", {
      src,
      controls: true
    });
  }
  if (fileType === "video") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("video", {
      src,
      controls: true
    });
  }
  if (fileType === "image") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("img", {
      src
    });
  }
  if (fileType === "json") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(JSONViewer, {
      src
    });
  }
  if (fileType === "txt") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TextViewer, {
      src
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: msgStyle,
        children: currentAsset
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 0.5
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: msgStyle,
        children: [
          "Size: ",
          (0,_remotion_studio_shared__WEBPACK_IMPORTED_MODULE_6__/* .formatBytes */ .z3)(assetMetadata.size),
          " "
        ]
      })
    ]
  });
};

// src/components/RenderPreview.tsx

var msgStyle2 = {
  fontSize: 13,
  color: "white",
  fontFamily: "sans-serif",
  display: "flex",
  justifyContent: "center"
};
var errMsgStyle = {
  ...msgStyle2,
  color: LIGHT_TEXT
};
var RenderPreview = ({ path, assetMetadata, getBlob }) => {
  const fileType = getPreviewFileType(path);
  const connectionStatus = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx).previewServerState.type;
  const [blobUrl, setBlobUrl] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const [blobError, setBlobError] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!getBlob) {
      setBlobUrl(null);
      setBlobError(null);
      return;
    }
    let cancelled = false;
    let blobUrlToRevoke = null;
    setBlobError(null);
    getBlob().then((blob) => {
      const url = URL.createObjectURL(blob);
      if (cancelled) {
        URL.revokeObjectURL(url);
        return;
      }
      blobUrlToRevoke = url;
      setBlobUrl(url);
    }).catch((err) => {
      if (cancelled) {
        return;
      }
      setBlobError(err instanceof Error ? err : new Error(String(err)));
    });
    return () => {
      cancelled = true;
      if (blobUrlToRevoke) {
        URL.revokeObjectURL(blobUrlToRevoke);
      }
    };
  }, [getBlob]);
  const src = blobUrl ?? remotion_outputsBase + path;
  if (connectionStatus === "disconnected") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: errMsgStyle,
      children: "Studio server disconnected"
    });
  }
  if (getBlob && blobError) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
      style: errMsgStyle,
      children: [
        "Failed to load preview: ",
        blobError.message
      ]
    });
  }
  if (getBlob && !blobUrl) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: msgStyle2,
      children: "Loading preview..."
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FilePreview, {
    assetMetadata,
    currentAsset: path,
    fileType,
    src
  });
};

// src/components/Spinner.tsx


var viewBox = 100;
var lines = 8;
var className = "__remotion_spinner_line";
var remotionSpinnerAnimation = "__remotion_spinner_animation";
var translated = "M 44 0 L 50 0 a 6 6 0 0 1 6 6 L 56 26 a 6 6 0 0 1 -6 6 L 50 32 a 6 6 0 0 1 -6 -6 L 44 6 a 6 6 0 0 1 6 -6 Z";
var Spinner = ({ size, duration }) => {
  const style3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      width: size,
      height: size
    };
  }, [size]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("style", {
        type: "text/css",
        children: `
				@keyframes ${remotionSpinnerAnimation} {
          0% {
            opacity: 1;
          }
          100% {
            opacity: 0.15;
          }
        }
        
        .${className} {
            animation: ${remotionSpinnerAnimation} ${duration}s linear infinite;
        }        
			`
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
        style: style3,
        viewBox: `0 0 ${viewBox} ${viewBox}`,
        children: new Array(lines).fill(true).map((_, index) => {
          return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
            className,
            style: {
              rotate: `${index * Math.PI * 2 / lines}rad`,
              transformOrigin: "center center",
              animationDelay: `${index * (duration / lines) - duration}s`
            },
            d: translated,
            fill: LIGHT_TEXT
          }, index);
        })
      })
    ]
  });
};

// src/components/StaticFilePreview.tsx



var msgStyle3 = {
  fontSize: 13,
  color: "white",
  fontFamily: "sans-serif",
  display: "flex",
  justifyContent: "center"
};
var errMsgStyle2 = {
  ...msgStyle3,
  color: LIGHT_TEXT
};
var StaticFilePreview = ({ currentAsset, assetMetadata }) => {
  const fileType = getPreviewFileType(currentAsset);
  const staticFileSrc = (0,remotion__WEBPACK_IMPORTED_MODULE_2__.staticFile)(currentAsset);
  const staticFiles = useStaticFiles();
  const connectionStatus = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx).previewServerState.type;
  const exists = staticFiles.find((file) => file.name === currentAsset);
  if (connectionStatus === "disconnected") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: errMsgStyle2,
      children: "Studio server disconnected"
    });
  }
  if (!exists) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
      style: errMsgStyle2,
      children: [
        currentAsset,
        " does not exist in your public folder."
      ]
    });
  }
  if (!currentAsset) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FilePreview, {
    currentAsset,
    fileType,
    src: `${staticFileSrc}?date=${assetMetadata && assetMetadata.type === "found" ? assetMetadata.fetchedAt : 0}`,
    assetMetadata
  });
};

// src/components/Preview.tsx

var centeredContainer = {
  display: "flex",
  flex: 1,
  justifyContent: "center",
  alignItems: "center"
};
var label3 = {
  fontFamily: "sans-serif",
  fontSize: 14,
  color: LIGHT_TEXT
};
var getPreviewFileType = (fileName) => {
  if (!fileName) {
    return "other";
  }
  const audioExtensions = ["mp3", "wav", "ogg", "aac"];
  const videoExtensions = ["mp4", "avi", "mkv", "mov", "webm"];
  const imageExtensions = ["jpg", "jpeg", "png", "gif", "bmp"];
  const fileExtension = fileName.split(".").pop()?.toLowerCase();
  if (fileExtension === undefined) {
    throw new Error("File extension is undefined");
  }
  if (audioExtensions.includes(fileExtension)) {
    return "audio";
  }
  if (videoExtensions.includes(fileExtension)) {
    return "video";
  }
  if (imageExtensions.includes(fileExtension)) {
    return "image";
  }
  if (fileExtension === "json") {
    return "json";
  }
  if (fileExtension === "txt") {
    return "txt";
  }
  return "other";
};
var checkerboardSize = 49;
var containerStyle = (options) => {
  return {
    transform: `scale(${options.scale})`,
    marginLeft: options.xCorrection,
    marginTop: options.yCorrection,
    width: options.width,
    height: options.height,
    display: "flex",
    position: "absolute",
    backgroundColor: checkerboardBackgroundColor(options.checkerboard),
    backgroundImage: checkerboardBackgroundImage(options.checkerboard),
    backgroundSize: getCheckerboardBackgroundSize(checkerboardSize),
    backgroundPosition: getCheckerboardBackgroundPos(checkerboardSize)
  };
};
var VideoPreview = ({ canvasSize, contentDimensions, canvasContent, assetMetadata }) => {
  if (assetMetadata && assetMetadata.type === "not-found") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: centeredContainer,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: label3,
        children: "File does not exist"
      })
    });
  }
  if (contentDimensions === null) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: centeredContainer,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spinner, {
        duration: 0.5,
        size: 24
      })
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CompWhenItHasDimensions, {
    contentDimensions,
    canvasSize,
    canvasContent,
    assetMetadata
  });
};
var CompWhenItHasDimensions = ({ contentDimensions, canvasSize, canvasContent, assetMetadata }) => {
  const { size: previewSize } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.PreviewSizeContext);
  const { centerX, centerY, yCorrection, xCorrection, scale } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (contentDimensions === "none") {
      return {
        centerX: 0,
        centerY: 0,
        yCorrection: 0,
        xCorrection: 0,
        scale: 1
      };
    }
    return _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.calculateCanvasTransformation({
      canvasSize,
      compositionHeight: contentDimensions.height,
      compositionWidth: contentDimensions.width,
      previewSize: previewSize.size
    });
  }, [canvasSize, contentDimensions, previewSize.size]);
  const outer = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      width: contentDimensions === "none" ? "100%" : contentDimensions.width * scale,
      height: contentDimensions === "none" ? "100%" : contentDimensions.height * scale,
      display: "flex",
      flexDirection: "column",
      position: "absolute",
      left: centerX - previewSize.translation.x,
      top: centerY - previewSize.translation.y,
      overflow: "hidden",
      justifyContent: canvasContent.type === "asset" ? "center" : "flex-start",
      alignItems: canvasContent.type === "asset" && getPreviewFileType(canvasContent.asset) === "audio" ? "center" : "normal"
    };
  }, [
    contentDimensions,
    scale,
    centerX,
    previewSize.translation.x,
    previewSize.translation.y,
    centerY,
    canvasContent
  ]);
  if (canvasContent.type === "asset") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: outer,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(StaticFilePreview, {
        assetMetadata,
        currentAsset: canvasContent.asset
      })
    });
  }
  if (canvasContent.type === "output") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: outer,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderPreview, {
        path: canvasContent.path,
        assetMetadata
      })
    });
  }
  if (canvasContent.type === "output-blob") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: outer,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderPreview, {
        path: canvasContent.displayName,
        assetMetadata,
        getBlob: canvasContent.getBlob
      })
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: outer,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(PortalContainer, {
      contentDimensions,
      scale,
      xCorrection,
      yCorrection
    })
  });
};
var PortalContainer = ({ scale, xCorrection, yCorrection, contentDimensions }) => {
  const { checkerboard } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(CheckerboardContext);
  const style3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return containerStyle({
      checkerboard,
      scale,
      xCorrection,
      yCorrection,
      width: contentDimensions.width,
      height: contentDimensions.height
    });
  }, [
    checkerboard,
    contentDimensions.height,
    contentDimensions.width,
    scale,
    xCorrection,
    yCorrection
  ]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const { current } = portalContainer;
    current?.appendChild(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.portalNode());
    return () => {
      current?.removeChild(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.portalNode());
    };
  }, []);
  const portalContainer = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    ref: portalContainer,
    style: style3
  });
};

// src/components/SizeSelector.tsx

var commonPreviewSizes = [
  {
    size: "auto",
    translation: {
      x: 0,
      y: 0
    }
  },
  {
    size: 0.25,
    translation: {
      x: 0,
      y: 0
    }
  },
  {
    size: 0.5,
    translation: {
      x: 0,
      y: 0
    }
  },
  {
    size: 1,
    translation: {
      x: 0,
      y: 0
    }
  }
];
var getPreviewSizeLabel = (previewSize) => {
  if (previewSize.size === "auto") {
    return "Fit";
  }
  return `${(previewSize.size * 100).toFixed(0)}%`;
};
var accessibilityLabel = "Preview Size";
var comboStyle = { width: 80 };
var getUniqueSizes = (size) => {
  const customPreviewSizes = [size, ...commonPreviewSizes];
  const uniqueSizes = [];
  customPreviewSizes.forEach((p) => {
    if (!uniqueSizes.find((s) => s.size === p.size)) {
      uniqueSizes.push(p);
    }
  });
  return uniqueSizes.sort((a, b) => {
    if (a.size === "auto") {
      return -1;
    }
    if (b.size === "auto") {
      return 1;
    }
    return a.size - b.size;
  });
};
var zoomableFileTypes = ["video", "image"];
var SizeSelector = () => {
  const { size, setSize } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.PreviewSizeContext);
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const style3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      padding: CONTROL_BUTTON_PADDING
    };
  }, []);
  const zoomable = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!canvasContent) {
      return null;
    }
    if (canvasContent.type === "composition") {
      return true;
    }
    if (canvasContent.type === "asset" && zoomableFileTypes.includes(getPreviewFileType(canvasContent.asset))) {
      return true;
    }
    if (canvasContent.type === "output" && zoomableFileTypes.includes(getPreviewFileType(canvasContent.path))) {
      return true;
    }
    return false;
  }, [canvasContent]);
  const items = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return getUniqueSizes(size).map((newSize) => {
      return {
        id: String(newSize.size),
        label: getPreviewSizeLabel(newSize),
        onClick: () => {
          return setSize(() => {
            return newSize;
          });
        },
        type: "item",
        value: newSize.size,
        keyHint: newSize.size === "auto" ? "0" : null,
        leftItem: String(size.size) === String(newSize.size) ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        subMenu: null,
        quickSwitcherLabel: null
      };
    });
  }, [setSize, size]);
  if (!zoomable) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: style3,
    "aria-label": accessibilityLabel,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
      title: accessibilityLabel,
      style: comboStyle,
      selectedId: String(size.size),
      values: items
    })
  });
};

// src/components/TimelineInOutToggle.tsx





// src/icons/timelineInOutPointer.tsx

var TimelineInPointer = (props) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    viewBox: "0 0 256 256",
    fill: "none",
    ...props,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      d: "M158 25H99V230.5H158",
      stroke: props.color,
      strokeWidth: "42",
      strokeLinecap: "round",
      strokeLinejoin: "round"
    })
  });
};
var TimelineOutPointer = (props) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    viewBox: "0 0 256 256",
    fill: "none",
    ...props,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      d: "M98 25H157V230.5H98",
      stroke: props.color,
      strokeWidth: "42",
      strokeLinecap: "round",
      strokeLinejoin: "round"
    })
  });
};

// src/state/in-out.ts


var TimelineInOutContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({});
var SetTimelineInOutContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  setInAndOutFrames: () => {
    throw new Error("default");
  }
});
var useTimelineInOutFramePosition = () => {
  const videoConfig = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useUnsafeVideoConfig();
  const state = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(TimelineInOutContext);
  const id = videoConfig?.id;
  const durationInFrames = videoConfig?.durationInFrames;
  return (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!id || !durationInFrames) {
      return { inFrame: null, outFrame: null };
    }
    const maxFrame = durationInFrames - 1;
    const actualInFrame = state[id]?.inFrame ?? null;
    const actualOutFrame = state[id]?.outFrame ?? null;
    return {
      inFrame: actualInFrame === null ? null : actualInFrame >= maxFrame ? null : actualInFrame,
      outFrame: actualOutFrame === null ? null : actualOutFrame >= maxFrame ? null : actualOutFrame
    };
  }, [durationInFrames, id, state]);
};
var useTimelineSetInOutFramePosition = () => {
  const { setInAndOutFrames } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SetTimelineInOutContext);
  return { setInAndOutFrames };
};

// src/components/TimelineInOutToggle.tsx

var getTooltipText = (pointType, key) => [
  `Mark ${pointType}`,
  areKeyboardShortcutsDisabled() ? null : `(${key})`,
  "- right click to clear"
].filter(remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.truthy).join(" ");
var style3 = {
  width: 16,
  height: 16
};
var inOutHandles = (0,react__WEBPACK_IMPORTED_MODULE_0__.createRef)();
var defaultInOutValue = { inFrame: null, outFrame: null };
var TimelineInOutPointToggle = () => {
  const { inFrame, outFrame } = useTimelineInOutFramePosition();
  const { setInAndOutFrames } = useTimelineSetInOutFramePosition();
  const videoConfig = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useUnsafeVideoConfig();
  const keybindings = useKeybinding();
  const { getCurrentFrame: getCurrentFrame2, isFirstFrame, isLastFrame } = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.usePlayer();
  const onInOutClear = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((composition) => {
    setInAndOutFrames((prev) => {
      return {
        ...prev,
        [composition]: {
          inFrame: null,
          outFrame: null
        }
      };
    });
  }, [setInAndOutFrames]);
  const onInMark = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (!videoConfig) {
      return null;
    }
    if (e?.shiftKey) {
      setInAndOutFrames((prev) => {
        return {
          ...prev,
          [videoConfig.id]: {
            ...prev[videoConfig.id] ?? defaultInOutValue,
            inFrame: null
          }
        };
      });
      return null;
    }
    setInAndOutFrames((prev) => {
      const prevOut = prev[videoConfig.id]?.outFrame;
      const biggestPossible = prevOut === undefined || prevOut === null ? Infinity : prevOut - 1;
      const selected = Math.min(getCurrentFrame2(), biggestPossible);
      if (selected === 0) {
        return {
          ...prev,
          [videoConfig.id]: {
            ...prev[videoConfig.id] ?? defaultInOutValue,
            inFrame: null
          }
        };
      }
      const prevIn = prev[videoConfig.id]?.inFrame;
      if (prevIn !== null && prevIn !== undefined) {
        if (prevIn === selected) {
          return {
            ...prev,
            [videoConfig.id]: {
              ...prev[videoConfig.id] ?? defaultInOutValue,
              inFrame: null
            }
          };
        }
      }
      return {
        ...prev,
        [videoConfig.id]: {
          ...prev[videoConfig.id] ?? defaultInOutValue,
          inFrame: selected
        }
      };
    });
  }, [getCurrentFrame2, setInAndOutFrames, videoConfig]);
  const clearInMark = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (!videoConfig) {
      return null;
    }
    e.preventDefault();
    setInAndOutFrames((f) => {
      return {
        ...f,
        [videoConfig.id]: {
          ...f[videoConfig.id] ?? defaultInOutValue,
          inFrame: null
        }
      };
    });
  }, [setInAndOutFrames, videoConfig]);
  const clearOutMark = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (!videoConfig) {
      return null;
    }
    e?.preventDefault();
    setInAndOutFrames((f) => {
      return {
        ...f,
        [videoConfig.id]: {
          ...f[videoConfig.id] ?? defaultInOutValue,
          outFrame: null
        }
      };
    });
  }, [setInAndOutFrames, videoConfig]);
  const onOutMark = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (!videoConfig) {
      return null;
    }
    if (e?.shiftKey) {
      setInAndOutFrames((f) => {
        return {
          ...f,
          [videoConfig.id]: {
            ...f[videoConfig.id] ?? defaultInOutValue,
            outFrame: null
          }
        };
      });
      return;
    }
    setInAndOutFrames((prev) => {
      const prevInFrame = prev[videoConfig.id]?.inFrame;
      const smallestPossible = prevInFrame === null || prevInFrame === undefined ? -Infinity : prevInFrame + 1;
      const selected = Math.max(getCurrentFrame2(), smallestPossible);
      if (selected === videoConfig.durationInFrames - 1) {
        return {
          ...prev,
          [videoConfig.id]: {
            ...prev[videoConfig.id] ?? defaultInOutValue,
            outFrame: null
          }
        };
      }
      const prevOut = prev[videoConfig.id]?.outFrame;
      if (prevOut !== null && prevOut !== undefined) {
        if (prevOut === selected) {
          return {
            ...prev,
            [videoConfig.id]: {
              ...prev[videoConfig.id] ?? defaultInOutValue,
              outFrame: null
            }
          };
        }
      }
      return {
        ...prev,
        [videoConfig.id]: {
          ...prev[videoConfig.id] ?? defaultInOutValue,
          outFrame: selected
        }
      };
    });
  }, [getCurrentFrame2, setInAndOutFrames, videoConfig]);
  const confId = videoConfig?.id;
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!confId) {
      return;
    }
    const iKey = keybindings.registerKeybinding({
      event: "keypress",
      key: "i",
      callback: (e) => {
        onInMark(e);
      },
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const oKey = keybindings.registerKeybinding({
      event: "keypress",
      key: "o",
      callback: (e) => {
        onOutMark(e);
      },
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const xKey = keybindings.registerKeybinding({
      event: "keypress",
      key: "x",
      callback: () => {
        onInOutClear(confId);
      },
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      oKey.unregister();
      iKey.unregister();
      xKey.unregister();
    };
  }, [confId, keybindings, onInMark, onInOutClear, onOutMark]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(inOutHandles, () => {
    return {
      clearMarks: () => {
        if (!confId) {
          return;
        }
        onInOutClear(confId);
      },
      inMarkClick: onInMark,
      outMarkClick: onOutMark
    };
  }, [confId, onInMark, onInOutClear, onOutMark]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ControlButton, {
        title: getTooltipText("In", "I"),
        "aria-label": getTooltipText("In", "I"),
        onClick: onInMark,
        onContextMenu: clearInMark,
        disabled: !videoConfig || isFirstFrame,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineInPointer, {
          color: inFrame === null ? "white" : BLUE,
          style: style3
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ControlButton, {
        title: getTooltipText("Out", "O"),
        "aria-label": getTooltipText("Out", "O"),
        onClick: onOutMark,
        onContextMenu: clearOutMark,
        disabled: !videoConfig || isLastFrame,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineOutPointer, {
          color: outFrame === null ? "white" : BLUE,
          style: style3
        })
      })
    ]
  });
};

// src/error-overlay/remotion-overlay/ShortcutHint.tsx


var cmdOrCtrlCharacter = window.navigator.platform.startsWith("Mac") ? "⌘" : "Ctrl";
var container14 = {
  display: "inline-block",
  marginLeft: 6,
  opacity: 0.6,
  verticalAlign: "middle",
  fontSize: 14
};
var ShortcutHint = ({ keyToPress, cmdOrCtrl }) => {
  const style4 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (keyToPress === "↵") {
      return {
        display: "inline-block",
        transform: `translateY(2px)`,
        fontSize: 14
      };
    }
    return {};
  }, [keyToPress]);
  if (areKeyboardShortcutsDisabled()) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("span", {
    style: container14,
    children: [
      cmdOrCtrl ? `${cmdOrCtrlCharacter}` : "",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
        style: style4,
        children: keyToPress.toUpperCase()
      })
    ]
  });
};

// src/state/editor-guides.ts

var persistEditorShowGuidesOption = (option) => {
  localStorage.setItem("remotion.editorShowGuides", String(option));
};
var loadEditorShowGuidesOption = () => {
  const item = localStorage.getItem("remotion.editorShowGuides");
  return item === "true";
};
var persistGuidesList = (guides) => {
  localStorage.setItem("remotion.guidesList", JSON.stringify(guides));
};
var loadGuidesList = () => {
  const item = localStorage.getItem("remotion.guidesList");
  return item ? JSON.parse(item) : [];
};
var EditorShowGuidesContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  editorShowGuides: false,
  setEditorShowGuides: () => {
    return;
  },
  guidesList: [],
  setGuidesList: () => {
    return;
  },
  selectedGuideId: null,
  setSelectedGuideId: () => {
    return;
  },
  shouldCreateGuideRef: { current: false },
  shouldDeleteGuideRef: { current: false },
  hoveredGuideId: null,
  setHoveredGuideId: () => {
    return;
  }
});

// src/state/editor-rulers.ts

var persistEditorShowRulersOption = (option) => {
  localStorage.setItem("remotion.editorShowRulers", String(option));
};
var loadEditorShowRulersOption = () => {
  const item = localStorage.getItem("remotion.editorShowRulers");
  return item === "true";
};
var EditorShowRulersContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  editorShowRulers: loadEditorShowRulersOption(),
  setEditorShowRulers: () => {
    return;
  }
});
var RULER_WIDTH = 20;
var MINIMUM_VISIBLE_CANVAS_SIZE = 50;
var PREDEFINED_RULER_SCALE_GAPS = [
  1,
  2,
  5,
  10,
  20,
  50,
  100,
  250,
  500,
  1000,
  2000,
  5000
];
var MAXIMUM_PREDEFINED_RULER_SCALE_GAP = 5000;
var MINIMUM_RULER_MARKING_GAP_PX = 50;

// src/state/editor-zoom-gestures.ts

var persistEditorZoomGesturesOption = (option) => {
  localStorage.setItem("remotion.editorZoomGestures", String(option));
};
var loadEditorZoomGesturesOption = () => {
  const item = localStorage.getItem("remotion.editorZoomGestures");
  return item !== "false";
};
var EditorZoomGesturesContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  editorZoomGestures: loadEditorZoomGesturesOption(),
  setEditorZoomGestures: () => {
    return;
  }
});

// src/helpers/check-fullscreen-support.ts
var checkFullscreenSupport = () => {
  return document.fullscreenEnabled || document.webkitFullscreenEnabled;
};

// src/helpers/get-git-menu-item.ts
var getGitSourceName = (gitSource) => {
  if (gitSource.type === "github") {
    return "GitHub";
  }
  throw new Error("Unknown git source type");
};
var getGitSourceBranchUrl = (gitSource) => {
  if (gitSource.type === "github") {
    return `https://github.com/${gitSource.org}/${gitSource.name}/tree/${gitSource.ref}${gitSource.relativeFromGitRoot ? `/${gitSource.relativeFromGitRoot}` : ""}`;
  }
  throw new Error("Unknown git source type");
};
var getGitRefUrl = (gitSource, originalLocation) => {
  if (gitSource.type === "github") {
    return `https://github.com/${gitSource.org}/${gitSource.name}/tree/${gitSource.ref}/${gitSource.relativeFromGitRoot ? `${gitSource.relativeFromGitRoot}/` : ""}${originalLocation.source}#L${originalLocation.line}`;
  }
  throw new Error("Unknown git source type");
};
var getGitMenuItem = () => {
  if (!window.remotion_gitSource) {
    return null;
  }
  return {
    id: "open-git-source",
    value: "open-git-source",
    label: `Open ${getGitSourceName(window.remotion_gitSource)} Repo`,
    onClick: () => {
      window.open(getGitSourceBranchUrl(window.remotion_gitSource), "_blank");
    },
    type: "item",
    keyHint: null,
    leftItem: null,
    subMenu: null,
    quickSwitcherLabel: `Open ${getGitSourceName(window.remotion_gitSource)} repo`
  };
};

// src/helpers/open-in-editor.ts
var openInEditor = (stack) => {
  const {
    originalFileName,
    originalLineNumber,
    originalColumnNumber,
    originalFunctionName,
    originalScriptCode
  } = stack;
  return fetch(`/api/open-in-editor`, {
    method: "post",
    headers: {
      "content-type": "application/json"
    },
    body: JSON.stringify({
      stack: {
        originalFileName,
        originalLineNumber,
        originalColumnNumber,
        originalFunctionName,
        originalScriptCode
      }
    })
  });
};
var openOriginalPositionInEditor = async (originalPosition) => {
  await openInEditor({
    originalColumnNumber: originalPosition.column,
    originalFileName: originalPosition.source,
    originalFunctionName: null,
    originalLineNumber: originalPosition.line,
    originalScriptCode: null
  });
};

// src/components/Notifications/ColorDot.tsx


var container15 = {
  height: 16,
  width: 16,
  backgroundColor: "red",
  border: "1px solid rgba(255, 255, 255, 0.2)",
  borderRadius: 8
};
var ColorDot = ({ color }) => {
  const style4 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...container15,
      backgroundColor: color
    };
  }, [color]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: style4
  });
};

// src/helpers/pick-color.tsx

var pickColor = () => {
  const open = new EyeDropper().open();
  open.then((color) => {
    copyText(color.sRGBHex).then(() => {
      showNotification(/* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ColorDot, {
            color: color.sRGBHex
          }),
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 1
          }),
          " Copied",
          " ",
          color.sRGBHex
        ]
      }), 2000);
    }).catch((err) => {
      showNotification(`Could not copy: ${err.message}`, 2000);
    });
  }).catch((err) => {
    if (err.message.includes("canceled")) {
      return;
    }
    showNotification(`Could not pick color.`, 2000);
  });
};

// src/helpers/show-browser-rendering.ts
var SHOW_BROWSER_RENDERING = Boolean(false);

// src/helpers/use-menu-structure.tsx

var openExternal = (link) => {
  window.open(link, "_blank");
};
var rotate = {
  transform: `rotate(90deg)`
};
var ICON_SIZE = 16;
var getFileMenu = ({
  readOnlyStudio,
  closeMenu,
  previewServerState,
  setSelectedModal
}) => {
  const items = [
    window.remotion_isReadOnlyStudio ? {
      id: "input-props-override",
      value: "input-props-override",
      label: "Set input props...",
      onClick: () => {
        closeMenu();
        setSelectedModal({
          type: "input-props-override"
        });
      },
      type: "item",
      keyHint: null,
      leftItem: null,
      subMenu: null,
      quickSwitcherLabel: "Override input props"
    } : null,
    readOnlyStudio ? null : {
      id: "render",
      value: "render",
      label: "Render...",
      onClick: () => {
        closeMenu();
        if (previewServerState !== "connected") {
          showNotification("Restart the studio to render", 2000);
          return;
        }
        const renderButton = document.getElementById("render-modal-button-server");
        renderButton.click();
      },
      type: "item",
      keyHint: "R",
      leftItem: null,
      subMenu: null,
      quickSwitcherLabel: "Render..."
    },
    SHOW_BROWSER_RENDERING && !readOnlyStudio ? {
      id: "render-on-web",
      value: "render-on-web",
      label: "Render on web...",
      onClick: () => {
        closeMenu();
        const renderButton = document.getElementById("render-modal-button-client");
        renderButton.click();
      },
      type: "item",
      keyHint: null,
      leftItem: null,
      subMenu: null,
      quickSwitcherLabel: "Render on web..."
    } : null,
    window.remotion_editorName && !readOnlyStudio ? {
      type: "divider",
      id: "open-in-editor-divider"
    } : null,
    window.remotion_editorName && !readOnlyStudio ? {
      id: "open-in-editor",
      value: "open-in-editor",
      label: `Open in ${window.remotion_editorName}`,
      onClick: async () => {
        await openInEditor({
          originalFileName: `${window.remotion_cwd}`,
          originalLineNumber: 1,
          originalColumnNumber: 1,
          originalFunctionName: null,
          originalScriptCode: null
        }).then((res) => res.json()).then(({ success }) => {
          if (!success) {
            showNotification(`Could not open ${window.remotion_editorName}`, 2000);
          }
        }).catch((err) => {
          console.error(err);
          showNotification(`Could not open ${window.remotion_editorName}`, 2000);
        });
      },
      type: "item",
      keyHint: null,
      leftItem: null,
      subMenu: null,
      quickSwitcherLabel: "Open in editor..."
    } : null,
    getGitMenuItem()
  ].filter(remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.truthy);
  if (items.length === 0) {
    return null;
  }
  return {
    id: "file",
    label: "File",
    leaveLeftPadding: false,
    items,
    quickSwitcherLabel: null
  };
};
var useMenuStructure = (closeMenu, readOnlyStudio) => {
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const { checkerboard, setCheckerboard } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(CheckerboardContext);
  const { editorZoomGestures, setEditorZoomGestures } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(EditorZoomGesturesContext);
  const { editorShowRulers, setEditorShowRulers } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(EditorShowRulersContext);
  const { editorShowGuides, setEditorShowGuides } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(EditorShowGuidesContext);
  const { size, setSize } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.PreviewSizeContext);
  const { type } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx).previewServerState;
  const {
    setSidebarCollapsedState,
    sidebarCollapsedStateLeft,
    sidebarCollapsedStateRight
  } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SidebarContext);
  const sizes = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => getUniqueSizes(size), [size]);
  const isFullscreenSupported = checkFullscreenSupport();
  const { remotion_packageManager } = window;
  const sizePreselectIndex = sizes.findIndex((s) => String(size.size) === String(s.size));
  const mobileLayout = useMobileLayout();
  const structure = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    let struct = [
      {
        id: "remotion",
        label: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Row, {
          align: "center",
          justify: "center",
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
            width: ICON_SIZE,
            height: ICON_SIZE,
            viewBox: "-100 -100 400 400",
            style: rotate,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
              fill: "#fff",
              stroke: "#fff",
              strokeWidth: "100",
              strokeLinejoin: "round",
              d: "M 2 172 a 196 100 0 0 0 195 5 A 196 240 0 0 0 100 2.259 A 196 240 0 0 0 2 172 z"
            })
          })
        }),
        leaveLeftPadding: false,
        items: [
          {
            id: "about",
            value: "about",
            label: "About Remotion",
            onClick: () => {
              closeMenu();
              openExternal("https://remotion.dev");
            },
            type: "item",
            keyHint: null,
            leftItem: null,
            subMenu: null,
            quickSwitcherLabel: "Help: About Remotion"
          },
          {
            id: "changelog",
            value: "changelog",
            label: "Changelog",
            onClick: () => {
              closeMenu();
              openExternal("https://github.com/remotion-dev/remotion/releases");
            },
            type: "item",
            keyHint: null,
            leftItem: null,
            subMenu: null,
            quickSwitcherLabel: "Help: Changelog"
          },
          {
            id: "license",
            value: "license",
            label: "License",
            onClick: () => {
              closeMenu();
              openExternal("https://github.com/remotion-dev/remotion/blob/main/LICENSE.md");
            },
            type: "item",
            keyHint: null,
            leftItem: null,
            subMenu: null,
            quickSwitcherLabel: "Help: License"
          },
          {
            id: "acknowledgements",
            value: "acknowledgements",
            label: "Acknowledgements",
            onClick: () => {
              closeMenu();
              openExternal("https://remotion.dev/acknowledgements");
            },
            type: "item",
            keyHint: null,
            leftItem: null,
            subMenu: null,
            quickSwitcherLabel: "Help: Acknowledgements"
          },
          {
            type: "divider",
            id: "timeline-divider-1"
          },
          {
            id: "restart-studio",
            value: "restart-studio",
            label: "Restart Studio Server",
            onClick: () => {
              closeMenu();
              restartStudio();
            },
            type: "item",
            keyHint: null,
            leftItem: null,
            subMenu: null,
            quickSwitcherLabel: "Restart Studio Server"
          }
        ],
        quickSwitcherLabel: null
      },
      getFileMenu({
        readOnlyStudio,
        closeMenu,
        previewServerState: type,
        setSelectedModal
      }),
      {
        id: "view",
        label: "View",
        leaveLeftPadding: true,
        items: [
          {
            id: "preview-size",
            keyHint: null,
            label: "Preview size",
            onClick: () => {
              return;
            },
            type: "item",
            value: "preview-size",
            leftItem: null,
            subMenu: {
              leaveLeftSpace: true,
              preselectIndex: sizePreselectIndex,
              items: sizes.map((newSize) => ({
                id: String(newSize.size),
                keyHint: newSize.size === 1 ? "0" : null,
                label: getPreviewSizeLabel(newSize),
                leftItem: String(newSize.size) === String(size.size) ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
                onClick: () => {
                  closeMenu();
                  setSize(() => newSize);
                },
                subMenu: null,
                type: "item",
                value: newSize.size,
                quickSwitcherLabel: null
              })),
              quickSwitcherLabel: null
            },
            quickSwitcherLabel: null
          },
          {
            id: "editor-zoom-gestures",
            keyHint: null,
            label: "Zoom and Pan Gestures",
            onClick: () => {
              closeMenu();
              setEditorZoomGestures((c) => !c);
            },
            type: "item",
            value: "editor-zoom-gestures",
            leftItem: editorZoomGestures ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
            subMenu: null,
            quickSwitcherLabel: editorZoomGestures ? "Disable Zoom and Pan Gestures" : "Enable Zoom and Pan Gestures"
          },
          {
            id: "show-rulers",
            keyHint: null,
            label: "Show Rulers",
            onClick: () => {
              closeMenu();
              setEditorShowRulers((c) => !c);
            },
            type: "item",
            value: "show-ruler",
            leftItem: editorShowRulers ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
            subMenu: null,
            quickSwitcherLabel: editorShowRulers ? "Hide Rulers" : "Show Rulers"
          },
          {
            id: "show-guides",
            keyHint: null,
            label: "Show Guides",
            onClick: () => {
              closeMenu();
              setEditorShowGuides((c) => !c);
            },
            type: "item",
            value: "show-guides",
            leftItem: editorShowGuides ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
            subMenu: null,
            quickSwitcherLabel: editorShowGuides ? "Hide Guides" : "Show Guides"
          },
          {
            id: "timeline-divider-1",
            type: "divider"
          },
          {
            id: "left-sidebar",
            label: "Left Sidebar",
            keyHint: null,
            type: "item",
            value: "preview-size",
            leftItem: null,
            quickSwitcherLabel: null,
            subMenu: {
              leaveLeftSpace: true,
              preselectIndex: 0,
              items: [
                {
                  id: "left-sidebar-responsive",
                  keyHint: null,
                  label: "Responsive",
                  leftItem: sidebarCollapsedStateLeft === "responsive" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
                  onClick: () => {
                    closeMenu();
                    setSidebarCollapsedState({
                      left: "responsive",
                      right: null
                    });
                  },
                  subMenu: null,
                  type: "item",
                  value: "responsive",
                  quickSwitcherLabel: null
                },
                {
                  id: "left-sidebar-expanded",
                  keyHint: null,
                  label: "Expanded",
                  leftItem: sidebarCollapsedStateLeft === "expanded" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
                  onClick: () => {
                    closeMenu();
                    setSidebarCollapsedState({ left: "expanded", right: null });
                  },
                  subMenu: null,
                  type: "item",
                  value: "expanded",
                  quickSwitcherLabel: "Expand"
                },
                {
                  id: "left-sidebar-collapsed",
                  keyHint: null,
                  label: "Collapsed",
                  leftItem: sidebarCollapsedStateLeft === "collapsed" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
                  onClick: () => {
                    closeMenu();
                    setSidebarCollapsedState({
                      left: "collapsed",
                      right: null
                    });
                  },
                  subMenu: null,
                  type: "item",
                  value: "collapsed",
                  quickSwitcherLabel: "Collapse"
                }
              ]
            },
            onClick: () => {
              return;
            }
          },
          {
            id: "right-sidebar",
            label: "Right Sidebar",
            keyHint: null,
            type: "item",
            value: "preview-size",
            leftItem: null,
            quickSwitcherLabel: null,
            subMenu: {
              leaveLeftSpace: true,
              preselectIndex: 0,
              items: [
                {
                  id: "sidebar-expanded",
                  keyHint: null,
                  label: "Expanded",
                  leftItem: sidebarCollapsedStateRight === "expanded" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
                  onClick: () => {
                    closeMenu();
                    setSidebarCollapsedState({ left: null, right: "expanded" });
                  },
                  subMenu: null,
                  type: "item",
                  value: "expanded",
                  quickSwitcherLabel: "Expand"
                },
                {
                  id: "right-sidebar-collapsed",
                  keyHint: null,
                  label: "Collapsed",
                  leftItem: sidebarCollapsedStateRight === "collapsed" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
                  onClick: () => {
                    closeMenu();
                    setSidebarCollapsedState({
                      left: null,
                      right: "collapsed"
                    });
                  },
                  subMenu: null,
                  type: "item",
                  value: "collapsed",
                  quickSwitcherLabel: "Collapse"
                }
              ]
            },
            onClick: () => {
              return;
            }
          },
          {
            id: "timeline-divider-2",
            type: "divider"
          },
          {
            id: "checkerboard",
            keyHint: "T",
            label: "Transparency as checkerboard",
            onClick: () => {
              closeMenu();
              setCheckerboard((c) => !c);
            },
            type: "item",
            value: "checkerboard",
            leftItem: checkerboard ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
            subMenu: null,
            quickSwitcherLabel: checkerboard ? "Disable Checkerboard Transparency" : "Enable Checkerboard Transparency"
          },
          {
            id: "timeline-divider-3",
            type: "divider"
          },
          {
            id: "quick-switcher",
            keyHint: `${cmdOrCtrlCharacter}+K`,
            label: "Quick Switcher",
            onClick: () => {
              closeMenu();
              setSelectedModal({
                type: "quick-switcher",
                mode: "compositions",
                invocationTimestamp: Date.now()
              });
            },
            type: "item",
            value: "quick-switcher",
            leftItem: null,
            subMenu: null,
            quickSwitcherLabel: "Switch composition"
          },
          {
            id: "in-out-divider-5",
            type: "divider"
          },
          {
            id: "in-mark",
            keyHint: "I",
            label: "In Mark",
            leftItem: null,
            onClick: () => {
              closeMenu();
              inOutHandles.current?.inMarkClick(null);
            },
            subMenu: null,
            type: "item",
            value: "in-mark",
            quickSwitcherLabel: "Timeline: Set In Mark"
          },
          {
            id: "out-mark",
            keyHint: "O",
            label: "Out Mark",
            leftItem: null,
            onClick: () => {
              closeMenu();
              inOutHandles.current?.outMarkClick(null);
            },
            subMenu: null,
            type: "item",
            value: "out-mark",
            quickSwitcherLabel: "Timeline: Set Out Mark"
          },
          {
            id: "x-mark",
            keyHint: "X",
            label: "Clear In/Out Marks",
            leftItem: null,
            onClick: () => {
              closeMenu();
              inOutHandles.current?.clearMarks();
            },
            subMenu: null,
            type: "item",
            value: "clear-marks",
            quickSwitcherLabel: "Timeline: Clear In and Out Mark"
          },
          {
            id: "goto-time",
            keyHint: "G",
            label: "Go to frame",
            leftItem: null,
            onClick: () => {
              closeMenu();
              remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.timeValueRef.current?.goToFrame();
            },
            subMenu: null,
            type: "item",
            value: "clear-marks",
            quickSwitcherLabel: "Timeline: Go to frame"
          },
          {
            id: "fullscreen-divider",
            type: "divider"
          },
          isFullscreenSupported ? {
            id: "fullscreen",
            keyHint: null,
            label: "Fullscreen",
            leftItem: null,
            onClick: () => {
              closeMenu();
              drawRef.current?.requestFullscreen();
            },
            subMenu: null,
            type: "item",
            value: "fullscreen",
            quickSwitcherLabel: "Go Fullscreen"
          } : null
        ].filter(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.truthy)
      },
      {
        id: "tools",
        label: "Tools",
        leaveLeftPadding: false,
        items: [
           true ? {
            id: "ask-ai",
            value: "ask-ai",
            label: "Ask AI",
            onClick: () => {
              closeMenu();
              askAiModalRef.current?.toggle();
            },
            leftItem: null,
            keyHint: `${cmdOrCtrlCharacter}+I`,
            subMenu: null,
            type: "item",
            quickSwitcherLabel: "Ask AI"
          } : 0,
          "EyeDropper" in window ? {
            id: "color-picker",
            value: "color-picker",
            label: "Color Picker",
            onClick: () => {
              closeMenu();
              pickColor();
            },
            leftItem: null,
            keyHint: null,
            subMenu: null,
            type: "item",
            quickSwitcherLabel: "Show Color Picker"
          } : null,
          {
            id: "spring-editor",
            value: "spring-editor",
            label: "Timing Editor",
            onClick: () => {
              closeMenu();
              window.open("https://www.remotion.dev/timing-editor", "_blank");
            },
            leftItem: null,
            keyHint: null,
            subMenu: null,
            type: "item",
            quickSwitcherLabel: "Open spring() Editor"
          }
        ].filter(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.truthy),
        quickSwitcherLabel: null
      },
      readOnlyStudio || remotion_packageManager === "unknown" ? null : {
        id: "install",
        label: "Packages",
        leaveLeftPadding: false,
        items: [
          {
            id: "install-packages",
            value: "install-packages",
            label: "Install...",
            onClick: () => {
              closeMenu();
              setSelectedModal({
                type: "install-packages",
                packageManager: remotion_packageManager
              });
            },
            type: "item",
            keyHint: null,
            leftItem: null,
            subMenu: null,
            quickSwitcherLabel: `Install packages`
          }
        ]
      },
      {
        id: "help",
        label: "Help",
        leaveLeftPadding: false,
        items: [
          {
            id: "shortcuts",
            value: "shortcuts",
            label: areKeyboardShortcutsDisabled() ? "Shortcuts (disabled)" : "Shortcuts",
            onClick: () => {
              closeMenu();
              setSelectedModal({
                type: "quick-switcher",
                mode: "docs",
                invocationTimestamp: Date.now()
              });
            },
            keyHint: "?",
            leftItem: null,
            subMenu: null,
            type: "item",
            quickSwitcherLabel: areKeyboardShortcutsDisabled() ? "Show all Keyboard Shortcuts (disabled)" : "Show all Keyboard Shortcuts"
          },
          {
            id: "docs",
            value: "docs",
            label: "Docs",
            onClick: () => {
              closeMenu();
              openExternal("https://remotion.dev/docs");
            },
            type: "item",
            keyHint: null,
            leftItem: null,
            subMenu: null,
            quickSwitcherLabel: "Visit Documentation"
          },
          {
            id: "file-issue",
            value: "file-issue",
            label: "File an issue",
            onClick: () => {
              closeMenu();
              openExternal("https://github.com/remotion-dev/remotion/issues/new/choose");
            },
            type: "item",
            keyHint: null,
            leftItem: null,
            subMenu: null,
            quickSwitcherLabel: "File GitHub issue"
          },
          {
            id: "discord",
            value: "discord",
            label: "Join Discord community",
            onClick: () => {
              closeMenu();
              openExternal("https://discord.com/invite/6VzzNDwUwV");
            },
            type: "item",
            keyHint: null,
            leftItem: null,
            subMenu: null,
            quickSwitcherLabel: null
          },
          {
            id: "help-divider-6",
            type: "divider"
          },
          {
            id: "insta",
            value: "insta",
            label: "Instagram",
            onClick: () => {
              closeMenu();
              openExternal("https://instagram.com/remotion");
            },
            type: "item",
            keyHint: null,
            leftItem: null,
            subMenu: null,
            quickSwitcherLabel: "Follow Remotion on Instagram"
          },
          {
            id: "x",
            value: "x",
            label: "X",
            onClick: () => {
              closeMenu();
              openExternal("https://x.com/remotion");
            },
            type: "item",
            keyHint: null,
            leftItem: null,
            subMenu: null,
            quickSwitcherLabel: "Follow Remotion on X"
          },
          {
            id: "youtube",
            value: "youtube",
            label: "YouTube",
            onClick: () => {
              closeMenu();
              openExternal("https://www.youtube.com/@remotion_dev");
            },
            type: "item",
            keyHint: null,
            leftItem: null,
            subMenu: null,
            quickSwitcherLabel: "Watch Remotion on YouTube"
          },
          {
            id: "linkedin",
            value: "linkedin",
            label: "LinkedIn",
            onClick: () => {
              closeMenu();
              openExternal("https://www.linkedin.com/company/remotion-dev/");
            },
            type: "item",
            keyHint: null,
            leftItem: null,
            subMenu: null,
            quickSwitcherLabel: "Follow Remotion on LinkedIn"
          },
          {
            id: "tiktok",
            value: "tiktok",
            label: "TikTok",
            onClick: () => {
              closeMenu();
              openExternal("https://www.tiktok.com/@remotion");
            },
            type: "item",
            keyHint: null,
            leftItem: null,
            subMenu: null,
            quickSwitcherLabel: "Follow Remotion on TikTok"
          }
        ]
      }
    ].filter(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.truthy);
    if (mobileLayout) {
      struct = [
        {
          ...struct[0],
          items: [
            ...struct.slice(1).map((s) => {
              return {
                ...s,
                keyHint: null,
                onClick: () => {
                  return;
                },
                type: "item",
                value: s.id,
                leftItem: null,
                subMenu: {
                  items: s.items,
                  leaveLeftSpace: true,
                  preselectIndex: 0
                },
                quickSwitcherLabel: null
              };
            }),
            ...struct[0].items
          ]
        }
      ];
    }
    return struct;
  }, [
    readOnlyStudio,
    closeMenu,
    type,
    sizePreselectIndex,
    sizes,
    editorZoomGestures,
    editorShowRulers,
    editorShowGuides,
    sidebarCollapsedStateLeft,
    sidebarCollapsedStateRight,
    checkerboard,
    isFullscreenSupported,
    remotion_packageManager,
    mobileLayout,
    size.size,
    setSize,
    setEditorZoomGestures,
    setEditorShowRulers,
    setEditorShowGuides,
    setSidebarCollapsedState,
    setCheckerboard,
    setSelectedModal
  ]);
  return structure;
};
var getItemLabel = (item) => {
  if (item.quickSwitcherLabel !== null) {
    return item.quickSwitcherLabel;
  }
  if (typeof item.label === "string") {
    return item.label;
  }
  return item.label?.toString();
};
var itemToSearchResult = (item, setSelectedModal, prefixes) => {
  if (item.subMenu) {
    return item.subMenu.items.map((subItem) => {
      if (subItem.type === "divider") {
        return null;
      }
      return itemToSearchResult(subItem, setSelectedModal, [
        ...prefixes,
        getItemLabel(item)
      ]);
    }).flat(1).filter(remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.truthy);
  }
  return [
    {
      type: "menu-item",
      id: item.id,
      onSelected: () => {
        setSelectedModal(null);
        item.onClick(item.id, null);
      },
      title: [...prefixes, getItemLabel(item)].join(": ")
    }
  ];
};
var makeSearchResults = (actions, setSelectedModal) => {
  const items = actions.map((menu) => {
    return menu.items.map((item) => {
      if (item.type === "divider") {
        return null;
      }
      return itemToSearchResult(item, setSelectedModal, []);
    });
  }).flat(Infinity).filter(remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.truthy);
  return items;
};

// src/components/Menu/MenuItem.tsx




var container16 = {
  fontSize: 13,
  color: "white",
  paddingLeft: 10,
  paddingRight: 10,
  cursor: "default",
  paddingTop: 8,
  paddingBottom: 8,
  userSelect: "none",
  WebkitUserSelect: "none",
  border: "none"
};
var MenuItem = ({
  label: itemName,
  selected,
  id,
  onItemSelected,
  onItemHovered,
  onItemQuit,
  onPreviousMenu,
  onNextMenu,
  menu
}) => {
  const [hovered, setHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const size = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.useElementSize(ref, {
    triggerOnWindowResize: true,
    shouldApplyCssTransforms: true
  });
  const { tabIndex, currentZIndex } = useZIndex();
  const containerStyle2 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...container16,
      backgroundColor: getBackgroundFromHoverState({
        hovered,
        selected
      })
    };
  }, [hovered, selected]);
  const portalStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!selected || !size) {
      return null;
    }
    return {
      ...menuContainerTowardsBottom,
      left: size.left,
      top: size.top + size.height
    };
  }, [selected, size]);
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onItemHovered(id);
    setHovered(true);
  }, [id, onItemHovered]);
  const onPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(false);
  }, []);
  const onPointerDown = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (e.button !== 0) {
      return;
    }
    onItemSelected(id);
    window.addEventListener("pointerup", (evt) => {
      if (!isMenuItem(evt.target)) {
        onItemQuit();
      }
    }, {
      once: true
    });
  }, [id, onItemQuit, onItemSelected]);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.stopPropagation();
    const isKeyboardInitiated = e.detail === 0;
    if (!isKeyboardInitiated) {
      return;
    }
    onItemSelected((p) => {
      return p === null ? id : null;
    });
  }, [id, onItemSelected]);
  const outerStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...outerPortal,
      top: (size?.top ?? 0) + (size?.height ?? 0)
    };
  }, [size]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
        ref,
        role: "button",
        tabIndex,
        onPointerEnter,
        onPointerLeave,
        onPointerDown,
        onClick,
        style: containerStyle2,
        type: "button",
        className: MENU_INITIATOR_CLASSNAME,
        children: itemName
      }),
      portalStyle ? react_dom__WEBPACK_IMPORTED_MODULE_1__.createPortal(/* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        className: "css-reset",
        style: outerStyle,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(HigherZIndex, {
          onEscape: onItemQuit,
          onOutsideClick: onItemQuit,
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: portalStyle,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MenuContent, {
              onNextMenu: onPreviousMenu,
              onPreviousMenu: onNextMenu,
              values: menu.items,
              onHide: onItemQuit,
              leaveLeftSpace: menu.leaveLeftPadding,
              preselectIndex: false,
              topItemCanBeUnselected: true,
              fixedHeight: null
            })
          })
        })
      }), getPortal(currentZIndex)) : null
    ]
  });
};

// src/components/MenuBuildIndicator.tsx


// src/components/OpenEditorButton.tsx


var svgStyle = {
  width: 11,
  height: 11
};
var buttonStyle = {
  border: "none",
  height: "20px",
  display: "flex",
  paddingInline: "6px",
  justifyContent: "center",
  alignItems: "center"
};
var OpenEditorButton = ({ type }) => {
  const [hovered, setHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const svgFillColor = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return hovered ? "white" : LIGHT_TEXT;
  }, [hovered]);
  const handleClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(async () => {
    if (type === "editor") {
      await openInEditor({
        originalFileName: `${window.remotion_cwd}`,
        originalLineNumber: 1,
        originalColumnNumber: 1,
        originalFunctionName: null,
        originalScriptCode: null
      }).then((res) => res.json()).then(({ success }) => {
        if (!success) {
          showNotification(`Could not open ${window.remotion_editorName}`, 2000);
        }
      }).catch((err) => {
        console.error(err);
        showNotification(`Could not open ${window.remotion_editorName}`, 2000);
      });
    }
    if (type === "git") {
      if (!window.remotion_gitSource) {
        throw new Error("No git source");
      }
      window.open(getGitSourceBranchUrl(window.remotion_gitSource), "_blank");
    }
  }, [type]);
  const buttonTooltip = type === "git" ? `Open ${getGitSourceName(window.remotion_gitSource)} Repo` : `Open in ${window.remotion_editorName}`;
  const openInEditorSvg = /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    viewBox: "0 0 512 512",
    style: svgStyle,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: svgFillColor,
      d: "M320 0c-17.7 0-32 14.3-32 32s14.3 32 32 32h82.7L201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L448 109.3V192c0 17.7 14.3 32 32 32s32-14.3 32-32V32c0-17.7-14.3-32-32-32H320zM80 32C35.8 32 0 67.8 0 112V432c0 44.2 35.8 80 80 80H400c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32V432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H192c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z"
    })
  });
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(true);
  }, []);
  const onPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(false);
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
    title: buttonTooltip,
    type: "button",
    onPointerEnter,
    onPointerLeave,
    style: buttonStyle,
    onClick: handleClick,
    children: openInEditorSvg
  });
};

// src/components/MenuBuildIndicator.tsx

var cwd = {
  fontSize: 13,
  opacity: 0.8,
  display: "flex",
  alignItems: "center",
  justifyContent: "center"
};
var spinnerSize = 14;
var spinner = {
  position: "relative",
  width: spinnerSize,
  marginTop: 4
};
var noSpinner = {
  position: "relative",
  width: spinnerSize
};
var MenuBuildIndicator = () => {
  const [isBuilding, setIsBuilding] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const ctx = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx).previewServerState;
  const showButton = window.remotion_editorName && ctx.type === "connected";
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    window.remotion_isBuilding = () => {
      setIsBuilding(true);
    };
    window.remotion_finishedBuilding = () => {
      setIsBuilding(false);
    };
    return () => {
      window.remotion_isBuilding = undefined;
      window.remotion_finishedBuilding = undefined;
    };
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: cwd,
    title: window.remotion_cwd,
    children: [
      showButton ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 2
      }) : null,
      isBuilding ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: spinner,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spinner, {
          duration: 0.5,
          size: spinnerSize
        })
      }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: noSpinner
      }),
      showButton ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 0.5
      }) : null,
      window.remotion_projectName,
      showButton ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 0.25
      }) : null,
      showButton ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OpenEditorButton, {
        type: "editor"
      }) : window.remotion_gitSource ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OpenEditorButton, {
        type: "git"
      }) : null
    ]
  });
};

// src/components/SidebarCollapserControls.tsx


// src/components/TopPanel.tsx


// src/helpers/use-breakpoint.ts

function useBreakpoint(breakpoint2) {
  const [compactUI, setCompactUI] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(window.innerWidth < breakpoint2);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    function handleResize() {
      setCompactUI(window.innerWidth < breakpoint2);
    }
    window.addEventListener("resize", handleResize);
    handleResize();
    return () => window.removeEventListener("resize", handleResize);
  }, [breakpoint2]);
  return compactUI;
}

// src/components/CanvasIfSizeIsAvailable.tsx



// src/components/CanvasOrLoading.tsx



// src/error-overlay/remotion-overlay/ErrorLoader.tsx


// src/error-overlay/react-overlay/utils/parser.ts


// src/error-overlay/react-overlay/effects/resolve-file-source.ts
var resolveFileSource = async (location, contextLines) => {
  const res = await fetch(`/api/file-source?f=${encodeURIComponent(location.fileName)}`);
  const text = await res.text();
  const lines2 = text.split(`
`).map((l, i) => {
    const oneIndexedLineNumber = i + 1;
    return [oneIndexedLineNumber, l];
  }).filter(([oneIndexedLineNumber]) => {
    return Math.abs(oneIndexedLineNumber - location.lineNumber) <= contextLines;
  });
  const scriptCode = lines2.map(([num, line2]) => {
    return {
      content: line2,
      highlight: location.lineNumber === num,
      lineNumber: num
    };
  });
  return {
    originalColumnNumber: location.columnNumber,
    originalFunctionName: null,
    originalFileName: location.fileName,
    originalLineNumber: location.lineNumber,
    originalScriptCode: scriptCode
  };
};

// src/error-overlay/react-overlay/utils/make-stack-frame.ts
var makeStackFrame = ({
  functionName,
  fileName,
  lineNumber,
  columnNumber
}) => {
  if (functionName && functionName.indexOf("Object.") === 0) {
    functionName = functionName.slice("Object.".length);
  }
  if (functionName === "friendlySyntaxErrorLabel" || functionName === "exports.__esModule" || functionName === "<anonymous>" || !functionName) {
    functionName = null;
  }
  return {
    columnNumber,
    fileName,
    functionName,
    lineNumber
  };
};

// src/error-overlay/react-overlay/utils/parser.ts
var regexExtractLocation = /\(?(.+?)(?::(\d+))?(?::(\d+))?\)?$/;
function extractLocation(token) {
  const execed = regexExtractLocation.exec(token);
  if (!execed) {
    throw new Error("Could not match in extractLocation");
  }
  return execed.slice(1).map((v) => {
    const p = Number(v);
    if (!isNaN(p)) {
      return p;
    }
    return v;
  });
}
var regexValidFrame_Chrome = /^\s*(at|in)\s.+(:\d+)/;
var regexValidFrame_FireFox = /(^|@)\S+:\d+|.+line\s+\d+\s+>\s+(eval|Function).+/;
function parseStack(stack) {
  const frames = stack.filter((e) => regexValidFrame_Chrome.test(e) || regexValidFrame_FireFox.test(e)).map((e) => {
    if (regexValidFrame_FireFox.test(e)) {
      let isEval = false;
      if (/ > (eval|Function)/.test(e)) {
        e = e.replace(/ line (\d+)(?: > eval line \d+)* > (eval|Function):\d+:\d+/g, ":$1");
        isEval = true;
      }
      const _data = e.split(/[@]/g);
      const _last = _data.pop();
      if (!_last) {
        throw new Error("could not get last");
      }
      const [_fileName, _lineNumber, _columnNumber] = extractLocation(_last);
      return makeStackFrame({
        functionName: _data.join("@") || (isEval ? "eval" : null),
        fileName: _fileName,
        lineNumber: _lineNumber,
        columnNumber: _columnNumber
      });
    }
    if (e.indexOf("(eval ") !== -1) {
      e = e.replace(/(\(eval at [^()]*)|(\),.*$)/g, "");
    }
    if (e.indexOf("(at ") !== -1) {
      e = e.replace(/\(at /, "(");
    }
    const data = e.trim().split(/\s+/g).slice(1);
    const last = data.pop();
    if (!last) {
      throw new Error("could not get last");
    }
    const [fileName, lineNumber, columnNumber] = extractLocation(last);
    return makeStackFrame({
      functionName: data.join(" ") || null,
      fileName,
      lineNumber,
      columnNumber
    });
  });
  return frames;
}
var parseError = async (error, contextLines) => {
  if (error === null) {
    throw new Error("You cannot pass a null object.");
  }
  if (typeof error === "string") {
    return parseStack(error.split(`
`)).map((frame) => {
      return {
        type: "transpiled",
        frame
      };
    });
  }
  if (Array.isArray(error)) {
    return parseStack(error).map((frame) => {
      return {
        type: "transpiled",
        frame
      };
    });
  }
  const errorLocation = (0,_remotion_studio_shared__WEBPACK_IMPORTED_MODULE_6__/* .getLocationFromBuildError */ .Ug)(error);
  if (errorLocation) {
    return [
      {
        type: "symbolicated",
        frame: await resolveFileSource(errorLocation, contextLines)
      }
    ];
  }
  if (typeof error.stack === "string") {
    return parseStack(error.stack.split(`
`)).map((frame) => {
      return {
        type: "transpiled",
        frame
      };
    });
  }
  return [];
};

// src/error-overlay/react-overlay/utils/unmapper.ts


// src/error-overlay/react-overlay/utils/get-lines-around.ts
function getLinesAround(line2, count, lines2) {
  const result = [];
  for (let index = Math.max(0, line2 - 1 - count);index <= Math.min(lines2.length - 1, line2 - 1 + count); ++index) {
    result.push({
      lineNumber: index + 1,
      content: lines2[index],
      highlight: index === line2 - 1
    });
  }
  return result;
}

// src/error-overlay/react-overlay/utils/get-source-map.ts

var getOriginalPosition = (source_map, line2, column) => {
  const result = source_map.originalPositionFor({
    line: line2,
    column
  });
  return { line: result.line, column: result.column, source: result.source };
};
function extractSourceMapUrl(fileContents) {
  const regex = /\/\/[#@] ?sourceMappingURL=([^\s'"]+)\s*$/gm;
  let match = null;
  for (;; ) {
    const next = regex.exec(fileContents);
    if (next == null) {
      break;
    }
    match = next;
  }
  if (!match?.[1]) {
    return null;
  }
  return match[1].toString();
}
async function getSourceMap(fileUri, fileContents) {
  const sm = extractSourceMapUrl(fileContents);
  if (sm === null) {
    return null;
  }
  if (sm.indexOf("data:") === 0) {
    const base64 = /^data:application\/json;([\w=:"-]+;)*base64,/;
    const match2 = sm.match(base64);
    if (!match2) {
      throw new Error("Sorry, non-base64 inline source-map encoding is not supported.");
    }
    const converted = window.atob(sm.substring(match2[0].length));
    return new source_map__WEBPACK_IMPORTED_MODULE_11__.SourceMapConsumer(JSON.parse(converted));
  }
  const index = fileUri.lastIndexOf("/");
  const url = fileUri.substring(0, index + 1) + sm;
  const obj = await fetch(url).then((res) => res.json());
  return new source_map__WEBPACK_IMPORTED_MODULE_11__.SourceMapConsumer(obj);
}

// src/error-overlay/react-overlay/utils/unmapper.ts
var getFileContents = async (fileName) => {
  const res = await fetch(fileName);
  const fileContents = await res.text();
  return fileContents;
};
var unmap = async (frames, contextLines) => {
  const transpiled = frames.filter((s) => s.type === "transpiled").map((s) => s.frame);
  const uniqueFileNames = [
    ...new Set(transpiled.map((f) => f.fileName).filter(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.truthy))
  ];
  const maps = await Promise.all(uniqueFileNames.map(async (fileName) => {
    const fileContents = await getFileContents(fileName);
    return getSourceMap(fileName, fileContents);
  }));
  const mapValues = {};
  for (let i = 0;i < uniqueFileNames.length; i++) {
    mapValues[uniqueFileNames[i]] = maps[i];
  }
  return frames.map((frame) => {
    if (frame.type === "symbolicated") {
      return frame.frame;
    }
    const map = mapValues[frame.frame.fileName];
    if (!map) {
      return null;
    }
    const pos = getOriginalPosition(map, frame.frame.lineNumber, frame.frame.columnNumber);
    const { functionName } = frame.frame;
    let hasSource = null;
    hasSource = pos.source ? map.sourceContentFor(pos.source, false) : null;
    const scriptCode = hasSource && pos.line ? getLinesAround(pos.line, contextLines, hasSource.split(`
`)) : null;
    return {
      originalColumnNumber: pos.column,
      originalFileName: pos.source,
      originalFunctionName: functionName,
      originalLineNumber: pos.line,
      originalScriptCode: scriptCode
    };
  }).filter(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.truthy);
};

// src/error-overlay/react-overlay/utils/get-stack-frames.ts
var getStackFrames = async (error, contextSize) => {
  const parsedFrames = await parseError(error, contextSize);
  const enhancedFrames = await unmap(parsedFrames, contextSize);
  if (enhancedFrames.map((f) => f.originalFileName).filter((f_1) => f_1 !== null && f_1 !== undefined).length === 0) {
    return null;
  }
  return enhancedFrames;
};

// src/error-overlay/react-overlay/listen-to-runtime-errors.ts
var CONTEXT_SIZE = 3;
var getErrorRecord = async (error) => {
  const stackFrames = await getStackFrames(error, CONTEXT_SIZE);
  if (stackFrames === null || stackFrames === undefined) {
    return null;
  }
  return {
    error,
    contextSize: CONTEXT_SIZE,
    stackFrames
  };
};

// src/error-overlay/remotion-overlay/ErrorDisplay.tsx



// src/error-overlay/remotion-overlay/AskOnDiscord.tsx


// src/components/Button.tsx


var button = {
  border: `1px solid ${INPUT_BORDER_COLOR_UNHOVERED}`,
  borderRadius: 4,
  backgroundColor: INPUT_BACKGROUND,
  appearance: "none",
  fontFamily: "inherit",
  fontSize: 14,
  color: "white",
  flexDirection: "row"
};
var ButtonRefForwardFunction = ({
  children,
  onClick,
  title: title3,
  disabled,
  style: style4,
  id,
  autoFocus,
  buttonContainerStyle
}, ref) => {
  const combined = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...button,
      ...style4 ?? {}
    };
  }, [style4]);
  const buttonContainer = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      padding: 10,
      cursor: disabled ? "inherit" : "pointer",
      fontSize: 14,
      opacity: disabled ? 0.7 : 1,
      ...buttonContainerStyle ?? {}
    };
  }, [buttonContainerStyle, disabled]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
    ref,
    id,
    style: combined,
    type: "button",
    disabled,
    onClick,
    autoFocus,
    title: title3,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      className: "css-reset",
      style: buttonContainer,
      children
    })
  });
};
var Button = (0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(ButtonRefForwardFunction);

// src/error-overlay/remotion-overlay/AskOnDiscord.tsx

var DISCORD_LINK = "https://remotion.dev/discord";
var AskOnDiscord = ({ canHaveKeyboardShortcuts }) => {
  const openInBrowser = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    window.open(DISCORD_LINK, "_blank");
  }, []);
  const { registerKeybinding } = useKeybinding();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!canHaveKeyboardShortcuts) {
      return;
    }
    const onEditor = () => {
      openInBrowser();
    };
    const { unregister } = registerKeybinding({
      event: "keydown",
      key: "d",
      callback: onEditor,
      commandCtrlKey: true,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => unregister();
  }, [canHaveKeyboardShortcuts, openInBrowser, registerKeybinding]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Button, {
    onClick: openInBrowser,
    children: [
      "Ask on Discord",
      " ",
      canHaveKeyboardShortcuts ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ShortcutHint, {
        keyToPress: "d",
        cmdOrCtrl: true
      }) : null
    ]
  });
};

// src/error-overlay/remotion-overlay/CalculateMetadataErrorExplainer.tsx

var CalculateMetadataErrorExplainer = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: style4,
    children: [
      "This error occured while calling",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
        style: inlineCodeSnippet,
        children: "calculateMetadata()"
      }),
      "."
    ]
  });
};
var style4 = {
  borderRadius: 3,
  color: "white",
  padding: 12,
  backgroundColor: BORDER_COLOR,
  fontSize: 14,
  fontFamily: "sans-serif"
};

// src/error-overlay/remotion-overlay/CompositionIdsDropdown.tsx


// src/error-overlay/remotion-overlay/carets.tsx

var CaretRight2 = ({ size }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    style: { height: size ?? 20 },
    "aria-hidden": "true",
    focusable: "false",
    role: "img",
    viewBox: "0 0 192 512",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: "currentColor",
      d: "M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"
    })
  });
};
var CaretDown2 = ({ invert, size }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    "aria-hidden": "true",
    focusable: "false",
    role: "img",
    xmlns: "http://www.w3.org/2000/svg",
    viewBox: "0 0 320 512",
    style: { height: size ?? 20, transform: invert ? `rotate(180deg)` : "" },
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: "currentColor",
      d: "M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
    })
  });
};

// src/error-overlay/remotion-overlay/CompositionIdListItem.tsx


var listItemStyle = {
  padding: 8,
  cursor: "pointer",
  borderRadius: 4,
  lineHeight: 1.4,
  color: TEXT_COLOR,
  fontFamily: "inherit",
  fontSize: 14
};
var listItemActiveStyle = {
  backgroundColor: SELECTED_BACKGROUND
};
var listItemHoverStyle = {
  backgroundColor: CLEAR_HOVER
};
var CompositionIdListItem = ({ id, isActive, onSelect }) => {
  const [hover, setHover] = react__WEBPACK_IMPORTED_MODULE_0__.useState(false);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    role: "button",
    onPointerEnter: () => setHover(true),
    onPointerLeave: () => setHover(false),
    onClick: () => onSelect(id),
    style: {
      ...listItemStyle,
      ...hover ? listItemHoverStyle : {},
      ...isActive ? listItemActiveStyle : {}
    },
    title: id,
    children: id
  });
};

// src/error-overlay/remotion-overlay/CompositionIdsDropdown.tsx

var containerStyle2 = {
  display: "inline-block",
  position: "relative"
};
var dropdownStyle = {
  position: "absolute",
  top: "110%",
  left: 0,
  width: 320,
  maxHeight: 300,
  overflowY: "auto",
  backgroundColor: INPUT_BACKGROUND,
  border: `1px solid ${INPUT_BORDER_COLOR_UNHOVERED}`,
  borderRadius: 8,
  padding: 8,
  boxShadow: "0 6px 24px rgba(0,0,0,0.35)",
  zIndex: 1000,
  fontFamily: "inherit",
  fontSize: 14
};
var searchStyle = {
  width: "100%",
  padding: "6px 8px",
  borderRadius: 6,
  border: `1px solid ${INPUT_BORDER_COLOR_UNHOVERED}`,
  background: INPUT_BACKGROUND,
  color: TEXT_COLOR,
  marginBottom: 8,
  outline: "none",
  fontFamily: "inherit",
  fontSize: 14
};
var CompositionIdsDropdown = ({ compositionIds, currentId }) => {
  const [open, setOpen] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const [query, setQuery] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)("");
  const containerRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const filtered = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const q = query.trim().toLowerCase();
    if (!q) {
      return compositionIds;
    }
    return compositionIds.filter((id) => id.toLowerCase().includes(q));
  }, [compositionIds, query]);
  const onSelect = (id) => {
    const isQuery = window.remotion_isReadOnlyStudio;
    if (isQuery) {
      window.location.href = `${window.location.pathname}?/${id}`;
    } else {
      window.location.href = `/${id}`;
    }
  };
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!open) {
      return;
    }
    const onClickAway = (e) => {
      if (!containerRef.current) {
        return;
      }
      if (!containerRef.current.contains(e.target)) {
        setOpen(false);
      }
    };
    const onKey = (e) => {
      if (e.key === "Escape") {
        setOpen(false);
      }
    };
    document.addEventListener("mousedown", onClickAway);
    document.addEventListener("touchstart", onClickAway, { passive: true });
    document.addEventListener("keydown", onKey);
    return () => {
      document.removeEventListener("mousedown", onClickAway);
      document.removeEventListener("touchstart", onClickAway);
      document.removeEventListener("keydown", onKey);
    };
  }, [open, containerRef]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    ref: containerRef,
    style: containerStyle2,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Button, {
        onClick: () => setOpen((p) => !p),
        buttonContainerStyle: {
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          gap: 8,
          minWidth: 180
        },
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
            style: {
              overflow: "hidden",
              textOverflow: "ellipsis",
              whiteSpace: "nowrap",
              fontSize: "14px",
              lineHeight: "24px"
            },
            children: currentId ?? "Select composition"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CaretDown2, {
            size: 20,
            invert: open
          })
        ]
      }),
      open ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: dropdownStyle,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("input", {
            value: query,
            onChange: (e) => setQuery(e.target.value),
            placeholder: "Search compositions...",
            style: searchStyle,
            "aria-label": "Search compositions"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            children: filtered.length === 0 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              style: { opacity: 0.7, padding: 8, textAlign: "center" },
              children: "No compositions found"
            }) : filtered.map((id) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CompositionIdListItem, {
              id,
              isActive: id === currentId,
              onSelect
            }, id))
          })
        ]
      }) : null
    ]
  });
};

// src/error-overlay/react-overlay/index.ts

var didUnmountReactApp = () => {
  return !remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.getPreviewDomElement()?.hasChildNodes();
};

// src/error-overlay/remotion-overlay/DismissButton.tsx


var size = {
  height: 20,
  width: 20
};
var style5 = {
  appearance: "none",
  WebkitAppearance: "none",
  backgroundColor: "transparent",
  border: "none",
  cursor: "pointer"
};
var DismissButton = () => {
  const dismiss = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    clearUrl();
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
    type: "button",
    style: style5,
    onClick: dismiss,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      focusable: "false",
      role: "img",
      xmlns: "http://www.w3.org/2000/svg",
      viewBox: "0 0 352 512",
      style: size,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        fill: "white",
        d: "M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"
      })
    })
  });
};

// src/error-overlay/remotion-overlay/ErrorMessage.tsx



var fontSize = 24;
var lineHeight = 1.5;
var maxLines = 2;
var buttonSize = 32;
var maskImage = "linear-gradient(to bottom, white 60%, transparent)";
var container17 = {
  position: "relative",
  marginBottom: 15
};
var messageContainer = {
  overflow: "hidden"
};
var textContainer = {
  fontSize,
  lineHeight
};
var moreLine = {
  width: "100%",
  display: "flex",
  justifyContent: "center",
  position: "absolute",
  border: `1px solid ${INPUT_BORDER_COLOR_HOVERED}`,
  height: 0,
  marginTop: 4
};
var moreButton = {
  height: buttonSize,
  width: buttonSize,
  borderRadius: buttonSize / 2,
  backgroundColor: INPUT_BACKGROUND,
  border: `1px solid ${INPUT_BORDER_COLOR_UNHOVERED}`,
  marginTop: -buttonSize / 2,
  display: "flex",
  justifyContent: "center",
  alignItems: "center",
  cursor: "pointer",
  color: "white"
};
var ErrorMessage = ({ message }) => {
  const [expanded, setExpanded] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const size2 = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.useElementSize(ref, {
    shouldApplyCssTransforms: false,
    triggerOnWindowResize: true
  });
  const errorLines = size2 ? size2.height / (lineHeight * fontSize) : null;
  const style6 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const isExpanded = expanded || errorLines !== null && errorLines <= maxLines;
    return {
      ...messageContainer,
      maxHeight: isExpanded ? undefined : fontSize * lineHeight * maxLines,
      maskImage: isExpanded ? undefined : maskImage,
      WebkitMaskImage: isExpanded ? undefined : maskImage
    };
  }, [errorLines, expanded]);
  const toggle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setExpanded((e) => !e);
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container17,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: style6,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          ref,
          style: textContainer,
          children: message
        })
      }),
      errorLines !== null && errorLines > maxLines ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: moreLine,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
          type: "button",
          onClick: toggle,
          style: moreButton,
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CaretDown2, {
            invert: expanded
          })
        })
      }) : null
    ]
  });
};

// src/error-overlay/remotion-overlay/Symbolicating.tsx

var Symbolicating = (props) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("svg", {
    id: "loading",
    xmlns: "http://www.w3.org/2000/svg",
    viewBox: "0 0 32 32",
    width: "16",
    height: "16",
    fill: "white",
    ...props,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        opacity: ".1",
        d: "M14 0 H18 V8 H14 z",
        transform: "rotate(0 16 16)",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("animate", {
          attributeName: "opacity",
          from: "1",
          to: ".1",
          dur: "1s",
          repeatCount: "indefinite",
          begin: "0"
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        opacity: ".1",
        d: "M14 0 H18 V8 H14 z",
        transform: "rotate(45 16 16)",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("animate", {
          attributeName: "opacity",
          from: "1",
          to: ".1",
          dur: "1s",
          repeatCount: "indefinite",
          begin: "0.125s"
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        opacity: ".1",
        d: "M14 0 H18 V8 H14 z",
        transform: "rotate(90 16 16)",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("animate", {
          attributeName: "opacity",
          from: "1",
          to: ".1",
          dur: "1s",
          repeatCount: "indefinite",
          begin: "0.25s"
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        opacity: ".1",
        d: "M14 0 H18 V8 H14 z",
        transform: "rotate(135 16 16)",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("animate", {
          attributeName: "opacity",
          from: "1",
          to: ".1",
          dur: "1s",
          repeatCount: "indefinite",
          begin: "0.375s"
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        opacity: ".1",
        d: "M14 0 H18 V8 H14 z",
        transform: "rotate(180 16 16)",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("animate", {
          attributeName: "opacity",
          from: "1",
          to: ".1",
          dur: "1s",
          repeatCount: "indefinite",
          begin: "0.5s"
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        opacity: ".1",
        d: "M14 0 H18 V8 H14 z",
        transform: "rotate(225 16 16)",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("animate", {
          attributeName: "opacity",
          from: "1",
          to: ".1",
          dur: "1s",
          repeatCount: "indefinite",
          begin: "0.675s"
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        opacity: ".1",
        d: "M14 0 H18 V8 H14 z",
        transform: "rotate(270 16 16)",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("animate", {
          attributeName: "opacity",
          from: "1",
          to: ".1",
          dur: "1s",
          repeatCount: "indefinite",
          begin: "0.75s"
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        opacity: ".1",
        d: "M14 0 H18 V8 H14 z",
        transform: "rotate(315 16 16)",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("animate", {
          attributeName: "opacity",
          from: "1",
          to: ".1",
          dur: "1s",
          repeatCount: "indefinite",
          begin: "0.875s"
        })
      })
    ]
  });
};

// src/error-overlay/remotion-overlay/ErrorTitle.tsx

var title3 = {
  marginBottom: 8,
  display: "flex",
  flexDirection: "row",
  justifyContent: "center"
};
var left = {
  flex: 1,
  paddingRight: 14,
  fontWeight: "bold",
  maxWidth: "100%"
};
var errName = {
  fontSize: 18,
  color: BLUE,
  display: "inline-block"
};
var row3 = {
  display: "flex",
  flexDirection: "row",
  alignItems: "center"
};
var spacer = {
  width: 5
};
var ErrorTitle = ({ name, message, symbolicating, canHaveDismissButton }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: title3,
    className: "css-reset",
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: left,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
            style: errName,
            children: name
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("br", {}),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: row3,
            children: [
              symbolicating ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Symbolicating, {}),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: spacer
                  })
                ]
              }) : null,
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ErrorMessage, {
                message
              })
            ]
          })
        ]
      }),
      didUnmountReactApp() ? null : canHaveDismissButton ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DismissButton, {}) : null
    ]
  });
};

// src/error-overlay/remotion-overlay/get-help-link.ts
var getHelpLink = (message) => {
  if (message.includes("See https://www.remotion.dev/docs/the-fundamentals#defining-compositions")) {
    return {
      title: "Defining compositions",
      url: "See https://www.remotion.dev/docs/the-fundamentals#defining-compositions"
    };
  }
  if (message.includes("https://remotion.dev/docs/wrong-composition-mount")) {
    return {
      title: "Wrongly mounted <Composition>",
      url: "https://remotion.dev/docs/wrong-composition-mount"
    };
  }
  if (message.includes("https://remotion.dev/docs/staticfile-relative-paths")) {
    return {
      title: "staticFile() relative paths",
      url: "https://remotion.dev/docs/staticfile-relative-paths"
    };
  }
  if (message.includes("https://remotion.dev/docs/staticfile-remote-urls")) {
    return {
      title: "staticFile() remote URLs",
      url: "https://remotion.dev/docs/staticfile-remote-urls"
    };
  }
  if (message.includes("https://remotion.dev/docs/non-seekable-media")) {
    return {
      title: "Non-seekable media",
      url: "https://remotion.dev/docs/non-seekable-media"
    };
  }
  if (message.includes("https://remotion.dev/docs/media-playback-error")) {
    return {
      title: "Media playback error",
      url: "https://remotion.dev/docs/media-playback-error"
    };
  }
  if (message.includes("Div is not part of the THREE")) {
    return {
      title: "<Sequence> inside <ThreeCanvas>",
      url: "https://remotion.dev/docs/sequence#note-for-remotionthree"
    };
  }
  return null;
};

// src/error-overlay/remotion-overlay/HelpLink.tsx


var buttonStyle2 = {
  backgroundColor: BLUE,
  color: "white"
};
var HelpLink = ({ canHaveKeyboardShortcuts, link }) => {
  const openLink = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    window.open(link.url, "_blank");
  }, [link]);
  const { registerKeybinding } = useKeybinding();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!canHaveKeyboardShortcuts) {
      return;
    }
    const onEditor = () => {
      openLink();
    };
    const { unregister } = registerKeybinding({
      event: "keydown",
      key: "h",
      callback: onEditor,
      commandCtrlKey: true,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => unregister();
  }, [canHaveKeyboardShortcuts, openLink, registerKeybinding]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Button, {
    style: buttonStyle2,
    onClick: openLink,
    children: [
      "Help: ",
      '"',
      link.title,
      '"',
      canHaveKeyboardShortcuts ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ShortcutHint, {
        keyToPress: "h",
        cmdOrCtrl: true
      }) : null
    ]
  });
};

// src/error-overlay/remotion-overlay/OpenInEditor.tsx


var initialState = { type: "idle" };
var reducer = (state, action) => {
  if (action.type === "start") {
    return {
      type: "load"
    };
  }
  if (action.type === "fail") {
    return {
      type: "error"
    };
  }
  if (action.type === "reset") {
    return {
      type: "idle"
    };
  }
  if (action.type === "succeed") {
    return {
      type: "success"
    };
  }
  return state;
};
var OpenInEditor = ({ stack, canHaveKeyboardShortcuts }) => {
  const isMounted = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(true);
  const [state, dispatch] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useReducer)(reducer, initialState);
  const { registerKeybinding } = useKeybinding();
  const dispatchIfMounted = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((payload) => {
    if (isMounted.current === false)
      return;
    dispatch(payload);
  }, []);
  const openInBrowser = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    dispatch({ type: "start" });
    openInEditor(stack).then((res) => res.json()).then((data) => {
      if (data.success) {
        dispatchIfMounted({ type: "succeed" });
      } else {
        dispatchIfMounted({ type: "fail" });
      }
    }).catch((err) => {
      dispatchIfMounted({ type: "fail" });
      console.log("Could not open browser", err);
    }).finally(() => {
      setTimeout(() => {
        dispatchIfMounted({ type: "reset" });
      }, 2000);
    });
  }, [dispatchIfMounted, stack]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    return () => {
      isMounted.current = false;
    };
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!canHaveKeyboardShortcuts) {
      return;
    }
    const onEditor = () => {
      openInBrowser();
    };
    const { unregister } = registerKeybinding({
      event: "keydown",
      key: "o",
      callback: onEditor,
      commandCtrlKey: true,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => unregister();
  }, [canHaveKeyboardShortcuts, openInBrowser, registerKeybinding]);
  const label4 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    switch (state.type) {
      case "error":
        return "Failed to open";
      case "idle":
        return `Open in ${window.remotion_editorName}`;
      case "success":
        return `Opened in ${window.remotion_editorName}`;
      case "load":
        return `Opening...`;
      default:
        throw new Error("invalid state");
    }
  }, [state.type]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Button, {
    onClick: openInBrowser,
    disabled: state.type !== "idle",
    children: [
      label4,
      canHaveKeyboardShortcuts ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ShortcutHint, {
        keyToPress: "o",
        cmdOrCtrl: true
      }) : null
    ]
  });
};

// src/error-overlay/remotion-overlay/Retry.tsx

var RetryButton = ({ onClick }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
    onClick,
    children: "Retry calculateMetadata()"
  });
};

// src/error-overlay/remotion-overlay/SearchGitHubIssues.tsx


var SearchGithubIssues = ({ message, canHaveKeyboardShortcuts }) => {
  const openInBrowser = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    window.open(`https://github.com/remotion-dev/remotion/issues?q=${encodeURIComponent(message)}`, "_blank");
  }, [message]);
  const { registerKeybinding } = useKeybinding();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!canHaveKeyboardShortcuts) {
      return;
    }
    const onEditor = () => {
      openInBrowser();
    };
    const { unregister } = registerKeybinding({
      event: "keydown",
      key: "g",
      callback: onEditor,
      commandCtrlKey: true,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => unregister();
  }, [canHaveKeyboardShortcuts, openInBrowser, registerKeybinding]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Button, {
    onClick: openInBrowser,
    children: [
      "Search GitHub Issues",
      " ",
      canHaveKeyboardShortcuts ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ShortcutHint, {
        keyToPress: "g",
        cmdOrCtrl: true
      }) : null
    ]
  });
};

// src/error-overlay/remotion-overlay/StackFrame.tsx


// src/error-overlay/remotion-overlay/CodeFrame.tsx

var container18 = {
  display: "flex",
  flexDirection: "row",
  width: "100%"
};
var frame = {
  backgroundColor: "#070707",
  marginBottom: 20,
  overflowY: "auto"
};
var lineNumber = {
  whiteSpace: "pre",
  paddingRight: 12,
  color: "inherit",
  fontSize: 14,
  lineHeight: 1.7,
  width: 60,
  flexShrink: 0,
  display: "inline-flex",
  alignItems: "center",
  justifyContent: "flex-end",
  fontFamily: "monospace"
};
var CodeFrame = ({ source, lineNumberWidth }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: frame,
    className: HORIZONTAL_SCROLLBAR_CLASSNAME,
    children: source.map((s, j) => {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: container18,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: {
              ...lineNumber,
              backgroundColor: s.highlight ? "white" : "#121212",
              color: s.highlight ? "black" : "rgba(255, 255, 255, 0.6)"
            },
            children: String(s.lineNumber).padStart(lineNumberWidth, " ")
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: {
              fontFamily: "monospace",
              whiteSpace: "pre",
              tabSize: 2,
              color: s.highlight ? "white" : "rgba(255, 255, 255, 0.6)",
              backgroundColor: s.highlight ? BLUE : "transparent",
              lineHeight: 1.7,
              paddingRight: 12,
              paddingLeft: 12
            },
            children: s.content
          })
        ]
      }, j);
    })
  });
};

// src/error-overlay/remotion-overlay/format-location.ts
var formatLocation = (location) => {
  if (location.startsWith("webpack://")) {
    return location.replace("webpack://", "");
  }
  return location;
};

// src/error-overlay/remotion-overlay/StackFrame.tsx

var location = {
  color: "rgba(255, 255, 255, 0.6)",
  fontFamily: "monospace",
  fontSize: 14
};
var header = {
  paddingLeft: 14,
  paddingTop: 10,
  paddingBottom: 10,
  paddingRight: 14,
  display: "flex",
  flexDirection: "row",
  alignItems: "center",
  borderBottom: "1px solid rgb(66, 144, 245)",
  backgroundColor: "black"
};
var left2 = {
  paddingRight: 14,
  flex: 1
};
var fnName = {
  fontSize: 14,
  lineHeight: 1.5,
  marginBottom: 3
};
var StackElement = ({ s, lineNumberWidth, isFirst, defaultFunctionName }) => {
  const [showCodeFrame, setShowCodeFrame] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => !s.originalFileName?.includes("node_modules") && !s.originalFileName?.startsWith("webpack/") || isFirst);
  const toggleCodeFrame = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setShowCodeFrame((f) => !f);
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    className: "css-reset",
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: header,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: left2,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: fnName,
                children: s.originalFunctionName ?? defaultFunctionName
              }),
              s.originalFileName ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                style: location,
                children: [
                  formatLocation(s.originalFileName),
                  ":",
                  s.originalLineNumber
                ]
              }) : null
            ]
          }),
          s.originalScriptCode && s.originalScriptCode.length > 0 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
            onClick: toggleCodeFrame,
            children: showCodeFrame ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CaretDown2, {
              invert: false
            }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CaretRight2, {})
          }) : null
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        children: s.originalScriptCode && s.originalScriptCode.length > 0 && showCodeFrame ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CodeFrame, {
          lineNumberWidth,
          source: s.originalScriptCode
        }) : null
      })
    ]
  });
};

// src/error-overlay/remotion-overlay/ErrorDisplay.tsx

var stack = {
  marginTop: 17,
  overflowX: "scroll",
  marginBottom: "10vh"
};
var spacer2 = {
  width: 5,
  display: "inline-block"
};
var ErrorDisplay = ({
  display,
  keyboardShortcuts,
  onRetry,
  canHaveDismissButton,
  calculateMetadata
}) => {
  const compositionIds = window?.remotion_seenCompositionIds ?? [];
  const highestLineNumber = Math.max(...display.stackFrames.map((s) => s.originalScriptCode).flat(1).map((s) => s?.lineNumber ?? 0));
  const message = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const location2 = (0,_remotion_studio_shared__WEBPACK_IMPORTED_MODULE_6__/* .getLocationFromBuildError */ .Ug)(display.error);
    if (!location2) {
      return display.error.message;
    }
    return location2.message.replace(/\\n/g, `
`).replace(/\\t/g, "  ").replace(/^error:/, "").trim();
  }, [display.error]);
  const lineNumberWidth = String(highestLineNumber).length;
  const helpLink = getHelpLink(message);
  const getCurrentCompositionId = () => {
    const route = getRoute();
    const id = route.startsWith("/") ? route.slice(1) : route;
    return compositionIds.includes(id) ? id : compositionIds[0] ?? null;
  };
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ErrorTitle, {
        symbolicating: false,
        name: display.error.name,
        message,
        canHaveDismissButton
      }),
      helpLink ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(HelpLink, {
            link: helpLink,
            canHaveKeyboardShortcuts: keyboardShortcuts
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: spacer2
          })
        ]
      }) : null,
      display.stackFrames.length > 0 && window.remotion_editorName ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OpenInEditor, {
            canHaveKeyboardShortcuts: keyboardShortcuts,
            stack: display.stackFrames[0]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: spacer2
          })
        ]
      }) : null,
      compositionIds.length > 0 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CompositionIdsDropdown, {
            compositionIds,
            currentId: getCurrentCompositionId()
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: spacer2
          })
        ]
      }) : null,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SearchGithubIssues, {
        canHaveKeyboardShortcuts: keyboardShortcuts,
        message: display.error.message
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: spacer2
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(AskOnDiscord, {
        canHaveKeyboardShortcuts: keyboardShortcuts
      }),
      onRetry ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: spacer2
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RetryButton, {
            onClick: onRetry
          })
        ]
      }) : null,
      calculateMetadata ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("br", {}),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            y: 0.5
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CalculateMetadataErrorExplainer, {})
        ]
      }) : null,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: stack,
        className: HORIZONTAL_SCROLLBAR_CLASSNAME,
        children: display.stackFrames.map((s, i) => {
          return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(StackElement, {
            isFirst: i === 0,
            s,
            lineNumberWidth,
            defaultFunctionName: "(anonymous function)"
          }, i);
        })
      })
    ]
  });
};

// src/error-overlay/remotion-overlay/ErrorLoader.tsx

var container19 = {
  width: "100%",
  maxWidth: 1000,
  paddingLeft: 14,
  paddingRight: 14,
  marginLeft: "auto",
  marginRight: "auto",
  fontFamily: "SF Pro Text, sans-serif",
  paddingTop: "5vh"
};
var errorWhileErrorStyle = {
  color: "white",
  lineHeight: 1.5,
  whiteSpace: "pre"
};
var ErrorLoader = ({
  error,
  keyboardShortcuts,
  onRetry,
  canHaveDismissButton,
  calculateMetadata
}) => {
  const [state, setState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({
    type: "loading"
  });
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    getErrorRecord(error).then((record) => {
      if (record) {
        setState({
          type: "symbolicated",
          record
        });
      } else {
        setState({
          type: "no-record"
        });
      }
    }).catch((err) => {
      setState({
        err,
        type: "error"
      });
    });
  }, [error]);
  if (state.type === "loading") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: container19,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ErrorTitle, {
        symbolicating: true,
        name: error.name,
        message: error.message,
        canHaveDismissButton
      })
    });
  }
  if (state.type === "error") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
      style: container19,
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ErrorTitle, {
          symbolicating: false,
          name: error.name,
          message: error.message,
          canHaveDismissButton
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: errorWhileErrorStyle,
          children: "Error while getting stack trace:"
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: errorWhileErrorStyle,
          children: state.err.stack
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: errorWhileErrorStyle,
          children: "Report this in the Remotion repo."
        })
      ]
    });
  }
  if (state.type === "no-record") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
      style: container19,
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ErrorTitle, {
          symbolicating: false,
          name: error.name,
          message: error.message,
          canHaveDismissButton
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: errorWhileErrorStyle,
          children: "Check the Terminal and browser console for error messages."
        })
      ]
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: container19,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ErrorDisplay, {
      keyboardShortcuts,
      display: state.record,
      onRetry,
      canHaveDismissButton,
      calculateMetadata
    })
  });
};

// src/components/Canvas.tsx



// src/helpers/get-effective-translation.ts
var getEffectiveXTranslation = ({
  canvasSize,
  scale,
  compositionWidth,
  translation
}) => {
  const maxTranslation = Math.abs(canvasSize.width / 2 + scale * compositionWidth / 2 - MUST_BE_INSIDE_CANVAS);
  return Math.max(-maxTranslation, Math.min(translation.x, maxTranslation));
};
var MUST_BE_INSIDE_CANVAS = 50;
var getEffectiveYTranslation = ({
  canvasSize,
  scale,
  compositionHeight,
  translation
}) => {
  const maxTranslation = Math.abs(canvasSize.height / 2 + scale * compositionHeight / 2) - MUST_BE_INSIDE_CANVAS;
  return Math.max(-maxTranslation, Math.min(translation.y, maxTranslation));
};
var getEffectiveTranslation = ({
  canvasSize,
  scale,
  compositionHeight,
  compositionWidth,
  translation
}) => {
  return {
    x: getEffectiveXTranslation({
      canvasSize,
      compositionWidth,
      scale,
      translation
    }),
    y: getEffectiveYTranslation({
      canvasSize,
      compositionHeight,
      scale,
      translation
    })
  };
};
var getCenterPointWhileScrolling = ({
  size: size2,
  clientX,
  clientY,
  compositionWidth,
  compositionHeight,
  scale,
  translation
}) => {
  const mouseLeft = clientX - size2.left;
  const mouseTop = clientY - size2.top;
  const contentLeftPoint = size2.width / 2 - compositionWidth * scale / 2 - translation.x;
  const contentTopPoint = size2.height / 2 - compositionHeight * scale / 2 - translation.y;
  const offsetFromVideoLeft = Math.min(compositionWidth, Math.max(0, (mouseLeft - contentLeftPoint) / scale));
  const offsetFromVideoTop = Math.min(compositionHeight, Math.max(0, (mouseTop - contentTopPoint) / scale));
  return {
    centerX: offsetFromVideoLeft,
    centerY: offsetFromVideoTop
  };
};

// src/helpers/smooth-zoom.ts
var BASE = Math.E / 4;
var MIN_ZOOM = 0.05;
var MAX_ZOOM = 10;
function logN(val) {
  return Math.log(val) / Math.log(BASE);
}
var smoothenZoom = (input) => {
  return BASE ** (input - 1);
};
var unsmoothenZoom = (input) => {
  if (input < 0) {
    return MAX_ZOOM;
  }
  return Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, logN(input) + 1));
};

// src/components/EditorGuides/index.tsx



// src/helpers/use-studio-canvas-dimensions.ts



var useStudioCanvasDimensions = ({
  canvasSize,
  contentDimensions,
  assetMetadata
}) => {
  const { size: previewSize } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.PreviewSizeContext);
  const { centerX, centerY, scale } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (contentDimensions === "none" || contentDimensions === null || assetMetadata && assetMetadata.type === "not-found" || !canvasSize) {
      return {
        centerX: previewSize.translation.x,
        centerY: previewSize.translation.y,
        scale: 1
      };
    }
    return _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.calculateCanvasTransformation({
      canvasSize,
      compositionHeight: contentDimensions.height,
      compositionWidth: contentDimensions.width,
      previewSize: previewSize.size
    });
  }, [
    canvasSize,
    contentDimensions,
    previewSize.size,
    previewSize.translation.y,
    previewSize.translation.x,
    assetMetadata
  ]);
  const canvasPosition = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      left: centerX - previewSize.translation.x,
      top: centerY - previewSize.translation.y,
      width: contentDimensions === "none" || !contentDimensions ? canvasSize?.width || 0 : contentDimensions.width * scale,
      height: contentDimensions === "none" || !contentDimensions ? canvasSize?.height || 0 : contentDimensions.height * scale
    };
  }, [
    scale,
    centerX,
    previewSize.translation.x,
    previewSize.translation.y,
    centerY,
    canvasSize,
    contentDimensions
  ]);
  return {
    canvasPosition,
    scale
  };
};

// src/components/EditorGuides/Guide.tsx



var PADDING_FOR_EASY_DRAG = 4;
var GuideComp = ({ guide, canvasDimensions, scale }) => {
  const {
    shouldCreateGuideRef,
    setGuidesList,
    setSelectedGuideId,
    selectedGuideId,
    setHoveredGuideId,
    hoveredGuideId
  } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(EditorShowGuidesContext);
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHoveredGuideId(() => guide.id);
  }, [guide.id, setHoveredGuideId]);
  const onPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHoveredGuideId(() => null);
  }, [setHoveredGuideId]);
  const isVerticalGuide = guide.orientation === "vertical";
  const guideStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const canvasPosition = isVerticalGuide ? canvasDimensions.left : canvasDimensions.top;
    const guidePosition = guide.position * scale + canvasPosition;
    return {
      position: "absolute",
      width: `${isVerticalGuide ? "1px" : "100%"}`,
      height: `${isVerticalGuide ? "100%" : "1px"}`,
      left: `${isVerticalGuide ? guidePosition - PADDING_FOR_EASY_DRAG : 0}px`,
      top: `${isVerticalGuide ? 0 : guidePosition - PADDING_FOR_EASY_DRAG}px`,
      cursor: `${isVerticalGuide ? "ew-resize" : "ns-resize"}`,
      padding: isVerticalGuide ? `0 ${PADDING_FOR_EASY_DRAG}px` : `${PADDING_FOR_EASY_DRAG}px 0`
    };
  }, [guide, scale, canvasDimensions, isVerticalGuide]);
  const guideContentStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      position: "relative",
      minWidth: `${isVerticalGuide ? "1px" : `calc(100% + ${RULER_WIDTH}px`}`,
      minHeight: `${isVerticalGuide ? `calc(100% + ${RULER_WIDTH}px` : "1px"}`,
      top: `${isVerticalGuide ? `-${RULER_WIDTH}px` : "0px"}`,
      left: `${isVerticalGuide ? "0px" : `-${RULER_WIDTH}px`}`,
      display: guide.show ? "block" : "none",
      backgroundColor: selectedGuideId === guide.id || hoveredGuideId === guide.id ? SELECTED_GUIDE : UNSELECTED_GUIDE
    };
  }, [isVerticalGuide, guide.show, guide.id, selectedGuideId, hoveredGuideId]);
  const onMouseDown = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.preventDefault();
    if (e.button !== 0) {
      return;
    }
    shouldCreateGuideRef.current = true;
    document.body.style.cursor = "no-drop";
    setSelectedGuideId(() => guide.id);
  }, [shouldCreateGuideRef, setSelectedGuideId, guide.id]);
  const values = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return [
      {
        id: "1",
        keyHint: null,
        label: "Remove guide",
        leftItem: null,
        onClick: () => {
          setGuidesList((prevState) => {
            const newGuides = prevState.filter((selected) => {
              return selected.id !== guide.id;
            });
            persistGuidesList(newGuides);
            return newGuides;
          });
        },
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: "remove"
      }
    ];
  }, [guide.id, setGuidesList]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ContextMenu, {
    values,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: guideStyle,
      onMouseDown,
      className: "__remotion_editor_guide",
      onPointerEnter,
      onPointerLeave,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: guideContentStyle,
        className: [
          "__remotion_editor_guide_content",
          selectedGuideId === guide.id || hoveredGuideId === guide.id ? "__remotion_editor_guide_selected" : null
        ].filter(remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.truthy).join(" ")
      })
    })
  });
};
var Guide_default = (0,react__WEBPACK_IMPORTED_MODULE_0__.memo)(GuideComp);

// src/components/EditorGuides/index.tsx

var EditorGuides = ({ canvasSize, contentDimensions, assetMetadata }) => {
  const { canvasPosition: canvasDimensions, scale } = useStudioCanvasDimensions({
    canvasSize,
    contentDimensions,
    assetMetadata
  });
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  if (canvasContent === null || canvasContent.type !== "composition") {
    throw new Error("Expected to be in a composition");
  }
  const { guidesList } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(EditorShowGuidesContext);
  const guidesForThisComposition = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return guidesList.filter((guide) => {
      return guide.compositionId === canvasContent.compositionId;
    });
  }, [canvasContent.compositionId, guidesList]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: guidesForThisComposition.map((guide) => {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Guide_default, {
        guide,
        canvasDimensions,
        scale
      }, guide.id);
    })
  });
};
var EditorGuides_default = EditorGuides;

// src/components/EditorRuler/index.tsx


// src/helpers/editor-ruler.ts
var drawLabel = ({
  orientation,
  context,
  label: label4,
  originDistance,
  color
}) => {
  context.fillStyle = color;
  if (orientation === "horizontal") {
    context.fillText(label4, originDistance + 4, 16);
  } else {
    context.rotate(-Math.PI / 2);
    context.fillText(label4, -originDistance + 4, 16);
    context.rotate(Math.PI / 2);
  }
};
var drawGradient = ({
  orientation,
  context,
  originDistance,
  canvasHeight,
  canvasWidth
}) => {
  const size2 = 250;
  const startX = orientation === "horizontal" ? originDistance - size2 / 2 : 0;
  const startY = orientation === "horizontal" ? 0 : originDistance - size2 / 2;
  const endX = orientation === "horizontal" ? originDistance + size2 / 2 : canvasWidth;
  const endY = orientation === "horizontal" ? canvasHeight : originDistance + size2 / 2;
  const grd = context.createLinearGradient(startX, startY, endX, endY);
  grd.addColorStop(0, BACKGROUND__TRANSPARENT);
  grd.addColorStop(0.25, BACKGROUND);
  grd.addColorStop(0.75, BACKGROUND);
  grd.addColorStop(1, BACKGROUND__TRANSPARENT);
  context.fillStyle = grd;
  context.fillRect(startX, startY, endX - startX, endY - startY);
};
var drawGuide = ({
  selectedGuide,
  scale,
  startMarking,
  context,
  canvasHeight,
  canvasWidth,
  orientation,
  originOffset
}) => {
  const originDistance = rulerValueToPosition({
    value: selectedGuide.position,
    startMarking,
    scale
  }) + originOffset - startMarking * scale;
  drawGradient({
    canvasHeight,
    context,
    orientation,
    originDistance,
    canvasWidth
  });
  context.strokeStyle = SELECTED_GUIDE;
  context.lineWidth = 1;
  context.beginPath();
  if (orientation === "horizontal" && selectedGuide.orientation === "horizontal") {
    return;
  }
  if (orientation === "vertical" && selectedGuide.orientation === "vertical") {
    return;
  }
  if (orientation === "vertical" && selectedGuide.orientation === "horizontal") {
    context.moveTo(0, originDistance);
    context.lineTo(canvasWidth, originDistance);
    drawLabel({
      context,
      label: selectedGuide.position.toString(),
      originDistance,
      orientation,
      color: SELECTED_GUIDE
    });
  } else if (orientation === "horizontal" && selectedGuide.orientation === "vertical") {
    context.moveTo(originDistance, 0);
    context.lineTo(originDistance, canvasHeight);
    drawLabel({
      context,
      label: selectedGuide.position.toString(),
      originDistance,
      orientation,
      color: SELECTED_GUIDE
    });
  }
  context.stroke();
};
var drawMarkingOnRulerCanvas = ({
  scale,
  points,
  startMarking,
  originOffset,
  markingGaps,
  orientation,
  rulerCanvasRef,
  selectedGuide,
  canvasHeight,
  canvasWidth
}) => {
  const canvas = rulerCanvasRef.current;
  if (!canvas)
    return;
  const context = canvas.getContext("2d");
  if (!context)
    return;
  canvas.width = canvasWidth;
  canvas.height = canvasHeight;
  context.scale(window.devicePixelRatio, window.devicePixelRatio);
  context.clearRect(0, 0, canvasWidth, canvasHeight);
  context.strokeStyle = RULER_COLOR;
  context.lineWidth = 1;
  context.beginPath();
  points.forEach((point) => {
    context.strokeStyle = RULER_COLOR;
    context.lineWidth = 1;
    const originDistance = point.position + originOffset - startMarking * scale;
    context.beginPath();
    if (orientation === "horizontal") {
      context.moveTo(originDistance, 0);
      context.lineTo(originDistance, canvasHeight);
    } else {
      context.moveTo(0, originDistance);
      context.lineTo(canvasWidth, originDistance);
    }
    for (let i = 1;i < 5; i++) {
      const markingOffsetXY = i * markingGaps * scale;
      if (orientation === "horizontal") {
        context.moveTo(originDistance + markingOffsetXY / 5, 0);
        context.lineTo(originDistance + markingOffsetXY / 5, 4);
      } else {
        context.moveTo(0, originDistance + markingOffsetXY / 5);
        context.lineTo(4, originDistance + markingOffsetXY / 5);
      }
    }
    context.stroke();
    context.font = "10px Arial, Helvetica, sans-serif";
    context.textAlign = "left";
    context.fillStyle = RULER_COLOR;
    drawLabel({
      orientation,
      context,
      label: point.value.toString(),
      originDistance,
      color: RULER_COLOR
    });
  });
  if (selectedGuide && orientation !== selectedGuide.orientation) {
    drawGuide({
      canvasHeight,
      canvasWidth,
      context,
      orientation,
      originOffset,
      scale,
      selectedGuide,
      startMarking
    });
  }
};
var getRulerPoints = ({
  rulerScaleRange,
  rulerMarkingGaps,
  scale
}) => {
  const points = [];
  const startPoint = Math.ceil(rulerScaleRange.start / rulerMarkingGaps);
  const endPoint = Math.floor(rulerScaleRange.end / rulerMarkingGaps);
  const startMarking = startPoint * rulerMarkingGaps;
  for (let i = startPoint;i <= endPoint; i++) {
    points.push({
      value: i * rulerMarkingGaps,
      position: rulerValueToPosition({
        scale,
        startMarking,
        value: i * rulerMarkingGaps
      })
    });
  }
  return {
    points,
    startMarking
  };
};
var rulerValueToPosition = ({
  value,
  startMarking,
  scale
}) => {
  return (value + startMarking) * scale;
};
var getRulerScaleRange = ({
  canvasLength,
  scale,
  canvasSize
}) => {
  const scaleRangeBeyondCanvas = (canvasSize.width || MINIMUM_VISIBLE_CANVAS_SIZE - MINIMUM_VISIBLE_CANVAS_SIZE) / scale;
  return {
    start: -scaleRangeBeyondCanvas,
    end: scaleRangeBeyondCanvas + canvasLength
  };
};

// src/components/EditorRuler/Ruler.tsx



var makeGuideId = () => {
  return Math.random().toString(36).substring(7);
};
var Ruler = ({
  scale,
  points,
  originOffset,
  startMarking,
  size: size2,
  markingGaps,
  orientation
}) => {
  const rulerCanvasRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const isVerticalRuler = orientation === "vertical";
  const {
    shouldCreateGuideRef,
    setGuidesList,
    selectedGuideId,
    hoveredGuideId,
    setSelectedGuideId,
    guidesList,
    setEditorShowGuides
  } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(EditorShowGuidesContext);
  const unsafeVideoConfig = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useUnsafeVideoConfig();
  if (!unsafeVideoConfig) {
    throw new Error("Video config not set");
  }
  const [cursor, setCursor] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(isVerticalRuler ? "ew-resize" : "ns-resize");
  const selectedOrHoveredGuide = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return guidesList.find((guide) => guide.id === selectedGuideId) ?? guidesList.find((guide) => guide.id === hoveredGuideId) ?? null;
  }, [guidesList, hoveredGuideId, selectedGuideId]);
  const rulerWidth = isVerticalRuler ? RULER_WIDTH : size2.width - RULER_WIDTH;
  const rulerHeight = isVerticalRuler ? size2.height - RULER_WIDTH : RULER_WIDTH;
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    drawMarkingOnRulerCanvas({
      scale,
      points,
      startMarking,
      originOffset,
      markingGaps,
      orientation,
      rulerCanvasRef,
      selectedGuide: selectedOrHoveredGuide,
      canvasHeight: rulerHeight * window.devicePixelRatio,
      canvasWidth: rulerWidth * window.devicePixelRatio
    });
  }, [
    scale,
    points,
    startMarking,
    originOffset,
    markingGaps,
    orientation,
    selectedOrHoveredGuide,
    size2,
    rulerHeight,
    rulerWidth
  ]);
  const rulerStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => ({
    position: "absolute",
    background: BACKGROUND,
    width: rulerWidth,
    height: rulerHeight,
    left: isVerticalRuler ? 0 : "unset",
    top: isVerticalRuler ? "unset" : 0,
    borderBottom: isVerticalRuler ? undefined : "1px solid " + RULER_COLOR,
    borderRight: isVerticalRuler ? "1px solid " + RULER_COLOR : undefined,
    cursor
  }), [rulerWidth, rulerHeight, cursor, isVerticalRuler]);
  const onMouseDown = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (e.button !== 0) {
      return;
    }
    e.preventDefault();
    shouldCreateGuideRef.current = true;
    document.body.style.cursor = "no-drop";
    const guideId = makeGuideId();
    setEditorShowGuides(() => true);
    setSelectedGuideId(() => guideId);
    setGuidesList((prevState) => {
      return [
        ...prevState,
        {
          orientation,
          position: -originOffset,
          show: false,
          id: guideId,
          compositionId: unsafeVideoConfig.id
        }
      ];
    });
  }, [
    shouldCreateGuideRef,
    setEditorShowGuides,
    setSelectedGuideId,
    setGuidesList,
    orientation,
    originOffset,
    unsafeVideoConfig.id
  ]);
  const changeCursor = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.preventDefault();
    if (selectedGuideId !== null) {
      setCursor("no-drop");
    }
  }, [setCursor, selectedGuideId]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (selectedGuideId === null) {
      setCursor(isVerticalRuler ? "ew-resize" : "ns-resize");
    }
  }, [selectedGuideId, isVerticalRuler]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("canvas", {
    ref: rulerCanvasRef,
    width: rulerWidth * window.devicePixelRatio,
    height: rulerHeight * window.devicePixelRatio,
    style: rulerStyle,
    onPointerDown: onMouseDown,
    onPointerEnter: changeCursor,
    onPointerLeave: changeCursor
  });
};
var Ruler_default = Ruler;

// src/components/EditorRuler/index.tsx

var originBlockStyles = {
  position: "absolute",
  top: 0,
  left: 0,
  borderBottom: "1px solid " + RULER_COLOR,
  borderRight: "1px solid " + RULER_COLOR,
  width: `${RULER_WIDTH}px`,
  height: `${RULER_WIDTH}px`,
  background: BACKGROUND
};
var EditorRulers = ({ contentDimensions, canvasSize, assetMetadata, containerRef }) => {
  const { scale, canvasPosition } = useStudioCanvasDimensions({
    canvasSize,
    contentDimensions,
    assetMetadata
  });
  const {
    shouldCreateGuideRef,
    shouldDeleteGuideRef,
    setGuidesList,
    selectedGuideId,
    setSelectedGuideId
  } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(EditorShowGuidesContext);
  const rulerMarkingGaps = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const minimumGap = MINIMUM_RULER_MARKING_GAP_PX;
    const predefinedGap = PREDEFINED_RULER_SCALE_GAPS.find((gap) => gap * scale > minimumGap);
    return predefinedGap || MAXIMUM_PREDEFINED_RULER_SCALE_GAP;
  }, [scale]);
  const horizontalRulerScaleRange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => getRulerScaleRange({
    canvasLength: canvasPosition.width,
    scale,
    canvasSize
  }), [canvasPosition.width, canvasSize, scale]);
  const verticalRulerScaleRange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => getRulerScaleRange({
    canvasLength: canvasPosition.height,
    scale,
    canvasSize
  }), [canvasPosition.height, canvasSize, scale]);
  const {
    points: horizontalRulerPoints,
    startMarking: horizontalRulerStartMarking
  } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => getRulerPoints({
    rulerScaleRange: horizontalRulerScaleRange,
    rulerMarkingGaps,
    scale
  }), [horizontalRulerScaleRange, rulerMarkingGaps, scale]);
  const { points: verticalRulerPoints, startMarking: verticalRulerStartMarking } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => getRulerPoints({
    rulerScaleRange: verticalRulerScaleRange,
    rulerMarkingGaps,
    scale
  }), [verticalRulerScaleRange, rulerMarkingGaps, scale]);
  const requestAnimationFrameRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const onMouseMove = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (requestAnimationFrameRef.current) {
      cancelAnimationFrame(requestAnimationFrameRef.current);
    }
    requestAnimationFrameRef.current = requestAnimationFrame(() => {
      const { clientX: mouseX, clientY: mouseY } = e;
      const {
        left: containerLeft = 0,
        top: containerTop = 0,
        right: containerRight = 0,
        bottom: containerBottom = 0
      } = containerRef.current?.getBoundingClientRect() || {};
      if (mouseX < containerLeft || mouseX > containerRight || mouseY < containerTop || mouseY > containerBottom) {
        if (!shouldDeleteGuideRef.current) {
          shouldDeleteGuideRef.current = true;
        }
        if (document.body.style.cursor !== "no-drop") {
          document.body.style.cursor = "no-drop";
        }
        setGuidesList((prevState) => {
          const newGuides = prevState.map((guide) => {
            if (guide.id !== selectedGuideId) {
              return guide;
            }
            return {
              ...guide,
              show: false
            };
          });
          persistGuidesList(newGuides);
          return newGuides;
        });
      } else {
        if (shouldDeleteGuideRef.current) {
          shouldDeleteGuideRef.current = false;
        }
        setGuidesList((prevState) => {
          return prevState.map((guide) => {
            if (guide.id !== selectedGuideId) {
              return guide;
            }
            const position = guide.orientation === "vertical" ? (mouseX - containerLeft) / scale - canvasPosition.left / scale : (mouseY - containerTop) / scale - canvasPosition.top / scale;
            const desiredCursor = guide.orientation === "vertical" ? "ew-resize" : "ns-resize";
            if (document.body.style.cursor !== desiredCursor) {
              document.body.style.cursor = desiredCursor;
            }
            return {
              ...guide,
              position: Math.floor(position / 1),
              show: true
            };
          });
        });
      }
    });
  }, [
    containerRef,
    shouldDeleteGuideRef,
    setGuidesList,
    selectedGuideId,
    scale,
    canvasPosition.left,
    canvasPosition.top
  ]);
  const onMouseUp = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setGuidesList((prevState) => {
      const newGuides = prevState.filter((selected) => {
        if (!shouldDeleteGuideRef.current) {
          return true;
        }
        return selected.id !== selectedGuideId;
      });
      persistGuidesList(newGuides);
      return newGuides;
    });
    shouldDeleteGuideRef.current = false;
    document.body.style.cursor = "auto";
    shouldCreateGuideRef.current = false;
    setSelectedGuideId(() => null);
    document.removeEventListener("pointerup", onMouseUp);
    document.removeEventListener("pointermove", onMouseMove);
  }, [
    selectedGuideId,
    shouldCreateGuideRef,
    shouldDeleteGuideRef,
    setSelectedGuideId,
    setGuidesList,
    onMouseMove
  ]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (selectedGuideId !== null) {
      document.addEventListener("pointermove", onMouseMove);
      document.addEventListener("pointerup", onMouseUp);
    }
    return () => {
      document.removeEventListener("pointermove", onMouseMove);
      document.removeEventListener("pointerup", onMouseUp);
      if (requestAnimationFrameRef.current) {
        cancelAnimationFrame(requestAnimationFrameRef.current);
      }
    };
  }, [selectedGuideId, onMouseMove, onMouseUp]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: originBlockStyles
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Ruler_default, {
        orientation: "horizontal",
        scale,
        points: horizontalRulerPoints,
        startMarking: horizontalRulerStartMarking,
        markingGaps: rulerMarkingGaps,
        originOffset: canvasPosition.left,
        size: canvasSize
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Ruler_default, {
        orientation: "vertical",
        scale,
        points: verticalRulerPoints,
        startMarking: verticalRulerStartMarking,
        markingGaps: rulerMarkingGaps,
        originOffset: canvasPosition.top,
        size: canvasSize
      })
    ]
  });
};

// src/components/EditorRuler/use-is-ruler-visible.ts


var useIsRulerVisible = () => {
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const { editorShowRulers } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(EditorShowRulersContext);
  return editorShowRulers && canvasContent && canvasContent.type === "composition";
};

// src/components/ResetZoomButton.tsx

var ResetZoomButton = ({ onClick }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
    onClick,
    children: "Reset zoom"
  });
};

// src/components/Canvas.tsx

var container20 = {
  flex: 1,
  display: "flex",
  overflow: "hidden",
  position: "relative",
  backgroundColor: BACKGROUND
};
var resetZoom = {
  position: "absolute",
  top: SPACING_UNIT * 2,
  right: SPACING_UNIT * 2
};
var ZOOM_PX_FACTOR = 0.003;
var Canvas = ({ canvasContent, size: size2 }) => {
  const { setSize, size: previewSize } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.PreviewSizeContext);
  const { editorZoomGestures } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(EditorZoomGesturesContext);
  const keybindings = useKeybinding();
  const config = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useUnsafeVideoConfig();
  const areRulersVisible = useIsRulerVisible();
  const { editorShowGuides } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(EditorShowGuidesContext);
  const [assetResolution, setAssetResolution] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const contentDimensions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if ((canvasContent.type === "asset" || canvasContent.type === "output" || canvasContent.type === "output-blob") && assetResolution && assetResolution.type === "found") {
      return assetResolution.dimensions;
    }
    if (config) {
      return { width: config.width, height: config.height };
    }
    return null;
  }, [assetResolution, config, canvasContent]);
  const isFit = previewSize.size === "auto";
  const onWheel = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (!editorZoomGestures) {
      return;
    }
    if (!size2) {
      return;
    }
    if (!contentDimensions || contentDimensions === "none") {
      return;
    }
    const wantsToZoom = e.ctrlKey || e.metaKey;
    if (!wantsToZoom && isFit) {
      return;
    }
    e.preventDefault();
    setSize((prevSize) => {
      const scale = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.calculateScale({
        canvasSize: size2,
        compositionHeight: contentDimensions.height,
        compositionWidth: contentDimensions.width,
        previewSize: prevSize.size
      });
      if (wantsToZoom) {
        const oldSize = prevSize.size === "auto" ? scale : prevSize.size;
        const smoothened = smoothenZoom(oldSize);
        const added = smoothened + e.deltaY * ZOOM_PX_FACTOR;
        const unsmoothened = unsmoothenZoom(added);
        const { centerX, centerY } = getCenterPointWhileScrolling({
          size: size2,
          clientX: e.clientX,
          clientY: e.clientY,
          compositionWidth: contentDimensions.width,
          compositionHeight: contentDimensions.height,
          scale,
          translation: prevSize.translation
        });
        const zoomDifference = unsmoothened - oldSize;
        const uvCoordinatesX = centerX / contentDimensions.width;
        const uvCoordinatesY = centerY / contentDimensions.height;
        const correctionLeft = -uvCoordinatesX * (zoomDifference * contentDimensions.width) + (1 - uvCoordinatesX) * zoomDifference * contentDimensions.width;
        const correctionTop = -uvCoordinatesY * (zoomDifference * contentDimensions.height) + (1 - uvCoordinatesY) * zoomDifference * contentDimensions.height;
        return {
          translation: getEffectiveTranslation({
            translation: {
              x: prevSize.translation.x - correctionLeft / 2,
              y: prevSize.translation.y - correctionTop / 2
            },
            canvasSize: size2,
            compositionHeight: contentDimensions.height,
            compositionWidth: contentDimensions.width,
            scale
          }),
          size: unsmoothened
        };
      }
      const effectiveTranslation = getEffectiveTranslation({
        translation: prevSize.translation,
        canvasSize: size2,
        compositionHeight: contentDimensions.height,
        compositionWidth: contentDimensions.width,
        scale
      });
      return {
        ...prevSize,
        translation: getEffectiveTranslation({
          translation: {
            x: effectiveTranslation.x + e.deltaX,
            y: effectiveTranslation.y + e.deltaY
          },
          canvasSize: size2,
          compositionHeight: contentDimensions.height,
          compositionWidth: contentDimensions.width,
          scale
        })
      };
    });
  }, [editorZoomGestures, contentDimensions, isFit, setSize, size2]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const { current } = canvasRef;
    if (!current) {
      return;
    }
    current.addEventListener("wheel", onWheel, { passive: false });
    return () => current.removeEventListener("wheel", onWheel, {
      passive: false
    });
  }, [onWheel]);
  const onReset = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSize(() => {
      return {
        translation: {
          x: 0,
          y: 0
        },
        size: "auto"
      };
    });
  }, [setSize]);
  const onZoomIn = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (!contentDimensions || contentDimensions === "none") {
      return;
    }
    if (!size2) {
      return;
    }
    setSize((prevSize) => {
      const scale = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.calculateScale({
        canvasSize: size2,
        compositionHeight: contentDimensions.height,
        compositionWidth: contentDimensions.width,
        previewSize: prevSize.size
      });
      return {
        translation: {
          x: 0,
          y: 0
        },
        size: Math.min(MAX_ZOOM, scale * 2)
      };
    });
  }, [contentDimensions, setSize, size2]);
  const onZoomOut = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (!contentDimensions || contentDimensions === "none") {
      return;
    }
    if (!size2) {
      return;
    }
    setSize((prevSize) => {
      const scale = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.calculateScale({
        canvasSize: size2,
        compositionHeight: contentDimensions.height,
        compositionWidth: contentDimensions.width,
        previewSize: prevSize.size
      });
      return {
        translation: {
          x: 0,
          y: 0
        },
        size: Math.max(MIN_ZOOM, scale / 2)
      };
    });
  }, [contentDimensions, setSize, size2]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const resetBinding = keybindings.registerKeybinding({
      event: "keydown",
      key: "0",
      commandCtrlKey: false,
      callback: onReset,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const zoomIn = keybindings.registerKeybinding({
      event: "keydown",
      key: "+",
      commandCtrlKey: false,
      callback: onZoomIn,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const zoomOut = keybindings.registerKeybinding({
      event: "keydown",
      key: "-",
      commandCtrlKey: false,
      callback: onZoomOut,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      resetBinding.unregister();
      zoomIn.unregister();
      zoomOut.unregister();
    };
  }, [keybindings, onReset, onZoomIn, onZoomOut]);
  const fetchMetadata = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(async () => {
    setAssetResolution(null);
    if (canvasContent.type === "composition") {
      return;
    }
    const metadata = await getAssetMetadata(canvasContent, canvasContent.type === "asset");
    setAssetResolution(metadata);
  }, [canvasContent]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (canvasContent.type !== "asset") {
      return;
    }
    const file = (0,remotion__WEBPACK_IMPORTED_MODULE_2__.watchStaticFile)(canvasContent.asset, () => {
      fetchMetadata();
    });
    return () => {
      file.cancel();
    };
  }, [canvasContent, fetchMetadata]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    fetchMetadata();
  }, [fetchMetadata]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        ref: canvasRef,
        style: container20,
        children: [
          size2 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(VideoPreview, {
            canvasContent,
            contentDimensions,
            canvasSize: size2,
            assetMetadata: assetResolution
          }) : null,
          isFit ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: resetZoom,
            className: "css-reset",
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ResetZoomButton, {
              onClick: onReset
            })
          }),
          editorShowGuides && canvasContent.type === "composition" && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(EditorGuides_default, {
            canvasSize: size2,
            contentDimensions,
            assetMetadata: assetResolution
          })
        ]
      }),
      areRulersVisible && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(EditorRulers, {
        contentDimensions,
        canvasSize: size2,
        assetMetadata: assetResolution,
        containerRef: canvasRef
      })
    ]
  });
};

// src/components/FramePersistor.tsx


var FramePersistor = () => {
  const [playing] = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.Timeline.usePlayingState();
  const config = (0,remotion__WEBPACK_IMPORTED_MODULE_2__.useVideoConfig)();
  const frame2 = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.Timeline.useTimelinePosition();
  const setFrame = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useTimelineSetFrame();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!playing) {
      setFrame((f) => {
        const newObj = { ...f, [config.id]: frame2 };
        remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.persistCurrentFrame(newObj);
        return newObj;
      });
    }
  }, [config.id, frame2, playing, setFrame]);
  return null;
};

// src/components/RefreshCompositionOverlay.tsx


// src/components/RunningCalculateMetadata.tsx

var loaderLabel = {
  fontSize: 14,
  color: LIGHT_TEXT,
  fontFamily: "sans-serif",
  lineHeight: 1.5
};
var container21 = {
  backgroundColor: BACKGROUND,
  display: "inline-flex",
  justifyContent: "center",
  alignItems: "center",
  flexDirection: "row",
  padding: 20
};
var RunningCalculateMetadata = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container21,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spinner, {
        size: 24,
        duration: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 2
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: loaderLabel,
        children: [
          "Running ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: inlineCodeSnippet,
            children: "calculateMetadata()"
          }),
          "..."
        ]
      })
    ]
  });
};

// src/components/RefreshCompositionOverlay.tsx

var container22 = {
  justifyContent: "flex-end",
  alignItems: "flex-start",
  padding: 20,
  pointerEvents: "none"
};
var shadow = {
  boxShadow: "0 0 4px black"
};
var RefreshCompositionOverlay = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_2__.AbsoluteFill, {
    style: container22,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: shadow,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RunningCalculateMetadata, {})
    })
  });
};

// src/components/CanvasOrLoading.tsx

var container23 = {
  color: "white",
  flex: 1,
  justifyContent: "center",
  alignItems: "center",
  display: "flex",
  backgroundColor: BACKGROUND,
  flexDirection: "column"
};
var CanvasOrLoading = ({ size: size2 }) => {
  const resolved = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useResolvedVideoConfig(null);
  const { setZoom } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(TimelineZoomCtx);
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (resolved?.type !== "success" && resolved?.type !== "success-and-refreshing") {
      return;
    }
    const c = resolved.result;
    setTimeout(() => {
      ensureFrameIsInViewport({
        direction: "center",
        frame: getCurrentFrame(),
        durationInFrames: c.durationInFrames
      });
    });
  }, [resolved, setZoom]);
  if (!canvasContent) {
    const compname = window.location.pathname.replace("/", "");
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: container23,
      className: "css-reset",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: loaderLabel,
        children: [
          "Composition with ID ",
          compname,
          " not found."
        ]
      })
    });
  }
  const content = /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZoomPersistor, {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Canvas, {
        size: size2,
        canvasContent
      }),
      resolved?.type === "success-and-refreshing" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RefreshCompositionOverlay, {}) : null
    ]
  });
  if (canvasContent.type === "asset" || canvasContent.type === "output" || canvasContent.type === "output-blob") {
    return content;
  }
  if (!resolved) {
    return null;
  }
  if (resolved.type === "loading") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: container23,
      className: "css-reset",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RunningCalculateMetadata, {})
    });
  }
  if (resolved.type === "error") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ErrorLoading, {
      error: resolved.error
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FramePersistor, {}),
      " ",
      content
    ]
  });
};
var loaderContainer = {
  marginLeft: "auto",
  marginRight: "auto",
  width: "100%",
  position: "absolute",
  height: "100%",
  overflowY: "auto"
};
var ErrorLoading = ({ error }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: loaderContainer,
    className: VERTICAL_SCROLLBAR_CLASSNAME,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ErrorLoader, {
      canHaveDismissButton: false,
      keyboardShortcuts: false,
      error,
      onRetry: () => remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.resolveCompositionsRef.current?.reloadCurrentlySelectedComposition(),
      calculateMetadata: true
    }, error.stack)
  });
};

// src/components/CanvasIfSizeIsAvailable.tsx

var CanvasIfSizeIsAvailable = () => {
  const rulersAreVisible = useIsRulerVisible();
  const context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CurrentScaleContext);
  const sizeWithRulersApplied = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const size2 = context && context.type === "canvas-size" ? context.canvasSize : null;
    if (!rulersAreVisible) {
      return size2;
    }
    if (!size2) {
      return null;
    }
    return {
      ...size2,
      width: size2.width - RULER_WIDTH,
      height: size2.height - RULER_WIDTH
    };
  }, [context, rulersAreVisible]);
  if (!sizeWithRulersApplied) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CanvasOrLoading, {
    size: sizeWithRulersApplied
  });
};

// src/components/CurrentCompositionSideEffects.tsx



// src/helpers/document-title.ts

var currentItemName = null;
var unsavedProps = false;
var tabInactive = false;
var renderJobs = [];
var setCurrentCanvasContentId = (id) => {
  if (!id) {
    currentItemName = id;
    updateTitle();
    return;
  }
  const idWithoutFolder = id.split("/").pop();
  currentItemName = idWithoutFolder;
  updateTitle();
};
var setUnsavedProps = (unsaved) => {
  window.remotion_unsavedProps = unsaved;
  unsavedProps = unsaved;
};
var setRenderJobs = (jobs) => {
  renderJobs = jobs;
  updateTitle();
};
document.addEventListener("visibilitychange", () => {
  tabInactive = document.visibilityState === "hidden";
  updateTitle();
});
var productName = "Remotion Studio";
var suffix = `- ${productName}`;
var updateTitle = () => {
  if (!currentItemName) {
    document.title = productName;
    return;
  }
  const currentCompTitle = `${currentItemName} / ${window.remotion_projectName}`;
  document.title = [
    getProgressInBrackets(currentItemName, renderJobs),
    unsavedProps && tabInactive ? "✏️" : null,
    `${currentCompTitle} ${suffix}`
  ].filter(remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.truthy).join(" ");
};
var getProgressInBrackets = (selectedCompositionId, jobs) => {
  const currentRender = jobs.find((job) => job.status === "running");
  if (!currentRender) {
    return null;
  }
  if (currentRender.status !== "running") {
    throw new Error("expected running job");
  }
  let progInPercent;
  if (isClientRenderJob(currentRender)) {
    const { encodedFrames, totalFrames } = currentRender.progress;
    progInPercent = totalFrames > 0 ? Math.ceil(encodedFrames / totalFrames * 100) : 0;
  } else {
    progInPercent = Math.ceil(currentRender.progress.value * 100);
  }
  const progressInBrackets = currentRender.compositionId === selectedCompositionId ? `[${progInPercent}%]` : `[${progInPercent}% ${currentRender.compositionId}]`;
  return progressInBrackets;
};
document.addEventListener("visibilitychange", () => {
  tabInactive = document.visibilityState === "hidden";
  updateTitle();
});

// src/components/CurrentCompositionSideEffects.tsx
var TitleUpdater = () => {
  const renderQueue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(RenderQueueContext);
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const { jobs } = renderQueue;
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!canvasContent) {
      setCurrentCanvasContentId(null);
      return;
    }
    if (canvasContent.type === "composition") {
      setCurrentCanvasContentId(canvasContent.compositionId);
      return;
    }
    if (canvasContent.type === "output") {
      setCurrentCanvasContentId(canvasContent.path);
      return;
    }
    if (canvasContent.type === "output-blob") {
      setCurrentCanvasContentId(canvasContent.displayName);
      return;
    }
    setCurrentCanvasContentId(canvasContent.asset);
  }, [canvasContent]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    setRenderJobs(jobs);
  }, [jobs]);
  return null;
};
var CurrentCompositionKeybindings = ({ readOnlyStudio }) => {
  const keybindings = useKeybinding();
  const video = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useVideo();
  const { type } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx).previewServerState;
  const openRenderModal = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (!video) {
      return;
    }
    if (readOnlyStudio) {
      return showNotification("Studio is read-only", 2000);
    }
    if (type !== "connected") {
      showNotification("Studio server is offline", 2000);
      return;
    }
    const renderButton = document.getElementById("render-modal-button");
    renderButton.click();
  }, [readOnlyStudio, type, video]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const binding = keybindings.registerKeybinding({
      event: "keydown",
      key: "r",
      commandCtrlKey: false,
      callback: openRenderModal,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      binding.unregister();
    };
  }, [keybindings, openRenderModal]);
  return null;
};

// src/components/MobilePanel.tsx


var container24 = {
  position: "fixed",
  top: 0,
  left: 0,
  width: "100%",
  height: "100%",
  padding: "0 0px 50px 0px",
  background: BACKGROUND
};
var buttonContainer = {
  height: "40px",
  width: "100%",
  alignItems: "center",
  display: "flex",
  justifyContent: "flex-end"
};
var button2 = {
  height: 20,
  width: 20
};
function MobilePanel({
  children,
  onClose
}) {
  const { currentZIndex } = useZIndex();
  return react_dom__WEBPACK_IMPORTED_MODULE_1__.createPortal(/* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container24,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: buttonContainer,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CancelButton, {
          style: button2,
          onPress: onClose
        })
      }),
      children
    ]
  }), getPortal(currentZIndex));
}

// src/components/OptionsPanel.tsx



// src/visual-controls/VisualControls.tsx



// src/api/get-zod-schema-from-primitive.ts
function getZodSchemaFromPrimitive(value, z) {
  if (typeof value === "string") {
    return z.string();
  }
  if (typeof value === "number") {
    return z.number();
  }
  let stringified;
  try {
    stringified = JSON.stringify(value);
  } catch {}
  throw new Error(`visualControl(): Specify a schema for this value: ${stringified ?? "[non-serializable value]"}. See https://remotion.dev/docs/studio/visual-control`);
}

// src/components/get-zod-if-possible.tsx


async function getZodIfPossible() {
  try {
    const { z } = await Promise.all(/* import() */[__webpack_require__.e(69), __webpack_require__.e(997)]).then(__webpack_require__.bind(__webpack_require__, 997));
    return z;
  } catch {
    return null;
  }
}
var getZodV3IfPossible = async () => {
  try {
    const mod = await __webpack_require__.e(/* import() */ 161).then(__webpack_require__.bind(__webpack_require__, 3161));
    return mod;
  } catch {
    return null;
  }
};
var getZTypesIfPossible = async () => {
  try {
    const mod = await Promise.all(/* import() */[__webpack_require__.e(69), __webpack_require__.e(761)]).then(__webpack_require__.bind(__webpack_require__, 761));
    return mod;
  } catch {
    return null;
  }
};
function useZodIfPossible() {
  const context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ZodContext);
  return context?.zod ?? null;
}
var useZodTypesIfPossible = () => {
  const context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ZodContext);
  return context?.zodTypes ?? null;
};
var ZodContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)(null);
var ZodProvider = ({ children }) => {
  const [zod, setZod] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const [zodV3, setZodV3] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const [zodTypes, setZodTypes] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    getZodIfPossible().then((z) => setZod(z));
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    getZodV3IfPossible().then((z) => setZodV3(z));
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    getZTypesIfPossible().then((z) => setZodTypes(z));
  }, []);
  const contextValue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      zod,
      zodV3,
      zodTypes
    };
  }, [zod, zodV3, zodTypes]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodContext.Provider, {
    value: contextValue,
    children
  });
};

// src/visual-controls/get-current-edited-value.ts
var getVisualControlEditedValue = ({
  handles,
  key
}) => {
  return handles?.[key]?.unsavedValue ?? null;
};

// src/visual-controls/VisualControls.tsx

var VisualControlsTabActivatedContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)(false);
var VisualControlsContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  handles: {}
});
var visualControlRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.createRef)();
var SetVisualControlsContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  updateHandles: () => {
    throw new Error("updateHandles is not implemented");
  },
  updateValue: () => {
    throw new Error("updateValue is not implemented");
  },
  visualControl: () => {
    throw new Error("visualControl is not implemented");
  }
});
var VisualControlsProvider = ({ children }) => {
  const imperativeHandles = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)({});
  const [handles, setHandles] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({});
  const state = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      handles
    };
  }, [handles]);
  const setControl = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((key, value) => {
    const currentUnsaved = imperativeHandles.current?.[key]?.unsavedValue;
    const currentSavedState = imperativeHandles.current?.[key]?.valueInCode;
    const changedSavedValue = value.valueInCode !== currentSavedState;
    const changedUnsavedValue = currentUnsaved === undefined && value.valueInCode !== undefined;
    imperativeHandles.current = {
      ...imperativeHandles.current,
      [key]: {
        ...value,
        unsavedValue: currentUnsaved ?? value.valueInCode,
        valueInCode: value.valueInCode
      }
    };
    return {
      changed: changedSavedValue || changedUnsavedValue,
      currentValue: getVisualControlEditedValue({
        key,
        handles: imperativeHandles.current
      })
    };
  }, []);
  const z = useZodIfPossible();
  const changedRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(false);
  const env = (0,remotion__WEBPACK_IMPORTED_MODULE_2__.useRemotionEnvironment)();
  const visualControl = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(function(key, value, schema) {
    if (handles && false) // removed by dead control flow
{}
    if (!env.isStudio) {
      return value;
    }
    if (!z) {
      return value;
    }
    const { changed, currentValue } = setControl(key, {
      valueInCode: value,
      schema: schema ?? getZodSchemaFromPrimitive(value, z),
      stack: new Error().stack
    });
    if (changed) {
      changedRef.current = true;
    }
    return currentValue;
  }, [setControl, handles, z, env.isStudio]);
  const updateHandles = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHandles(() => {
      return imperativeHandles.current;
    });
  }, []);
  const updateValue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((key, value) => {
    imperativeHandles.current = {
      ...imperativeHandles.current,
      [key]: {
        ...imperativeHandles.current[key],
        unsavedValue: value
      }
    };
    updateHandles();
  }, [updateHandles]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(visualControlRef, () => {
    return {
      globalVisualControl: visualControl
    };
  }, [visualControl]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const callback = () => {
      if (imperativeHandles.current) {
        updateHandles();
        changedRef.current = false;
      }
    };
    const interval = setInterval(callback, 100);
    return () => {
      clearInterval(interval);
    };
  }, [updateHandles]);
  const setState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      setControl,
      updateHandles,
      updateValue,
      visualControl
    };
  }, [setControl, updateHandles, updateValue, visualControl]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(VisualControlsTabActivatedContext.Provider, {
    value: Object.keys(state.handles).length > 0,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(VisualControlsContext.Provider, {
      value: state,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SetVisualControlsContext.Provider, {
        value: setState,
        children
      })
    })
  });
};

// src/components/GlobalPropsEditorUpdateButton.tsx



// src/api/save-default-props.ts


// src/components/RenderModal/SchemaEditor/extract-enum-json-paths.ts
var extractEnumJsonPaths = ({
  schema,
  zodRuntime,
  currentPath,
  zodTypes
}) => {
  const description = getZodSchemaDescription(schema);
  if (zodTypes && description === zodTypes.ZodZypesInternals.REMOTION_MATRIX_BRAND) {
    return [currentPath];
  }
  const typeName = getZodSchemaType(schema);
  switch (typeName) {
    case "object": {
      const shape = getObjectShape(schema);
      const keys = Object.keys(shape);
      return keys.map((key) => {
        return extractEnumJsonPaths({
          schema: shape[key],
          zodRuntime,
          currentPath: [...currentPath, key],
          zodTypes
        });
      }).flat(1);
    }
    case "array": {
      return extractEnumJsonPaths({
        schema: getArrayElement(schema),
        zodRuntime,
        currentPath: [...currentPath, "[]"],
        zodTypes
      });
    }
    case "union": {
      return getUnionOptions(schema).map((option) => {
        return extractEnumJsonPaths({
          schema: option,
          zodRuntime,
          currentPath,
          zodTypes
        });
      }).flat(1);
    }
    case "discriminatedUnion": {
      return getUnionOptions(schema).map((op) => {
        return extractEnumJsonPaths({
          schema: op,
          zodRuntime,
          currentPath,
          zodTypes
        });
      }).flat(1);
    }
    case "literal": {
      return [currentPath];
    }
    case "effects": {
      return extractEnumJsonPaths({
        schema: getEffectsInner(schema),
        zodRuntime,
        currentPath,
        zodTypes
      });
    }
    case "intersection": {
      const { left: left3, right } = getIntersectionSchemas(schema);
      const leftValue = extractEnumJsonPaths({
        schema: left3,
        zodRuntime,
        currentPath,
        zodTypes
      });
      const rightValue = extractEnumJsonPaths({
        schema: right,
        zodRuntime,
        currentPath,
        zodTypes
      });
      return [...leftValue, ...rightValue];
    }
    case "tuple": {
      return getTupleItems(schema).map((item, i) => extractEnumJsonPaths({
        schema: item,
        zodRuntime,
        currentPath: [...currentPath, i],
        zodTypes
      })).flat(1);
    }
    case "record": {
      const recordPath = [...currentPath, "{}"];
      const keyResults = extractEnumJsonPaths({
        schema: getRecordKeyType(schema),
        zodRuntime,
        currentPath: recordPath,
        zodTypes
      });
      const valueResults = extractEnumJsonPaths({
        schema: getRecordValueType(schema),
        zodRuntime,
        currentPath: recordPath,
        zodTypes
      });
      return [...keyResults, ...valueResults];
    }
    case "function": {
      throw new Error("Cannot create a value for type function");
    }
    case "enum": {
      return [currentPath];
    }
    case "nativeEnum": {
      return [];
    }
    case "optional":
    case "nullable":
    case "catch": {
      return extractEnumJsonPaths({
        schema: getInnerType(schema),
        zodRuntime,
        currentPath,
        zodTypes
      });
    }
    case "default": {
      return extractEnumJsonPaths({
        schema: getInnerType(schema),
        zodRuntime,
        currentPath,
        zodTypes
      });
    }
    case "promise": {
      return [];
    }
    case "branded": {
      return extractEnumJsonPaths({
        schema: getBrandedInner(schema),
        zodRuntime,
        currentPath,
        zodTypes
      });
    }
    case "pipeline":
    case "pipe": {
      return extractEnumJsonPaths({
        schema: getPipelineOutput(schema),
        zodRuntime,
        currentPath,
        zodTypes
      });
    }
    case "string":
    case "number":
    case "bigint":
    case "boolean":
    case "nan":
    case "date":
    case "symbol":
    case "undefined":
    case "null":
    case "any":
    case "unknown":
    case "never":
    case "void":
    case "map":
    case "lazy":
    case "set":
    case "custom": {
      return [];
    }
    default:
      throw new Error("Not implemented: " + typeName);
  }
};

// src/api/helpers/calc-new-props.ts

var calcNewProps = (compositionId, defaultProps) => {
  if (!(0,remotion__WEBPACK_IMPORTED_MODULE_2__.getRemotionEnvironment)().isStudio) {
    throw new Error("saveDefaultProps can only be called in the Remotion Studio.");
  }
  const { compositionsRef, editorPropsProviderRef } = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals;
  const compositionsStore = compositionsRef.current;
  if (!compositionsStore) {
    throw new Error("No compositions ref found. Are you in the Remotion Studio and are the Remotion versions aligned?");
  }
  const compositions = compositionsStore.getCompositions();
  const composition = compositions.find((c) => c.id === compositionId);
  if (!composition) {
    throw new Error(`No composition with the ID ${compositionId} found. Available compositions: ${compositions.map((c) => c.id).join(", ")}`);
  }
  const propsStore = editorPropsProviderRef.current;
  if (!propsStore) {
    throw new Error("No props store found. Are you in the Remotion Studio and are the Remotion versions aligned?");
  }
  const savedDefaultProps = composition.defaultProps ?? {};
  const unsavedDefaultProps = propsStore.getProps()[compositionId] ?? savedDefaultProps;
  const generatedDefaultProps = defaultProps({
    schema: composition.schema,
    savedDefaultProps,
    unsavedDefaultProps
  });
  return {
    composition,
    generatedDefaultProps
  };
};

// src/api/save-default-props.ts
var saveDefaultProps = async ({
  compositionId,
  defaultProps
}) => {
  if (!(0,remotion__WEBPACK_IMPORTED_MODULE_2__.getRemotionEnvironment)().isStudio) {
    throw new Error("saveDefaultProps() is only available in the Studio");
  }
  if (window.remotion_isReadOnlyStudio) {
    throw new Error("saveDefaultProps() is not available in read-only Studio");
  }
  try {
    await Promise.all(/* import() */[__webpack_require__.e(69), __webpack_require__.e(997)]).then(__webpack_require__.bind(__webpack_require__, 997));
  } catch {
    throw new Error('"zod" is required to use saveDefaultProps(), but is not installed.');
  }
  const z = await Promise.all(/* import() */[__webpack_require__.e(69), __webpack_require__.e(997)]).then(__webpack_require__.bind(__webpack_require__, 997));
  let zodTypes = null;
  try {
    zodTypes = await Promise.all(/* import() */[__webpack_require__.e(69), __webpack_require__.e(761)]).then(__webpack_require__.bind(__webpack_require__, 761));
  } catch {}
  const { generatedDefaultProps, composition } = calcNewProps(compositionId, defaultProps);
  const res = await callUpdateDefaultPropsApi(compositionId, generatedDefaultProps, composition.schema ? extractEnumJsonPaths({
    schema: composition.schema,
    zodRuntime: z,
    currentPath: [],
    zodTypes
  }) : []);
  if (res.success) {
    return Promise.resolve();
  }
  const err = new Error(res.reason);
  err.stack = res.stack;
  return Promise.reject(err);
};

// src/fast-refresh-context.ts

var FastRefreshContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  fastRefreshes: 0,
  manualRefreshes: 0,
  increaseManualRefreshes: () => {}
});

// src/components/RenderModal/SchemaEditor/SchemaResetButton.tsx


var icon2 = {
  height: 14,
  color: "currentColor"
};
var SchemaResetButton = ({ onClick }) => {
  const renderAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      style: icon2,
      viewBox: "0 0 512 512",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        fill: color,
        d: "M48.5 224H40c-13.3 0-24-10.7-24-24V72c0-9.7 5.8-18.5 14.8-22.2s19.3-1.7 26.2 5.2L98.6 96.6c87.6-86.5 228.7-86.2 315.8 1c87.5 87.5 87.5 229.3 0 316.8s-229.3 87.5-316.8 0c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0c62.5 62.5 163.8 62.5 226.3 0s62.5-163.8 0-226.3c-62.2-62.2-162.7-62.5-225.3-1L185 183c6.9 6.9 8.9 17.2 5.2 26.2s-12.5 14.8-22.2 14.8H48.5z"
      })
    });
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
    renderAction,
    onClick
  });
};

// src/components/RenderModal/SchemaEditor/SchemaSaveButton.tsx


var icon3 = {
  height: 14,
  color: "currentColor"
};
var SchemaSaveButton = ({ onClick, disabled }) => {
  const renderAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      style: icon3,
      viewBox: "0 0 448 512",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        fill: disabled ? LIGHT_TEXT : color,
        d: "M64 32C28.7 32 0 60.7 0 96V416c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V173.3c0-17-6.7-33.3-18.7-45.3L352 50.7C340 38.7 323.7 32 306.7 32H64zm0 96c0-17.7 14.3-32 32-32H288c17.7 0 32 14.3 32 32v64c0 17.7-14.3 32-32 32H96c-17.7 0-32-14.3-32-32V128zM224 288a64 64 0 1 1 0 128 64 64 0 1 1 0-128z"
      })
    });
  }, [disabled]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
    renderAction,
    onClick,
    disabled
  });
};

// src/components/GlobalPropsEditorUpdateButton.tsx

var container25 = {
  display: "inline-block",
  flexDirection: "row"
};
var GlobalPropsEditorUpdateButton = ({ compositionId, currentDefaultProps }) => {
  const { fastRefreshes } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(FastRefreshContext);
  const [disabled, setDisabled] = react__WEBPACK_IMPORTED_MODULE_0__.useState(false);
  const onClicked = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setDisabled(true);
    window.remotion_ignoreFastRefreshUpdate = fastRefreshes + 1;
    saveDefaultProps({
      compositionId,
      defaultProps: () => currentDefaultProps
    }).catch((err) => {
      showNotification(`Cannot update default props: ${err.stack}`, 2000);
    }).finally(() => {
      setDisabled(true);
    });
  }, [compositionId, currentDefaultProps, fastRefreshes]);
  const onReset = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    window.remotion_ignoreFastRefreshUpdate = null;
    window.dispatchEvent(new CustomEvent(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.PROPS_UPDATED_EXTERNALLY, {
      detail: {
        resetUnsaved: compositionId
      }
    }));
  }, [compositionId]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container25,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaResetButton, {
        onClick: onReset
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaSaveButton, {
        disabled,
        onClick: onClicked
      })
    ]
  });
};

// src/components/RenderModal/DataEditor.tsx




// src/components/NewComposition/ValidationMessage.tsx


var WarningTriangle = (props) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    viewBox: "0 0 576 512",
    ...props,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      d: "M248.747 204.705l6.588 112c.373 6.343 5.626 11.295 11.979 11.295h41.37a12 12 0 0 0 11.979-11.295l6.588-112c.405-6.893-5.075-12.705-11.979-12.705h-54.547c-6.903 0-12.383 5.812-11.978 12.705zM330 384c0 23.196-18.804 42-42 42s-42-18.804-42-42 18.804-42 42-42 42 18.804 42 42zm-.423-360.015c-18.433-31.951-64.687-32.009-83.154 0L6.477 440.013C-11.945 471.946 11.118 512 48.054 512H527.94c36.865 0 60.035-39.993 41.577-71.987L329.577 23.985zM53.191 455.002L282.803 57.008c2.309-4.002 8.085-4.002 10.394 0l229.612 397.993c2.308 4-.579 8.998-5.197 8.998H58.388c-4.617.001-7.504-4.997-5.197-8.997z"
    })
  });
};
var style6 = {
  width: 12,
  height: 12,
  flexShrink: 0
};
var container26 = {
  maxWidth: 500
};
var label4 = {
  fontSize: 13,
  color: "white",
  fontFamily: "sans-serif"
};
var ValidationMessage = ({ message, align, type }) => {
  const finalStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...style6,
      fill: type === "warning" ? WARNING_COLOR : FAIL_COLOR
    };
  }, [type]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: container26,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
      align: "center",
      justify: align,
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(WarningTriangle, {
          style: finalStyle
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
          x: 1
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: label4,
          children: message
        })
      ]
    })
  });
};

// src/components/SegmentedControl.tsx


var container27 = {
  display: "flex",
  flexDirection: "row",
  overflow: "hidden",
  border: "1px solid " + INPUT_BORDER_COLOR_UNHOVERED,
  flexWrap: "wrap",
  maxWidth: 350,
  justifyContent: "flex-end"
};
var item = {
  display: "flex",
  fontSize: 15,
  padding: "4px 12px",
  cursor: "pointer",
  appearance: "none",
  border: "none",
  flex: 1,
  justifyContent: "center",
  whiteSpace: "nowrap"
};
var SegmentedControl = ({ items, needsWrapping }) => {
  const controlStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (needsWrapping) {
      return {
        ...container27,
        flexWrap: "wrap",
        maxWidth: "248px",
        justifyContent: "flex-end",
        marginBottom: "8px"
      };
    }
    return {
      ...container27
    };
  }, [needsWrapping]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: controlStyle,
    children: items.map((i) => {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Item, {
        onClick: i.onClick,
        selected: i.selected,
        children: i.label
      }, i.key);
    })
  });
};
var Item = ({ selected, onClick, children }) => {
  const [hovered, setHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const { tabIndex } = useZIndex();
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(true);
  }, []);
  const onPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(false);
  }, []);
  const itemStyle3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...item,
      backgroundColor: selected ? INPUT_BACKGROUND : "transparent",
      color: selected ? "white" : hovered ? "white" : LIGHT_TEXT
    };
  }, [hovered, selected]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
    type: "button",
    onPointerEnter,
    onPointerLeave,
    style: itemStyle3,
    tabIndex,
    onClick,
    children
  });
};

// src/components/RenderModal/get-render-modal-warnings.ts

var defaultTypeCanSaveState = {
  canUpdate: false,
  reason: "Loading...",
  determined: false
};
var getInputPropsWarning = ({
  cliProps,
  propsEditType
}) => {
  if (Object.keys(cliProps).length > 0 && propsEditType === "default-props") {
    return "The data that was passed using --props takes priority over the data you enter here.";
  }
  return null;
};
var getCannotSaveDefaultProps = (canSaveDefaultProps) => {
  if (canSaveDefaultProps.canUpdate) {
    return null;
  }
  if (!canSaveDefaultProps.determined) {
    return null;
  }
  return `Can't save default props: ${canSaveDefaultProps.reason}.`;
};
var customDateUsed = (used, inJSONEditor) => {
  if (used && inJSONEditor) {
    return "There is a Date in the schema which was serialized. Note the custom syntax.";
  }
  return null;
};
var staticFileUsed = (used, inJSONEditor) => {
  if (used && inJSONEditor) {
    return "There is a staticFile() in the schema which was serialized. Note the custom syntax.";
  }
  return null;
};
var mapUsed = (used, inJSONEditor) => {
  if (used && inJSONEditor) {
    return "A `Map` was used in the schema which can not be serialized to JSON.";
  }
  return null;
};
var setUsed = (used, inJSONEditor) => {
  if (used && inJSONEditor) {
    return "A `Set` was used in the schema which can not be serialized to JSON.";
  }
  return null;
};
var getRenderModalWarnings = ({
  cliProps,
  canSaveDefaultProps,
  isCustomDateUsed,
  customFileUsed,
  jsMapUsed,
  jsSetUsed,
  inJSONEditor,
  propsEditType
}) => {
  return [
    getInputPropsWarning({ cliProps, propsEditType }),
    getCannotSaveDefaultProps(canSaveDefaultProps),
    customDateUsed(isCustomDateUsed, inJSONEditor),
    staticFileUsed(customFileUsed, inJSONEditor),
    mapUsed(jsMapUsed, inJSONEditor),
    setUsed(jsSetUsed, inJSONEditor)
  ].filter(remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.truthy);
};

// src/components/RenderModal/RenderModalJSONPropsEditor.tsx



// src/components/RenderModal/SchemaEditor/deep-equal.ts
function deepEqual(a, b) {
  if (a === b) {
    return true;
  }
  if (a instanceof Date && b instanceof Date) {
    return a.getTime() === b.getTime();
  }
  if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) {
    return false;
  }
  const keysA = Object.keys(a);
  const keysB = Object.keys(b);
  if (keysA.length !== keysB.length) {
    return false;
  }
  for (const key of keysA) {
    if (!keysB.includes(key) || !deepEqual(a[key], b[key])) {
      return false;
    }
  }
  return true;
}

// src/components/RenderModal/SchemaEditor/ZodErrorMessages.tsx


var schemaLabel = {
  fontSize: 14,
  color: LIGHT_TEXT
};
var jsonLabel = {
  color: "white",
  fontSize: 13,
  fontFamily: "sans-serif",
  display: "flex",
  alignItems: "center"
};
var triangleStyle = {
  width: 12,
  height: 12,
  flexShrink: 0,
  fill: FAIL_COLOR
};
var ZodErrorMessages = ({ zodValidationResult, viewTab }) => {
  if (zodValidationResult.success) {
    throw new Error("Expected error");
  }
  const style7 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return viewTab === "json" ? jsonLabel : schemaLabel;
  }, [viewTab]);
  const code = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...schemaLabel,
      fontFamily: "monospace"
    };
  }, []);
  if (viewTab === "json") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      children: zodValidationResult.error.issues.map((error) => {
        return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
          style: style7,
          children: [
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(WarningTriangle, {
              style: triangleStyle
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
              x: 1
            }),
            error.path.length === 0 ? "Root" : error.path.join("."),
            ":",
            " ",
            error.message
          ]
        }, error.path.join("."));
      })
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    children: zodValidationResult.error.issues.map((error) => {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: style7,
        children: [
          "-",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: code,
            children: error.path.length === 0 ? "Root" : error.path.join(".")
          }),
          ": ",
          error.message
        ]
      }, error.path.join("."));
    })
  });
};

// src/components/RenderModal/RenderModalJSONPropsEditor.tsx

var style7 = {
  fontFamily: "monospace",
  flex: 1
};
var scrollable = {
  padding: "8px 12px",
  display: "flex",
  flexDirection: "column",
  flex: 1
};
var parseJSON = (str, schema) => {
  try {
    const value = remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.deserializeJSONWithSpecialTypes(str);
    const zodValidation = zodSafeParse(schema, value);
    return { str, value, validJSON: true, zodValidation };
  } catch (e) {
    return { str, validJSON: false, error: e.message };
  }
};
var RenderModalJSONPropsEditor = ({
  setValue,
  value,
  defaultProps,
  onSave,
  showSaveButton,
  serializedJSON,
  schema
}) => {
  if (serializedJSON === null) {
    throw new Error("expecting serializedJSON to be defined");
  }
  const keybindings = useKeybinding();
  const [localValue, setLocalValue] = react__WEBPACK_IMPORTED_MODULE_0__.useState(() => {
    return parseJSON(serializedJSON.serializedString, schema);
  });
  const onPretty = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (!localValue.validJSON) {
      return;
    }
    const parsed = JSON.parse(localValue.str);
    setLocalValue({ ...localValue, str: JSON.stringify(parsed, null, 2) });
  }, [localValue, setLocalValue]);
  const onChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    const parsed = parseJSON(e.target.value, schema);
    if (parsed.validJSON) {
      const validationResult = zodSafeParse(schema, parsed.value);
      setLocalValue({
        str: e.target.value,
        value: parsed.value,
        validJSON: parsed.validJSON,
        zodValidation: validationResult
      });
      if (validationResult.success) {
        setValue(parsed.value);
      }
    } else {
      setLocalValue({
        str: e.target.value,
        validJSON: parsed.validJSON,
        error: parsed.error
      });
    }
  }, [schema, setValue]);
  const hasChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return !deepEqual(value, defaultProps);
  }, [defaultProps, value]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    setUnsavedProps(hasChanged);
  }, [hasChanged]);
  const onQuickSave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (hasChanged) {
      onSave();
    }
  }, [hasChanged, onSave]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    setLocalValue(parseJSON(localValue.str, schema));
  }, [localValue.str, schema]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const save = keybindings.registerKeybinding({
      event: "keydown",
      key: "s",
      commandCtrlKey: true,
      callback: onQuickSave,
      preventDefault: true,
      triggerIfInputFieldFocused: true,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      save.unregister();
    };
  }, [keybindings, onQuickSave, onSave]);
  const reset = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setValue(defaultProps);
    setLocalValue(parseJSON(JSON.stringify(defaultProps, null, 2), schema));
  }, [defaultProps, schema, setValue]);
  const textAreaStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const fail = !localValue.validJSON || !localValue.zodValidation.success;
    if (!fail) {
      return style7;
    }
    return {
      ...style7,
      borderColor: FAIL_COLOR
    };
  }, [localValue]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: scrollable,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemTextarea, {
        onChange,
        value: localValue.str,
        status: localValue.validJSON ? "ok" : "error",
        style: textAreaStyle
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 1
      }),
      localValue.validJSON === false ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ValidationMessage, {
        align: "flex-start",
        message: localValue.error,
        type: "error"
      }) : localValue.zodValidation.success === false ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodErrorMessages, {
        zodValidationResult: localValue.zodValidation,
        viewTab: "json"
      }) : null,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
            disabled: !(hasChanged || !localValue.validJSON),
            onClick: reset,
            children: "Reset"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {}),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
            disabled: !localValue.validJSON,
            onClick: onPretty,
            children: "Format"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 1
          }),
          showSaveButton ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
            onClick: onSave,
            disabled: !(localValue.validJSON && localValue.zodValidation.success) || !localValue.validJSON || !hasChanged,
            children: "Save"
          }) : null
        ]
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/SchemaEditor.tsx



// src/components/RenderModal/SchemaEditor/local-state.tsx



var RevisionContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  childResetRevision: 0
});
var useLocalState = ({
  unsavedValue,
  schema,
  setValue,
  savedValue
}) => {
  const parentRevision = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(RevisionContext).childResetRevision;
  const [resetRevision, setResetRevision] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(0);
  const [localValueOrNull, setLocalValue] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => {
    return {
      [parentRevision]: {
        value: unsavedValue,
        keyStabilityRevision: 0,
        zodValidation: zodSafeParse(schema, unsavedValue)
      }
    };
  });
  const localUnsavedValue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if ((localValueOrNull[parentRevision] ?? null) === null) {
      return {
        value: unsavedValue,
        keyStabilityRevision: 0,
        zodValidation: zodSafeParse(schema, unsavedValue)
      };
    }
    return localValueOrNull[parentRevision];
  }, [localValueOrNull, parentRevision, schema, unsavedValue]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const checkFile = () => {
      setResetRevision((old) => old + 1);
      setLocalValue({});
    };
    window.addEventListener(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.PROPS_UPDATED_EXTERNALLY, checkFile);
    return () => {
      window.removeEventListener(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.PROPS_UPDATED_EXTERNALLY, checkFile);
    };
  }, []);
  const currentLocalValue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return localUnsavedValue ?? {
      value: savedValue,
      keyStabilityRevision: 0,
      zodValidation: zodSafeParse(schema, savedValue)
    };
  }, [localUnsavedValue, savedValue, schema]);
  const stateRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(currentLocalValue);
  stateRef.current = currentLocalValue;
  const onChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((updater, forceApply, increment) => {
    const newValue = updater(stateRef.current.value);
    const isSame = deepEqual(newValue, stateRef.current.value);
    if (isSame) {
      return;
    }
    const safeParse = zodSafeParse(schema, newValue);
    if (safeParse.success || forceApply) {
      setValue(updater, forceApply, increment);
    }
    setLocalValue(() => {
      const newState = {
        keyStabilityRevision: currentLocalValue.keyStabilityRevision + (increment ? 1 : 0),
        value: newValue,
        zodValidation: safeParse
      };
      stateRef.current = newState;
      return {
        ...localUnsavedValue,
        [parentRevision]: newState
      };
    });
  }, [
    currentLocalValue.keyStabilityRevision,
    localUnsavedValue,
    parentRevision,
    schema,
    setValue
  ]);
  const contextValue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      childResetRevision: resetRevision
    };
  }, [resetRevision]);
  const reset = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onChange(() => savedValue, true, true);
    setResetRevision((old) => old + 1);
  }, [savedValue, onChange]);
  const RevisionContextProvider = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(({ children }) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RevisionContext.Provider, {
      value: contextValue,
      children
    });
  }, [contextValue]);
  return (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => ({
    localValue: currentLocalValue,
    onChange,
    reset,
    RevisionContextProvider
  }), [RevisionContextProvider, currentLocalValue, onChange, reset]);
};

// src/components/RenderModal/SchemaEditor/SchemaErrorMessages.tsx

var explainer = {
  display: "flex",
  flex: 1,
  flexDirection: "column",
  padding: "0 12px",
  justifyContent: "center",
  alignItems: "center",
  textAlign: "center",
  background: BACKGROUND
};
var errorExplanation = {
  fontSize: 14,
  color: LIGHT_TEXT,
  fontFamily: "sans-serif",
  lineHeight: 1.5
};
var codeSnippet = {
  fontSize: 14,
  color: BLUE,
  fontFamily: "monospace"
};
var errorContainer = {
  padding: "8px 12px",
  overflowY: "auto"
};
var openDocs = () => {
  window.open("https://www.remotion.dev/docs/schemas");
};
var ZodNotInstalled = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: explainer,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: errorExplanation,
        children: [
          "Install ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: inlineCodeSnippet,
            children: "zod"
          }),
          " as a dependency to interactively control the props of the composition."
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 2,
        block: true
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
        onClick: openDocs,
        children: "Learn how"
      })
    ]
  });
};
var NoSchemaDefined = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: explainer,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: errorExplanation,
        children: [
          "Make the props of this composition interactively editable by adding a",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: inlineCodeSnippet,
            children: "schema"
          }),
          " prop to the",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: inlineCodeSnippet,
            children: "<Composition>"
          }),
          " component."
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 2,
        block: true
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
        onClick: openDocs,
        children: "Learn how"
      })
    ]
  });
};
var NoDefaultProps = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: explainer,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: errorExplanation,
        children: [
          "The schema can not be edited because the",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: inlineCodeSnippet,
            children: "defaultProps"
          }),
          " prop in the",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: inlineCodeSnippet,
            children: "<Composition>"
          }),
          " does not exist."
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: errorExplanation,
        children: [
          "Fix the schema by adding a",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: inlineCodeSnippet,
            children: "defaultProps"
          }),
          " prop to your composition."
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 2,
        block: true
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
        onClick: openDocs,
        children: "Learn more"
      })
    ]
  });
};
var InvalidDefaultProps = ({ zodValidationResult }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: errorContainer,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: errorExplanation,
        children: [
          "The schema can not be edited because the",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: inlineCodeSnippet,
            children: "defaultProps"
          }),
          " prop in the",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: inlineCodeSnippet,
            children: "<Composition>"
          }),
          " is not valid:"
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 1,
        block: true
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodErrorMessages, {
        zodValidationResult,
        viewTab: "schema"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 1,
        block: true
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: errorExplanation,
        children: [
          "Fix the schema by changing the",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: inlineCodeSnippet,
            children: "defaultProps"
          }),
          " prop in your composition so it does not give a type error."
        ]
      })
    ]
  });
};
var InvalidSchema = ({ zodValidationResult, reset }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: errorContainer,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: errorExplanation,
        children: "The data does not satisfy the schema:"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 1,
        block: true
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodErrorMessages, {
        zodValidationResult,
        viewTab: "schema"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 1,
        block: true
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: errorExplanation,
        children: "Fix the schema using the JSON editor."
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 1,
        block: true
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: errorExplanation,
        children: [
          "Alternatively, reset the data to the",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: inlineCodeSnippet,
            children: "defaultProps"
          }),
          " that you have defined."
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 1,
        block: true
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
        onClick: reset,
        children: "Reset props"
      })
    ]
  });
};
var TopLevelZodValue = ({ typeReceived }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: explainer,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: errorExplanation,
        children: [
          "The top-level type of the schema must be a pure",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: codeSnippet,
            children: "z.object"
          }),
          ". Instead got a schema of type",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: codeSnippet,
            children: typeReceived
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: errorExplanation,
        children: "Fix the schema by changing the top-level Zod type to an object."
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 2,
        block: true
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
        onClick: openDocs,
        children: "Learn more"
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/scroll-to-default-props-path.ts

var DEFAULT_PROPS_PATH_CLASSNAME = "__remotion-default-props-editor-label";
var DEFAULT_PROPS_PATH_ACTIVE_CLASSNAME = "__remotion-default-props-editor-label-active";
var defaultPropsEditorScrollableAreaRef = react__WEBPACK_IMPORTED_MODULE_0__.createRef();

// src/components/RenderModal/SchemaEditor/ZodObjectEditor.tsx


// src/components/RenderModal/layout.ts
var optionRow = {
  display: "flex",
  flexDirection: "row",
  minHeight: 40,
  paddingLeft: 16,
  paddingRight: 16,
  paddingTop: 8,
  paddingBottom: 8
};
var label5 = {
  width: 290,
  fontSize: 15,
  lineHeight: "40px",
  color: LIGHT_TEXT,
  fontFamily: "sans-serif",
  display: "flex",
  flexDirection: "row",
  alignItems: "center"
};
var rightRow = {
  display: "flex",
  flexDirection: "row",
  justifyContent: "flex-end",
  alignSelf: "center",
  flex: 1
};
var input = {
  minWidth: 250
};
var fieldSetText = {
  color: LIGHT_TEXT,
  fontSize: 14,
  fontFamily: "monospace"
};
var fieldsetLabel = {
  ...fieldSetText,
  display: "flex",
  flexDirection: "row",
  alignItems: "center",
  width: "100%"
};

// src/components/RenderModal/SchemaEditor/Fieldset.tsx


var SCHEMA_EDITOR_FIELDSET_PADDING = 10;
var AlreadyPaddedRightContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)(false);
var Fieldset = ({ children, shouldPad }) => {
  const alreadyPadded = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(AlreadyPaddedRightContext);
  const style8 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (shouldPad) {
      return {
        padding: SCHEMA_EDITOR_FIELDSET_PADDING,
        paddingTop: SCHEMA_EDITOR_FIELDSET_PADDING / 2,
        paddingRight: alreadyPadded ? 0 : SCHEMA_EDITOR_FIELDSET_PADDING
      };
    }
    return {};
  }, [alreadyPadded, shouldPad]);
  const content = /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: style8,
    children
  });
  if (shouldPad) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(AlreadyPaddedRightContext.Provider, {
      value: true,
      children: content
    });
  }
  return content;
};

// src/components/RenderModal/SchemaEditor/SchemaLabel.tsx


// src/components/RenderModal/InlineRemoveButton.tsx


var clearIcon = {
  height: 14,
  color: "currentColor"
};
var InlineRemoveButton = ({ onClick }) => {
  const renderAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      xmlns: "http://www.w3.org/2000/svg",
      viewBox: "0 0 320 512",
      style: clearIcon,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        d: "M310.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 210.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L114.7 256 9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 301.3 265.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L205.3 256 310.6 150.6z",
        fill: color
      })
    });
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
    renderAction,
    onClick
  });
};

// src/components/RenderModal/SchemaEditor/get-schema-label.ts
var getSchemaLabel = (jsonPath) => {
  const lastKey = jsonPath[jsonPath.length - 1];
  if (typeof lastKey === "number") {
    const secondLastKey = jsonPath[jsonPath.length - 2];
    if (typeof secondLastKey === "undefined") {
      return `[${lastKey}]:`;
    }
    return `${lastKey}:`;
  }
  return `${lastKey}:`;
};

// src/components/RenderModal/SchemaEditor/SchemaLabel.tsx

var compactStyles = {
  fontSize: 15,
  color: LIGHT_TEXT,
  fontFamily: "sans-serif",
  display: "flex",
  flexDirection: "row",
  alignItems: "center",
  flex: 1
};
var SchemaLabel = ({
  jsonPath,
  isDefaultValue,
  onReset,
  onSave,
  showSaveButton,
  onRemove,
  saving,
  valid,
  saveDisabledByParent,
  suffix: suffix2,
  handleClick
}) => {
  const [clickableButtonHovered, setClickableButtonHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const disableSave = saving || !valid || saveDisabledByParent;
  const labelStyle4 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      fontFamily: "monospace",
      fontSize: 14,
      color: valid ? clickableButtonHovered ? "white" : LIGHT_TEXT : FAIL_COLOR,
      lineHeight: "24px"
    };
  }, [clickableButtonHovered, valid]);
  const onClickablePointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setClickableButtonHovered(true);
  }, []);
  const onClickablePointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setClickableButtonHovered(false);
  }, []);
  const labelContent = /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("span", {
    style: labelStyle4,
    children: [
      getSchemaLabel(jsonPath),
      " ",
      suffix2 ? suffix2 : null
    ]
  });
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: compactStyles,
    className: DEFAULT_PROPS_PATH_CLASSNAME,
    "data-json-path": jsonPath.join("."),
    children: [
      handleClick ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
        onPointerEnter: onClickablePointerEnter,
        onPointerLeave: onClickablePointerLeave,
        type: "button",
        onClick: handleClick,
        style: { border: "none", padding: 0 },
        children: labelContent
      }) : labelContent,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {}),
      isDefaultValue ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaResetButton, {
        onClick: onReset
      }),
      isDefaultValue ? null : showSaveButton ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaSaveButton, {
        onClick: onSave,
        disabled: disableSave
      }) : null,
      onRemove ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineRemoveButton, {
        onClick: onRemove
      }) : null
    ]
  });
};

// src/components/RenderModal/SchemaEditor/SchemaSeparationLine.tsx


// src/icons/plus.tsx

var Plus = ({ color, ...props }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    ...props,
    xmlns: "http://www.w3.org/2000/svg",
    viewBox: "0 0 448 512",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: color,
      d: "M432 256c0 17.69-14.33 32.01-32 32.01H256v144c0 17.69-14.33 31.99-32 31.99s-32-14.3-32-31.99v-144H48c-17.67 0-32-14.32-32-32.01s14.33-31.99 32-31.99H192v-144c0-17.69 14.33-32.01 32-32.01s32 14.32 32 32.01v144h144C417.7 224 432 238.3 432 256z"
    })
  });
};

// src/components/RenderModal/SchemaEditor/create-zod-values.ts
var createZodValues = (schema, zodRuntime, zodTypes) => {
  if (!schema) {
    throw new Error("Invalid zod schema");
  }
  const description = getZodSchemaDescription(schema);
  if (zodTypes) {
    if (description === zodTypes.ZodZypesInternals.REMOTION_COLOR_BRAND) {
      return "#ffffff";
    }
    if (description === zodTypes.ZodZypesInternals.REMOTION_TEXTAREA_BRAND) {
      return "";
    }
    if (description === zodTypes.ZodZypesInternals.REMOTION_MATRIX_BRAND) {
      return [
        [1, 0, 0],
        [0, 1, 0],
        [0, 0, 1]
      ];
    }
  }
  const typeName = getZodSchemaType(schema);
  switch (typeName) {
    case "string":
      return "";
    case "number": {
      const { checks } = getZodDef(schema);
      if (checks) {
        if (isZodV3Schema(schema)) {
          for (const check of checks) {
            if (check.kind === "min")
              return check.value;
            if (check.kind === "max" && check.value < 0)
              return check.value;
          }
        } else {
          for (const check of checks) {
            const cd = check._zod?.def;
            if (cd?.check === "greater_than")
              return cd.value;
            if (cd?.check === "less_than" && cd.value < 0)
              return cd.value;
          }
        }
      }
      return 0;
    }
    case "bigint":
      return BigInt(0);
    case "boolean":
      return false;
    case "nan":
      return NaN;
    case "date":
      return new Date;
    case "symbol":
      return Symbol("remotion");
    case "undefined":
    case "void":
      return;
    case "null":
      return null;
    case "any":
    case "custom":
      throw new Error("Cannot create a value for type z.any()");
    case "unknown":
      throw new Error("Cannot create a value for type z.unknown()");
    case "never":
      throw new Error("Cannot create a value for type z.never()");
    case "object": {
      const shape = getObjectShape(schema);
      const keys = Object.keys(shape);
      const returnValue = keys.reduce((existing, key) => {
        existing[key] = createZodValues(shape[key], zodRuntime, zodTypes);
        return existing;
      }, {});
      return returnValue;
    }
    case "array": {
      return [createZodValues(getArrayElement(schema), zodRuntime, zodTypes)];
    }
    case "union": {
      const firstOption = getUnionOptions(schema)[0];
      return firstOption ? createZodValues(firstOption, zodRuntime, zodTypes) : undefined;
    }
    case "discriminatedUnion": {
      const firstOption = getUnionOptions(schema)[0];
      return createZodValues(firstOption, zodRuntime, zodTypes);
    }
    case "literal": {
      return getLiteralValue(schema);
    }
    case "effects": {
      return createZodValues(getEffectsInner(schema), zodRuntime, zodTypes);
    }
    case "intersection": {
      const { left: left3, right } = getIntersectionSchemas(schema);
      const leftValue = createZodValues(left3, zodRuntime, zodTypes);
      if (typeof leftValue !== "object") {
        throw new Error("Cannot create value for type z.intersection: Left side is not an object");
      }
      const rightValue = createZodValues(right, zodRuntime, zodTypes);
      if (typeof rightValue !== "object") {
        throw new Error("Cannot create value for type z.intersection: Right side is not an object");
      }
      return { ...leftValue, ...rightValue };
    }
    case "tuple": {
      return getTupleItems(schema).map((item2) => createZodValues(item2, zodRuntime, zodTypes));
    }
    case "record": {
      const values = createZodValues(getRecordValueType(schema), zodRuntime, zodTypes);
      return { key: values };
    }
    case "map": {
      const values = createZodValues(getRecordValueType(schema), zodRuntime, zodTypes);
      const key = createZodValues(getRecordKeyType(schema), zodRuntime, zodTypes);
      return new Map([[key, values]]);
    }
    case "lazy": {
      const type = getZodDef(schema).getter();
      return createZodValues(type, zodRuntime, zodTypes);
    }
    case "set": {
      const values = createZodValues(getZodDef(schema).valueType, zodRuntime, zodTypes);
      return new Set([values]);
    }
    case "function": {
      throw new Error("Cannot create a value for type function");
    }
    case "enum": {
      return getFirstEnumValue(schema);
    }
    case "nativeEnum": {
      return 0;
    }
    case "optional":
    case "nullable":
    case "catch": {
      return createZodValues(getInnerType(schema), zodRuntime, zodTypes);
    }
    case "default": {
      return getDefaultValue(schema);
    }
    case "promise": {
      const def = getZodDef(schema);
      const inner = isZodV3Schema(schema) ? def.type : def.innerType;
      const value = createZodValues(inner, zodRuntime, zodTypes);
      return Promise.resolve(value);
    }
    case "branded": {
      return createZodValues(getBrandedInner(schema), zodRuntime, zodTypes);
    }
    case "pipeline":
    case "pipe": {
      const out = getPipelineOutput(schema);
      if (getZodSchemaType(out) === "transform") {
        return createZodValues(getPipelineInput(schema), zodRuntime, zodTypes);
      }
      return createZodValues(out, zodRuntime, zodTypes);
    }
    default:
      throw new Error("Not implemented: " + typeName);
  }
};

// src/components/RenderModal/SchemaEditor/SchemaSeparationLine.tsx

var VERTICAL_GUIDE_HEIGHT = 24;
var line2 = {
  borderBottom: "1px solid " + LINE_COLOR
};
var SchemaSeparationLine = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: line2
  });
};
var arraySeparationLine = {
  borderBottom: "1px solid " + LINE_COLOR,
  marginTop: -VERTICAL_GUIDE_HEIGHT / 2,
  pointerEvents: "none",
  width: "100%",
  flexBasis: "100%"
};
var SchemaArrayItemSeparationLine = ({ onChange, index, schema, isLast, showAddButton }) => {
  const [outerHovered, setOuterHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const [innerHovered, setInnerHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const zodTypes = useZodTypesIfPossible();
  const z = useZodIfPossible();
  if (!z) {
    throw new Error("expected zod");
  }
  const arrayElement = getArrayElement(schema);
  const onAdd = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onChange((oldV) => {
      return [
        ...oldV.slice(0, index + 1),
        createZodValues(arrayElement, z, zodTypes),
        ...oldV.slice(index + 1)
      ];
    }, false, true);
  }, [arrayElement, index, onChange, z, zodTypes]);
  const dynamicAddButtonStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      display: "flex",
      justifyContent: "center",
      height: VERTICAL_GUIDE_HEIGHT,
      opacity: outerHovered || isLast ? 1 : 0,
      position: "absolute",
      top: "50%",
      left: "50%",
      transform: "translate(-50%, -50%)"
    };
  }, [isLast, outerHovered]);
  const inner = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      background: BACKGROUND,
      paddingLeft: 10,
      paddingRight: 10
    };
  }, []);
  const onOuterMouseEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setOuterHovered(true);
  }, []);
  const onOuterMouseLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setOuterHovered(false);
  }, []);
  const onInnerMouseEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setInnerHovered(true);
  }, []);
  const onInnerMouseLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setInnerHovered(false);
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: {
      display: "flex",
      flexDirection: "row",
      height: VERTICAL_GUIDE_HEIGHT
    },
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: {
          flex: 1,
          position: "relative",
          display: "flex",
          flexDirection: "column",
          alignItems: "flex-end"
        },
        children: [
          showAddButton && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: dynamicAddButtonStyle,
            onPointerEnter: onOuterMouseEnter,
            onPointerLeave: onOuterMouseLeave,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              onClick: onAdd,
              style: inner,
              onPointerEnter: onInnerMouseEnter,
              onPointerLeave: onInnerMouseLeave,
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Plus, {
                color: innerHovered ? "white" : LIGHT_TEXT,
                style: { height: VERTICAL_GUIDE_HEIGHT / 2 }
              })
            })
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: arraySeparationLine
          })
        ]
      }),
      isLast ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 1
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: {
              ...fieldSetText,
              alignItems: "center",
              display: "flex"
            },
            children: "]"
          })
        ]
      }) : null
    ]
  });
};

// src/components/RenderModal/SchemaEditor/SchemaVerticalGuide.tsx


var flex = {
  flex: 1
};
var SchemaVerticalGuide = ({ isRoot, children }) => {
  const outer = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      display: "flex",
      flexDirection: "row",
      position: "relative",
      marginLeft: isRoot ? 0 : 4
    };
  }, [isRoot]);
  const inner = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return isRoot ? {} : {
      height: `calc(100% - ${VERTICAL_GUIDE_HEIGHT / 2}px)`,
      width: 1,
      background: "#363A3E",
      position: "absolute"
    };
  }, [isRoot]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: outer,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: inner
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: flex,
        children
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodArrayEditor.tsx


// src/components/RenderModal/SchemaEditor/ZodArrayItemEditor.tsx


var ZodArrayItemEditor = ({
  elementSchema,
  onChange,
  jsonPath,
  index,
  value,
  defaultValue,
  onSave: onSaveObject,
  showSaveButton,
  saving,
  saveDisabledByParent,
  mayPad,
  mayRemove
}) => {
  const z = useZodIfPossible();
  if (!z) {
    throw new Error("expected zod");
  }
  const onRemove = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onChange((oldV) => [...oldV.slice(0, index), ...oldV.slice(index + 1)], false, true);
  }, [index, onChange]);
  const setValue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((val) => {
    onChange((oldV) => [
      ...oldV.slice(0, index),
      typeof val === "function" ? val(oldV[index]) : val,
      ...oldV.slice(index + 1)
    ], false, false);
  }, [index, onChange]);
  const newJsonPath = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => [...jsonPath, index], [index, jsonPath]);
  const onSave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((updater) => {
    onSaveObject((oldV) => [
      ...oldV.slice(0, index),
      updater(oldV[index]),
      ...oldV.slice(index + 1)
    ], false, false);
  }, [index, onSaveObject]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodSwitch, {
      jsonPath: newJsonPath,
      schema: elementSchema,
      value,
      setValue,
      defaultValue,
      onSave,
      showSaveButton,
      onRemove: mayRemove ? onRemove : null,
      saving,
      saveDisabledByParent,
      mayPad
    })
  });
};

// src/components/RenderModal/InfoBubble.tsx




// src/components/RenderModal/InfoTooltip.tsx


var arrow = {
  height: 7,
  display: "block",
  overflow: "visible",
  marginLeft: 7
};
var arrowUp = {
  ...arrow,
  transform: `translateY(1px)`
};
var arrowDown = {
  ...arrow,
  marginTop: -1
};
var InfoTooltip = ({ children, arrowDirection, backgroundColor }) => {
  const container28 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      boxShadow: arrowDirection === "down" ? SHADOW_TOWARDS_TOP : SHADOW_TOWARDS_BOTTOM,
      background: backgroundColor,
      color: "white",
      border: "0.5px solid " + BORDER_COLOR,
      maxHeight: 200,
      overflow: "auto",
      borderRadius: "4px"
    };
  }, [arrowDirection, backgroundColor]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: {
      display: "flex",
      flexDirection: arrowDirection === "up" ? "column-reverse" : "column",
      alignItems: "flex-start"
    },
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: container28,
        className: VERTICAL_SCROLLBAR_CLASSNAME,
        children
      }),
      arrowDirection === "down" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
        viewBox: "0 0 14 7",
        style: arrowDown,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
          d: `M 14 0 L 7 7 L 0 0`,
          fill: backgroundColor,
          strokeLinecap: "butt",
          stroke: BORDER_COLOR,
          strokeWidth: 0.5
        })
      }) : null,
      arrowDirection === "up" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
        viewBox: "0 0 14 7",
        style: arrowUp,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
          d: `M 0 7 L 7 0 L 14 7`,
          fill: backgroundColor,
          strokeLinecap: "butt",
          stroke: BORDER_COLOR,
          strokeWidth: 0.5
        })
      }) : null
    ]
  });
};

// src/components/RenderModal/InfoBubble.tsx

var icon4 = {
  color: LIGHT_TEXT,
  height: 15
};
var container28 = {
  display: "inline-block",
  border: "none",
  fontSize: 14,
  verticalAlign: "text-bottom"
};
var InfoBubble = ({ title: title4, children }) => {
  const [hovered, setIsHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const [opened, setOpened] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const { tabIndex, currentZIndex } = useZIndex();
  const size2 = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.useElementSize(ref, {
    triggerOnWindowResize: true,
    shouldApplyCssTransforms: true
  });
  const refresh = size2?.refresh;
  const onHide = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setOpened(false);
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const { current } = ref;
    if (!current) {
      return;
    }
    const onMouseEnter = () => setIsHovered(true);
    const onMouseLeave = () => setIsHovered(false);
    const onPointerUp = () => {
      return setOpened((o) => {
        if (!o) {
          refresh?.();
        }
        return !o;
      });
    };
    const onClick = (e) => {
      e.stopPropagation();
      const isKeyboardInitiated = e.detail === 0;
      if (!isKeyboardInitiated) {
        return;
      }
      return setOpened((o) => {
        return !o;
      });
    };
    current.addEventListener("mouseenter", onMouseEnter);
    current.addEventListener("mouseleave", onMouseLeave);
    current.addEventListener("pointerup", onPointerUp);
    current.addEventListener("click", onClick);
    return () => {
      current.removeEventListener("mouseenter", onMouseEnter);
      current.removeEventListener("mouseleave", onMouseLeave);
      current.removeEventListener("pointerup", onPointerUp);
      current.removeEventListener("click", onClick);
    };
  }, [refresh]);
  const layout = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!size2) {
      return "down";
    }
    const spaceToBottom = size2.windowSize.height - (size2.top + size2.height);
    const spaceToTop = size2.top;
    const l = spaceToTop > spaceToBottom ? "down" : "up";
    return l;
  }, [size2]);
  const portalStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!size2 || !opened) {
      return null;
    }
    return {
      ...layout === "up" ? {
        position: "fixed",
        top: size2.top + size2.height
      } : {
        position: "fixed",
        bottom: size2.windowSize.height - size2.top
      },
      left: size2.left
    };
  }, [layout, opened, size2]);
  const style8 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...container28,
      userSelect: "none",
      WebkitUserSelect: "none",
      color: "white",
      display: "inline-flex",
      flexDirection: "row",
      alignItems: "center",
      padding: 6
    };
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
        ref,
        tabIndex,
        style: style8,
        title: title4,
        type: "button",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
          style: icon4,
          viewBox: "0 0 512 512",
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
            fill: hovered ? "white" : LIGHT_TEXT,
            d: "M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM216 336c-13.3 0-24 10.7-24 24s10.7 24 24 24h80c13.3 0 24-10.7 24-24s-10.7-24-24-24h-8V248c0-13.3-10.7-24-24-24H216c-13.3 0-24 10.7-24 24s10.7 24 24 24h24v64H216zm40-144a32 32 0 1 0 0-64 32 32 0 1 0 0 64z"
          })
        })
      }),
      portalStyle ? react_dom__WEBPACK_IMPORTED_MODULE_1__.createPortal(/* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: outerPortal,
        className: "css-reset",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(HigherZIndex, {
          onOutsideClick: onHide,
          onEscape: onHide,
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: portalStyle,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InfoTooltip, {
              backgroundColor: INPUT_BACKGROUND,
              arrowDirection: layout,
              children
            })
          })
        })
      }), getPortal(currentZIndex)) : null
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodFieldValidation.tsx

var legend = {
  display: "flex",
  flexDirection: "row",
  alignItems: "center"
};
var stackTrace = {
  padding: 10
};
var stackTraceLabel = {
  fontSize: 14
};
var ZodFieldValidation = ({ localValue, path }) => {
  const { zodValidation } = localValue;
  if (zodValidation.success) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: legend,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ValidationMessage, {
        align: "flex-start",
        message: zodValidation.error.format()._errors[0],
        type: "error"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 0.5
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InfoBubble, {
        title: "Zod validation failure",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
          style: stackTrace,
          children: [
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              style: stackTraceLabel,
              children: "Zod Validation has failed:"
            }),
            zodValidation.error.issues.map((error, index) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
              style: stackTraceLabel,
              children: [
                "Type: ",
                error.code,
                " ",
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("br", {}),
                "Message: ",
                error.message,
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("br", {}),
                "Path: ",
                path.join(".")
              ]
            }, index))
          ]
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 0.5
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodArrayEditor.tsx

var ZodArrayEditor = ({
  schema,
  jsonPath,
  setValue,
  defaultValue,
  value,
  onSave,
  showSaveButton,
  onRemove,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const { localValue, onChange, RevisionContextProvider, reset } = useLocalState({
    unsavedValue: value,
    schema,
    setValue,
    savedValue: defaultValue
  });
  const [expanded, setExpanded] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(true);
  const arrayElement = getArrayElement(schema);
  const suffix2 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return expanded ? " [" : " [...] ";
  }, [expanded]);
  const z = useZodIfPossible();
  if (!z) {
    throw new Error("expected zod");
  }
  const zodTypes = useZodTypesIfPossible();
  const isDefaultValue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return deepEqual(localValue.value, defaultValue);
  }, [defaultValue, localValue]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
    shouldPad: mayPad,
    success: localValue.zodValidation.success,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: {
          display: "flex",
          flexDirection: "row"
        },
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaLabel, {
          onReset: reset,
          isDefaultValue,
          jsonPath,
          onRemove,
          suffix: suffix2,
          onSave: () => {
            onSave(() => localValue.value, false, false);
          },
          saveDisabledByParent,
          saving,
          showSaveButton,
          valid: localValue.zodValidation.success,
          handleClick: () => setExpanded(!expanded)
        })
      }),
      expanded ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RevisionContextProvider, {
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(SchemaVerticalGuide, {
          isRoot: false,
          children: [
            localValue.value.map((child, i) => {
              return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodArrayItemEditor, {
                    onChange,
                    value: child,
                    elementSchema: arrayElement,
                    index: i,
                    jsonPath,
                    defaultValue: defaultValue?.[i] ?? createZodValues(arrayElement, z, zodTypes),
                    onSave,
                    showSaveButton,
                    saving,
                    saveDisabledByParent,
                    mayPad,
                    mayRemove: true
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaArrayItemSeparationLine, {
                    schema,
                    index: i,
                    onChange,
                    isLast: i === localValue.value.length - 1,
                    showAddButton: true
                  })
                ]
              }, `${i}${localValue.keyStabilityRevision}`);
            }),
            value.length === 0 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaArrayItemSeparationLine, {
              schema,
              index: 0,
              onChange,
              isLast: true,
              showAddButton: true
            }) : null
          ]
        })
      }) : null,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodFieldValidation, {
        path: jsonPath,
        localValue
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodBooleanEditor.tsx


// src/components/Checkbox.tsx


var size2 = 20;
var background = {
  height: size2,
  width: size2,
  position: "relative"
};
var bullet = {
  width: 10,
  height: 10,
  backgroundColor: LIGHT_TEXT,
  borderRadius: "50%"
};
var box = {
  display: "flex",
  justifyContent: "center",
  alignItems: "center",
  position: "absolute",
  height: size2,
  width: size2,
  top: 0,
  left: 0,
  pointerEvents: "none",
  color: "white"
};
var Checkbox = ({ checked, onChange, disabled, name, rounded }) => {
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const input2 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      appearance: "none",
      background: disabled ? "transparent" : INPUT_BACKGROUND,
      border: "1px solid " + INPUT_BORDER_COLOR_UNHOVERED,
      height: size2,
      width: size2,
      top: 0,
      left: 0,
      position: "absolute",
      margin: 0
    };
  }, [disabled]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (ref.current) {
      ref.current.style.setProperty("border-radius", rounded ? "50%" : "0%", "important");
    }
  }, [rounded]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: background,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("input", {
        ref,
        style: input2,
        type: "checkbox",
        checked,
        onChange,
        disabled,
        name
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: box,
        children: checked ? rounded ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: bullet
        }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodBooleanEditor.tsx

var fullWidth = {
  width: "100%"
};
var ZodBooleanEditor = ({
  schema,
  jsonPath,
  value,
  setValue,
  onSave,
  defaultValue,
  onRemove,
  showSaveButton,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const { localValue, onChange, reset } = useLocalState({
    schema,
    setValue,
    unsavedValue: value,
    savedValue: defaultValue
  });
  const onToggle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    onChange(() => e.target.checked, false, false);
  }, [onChange]);
  const save = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onSave(() => value, false, false);
  }, [onSave, value]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
    shouldPad: mayPad,
    success: localValue.zodValidation.success,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaLabel, {
        handleClick: null,
        isDefaultValue: localValue.value === defaultValue,
        jsonPath,
        onReset: reset,
        onSave: save,
        showSaveButton,
        onRemove,
        saving,
        valid: true,
        saveDisabledByParent,
        suffix: null
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: fullWidth,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
          name: jsonPath.join("."),
          checked: localValue.value,
          onChange: onToggle,
          disabled: false
        })
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodColorEditor.tsx


// src/helpers/color-math.ts
var colorWithNewOpacity = (color, opacity, zodTypes) => {
  const { r, g, b } = zodTypes.ZodZypesInternals.parseColor(color);
  if (opacity >= 255) {
    return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
  }
  return `rgba(${r}, ${g}, ${b}, ${(opacity / 255).toFixed(2)})`;
};

// src/components/NewComposition/InputDragger.tsx



var isInt = (num) => {
  return num % 1 === 0;
};
var InputDraggerForwardRefFn = ({
  onValueChange,
  onValueChangeEnd,
  min: _min,
  max: _max,
  step: _step,
  value,
  onTextChange,
  formatter = (q) => String(q),
  status,
  rightAlign,
  ...props
}, ref) => {
  const [inputFallback, setInputFallback] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const fallbackRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const style8 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...inputBaseStyle,
      backgroundColor: "transparent",
      borderColor: "transparent"
    };
  }, []);
  const span = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => ({
    borderBottom: "1px dotted " + BLUE,
    paddingBottom: 1,
    color: BLUE,
    cursor: "ew-resize",
    userSelect: "none",
    WebkitUserSelect: "none",
    fontSize: 13,
    fontVariantNumeric: "tabular-nums"
  }), []);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (!getClickLock()) {
      e.stopPropagation();
    }
    if (getClickLock()) {
      return;
    }
    setInputFallback(true);
  }, []);
  const onEscape = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setInputFallback(false);
  }, []);
  const onBlur = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (!fallbackRef.current) {
      return;
    }
    const newValue = fallbackRef.current.value;
    if (newValue.trim() === "") {
      onEscape();
      return;
    }
    if (fallbackRef.current.checkValidity()) {
      onTextChange?.(newValue);
      setInputFallback(false);
    } else {
      fallbackRef.current.reportValidity();
    }
  }, [onEscape, onTextChange]);
  const onKeyPress = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (e.key === "Enter") {
      fallbackRef.current?.blur();
    }
  }, []);
  const roundToStep = (val, stepSize) => {
    const factor = 1 / stepSize;
    return Math.ceil(val * factor) / factor;
  };
  const onPointerDown = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    const { pageX, pageY, button: button3 } = e;
    if (button3 !== 0) {
      return;
    }
    let lastDragValue = null;
    const moveListener = (ev) => {
      const xDistance = ev.pageX - pageX;
      const distanceFromStart = Math.sqrt(xDistance ** 2 + (ev.pageY - pageY) ** 2);
      const step = Number(_step ?? 1);
      const min = Number(_min ?? 0);
      const max = Number(_max ?? Infinity);
      if (distanceFromStart > 4) {
        setClickLock(true);
      }
      const diff = (0,remotion__WEBPACK_IMPORTED_MODULE_2__.interpolate)(xDistance, [-5, -4, 0, 4, 5], [-step, 0, 0, 0, step]);
      const newValue = Math.min(max, Math.max(min, Number(value) + diff));
      const roundedToStep = roundToStep(newValue, step);
      lastDragValue = roundedToStep;
      onValueChange(roundedToStep);
    };
    window.addEventListener("mousemove", moveListener);
    window.addEventListener("pointerup", () => {
      window.removeEventListener("mousemove", moveListener);
      if (lastDragValue !== null && onValueChangeEnd) {
        onValueChangeEnd(lastDragValue);
      }
      setTimeout(() => {
        setClickLock(false);
      }, 2);
    }, {
      once: true
    });
  }, [_step, _min, _max, value, onValueChange, onValueChangeEnd]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (inputFallback) {
      fallbackRef.current?.select();
    }
  }, [inputFallback]);
  const deriveStep = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (_step !== undefined) {
      return _step;
    }
    if (typeof _min === "number" && isInt(_min)) {
      return 1;
    }
    return 0.0001;
  }, [_min, _step]);
  if (inputFallback) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(HigherZIndex, {
      onEscape,
      onOutsideClick: noop,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
        ref: fallbackRef,
        autoFocus: true,
        onKeyPress,
        onBlur,
        min: _min,
        max: _max,
        step: deriveStep,
        defaultValue: value,
        status,
        pattern: "[0-9]*[.]?[0-9]*",
        rightAlign,
        ...props
      })
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
    ref,
    type: "button",
    style: style8,
    onClick,
    onPointerDown,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
      style: span,
      children: formatter(value)
    })
  });
};
var InputDragger = react__WEBPACK_IMPORTED_MODULE_0__.forwardRef(InputDraggerForwardRefFn);

// src/components/NewComposition/RemInputTypeColor.tsx


var inputBaseStyle3 = {
  padding: 0,
  borderStyle: "solid",
  borderWidth: 1
};
var RemInputTypeColorForwardRef = ({ status, ...props }, ref) => {
  const [isFocused, setIsFocused] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const [isHovered, setIsHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const inputRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const { tabIndex } = useZIndex();
  const style8 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      backgroundColor: INPUT_BACKGROUND,
      ...inputBaseStyle3,
      borderColor: getInputBorderColor({ isFocused, isHovered, status }),
      ...props.style ?? {}
    };
  }, [isFocused, isHovered, props.style, status]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(ref, () => {
    return inputRef.current;
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!inputRef.current) {
      return;
    }
    const { current } = inputRef;
    const onFocus = () => setIsFocused(true);
    const onBlur = () => setIsFocused(false);
    const onMouseEnter = () => setIsHovered(true);
    const onMouseLeave = () => setIsHovered(false);
    current.addEventListener("focus", onFocus);
    current.addEventListener("blur", onBlur);
    current.addEventListener("mouseenter", onMouseEnter);
    current.addEventListener("mouseleave", onMouseLeave);
    return () => {
      current.removeEventListener("focus", onFocus);
      current.removeEventListener("blur", onBlur);
      current.removeEventListener("mouseenter", onMouseEnter);
      current.removeEventListener("mouseleave", onMouseLeave);
    };
  }, [inputRef]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("input", {
    ref: inputRef,
    type: "color",
    tabIndex,
    ...props,
    name: props.name,
    style: style8
  });
};
var RemInputTypeColor = (0,react__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(RemInputTypeColorForwardRef);

// src/components/RenderModal/SchemaEditor/ZodColorEditor.tsx

var fullWidth2 = {
  width: "100%"
};
var ZodColorEditor = ({
  jsonPath,
  value,
  setValue,
  showSaveButton,
  defaultValue,
  schema,
  onSave,
  onRemove,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const z = useZodIfPossible();
  if (!z) {
    throw new Error("expected zod");
  }
  const zodTypes = useZodTypesIfPossible();
  if (!zodTypes) {
    throw new Error("expected zod color");
  }
  const {
    localValue,
    onChange: onValueChange,
    reset
  } = useLocalState({
    schema,
    setValue,
    unsavedValue: value,
    savedValue: defaultValue
  });
  const { a, b, g, r } = localValue.zodValidation.success ? zodTypes.ZodZypesInternals.parseColor(localValue.value) : { a: 1, b: 0, g: 0, r: 0 };
  const onChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    const newColor = colorWithNewOpacity(e.target.value, Math.round(a), zodTypes);
    onValueChange(() => newColor, false, false);
  }, [a, onValueChange, zodTypes]);
  const onTextChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    const newValue = e.target.value;
    onValueChange(() => newValue, false, false);
  }, [onValueChange]);
  const save = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onSave(() => value, false, false);
  }, [onSave, value]);
  const rgb = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
  const status = localValue.zodValidation.success ? "ok" : "error";
  const colorPicker = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      height: 39,
      width: 45,
      display: "inline-block"
    };
  }, []);
  const onOpacityChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newValue) => {
    const newColor = colorWithNewOpacity(localValue.value, Math.round(Number(newValue) / 100 * 255), zodTypes);
    onValueChange(() => newColor, false, false);
  }, [localValue.value, onValueChange, zodTypes]);
  const onOpacityValueChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newValue) => {
    const newColor = colorWithNewOpacity(localValue.value, Math.round(Number(newValue) / 100 * 255), zodTypes);
    onValueChange(() => newColor, false, false);
  }, [localValue.value, onValueChange, zodTypes]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
    shouldPad: mayPad,
    success: localValue.zodValidation.success,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaLabel, {
        handleClick: null,
        isDefaultValue: localValue.value === defaultValue,
        jsonPath,
        onReset: reset,
        onSave: save,
        showSaveButton,
        onRemove,
        saving,
        valid: localValue.zodValidation.success,
        saveDisabledByParent,
        suffix: null
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: fullWidth2,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
            align: "center",
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: colorPicker,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemInputTypeColor, {
                  type: "color",
                  style: {
                    height: 39
                  },
                  value: rgb,
                  onChange,
                  className: "__remotion_color_picker",
                  status,
                  name: jsonPath.join(".")
                })
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 1,
                block: true
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
                value: localValue.value,
                status,
                placeholder: jsonPath.join("."),
                onChange: onTextChange,
                rightAlign: false
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 1
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InputDragger, {
                onTextChange: onOpacityChange,
                onValueChange: onOpacityValueChange,
                status,
                value: a / 255 * 100,
                min: 0,
                max: 100,
                step: 1,
                formatter: (v) => `${Math.round(Number(v))}%`,
                rightAlign: false
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodFieldValidation, {
            path: jsonPath,
            localValue
          })
        ]
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodDateEditor.tsx


var fullWidth3 = {
  width: "100%"
};
var explainer2 = {
  fontFamily: "sans-serif",
  fontSize: 12,
  color: VERY_LIGHT_TEXT
};
var inputStyle = {
  colorScheme: "dark"
};
var formatDate = (date) => {
  const year = date.getFullYear();
  const month = date.getMonth() + 1;
  const day = date.getDate();
  const hours = date.getHours();
  const minutes = date.getMinutes();
  const seconds = date.getSeconds();
  const milliseconds = date.getMilliseconds();
  const formattedDate = `${year}-${month.toString().padStart(2, "0")}-${day.toString().padStart(2, "0")}T${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}.${milliseconds.toString().padStart(3, "0")}`;
  return formattedDate;
};
var ZodDateEditor = ({
  jsonPath,
  value,
  setValue,
  showSaveButton,
  defaultValue,
  schema,
  onSave,
  onRemove,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const {
    localValue,
    onChange: setLocalValue,
    reset
  } = useLocalState({
    schema,
    setValue,
    unsavedValue: value,
    savedValue: defaultValue
  });
  const onChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setLocalValue(() => new Date(e.target.value), false, false);
  }, [setLocalValue]);
  const save = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onSave(() => value, false, false);
  }, [onSave, value]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
    shouldPad: mayPad,
    success: localValue.zodValidation.success,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaLabel, {
        handleClick: null,
        isDefaultValue: localValue.value.getTime() === defaultValue.getTime(),
        jsonPath,
        onReset: reset,
        onSave: save,
        showSaveButton,
        onRemove,
        saving,
        valid: localValue.zodValidation.success,
        saveDisabledByParent,
        suffix: null
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: fullWidth3,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
            value: formatDate(localValue.value),
            type: "datetime-local",
            status: localValue.zodValidation.success ? "ok" : "error",
            placeholder: jsonPath.join("."),
            onChange,
            style: inputStyle,
            rightAlign: false
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            y: 1,
            block: true
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: explainer2,
            children: "Date is in local format"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodFieldValidation, {
            path: jsonPath,
            localValue
          })
        ]
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodDefaultEditor.tsx

var ZodDefaultEditor = ({
  jsonPath,
  schema,
  setValue,
  onSave,
  defaultValue,
  value,
  showSaveButton,
  onRemove,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const innerType = getInnerType(schema);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodSwitch, {
    defaultValue,
    jsonPath,
    onRemove,
    onSave,
    schema: innerType,
    setValue,
    showSaveButton,
    value,
    saving,
    saveDisabledByParent,
    mayPad
  });
};

// src/components/RenderModal/SchemaEditor/ZodDiscriminatedUnionEditor.tsx


var ZodDiscriminatedUnionEditor = ({
  schema,
  setValue,
  showSaveButton,
  saving,
  value,
  defaultValue,
  saveDisabledByParent,
  onSave,
  mayPad,
  jsonPath,
  onRemove
}) => {
  const z = useZodIfPossible();
  if (!z) {
    throw new Error("expected zod");
  }
  const zodTypes = useZodTypesIfPossible();
  const discriminator = getDiscriminator(schema);
  const options = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => getDiscriminatedOptionKeys(schema), [schema]);
  const {
    localValue,
    onChange: setLocalValue,
    reset
  } = useLocalState({
    schema,
    setValue,
    unsavedValue: value,
    savedValue: defaultValue
  });
  const comboBoxValues = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return options.map((option) => {
      return {
        value: option,
        label: option,
        id: option,
        keyHint: null,
        leftItem: option === value[discriminator] ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        onClick: () => {
          const optionSchema = getDiscriminatedOption(schema, option);
          if (!optionSchema) {
            throw new Error(`No schema found for discriminator value: ${option}`);
          }
          const val = createZodValues(optionSchema, z, zodTypes);
          setLocalValue(() => val, false, false);
        },
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item"
      };
    });
  }, [options, setLocalValue, discriminator, schema, value, z, zodTypes]);
  const save = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onSave(() => value, false, false);
  }, [onSave, value]);
  const discriminatedUnionReplacement = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      discriminator,
      markup: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
        shouldPad: mayPad,
        success: true,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaLabel, {
            handleClick: null,
            isDefaultValue: localValue.value[discriminator] === defaultValue[discriminator],
            jsonPath: [...jsonPath, discriminator],
            onRemove,
            onReset: reset,
            onSave: save,
            saveDisabledByParent,
            saving,
            showSaveButton,
            suffix: null,
            valid: localValue.zodValidation.success
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
            title: "Select type",
            values: comboBoxValues,
            selectedId: value[discriminator]
          })
        ]
      }, "replacement")
    };
  }, [
    comboBoxValues,
    defaultValue,
    jsonPath,
    localValue.value,
    localValue.zodValidation.success,
    mayPad,
    onRemove,
    reset,
    save,
    saveDisabledByParent,
    saving,
    showSaveButton,
    discriminator,
    value
  ]);
  const currentOptionSchema = getDiscriminatedOption(schema, value[discriminator]);
  if (!currentOptionSchema) {
    throw new Error("No matching option found for discriminated union");
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodObjectEditor, {
    jsonPath,
    mayPad,
    savedValue: defaultValue,
    onRemove,
    onSave,
    saveDisabledByParent,
    saving,
    schema: currentOptionSchema,
    setValue: setLocalValue,
    showSaveButton,
    unsavedValue: value,
    discriminatedUnionReplacement
  }, value[discriminator]);
};

// src/components/RenderModal/SchemaEditor/ZodEffectEditor.tsx

var fullWidth4 = {
  width: "100%"
};
var ZodEffectEditor = ({
  schema,
  jsonPath,
  value,
  setValue: updateValue,
  defaultValue,
  onSave,
  onRemove,
  showSaveButton,
  saving,
  mayPad
}) => {
  const typeName = getZodSchemaType(schema);
  if (typeName !== "effects") {
    throw new Error("expected effect");
  }
  const { localValue, onChange } = useLocalState({
    unsavedValue: value,
    schema,
    setValue: updateValue,
    savedValue: defaultValue
  });
  const innerSchema = getEffectsInner(schema);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
    shouldPad: mayPad,
    success: localValue.zodValidation.success,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: fullWidth4,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodSwitch, {
          value,
          setValue: onChange,
          jsonPath,
          schema: innerSchema,
          defaultValue,
          onSave,
          showSaveButton,
          onRemove,
          saving,
          saveDisabledByParent: !localValue.zodValidation.success,
          mayPad: false
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodFieldValidation, {
        path: jsonPath,
        localValue
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodEnumEditor.tsx


var container29 = {
  width: "100%"
};
var ZodEnumEditor = ({
  schema,
  jsonPath,
  setValue,
  defaultValue,
  value,
  onSave,
  showSaveButton,
  onRemove,
  saving
}) => {
  const {
    localValue,
    onChange: setLocalValue,
    reset
  } = useLocalState({
    schema,
    setValue,
    unsavedValue: value,
    savedValue: defaultValue
  });
  const enumValues = getEnumValues(schema);
  const isRoot = jsonPath.length === 0;
  const comboBoxValues = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return enumValues.map((option) => {
      return {
        value: option,
        label: option,
        id: option,
        keyHint: null,
        leftItem: option === value ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        onClick: (id) => {
          setLocalValue(() => id, false, false);
        },
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item"
      };
    });
  }, [enumValues, setLocalValue, value]);
  const save = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onSave(() => value, false, false);
  }, [onSave, value]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
    shouldPad: true,
    success: localValue.zodValidation.success,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaLabel, {
        handleClick: null,
        onSave: save,
        showSaveButton,
        isDefaultValue: localValue.value === defaultValue,
        onReset: reset,
        jsonPath,
        onRemove,
        saving,
        valid: localValue.zodValidation.success,
        saveDisabledByParent: !localValue.zodValidation.success,
        suffix: null
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: isRoot ? undefined : container29,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
          values: comboBoxValues,
          selectedId: value,
          title: value
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodFieldValidation, {
        path: jsonPath,
        localValue
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodMatrixEditor.tsx


var rowStyle = {
  display: "flex",
  flexDirection: "row",
  width: "100%"
};
var ZodMatrixEditor = ({
  schema,
  jsonPath,
  setValue,
  defaultValue,
  value,
  onSave,
  showSaveButton,
  onRemove,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const { localValue, onChange, RevisionContextProvider, reset } = useLocalState({
    unsavedValue: value,
    schema,
    setValue,
    savedValue: defaultValue
  });
  const [expanded, setExpanded] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(true);
  const arrayElement = getArrayElement(schema);
  const suffix2 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return expanded ? " [" : " [...] ";
  }, [expanded]);
  const z = useZodIfPossible();
  if (!z) {
    throw new Error("expected zod");
  }
  const zodTypes = useZodTypesIfPossible();
  const isDefaultValue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return deepEqual(localValue.value, defaultValue);
  }, [defaultValue, localValue]);
  const dimensions = Math.sqrt(localValue.value.length);
  if (!Number.isInteger(dimensions)) {
    throw new Error("Invalid matrix");
  }
  const chunkedItems = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return localValue.value.reduce((acc, item2, index) => {
      const chunkIndex = Math.floor(index / dimensions);
      acc[chunkIndex] = acc[chunkIndex] || [];
      acc[chunkIndex].push(item2);
      return acc;
    }, []);
  }, [localValue.value, dimensions]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
    shouldPad: mayPad,
    success: localValue.zodValidation.success,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaLabel, {
        onReset: reset,
        isDefaultValue,
        jsonPath,
        onRemove,
        suffix: suffix2,
        onSave: () => {
          onSave(() => localValue.value, false, false);
        },
        saveDisabledByParent,
        saving,
        showSaveButton,
        valid: localValue.zodValidation.success,
        handleClick: () => setExpanded(!expanded)
      }),
      expanded ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RevisionContextProvider, {
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(SchemaVerticalGuide, {
          isRoot: false,
          children: [
            chunkedItems.map((row4, rowIndex) => {
              return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                  style: rowStyle,
                  children: row4.map((item2, _index) => {
                    const actualIndex = rowIndex * dimensions + _index;
                    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                      style: { flex: 1 },
                      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodArrayItemEditor, {
                        onChange,
                        value: item2,
                        elementSchema: arrayElement,
                        index: actualIndex,
                        jsonPath,
                        defaultValue: defaultValue?.[actualIndex] ?? createZodValues(arrayElement, z, zodTypes),
                        onSave,
                        showSaveButton,
                        saving,
                        saveDisabledByParent,
                        mayPad,
                        mayRemove: false
                      })
                    }, `${_index}${localValue.keyStabilityRevision}`);
                  })
                })
              }, `${rowIndex}${localValue.keyStabilityRevision}`);
            }),
            value.length === 0 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaArrayItemSeparationLine, {
              schema,
              index: 0,
              onChange,
              isLast: true,
              showAddButton: true
            }) : null
          ]
        })
      }) : null,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodFieldValidation, {
        path: jsonPath,
        localValue
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodNonEditableValue.tsx


var fullWidth5 = {
  width: "100%"
};
var emptyLabel = {
  width: "100%",
  color: VERY_LIGHT_TEXT,
  fontFamily: "sans-serif",
  fontSize: 14
};
var wideEmptyLabel = {
  ...emptyLabel,
  lineHeight: "37px"
};
var ZonNonEditableValue = ({ jsonPath, label: label6, showSaveButton, saving, mayPad }) => {
  const save = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    return;
  }, []);
  const reset = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    return;
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
    shouldPad: mayPad,
    success: true,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaLabel, {
        handleClick: null,
        isDefaultValue: true,
        jsonPath,
        onReset: reset,
        onSave: save,
        showSaveButton,
        onRemove: null,
        saving,
        valid: true,
        saveDisabledByParent: true,
        suffix: null
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: fullWidth5,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("em", {
          style: wideEmptyLabel,
          children: label6
        })
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodOrNullishEditor.tsx


var labelStyle4 = {
  fontFamily: "sans-serif",
  fontSize: 14,
  color: LIGHT_TEXT
};
var checkBoxWrapper = {
  display: "flex",
  flexDirection: "row",
  alignItems: "center",
  marginTop: "5px"
};
var ZodOrNullishEditor = ({
  jsonPath,
  schema,
  setValue,
  onSave,
  defaultValue,
  value,
  showSaveButton,
  onRemove,
  nullishValue,
  saving,
  saveDisabledByParent,
  mayPad,
  innerSchema
}) => {
  const z = useZodIfPossible();
  if (!z) {
    throw new Error("expected zod");
  }
  const zodTypes = useZodTypesIfPossible();
  const isChecked = value === nullishValue;
  const {
    localValue,
    onChange: setLocalValue,
    reset
  } = useLocalState({
    schema,
    setValue,
    unsavedValue: value,
    savedValue: defaultValue
  });
  const onCheckBoxChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    const val = e.target.checked ? nullishValue : createZodValues(innerSchema, z, zodTypes);
    setLocalValue(() => val, false, false);
  }, [innerSchema, nullishValue, setLocalValue, z, zodTypes]);
  const save = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onSave(() => value, false, false);
  }, [onSave, value]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
    shouldPad: mayPad,
    success: localValue.zodValidation.success,
    children: [
      localValue.value === nullishValue ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaLabel, {
        handleClick: null,
        isDefaultValue: localValue.value === defaultValue,
        jsonPath,
        onReset: reset,
        onSave: save,
        showSaveButton,
        onRemove,
        saving,
        valid: localValue.zodValidation.success,
        saveDisabledByParent,
        suffix: null
      }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodSwitch, {
        value: localValue.value,
        setValue: setLocalValue,
        jsonPath,
        schema: innerSchema,
        defaultValue,
        onSave,
        showSaveButton,
        onRemove,
        saving,
        saveDisabledByParent,
        mayPad: false
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: checkBoxWrapper,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
            checked: isChecked,
            onChange: onCheckBoxChange,
            disabled: false,
            name: jsonPath.join(".")
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 1
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: labelStyle4,
            children: String(nullishValue)
          })
        ]
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodNullableEditor.tsx

var ZodNullableEditor = ({
  jsonPath,
  schema,
  setValue,
  onSave,
  defaultValue,
  value,
  showSaveButton,
  onRemove,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const innerType = getInnerType(schema);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodOrNullishEditor, {
    defaultValue,
    jsonPath,
    onRemove,
    onSave,
    schema,
    innerSchema: innerType,
    setValue,
    showSaveButton,
    value,
    nullishValue: null,
    saving,
    saveDisabledByParent,
    mayPad
  });
};

// src/components/RenderModal/SchemaEditor/ZodNumberEditor.tsx


// src/components/RenderModal/SchemaEditor/zod-number-constraints.ts
var getZodNumberMinimum = (schema) => {
  const { checks } = getZodDef(schema);
  if (!checks)
    return -Infinity;
  if (isZodV3Schema(schema)) {
    const minCheck = checks.find((c) => c.kind === "min");
    if (!minCheck || !minCheck.inclusive)
      return -Infinity;
    return minCheck.value;
  }
  for (const c of checks) {
    const def = c._zod?.def;
    if (def?.check === "greater_than" && def.inclusive) {
      return def.value;
    }
  }
  return -Infinity;
};
var getZodNumberMaximum = (schema) => {
  const { checks } = getZodDef(schema);
  if (!checks)
    return Infinity;
  if (isZodV3Schema(schema)) {
    const maxCheck = checks.find((c) => c.kind === "max");
    if (!maxCheck || !maxCheck.inclusive)
      return Infinity;
    return maxCheck.value;
  }
  for (const c of checks) {
    const def = c._zod?.def;
    if (def?.check === "less_than" && def.inclusive) {
      return def.value;
    }
  }
  return Infinity;
};
var getZodNumberStep = (schema) => {
  const { checks } = getZodDef(schema);
  if (!checks)
    return;
  if (isZodV3Schema(schema)) {
    const multipleStep = checks.find((c) => c.kind === "multipleOf");
    if (!multipleStep)
      return;
    return multipleStep.value;
  }
  for (const c of checks) {
    const def = c._zod?.def;
    if (def?.check === "multiple_of") {
      return def.value;
    }
  }
  return;
};

// src/components/RenderModal/SchemaEditor/ZodNumberEditor.tsx

var fullWidth6 = {
  width: "100%"
};
var ZodNumberEditor = ({
  jsonPath,
  value,
  schema,
  setValue,
  onSave,
  defaultValue,
  onRemove,
  showSaveButton,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const {
    localValue,
    onChange: setLocalValue,
    reset
  } = useLocalState({
    unsavedValue: value,
    schema,
    setValue,
    savedValue: defaultValue
  });
  const onNumberChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newValue) => {
    setLocalValue(() => newValue, false, false);
  }, [setLocalValue]);
  const isDefault = localValue.value === defaultValue;
  const onTextChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newValue) => {
    setLocalValue(() => Number(newValue), false, false);
  }, [setLocalValue]);
  const save = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onSave(() => value, false, false);
  }, [onSave, value]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
    shouldPad: mayPad,
    success: localValue.zodValidation.success,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaLabel, {
        handleClick: null,
        isDefaultValue: isDefault,
        jsonPath,
        onReset: reset,
        onSave: save,
        showSaveButton,
        onRemove,
        saving,
        valid: localValue.zodValidation.success,
        saveDisabledByParent,
        suffix: null
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: fullWidth6,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InputDragger, {
            type: "number",
            value: localValue.value,
            style: fullWidth6,
            status: localValue.zodValidation.success ? "ok" : "error",
            placeholder: jsonPath.join("."),
            onTextChange,
            onValueChange: onNumberChange,
            min: getZodNumberMinimum(schema),
            max: getZodNumberMaximum(schema),
            step: getZodNumberStep(schema),
            rightAlign: false
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodFieldValidation, {
            path: jsonPath,
            localValue
          })
        ]
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodOptionalEditor.tsx

var ZodOptionalEditor = ({
  jsonPath,
  schema,
  setValue,
  onSave,
  defaultValue,
  value,
  showSaveButton,
  onRemove,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const innerType = getInnerType(schema);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodOrNullishEditor, {
    defaultValue,
    jsonPath,
    onRemove,
    onSave,
    schema,
    setValue,
    showSaveButton,
    value,
    nullishValue: undefined,
    saving,
    saveDisabledByParent,
    mayPad,
    innerSchema: innerType
  });
};

// src/components/RenderModal/SchemaEditor/ZodStaticFileEditor.tsx


var container30 = {
  width: "100%"
};
var ZodStaticFileEditor = ({
  schema,
  jsonPath,
  setValue,
  defaultValue,
  value,
  onSave,
  showSaveButton,
  onRemove,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const {
    localValue,
    onChange: setLocalValue,
    reset
  } = useLocalState({
    schema,
    setValue,
    unsavedValue: value,
    savedValue: defaultValue
  });
  const isRoot = jsonPath.length === 0;
  const staticFiles = useStaticFiles();
  const comboBoxValues = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return staticFiles.map((option) => {
      return {
        value: option.src,
        label: option.name,
        id: option.src,
        keyHint: null,
        leftItem: option.src === value ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        onClick: (id) => {
          setLocalValue(() => id, false, false);
        },
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item"
      };
    });
  }, [setLocalValue, staticFiles, value]);
  const save = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onSave(() => value);
  }, [onSave, value]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
    shouldPad: mayPad,
    success: localValue.zodValidation.success,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaLabel, {
        handleClick: null,
        onSave: save,
        showSaveButton,
        isDefaultValue: localValue.value === defaultValue,
        onReset: reset,
        jsonPath,
        onRemove,
        saving,
        valid: localValue.zodValidation.success,
        saveDisabledByParent,
        suffix: null
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: isRoot ? undefined : container30,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
          values: comboBoxValues,
          selectedId: localValue.value,
          title: value
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodFieldValidation, {
        path: jsonPath,
        localValue
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodStringEditor.tsx


var fullWidth7 = {
  width: "100%"
};
var ZodStringEditor = ({
  jsonPath,
  value,
  setValue,
  showSaveButton,
  defaultValue,
  schema,
  onSave,
  onRemove,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const z = useZodIfPossible();
  if (!z) {
    throw new Error("expected zod");
  }
  const {
    localValue,
    onChange: setLocalValue,
    reset
  } = useLocalState({
    schema,
    setValue,
    unsavedValue: value,
    savedValue: defaultValue
  });
  const onChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setLocalValue(() => e.target.value, false, false);
  }, [setLocalValue]);
  const save = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onSave(() => value, false, false);
  }, [onSave, value]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
    shouldPad: mayPad,
    success: false,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaLabel, {
        handleClick: null,
        isDefaultValue: localValue.value === defaultValue,
        jsonPath,
        onReset: reset,
        onSave: save,
        showSaveButton,
        onRemove,
        saving,
        valid: localValue.zodValidation.success,
        saveDisabledByParent,
        suffix: null
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: fullWidth7,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
            value: localValue.value,
            status: localValue.zodValidation ? "ok" : "error",
            placeholder: jsonPath.join("."),
            onChange,
            rightAlign: false,
            name: jsonPath.join(".")
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodFieldValidation, {
            path: jsonPath,
            localValue
          })
        ]
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodTextareaEditor.tsx


var fullWidth8 = {
  width: "100%"
};
var textareaStyle = {
  resize: "vertical",
  minHeight: 100
};
var ZodTextareaEditor = ({
  jsonPath,
  value,
  setValue,
  showSaveButton,
  defaultValue,
  schema,
  onSave,
  onRemove,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const z = useZodIfPossible();
  if (!z) {
    throw new Error("expected zod");
  }
  const zodTypes = useZodTypesIfPossible();
  if (!zodTypes) {
    throw new Error("expected zod textarea");
  }
  const {
    localValue,
    onChange: setLocalValue,
    reset
  } = useLocalState({
    schema,
    setValue,
    unsavedValue: value,
    savedValue: defaultValue
  });
  const onChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setLocalValue(() => e.target.value, false, false);
  }, [setLocalValue]);
  const save = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onSave(() => value, false, false);
  }, [onSave, value]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
    shouldPad: mayPad,
    success: localValue.zodValidation.success,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaLabel, {
        handleClick: null,
        isDefaultValue: localValue.value === defaultValue,
        jsonPath,
        onReset: reset,
        onSave: save,
        showSaveButton,
        onRemove,
        saving,
        valid: localValue.zodValidation.success,
        saveDisabledByParent,
        suffix: null
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: fullWidth8,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemTextarea, {
            onChange,
            value: localValue.value,
            status: localValue.zodValidation ? "ok" : "error",
            placeholder: jsonPath.join("."),
            name: jsonPath.join("."),
            style: textareaStyle
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodFieldValidation, {
            path: jsonPath,
            localValue
          })
        ]
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodTupleEditor.tsx


// src/components/RenderModal/SchemaEditor/ZodTupleItemEditor.tsx


var ZodTupleItemEditor = ({
  tupleItems,
  onChange,
  jsonPath,
  index,
  value,
  defaultValue,
  onSave: onSaveObject,
  showSaveButton,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const z = useZodIfPossible();
  if (!z) {
    throw new Error("expected zod");
  }
  const setValue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((val) => {
    onChange((oldV) => [
      ...oldV.slice(0, index),
      typeof val === "function" ? val(oldV[index]) : val,
      ...oldV.slice(index + 1)
    ], false, false);
  }, [index, onChange]);
  const newJsonPath = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => [...jsonPath, index], [index, jsonPath]);
  const onSave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((updater) => {
    onSaveObject((oldV) => [
      ...oldV.slice(0, index),
      updater(oldV[index]),
      ...oldV.slice(index + 1)
    ], false, false);
  }, [index, onSaveObject]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodSwitch, {
      jsonPath: newJsonPath,
      schema: tupleItems[index],
      value,
      setValue,
      defaultValue,
      onSave,
      showSaveButton,
      onRemove: null,
      saving,
      saveDisabledByParent,
      mayPad
    })
  });
};

// src/components/RenderModal/SchemaEditor/ZodTupleEditor.tsx

var ZodTupleEditor = ({
  schema,
  jsonPath,
  setValue,
  defaultValue,
  value,
  onSave,
  showSaveButton,
  onRemove,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const { localValue, onChange, RevisionContextProvider, reset } = useLocalState({
    unsavedValue: value,
    schema,
    setValue,
    savedValue: defaultValue
  });
  const [expanded, setExpanded] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(true);
  const tupleItems = getTupleItems(schema);
  const suffix2 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return expanded ? " [" : " [...] ";
  }, [expanded]);
  const z = useZodIfPossible();
  if (!z) {
    throw new Error("expected zod");
  }
  const zodTypes = useZodTypesIfPossible();
  const isDefaultValue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return deepEqual(localValue.value, defaultValue);
  }, [defaultValue, localValue]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
    shouldPad: mayPad,
    success: localValue.zodValidation.success,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: {
          display: "flex",
          flexDirection: "row"
        },
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaLabel, {
          onReset: reset,
          isDefaultValue,
          jsonPath,
          onRemove,
          suffix: suffix2,
          onSave: () => {
            onSave(() => localValue.value, false, false);
          },
          saveDisabledByParent,
          saving,
          showSaveButton,
          valid: localValue.zodValidation.success,
          handleClick: () => setExpanded(!expanded)
        })
      }),
      expanded ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RevisionContextProvider, {
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(SchemaVerticalGuide, {
          isRoot: false,
          children: [
            localValue.value.map((child, i) => {
              return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodTupleItemEditor, {
                    onChange,
                    value: child,
                    tupleItems,
                    index: i,
                    jsonPath,
                    defaultValue: defaultValue?.[i] ?? createZodValues(tupleItems[i], z, zodTypes),
                    onSave,
                    showSaveButton,
                    saving,
                    saveDisabledByParent,
                    mayPad
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaArrayItemSeparationLine, {
                    schema,
                    index: i,
                    onChange,
                    isLast: i === localValue.value.length - 1,
                    showAddButton: false
                  })
                ]
              }, `${i}${localValue.keyStabilityRevision}`);
            }),
            value.length === 0 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaArrayItemSeparationLine, {
              schema,
              index: 0,
              onChange,
              isLast: true,
              showAddButton: false
            }) : null
          ]
        })
      }) : null,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodFieldValidation, {
        path: jsonPath,
        localValue
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/ZodUnionEditor.tsx

var findNull = (value) => {
  const nullIndex = value.findIndex((v) => {
    const type = getZodSchemaType(v);
    return type === "null" || type === "undefined";
  });
  if (nullIndex === -1) {
    return null;
  }
  const nullishValue = getZodSchemaType(value[nullIndex]) === "null" ? null : undefined;
  const otherSchema = value[nullIndex === 0 ? 1 : 0];
  const otherType = getZodSchemaType(otherSchema);
  const otherSchemaIsAlsoNullish = otherType === "null" || otherType === "undefined";
  return {
    nullIndex,
    nullishValue,
    otherSchema,
    otherSchemaIsAlsoNullish
  };
};
var ZodUnionEditor = ({
  jsonPath,
  schema,
  setValue,
  onSave,
  defaultValue,
  value,
  showSaveButton,
  onRemove,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const options = getUnionOptions(schema);
  if (options.length > 2) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZonNonEditableValue, {
      jsonPath,
      label: "Union with more than 2 options not editable",
      showSaveButton,
      saving,
      mayPad
    });
  }
  if (options.length < 2) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZonNonEditableValue, {
      jsonPath,
      label: "Union with less than 2 options not editable",
      showSaveButton,
      saving,
      mayPad
    });
  }
  const nullResult = findNull(options);
  if (!nullResult) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZonNonEditableValue, {
      jsonPath,
      label: "Union only editable with 1 value being null",
      showSaveButton,
      saving,
      mayPad
    });
  }
  const { otherSchema, nullishValue, otherSchemaIsAlsoNullish } = nullResult;
  if (otherSchemaIsAlsoNullish) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZonNonEditableValue, {
      jsonPath,
      label: "Not editable - both union values are nullish",
      showSaveButton,
      saving,
      mayPad
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodOrNullishEditor, {
    defaultValue,
    jsonPath,
    onRemove,
    onSave,
    schema,
    innerSchema: otherSchema,
    setValue,
    showSaveButton,
    value,
    nullishValue,
    saving,
    saveDisabledByParent,
    mayPad
  });
};

// src/components/RenderModal/SchemaEditor/ZodSwitch.tsx

var ZodSwitch = ({
  schema,
  jsonPath,
  value,
  setValue,
  defaultValue,
  onSave,
  showSaveButton,
  onRemove,
  saving,
  saveDisabledByParent,
  mayPad
}) => {
  const typeName = getZodSchemaType(schema);
  const description = getZodSchemaDescription(schema);
  const zodTypes = useZodTypesIfPossible();
  if (typeName === "object") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodObjectEditor, {
      setValue,
      unsavedValue: value,
      savedValue: defaultValue,
      jsonPath,
      schema,
      onSave,
      showSaveButton,
      onRemove,
      saving,
      saveDisabledByParent,
      mayPad,
      discriminatedUnionReplacement: null
    });
  }
  if (typeName === "string") {
    if (zodTypes && description === zodTypes.ZodZypesInternals.REMOTION_COLOR_BRAND) {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodColorEditor, {
        value,
        setValue,
        jsonPath,
        schema,
        onSave,
        defaultValue,
        showSaveButton,
        onRemove,
        saving,
        saveDisabledByParent,
        mayPad
      });
    }
    if (value.startsWith(window.remotion_staticBase)) {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodStaticFileEditor, {
        setValue,
        value,
        jsonPath,
        schema,
        defaultValue,
        onSave,
        showSaveButton,
        onRemove,
        saving,
        saveDisabledByParent,
        mayPad
      });
    }
    if (zodTypes && description === zodTypes.ZodZypesInternals.REMOTION_TEXTAREA_BRAND) {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodTextareaEditor, {
        value,
        setValue,
        jsonPath,
        schema,
        onSave,
        defaultValue,
        showSaveButton,
        onRemove,
        saving,
        saveDisabledByParent,
        mayPad
      });
    }
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodStringEditor, {
      value,
      setValue,
      jsonPath,
      schema,
      onSave,
      defaultValue,
      showSaveButton,
      onRemove,
      saving,
      saveDisabledByParent,
      mayPad
    });
  }
  if (typeName === "date") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodDateEditor, {
      value,
      setValue,
      jsonPath,
      schema,
      onSave,
      defaultValue,
      showSaveButton,
      onRemove,
      saving,
      saveDisabledByParent,
      mayPad
    });
  }
  if (typeName === "number") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodNumberEditor, {
      value,
      setValue,
      jsonPath,
      schema,
      defaultValue,
      onSave,
      showSaveButton,
      onRemove,
      saving,
      saveDisabledByParent,
      mayPad
    });
  }
  if (typeName === "boolean") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodBooleanEditor, {
      value,
      setValue,
      jsonPath,
      defaultValue,
      onSave,
      showSaveButton,
      onRemove,
      saving,
      saveDisabledByParent,
      mayPad,
      schema
    });
  }
  if (typeName === "undefined") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZonNonEditableValue, {
      jsonPath,
      showSaveButton,
      label: "undefined",
      saving,
      mayPad
    });
  }
  if (typeName === "null") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZonNonEditableValue, {
      jsonPath,
      showSaveButton,
      label: "null",
      saving,
      mayPad
    });
  }
  if (typeName === "any") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZonNonEditableValue, {
      jsonPath,
      showSaveButton,
      label: "any (not editable)",
      saving,
      mayPad
    });
  }
  if (typeName === "bigint") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZonNonEditableValue, {
      jsonPath,
      showSaveButton,
      label: "BigInt (not editable)",
      saving,
      mayPad
    });
  }
  if (typeName === "unknown") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZonNonEditableValue, {
      jsonPath,
      showSaveButton,
      label: "unknown (not editable)",
      saving,
      mayPad
    });
  }
  if (typeName === "array") {
    if (zodTypes && description === zodTypes.ZodZypesInternals.REMOTION_MATRIX_BRAND) {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodMatrixEditor, {
        setValue,
        value,
        jsonPath,
        schema,
        defaultValue,
        onSave,
        showSaveButton,
        onRemove,
        saving,
        saveDisabledByParent,
        mayPad
      });
    }
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodArrayEditor, {
      setValue,
      value,
      jsonPath,
      schema,
      defaultValue,
      onSave,
      showSaveButton,
      onRemove,
      saving,
      saveDisabledByParent,
      mayPad
    });
  }
  if (typeName === "enum") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodEnumEditor, {
      setValue,
      value,
      jsonPath,
      schema,
      defaultValue,
      onSave,
      showSaveButton,
      onRemove,
      saving
    });
  }
  if (typeName === "effects") {
    if (zodTypes && description === zodTypes.ZodZypesInternals.REMOTION_COLOR_BRAND) {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodColorEditor, {
        value,
        setValue,
        jsonPath,
        schema,
        onSave,
        defaultValue,
        showSaveButton,
        onRemove,
        saving,
        saveDisabledByParent,
        mayPad
      });
    }
    if (zodTypes && description === zodTypes.ZodZypesInternals.REMOTION_MATRIX_BRAND) {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodMatrixEditor, {
        setValue,
        value,
        jsonPath,
        schema: getEffectsInner(schema),
        defaultValue,
        onSave,
        showSaveButton,
        onRemove,
        saving,
        saveDisabledByParent,
        mayPad
      });
    }
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodEffectEditor, {
      value,
      setValue,
      jsonPath,
      schema,
      defaultValue,
      onSave,
      showSaveButton,
      onRemove,
      saving,
      mayPad
    });
  }
  if (typeName === "union") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodUnionEditor, {
      schema,
      showSaveButton,
      jsonPath,
      value,
      defaultValue,
      setValue,
      onSave,
      onRemove,
      saving,
      saveDisabledByParent,
      mayPad
    });
  }
  if (typeName === "optional") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodOptionalEditor, {
      jsonPath,
      showSaveButton,
      defaultValue,
      value,
      setValue,
      onSave,
      onRemove,
      schema,
      saving,
      saveDisabledByParent,
      mayPad
    });
  }
  if (typeName === "nullable") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodNullableEditor, {
      jsonPath,
      showSaveButton,
      defaultValue,
      value,
      setValue,
      onSave,
      onRemove,
      schema,
      saving,
      saveDisabledByParent,
      mayPad
    });
  }
  if (typeName === "default") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodDefaultEditor, {
      jsonPath,
      showSaveButton,
      defaultValue,
      value,
      setValue,
      onSave,
      onRemove,
      schema,
      saving,
      saveDisabledByParent,
      mayPad
    });
  }
  if (typeName === "discriminatedUnion") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodDiscriminatedUnionEditor, {
      defaultValue,
      mayPad,
      schema,
      setValue,
      value,
      jsonPath,
      onRemove,
      onSave,
      saving,
      saveDisabledByParent,
      showSaveButton
    });
  }
  if (typeName === "tuple") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodTupleEditor, {
      setValue,
      value,
      jsonPath,
      schema,
      defaultValue,
      onSave,
      showSaveButton,
      onRemove,
      saving,
      saveDisabledByParent,
      mayPad
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZonNonEditableValue, {
    jsonPath,
    showSaveButton,
    label: `${typeName} (not editable)`,
    saving,
    mayPad
  });
};

// src/components/RenderModal/SchemaEditor/ZodObjectEditor.tsx

var ZodObjectEditor = ({
  schema,
  jsonPath,
  setValue,
  unsavedValue,
  savedValue,
  onSave,
  showSaveButton,
  onRemove,
  saving,
  saveDisabledByParent,
  mayPad,
  discriminatedUnionReplacement
}) => {
  const [expanded, setExpanded] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(true);
  const { localValue, onChange, RevisionContextProvider, reset } = useLocalState({
    schema,
    setValue,
    unsavedValue,
    savedValue
  });
  const typeName = getZodSchemaType(schema);
  if (typeName !== "object") {
    throw new Error("expected object");
  }
  const shape = getObjectShape(schema);
  const keys = Object.keys(shape);
  const isRoot = jsonPath.length === 0;
  const isDefaultValue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return deepEqual(localValue.value, savedValue);
  }, [savedValue, localValue]);
  const suffix2 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return expanded ? " {" : " {...}";
  }, [expanded]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Fieldset, {
    shouldPad: !isRoot && mayPad,
    success: localValue.zodValidation.success,
    children: [
      isRoot ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaLabel, {
        isDefaultValue,
        onReset: reset,
        jsonPath,
        onRemove,
        suffix: suffix2,
        onSave: () => {
          onSave(() => {
            return localValue.value;
          }, false, false);
        },
        saveDisabledByParent,
        saving,
        showSaveButton,
        valid: localValue.zodValidation.success,
        handleClick: () => setExpanded(!expanded)
      }),
      expanded ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RevisionContextProvider, {
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaVerticalGuide, {
          isRoot,
          children: keys.map((key, i) => {
            if (discriminatedUnionReplacement && key === discriminatedUnionReplacement.discriminator) {
              return discriminatedUnionReplacement.markup;
            }
            return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
              children: [
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodSwitch, {
                  mayPad: true,
                  jsonPath: [...jsonPath, key],
                  schema: shape[key],
                  value: localValue.value[key],
                  defaultValue: (savedValue ?? unsavedValue)[key],
                  setValue: (val, forceApply) => {
                    onChange((oldVal) => {
                      return {
                        ...oldVal,
                        [key]: typeof val === "function" ? val(oldVal[key]) : val
                      };
                    }, forceApply, false);
                  },
                  onSave: (val, forceApply) => {
                    onSave((oldVal) => {
                      return {
                        ...oldVal,
                        [key]: typeof val === "function" ? val(oldVal[key]) : val
                      };
                    }, forceApply, false);
                  },
                  onRemove: null,
                  showSaveButton,
                  saving,
                  saveDisabledByParent
                }),
                i === keys.length - 1 ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaSeparationLine, {})
              ]
            }, key);
          })
        })
      }) : null,
      isRoot || !expanded ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: fieldsetLabel,
        children: "}"
      })
    ]
  });
};

// src/components/RenderModal/SchemaEditor/SchemaEditor.tsx

var scrollable2 = {
  display: "flex",
  flexDirection: "column",
  overflowY: "auto"
};
var SchemaEditor = ({
  schema,
  unsavedDefaultProps,
  setValue,
  zodValidationResult,
  savedDefaultProps,
  onSave,
  showSaveButton,
  saving,
  saveDisabledByParent
}) => {
  const keybindings = useKeybinding();
  const [revision, setRevision] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(0);
  const revisionState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      childResetRevision: revision
    };
  }, [revision]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const bumpRevision = () => {
      setRevision((old) => old + 1);
    };
    window.addEventListener(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.PROPS_UPDATED_EXTERNALLY, bumpRevision);
    return () => {
      window.removeEventListener(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.PROPS_UPDATED_EXTERNALLY, bumpRevision);
    };
  }, []);
  const z = useZodIfPossible();
  if (!z) {
    throw new Error("expected zod");
  }
  const hasChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return !deepEqual(savedDefaultProps, unsavedDefaultProps);
  }, [savedDefaultProps, unsavedDefaultProps]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    setUnsavedProps(hasChanged);
  }, [hasChanged]);
  const onQuickSave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (hasChanged && showSaveButton) {
      onSave(() => {
        return unsavedDefaultProps;
      });
    }
  }, [hasChanged, onSave, showSaveButton, unsavedDefaultProps]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const save = keybindings.registerKeybinding({
      event: "keydown",
      key: "s",
      commandCtrlKey: true,
      callback: onQuickSave,
      preventDefault: true,
      triggerIfInputFieldFocused: true,
      keepRegisteredWhenNotHighestContext: true
    });
    return () => {
      save.unregister();
    };
  }, [keybindings, onQuickSave, onSave]);
  const typeName = getZodSchemaType(schema);
  const reset = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setValue(savedDefaultProps);
  }, [savedDefaultProps, setValue]);
  if (!zodValidationResult.success) {
    const defaultPropsValid = zodSafeParse(schema, savedDefaultProps);
    if (!defaultPropsValid.success) {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InvalidDefaultProps, {
        zodValidationResult
      });
    }
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InvalidSchema, {
      reset,
      zodValidationResult
    });
  }
  if (typeName !== "object") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TopLevelZodValue, {
      typeReceived: typeName
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    ref: defaultPropsEditorScrollableAreaRef,
    style: scrollable2,
    className: VERTICAL_SCROLLBAR_CLASSNAME,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RevisionContext.Provider, {
      value: revisionState,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodObjectEditor, {
        discriminatedUnionReplacement: null,
        unsavedValue: unsavedDefaultProps,
        setValue,
        jsonPath: [],
        schema,
        savedValue: savedDefaultProps,
        onSave,
        showSaveButton,
        onRemove: null,
        saving,
        saveDisabledByParent,
        mayPad: true
      })
    })
  });
};

// src/components/RenderModal/WarningIndicatorButton.tsx


var style8 = {
  fontSize: 12,
  display: "inline-flex",
  justifyContent: "center",
  alignItems: "center",
  backgroundColor: "transparent",
  color: LIGHT_TEXT,
  borderStyle: "solid",
  borderWidth: 1,
  cursor: "pointer",
  paddingLeft: 8,
  paddingRight: 8,
  paddingTop: 4,
  paddingBottom: 4
};
var triangleStyle2 = {
  width: 12,
  height: 12,
  flexShrink: 0,
  fill: WARNING_COLOR
};
var WarningTriangle2 = (props) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    viewBox: "0 0 576 512",
    ...props,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      d: "M248.747 204.705l6.588 112c.373 6.343 5.626 11.295 11.979 11.295h41.37a12 12 0 0 0 11.979-11.295l6.588-112c.405-6.893-5.075-12.705-11.979-12.705h-54.547c-6.903 0-12.383 5.812-11.978 12.705zM330 384c0 23.196-18.804 42-42 42s-42-18.804-42-42 18.804-42 42-42 42 18.804 42 42zm-.423-360.015c-18.433-31.951-64.687-32.009-83.154 0L6.477 440.013C-11.945 471.946 11.118 512 48.054 512H527.94c36.865 0 60.035-39.993 41.577-71.987L329.577 23.985zM53.191 455.002L282.803 57.008c2.309-4.002 8.085-4.002 10.394 0l229.612 397.993c2.308 4-.579 8.998-5.197 8.998H58.388c-4.617.001-7.504-4.997-5.197-8.997z"
    })
  });
};
var WarningIndicatorButton = ({ setShowWarning, showWarning, warningCount }) => {
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setShowWarning((s) => !s);
  }, [setShowWarning]);
  const buttonStyle3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...style8,
      backgroundColor: showWarning ? INPUT_BACKGROUND : "transparent",
      borderColor: showWarning ? INPUT_BORDER_COLOR_HOVERED : INPUT_BORDER_COLOR_UNHOVERED,
      color: showWarning ? "white" : LIGHT_TEXT
    };
  }, [showWarning]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("button", {
    type: "button",
    style: buttonStyle3,
    onClick,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(WarningTriangle2, {
        style: triangleStyle2
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 0.5
      }),
      warningCount,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(AngleDown, {
        down: showWarning
      })
    ]
  });
};

// src/components/RenderModal/DataEditor.tsx

var errorExplanation2 = {
  fontSize: 14,
  color: LIGHT_TEXT,
  fontFamily: "sans-serif",
  lineHeight: 1.5
};
var explainer3 = {
  display: "flex",
  flex: 1,
  flexDirection: "column",
  padding: "0 12px",
  justifyContent: "center",
  alignItems: "center",
  textAlign: "center"
};
var outer = {
  display: "flex",
  flexDirection: "column",
  flex: 1,
  overflow: "hidden",
  backgroundColor: BACKGROUND
};
var controlContainer = {
  flexDirection: "column",
  display: "flex",
  padding: 12,
  borderBottom: `1px solid ${BORDER_COLOR}`
};
var tabWrapper = {
  display: "flex",
  marginBottom: "4px",
  flexDirection: "row",
  alignItems: "center"
};
var persistanceKey = "remotion.show-render-modalwarning";
var getPersistedShowWarningState = () => {
  const val = localStorage.getItem(persistanceKey);
  if (!val) {
    return true;
  }
  return val === "true";
};
var setPersistedShowWarningState = (val) => {
  localStorage.setItem(persistanceKey, String(Boolean(val)));
};
var DataEditor = ({
  unresolvedComposition,
  defaultProps,
  setDefaultProps,
  mayShowSaveButton,
  propsEditType,
  saving,
  setSaving,
  readOnlyStudio
}) => {
  const [mode, setMode] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)("schema");
  const [showWarning, setShowWarningWithoutPersistance] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => getPersistedShowWarningState());
  const { updateCompositionDefaultProps } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionSetters);
  const inJSONEditor = mode === "json";
  const serializedJSON = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!inJSONEditor) {
      return null;
    }
    const value = defaultProps;
    return remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.serializeJSONWithSpecialTypes({
      data: value,
      indent: 2,
      staticBase: window.remotion_staticBase
    });
  }, [inJSONEditor, defaultProps]);
  const cliProps = (0,remotion__WEBPACK_IMPORTED_MODULE_2__.getInputProps)();
  const [canSaveDefaultPropsObjectState, setCanSaveDefaultProps] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({
    [unresolvedComposition.id]: defaultTypeCanSaveState
  });
  const z = useZodIfPossible();
  const zodTypes = useZodTypesIfPossible();
  const schema = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!z) {
      return "no-zod";
    }
    if (!unresolvedComposition.schema) {
      return "no-schema";
    }
    if (!(typeof unresolvedComposition.schema.safeParse === "function")) {
      throw new Error("A value which is not a Zod schema was passed to `schema`");
    }
    return unresolvedComposition.schema;
  }, [unresolvedComposition.schema, z]);
  const zodValidationResult = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (schema === "no-zod") {
      return "no-zod";
    }
    if (schema === "no-schema") {
      return "no-schema";
    }
    return zodSafeParse(schema, defaultProps);
  }, [defaultProps, schema]);
  const setShowWarning = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((val) => {
    setShowWarningWithoutPersistance((prevVal) => {
      if (typeof val === "boolean") {
        setPersistedShowWarningState(val);
        return val;
      }
      setPersistedShowWarningState(val(prevVal));
      return val(prevVal);
    });
  }, []);
  const canSaveDefaultProps = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return canSaveDefaultPropsObjectState[unresolvedComposition.id] ? canSaveDefaultPropsObjectState[unresolvedComposition.id] : defaultTypeCanSaveState;
  }, [canSaveDefaultPropsObjectState, unresolvedComposition.id]);
  const showSaveButton = mayShowSaveButton && canSaveDefaultProps.canUpdate;
  const { fastRefreshes } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(FastRefreshContext);
  const checkIfCanSaveDefaultProps = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(async () => {
    try {
      const can = await canUpdateDefaultProps(unresolvedComposition.id, readOnlyStudio);
      if (can.canUpdate) {
        setCanSaveDefaultProps((prevState) => ({
          ...prevState,
          [unresolvedComposition.id]: {
            canUpdate: true
          }
        }));
      } else {
        setCanSaveDefaultProps((prevState) => ({
          ...prevState,
          [unresolvedComposition.id]: {
            canUpdate: false,
            reason: can.reason,
            determined: true
          }
        }));
      }
    } catch (err) {
      setCanSaveDefaultProps((prevState) => ({
        ...prevState,
        [unresolvedComposition.id]: {
          canUpdate: false,
          reason: err.message,
          determined: true
        }
      }));
    }
  }, [readOnlyStudio, unresolvedComposition.id]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    checkIfCanSaveDefaultProps();
  }, [checkIfCanSaveDefaultProps]);
  const { previewServerState, subscribeToEvent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const unsub = subscribeToEvent("root-file-changed", checkIfCanSaveDefaultProps);
    return () => {
      unsub();
    };
  }, [checkIfCanSaveDefaultProps, subscribeToEvent]);
  const modeItems = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return [
      {
        key: "schema",
        label: "Schema",
        onClick: () => {
          setMode("schema");
        },
        selected: mode === "schema"
      },
      {
        key: "json",
        label: "JSON",
        onClick: () => {
          setMode("json");
        },
        selected: mode === "json"
      }
    ];
  }, [mode]);
  const onUpdate = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (schema === "no-zod" || schema === "no-schema" || z === null) {
      showNotification("Cannot update default props: No Zod schema", 2000);
      return;
    }
    callUpdateDefaultPropsApi(unresolvedComposition.id, defaultProps, extractEnumJsonPaths({ schema, zodRuntime: z, currentPath: [], zodTypes })).then((response) => {
      if (!response.success) {
        showNotification(`Cannot update default props: ${response.reason}`, 2000);
      }
    });
  }, [schema, z, unresolvedComposition.id, defaultProps, zodTypes]);
  const onSave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((updater) => {
    if (schema === "no-zod" || schema === "no-schema" || z === null) {
      showNotification("Cannot update default props: No Zod schema", 2000);
      return;
    }
    window.remotion_ignoreFastRefreshUpdate = fastRefreshes + 1;
    setSaving(true);
    const newDefaultProps = updater(unresolvedComposition.defaultProps ?? {});
    callUpdateDefaultPropsApi(unresolvedComposition.id, newDefaultProps, extractEnumJsonPaths({
      schema,
      zodRuntime: z,
      currentPath: [],
      zodTypes
    })).then((response) => {
      if (!response.success) {
        console.log(response.stack);
        showNotification(`Cannot update default props: ${response.reason}. See console for more information.`, 2000);
      }
      updateCompositionDefaultProps(unresolvedComposition.id, newDefaultProps);
    }).catch((err) => {
      showNotification(`Cannot update default props: ${err.message}`, 2000);
    }).finally(() => {
      setSaving(false);
    });
  }, [
    schema,
    z,
    zodTypes,
    fastRefreshes,
    setSaving,
    unresolvedComposition.defaultProps,
    unresolvedComposition.id,
    updateCompositionDefaultProps
  ]);
  const connectionStatus = previewServerState.type;
  const warnings = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return getRenderModalWarnings({
      canSaveDefaultProps,
      cliProps,
      isCustomDateUsed: serializedJSON ? serializedJSON.customDateUsed : false,
      customFileUsed: serializedJSON ? serializedJSON.customFileUsed : false,
      inJSONEditor,
      propsEditType,
      jsMapUsed: serializedJSON ? serializedJSON.mapUsed : false,
      jsSetUsed: serializedJSON ? serializedJSON.setUsed : false
    });
  }, [
    cliProps,
    canSaveDefaultProps,
    inJSONEditor,
    propsEditType,
    serializedJSON
  ]);
  if (connectionStatus === "disconnected") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
      style: explainer3,
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
          y: 5
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: errorExplanation2,
          children: "The studio server has disconnected. Reconnect to edit the schema."
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
          y: 2,
          block: true
        })
      ]
    });
  }
  if (schema === "no-zod") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodNotInstalled, {});
  }
  if (schema === "no-schema") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NoSchemaDefined, {});
  }
  if (!z) {
    throw new Error("expected zod");
  }
  if (zodValidationResult === "no-zod") {
    throw new Error("expected zod");
  }
  if (zodValidationResult === "no-schema") {
    throw new Error("expected schema");
  }
  const typeName = getZodSchemaType(schema);
  if (typeName === "any") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NoSchemaDefined, {});
  }
  if (!unresolvedComposition.defaultProps) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NoDefaultProps, {});
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: outer,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: controlContainer,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: tabWrapper,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SegmentedControl, {
                items: modeItems,
                needsWrapping: false
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {}),
              warnings.length > 0 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(WarningIndicatorButton, {
                setShowWarning,
                showWarning,
                warningCount: warnings.length
              }) : null
            ]
          }),
          showWarning && warnings.length > 0 ? warnings.map((warning) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                y: 1
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ValidationMessage, {
                message: warning,
                align: "flex-start",
                type: "warning"
              })
            ]
          }, warning)) : null
        ]
      }),
      mode === "schema" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaEditor, {
        unsavedDefaultProps: defaultProps,
        setValue: setDefaultProps,
        schema,
        zodValidationResult,
        savedDefaultProps: unresolvedComposition.defaultProps,
        onSave,
        showSaveButton,
        saving,
        saveDisabledByParent: !zodValidationResult.success
      }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalJSONPropsEditor, {
        value: defaultProps ?? {},
        setValue: setDefaultProps,
        onSave: onUpdate,
        showSaveButton,
        serializedJSON,
        defaultProps: unresolvedComposition.defaultProps,
        schema
      })
    ]
  });
};

// src/components/RenderQueue/index.tsx



// src/components/RenderQueue/RenderQueueItem.tsx



// src/components/RenderQueue/client-side-render-types.ts
var isRestoredClientJob = (job) => {
  return !("inputProps" in job);
};

// src/components/RenderQueue/item-style.ts
var renderQueueItemSubtitleStyle = {
  fontSize: 13,
  color: LIGHT_TEXT,
  appearance: "none",
  border: "none",
  padding: 0,
  cursor: "pointer",
  lineHeight: 1.2,
  textAlign: "left",
  whiteSpace: "nowrap",
  marginRight: SPACING_UNIT,
  overflowX: "hidden",
  maxWidth: 500,
  textOverflow: "ellipsis"
};

// src/components/RenderQueue/RenderQueueCancelledMessage.tsx

var cancelledStyle = {
  ...renderQueueItemSubtitleStyle,
  color: LIGHT_TEXT,
  cursor: "default"
};
var RenderQueueCancelledMessage = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
    style: cancelledStyle,
    children: "Cancelled"
  });
};

// src/components/RenderQueue/RenderQueueCopyToClipboard.tsx


var revealIconStyle2 = {
  height: 12,
  color: "currentColor"
};
var supportsCopyingToClipboard = (job) => {
  if (job.status !== "done") {
    return false;
  }
  if (job.type !== "still") {
    return false;
  }
  if (job.imageFormat === "png") {
    return true;
  }
  if (job.imageFormat === "jpeg") {
    return true;
  }
  return false;
};
var RenderQueueCopyToClipboard = ({ job }) => {
  const renderCopyAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ClipboardIcon, {
      style: revealIconStyle2,
      color
    });
  }, []);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(async (e) => {
    e.stopPropagation();
    try {
      const src = `${remotion_outputsBase}/${job.outName}`;
      const content = await fetch(src);
      const contentType = content.headers.get("content-type");
      if (!contentType) {
        throw new Error("Expected content-type header");
      }
      const blob = await content.blob();
      await navigator.clipboard.write([
        new ClipboardItem({
          [contentType]: blob
        })
      ]);
      showNotification("Copied to clipboard!", 1000);
    } catch (err) {
      showNotification(`Could not copy to clipboard: ${err.message}`, 2000);
    }
  }, [job.outName]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
    title: "Copy to clipboard",
    renderAction: renderCopyAction,
    onClick
  });
};

// src/components/RenderQueue/RenderQueueDownloadItem.tsx


// src/components/RenderQueue/ClientRenderQueueProcessor.tsx



// src/api/save-render-output.ts
var throwIfNotOk = async (response) => {
  if (!response.ok) {
    try {
      const jsonResponse = await response.json();
      throw new Error(jsonResponse.error);
    } catch (parseError2) {
      if (parseError2 instanceof Error && parseError2.message) {
        throw parseError2;
      }
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }
  }
};
var saveOutputFile = async ({
  blob,
  filePath
}) => {
  const url = new URL("/api/upload-output", window.location.origin);
  url.search = new URLSearchParams({ filePath }).toString();
  const response = await fetch(url, {
    method: "POST",
    body: blob
  });
  await throwIfNotOk(response);
};
var registerClientRender = async (render) => {
  const response = await fetch("/api/register-client-render", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(render)
  });
  await throwIfNotOk(response);
};
var unregisterClientRender = async (id) => {
  const response = await fetch("/api/unregister-client-render", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ id })
  });
  await throwIfNotOk(response);
};

// src/components/RenderQueue/ClientRenderQueueProcessor.tsx
var downloadBlob = (blob, filename) => {
  const url = URL.createObjectURL(blob);
  const a = document.createElement("a");
  a.href = url;
  const cleanFilename = filename.includes("/") ? filename.substring(filename.lastIndexOf("/") + 1) : filename;
  a.download = cleanFilename;
  a.click();
  URL.revokeObjectURL(url);
};
var ClientRenderQueueProcessor = () => {
  const {
    getAbortController: getAbortController2,
    getCompositionForJob: getCompositionForJob2,
    updateClientJobProgress,
    markClientJobSaving,
    markClientJobDone,
    markClientJobFailed,
    markClientJobCancelled,
    setProcessJobCallback
  } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(RenderQueueContext);
  const processStillJob = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(async (job, signal) => {
    const compositionRef = getCompositionForJob2(job.id);
    if (!compositionRef) {
      throw new Error(`Composition not found for job ${job.id}`);
    }
    const { blob } = await (0,_remotion_web_renderer__WEBPACK_IMPORTED_MODULE_12__/* .renderStillOnWeb */ .Uu)({
      composition: {
        component: compositionRef.component,
        width: compositionRef.width,
        height: compositionRef.height,
        fps: compositionRef.fps,
        durationInFrames: compositionRef.durationInFrames,
        defaultProps: compositionRef.defaultProps,
        calculateMetadata: compositionRef.calculateMetadata ?? undefined,
        id: job.compositionId
      },
      frame: job.frame,
      imageFormat: job.imageFormat,
      inputProps: job.inputProps,
      delayRenderTimeoutInMilliseconds: job.delayRenderTimeout,
      mediaCacheSizeInBytes: job.mediaCacheSizeInBytes,
      logLevel: job.logLevel,
      licenseKey: job.licenseKey ?? undefined,
      scale: job.scale,
      signal
    });
    return {
      getBlob: () => Promise.resolve(blob),
      width: compositionRef.width,
      height: compositionRef.height
    };
  }, [getCompositionForJob2]);
  const processVideoJob = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(async (job, signal, onProgress) => {
    const compositionRef = getCompositionForJob2(job.id);
    if (!compositionRef) {
      throw new Error(`Composition not found for job ${job.id}`);
    }
    const totalFrames = job.endFrame - job.startFrame + 1;
    const { getBlob } = await (0,_remotion_web_renderer__WEBPACK_IMPORTED_MODULE_12__/* .renderMediaOnWeb */ .CE)({
      composition: {
        component: compositionRef.component,
        width: compositionRef.width,
        height: compositionRef.height,
        fps: compositionRef.fps,
        durationInFrames: compositionRef.durationInFrames,
        defaultProps: compositionRef.defaultProps,
        calculateMetadata: compositionRef.calculateMetadata ?? undefined,
        id: job.compositionId
      },
      inputProps: job.inputProps,
      delayRenderTimeoutInMilliseconds: job.delayRenderTimeout,
      mediaCacheSizeInBytes: job.mediaCacheSizeInBytes,
      logLevel: job.logLevel,
      videoCodec: job.videoCodec,
      audioCodec: job.audioCodec,
      audioBitrate: job.audioBitrate,
      container: job.container,
      videoBitrate: job.videoBitrate,
      hardwareAcceleration: job.hardwareAcceleration,
      keyframeIntervalInSeconds: job.keyframeIntervalInSeconds,
      frameRange: [job.startFrame, job.endFrame],
      transparent: job.transparent,
      muted: job.muted,
      scale: job.scale,
      signal,
      onProgress: (progress) => {
        onProgress(job.id, {
          encodedFrames: progress.encodedFrames,
          totalFrames
        });
      },
      outputTarget: "web-fs",
      licenseKey: job.licenseKey ?? undefined
    });
    return {
      getBlob,
      width: compositionRef.width,
      height: compositionRef.height
    };
  }, [getCompositionForJob2]);
  const processJob = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(async (job) => {
    const abortController = getAbortController2(job.id);
    try {
      let result;
      if (job.type === "client-still") {
        result = await processStillJob(job, abortController.signal);
      } else if (job.type === "client-video") {
        result = await processVideoJob(job, abortController.signal, updateClientJobProgress);
      } else {
        throw new Error(`Unknown job type`);
      }
      const blob = await result.getBlob();
      const metadata = {
        width: result.width,
        height: result.height,
        sizeInBytes: blob.size
      };
      markClientJobSaving(job.id);
      const getBlob = () => Promise.resolve(blob);
      const downloadAndFinish = () => {
        downloadBlob(blob, job.outName);
        markClientJobDone(job.id, metadata, getBlob);
      };
      if (window.remotion_isReadOnlyStudio) {
        downloadAndFinish();
      } else {
        try {
          await saveOutputFile({ blob, filePath: job.outName });
          await registerClientRender({
            id: job.id,
            type: job.type,
            compositionId: job.compositionId,
            outName: job.outName,
            startedAt: job.startedAt,
            deletedOutputLocation: false,
            metadata
          });
          markClientJobDone(job.id, metadata);
        } catch (err) {
          console.error("Failed to save render output, falling back to browser download.", err);
          downloadAndFinish();
        }
      }
    } catch (err) {
      if (abortController.signal.aborted) {
        markClientJobCancelled(job.id);
      } else {
        markClientJobFailed(job.id, err);
      }
    }
  }, [
    getAbortController2,
    processStillJob,
    processVideoJob,
    updateClientJobProgress,
    markClientJobSaving,
    markClientJobDone,
    markClientJobFailed,
    markClientJobCancelled
  ]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    setProcessJobCallback(processJob);
    return () => setProcessJobCallback(null);
  }, [processJob, setProcessJobCallback]);
  return null;
};

// src/components/RenderQueue/RenderQueueDownloadItem.tsx

var RenderQueueDownloadItem = ({ job }) => {
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.stopPropagation();
    if (job.status !== "done" || !job.getBlob) {
      return;
    }
    job.getBlob().then((blob) => {
      downloadBlob(blob, job.outName);
    }).catch((err) => {
      showNotification(`Could not download file: ${err.message}`, 2000);
    });
  }, [job]);
  const icon5 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      height: 12,
      color: "currentColor"
    };
  }, []);
  const renderAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      style: icon5,
      xmlns: "http://www.w3.org/2000/svg",
      viewBox: "0 0 512 512",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        fill: color,
        d: "M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 242.7-73.4-73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l128 128c12.5 12.5 32.8 12.5 45.3 0l128-128c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L288 274.7 288 32zM64 352c-35.3 0-64 28.7-64 64l0 32c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-32c0-35.3-28.7-64-64-64l-101.5 0-45.3 45.3c-25 25-65.5 25-90.5 0L165.5 352 64 352zm368 56a24 24 0 1 1 0 48 24 24 0 1 1 0-48z"
      })
    });
  }, [icon5]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
    renderAction,
    onClick,
    title: "Download"
  });
};

// src/components/RenderQueue/RenderQueueError.tsx


var outputLocation = {
  ...renderQueueItemSubtitleStyle
};
var RenderQueueError = ({ job }) => {
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const { tabIndex } = useZIndex();
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSelectedModal({
      type: "render-progress",
      jobId: job.id
    });
  }, [job.id, setSelectedModal]);
  if (job.status !== "failed") {
    throw new Error("should not have rendered this component");
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
    onClick,
    type: "button",
    style: outputLocation,
    tabIndex,
    title: job.error.message,
    children: job.error.message
  });
};

// src/components/RenderQueue/RenderQueueItemCancelButton.tsx


var RenderQueueCancelButton = ({ job }) => {
  const isClientJob = isClientRenderJob(job);
  const { cancelClientJob } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(RenderQueueContext);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.stopPropagation();
    if (isClientJob) {
      cancelClientJob(job.id);
      return;
    }
    cancelRenderJob(job).catch((err) => {
      showNotification(`Could not cancel job: ${err.message}`, 2000);
    });
  }, [job, isClientJob, cancelClientJob]);
  const icon5 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      height: 14,
      color: "currentColor"
    };
  }, []);
  const renderAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      style: icon5,
      xmlns: "http://www.w3.org/2000/svg",
      viewBox: "0 0 512 512",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        fill: color,
        d: "M367.2 412.5L99.5 144.8C77.1 176.1 64 214.5 64 256c0 106 86 192 192 192c41.5 0 79.9-13.1 111.2-35.5zm45.3-45.3C434.9 335.9 448 297.5 448 256c0-106-86-192-192-192c-41.5 0-79.9 13.1-111.2 35.5L412.5 367.2zM512 256c0 141.4-114.6 256-256 256S0 397.4 0 256S114.6 0 256 0S512 114.6 512 256z"
      })
    });
  }, [icon5]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
    renderAction,
    onClick
  });
};

// src/components/RenderQueue/RenderQueueItemStatus.tsx


// src/components/RenderQueue/CircularProgress.tsx

var RENDER_STATUS_INDICATOR_SIZE = 16;
var STROKE_WIDTH = 3;
var container31 = {
  height: RENDER_STATUS_INDICATOR_SIZE,
  width: RENDER_STATUS_INDICATOR_SIZE,
  transform: `rotate(-90deg)`
};
var CircularProgress = ({ progress }) => {
  const r = RENDER_STATUS_INDICATOR_SIZE / 2 - STROKE_WIDTH;
  const circumference = r * Math.PI * 2;
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    style: container31,
    viewBox: `0 0 ${RENDER_STATUS_INDICATOR_SIZE} ${RENDER_STATUS_INDICATOR_SIZE}`,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("circle", {
      r: RENDER_STATUS_INDICATOR_SIZE / 2 - STROKE_WIDTH,
      stroke: LIGHT_TEXT,
      fill: "none",
      strokeWidth: STROKE_WIDTH,
      cx: RENDER_STATUS_INDICATOR_SIZE / 2,
      cy: RENDER_STATUS_INDICATOR_SIZE / 2,
      strokeDasharray: `${circumference} ${circumference}`,
      strokeMiterlimit: 0,
      strokeDashoffset: (1 - progress) * circumference
    })
  });
};

// src/components/RenderQueue/RenderQueueItemStatus.tsx

var iconStyle3 = {
  height: RENDER_STATUS_INDICATOR_SIZE,
  width: RENDER_STATUS_INDICATOR_SIZE
};
var invisibleStyle = {
  appearance: "none",
  border: "none",
  padding: 0,
  cursor: "pointer",
  display: "flex"
};
var RenderQueueItemStatus = ({ job }) => {
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const [hovered, setHovered] = react__WEBPACK_IMPORTED_MODULE_0__.useState(false);
  const isClientJob = isClientRenderJob(job);
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(true);
  }, []);
  const onPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(false);
  }, []);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.stopPropagation();
    setSelectedModal({
      type: "render-progress",
      jobId: job.id
    });
  }, [job.id, setSelectedModal]);
  if (job.status === "failed") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
      type: "button",
      style: invisibleStyle,
      onClick,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
        style: iconStyle3,
        viewBox: "0 0 512 512",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
          fill: FAIL_COLOR,
          d: "M0 160V352L160 512H352L512 352V160L352 0H160L0 160zm353.9 32l-17 17-47 47 47 47 17 17L320 353.9l-17-17-47-47-47 47-17 17L158.1 320l17-17 47-47-47-47-17-17L192 158.1l17 17 47 47 47-47 17-17L353.9 192z"
        })
      })
    });
  }
  if (job.status === "idle") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      style: iconStyle3,
      viewBox: "0 0 512 512",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        fill: LIGHT_TEXT,
        d: "M256 512C114.6 512 0 397.4 0 256S114.6 0 256 0S512 114.6 512 256s-114.6 256-256 256zM232 120V256c0 8 4 15.5 10.7 20l96 64c11 7.4 25.9 4.4 33.3-6.7s4.4-25.9-6.7-33.3L280 243.2V120c0-13.3-10.7-24-24-24s-24 10.7-24 24z"
      })
    });
  }
  if (job.status === "done") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
      type: "button",
      style: invisibleStyle,
      onPointerEnter,
      onPointerLeave,
      onClick,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
        style: iconStyle3,
        viewBox: "0 0 512 512",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
          fill: hovered ? "white" : LIGHT_TEXT,
          d: "M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM369 209L241 337l-17 17-17-17-64-64-17-17L160 222.1l17 17 47 47L335 175l17-17L385.9 192l-17 17z"
        })
      })
    });
  }
  if (job.status === "running") {
    let progressValue;
    if (isClientJob) {
      const { encodedFrames, totalFrames } = job.progress;
      progressValue = totalFrames > 0 ? encodedFrames / totalFrames : 0;
    } else {
      progressValue = job.progress.value;
    }
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
      type: "button",
      style: invisibleStyle,
      onClick,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CircularProgress, {
        progress: Math.max(0.07, progressValue)
      })
    });
  }
  if (job.status === "saving") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
      type: "button",
      style: invisibleStyle,
      onClick,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CircularProgress, {
        progress: 0.95
      })
    });
  }
  if (job.status === "cancelled") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      style: iconStyle3,
      viewBox: "0 0 512 512",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        fill: FAIL_COLOR,
        d: "M0 160V352L160 512H352L512 352V160L352 0H160L0 160zm353.9 32l-17 17-47 47 47 47 17 17L320 353.9l-17-17-47-47-47 47-17 17L158.1 320l17-17 47-47-47-47-17-17L192 158.1l17 17 47 47 47-47 17-17L353.9 192z"
      })
    });
  }
  throw new Error("Unknown job status");
};

// src/components/RenderQueue/RenderQueueOpenInFolder.tsx


var RenderQueueOpenInFinderItem = ({ job }) => {
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.stopPropagation();
    openInFileExplorer({ directory: job.outName }).catch((err) => {
      showNotification(`Could not open file: ${err.message}`, 2000);
    });
  }, [job.outName]);
  const icon5 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      height: 12,
      color: "currentColor"
    };
  }, []);
  const renderAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ExpandedFolderIconSolid, {
      style: icon5,
      color
    });
  }, [icon5]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
    renderAction,
    onClick
  });
};

// src/components/RenderQueue/RenderQueueOutputName.tsx


var RenderQueueOutputName = ({ job }) => {
  const deletedOutputLocation = "deletedOutputLocation" in job && job.deletedOutputLocation;
  const style9 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...renderQueueItemSubtitleStyle,
      textDecoration: deletedOutputLocation ? "line-through" : "none",
      color: renderQueueItemSubtitleStyle.color,
      cursor: "inherit"
    };
  }, [deletedOutputLocation]);
  const getTitle = () => {
    if (deletedOutputLocation) {
      return "File was deleted";
    }
    return job.outName;
  };
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
    style: style9,
    title: getTitle(),
    children: job.outName
  });
};

// src/components/RenderQueue/RenderQueueProgressMessage.tsx


var outputLocation2 = {
  ...renderQueueItemSubtitleStyle
};
var RenderQueueProgressMessage = ({ job }) => {
  if (job.status !== "running") {
    throw new Error("should not have rendered this component");
  }
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const { tabIndex } = useZIndex();
  const isClientJob = isClientRenderJob(job);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSelectedModal({
      type: "render-progress",
      jobId: job.id
    });
  }, [job.id, setSelectedModal]);
  const message = isClientJob ? job.progress.totalFrames === 0 ? "Getting composition" : `Encoding frame ${job.progress.encodedFrames}/${job.progress.totalFrames}` : job.progress.message;
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
    onClick,
    type: "button",
    style: outputLocation2,
    tabIndex,
    title: message,
    children: message
  });
};

// src/components/RenderQueue/RenderQueueRemoveItem.tsx



var RenderQueueRemoveItem = ({ job }) => {
  const isClientJob = isClientRenderJob(job);
  const { removeClientJob } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(RenderQueueContext);
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const { setCanvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionSetters);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.stopPropagation();
    if (isClientJob) {
      if (canvasContent && canvasContent.type === "output" && job.status === "done" && canvasContent.path === `/${job.outName}`) {
        setCanvasContent(null);
      }
      removeClientJob(job.id);
      unregisterClientRender(job.id).catch(() => {});
      showNotification("Removed job", 2000);
      return;
    }
    removeRenderJob(job).then(() => {
      showNotification("Removed job", 2000);
    }).catch((err) => {
      showNotification(`Could not remove item: ${err.message}`, 2000);
    });
  }, [job, isClientJob, removeClientJob, canvasContent, setCanvasContent]);
  const icon5 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      height: 16,
      color: "currentColor"
    };
  }, []);
  const renderAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      style: icon5,
      xmlns: "http://www.w3.org/2000/svg",
      viewBox: "0 0 320 512",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        fill: color,
        d: "M310.6 150.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L160 210.7 54.6 105.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L114.7 256 9.4 361.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 301.3 265.4 406.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L205.3 256 310.6 150.6z"
      })
    });
  }, [icon5]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
    renderAction,
    onClick
  });
};

// src/components/RenderQueue/RenderQueueRepeat.tsx


// src/helpers/retry-payload.ts

var makeRetryPayload = (job) => {
  const defaults = window.remotion_renderDefaults;
  if (!defaults) {
    throw new Error("defaults not set");
  }
  if (job.type === "still") {
    return {
      type: "server-render",
      compositionId: job.compositionId,
      initialFrame: job.frame,
      initialStillImageFormat: job.imageFormat,
      initialVideoImageFormat: null,
      initialJpegQuality: job.jpegQuality ?? defaults.jpegQuality,
      initialScale: job.scale,
      initialLogLevel: job.logLevel,
      initialConcurrency: defaults.concurrency,
      maxConcurrency: defaults.maxConcurrency,
      minConcurrency: defaults.minConcurrency,
      initialMuted: defaults.muted,
      initialEnforceAudioTrack: defaults.enforceAudioTrack,
      initialProResProfile: null,
      initialx264Preset: defaults.x264Preset,
      initialPixelFormat: defaults.pixelFormat,
      initialAudioBitrate: defaults.audioBitrate,
      initialVideoBitrate: defaults.videoBitrate,
      initialEveryNthFrame: defaults.everyNthFrame,
      initialNumberOfGifLoops: defaults.numberOfGifLoops,
      initialDelayRenderTimeout: job.delayRenderTimeout,
      defaultConfigurationAudioCodec: defaults.audioCodec,
      initialEnvVariables: job.envVariables,
      initialDisableWebSecurity: job.chromiumOptions.disableWebSecurity,
      initialOpenGlRenderer: job.chromiumOptions.gl,
      initialHeadless: job.chromiumOptions.headless,
      initialIgnoreCertificateErrors: job.chromiumOptions.ignoreCertificateErrors,
      initialDarkMode: job.chromiumOptions.darkMode,
      defaultProps: remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.deserializeJSONWithSpecialTypes(job.serializedInputPropsWithCustomSchema),
      inFrameMark: null,
      outFrameMark: null,
      initialOffthreadVideoCacheSizeInBytes: job.offthreadVideoCacheSizeInBytes,
      initialOffthreadVideoThreads: job.offthreadVideoThreads,
      initialColorSpace: defaults.colorSpace,
      initialMultiProcessOnLinux: job.multiProcessOnLinux,
      defaultConfigurationVideoCodec: defaults.codec,
      initialEncodingBufferSize: defaults.encodingBufferSize,
      initialEncodingMaxRate: defaults.encodingMaxRate,
      initialUserAgent: job.chromiumOptions.userAgent,
      initialBeep: job.beepOnFinish,
      initialRepro: job.repro,
      initialForSeamlessAacConcatenation: defaults.forSeamlessAacConcatenation,
      defaulMetadata: job.metadata,
      renderTypeOfLastRender: "still",
      initialHardwareAcceleration: defaults.hardwareAcceleration,
      initialChromeMode: job.chromeMode,
      initialMediaCacheSizeInBytes: job.mediaCacheSizeInBytes,
      renderDefaults: defaults
    };
  }
  if (job.type === "sequence") {
    return {
      type: "server-render",
      initialFrame: 0,
      compositionId: job.compositionId,
      initialVideoImageFormat: null,
      initialJpegQuality: job.jpegQuality ?? defaults.jpegQuality,
      initialScale: job.scale,
      initialLogLevel: job.logLevel,
      initialConcurrency: defaults.concurrency,
      maxConcurrency: defaults.maxConcurrency,
      minConcurrency: defaults.minConcurrency,
      initialMuted: defaults.muted,
      initialEnforceAudioTrack: defaults.enforceAudioTrack,
      initialProResProfile: null,
      initialx264Preset: defaults.x264Preset,
      initialPixelFormat: defaults.pixelFormat,
      initialAudioBitrate: defaults.audioBitrate,
      initialVideoBitrate: defaults.videoBitrate,
      initialEveryNthFrame: defaults.everyNthFrame,
      initialNumberOfGifLoops: defaults.numberOfGifLoops,
      initialDelayRenderTimeout: job.delayRenderTimeout,
      initialEnvVariables: job.envVariables,
      initialDisableWebSecurity: job.chromiumOptions.disableWebSecurity,
      initialOpenGlRenderer: job.chromiumOptions.gl,
      initialHeadless: job.chromiumOptions.headless,
      initialIgnoreCertificateErrors: job.chromiumOptions.ignoreCertificateErrors,
      initialDarkMode: job.chromiumOptions.darkMode,
      defaultProps: remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.deserializeJSONWithSpecialTypes(job.serializedInputPropsWithCustomSchema),
      initialStillImageFormat: defaults.stillImageFormat,
      inFrameMark: job.startFrame,
      outFrameMark: job.endFrame,
      initialOffthreadVideoCacheSizeInBytes: job.offthreadVideoCacheSizeInBytes,
      initialOffthreadVideoThreads: job.offthreadVideoThreads,
      initialColorSpace: defaults.colorSpace,
      initialMultiProcessOnLinux: job.multiProcessOnLinux,
      defaultConfigurationVideoCodec: defaults.codec,
      defaultConfigurationAudioCodec: defaults.audioCodec,
      initialEncodingBufferSize: defaults.encodingBufferSize,
      initialEncodingMaxRate: defaults.encodingMaxRate,
      initialUserAgent: job.chromiumOptions.userAgent,
      initialBeep: job.beepOnFinish,
      initialRepro: job.repro,
      initialForSeamlessAacConcatenation: defaults.forSeamlessAacConcatenation,
      defaulMetadata: job.metadata,
      renderTypeOfLastRender: "sequence",
      initialHardwareAcceleration: defaults.hardwareAcceleration,
      initialChromeMode: job.chromeMode,
      initialMediaCacheSizeInBytes: job.mediaCacheSizeInBytes,
      renderDefaults: defaults
    };
  }
  if (job.type === "video") {
    return {
      type: "server-render",
      compositionId: job.compositionId,
      initialStillImageFormat: defaults.stillImageFormat,
      initialVideoImageFormat: job.imageFormat,
      initialJpegQuality: job.jpegQuality ?? defaults.jpegQuality,
      initialScale: job.scale,
      initialLogLevel: job.logLevel,
      initialFrame: 0,
      initialConcurrency: job.concurrency,
      maxConcurrency: defaults.maxConcurrency,
      minConcurrency: defaults.minConcurrency,
      initialMuted: job.muted,
      initialEnforceAudioTrack: job.enforceAudioTrack,
      initialProResProfile: job.proResProfile ?? null,
      initialx264Preset: job.x264Preset ?? defaults.x264Preset,
      initialPixelFormat: job.pixelFormat,
      initialAudioBitrate: job.audioBitrate,
      initialVideoBitrate: job.videoBitrate,
      initialEveryNthFrame: job.everyNthFrame,
      initialNumberOfGifLoops: job.numberOfGifLoops,
      initialDelayRenderTimeout: job.delayRenderTimeout,
      initialEnvVariables: job.envVariables,
      initialDisableWebSecurity: job.chromiumOptions.disableWebSecurity,
      initialOpenGlRenderer: job.chromiumOptions.gl,
      initialHeadless: job.chromiumOptions.headless,
      initialIgnoreCertificateErrors: job.chromiumOptions.ignoreCertificateErrors,
      initialDarkMode: job.chromiumOptions.darkMode,
      defaultProps: remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.deserializeJSONWithSpecialTypes(job.serializedInputPropsWithCustomSchema),
      inFrameMark: job.startFrame,
      outFrameMark: job.endFrame,
      initialOffthreadVideoCacheSizeInBytes: job.offthreadVideoCacheSizeInBytes,
      initialOffthreadVideoThreads: job.offthreadVideoThreads,
      initialColorSpace: job.colorSpace,
      initialMultiProcessOnLinux: job.multiProcessOnLinux,
      defaultConfigurationVideoCodec: job.codec,
      defaultConfigurationAudioCodec: job.audioCodec,
      initialEncodingBufferSize: job.encodingBufferSize,
      initialEncodingMaxRate: job.encodingMaxRate,
      initialUserAgent: job.chromiumOptions.userAgent,
      initialBeep: job.beepOnFinish,
      initialRepro: job.repro,
      initialForSeamlessAacConcatenation: job.forSeamlessAacConcatenation,
      defaulMetadata: job.metadata,
      renderTypeOfLastRender: "video",
      initialHardwareAcceleration: job.hardwareAcceleration,
      initialChromeMode: job.chromeMode,
      initialMediaCacheSizeInBytes: job.mediaCacheSizeInBytes,
      renderDefaults: defaults
    };
  }
  throw new Error(`Job ${JSON.stringify(job)} Not implemented`);
};
var makeClientRetryPayload = (job) => {
  return {
    type: "web-render",
    compositionId: job.compositionId,
    initialFrame: job.type === "client-still" ? job.frame : 0,
    initialLogLevel: job.logLevel,
    initialLicenseKey: job.licenseKey,
    defaultProps: job.inputProps,
    inFrameMark: job.type === "client-video" ? job.startFrame : null,
    outFrameMark: job.type === "client-video" ? job.endFrame : null,
    initialDefaultOutName: job.outName,
    initialScale: job.scale,
    initialDelayRenderTimeout: job.delayRenderTimeout,
    initialMediaCacheSizeInBytes: job.mediaCacheSizeInBytes,
    initialAudioBitrate: job.type === "client-video" ? job.audioBitrate : null,
    initialAudioCodec: job.type === "client-video" ? job.audioCodec : null,
    initialContainer: job.type === "client-video" ? job.container : null,
    initialHardwareAcceleration: job.type === "client-video" ? job.hardwareAcceleration : null,
    initialVideoBitrate: job.type === "client-video" ? job.videoBitrate : null,
    initialVideoCodec: job.type === "client-video" ? job.videoCodec : null,
    initialStillImageFormat: job.type === "client-still" ? job.imageFormat : "png",
    initialKeyframeIntervalInSeconds: job.type === "client-video" ? job.keyframeIntervalInSeconds : null,
    initialMuted: job.type === "client-video" ? job.muted : null,
    initialTransparent: job.type === "client-video" ? job.transparent : null
  };
};

// src/components/RenderQueue/RenderQueueRepeat.tsx

var RenderQueueRepeatItem = ({ job }) => {
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const isMobileLayout = useMobileLayout();
  const { setSidebarCollapsedState } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SidebarContext);
  const isClientJob = isClientRenderJob(job);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.stopPropagation();
    if (isClientJob) {
      const retryPayload = makeClientRetryPayload(job);
      setSelectedModal(retryPayload);
    } else {
      const retryPayload = makeRetryPayload(job);
      setSelectedModal(retryPayload);
    }
    if (isMobileLayout) {
      setSidebarCollapsedState({ left: "collapsed", right: "collapsed" });
    }
  }, [
    isMobileLayout,
    job,
    isClientJob,
    setSelectedModal,
    setSidebarCollapsedState
  ]);
  const icon5 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      height: 12,
      color: "currentColor"
    };
  }, []);
  const renderAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      style: icon5,
      viewBox: "0 0 512 512",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        fill: color,
        d: "M386.3 160H336c-17.7 0-32 14.3-32 32s14.3 32 32 32H464c17.7 0 32-14.3 32-32V64c0-17.7-14.3-32-32-32s-32 14.3-32 32v51.2L414.4 97.6c-87.5-87.5-229.3-87.5-316.8 0s-87.5 229.3 0 316.8s229.3 87.5 316.8 0c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0c-62.5 62.5-163.8 62.5-226.3 0s-62.5-163.8 0-226.3s163.8-62.5 226.3 0L386.3 160z"
      })
    });
  }, [icon5]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
    onClick,
    renderAction
  });
};

// src/components/RenderQueue/RenderQueueSavingMessage.tsx

var savingStyle = {
  ...renderQueueItemSubtitleStyle,
  cursor: "default"
};
var RenderQueueSavingMessage = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
    style: savingStyle,
    children: "Saving to out/..."
  });
};

// src/components/RenderQueue/RenderQueueItem.tsx

var container32 = {
  padding: 12,
  display: "flex",
  flexDirection: "row",
  paddingBottom: 10,
  paddingRight: 4
};
var title4 = {
  fontSize: 13,
  lineHeight: 1
};
var right = {
  flex: 1,
  display: "flex",
  flexDirection: "column",
  overflow: "hidden"
};
var subtitle3 = {
  maxWidth: "100%",
  flex: 1,
  display: "flex",
  overflow: "hidden"
};
var SELECTED_CLASSNAME = "__remotion_selected_classname";
var RenderQueueItem = ({ job, selected }) => {
  const [hovered, setHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const { setCanvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionSetters);
  const isClientJob = isClientRenderJob(job);
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(true);
  }, []);
  const onPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(false);
  }, []);
  const isHoverable = job.status === "done" && (isClientJob || job.type !== "sequence");
  const containerStyle3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...container32,
      backgroundColor: getBackgroundFromHoverState({
        hovered: isHoverable && hovered,
        selected
      }),
      userSelect: "none",
      WebkitUserSelect: "none"
    };
  }, [hovered, isHoverable, selected]);
  const scrollCurrentIntoView = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    document.querySelector(`.${SELECTED_CLASSNAME}`)?.scrollIntoView({ behavior: "smooth" });
  }, []);
  const clientBlobInfo = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!isClientJob || job.status !== "done" || !job.getBlob) {
      return null;
    }
    return {
      getBlob: job.getBlob,
      width: job.metadata.width,
      height: job.metadata.height,
      sizeInBytes: job.metadata.sizeInBytes
    };
  }, [isClientJob, job]);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (job.status !== "done") {
      return;
    }
    if (!isClientJob && job.type === "sequence") {
      return;
    }
    if (clientBlobInfo) {
      setCanvasContent((c) => {
        const isAlreadySelected = c && c.type === "output-blob" && c.displayName === job.outName;
        if (isAlreadySelected && !selected) {
          scrollCurrentIntoView();
          return c;
        }
        return {
          type: "output-blob",
          displayName: job.outName,
          getBlob: clientBlobInfo.getBlob,
          width: clientBlobInfo.width,
          height: clientBlobInfo.height,
          sizeInBytes: clientBlobInfo.sizeInBytes
        };
      });
      return;
    }
    setCanvasContent((c) => {
      const isAlreadySelected = c && c.type === "output" && c.path === `/${job.outName}`;
      if (isAlreadySelected && !selected) {
        scrollCurrentIntoView();
        return c;
      }
      return { type: "output", path: `/${job.outName}` };
    });
    pushUrl(`/outputs/${job.outName}`);
  }, [
    job,
    isClientJob,
    clientBlobInfo,
    scrollCurrentIntoView,
    selected,
    setCanvasContent
  ]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (selected) {
      scrollCurrentIntoView();
    }
  }, [scrollCurrentIntoView, selected]);
  const canCopyToClipboard = job.status === "done" && !isClientJob && supportsCopyingToClipboard(job);
  const canRepeat = (job.status === "done" || job.status === "failed" || job.status === "cancelled") && !(isClientRenderJob(job) && isRestoredClientJob(job));
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
    onPointerEnter,
    onPointerLeave,
    style: containerStyle3,
    align: "center",
    onClick,
    className: selected ? SELECTED_CLASSNAME : undefined,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueueItemStatus, {
        job
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: right,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: title4,
            children: job.compositionId
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: subtitle3,
            children: job.status === "done" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueueOutputName, {
              job
            }) : job.status === "failed" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueueError, {
              job
            }) : job.status === "running" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueueProgressMessage, {
              job
            }) : job.status === "saving" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueueSavingMessage, {}) : job.status === "cancelled" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueueCancelledMessage, {}) : null
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 1
      }),
      canCopyToClipboard ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueueCopyToClipboard, {
        job
      }) : null,
      canRepeat ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueueRepeatItem, {
        job
      }) : null,
      job.status === "running" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueueCancelButton, {
        job
      }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueueRemoveItem, {
        job
      }),
      job.status === "done" ? clientBlobInfo ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueueDownloadItem, {
        job
      }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueueOpenInFinderItem, {
        job
      }) : null
    ]
  });
};

// src/components/RenderQueue/index.tsx

var separatorStyle = {
  borderBottom: `1px solid ${BORDER_COLOR}`
};
var errorExplanation3 = {
  fontSize: 14,
  color: LIGHT_TEXT,
  fontFamily: "sans-serif",
  lineHeight: 1.5
};
var explainer4 = {
  display: "flex",
  flex: 1,
  flexDirection: "column",
  padding: "0 12px",
  justifyContent: "center",
  alignItems: "center",
  textAlign: "center",
  background: BACKGROUND
};
var renderQueue = {
  background: BACKGROUND,
  flex: 1,
  overflowY: "auto"
};
var RenderQueue = () => {
  const connectionStatus = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx).previewServerState.type;
  const { jobs } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(RenderQueueContext);
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const previousJobCount = react__WEBPACK_IMPORTED_MODULE_0__.useRef(jobs.length);
  const jobCount = jobs.length;
  const divRef = react__WEBPACK_IMPORTED_MODULE_0__.useRef(null);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!divRef.current) {
      return;
    }
    if (jobCount > previousJobCount.current) {
      divRef.current.scrollTo({
        top: divRef.current.scrollHeight,
        behavior: "smooth"
      });
    }
    previousJobCount.current = jobCount;
  }, [jobCount]);
  const selectedJob = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!canvasContent) {
      return -1;
    }
    if (canvasContent.type === "output") {
      for (let i = 0;i < jobs.length; i++) {
        const job = jobs[i];
        if (job.status === "done" && canvasContent.path === `/${job.outName}`) {
          return i;
        }
      }
    }
    return -1;
  }, [canvasContent, jobs]);
  if (connectionStatus === "disconnected" && !SHOW_BROWSER_RENDERING) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
      style: explainer4,
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
          y: 5
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: errorExplanation3,
          children: "The studio server has disconnected."
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
          y: 2,
          block: true
        })
      ]
    });
  }
  if (jobCount === 0) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
      style: explainer4,
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
          y: 5
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: errorExplanation3,
          children: "No renders in the queue."
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
          y: 2,
          block: true
        })
      ]
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    ref: divRef,
    style: renderQueue,
    className: ["css-reset", VERTICAL_SCROLLBAR_CLASSNAME].join(" "),
    children: jobs.map((j, index) => {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: index === jobs.length - 1 ? undefined : separatorStyle,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueueItem, {
          selected: selectedJob === index,
          job: j
        })
      }, j.id);
    })
  });
};

// src/components/RendersTab.tsx



var row4 = {
  display: "flex",
  flexDirection: "row",
  fontSize: 14,
  color: "inherit",
  alignItems: "center",
  flex: 1
};
var badge = {
  height: 16,
  width: 16,
  borderRadius: 3,
  fontSize: 10,
  display: "inline-flex",
  justifyContent: "center",
  alignItems: "center"
};
var RendersTab = ({ selected, onClick }) => {
  const { jobs } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(RenderQueueContext);
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const failedJobs = jobs.filter((j) => j.status === "failed").length;
  const jobCount = jobs.length;
  const isActuallySelected = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!canvasContent || canvasContent.type !== "composition") {
      return true;
    }
    return selected;
  }, [canvasContent, selected]);
  const badgeStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...badge,
      backgroundColor: failedJobs > 0 ? FAIL_COLOR : "transparent",
      color: failedJobs > 0 ? "white" : LIGHT_TEXT,
      borderWidth: failedJobs > 0 ? 0 : 1,
      borderStyle: "solid",
      borderColor: LIGHT_TEXT
    };
  }, [failedJobs]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Tab, {
    selected: isActuallySelected,
    onClick,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
      style: row4,
      children: [
        "Renders",
        jobCount > 0 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
          children: [
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {}),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              style: badgeStyle,
              children: jobCount
            })
          ]
        }) : null
      ]
    })
  });
};

// src/components/VisualControls/VisualControlsContent.tsx


// src/components/VisualControls/VisualControlHandle.tsx



// src/components/VisualControls/get-original-stack-trace.ts


// src/components/Timeline/TimelineStack/get-stack.ts


// src/helpers/get-location-of-sequence.ts
var getLocationOfSequence = (stack2) => {
  if (!stack2) {
    return null;
  }
  const parsed = parseStack(stack2.split(`
`));
  let i = 0;
  while (i < parsed.length) {
    const frame2 = parsed[i];
    if (frame2.functionName === "apply") {
      i++;
      continue;
    }
    return frame2;
  }
  return null;
};
var getLocationOfFunctionCall = (stack2, functionName) => {
  if (!stack2) {
    return null;
  }
  const parsed = parseStack(stack2.split(`
`));
  let i = 0;
  while (i < parsed.length) {
    const frame2 = parsed[i];
    if (frame2.functionName !== functionName) {
      i++;
      continue;
    }
    return parsed[i + 1];
  }
  return null;
};

// src/components/Timeline/TimelineStack/get-stack.ts
var waiters = [];
var sourceMapConsumerCache = {};
var isCreating = {};
var getSourceMapCache = async (fileName) => {
  if (sourceMapConsumerCache[fileName]) {
    return sourceMapConsumerCache[fileName];
  }
  if (isCreating[fileName]) {
    return new Promise((resolve) => {
      waiters.push({
        id: String(Math.random()),
        forFileName: fileName,
        resolve
      });
    });
  }
  isCreating[fileName] = true;
  const res = await fetch(`${fileName}.map`);
  const json = await res.json();
  const map = await new Promise((resolve) => {
    source_map__WEBPACK_IMPORTED_MODULE_11__.SourceMapConsumer.with(json, null, (consumer) => {
      resolve(consumer);
    });
  });
  waiters.filter((w) => {
    if (w.forFileName === fileName) {
      w.resolve(map);
      return false;
    }
    return true;
  });
  sourceMapConsumerCache[fileName] = map;
  isCreating[fileName] = false;
  return map;
};
var getOriginalLocationFromStack = async (stack2, type) => {
  const location2 = type === "sequence" ? getLocationOfSequence(stack2) : getLocationOfFunctionCall(stack2, "visualControl");
  if (!location2) {
    return null;
  }
  const map = await getSourceMapCache(location2.fileName);
  const originalPosition = getOriginalPosition(map, location2.lineNumber, location2.columnNumber);
  return originalPosition;
};

// src/components/VisualControls/get-original-stack-trace.ts
var useOriginalFileName = (stack2) => {
  const [originalFileName, setOriginalFileName] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({ type: "loading" });
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!stack2) {
      return;
    }
    getOriginalLocationFromStack(stack2, "visual-control").then((frame2) => {
      if (frame2 === null) {
        setOriginalFileName({
          type: "error",
          error: new Error("No frame found")
        });
      } else {
        setOriginalFileName({ type: "loaded", originalFileName: frame2 });
      }
    }).catch((err) => {
      console.error("Could not get original location of Sequence", err);
    });
  }, [stack2]);
  return originalFileName;
};

// src/components/VisualControls/ClickableFileName.tsx


// src/components/Timeline/TimelineStack/source-attribution.ts
var getOriginalSourceAttribution = (originalLocation) => {
  if (!originalLocation.source) {
    return "";
  }
  const split = originalLocation.source.split("/");
  const last = split[split.length - 1];
  if (last.startsWith("index")) {
    const lastTwo = split[split.length - 2];
    return `${lastTwo}/${last}:${originalLocation.line}`;
  }
  return `${last}:${originalLocation.line}`;
};

// src/components/VisualControls/ClickableFileName.tsx

var container33 = {
  paddingLeft: SCHEMA_EDITOR_FIELDSET_PADDING,
  paddingTop: SCHEMA_EDITOR_FIELDSET_PADDING / 2
};
var ClickableFileName = ({
  originalFileName
}) => {
  const [titleHovered, setTitleHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const hoverEffect = titleHovered && originalFileName.type === "loaded";
  const onTitlePointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setTitleHovered(true);
  }, []);
  const onTitlePointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setTitleHovered(false);
  }, []);
  const style9 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      fontSize: 12,
      cursor: originalFileName.type === "loaded" ? "pointer" : undefined,
      borderBottom: hoverEffect ? "1px solid #fff" : "none",
      color: hoverEffect ? "#fff" : LIGHT_COLOR
    };
  }, [originalFileName, hoverEffect]);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(async () => {
    if (originalFileName.type !== "loaded") {
      return;
    }
    await openOriginalPositionInEditor(originalFileName.originalFileName);
  }, [originalFileName]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: container33,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
      style: style9,
      onClick,
      onPointerEnter: onTitlePointerEnter,
      onPointerLeave: onTitlePointerLeave,
      children: originalFileName.type === "loaded" ? getOriginalSourceAttribution(originalFileName.originalFileName) : originalFileName.type === "loading" ? "Loading..." : "Error loading"
    })
  });
};

// src/components/VisualControls/VisualControlHandleHeader.tsx

var VisualControlHandleHeader = ({ originalFileName }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ClickableFileName, {
    originalFileName
  });
};

// src/components/VisualControls/VisualControlHandle.tsx

var VisualControlHandle = ({ value, keyName }) => {
  const z = useZodIfPossible();
  if (!z) {
    throw new Error("expected zod");
  }
  const zodTypes = useZodTypesIfPossible();
  const state = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(VisualControlsContext);
  const { updateValue } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SetVisualControlsContext);
  const { fastRefreshes, increaseManualRefreshes } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(FastRefreshContext);
  const [saving, setSaving] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const currentValue = getVisualControlEditedValue({
    handles: state.handles,
    key: keyName
  });
  const originalFileName = useOriginalFileName(value.stack);
  const { localValue, RevisionContextProvider, onChange } = useLocalState({
    schema: value.schema,
    setValue: (updater) => {
      updateValue(keyName, updater(currentValue));
      increaseManualRefreshes();
    },
    unsavedValue: currentValue,
    savedValue: value.valueInCode
  });
  const disableSave = window.remotion_isReadOnlyStudio || originalFileName.type !== "loaded";
  const onSave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((updater) => {
    if (disableSave) {
      return;
    }
    if (originalFileName.type !== "loaded") {
      throw new Error("Original file name is not loaded");
    }
    const val = updater(value.valueInCode);
    window.remotion_ignoreFastRefreshUpdate = fastRefreshes + 1;
    const enumPaths = extractEnumJsonPaths({
      schema: value.schema,
      zodRuntime: z,
      currentPath: [],
      zodTypes
    });
    setSaving(true);
    Promise.resolve().then(() => {
      return applyVisualControlChange({
        fileName: originalFileName.originalFileName.source,
        changes: [
          {
            id: keyName,
            newValueSerialized: remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.serializeJSONWithSpecialTypes({
              data: val,
              indent: 2,
              staticBase: window.remotion_staticBase
            }).serializedString,
            enumPaths
          }
        ]
      });
    }).catch((e) => {
      showNotification(`Could not save visual control: ${e.message}`, 3000);
    });
  }, [
    disableSave,
    value.valueInCode,
    value.schema,
    fastRefreshes,
    z,
    originalFileName,
    keyName,
    zodTypes
  ]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    setSaving(false);
  }, [fastRefreshes]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(VisualControlHandleHeader, {
        originalFileName
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        block: true,
        y: 0.5
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RevisionContextProvider, {
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodSwitch, {
          mayPad: true,
          schema: value.schema,
          showSaveButton: !disableSave,
          saving,
          saveDisabledByParent: false,
          onSave,
          jsonPath: [keyName],
          value: localValue.value,
          defaultValue: value.valueInCode,
          setValue: onChange,
          onRemove: null
        })
      })
    ]
  });
};

// src/components/VisualControls/VisualControlsContent.tsx

var container34 = {
  overflowY: "auto"
};
var VisualControlsContent = () => {
  const { handles } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(VisualControlsContext);
  const entries = Object.entries(handles);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: container34,
    className: VERTICAL_SCROLLBAR_CLASSNAME,
    children: entries.map(([key, value], i) => {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(VisualControlHandle, {
            keyName: key,
            value
          }),
          i === entries.length - 1 ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SchemaSeparationLine, {})
        ]
      }, key);
    })
  });
};

// src/components/OptionsPanel.tsx

var localStorageKey3 = "remotion.sidebarPanel";
var getSelectedPanel2 = (renderingAvailable) => {
  if (!renderingAvailable) {
    return "input-props";
  }
  const panel2 = localStorage.getItem(localStorageKey3);
  if (panel2 === "renders") {
    return "renders";
  }
  if (panel2 === "visual-controls") {
    return "visual-controls";
  }
  return "input-props";
};
var tabsContainer3 = {
  backgroundColor: BACKGROUND
};
var persistSelectedOptionsSidebarPanel2 = (panel2) => {
  localStorage.setItem(localStorageKey3, panel2);
};
var optionsSidebarTabs = (0,react__WEBPACK_IMPORTED_MODULE_0__.createRef)();
var OptionsPanel = ({ readOnlyStudio }) => {
  const { props, updateProps, resetUnsaved } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.EditorPropsContext);
  const [saving, setSaving] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const renderingAvailable = !readOnlyStudio || SHOW_BROWSER_RENDERING;
  const isMobileLayout = useMobileLayout();
  const visualControlsTabActivated = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(VisualControlsTabActivatedContext);
  const container35 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => ({
    height: "100%",
    width: "100%",
    display: "flex",
    position: isMobileLayout ? "relative" : "absolute",
    flexDirection: "column",
    flex: 1
  }), [isMobileLayout]);
  const [panel2, setPanel] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => getSelectedPanel2(renderingAvailable));
  const onPropsSelected = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setPanel("input-props");
    persistSelectedOptionsSidebarPanel2("input-props");
  }, []);
  const onRendersSelected = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setPanel("renders");
    persistSelectedOptionsSidebarPanel2("renders");
  }, []);
  const onVisualControlsSelected = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setPanel("visual-controls");
    persistSelectedOptionsSidebarPanel2("visual-controls");
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(optionsSidebarTabs, () => {
    return {
      selectRendersPanel: () => {
        setPanel("renders");
        persistSelectedOptionsSidebarPanel2("renders");
      }
    };
  }, []);
  const { compositions, canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const composition = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (canvasContent === null || canvasContent.type !== "composition") {
      return null;
    }
    for (const comp of compositions) {
      if (comp.id === canvasContent.compositionId) {
        return comp;
      }
    }
    return null;
  }, [canvasContent, compositions]);
  const setDefaultProps = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newProps) => {
    if (composition === null) {
      return;
    }
    window.remotion_ignoreFastRefreshUpdate = null;
    updateProps({
      id: composition.id,
      defaultProps: composition.defaultProps,
      newProps
    });
  }, [composition, updateProps]);
  const currentDefaultProps = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (composition === null) {
      return {};
    }
    return props[composition.id] ?? composition.defaultProps ?? {};
  }, [composition, props]);
  const unsavedChangesExist = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (composition === null || composition.defaultProps === undefined) {
      return false;
    }
    return !deepEqual(composition.defaultProps, currentDefaultProps);
  }, [currentDefaultProps, composition]);
  const reset = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (e.detail.resetUnsaved) {
      resetUnsaved(e.detail.resetUnsaved);
    }
  }, [resetUnsaved]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    window.addEventListener(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.PROPS_UPDATED_EXTERNALLY, reset);
    return () => {
      window.removeEventListener(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.PROPS_UPDATED_EXTERNALLY, reset);
    };
  }, [reset]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container35,
    className: "css-reset",
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: tabsContainer3,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Tabs, {
          children: [
            visualControlsTabActivated ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Tab, {
              selected: panel2 === "visual-controls",
              onClick: onVisualControlsSelected,
              children: "Controls"
            }) : null,
            composition ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Tab, {
              selected: panel2 === "input-props",
              onClick: onPropsSelected,
              style: { justifyContent: "space-between" },
              children: [
                "Props",
                unsavedChangesExist ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(GlobalPropsEditorUpdateButton, {
                  compositionId: composition.id,
                  currentDefaultProps
                }) : null
              ]
            }) : null,
            renderingAvailable ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RendersTab, {
              onClick: onRendersSelected,
              selected: panel2 === "renders"
            }) : null
          ]
        })
      }),
      panel2 === `input-props` && composition ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DataEditor, {
        unresolvedComposition: composition,
        defaultProps: currentDefaultProps,
        setDefaultProps,
        mayShowSaveButton: true,
        propsEditType: "default-props",
        saving,
        setSaving,
        readOnlyStudio
      }, composition.id) : panel2 === "visual-controls" && visualControlsTabActivated ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(VisualControlsContent, {}) : !renderingAvailable ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueue, {})
    ]
  });
};

// src/components/PreviewToolbar.tsx



// src/helpers/should-show-render-button.ts
var shouldShowRenderButton = (readOnlyStudio) => {
  if (readOnlyStudio) {
    return SHOW_BROWSER_RENDERING;
  }
  return true;
};

// src/state/loop.ts
var key = "remotion.loop";
var persistLoopOption = (option) => {
  localStorage.setItem(key, String(option));
};
var loadLoopOption = () => {
  const item2 = localStorage.getItem(key);
  return item2 !== "false";
};

// src/components/CheckboardToggle.tsx



var accessibilityLabel2 = [
  "Show transparency as checkerboard",
  areKeyboardShortcutsDisabled() ? null : "(T)"
].filter(remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.truthy).join(" ");
var CheckboardToggle = () => {
  const { checkerboard, setCheckerboard } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(CheckerboardContext);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setCheckerboard((c) => {
      return !c;
    });
  }, [setCheckerboard]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ControlButton, {
    title: accessibilityLabel2,
    "aria-label": accessibilityLabel2,
    onClick,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      "aria-hidden": "true",
      focusable: "false",
      "data-prefix": "fas",
      "data-icon": "game-board-alt",
      className: "svg-inline--fa fa-game-board-alt fa-w-16",
      role: "img",
      xmlns: "http://www.w3.org/2000/svg",
      viewBox: "0 0 512 512",
      style: { width: 16, height: 16 },
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        fill: checkerboard ? BLUE : "white",
        d: "M480 0H32A32 32 0 0 0 0 32v448a32 32 0 0 0 32 32h448a32 32 0 0 0 32-32V32a32 32 0 0 0-32-32zm-32 256H256v192H64V256h192V64h192z"
      })
    })
  });
};

// src/components/FpsCounter.tsx



var label6 = {
  color: "white",
  fontSize: 15,
  fontFamily: "Arial, Helvetica, sans-serif",
  whiteSpace: "nowrap"
};
var pushWithMaxSize = (arr, value, maxSize) => {
  arr.push(value);
  return arr.slice(-maxSize);
};
var FpsCounter = ({ playbackSpeed }) => {
  const videoConfig = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useUnsafeVideoConfig();
  const [playing] = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.Timeline.usePlayingState();
  const frame2 = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.Timeline.useTimelinePosition();
  const [marker, rerender] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({});
  const [fps, setFps] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(0);
  const previousUpdates = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)([]);
  const fpsRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(0);
  const playingRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(playing);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useLayoutEffect)(() => {
    fpsRef.current = 0;
    previousUpdates.current = [];
    playingRef.current = playing;
  }, [playing]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useLayoutEffect)(() => {
    if (playingRef.current === false)
      return;
    previousUpdates.current = pushWithMaxSize(previousUpdates.current, performance.now(), 15);
    if (previousUpdates.current.length < 2)
      return;
    const diff = Math.max(...previousUpdates.current) - Math.min(...previousUpdates.current);
    const averageDistanceBetween = diff / (previousUpdates.current.length - 1);
    fpsRef.current = 1000 / averageDistanceBetween;
    if (previousUpdates.current.length === 2)
      setFps(fpsRef.current);
  }, [frame2]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (playing) {
      const t = setTimeout(() => {
        rerender({});
        setFps(fpsRef.current);
      }, 1000);
      return () => clearTimeout(t);
    }
  }, [marker, playing]);
  const style9 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!videoConfig) {
      return {};
    }
    const expectedFps = Math.abs(playbackSpeed) * videoConfig.fps;
    return {
      ...label6,
      color: fps < expectedFps * 0.9 ? "red" : "white"
    };
  }, [fps, playbackSpeed, videoConfig]);
  if (fps === 0) {
    return null;
  }
  if (playing === false) {
    return null;
  }
  if (videoConfig === null) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: style9,
    children: [
      fps.toFixed(1),
      " FPS"
    ]
  });
};

// src/components/FullscreenToggle.tsx




var accessibilityLabel3 = [
  "Enter fullscreen preview",
  areKeyboardShortcutsDisabled() ? null : "(F)"
].filter(remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.truthy).join(" ");
var FullScreenToggle = () => {
  const keybindings = useKeybinding();
  const { setSize } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.PreviewSizeContext);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    drawRef.current?.requestFullscreen();
    if (document.fullscreenElement)
      setSize(() => ({
        size: "auto",
        translation: {
          x: 0,
          y: 0
        }
      }));
  }, [setSize]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const f = keybindings.registerKeybinding({
      event: "keydown",
      key: "f",
      callback: onClick,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      f.unregister();
    };
  }, [keybindings, onClick]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ControlButton, {
    title: accessibilityLabel3,
    "aria-label": accessibilityLabel3,
    onClick,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      style: { width: 18, height: 18 },
      viewBox: "0 0 448 512",
      fill: "#fff",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        d: "M0 180V56c0-13.3 10.7-24 24-24h124c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12H64v84c0 6.6-5.4 12-12 12H12c-6.6 0-12-5.4-12-12zM288 44v40c0 6.6 5.4 12 12 12h84v84c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12V56c0-13.3-10.7-24-24-24H300c-6.6 0-12 5.4-12 12zm148 276h-40c-6.6 0-12 5.4-12 12v84h-84c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h124c13.3 0 24-10.7 24-24V332c0-6.6-5.4-12-12-12zM160 468v-40c0-6.6-5.4-12-12-12H64v-84c0-6.6-5.4-12-12-12H12c-6.6 0-12 5.4-12 12v124c0 13.3 10.7 24 24 24h124c6.6 0 12-5.4 12-12z"
      })
    })
  });
};

// src/components/LoopToggle.tsx


var accessibilityLabel4 = "Loop video";
var LoopToggle = ({ loop, setLoop }) => {
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setLoop((c) => {
      persistLoopOption(!c);
      return !c;
    });
  }, [setLoop]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ControlButton, {
    title: accessibilityLabel4,
    "aria-label": accessibilityLabel4,
    onClick,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      viewBox: "0 0 512 512",
      style: { width: 18, height: 18 },
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        fill: loop ? BLUE : "white",
        d: "M493.544 181.463c11.956 22.605 18.655 48.4 18.452 75.75C511.339 345.365 438.56 416 350.404 416H192v47.495c0 22.475-26.177 32.268-40.971 17.475l-80-80c-9.372-9.373-9.372-24.569 0-33.941l80-80C166.138 271.92 192 282.686 192 304v48h158.875c52.812 0 96.575-42.182 97.12-94.992.155-15.045-3.17-29.312-9.218-42.046-4.362-9.185-2.421-20.124 4.8-27.284 4.745-4.706 8.641-8.555 11.876-11.786 11.368-11.352 30.579-8.631 38.091 5.571zM64.005 254.992c.545-52.81 44.308-94.992 97.12-94.992H320v47.505c0 22.374 26.121 32.312 40.971 17.465l80-80c9.372-9.373 9.372-24.569 0-33.941l-80-80C346.014 16.077 320 26.256 320 48.545V96H161.596C73.44 96 .661 166.635.005 254.788c-.204 27.35 6.495 53.145 18.452 75.75 7.512 14.202 26.723 16.923 38.091 5.57 3.235-3.231 7.13-7.08 11.876-11.786 7.22-7.16 9.162-18.098 4.8-27.284-6.049-12.735-9.374-27.001-9.219-42.046z"
      })
    })
  });
};

// src/components/MuteToggle.tsx


// src/icons/media-volume.tsx

var size3 = 22;
var VolumeOffIcon = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    width: size3,
    height: size3,
    viewBox: "0 0 24 24",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      d: "M3.63 3.63a.996.996 0 000 1.41L7.29 8.7 7 9H4c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h3l3.29 3.29c.63.63 1.71.18 1.71-.71v-4.17l4.18 4.18c-.49.37-1.02.68-1.6.91-.36.15-.58.53-.58.92 0 .72.73 1.18 1.39.91.8-.33 1.55-.77 2.22-1.31l1.34 1.34a.996.996 0 101.41-1.41L5.05 3.63c-.39-.39-1.02-.39-1.42 0zM19 12c0 .82-.15 1.61-.41 2.34l1.53 1.53c.56-1.17.88-2.48.88-3.87 0-3.83-2.4-7.11-5.78-8.4-.59-.23-1.22.23-1.22.86v.19c0 .38.25.71.61.85C17.18 6.54 19 9.06 19 12zm-8.71-6.29l-.17.17L12 7.76V6.41c0-.89-1.08-1.33-1.71-.7zM16.5 12A4.5 4.5 0 0014 7.97v1.79l2.48 2.48c.01-.08.02-.16.02-.24z",
      fill: BLUE
    })
  });
};
var VolumeOnIcon = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    width: size3,
    height: size3,
    viewBox: "0 0 24 24",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      d: "M3 10v4c0 .55.45 1 1 1h3l3.29 3.29c.63.63 1.71.18 1.71-.71V6.41c0-.89-1.08-1.34-1.71-.71L7 9H4c-.55 0-1 .45-1 1zm13.5 2A4.5 4.5 0 0014 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 4.45v.2c0 .38.25.71.6.85C17.18 6.53 19 9.06 19 12s-1.82 5.47-4.4 6.5c-.36.14-.6.47-.6.85v.2c0 .63.63 1.07 1.21.85C18.6 19.11 21 15.84 21 12s-2.4-7.11-5.79-8.4c-.58-.23-1.21.22-1.21.85z",
      fill: "#fff"
    })
  });
};

// src/state/mute.ts
var key2 = "remotion.mute";
var persistMuteOption = (option) => {
  localStorage.setItem(key2, String(option));
};
var loadMuteOption = () => {
  const item2 = localStorage.getItem(key2);
  return item2 === "true";
};

// src/components/MuteToggle.tsx

var MuteToggle = ({ muted, setMuted }) => {
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setMuted((m) => {
      persistMuteOption(!m);
      return !m;
    });
  }, [setMuted]);
  const accessibilityLabel5 = muted ? "Unmute video" : "Mute video";
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ControlButton, {
    title: accessibilityLabel5,
    "aria-label": accessibilityLabel5,
    onClick,
    children: muted ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(VolumeOffIcon, {}) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(VolumeOnIcon, {})
  });
};

// src/components/PlaybackKeyboardShortcutsManager.tsx


var PlaybackKeyboardShortcutsManager = ({ setPlaybackRate }) => {
  const keybindings = useKeybinding();
  const { play, pause, playing } = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.usePlayer();
  const onJKey = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setPlaybackRate((prevPlaybackRate) => {
      if (!playing) {
        return -1;
      }
      if (prevPlaybackRate > -1) {
        return -1;
      }
      if (prevPlaybackRate > -2) {
        return -2;
      }
      return -4;
    });
    play();
  }, [play, playing, setPlaybackRate]);
  const onKKey = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setPlaybackRate(1);
    pause();
  }, [pause, setPlaybackRate]);
  const onLKey = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setPlaybackRate((prevPlaybackRate) => {
      if (!playing) {
        return 1;
      }
      if (prevPlaybackRate < 1) {
        return 1;
      }
      if (prevPlaybackRate < 2) {
        return 2;
      }
      return 4;
    });
    play();
  }, [play, playing, setPlaybackRate]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const jKey = keybindings.registerKeybinding({
      event: "keydown",
      key: "j",
      callback: onJKey,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const kKey = keybindings.registerKeybinding({
      event: "keydown",
      key: "k",
      callback: onKKey,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const lKey = keybindings.registerKeybinding({
      event: "keydown",
      key: "l",
      callback: onLKey,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      jKey.unregister();
      kKey.unregister();
      lKey.unregister();
    };
  }, [keybindings, onJKey, onKKey, onLKey]);
  return null;
};

// src/components/PlaybackRatePersistor.tsx



// src/state/playbackrate.ts
var key3 = "remotion.playbackrate";
var persistPlaybackRate = (option) => {
  localStorage.setItem(key3, String(option));
};
var loadPlaybackRate = () => {
  if (typeof window !== "undefined") {
    return 1;
  }
  const item2 = localStorage.getItem(key3);
  if (item2 === null) {
    return 1;
  }
  return Number(item2);
};

// src/components/PlaybackRatePersistor.tsx
var PlaybackRatePersistor = () => {
  const { setPlaybackRate, playbackRate } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.TimelineContext);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    setPlaybackRate(loadPlaybackRate());
  }, [setPlaybackRate]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    persistPlaybackRate(playbackRate);
  }, [playbackRate]);
  return null;
};

// src/components/PlaybackRateSelector.tsx



var commonPlaybackRates = [
  -4,
  -2,
  -1,
  -0.5,
  -0.25,
  0.25,
  0.5,
  1,
  1.5,
  2,
  4
];
var getPlaybackRateLabel = (playbackRate) => {
  return `${playbackRate}x`;
};
var accessibilityLabel5 = "Change the playback rate";
var comboStyle2 = { width: 80 };
var PlaybackRateSelector = ({ playbackRate, setPlaybackRate }) => {
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const isStill = useIsStill();
  const style9 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      padding: CONTROL_BUTTON_PADDING
    };
  }, []);
  const items = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const divider = {
      type: "divider",
      id: "divider"
    };
    const values = commonPlaybackRates.map((newPlaybackRate) => {
      return {
        id: String(newPlaybackRate),
        label: getPlaybackRateLabel(newPlaybackRate),
        onClick: () => {
          return setPlaybackRate(() => {
            persistPlaybackRate(newPlaybackRate);
            return newPlaybackRate;
          });
        },
        type: "item",
        value: newPlaybackRate,
        keyHint: null,
        leftItem: String(playbackRate) === String(newPlaybackRate) ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        subMenu: null,
        quickSwitcherLabel: null
      };
    });
    const middle = Math.floor(commonPlaybackRates.length / 2);
    return [...values.slice(0, middle), divider, ...values.slice(middle)];
  }, [playbackRate, setPlaybackRate]);
  if (isStill || canvasContent === null || canvasContent.type === "asset") {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: style9,
    "aria-label": accessibilityLabel5,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
      title: accessibilityLabel5,
      style: comboStyle2,
      selectedId: String(playbackRate),
      values: items
    })
  });
};

// src/components/PlayPause.tsx




// src/icons/jump-to-start.tsx

var JumpToStart = (props) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    xmlns: "http://www.w3.org/2000/svg",
    viewBox: "0 0 512 512",
    ...props,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: "currentColor",
      d: "M0 415.1V96.03c0-17.67 14.33-31.1 31.1-31.1C49.67 64.03 64 78.36 64 96.03v131.8l171.5-156.5C256.1 54.28 288 68.66 288 96.03v131.9l171.5-156.5C480.1 54.28 512 68.66 512 96.03v319.9c0 27.37-31.88 41.74-52.5 24.62L288 285.2v130.7c0 27.37-31.88 41.74-52.5 24.62L64 285.2v130.7c0 17.67-14.33 31.1-31.1 31.1C14.33 447.1 0 433.6 0 415.1z"
    })
  });
};

// src/icons/pause.tsx

var Pause = (props) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
  ...props,
  "aria-hidden": "true",
  focusable: "false",
  "data-prefix": "fas",
  "data-icon": "pause",
  className: "svg-inline--fa fa-pause fa-w-14",
  role: "img",
  xmlns: "http://www.w3.org/2000/svg",
  viewBox: "0 0 448 512",
  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
    fill: "currentColor",
    d: "M144 479H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h96c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zm304-48V79c0-26.5-21.5-48-48-48h-96c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h96c26.5 0 48-21.5 48-48z"
  })
});

// src/icons/play.tsx

var Play = (props) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
  ...props,
  "aria-hidden": "true",
  focusable: "false",
  "data-prefix": "fas",
  "data-icon": "play",
  className: "svg-inline--fa fa-play fa-w-14",
  role: "img",
  xmlns: "http://www.w3.org/2000/svg",
  viewBox: "0 0 448 512",
  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
    fill: "currentColor",
    d: "M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z"
  })
});

// src/icons/step-back.tsx

var StepBack = (props) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    viewBox: "0 0 448 512",
    ...props,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: "currentColor",
      d: "M64 468V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v176.4l195.5-181C352.1 22.3 384 36.6 384 64v384c0 27.4-31.9 41.7-52.5 24.6L136 292.7V468c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12z"
    })
  });
};

// src/icons/step-forward.tsx

var StepForward = (props) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    viewBox: "0 0 448 512",
    ...props,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: "currentColor",
      d: "M384 44v424c0 6.6-5.4 12-12 12h-48c-6.6 0-12-5.4-12-12V291.6l-195.5 181C95.9 489.7 64 475.4 64 448V64c0-27.4 31.9-41.7 52.5-24.6L312 219.3V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12z"
    })
  });
};

// src/components/PlayPause.tsx

var backStyle = {
  height: 18,
  color: "white"
};
var forwardBackStyle = {
  height: 16,
  color: "white"
};
var iconButton = {
  height: 14,
  width: 14,
  color: "white"
};
var PlayPause = ({ playbackRate, loop, bufferStateDelayInMilliseconds }) => {
  const { inFrame, outFrame } = useTimelineInOutFramePosition();
  const videoConfig = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useUnsafeVideoConfig();
  const [showBufferIndicator, setShowBufferState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const {
    playing,
    play,
    pause,
    pauseAndReturnToPlayStart,
    frameBack,
    seek,
    frameForward,
    isLastFrame,
    isFirstFrame,
    emitter,
    getCurrentFrame: getCurrentFrame2
  } = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.usePlayer();
  _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.usePlayback({
    loop,
    playbackRate,
    moveToBeginningWhenEnded: true,
    inFrame,
    outFrame,
    getCurrentFrame: getCurrentFrame2,
    browserMediaControlsBehavior: {
      mode: "register-media-session"
    }
  });
  const isStill = useIsStill();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (isStill) {
      pause();
    }
  }, [isStill, pause]);
  const onSpace = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (playing) {
      pause();
    } else {
      play();
    }
    e.preventDefault();
  }, [pause, play, playing]);
  const onEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (playing) {
      e.preventDefault();
      pauseAndReturnToPlayStart();
    }
  }, [pauseAndReturnToPlayStart, playing]);
  const onArrowLeft = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.preventDefault();
    if (e.altKey) {
      seek(0);
      ensureFrameIsInViewport({
        direction: "fit-left",
        durationInFrames: getCurrentDuration(),
        frame: 0
      });
    } else if (e.shiftKey) {
      frameBack(getCurrentFps());
      ensureFrameIsInViewport({
        direction: "fit-left",
        durationInFrames: getCurrentDuration(),
        frame: Math.max(0, getCurrentFrame2() - getCurrentFps())
      });
    } else {
      frameBack(1);
      ensureFrameIsInViewport({
        direction: "fit-left",
        durationInFrames: getCurrentDuration(),
        frame: Math.max(0, getCurrentFrame2() - 1)
      });
    }
  }, [frameBack, seek, getCurrentFrame2]);
  const onArrowRight = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (e.altKey) {
      seek(getCurrentDuration() - 1);
      ensureFrameIsInViewport({
        direction: "fit-right",
        durationInFrames: getCurrentDuration() - 1,
        frame: getCurrentDuration() - 1
      });
    } else if (e.shiftKey) {
      frameForward(getCurrentFps());
      ensureFrameIsInViewport({
        direction: "fit-right",
        durationInFrames: getCurrentDuration(),
        frame: Math.min(getCurrentDuration() - 1, getCurrentFrame2() + getCurrentFps())
      });
    } else {
      frameForward(1);
      ensureFrameIsInViewport({
        direction: "fit-right",
        durationInFrames: getCurrentDuration(),
        frame: Math.min(getCurrentDuration() - 1, getCurrentFrame2() + 1)
      });
    }
    e.preventDefault();
  }, [frameForward, seek, getCurrentFrame2]);
  const oneFrameBack = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    frameBack(1);
  }, [frameBack]);
  const oneFrameForward = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    frameForward(1);
  }, [frameForward]);
  const jumpToStart = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    seek(inFrame ?? 0);
  }, [seek, inFrame]);
  const jumpToEnd = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    seek(outFrame ?? getCurrentDuration() - 1);
  }, [seek, outFrame]);
  const keybindings = useKeybinding();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const arrowLeft = keybindings.registerKeybinding({
      event: "keydown",
      key: "ArrowLeft",
      callback: onArrowLeft,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const arrowRight = keybindings.registerKeybinding({
      event: "keydown",
      key: "ArrowRight",
      callback: onArrowRight,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const space = keybindings.registerKeybinding({
      event: "keydown",
      key: " ",
      callback: onSpace,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const enter = keybindings.registerKeybinding({
      event: "keydown",
      key: "enter",
      callback: onEnter,
      commandCtrlKey: false,
      preventDefault: false,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const a = keybindings.registerKeybinding({
      event: "keydown",
      key: "a",
      callback: jumpToStart,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const e = keybindings.registerKeybinding({
      event: "keydown",
      key: "e",
      callback: jumpToEnd,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      arrowLeft.unregister();
      arrowRight.unregister();
      space.unregister();
      enter.unregister();
      a.unregister();
      e.unregister();
    };
  }, [
    jumpToEnd,
    jumpToStart,
    keybindings,
    onArrowLeft,
    onArrowRight,
    onEnter,
    onSpace
  ]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    let timeout = null;
    let stopped = false;
    const onBuffer = () => {
      requestAnimationFrame(() => {
        stopped = false;
        timeout = setTimeout(() => {
          if (!stopped) {
            setShowBufferState(true);
          }
        }, bufferStateDelayInMilliseconds);
      });
    };
    const onResume = () => {
      requestAnimationFrame(() => {
        setShowBufferState(false);
        stopped = true;
        if (timeout) {
          clearTimeout(timeout);
        }
      });
    };
    emitter.addEventListener("waiting", onBuffer);
    emitter.addEventListener("resume", onResume);
    return () => {
      emitter.removeEventListener("waiting", onBuffer);
      emitter.removeEventListener("resume", onResume);
      setShowBufferState(false);
      if (timeout) {
        clearTimeout(timeout);
      }
      stopped = true;
    };
  }, [bufferStateDelayInMilliseconds, emitter]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ControlButton, {
        "aria-label": "Jump to beginning",
        title: "Jump to beginning",
        disabled: !videoConfig || isFirstFrame,
        onClick: jumpToStart,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(JumpToStart, {
          style: backStyle
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ControlButton, {
        "aria-label": "Step back one frame",
        title: "Step back one frame",
        disabled: !videoConfig || isFirstFrame,
        onClick: oneFrameBack,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(StepBack, {
          style: forwardBackStyle
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ControlButton, {
        "aria-label": playing ? "Pause" : "Play",
        title: playing ? "Pause" : "Play",
        onClick: playing ? pause : play,
        disabled: !videoConfig,
        children: playing ? showBufferIndicator ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.BufferingIndicator, {
          type: "studio"
        }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Pause, {
          style: iconButton
        }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Play, {
          style: iconButton
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ControlButton, {
        "aria-label": "Step forward one frame",
        title: "Step forward one frame",
        disabled: !videoConfig || isLastFrame,
        onClick: oneFrameForward,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(StepForward, {
          style: forwardBackStyle
        })
      })
    ]
  });
};

// src/components/RenderButton.tsx





var splitButtonContainer = {
  display: "inline-flex",
  flexDirection: "row",
  alignItems: "stretch",
  borderRadius: 4,
  border: `1px solid ${INPUT_BORDER_COLOR_UNHOVERED}`,
  backgroundColor: INPUT_BACKGROUND,
  overflow: "hidden"
};
var mainButtonStyle = {
  paddingLeft: 7,
  paddingRight: 7,
  paddingTop: 7,
  paddingBottom: 7,
  background: "transparent",
  border: "none",
  color: "white",
  cursor: "pointer",
  display: "flex",
  alignItems: "center",
  fontSize: 14,
  fontFamily: "inherit"
};
var dividerStyle = {
  width: 1,
  backgroundColor: INPUT_BORDER_COLOR_UNHOVERED,
  alignSelf: "stretch"
};
var dropdownTriggerStyle = {
  paddingLeft: 6,
  paddingRight: 6,
  paddingTop: 7,
  paddingBottom: 7,
  background: "transparent",
  border: "none",
  color: "white",
  cursor: "pointer",
  display: "flex",
  alignItems: "center"
};
var mainButtonContent = {
  paddingLeft: 4,
  paddingRight: 6
};
var label7 = {
  fontSize: 14
};
var RENDER_TYPE_STORAGE_KEY = "remotion.renderType";
var getInitialRenderType = (readOnlyStudio) => {
  if (!SHOW_BROWSER_RENDERING) {
    return "server-render";
  }
  if (readOnlyStudio) {
    return "client-render";
  }
  try {
    const stored = localStorage.getItem(RENDER_TYPE_STORAGE_KEY);
    if (stored === "server-render" || stored === "client-render") {
      return stored;
    }
  } catch {}
  return "server-render";
};
var RenderButton = ({
  readOnlyStudio
}) => {
  const { inFrame, outFrame } = useTimelineInOutFramePosition();
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const [preferredRenderType, setPreferredRenderType] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => getInitialRenderType(readOnlyStudio));
  const [dropdownOpened, setDropdownOpened] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const dropdownRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const containerRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const { currentZIndex } = useZIndex();
  const size4 = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.useElementSize(dropdownRef, {
    triggerOnWindowResize: true,
    shouldApplyCssTransforms: true
  });
  const refresh = size4?.refresh;
  const onPointerDown = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setDropdownOpened((o) => {
      if (!o) {
        refresh?.();
      }
      return !o;
    });
  }, [refresh]);
  const onClickDropdown = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.stopPropagation();
    const isKeyboardInitiated = e.detail === 0;
    if (!isKeyboardInitiated) {
      return;
    }
    setDropdownOpened((o) => {
      if (!o) {
        refresh?.();
        window.addEventListener("pointerup", (evt) => {
          if (!isMenuItem(evt.target)) {
            setDropdownOpened(false);
          }
        }, {
          once: true
        });
      }
      return !o;
    });
  }, [refresh]);
  const connectionStatus = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx).previewServerState.type;
  const canRender = connectionStatus === "connected" || SHOW_BROWSER_RENDERING;
  const renderType = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (connectionStatus === "disconnected" && SHOW_BROWSER_RENDERING) {
      return "client-render";
    }
    if (!SHOW_BROWSER_RENDERING) {
      return "server-render";
    }
    return preferredRenderType;
  }, [connectionStatus, preferredRenderType]);
  const shortcut = areKeyboardShortcutsDisabled() ? "" : "(R)";
  const tooltip = canRender ? "Export the current composition " + shortcut : "Connect to the Studio server to render";
  const iconStyle4 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      style: {
        height: 16,
        color: "currentColor"
      }
    };
  }, []);
  const video = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useVideo();
  const getCurrentFrame2 = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.useFrameImperative();
  const { props } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.EditorPropsContext);
  const openServerRenderModal = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (!video) {
      return null;
    }
    const defaults = window.remotion_renderDefaults;
    if (!defaults) {
      throw new TypeError("Expected defaults");
    }
    setSelectedModal({
      type: "server-render",
      compositionId: video.id,
      initialFrame: getCurrentFrame2(),
      initialStillImageFormat: defaults.stillImageFormat,
      initialVideoImageFormat: null,
      initialJpegQuality: defaults.jpegQuality,
      initialScale: window.remotion_renderDefaults?.scale ?? 1,
      initialLogLevel: defaults.logLevel,
      initialConcurrency: defaults.concurrency,
      maxConcurrency: defaults.maxConcurrency,
      minConcurrency: defaults.minConcurrency,
      initialMuted: defaults.muted,
      initialEnforceAudioTrack: defaults.enforceAudioTrack,
      initialProResProfile: defaults.proResProfile,
      initialx264Preset: defaults.x264Preset,
      initialPixelFormat: null,
      initialAudioBitrate: defaults.audioBitrate,
      initialVideoBitrate: defaults.videoBitrate,
      initialEveryNthFrame: defaults.everyNthFrame,
      initialNumberOfGifLoops: defaults.numberOfGifLoops,
      initialDelayRenderTimeout: defaults.delayRenderTimeout,
      defaultConfigurationAudioCodec: defaults.audioCodec,
      initialEnvVariables: window.process.env,
      initialDisableWebSecurity: defaults.disableWebSecurity,
      initialDarkMode: defaults.darkMode,
      initialOpenGlRenderer: defaults.openGlRenderer,
      initialHeadless: defaults.headless,
      initialIgnoreCertificateErrors: defaults.ignoreCertificateErrors,
      initialOffthreadVideoCacheSizeInBytes: defaults.offthreadVideoCacheSizeInBytes,
      initialOffthreadVideoThreads: defaults.offthreadVideoThreads,
      defaultProps: props[video.id] ?? video.defaultProps,
      inFrameMark: inFrame,
      outFrameMark: outFrame,
      initialColorSpace: defaults.colorSpace,
      initialMultiProcessOnLinux: defaults.multiProcessOnLinux,
      defaultConfigurationVideoCodec: defaults.codec,
      initialEncodingBufferSize: defaults.encodingBufferSize,
      initialEncodingMaxRate: defaults.encodingMaxRate,
      initialUserAgent: defaults.userAgent,
      initialBeep: defaults.beepOnFinish,
      initialRepro: defaults.repro,
      initialForSeamlessAacConcatenation: defaults.forSeamlessAacConcatenation,
      renderTypeOfLastRender: null,
      defaulMetadata: defaults.metadata,
      initialHardwareAcceleration: defaults.hardwareAcceleration,
      initialChromeMode: defaults.chromeMode,
      initialMediaCacheSizeInBytes: defaults.mediaCacheSizeInBytes,
      renderDefaults: defaults
    });
  }, [video, setSelectedModal, getCurrentFrame2, props, inFrame, outFrame]);
  const openClientRenderModal = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (!video) {
      return null;
    }
    const defaults = window.remotion_renderDefaults;
    if (!defaults) {
      throw new TypeError("Expected defaults");
    }
    setSelectedModal({
      type: "web-render",
      compositionId: video.id,
      initialFrame: getCurrentFrame2(),
      defaultProps: props[video.id] ?? video.defaultProps,
      inFrameMark: inFrame,
      outFrameMark: outFrame,
      initialLogLevel: defaults.logLevel,
      initialLicenseKey: defaults.publicLicenseKey,
      initialStillImageFormat: defaults.stillImageFormat,
      initialScale: defaults.scale,
      initialDelayRenderTimeout: defaults.delayRenderTimeout,
      initialDefaultOutName: null,
      initialContainer: null,
      initialVideoCodec: null,
      initialAudioCodec: null,
      initialAudioBitrate: null,
      initialVideoBitrate: null,
      initialHardwareAcceleration: null,
      initialKeyframeIntervalInSeconds: null,
      initialTransparent: null,
      initialMuted: null,
      initialMediaCacheSizeInBytes: defaults.mediaCacheSizeInBytes
    });
  }, [video, setSelectedModal, getCurrentFrame2, props, inFrame, outFrame]);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (!SHOW_BROWSER_RENDERING || renderType === "server-render") {
      openServerRenderModal();
    } else {
      openClientRenderModal();
    }
  }, [renderType, openServerRenderModal, openClientRenderModal]);
  const onHideDropdown = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setDropdownOpened(false);
  }, []);
  const handleRenderTypeChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newType) => {
    setPreferredRenderType(newType);
    try {
      localStorage.setItem(RENDER_TYPE_STORAGE_KEY, newType);
    } catch {}
    setDropdownOpened(false);
    if (newType === "server-render") {
      openServerRenderModal();
    } else {
      openClientRenderModal();
    }
  }, [openServerRenderModal, openClientRenderModal]);
  const dropdownValues = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return [
      {
        type: "item",
        id: "server-render",
        label: "Server-side render",
        value: "server-render",
        onClick: () => handleRenderTypeChange("server-render"),
        keyHint: null,
        leftItem: null,
        subMenu: null,
        quickSwitcherLabel: null
      },
      {
        type: "item",
        id: "client-render",
        label: "Client-side render",
        value: "client-render",
        onClick: () => handleRenderTypeChange("client-render"),
        keyHint: null,
        leftItem: null,
        subMenu: null,
        quickSwitcherLabel: null
      }
    ];
  }, [handleRenderTypeChange]);
  const spaceToBottom = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const margin2 = 10;
    if (size4 && dropdownOpened) {
      return size4.windowSize.height - (size4.top + size4.height) - margin2;
    }
    return 0;
  }, [dropdownOpened, size4]);
  const spaceToTop = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const margin2 = 10;
    if (size4 && dropdownOpened) {
      return size4.top - margin2;
    }
    return 0;
  }, [dropdownOpened, size4]);
  const derivedMaxHeight = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return spaceToTop > spaceToBottom ? spaceToTop : spaceToBottom;
  }, [spaceToBottom, spaceToTop]);
  const portalStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!dropdownOpened || !size4) {
      return null;
    }
    const verticalLayout = spaceToTop > spaceToBottom ? "bottom" : "top";
    return {
      ...verticalLayout === "top" ? {
        ...menuContainerTowardsBottom,
        top: size4.top + size4.height
      } : {
        ...menuContainerTowardsTop,
        bottom: size4.windowSize.height - size4.top
      },
      right: size4.windowSize.width - size4.left - size4.width
    };
  }, [dropdownOpened, size4, spaceToBottom, spaceToTop]);
  const containerStyle3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...splitButtonContainer,
      borderColor: INPUT_BORDER_COLOR_UNHOVERED,
      opacity: canRender ? 1 : 0.7,
      cursor: canRender ? "pointer" : "inherit"
    };
  }, [canRender]);
  const renderLabel = renderType === "server-render" ? "Render" : "Render on web";
  const shouldShowDropdown = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (readOnlyStudio) {
      return false;
    }
    if (!SHOW_BROWSER_RENDERING) {
      return false;
    }
    return true;
  }, [readOnlyStudio]);
  if (!video) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
        style: { display: "none" },
        id: "render-modal-button-server",
        disabled: !canRender,
        onClick: openServerRenderModal,
        type: "button"
      }),
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
        style: { display: "none" },
        id: "render-modal-button-client",
        onClick: openClientRenderModal,
        type: "button"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        ref: containerRef,
        style: containerStyle3,
        title: tooltip,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
            type: "button",
            style: mainButtonStyle,
            onClick,
            id: "render-modal-button",
            disabled: !canRender,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
              align: "center",
              style: mainButtonContent,
              children: [
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ThinRenderIcon, {
                  fill: "currentcolor",
                  svgProps: iconStyle4
                }),
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                  x: 1
                }),
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
                  style: label7,
                  children: renderLabel
                })
              ]
            })
          }),
          shouldShowDropdown ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: dividerStyle
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
                ref: dropdownRef,
                type: "button",
                style: dropdownTriggerStyle,
                disabled: connectionStatus !== "connected",
                className: MENU_INITIATOR_CLASSNAME,
                onPointerDown,
                onClick: onClickDropdown,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CaretDown, {})
              })
            ]
          }) : null
        ]
      }),
      portalStyle ? react_dom__WEBPACK_IMPORTED_MODULE_1__.createPortal(/* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: fullScreenOverlay,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: outerPortal,
          className: "css-reset",
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(HigherZIndex, {
            onOutsideClick: onHideDropdown,
            onEscape: onHideDropdown,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              style: portalStyle,
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MenuContent, {
                onNextMenu: () => {},
                onPreviousMenu: () => {},
                values: dropdownValues,
                onHide: onHideDropdown,
                leaveLeftSpace: false,
                preselectIndex: dropdownValues.findIndex((v) => v.id === renderType),
                topItemCanBeUnselected: false,
                fixedHeight: derivedMaxHeight
              })
            })
          })
        })
      }), getPortal(currentZIndex)) : null
    ]
  });
};

// src/components/Timeline/TimelineZoomControls.tsx



// src/icons/minus.tsx

var Minus = (props) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    ...props,
    xmlns: "http://www.w3.org/2000/svg",
    viewBox: "0 0 448 512",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: "currentColor",
      d: "M400 288h-352c-17.69 0-32-14.32-32-32.01s14.31-31.99 32-31.99h352c17.69 0 32 14.3 32 31.99S417.7 288 400 288z"
    })
  });
};

// src/components/Timeline/TimelineZoomControls.tsx

var container35 = {
  color: "black",
  flexDirection: "row",
  display: "flex",
  alignItems: "center"
};
var buttonStyle3 = {
  fontSize: 24
};
var iconStyle4 = {
  color: "white",
  width: 14
};
var TimelineZoomControls = () => {
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const { setZoom, zoom: zoomMap } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(TimelineZoomCtx);
  const { tabIndex } = useZIndex();
  const onMinusClicked = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (canvasContent === null || canvasContent.type !== "composition") {
      return;
    }
    setZoom(canvasContent.compositionId, (z) => Math.max(TIMELINE_MIN_ZOOM, z - 0.2));
  }, [canvasContent, setZoom]);
  const onPlusClicked = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (canvasContent === null || canvasContent.type !== "composition") {
      return;
    }
    setZoom(canvasContent.compositionId, (z) => Math.min(TIMELINE_MAX_ZOOM, z + 0.2));
  }, [canvasContent, setZoom]);
  const onChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (canvasContent === null || canvasContent.type !== "composition") {
      return;
    }
    setZoom(canvasContent.compositionId, () => Number(e.target.value));
  }, [canvasContent, setZoom]);
  const isStill = useIsStill();
  if (isStill || canvasContent === null || canvasContent.type !== "composition") {
    return null;
  }
  const zoom = zoomMap[canvasContent.compositionId] ?? TIMELINE_MIN_ZOOM;
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container35,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ControlButton, {
        onClick: onMinusClicked,
        style: buttonStyle3,
        title: "Zoom out timeline",
        role: "ControlButton",
        type: "button",
        disabled: TIMELINE_MIN_ZOOM === zoom,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Minus, {
          style: iconStyle4
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 0.5
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("input", {
        title: `Timeline zoom (${zoom}x)`,
        alt: `Timeline zoom (${zoom}x)`,
        type: "range",
        min: TIMELINE_MIN_ZOOM,
        step: 0.1,
        value: zoom,
        max: TIMELINE_MAX_ZOOM,
        onChange,
        className: "__remotion-timeline-slider",
        tabIndex
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 0.5
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ControlButton, {
        onClick: onPlusClicked,
        style: buttonStyle3,
        title: "Zoom in timeline",
        role: "button",
        type: "button",
        disabled: TIMELINE_MAX_ZOOM === zoom,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Plus, {
          color: "currentcolor",
          style: iconStyle4
        })
      })
    ]
  });
};

// src/components/PreviewToolbar.tsx

var container36 = {
  display: "flex",
  justifyContent: "center",
  borderTop: "1px solid rgba(0, 0, 0, 0.5)",
  paddingTop: 2,
  paddingBottom: 2,
  alignItems: "center",
  flexDirection: "row",
  background: BACKGROUND
};
var mobileContainer = {
  ...container36,
  position: "relative",
  overflowY: "auto",
  justifyContent: "flex-start"
};
var scrollIndicatorLeft = {
  position: "fixed",
  display: "none",
  top: 0,
  left: 0,
  width: 40,
  height: "100%",
  pointerEvents: "none",
  background: `linear-gradient(to right, ${BACKGROUND}, ${BACKGROUND__TRANSPARENT})`
};
var scrollIndicatorRight = {
  position: "fixed",
  display: "none",
  top: 0,
  right: 0,
  width: 40,
  height: "100%",
  pointerEvents: "none",
  background: `linear-gradient(to left, ${BACKGROUND}, ${BACKGROUND__TRANSPARENT})`
};
var sideContainer = {
  width: 300,
  height: 38,
  display: "flex",
  flexDirection: "row",
  alignItems: "center"
};
var padding2 = {
  width: TIMELINE_PADDING
};
var PreviewToolbar = ({ readOnlyStudio, bufferStateDelayInMilliseconds }) => {
  const { playbackRate, setPlaybackRate } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.TimelineContext);
  const { mediaMuted } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.MediaVolumeContext);
  const { setMediaMuted } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.SetMediaVolumeContext);
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const isVideoComposition = useIsVideoComposition();
  const previewToolbarRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const leftScrollIndicatorRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const rightScrollIndicatorRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const isStill = useIsStill();
  const [loop, setLoop] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(loadLoopOption());
  const isFullscreenSupported = checkFullscreenSupport();
  const isMobileLayout = useMobileLayout();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (isMobileLayout && previewToolbarRef.current) {
      const updateScrollableIndicatorProps = (target) => {
        const boundingBox = target.getBoundingClientRect();
        const { scrollLeft, scrollWidth, clientWidth } = target;
        const scrollRight = scrollWidth - clientWidth - scrollLeft;
        if (!leftScrollIndicatorRef.current || !rightScrollIndicatorRef.current) {
          return;
        }
        if (scrollLeft !== 0) {
          Object.assign(leftScrollIndicatorRef.current.style, {
            display: "block",
            height: `${boundingBox.height}px`,
            top: `${boundingBox.top}px`,
            left: `${boundingBox.left}px`
          });
        } else {
          Object.assign(leftScrollIndicatorRef.current.style, {
            display: "none"
          });
        }
        if (scrollRight !== 0) {
          const itemWidth = rightScrollIndicatorRef.current?.clientWidth || 0;
          Object.assign(rightScrollIndicatorRef.current.style, {
            display: "block",
            height: `${boundingBox.height}px`,
            top: `${boundingBox.top}px`,
            left: `${boundingBox.left + boundingBox.width - itemWidth}px`
          });
        } else {
          Object.assign(rightScrollIndicatorRef.current.style, {
            display: "none"
          });
        }
      };
      const previewToolbar = previewToolbarRef.current;
      const scrollHandler = () => {
        updateScrollableIndicatorProps(previewToolbar);
      };
      previewToolbar.addEventListener("scroll", scrollHandler);
      scrollHandler();
      return () => {
        previewToolbar.removeEventListener("scroll", scrollHandler);
      };
    }
  });
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    ref: previewToolbarRef,
    style: isMobileLayout ? mobileContainer : container36,
    className: "css-reset",
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        ref: leftScrollIndicatorRef,
        style: scrollIndicatorLeft
      }),
      isMobileLayout ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: sideContainer,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: padding2
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineZoomControls, {})
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {}),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SizeSelector, {}),
          isStill || isVideoComposition ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(PlaybackRateSelector, {
            setPlaybackRate,
            playbackRate
          }) : null
        ]
      }),
      isVideoComposition ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 2
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(PlayPause, {
            bufferStateDelayInMilliseconds,
            loop,
            playbackRate
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 2
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(LoopToggle, {
            loop,
            setLoop
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MuteToggle, {
            muted: mediaMuted,
            setMuted: setMediaMuted
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 2
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineInOutPointToggle, {}),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 2
          })
        ]
      }) : null,
      canvasContent?.type === "composition" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CheckboardToggle, {}) : null,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 1
      }),
      isFullscreenSupported && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FullScreenToggle, {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {}),
      isMobileLayout && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {}),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SizeSelector, {}),
          isStill || isVideoComposition ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(PlaybackRateSelector, {
            setPlaybackRate,
            playbackRate
          }) : null
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: sideContainer,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {}),
          !isMobileLayout && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FpsCounter, {
            playbackSpeed: playbackRate
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 2
          }),
          shouldShowRenderButton(readOnlyStudio) ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderButton, {
            readOnlyStudio
          }) : null,
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 1.5
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(PlaybackKeyboardShortcutsManager, {
        setPlaybackRate
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(PlaybackRatePersistor, {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        ref: rightScrollIndicatorRef,
        style: scrollIndicatorRight
      })
    ]
  });
};

// src/components/Splitter/SplitterContainer.tsx


// src/state/timeline.ts
var localStorageKey4 = (id) => `remotion.editor.timelineFlex.${id}`;
var persistTimelineFlex = (value, id) => {
  localStorage.setItem(localStorageKey4(id), String(value));
};
var loadTimelineFlex = (id) => {
  const item2 = localStorage.getItem(localStorageKey4(id));
  return item2 ? parseFloat(item2) : null;
};
var useTimelineFlex = (id) => {
  return [
    loadTimelineFlex(id),
    (value) => persistTimelineFlex(value, id)
  ];
};

// src/components/Splitter/SplitterContext.tsx

var SplitterContext = react__WEBPACK_IMPORTED_MODULE_0__.createContext({
  flexValue: 1,
  ref: { current: null },
  setFlexValue: () => {
    return;
  },
  isDragging: { current: false },
  orientation: "horizontal",
  maxFlex: 1,
  minFlex: 1,
  defaultFlex: 1,
  id: "--",
  persistFlex: () => {
    return;
  }
});

// src/components/Splitter/SplitterContainer.tsx

var containerRow = {
  display: "flex",
  flexDirection: "row",
  flex: 1,
  height: "100%",
  width: "100%"
};
var containerColumn = {
  display: "flex",
  flexDirection: "column",
  flex: 1,
  height: 0
};
var SplitterContainer = ({ orientation, children, defaultFlex, maxFlex, minFlex, id }) => {
  const [initialTimelineFlex, persistFlex] = useTimelineFlex(id);
  const [flexValue, setFlexValue] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialTimelineFlex ?? defaultFlex);
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const isDragging = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(false);
  const value = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      flexValue,
      ref,
      setFlexValue,
      isDragging,
      orientation,
      id,
      maxFlex,
      minFlex,
      defaultFlex,
      persistFlex
    };
  }, [
    defaultFlex,
    flexValue,
    id,
    maxFlex,
    minFlex,
    orientation,
    persistFlex,
    ref
  ]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SplitterContext.Provider, {
    value,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      ref,
      style: orientation === "horizontal" ? containerColumn : containerRow,
      children
    })
  });
};

// src/components/Splitter/SplitterElement.tsx



var SplitterElement = ({ children, type, sticky }) => {
  const context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SplitterContext);
  const style9 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      flex: (type === "flexer" ? context.flexValue : 1 - context.flexValue) * 1000,
      display: "flex",
      position: "relative",
      overflow: "hidden",
      flexDirection: "column"
    };
  }, [context.flexValue, type]);
  const stickStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      position: "absolute",
      left: (type === "flexer" ? 0 : context.flexValue) * 100 + "%",
      width: (type === "flexer" ? context.flexValue : 1 - context.flexValue) * 100 + "%",
      backgroundColor: (0,remotion__WEBPACK_IMPORTED_MODULE_2__.interpolateColors)((0,remotion__WEBPACK_IMPORTED_MODULE_2__.random)(context.flexValue), [0, 1], ["red", "blue"])
    };
  }, [context.flexValue, type]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: style9,
        children
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: stickStyle,
        children: sticky ?? null
      })
    ]
  });
};

// src/components/Splitter/SplitterHandle.tsx



var SPLITTER_HANDLE_SIZE = 3;
var containerRow2 = {
  height: SPLITTER_HANDLE_SIZE
};
var containerColumn2 = {
  width: SPLITTER_HANDLE_SIZE
};
var SplitterHandle = ({ allowToCollapse, onCollapse }) => {
  const context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SplitterContext);
  if (!context) {
    throw new Error("Cannot find splitter context");
  }
  const [lastPointerUp, setLastPointerUp] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => Date.now());
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (context.isDragging.current) {
      return;
    }
    const { current } = ref;
    if (!current) {
      return;
    }
    const getNewValue = (e, clamp) => {
      if (!context.isDragging.current) {
        throw new Error("cannot get value if not dragging");
      }
      if (!context.ref.current) {
        throw new Error("domRect is not mounted");
      }
      const { width, height } = context.ref.current.getBoundingClientRect();
      const change = (() => {
        if (context.orientation === "vertical") {
          return (e.clientX - context.isDragging.current.x) / (width - SPLITTER_HANDLE_SIZE);
        }
        return (e.clientY - context.isDragging.current.y) / (height - SPLITTER_HANDLE_SIZE);
      })();
      const newFlex = context.flexValue + change;
      if (clamp) {
        return Math.min(context.maxFlex, Math.max(context.minFlex, newFlex));
      }
      return newFlex;
    };
    const onPointerDown = (e) => {
      if (e.button !== 0) {
        return;
      }
      context.isDragging.current = {
        x: e.clientX,
        y: e.clientY
      };
      ref.current?.classList.add("remotion-splitter-active");
      window.addEventListener("pointerup", (ev) => {
        if (!context.isDragging.current) {
          return;
        }
        context.persistFlex(getNewValue(ev, true));
        cleanup();
        setLastPointerUp(Date.now());
      }, { once: true });
      window.addEventListener("pointermove", onPointerMove);
    };
    const onPointerMove = (e) => {
      if (context.isDragging.current) {
        const val = getNewValue(e, true);
        context.setFlexValue(val);
        if (allowToCollapse === "left") {
          const unclamped = getNewValue(e, false);
          if (unclamped < context.minFlex / 2) {
            cleanup();
            onCollapse();
            setLastPointerUp(Date.now());
          }
        }
        if (allowToCollapse === "right") {
          const unclamped = 1 - getNewValue(e, false);
          if (unclamped < (1 - context.maxFlex) / 2) {
            cleanup();
            onCollapse();
            setLastPointerUp(Date.now());
          }
        }
      }
    };
    const cleanup = () => {
      context.isDragging.current = false;
      ref.current?.classList.remove("remotion-splitter-active");
      current.removeEventListener("pointerdown", onPointerDown);
      window.removeEventListener("pointermove", onPointerMove);
      _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.updateAllElementsSizes();
    };
    current.addEventListener("pointerdown", onPointerDown);
    return () => {
      if (!context.isDragging.current) {
        cleanup();
      }
    };
  }, [allowToCollapse, context, context.flexValue, lastPointerUp, onCollapse]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const { current } = ref;
    if (!current) {
      return;
    }
    let isMouseDown = false;
    const onMouseDown = () => {
      isMouseDown = true;
    };
    const onMouseUp = () => {
      isMouseDown = false;
    };
    const onMouseEnter = (e) => {
      if (e.button !== 0) {
        return;
      }
      if (isMouseDown) {
        return;
      }
      current.classList.add("remotion-splitter-hover");
    };
    const onMouseLeave = (e) => {
      if (e.button !== 0) {
        return;
      }
      current.classList.remove("remotion-splitter-hover");
    };
    current.addEventListener("mouseenter", onMouseEnter);
    current.addEventListener("mouseleave", onMouseLeave);
    window.addEventListener("mousedown", onMouseDown);
    window.addEventListener("mouseup", onMouseUp);
    return () => {
      current.removeEventListener("mouseenter", onMouseEnter);
      current.removeEventListener("mouseleave", onMouseLeave);
      window.removeEventListener("mousedown", onMouseDown);
      window.removeEventListener("mouseup", onMouseUp);
    };
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    ref,
    className: [
      "remotion-splitter",
      context.orientation === "horizontal" ? "remotion-splitter-horizontal" : "remotion-splitter-vertical"
    ].join(" "),
    style: context.orientation === "horizontal" ? containerRow2 : containerColumn2
  });
};

// src/components/TopPanel.tsx

var container37 = {
  height: "100%",
  width: "100%",
  display: "flex",
  flexDirection: "column",
  flex: 1
};
var row5 = {
  display: "flex",
  flexDirection: "row",
  flex: 1,
  minHeight: 0
};
var useResponsiveSidebarStatus = () => {
  const { sidebarCollapsedStateLeft } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SidebarContext);
  const responsiveLeftStatus = useBreakpoint(1200) ? "collapsed" : "expanded";
  const actualStateLeft = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (sidebarCollapsedStateLeft === "collapsed") {
      return "collapsed";
    }
    if (sidebarCollapsedStateLeft === "expanded") {
      return "expanded";
    }
    return responsiveLeftStatus;
  }, [sidebarCollapsedStateLeft, responsiveLeftStatus]);
  return actualStateLeft;
};
var TopPanel = ({ readOnlyStudio, onMounted, drawRef: drawRef2, bufferStateDelayInMilliseconds }) => {
  const { setSidebarCollapsedState, sidebarCollapsedStateRight } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SidebarContext);
  const rulersAreVisible = useIsRulerVisible();
  const actualStateLeft = useResponsiveSidebarStatus();
  const actualStateRight = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (sidebarCollapsedStateRight === "collapsed") {
      return "collapsed";
    }
    return "expanded";
  }, [sidebarCollapsedStateRight]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    onMounted();
  }, [onMounted]);
  const canvasContainerStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => ({
    flex: 1,
    display: "flex",
    paddingTop: rulersAreVisible ? RULER_WIDTH : 0,
    paddingLeft: rulersAreVisible ? RULER_WIDTH : 0
  }), [rulersAreVisible]);
  const onCollapseLeft = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSidebarCollapsedState({ left: "collapsed", right: null });
  }, [setSidebarCollapsedState]);
  const onCollapseRight = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSidebarCollapsedState({ left: null, right: "collapsed" });
  }, [setSidebarCollapsedState]);
  const isMobileLayout = useMobileLayout();
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container37,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: row5,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(SplitterContainer, {
          minFlex: 0.15,
          maxFlex: 0.4,
          defaultFlex: 0.2,
          id: "sidebar-to-preview",
          orientation: "vertical",
          children: [
            actualStateLeft === "expanded" ? isMobileLayout ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MobilePanel, {
              onClose: onCollapseLeft,
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ExplorerPanel, {
                readOnlyStudio
              })
            }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SplitterElement, {
              sticky: null,
              type: "flexer",
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ExplorerPanel, {
                readOnlyStudio
              })
            }) : null,
            actualStateLeft === "expanded" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SplitterHandle, {
              allowToCollapse: "left",
              onCollapse: onCollapseLeft
            }) : null,
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SplitterElement, {
              sticky: null,
              type: "anti-flexer",
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(SplitterContainer, {
                minFlex: 0.5,
                maxFlex: 0.8,
                defaultFlex: 0.7,
                id: "canvas-to-right-sidebar",
                orientation: "vertical",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SplitterElement, {
                    sticky: null,
                    type: "flexer",
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                      ref: drawRef2,
                      style: canvasContainerStyle,
                      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CanvasIfSizeIsAvailable, {})
                    })
                  }),
                  actualStateRight === "expanded" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SplitterHandle, {
                    allowToCollapse: "right",
                    onCollapse: onCollapseRight
                  }) : null,
                  actualStateRight === "expanded" ? isMobileLayout ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MobilePanel, {
                    onClose: onCollapseRight,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionsPanel, {
                      readOnlyStudio
                    })
                  }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SplitterElement, {
                    sticky: null,
                    type: "anti-flexer",
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionsPanel, {
                      readOnlyStudio
                    })
                  }) : null
                ]
              })
            })
          ]
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(PreviewToolbar, {
        bufferStateDelayInMilliseconds,
        readOnlyStudio
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CurrentCompositionKeybindings, {
        readOnlyStudio
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TitleUpdater, {})
    ]
  });
};

// src/components/SidebarCollapserControls.tsx

var style9 = {
  width: 16,
  height: 16,
  minWidth: 16,
  border: "1px solid currentColor",
  borderRadius: 3,
  color: "currentColor",
  position: "relative"
};
var SidebarCollapserControls = () => {
  const { setSidebarCollapsedState, sidebarCollapsedStateRight } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SidebarContext);
  const keybindings = useKeybinding();
  const leftSidebarStatus = useResponsiveSidebarStatus();
  const leftIcon = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return {
      width: "35%",
      height: "100%",
      borderRight: "1px solid " + color,
      background: leftSidebarStatus === "expanded" ? color : "transparent"
    };
  }, [leftSidebarStatus]);
  const rightIcon = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return {
      width: "35%",
      height: "100%",
      right: 0,
      position: "absolute",
      borderLeft: "1px solid " + color,
      background: sidebarCollapsedStateRight === "expanded" ? color : "transparent"
    };
  }, [sidebarCollapsedStateRight]);
  const toggleLeft = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSidebarCollapsedState({
      left: (s) => {
        if (s === "responsive") {
          return leftSidebarStatus === "collapsed" ? "expanded" : "collapsed";
        }
        return s === "collapsed" ? "expanded" : "collapsed";
      },
      right: null
    });
  }, [leftSidebarStatus, setSidebarCollapsedState]);
  const toggleRight = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSidebarCollapsedState({
      right: (s) => s === "collapsed" ? "expanded" : "collapsed",
      left: null
    });
  }, [setSidebarCollapsedState]);
  const toggleBoth = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (sidebarCollapsedStateRight === leftSidebarStatus) {
      setSidebarCollapsedState({
        left: (s) => {
          if (s === "responsive") {
            return leftSidebarStatus === "collapsed" ? "expanded" : "collapsed";
          }
          return s === "collapsed" ? "expanded" : "collapsed";
        },
        right: (s) => s === "collapsed" ? "expanded" : "collapsed"
      });
    } else if (sidebarCollapsedStateRight === "expanded") {
      toggleRight();
    } else if (leftSidebarStatus === "expanded") {
      toggleLeft();
    }
  }, [
    leftSidebarStatus,
    setSidebarCollapsedState,
    sidebarCollapsedStateRight,
    toggleLeft,
    toggleRight
  ]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const left3 = keybindings.registerKeybinding({
      event: "keydown",
      key: "b",
      commandCtrlKey: true,
      callback: toggleLeft,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const right2 = keybindings.registerKeybinding({
      event: "keydown",
      key: "j",
      commandCtrlKey: true,
      callback: toggleRight,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const zen = keybindings.registerKeybinding({
      event: "keydown",
      key: "g",
      commandCtrlKey: true,
      callback: toggleBoth,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      left3.unregister();
      right2.unregister();
      zen.unregister();
    };
  }, [keybindings, toggleBoth, toggleLeft, toggleRight]);
  const toggleLeftTooltip = areKeyboardShortcutsDisabled() ? "Toggle Left Sidebar" : `Toggle Left Sidebar (${cmdOrCtrlCharacter}+B)`;
  const toggleRightTooltip = areKeyboardShortcutsDisabled() ? "Toggle Right Sidebar" : `Toggle Right Sidebar (${cmdOrCtrlCharacter}+J)`;
  const colorStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return {
      ...style9,
      color
    };
  }, []);
  const toggleLeftAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: colorStyle(color),
      title: toggleLeftTooltip,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: leftIcon(color)
      })
    });
  }, [colorStyle, leftIcon, toggleLeftTooltip]);
  const toggleRightAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: colorStyle(color),
      title: toggleRightTooltip,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: rightIcon(color)
      })
    });
  }, [colorStyle, rightIcon, toggleRightTooltip]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
        onClick: toggleLeft,
        renderAction: toggleLeftAction
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
        onClick: toggleRight,
        renderAction: toggleRightAction
      })
    ]
  });
};

// src/components/UpdateCheck.tsx



var buttonStyle4 = {
  appearance: "none",
  color: BLUE,
  border: "none",
  fontWeight: "bold",
  backgroundColor: "transparent",
  cursor: "pointer",
  fontSize: 14,
  display: "inline-flex",
  justifyContent: "center"
};
var UpdateCheck = () => {
  const [info, setInfo] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const { tabIndex } = useZIndex();
  const [knownBugs, setKnownBugs] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const hasKnownBugs = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return knownBugs && knownBugs.length > 0;
  }, [knownBugs]);
  const checkForUpdates = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    const controller = new AbortController;
    updateAvailable(controller.signal).then((d) => {
      setInfo(d);
    }).catch((err) => {
      if (err.message.includes("aborted")) {
        return;
      }
      console.log("Could not check for updates", err);
    });
    return controller;
  }, []);
  const checkForBugs = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    const controller = new AbortController;
    fetch(`https://bugs.remotion.dev/api/${remotion__WEBPACK_IMPORTED_MODULE_2__.VERSION}`, {
      signal: controller.signal
    }).then(async (res) => {
      const body = await res.json();
      setKnownBugs(body.bugs);
    }).catch((err) => {
      if (err.message.includes("aborted")) {
        return;
      }
      console.log("Could not check for bugs in this version", err);
    });
    return controller;
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const abortUpdate = checkForUpdates();
    const abortBugs = checkForBugs();
    return () => {
      abortUpdate.abort();
      abortBugs.abort();
    };
  }, [checkForBugs, checkForUpdates]);
  const openModal = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSelectedModal({
      type: "update",
      info,
      knownBugs
    });
  }, [info, knownBugs, setSelectedModal]);
  const dynButtonStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...buttonStyle4,
      color: hasKnownBugs ? WARNING_COLOR : LIGHT_TEXT
    };
  }, [hasKnownBugs]);
  if (!info) {
    return null;
  }
  if (!info.updateAvailable) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
    tabIndex,
    style: dynButtonStyle,
    onClick: openModal,
    type: "button",
    title: hasKnownBugs ? "Bugfixes available" : "Update available",
    children: hasKnownBugs ? "Bugfixes available" : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      xmlns: "http://www.w3.org/2000/svg",
      style: {
        height: 16,
        width: 16
      },
      viewBox: "0 0 512 512",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        fill: "currentcolor",
        d: "M256 48a208 208 0 1 1 0 416 208 208 0 1 1 0-416zm0 464A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM135.1 217.4c-4.5 4.2-7.1 10.1-7.1 16.3c0 12.3 10 22.3 22.3 22.3H208v96c0 17.7 14.3 32 32 32h32c17.7 0 32-14.3 32-32V256h57.7c12.3 0 22.3-10 22.3-22.3c0-6.2-2.6-12.1-7.1-16.3L269.8 117.5c-3.8-3.5-8.7-5.5-13.8-5.5s-10.1 2-13.8 5.5L135.1 217.4z"
      })
    })
  });
};

// src/components/MenuToolbar.tsx

var row6 = {
  alignItems: "center",
  flexDirection: "row",
  display: "flex",
  color: "white",
  borderBottom: "1px solid black",
  fontSize: 13,
  paddingLeft: 6,
  paddingRight: 10,
  backgroundColor: BACKGROUND
};
var flex2 = {
  flex: 1
};
var MenuToolbar = ({ readOnlyStudio }) => {
  const [selected, setSelected] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const mobileLayout = useMobileLayout();
  const fixedWidthRight = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...mobileLayout ? { width: "fit-content" } : {
        width: "330px"
      },
      display: "flex",
      alignItems: "center",
      justifyContent: "flex-end"
    };
  }, [mobileLayout]);
  const fixedWidthLeft = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...mobileLayout ? { minWidth: "0px" } : {
        minWidth: "330px"
      },
      display: "flex",
      alignItems: "center",
      justifyContent: "flex-start"
    };
  }, [mobileLayout]);
  const itemClicked = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((itemId) => {
    setSelected(itemId);
  }, [setSelected]);
  const itemHovered = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((itemId) => {
    if (selected) {
      setSelected(itemId);
    }
  }, [selected, setSelected]);
  const closeMenu = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSelected(null);
  }, []);
  const structure = useMenuStructure(closeMenu, readOnlyStudio);
  const menus = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return structure.map((s) => s.id);
  }, [structure]);
  const onPreviousMenu = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSelected((s) => {
      if (s === null) {
        return null;
      }
      return menus[(menus.indexOf(s) + 1) % menus.length];
    });
  }, [menus]);
  const onNextMenu = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSelected((s) => {
      if (s === null) {
        return null;
      }
      if (menus.indexOf(s) === 0) {
        return menus[menus.length - 1];
      }
      return menus[(menus.indexOf(s) - 1) % menus.length];
    });
  }, [menus]);
  const onItemQuit = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSelected(null);
  }, [setSelected]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
    align: "center",
    className: "css-reset",
    style: row6,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: fixedWidthLeft,
        children: [
          structure.map((s) => {
            return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MenuItem, {
              selected: selected === s.id,
              onItemSelected: itemClicked,
              onItemHovered: itemHovered,
              id: s.id,
              label: s.label,
              onItemQuit,
              menu: s,
              onPreviousMenu,
              onNextMenu,
              leaveLeftPadding: s.leaveLeftPadding
            }, s.id);
          }),
          readOnlyStudio ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(UpdateCheck, {})
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: flex2
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MenuBuildIndicator, {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: flex2
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: fixedWidthRight,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SidebarCollapserControls, {})
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 1
      })
    ]
  });
};

// src/components/Timeline/Timeline.tsx



// src/helpers/get-sequence-visible-range.ts
var getCascadedStart = (sequence, sequences) => {
  if (!sequence.parent) {
    return sequence.from;
  }
  const parent = sequences.find((s) => s.id === sequence.parent);
  if (!parent) {
    throw new TypeError("Parent not found for sequence " + sequence.id);
  }
  return getCascadedStart(parent, sequences) + sequence.from;
};
var getTimelineVisibleStart = (sequence, sequences) => {
  const cascadedStart = Math.max(0, getCascadedStart(sequence, sequences));
  if (!sequence.parent) {
    return cascadedStart;
  }
  const parent = sequences.find((s) => s.id === sequence.parent);
  if (!parent) {
    throw new TypeError("Parent not found for sequence " + sequence.id);
  }
  const timelineVisibleStart = getTimelineVisibleStart(parent, sequences);
  return Math.max(timelineVisibleStart, cascadedStart);
};
var getTimelineVisibleDuration = (sequence, sequences) => {
  const visibleDuration = sequence.duration + Math.min(sequence.from, 0);
  if (!sequence.parent) {
    return visibleDuration;
  }
  const parent = sequences.find((s) => s.id === sequence.parent);
  if (!parent) {
    throw new TypeError("Parent not found for sequence " + sequence.id);
  }
  return Math.min(visibleDuration, getTimelineVisibleDuration(parent, sequences));
};

// src/helpers/get-timeline-nestedness.ts
var getTimelineNestedLevel = (sequence, allSequences, depth) => {
  if (!sequence.parent) {
    return depth;
  }
  const parentSequence = allSequences.find((s) => s.id === sequence.parent);
  if (!parentSequence) {
    throw new Error("has parentId but no parent");
  }
  return getTimelineNestedLevel(parentSequence, allSequences, depth + 1);
};

// src/helpers/get-timeline-sequence-hash.ts
var getTimelineSequenceHash = (sequence, allSequences, hashesUsedInRoot, cache) => {
  if (cache[sequence.id]) {
    return cache[sequence.id];
  }
  const parent = allSequences.find((a) => a.id === sequence.parent);
  const baseHash = [
    parent ? getTimelineSequenceHash(parent, allSequences, hashesUsedInRoot, cache) : null,
    sequence.displayName,
    sequence.duration,
    sequence.from,
    sequence.type,
    sequence.type === "audio" ? sequence.src : null,
    sequence.type === "audio" ? sequence.volume : null,
    sequence.type === "video" ? sequence.src : null,
    sequence.type === "video" ? sequence.volume : null
  ].join("-");
  const actualHash = baseHash + hashesUsedInRoot[sequence.rootId].filter((h) => h === baseHash).length;
  hashesUsedInRoot[sequence.rootId].push(baseHash);
  cache[sequence.id] = actualHash;
  return actualHash;
};

// src/helpers/get-timeline-sequence-sort-key.ts
var getTimelineSequenceSequenceSortKey = (track, tracks, sameHashes = {}) => {
  const firstSequenceWithSameHash = tracks.find((t) => sameHashes[track.hash].includes(t.sequence.id));
  const id = String(firstSequenceWithSameHash.sequence.nonce).padStart(6, "0");
  if (!track.sequence.parent) {
    return id;
  }
  const parent = tracks.find((t) => t.sequence.id === track.sequence.parent);
  if (!parent) {
    return id;
  }
  const firstParentWithSameHash = tracks.find((a) => {
    return sameHashes[parent.hash].includes(a.sequence.id);
  });
  if (!firstParentWithSameHash) {
    throw new Error("could not find parent: " + track.sequence.parent);
  }
  return `${getTimelineSequenceSequenceSortKey(firstParentWithSameHash, tracks, sameHashes)}-${id}`;
};

// src/helpers/calculate-timeline.ts
var calculateTimeline = ({
  sequences,
  sequenceDuration
}) => {
  const tracks = [];
  if (sequences.length === 0) {
    return [
      {
        sequence: {
          displayName: "",
          duration: sequenceDuration,
          from: 0,
          id: "seq",
          parent: null,
          type: "sequence",
          rootId: "-",
          showInTimeline: true,
          nonce: 0,
          loopDisplay: undefined,
          stack: null,
          premountDisplay: null,
          postmountDisplay: null,
          controls: null
        },
        depth: 0,
        hash: "-"
      }
    ];
  }
  const sameHashes = {};
  const hashesUsedInRoot = {};
  const cache = {};
  for (let i = 0;i < sequences.length; i++) {
    const sequence = sequences[i];
    if (!hashesUsedInRoot[sequence.rootId]) {
      hashesUsedInRoot[sequence.rootId] = [];
    }
    const actualHash = getTimelineSequenceHash(sequence, sequences, hashesUsedInRoot, cache);
    if (!sameHashes[actualHash]) {
      sameHashes[actualHash] = [];
    }
    sameHashes[actualHash].push(sequence.id);
    const cascadedStart = getCascadedStart(sequence, sequences);
    const visibleStart = getTimelineVisibleStart(sequence, sequences);
    const visibleDuration = getTimelineVisibleDuration(sequence, sequences);
    tracks.push({
      sequence: {
        ...sequence,
        from: visibleStart,
        duration: visibleDuration
      },
      depth: getTimelineNestedLevel(sequence, sequences, 0),
      hash: actualHash,
      cascadedStart,
      cascadedDuration: sequence.duration
    });
  }
  const uniqueTracks = [];
  for (const track of tracks) {
    if (!uniqueTracks.find((t) => t.hash === track.hash)) {
      const { cascadedDuration, cascadedStart, ...cleanTrack } = track;
      uniqueTracks.push(cleanTrack);
    }
  }
  return uniqueTracks.sort((a, b) => {
    const sortKeyA = getTimelineSequenceSequenceSortKey(a, tracks, sameHashes);
    const sortKeyB = getTimelineSequenceSequenceSortKey(b, tracks, sameHashes);
    return sortKeyA.localeCompare(sortKeyB);
  });
};

// src/components/Timeline/is-collapsed.ts
var isTrackHidden = (track) => {
  if (!track.sequence.parent) {
    return false;
  }
  return !track.sequence.showInTimeline;
};

// src/components/Timeline/MaxTimelineTracks.tsx


var MAX_TIMELINE_TRACKS =  true ? _remotion_studio_shared__WEBPACK_IMPORTED_MODULE_6__/* .DEFAULT_TIMELINE_TRACKS */ .n3 : 0;
var MAX_TIMELINE_TRACKS_NOTICE_HEIGHT = 24;
var container38 = {
  height: MAX_TIMELINE_TRACKS_NOTICE_HEIGHT,
  display: "flex",
  alignItems: "center",
  color: "rgba(255, 255, 255, 0.6)",
  fontFamily: "sans-serif",
  fontSize: 12,
  backgroundColor: "rgba(255, 255, 255, 0.1)",
  paddingLeft: TIMELINE_PADDING + 5
};
var MaxTimelineTracksReached = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container38,
    children: [
      "Limited display to ",
      MAX_TIMELINE_TRACKS,
      " tracks to sustain performance.",
      "",
      "You can change this by setting Config.setMaxTimelineTracks() in your remotion.config.ts file."
    ]
  });
};

// src/components/Timeline/TimelineDragHandler.tsx




// src/components/Timeline/TimelineInOutPointer.tsx



var areaHighlight = {
  position: "absolute",
  backgroundColor: "rgba(0, 0, 0, 0.5)",
  height: "100%",
  bottom: 0,
  top: 0
};
var inMarkerAreaRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.createRef)();
var outMarkerAreaRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.createRef)();
var TimelineInOutPointer = () => {
  const { inFrame, outFrame } = useTimelineInOutFramePosition();
  const videoConfig = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useUnsafeVideoConfig();
  const timelineWidth = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(TimelineWidthContext);
  if (!videoConfig || timelineWidth === null) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      inFrame !== null && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        ref: inMarkerAreaRef,
        style: {
          ...areaHighlight,
          left: 0,
          width: getXPositionOfItemInTimelineImperatively(inFrame, videoConfig.durationInFrames, timelineWidth)
        }
      }),
      outFrame !== null && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        ref: outMarkerAreaRef,
        style: {
          ...areaHighlight,
          left: getXPositionOfItemInTimelineImperatively(outFrame, videoConfig.durationInFrames, timelineWidth),
          width: timelineWidth - getXPositionOfItemInTimelineImperatively(outFrame, videoConfig.durationInFrames, timelineWidth)
        }
      })
    ]
  });
};

// src/components/Timeline/TimelineInOutPointerHandle.tsx



var line3 = {
  height: "100%",
  width: 1,
  position: "absolute",
  backgroundColor: "rgba(255, 255, 255, 0.1)",
  cursor: "ew-resize",
  paddingLeft: 1,
  paddingRight: 1
};
var inPointerHandle = (0,react__WEBPACK_IMPORTED_MODULE_0__.createRef)();
var outPointerHandle = (0,react__WEBPACK_IMPORTED_MODULE_0__.createRef)();
var InnerTimelineInOutPointerHandle = ({ atFrame, dragging, timelineWidth, type }) => {
  const videoConfig = (0,remotion__WEBPACK_IMPORTED_MODULE_2__.useVideoConfig)();
  const style10 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...line3,
      backgroundColor: dragging ? LIGHT_TRANSPARENT : "rgba(255, 255, 255, 0.1)",
      transform: `translateX(${getXPositionOfItemInTimelineImperatively(atFrame, videoConfig.durationInFrames, timelineWidth)}px)`
    };
  }, [atFrame, dragging, timelineWidth, videoConfig.durationInFrames]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    ref: type === "in" ? inPointerHandle : outPointerHandle,
    style: style10
  });
};
var TimelineInOutPointerHandle = ({
  dragging,
  type,
  atFrame
}) => {
  const timelineWidth = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(TimelineWidthContext);
  if (timelineWidth === null) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InnerTimelineInOutPointerHandle, {
    atFrame,
    dragging,
    timelineWidth,
    type
  });
};

// src/components/Timeline/TimelineDragHandler.tsx

var inner = {
  overflowY: "auto",
  overflowX: "hidden"
};
var container39 = {
  userSelect: "none",
  WebkitUserSelect: "none",
  position: "absolute",
  height: "100%",
  top: 0
};
var style10 = {
  width: "100%",
  height: "100%",
  userSelect: "none",
  WebkitUserSelect: "none"
};
var getClientXWithScroll = (x) => {
  return x + scrollableRef.current?.scrollLeft;
};
var TimelineDragHandler = () => {
  const video = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useUnsafeVideoConfig();
  const { zoom: zoomMap } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(TimelineZoomCtx);
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const containerStyle3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!canvasContent || canvasContent.type !== "composition") {
      return {};
    }
    const zoom = zoomMap[canvasContent.compositionId] ?? TIMELINE_MIN_ZOOM;
    return {
      ...container39,
      width: 100 * zoom + "%"
    };
  }, [canvasContent, zoomMap]);
  if (!canvasContent || canvasContent.type !== "composition") {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    ref: sliderAreaRef,
    style: containerStyle3,
    children: video ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Inner2, {}) : null
  });
};
var Inner2 = () => {
  const videoConfig = (0,remotion__WEBPACK_IMPORTED_MODULE_2__.useVideoConfig)();
  const size4 = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.useElementSize(scrollableRef, {
    triggerOnWindowResize: true,
    shouldApplyCssTransforms: true
  });
  const { isHighestContext } = useZIndex();
  const setFrame = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useTimelineSetFrame();
  const [inOutDragging, setInOutDragging] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({
    dragging: false
  });
  const timelineWidth = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(TimelineWidthContext);
  const get = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((frame2) => {
    if (timelineWidth === null) {
      throw new Error("timeline width is not yet determined");
    }
    return getXPositionOfItemInTimelineImperatively(frame2, videoConfig.durationInFrames, timelineWidth);
  }, [timelineWidth, videoConfig.durationInFrames]);
  const width = scrollableRef.current?.scrollWidth ?? 0;
  const left3 = size4?.left ?? 0;
  const { inFrame, outFrame } = useTimelineInOutFramePosition();
  const { setInAndOutFrames } = useTimelineSetInOutFramePosition();
  const [dragging, setDragging] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({
    dragging: false
  });
  const { playing, play, pause, seek } = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.usePlayer();
  const scroller = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const stopInterval = () => {
    if (scroller.current) {
      clearInterval(scroller.current);
      scroller.current = null;
    }
  };
  const onPointerDown = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (e.button !== 0) {
      return;
    }
    if (!isHighestContext) {
      return;
    }
    stopInterval();
    if (!videoConfig) {
      return;
    }
    document.body.style.userSelect = "none";
    document.body.style.webkitUserSelect = "none";
    if (e.target === inPointerHandle.current) {
      if (inFrame === null) {
        throw new Error("expected outframe");
      }
      const inMarker = get(inFrame);
      const outMarker = outFrame === null ? Infinity : get(outFrame - 1);
      setInOutDragging({
        dragging: "in",
        initialOffset: getClientXWithScroll(e.clientX),
        boundaries: [-Infinity, outMarker - inMarker]
      });
      return;
    }
    if (e.target === outPointerHandle.current) {
      if (outFrame === null) {
        throw new Error("expected outframe");
      }
      const outMarker = get(outFrame);
      const inMarker = inFrame === null ? -Infinity : get(inFrame + 1);
      setInOutDragging({
        dragging: "out",
        initialOffset: getClientXWithScroll(e.clientX),
        boundaries: [inMarker - outMarker, Infinity]
      });
      return;
    }
    if (e.button !== 0) {
      return;
    }
    const frame2 = getFrameFromX({
      clientX: getClientXWithScroll(e.clientX) - left3,
      durationInFrames: videoConfig.durationInFrames,
      width,
      extrapolate: "clamp"
    });
    seek(frame2);
    setDragging({
      dragging: true,
      wasPlaying: playing
    });
    pause();
  }, [
    isHighestContext,
    videoConfig,
    left3,
    width,
    seek,
    playing,
    pause,
    inFrame,
    get,
    outFrame
  ]);
  const onPointerMoveScrubbing = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (!videoConfig) {
      return;
    }
    if (!dragging.dragging) {
      return;
    }
    const isRightOfArea = e.clientX >= scrollableRef.current?.clientWidth + left3 - TIMELINE_PADDING;
    const isLeftOfArea = e.clientX <= left3;
    const frame2 = getFrameFromX({
      clientX: getClientXWithScroll(e.clientX) - left3,
      durationInFrames: videoConfig.durationInFrames,
      width,
      extrapolate: "clamp"
    });
    if (isLeftOfArea && canScrollTimelineIntoDirection().canScrollLeft) {
      if (scroller.current) {
        return;
      }
      const scrollEvery = () => {
        if (!canScrollTimelineIntoDirection().canScrollLeft) {
          stopInterval();
          return;
        }
        const nextFrame = getFrameWhileScrollingLeft({
          durationInFrames: videoConfig.durationInFrames,
          width
        });
        const scrollPos = getScrollPositionForCursorOnLeftEdge({
          nextFrame,
          durationInFrames: videoConfig.durationInFrames
        });
        redrawTimelineSliderFast.current?.draw(nextFrame);
        seek(nextFrame);
        scrollToTimelineXOffset(scrollPos);
      };
      scrollEvery();
      scroller.current = setInterval(() => {
        scrollEvery();
      }, 100);
    } else if (isRightOfArea && canScrollTimelineIntoDirection().canScrollRight) {
      if (scroller.current) {
        return;
      }
      const scrollEvery = () => {
        if (!canScrollTimelineIntoDirection().canScrollRight) {
          stopInterval();
          return;
        }
        const nextFrame = getFrameWhileScrollingRight({
          durationInFrames: videoConfig.durationInFrames,
          width
        });
        const scrollPos = getScrollPositionForCursorOnRightEdge({
          nextFrame,
          durationInFrames: videoConfig.durationInFrames
        });
        redrawTimelineSliderFast.current?.draw(nextFrame);
        seek(nextFrame);
        scrollToTimelineXOffset(scrollPos);
      };
      scrollEvery();
      scroller.current = setInterval(() => {
        scrollEvery();
      }, 100);
    } else {
      stopInterval();
      seek(frame2);
    }
  }, [videoConfig, dragging.dragging, left3, width, seek]);
  const onPointerMoveInOut = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (!videoConfig) {
      return;
    }
    if (!inOutDragging.dragging) {
      return;
    }
    const offset = Math.max(inOutDragging.boundaries[0], Math.min(inOutDragging.boundaries[1], getClientXWithScroll(e.clientX) - inOutDragging.initialOffset));
    if (inOutDragging.dragging === "in") {
      if (!inPointerHandle.current) {
        throw new Error("in pointer handle");
      }
      if (!inMarkerAreaRef.current) {
        throw new Error("expected inMarkerAreaRef");
      }
      if (!inFrame) {
        throw new Error("expected inframes");
      }
      inPointerHandle.current.style.transform = `translateX(${get(inFrame) + offset}px)`;
      inMarkerAreaRef.current.style.width = String(get(inFrame) + offset) + "px";
    }
    if (inOutDragging.dragging === "out") {
      if (!outPointerHandle.current) {
        throw new Error("in pointer handle");
      }
      if (!outMarkerAreaRef.current) {
        throw new Error("in outMarkerAreaRef");
      }
      if (!outFrame) {
        throw new Error("expected outframes");
      }
      outPointerHandle.current.style.transform = `translateX(${get(outFrame) + offset}px)`;
      outMarkerAreaRef.current.style.left = String(get(outFrame) + offset) + "px";
      outMarkerAreaRef.current.style.width = String(width - get(outFrame) - offset) + "px";
    }
  }, [get, inFrame, inOutDragging, outFrame, videoConfig, width]);
  const onPointerUpScrubbing = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    stopInterval();
    document.body.style.userSelect = "";
    document.body.style.webkitUserSelect = "";
    if (!videoConfig) {
      return;
    }
    if (!dragging.dragging) {
      return;
    }
    setDragging({
      dragging: false
    });
    const frame2 = getFrameFromX({
      clientX: getClientXWithScroll(e.clientX) - left3,
      durationInFrames: videoConfig.durationInFrames,
      width,
      extrapolate: "clamp"
    });
    setFrame((c) => {
      const newObj = { ...c, [videoConfig.id]: frame2 };
      remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.persistCurrentFrame(newObj);
      return newObj;
    });
    if (dragging.wasPlaying) {
      play();
    }
  }, [dragging, left3, play, videoConfig, setFrame, width]);
  const onPointerUpInOut = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    document.body.style.userSelect = "";
    document.body.style.webkitUserSelect = "";
    if (!videoConfig) {
      return;
    }
    if (!inOutDragging.dragging) {
      return;
    }
    setInOutDragging({
      dragging: false
    });
    const frame2 = getFrameFromX({
      clientX: getClientXWithScroll(e.clientX) - left3,
      durationInFrames: videoConfig.durationInFrames,
      width,
      extrapolate: "extend"
    });
    if (inOutDragging.dragging === "in") {
      if (frame2 < 1) {
        return setInAndOutFrames((prev) => ({
          ...prev,
          [videoConfig.id]: {
            ...prev[videoConfig.id] ?? defaultInOutValue,
            inFrame: null
          }
        }));
      }
      const maxFrame = outFrame === null ? Infinity : outFrame - 1;
      setInAndOutFrames((prev) => ({
        ...prev,
        [videoConfig.id]: {
          ...prev[videoConfig.id] ?? defaultInOutValue,
          inFrame: Math.min(maxFrame, frame2)
        }
      }));
    } else {
      if (frame2 > videoConfig.durationInFrames - 2) {
        return setInAndOutFrames((prev) => ({
          ...prev,
          [videoConfig.id]: {
            ...prev[videoConfig.id] ?? defaultInOutValue,
            outFrame: null
          }
        }));
      }
      const minFrame = inFrame === null ? -Infinity : inFrame + 1;
      setInAndOutFrames((prev) => ({
        ...prev,
        [videoConfig.id]: {
          ...prev[videoConfig.id] ?? defaultInOutValue,
          outFrame: Math.max(minFrame, frame2)
        }
      }));
    }
  }, [
    inFrame,
    inOutDragging.dragging,
    left3,
    outFrame,
    setInAndOutFrames,
    videoConfig,
    width
  ]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!dragging.dragging) {
      return;
    }
    window.addEventListener("pointermove", onPointerMoveScrubbing);
    window.addEventListener("pointerup", onPointerUpScrubbing);
    return () => {
      window.removeEventListener("pointermove", onPointerMoveScrubbing);
      window.removeEventListener("pointerup", onPointerUpScrubbing);
    };
  }, [dragging.dragging, onPointerMoveScrubbing, onPointerUpScrubbing]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (inOutDragging.dragging === false) {
      return;
    }
    window.addEventListener("pointermove", onPointerMoveInOut);
    window.addEventListener("pointerup", onPointerUpInOut);
    return () => {
      window.removeEventListener("pointermove", onPointerMoveInOut);
      window.removeEventListener("pointerup", onPointerUpInOut);
    };
  }, [inOutDragging.dragging, onPointerMoveInOut, onPointerUpInOut]);
  const inContextMenu = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return [
      {
        id: "hide-in",
        keyHint: null,
        label: "Clear In marker",
        leftItem: null,
        onClick: (_, e) => {
          e?.stopPropagation();
          e?.preventDefault();
          setInAndOutFrames((prev) => ({
            ...prev,
            [videoConfig.id]: {
              ...prev[videoConfig.id] ?? defaultInOutValue,
              inFrame: null
            }
          }));
        },
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: "hide-in"
      }
    ];
  }, [setInAndOutFrames, videoConfig.id]);
  const outContextMenu = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return [
      {
        id: "hide-out",
        keyHint: null,
        label: "Clear Out marker",
        leftItem: null,
        onClick: (_, e) => {
          e?.stopPropagation();
          e?.preventDefault();
          setInAndOutFrames((prev) => ({
            ...prev,
            [videoConfig.id]: {
              ...prev[videoConfig.id] ?? defaultInOutValue,
              outFrame: null
            }
          }));
        },
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: "hide-out"
      }
    ];
  }, [setInAndOutFrames, videoConfig.id]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: style10,
    onPointerDown,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: inner,
        className: VERTICAL_SCROLLBAR_CLASSNAME
      }),
      inFrame !== null && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ContextMenu, {
        values: inContextMenu,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineInOutPointerHandle, {
          type: "in",
          atFrame: inFrame,
          dragging: inOutDragging.dragging === "in"
        })
      }),
      outFrame !== null && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ContextMenu, {
        values: outContextMenu,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineInOutPointerHandle, {
          type: "out",
          dragging: inOutDragging.dragging === "out",
          atFrame: outFrame
        })
      })
    ]
  });
};

// src/components/Timeline/TimelineList.tsx



// src/components/Timeline/TimelineListItem.tsx



// src/components/ExpandedTracksProvider.tsx


var ExpandedTracksContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.createContext)({
  expandedTracks: {},
  toggleTrack: () => {
    throw new Error("ExpandedTracksContext not initialized");
  }
});
var ExpandedTracksProvider = ({ children }) => {
  const [expandedTracks, setExpandedTracks] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({});
  const toggleTrack = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((id) => {
    setExpandedTracks((prev) => ({
      ...prev,
      [id]: !prev[id]
    }));
  }, []);
  const value = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => ({
    expandedTracks,
    toggleTrack
  }), [expandedTracks, toggleTrack]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ExpandedTracksContext.Provider, {
    value,
    children
  });
};

// src/components/Timeline/TimelineExpandedSection.tsx



// src/components/Timeline/TimelineSchemaField.tsx


var unsupportedLabel = {
  color: "rgba(255, 255, 255, 0.4)",
  fontSize: 12,
  marginLeft: "auto",
  fontStyle: "italic"
};
var draggerStyle = {
  width: 80,
  marginLeft: "auto"
};
var notEditableBackground = {
  backgroundColor: "rgba(255, 0, 0, 0.2)",
  borderRadius: 3,
  padding: "0 4px"
};
var TimelineNumberField = ({
  field,
  canUpdate,
  onSave,
  onSavingChange,
  onDragValueChange,
  onDragEnd
}) => {
  const [dragValue, setDragValue] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const dragging = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(false);
  const onValueChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newVal) => {
    dragging.current = true;
    setDragValue(newVal);
    onDragValueChange(field.key, newVal);
  }, [onDragValueChange, field.key]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    setDragValue(null);
    onSavingChange(false);
    onDragEnd();
  }, [field.currentValue, onSavingChange, onDragEnd]);
  const onValueChangeEnd = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newVal) => {
    if (canUpdate && newVal !== field.currentValue) {
      onSavingChange(true);
      onSave(field.key, newVal).catch(() => {
        onSavingChange(false);
        setDragValue(null);
      });
    } else {
      setDragValue(null);
    }
  }, [canUpdate, onSave, onSavingChange, field.key, field.currentValue]);
  const onTextChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newVal) => {
    if (canUpdate) {
      const parsed = Number(newVal);
      if (!Number.isNaN(parsed) && parsed !== field.currentValue) {
        setDragValue(parsed);
        onSavingChange(true);
        onSave(field.key, parsed).catch(() => {
          onSavingChange(false);
          setDragValue(null);
        });
      }
    }
  }, [canUpdate, onSave, onSavingChange, field.key, field.currentValue]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InputDragger, {
    type: "number",
    value: dragValue ?? field.currentValue,
    style: draggerStyle,
    status: "ok",
    onValueChange,
    onValueChangeEnd,
    onTextChange,
    min: getZodNumberMinimum(field.fieldSchema),
    max: getZodNumberMaximum(field.fieldSchema),
    step: getZodNumberStep(field.fieldSchema),
    rightAlign: true
  });
};
var TimelineFieldValue = ({
  field,
  onSave,
  onSavingChange,
  onDragValueChange,
  onDragEnd,
  propStatus,
  canUpdate
}) => {
  const wrapperStyle = canUpdate === null || canUpdate === false ? notEditableBackground : undefined;
  if (!field.supported) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
      style: unsupportedLabel,
      children: "unsupported"
    });
  }
  if (propStatus !== null && !propStatus.canUpdate) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
      style: unsupportedLabel,
      children: propStatus.reason
    });
  }
  if (propStatus === null) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
      style: { ...notEditableBackground },
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
        style: unsupportedLabel,
        children: "error"
      })
    });
  }
  if (field.typeName === "number") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
      style: wrapperStyle,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineNumberField, {
        field,
        canUpdate,
        onSave,
        onSavingChange,
        onDragValueChange,
        onDragEnd
      })
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
    style: { ...unsupportedLabel, fontStyle: "normal" },
    children: String(field.currentValue)
  });
};
var TimelineFieldSavingSpinner = ({ saving }) => {
  if (!saving) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spinner, {
    duration: 0.5,
    size: 12
  });
};

// src/components/Timeline/TimelineExpandedSection.tsx

var expandedSectionBase = {
  color: "white",
  fontFamily: "Arial, Helvetica, sans-serif",
  fontSize: 12,
  display: "flex",
  flexDirection: "column",
  paddingLeft: 28,
  paddingRight: 10,
  borderBottom: `1px solid ${TIMELINE_TRACK_SEPARATOR}`
};
var fieldRow = {
  display: "flex",
  alignItems: "center",
  gap: 8
};
var fieldName = {
  fontSize: 12
};
var fieldLabelRow = {
  flex: 1,
  display: "flex",
  flexDirection: "row",
  alignItems: "center",
  gap: 6
};
var TimelineFieldRow = ({ field, onSave, onDragValueChange, onDragEnd, propStatus }) => {
  const [saving, setSaving] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const onSavingChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((s) => {
    setSaving(s);
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: { ...fieldRow, height: field.rowHeight },
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: fieldLabelRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
            style: fieldName,
            children: field.key
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineFieldSavingSpinner, {
            saving
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineFieldValue, {
        field,
        propStatus,
        onSave,
        onSavingChange,
        onDragValueChange,
        onDragEnd,
        canUpdate: propStatus?.canUpdate ?? false
      })
    ]
  });
};
var TimelineExpandedSection = ({ sequence, originalLocation }) => {
  const [propStatuses, setPropStatuses] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const schemaFields = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => getSchemaFields(sequence.controls), [sequence.controls]);
  const validatedLocation = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!originalLocation || !originalLocation.source || !originalLocation.line) {
      return null;
    }
    return {
      source: originalLocation.source,
      line: originalLocation.line,
      column: originalLocation.column ?? 0
    };
  }, [originalLocation]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!sequence.controls || !validatedLocation || !schemaFields) {
      setPropStatuses(null);
      return;
    }
    callApi("/api/can-update-sequence-props", {
      fileName: validatedLocation.source,
      line: validatedLocation.line,
      column: validatedLocation.column,
      keys: schemaFields.map((f) => f.key)
    }).then((result) => {
      if (result.canUpdate) {
        setPropStatuses(result.props);
      } else {
        setPropStatuses(null);
      }
    }).catch(() => {
      setPropStatuses(null);
    });
  }, [sequence.controls, validatedLocation, schemaFields]);
  const expandedHeight = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => getExpandedTrackHeight(sequence.controls), [sequence.controls]);
  const { setOverride, clearOverrides } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.SequenceControlOverrideContext);
  const onSave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((key4, value) => {
    if (!propStatuses || !validatedLocation) {
      return Promise.reject(new Error("Cannot save"));
    }
    const status = propStatuses[key4];
    if (!status || !status.canUpdate) {
      return Promise.reject(new Error("Cannot save"));
    }
    return callApi("/api/save-sequence-props", {
      fileName: validatedLocation.source,
      line: validatedLocation.line,
      column: validatedLocation.column,
      key: key4,
      value: JSON.stringify(value),
      enumPaths: []
    }).then(() => {
      return;
    });
  }, [propStatuses, validatedLocation]);
  const onDragValueChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((key4, value) => {
    setOverride(sequence.id, key4, value);
  }, [setOverride, sequence.id]);
  const onDragEnd = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    clearOverrides(sequence.id);
  }, [clearOverrides, sequence.id]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: { ...expandedSectionBase, height: expandedHeight },
    children: schemaFields ? schemaFields.map((field) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineFieldRow, {
      field,
      propStatus: propStatuses?.[field.key] ?? null,
      onSave,
      onDragValueChange,
      onDragEnd
    }, field.key)) : "No schema"
  });
};

// src/components/Timeline/TimelineLayerEye.tsx


var eyeIcon = {
  width: 12,
  color: "currentColor",
  pointerEvents: "none"
};
var speakerIcon = {
  ...eyeIcon,
  height: 10,
  marginLeft: -1
};
var container40 = {
  height: 16,
  width: 16,
  borderRadius: 2,
  backgroundColor: "rgba(0, 0, 0, 0.4)",
  display: "inline-flex",
  justifyContent: "center",
  alignItems: "center",
  marginRight: 6,
  flexShrink: 0
};
var layerPointedDown = null;
var TimelineLayerEye = ({ onInvoked, hidden, type }) => {
  const renderAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    if (hidden) {
      return null;
    }
    if (type === "speaker") {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
        viewBox: "0 0 10 14",
        fill: "none",
        style: speakerIcon,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
          d: "M9.40938 0.0869018C9.76875 0.249402 10 0.605652 10 0.999402V12.9994C10 13.3932 9.76875 13.7494 9.40938 13.9119C9.05 14.0744 8.62813 14.0088 8.33438 13.7463L4.11875 9.9994H2C0.896875 9.9994 0 9.10253 0 7.9994V5.9994C0 4.89628 0.896875 3.9994 2 3.9994H4.11875L8.33438 0.252527C8.62813 -0.0099732 9.05 -0.0724732 9.40938 0.0869018Z",
          fill: color
        })
      });
    }
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      style: eyeIcon,
      viewBox: "0 0 24 16",
      fill: "none",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        d: "M24 7.551C24 7.551 19.748 16 12.015 16C4.835 16 0 7.551 0 7.551C0 7.551 4.446 0 12.015 0C19.709 0 24 7.551 24 7.551ZM17 8C17 5.243 14.757 3 12 3C9.243 3 7 5.243 7 8C7 10.757 9.243 13 12 13C14.757 13 17 10.757 17 8Z",
        fill: color
      })
    });
  }, [hidden, type]);
  const onPointerDown = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (e.button !== 0) {
      return;
    }
    layerPointedDown = hidden ? "enable" : "disable";
    onInvoked(layerPointedDown);
    window.addEventListener("pointerup", () => {
      layerPointedDown = null;
    }, { once: true });
  }, [hidden, onInvoked]);
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (layerPointedDown) {
      onInvoked(layerPointedDown);
    }
  }, [onInvoked]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: container40,
    onPointerEnter,
    onPointerDown,
    children: renderAction(LIGHT_COLOR)
  });
};

// src/components/Timeline/TimelineStack/index.tsx




var publicPath = window.remotion_publicPath === "/" ? "" : window.remotion_publicPath;
var withoutSlashInTheEnd = publicPath.endsWith("/") ? publicPath.slice(0, -1) : publicPath;
source_map__WEBPACK_IMPORTED_MODULE_11__.SourceMapConsumer.initialize({
  "lib/mappings.wasm": withoutSlashInTheEnd + _remotion_studio_shared__WEBPACK_IMPORTED_MODULE_6__/* .SOURCE_MAP_ENDPOINT */ .fC
});
var TimelineStack = ({ isCompact, sequence, originalLocation }) => {
  const [stackHovered, setStackHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const [titleHovered, setTitleHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const [opening, setOpening] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const selectAsset = useSelectAsset();
  const connectionStatus = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx).previewServerState.type;
  const assetPath = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (sequence.type !== "video" && sequence.type !== "audio") {
      return null;
    }
    const isStatic = sequence.src.startsWith(window.remotion_staticBase);
    if (!isStatic) {
      return null;
    }
    const relativePath = sequence.src.replace(window.remotion_staticBase + "/", "");
    return relativePath;
  }, [sequence]);
  const navigateToAsset = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((asset) => {
    selectAsset(asset);
    pushUrl(`/assets/${asset}`);
  }, [selectAsset]);
  const openEditor = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(async (location2) => {
    if (!window.remotion_editorName) {
      return;
    }
    setOpening(true);
    try {
      await openOriginalPositionInEditor(location2);
    } catch (err) {
      showNotification(err.message, 2000);
    } finally {
      setOpening(false);
    }
  }, []);
  const canOpenInEditor = window.remotion_editorName && connectionStatus === "connected" && originalLocation;
  const canOpenInGitHub = window.remotion_gitSource && originalLocation;
  const titleHoverable = isCompact && (canOpenInEditor || canOpenInGitHub) || assetPath;
  const stackHoverable = !isCompact && (canOpenInEditor || canOpenInGitHub);
  const onClickTitle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (!titleHoverable) {
      return null;
    }
    if (assetPath) {
      navigateToAsset(assetPath);
      return;
    }
    if (!originalLocation) {
      return;
    }
    if (canOpenInEditor) {
      openEditor(originalLocation);
      return;
    }
    if (canOpenInGitHub) {
      window.open(getGitRefUrl(window.remotion_gitSource, originalLocation), "_blank");
    }
  }, [
    assetPath,
    canOpenInEditor,
    canOpenInGitHub,
    navigateToAsset,
    openEditor,
    originalLocation,
    titleHoverable
  ]);
  const onClickStack = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (!originalLocation) {
      return;
    }
    if (canOpenInEditor) {
      openEditor(originalLocation);
      return;
    }
    if (canOpenInGitHub) {
      window.open(getGitRefUrl(window.remotion_gitSource, originalLocation), "_blank");
    }
  }, [canOpenInEditor, canOpenInGitHub, openEditor, originalLocation]);
  const onStackPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setStackHovered(true);
  }, []);
  const onStackPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setStackHovered(false);
  }, []);
  const onTitlePointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setTitleHovered(true);
  }, []);
  const onTitlePointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setTitleHovered(false);
  }, []);
  const style11 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      fontSize: 12,
      color: opening ? VERY_LIGHT_TEXT : stackHovered && stackHoverable ? LIGHT_TEXT : VERY_LIGHT_TEXT,
      marginLeft: 10,
      cursor: stackHoverable ? "pointer" : undefined,
      display: "flex",
      flexDirection: "row",
      alignItems: "center",
      whiteSpace: "nowrap",
      textOverflow: "ellipsis",
      overflow: "hidden",
      flexShrink: 1e5
    };
  }, [opening, stackHovered, stackHoverable]);
  const titleStyle2 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const hoverEffect = titleHovered && titleHoverable;
    return {
      fontSize: 12,
      whiteSpace: "nowrap",
      textOverflow: "ellipsis",
      overflow: "hidden",
      lineHeight: 1.2,
      color: opening && isCompact ? VERY_LIGHT_TEXT : LIGHT_COLOR,
      userSelect: "none",
      WebkitUserSelect: "none",
      borderBottom: hoverEffect ? "1px solid #fff" : "none",
      cursor: hoverEffect ? "pointer" : undefined
    };
  }, [titleHoverable, isCompact, opening, titleHovered]);
  const text = sequence.displayName.length > 1000 ? sequence.displayName.slice(0, 1000) + "..." : sequence.displayName;
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        onPointerEnter: onTitlePointerEnter,
        onPointerLeave: onTitlePointerLeave,
        title: originalLocation ? getOriginalSourceAttribution(originalLocation) : text || "<Sequence>",
        style: titleStyle2,
        onClick: onClickTitle,
        children: text || "<Sequence>"
      }),
      isCompact || !originalLocation ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        onPointerEnter: onStackPointerEnter,
        onPointerLeave: onStackPointerLeave,
        onClick: onClickStack,
        style: style11,
        children: getOriginalSourceAttribution(originalLocation)
      }),
      opening ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 0.5
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spinner, {
            duration: 0.5,
            size: 12
          })
        ]
      }) : null
    ]
  });
};

// src/components/Timeline/TimelineListItem.tsx

var SPACING = 5;
var space = {
  width: SPACING,
  flexShrink: 0
};
var arrowButton = {
  background: "none",
  border: "none",
  color: "white",
  cursor: "pointer",
  padding: 0,
  display: "flex",
  alignItems: "center",
  justifyContent: "center",
  width: 12,
  height: 12,
  flexShrink: 0,
  fontSize: 8,
  marginRight: 4,
  userSelect: "none",
  outline: "none",
  lineHeight: 1
};
var TimelineListItem = ({ nestedDepth, sequence, isCompact }) => {
  const visualModeEnabled = Boolean(false);
  const { hidden, setHidden } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.SequenceVisibilityToggleContext);
  const { expandedTracks, toggleTrack } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ExpandedTracksContext);
  const [originalLocation, setOriginalLocation] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!sequence.stack) {
      return;
    }
    getOriginalLocationFromStack(sequence.stack, "sequence").then((frame2) => {
      setOriginalLocation(frame2);
    }).catch((err) => {
      console.error("Could not get original location of Sequence", err);
    });
  }, [sequence.stack]);
  const isExpanded = expandedTracks[sequence.id] ?? false;
  const onToggleExpand = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    toggleTrack(sequence.id);
  }, [sequence.id, toggleTrack]);
  const padder = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      width: Number(SPACING * 1.5) * nestedDepth,
      flexShrink: 0
    };
  }, [nestedDepth]);
  const isItemHidden = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return hidden[sequence.id] ?? false;
  }, [hidden, sequence.id]);
  const onToggleVisibility = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((type) => {
    setHidden((prev) => {
      return {
        ...prev,
        [sequence.id]: type !== "enable"
      };
    });
  }, [sequence.id, setHidden]);
  const outer2 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      height: getTimelineLayerHeight(sequence.type === "video" ? "video" : "other") + TIMELINE_ITEM_BORDER_BOTTOM,
      color: "white",
      fontFamily: "Arial, Helvetica, sans-serif",
      display: "flex",
      flexDirection: "row",
      alignItems: "center",
      wordBreak: "break-all",
      textAlign: "left",
      paddingLeft: SPACING,
      borderBottom: `1px solid ${TIMELINE_TRACK_SEPARATOR}`
    };
  }, [sequence.type]);
  const arrowStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...arrowButton,
      transform: isExpanded ? "rotate(90deg)" : "rotate(0deg)"
    };
  }, [isExpanded]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: outer2,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineLayerEye, {
            type: sequence.type === "audio" ? "speaker" : "eye",
            hidden: isItemHidden,
            onInvoked: onToggleVisibility
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: padder
          }),
          sequence.parent && nestedDepth > 0 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: space
          }) : null,
          visualModeEnabled ? sequence.controls ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
            type: "button",
            style: arrowStyle,
            onClick: onToggleExpand,
            "aria-expanded": isExpanded,
            "aria-label": `${isExpanded ? "Collapse" : "Expand"} track`,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
              width: "12",
              height: "12",
              viewBox: "0 0 8 8",
              style: { display: "block" },
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
                d: "M2 1L6 4L2 7Z",
                fill: "white"
              })
            })
          }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: arrowButton
          }) : null,
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineStack, {
            sequence,
            isCompact,
            originalLocation
          })
        ]
      }),
      visualModeEnabled && isExpanded && sequence.controls ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineExpandedSection, {
        sequence,
        originalLocation
      }) : null
    ]
  });
};

// src/components/Timeline/TimelineTimeIndicators.tsx



// src/components/TimeValue.tsx




var text = {
  color: "white",
  display: "flex",
  flexDirection: "row",
  alignItems: "center",
  fontVariantNumeric: "tabular-nums",
  lineHeight: 1,
  width: "100%"
};
var time = {
  display: "inline-block",
  fontSize: 16,
  lineHeight: 1,
  fontFamily: "monospace"
};
var frameStyle = {
  color: LIGHT_TEXT,
  fontWeight: 500,
  lineHeight: 1,
  fontSize: 16,
  fontFamily: "monospace",
  paddingRight: 10
};
var TimeValue = () => {
  const frame2 = (0,remotion__WEBPACK_IMPORTED_MODULE_2__.useCurrentFrame)();
  const config = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useUnsafeVideoConfig();
  const isStill = useIsStill();
  const { seek, play, pause, toggle } = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.usePlayer();
  const keybindings = useKeybinding();
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const onTextChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newVal) => {
    seek(parseInt(newVal, 10));
  }, [seek]);
  const onValueChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((val) => {
    seek(val);
  }, [seek]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.timeValueRef, () => ({
    goToFrame: () => {
      ref.current?.click();
    },
    seek,
    play,
    pause,
    toggle
  }), [seek, play, pause, toggle]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const gKey = keybindings.registerKeybinding({
      event: "keypress",
      key: "g",
      callback: () => {
        ref.current?.click();
      },
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      gKey.unregister();
    };
  }, [keybindings]);
  if (!config) {
    return null;
  }
  if (isStill) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: text,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: time,
        children: renderFrame(frame2, config.fps)
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 2
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InputDragger, {
        ref,
        value: frame2,
        onTextChange,
        onValueChange,
        rightAlign: true,
        status: "ok",
        style: frameStyle
      })
    ]
  });
};

// src/components/Timeline/TimelineTimeIndicators.tsx

var TIMELINE_TIME_INDICATOR_HEIGHT = 39;
var container41 = {
  height: TIMELINE_TIME_INDICATOR_HEIGHT - 4,
  boxShadow: `0 0 4px ${TIMELINE_BACKGROUND}`,
  position: "absolute",
  backgroundColor: TIMELINE_BACKGROUND,
  top: 0
};
var tick = {
  width: 1,
  backgroundColor: "rgba(255, 255, 255, 0.15)",
  height: 20,
  position: "absolute"
};
var secondTick = {
  ...tick,
  height: 15
};
var tickLabel = {
  fontSize: 12,
  marginLeft: 8,
  marginTop: 7,
  color: LIGHT_TEXT
};
var timeValue = {
  height: TIMELINE_TIME_INDICATOR_HEIGHT,
  position: "absolute",
  top: 0,
  width: "100%",
  paddingLeft: 10,
  display: "flex",
  alignItems: "center",
  backgroundColor: BACKGROUND,
  borderBottom: `${TIMELINE_ITEM_BORDER_BOTTOM}px solid ${TIMELINE_TRACK_SEPARATOR}`
};
var TimelineTimePlaceholders = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: timeValue,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimeValue, {})
  });
};
var TimelineTimePadding = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: {
      height: TIMELINE_TIME_INDICATOR_HEIGHT
    }
  });
};
var TimelineTimeIndicators = () => {
  const sliderTrack = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(TimelineWidthContext);
  const video = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useVideo();
  if (sliderTrack === null) {
    return null;
  }
  if (video === null) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Inner3, {
    durationInFrames: video.durationInFrames,
    fps: video.fps,
    windowWidth: sliderTrack
  });
};
var Inner3 = ({ windowWidth, durationInFrames, fps }) => {
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const currentRef = ref.current;
    if (!currentRef) {
      return;
    }
    const { current } = timelineVerticalScroll;
    if (!current) {
      return;
    }
    const onScroll = () => {
      currentRef.style.top = current.scrollTop + "px";
    };
    current.addEventListener("scroll", onScroll);
    return () => {
      current.removeEventListener("scroll", onScroll);
    };
  }, []);
  const style11 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...container41,
      width: windowWidth - SPLITTER_HANDLE_SIZE / 2,
      overflow: "hidden",
      marginLeft: SPLITTER_HANDLE_SIZE / 2,
      pointerEvents: "none"
    };
  }, [windowWidth]);
  const ticks = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const frameInterval = getFrameIncrementFromWidth(durationInFrames, windowWidth);
    const MIN_SPACING_BETWEEN_TICKS_PX = 5;
    const seconds = Math.floor(durationInFrames / fps);
    const secondMarkerEveryNth = Math.ceil(MIN_SPACING_BETWEEN_TICKS_PX * fps / (frameInterval * fps));
    const frameMarkerEveryNth = Math.ceil(MIN_SPACING_BETWEEN_TICKS_PX / frameInterval);
    const secondTicks = new Array(seconds).fill(true).map((_, index) => {
      return {
        frame: index * fps,
        style: {
          ...secondTick,
          left: frameInterval * index * fps + TIMELINE_PADDING - SPLITTER_HANDLE_SIZE / 2
        },
        showTime: index > 0
      };
    }).filter((_, idx) => idx % secondMarkerEveryNth === 0);
    const frameTicks = new Array(durationInFrames).fill(true).map((_, index) => {
      return {
        frame: index,
        style: {
          ...tick,
          left: frameInterval * index + TIMELINE_PADDING - SPLITTER_HANDLE_SIZE / 2,
          height: index % fps === 0 ? 10 : index / frameMarkerEveryNth % 2 === 0 ? 5 : 2
        },
        showTime: false
      };
    }).filter((_, idx) => idx % frameMarkerEveryNth === 0);
    const hasTicks = [];
    return [...secondTicks, ...frameTicks].filter((t) => {
      const alreadyUsed = hasTicks.find((ht) => ht === t.frame) !== undefined;
      hasTicks.push(t.frame);
      return !alreadyUsed;
    });
  }, [durationInFrames, fps, windowWidth]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    ref,
    style: style11,
    children: ticks.map((t) => {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: t.style,
        children: t.showTime ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: tickLabel,
          children: renderFrame(t.frame, fps)
        }) : null
      }, t.frame);
    })
  });
};

// src/components/Timeline/TimelineList.tsx

var container42 = {
  flex: 1,
  background: BACKGROUND
};
var TimelineList = ({ timeline }) => {
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const size4 = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.useElementSize(ref, {
    shouldApplyCssTransforms: false,
    triggerOnWindowResize: false
  });
  const isCompact = size4 ? size4.width < 250 : false;
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    ref,
    style: container42,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineTimePadding, {}),
      timeline.map((track) => {
        return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineListItem, {
            nestedDepth: track.depth,
            sequence: track.sequence,
            isCompact
          }, track.sequence.id)
        }, track.sequence.id);
      })
    ]
  });
};

// src/components/Timeline/TimelinePlayCursorSyncer.tsx


var lastTimelinePositionWhileScrolling = null;
var TimelinePlayCursorSyncer = () => {
  const video = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useVideo();
  const timelineContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.TimelineContext);
  const timelinePosition = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.Timeline.useTimelinePosition();
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const { zoom: zoomMap } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(TimelineZoomCtx);
  const compositionId = canvasContent && canvasContent.type === "composition" ? canvasContent.compositionId : null;
  const zoom = compositionId ? zoomMap[compositionId] ?? TIMELINE_MIN_ZOOM : null;
  if (zoom && video) {
    setCurrentFrame(timelinePosition);
    setCurrentZoom(zoom);
    setCurrentDuration(video.durationInFrames);
    setCurrentFps(video.fps);
  }
  const playing = timelineContext.playing ?? false;
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!video) {
      return;
    }
    if (!playing) {
      return;
    }
    ensureFrameIsInViewport({
      direction: timelineContext.playbackRate > 0 ? "page-right" : "page-left",
      durationInFrames: video.durationInFrames,
      frame: timelinePosition
    });
  }, [playing, timelineContext, timelinePosition, video]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const { current } = scrollableRef;
    if (!current) {
      return;
    }
    if (playing) {
      lastTimelinePositionWhileScrolling = {
        scrollLeft: current.scrollLeft,
        frame: getCurrentFrame(),
        zoomLevel: getCurrentZoom(),
        durationInFrames: getCurrentDuration()
      };
    } else if (lastTimelinePositionWhileScrolling !== null) {
      if (isCursorInViewport({
        frame: getCurrentFrame(),
        durationInFrames: getCurrentDuration()
      })) {
        return;
      }
      if (lastTimelinePositionWhileScrolling.zoomLevel === getCurrentZoom() && lastTimelinePositionWhileScrolling.durationInFrames === getCurrentDuration()) {
        current.scrollLeft = lastTimelinePositionWhileScrolling.scrollLeft;
      } else {
        ensureFrameIsInViewport({
          direction: "center",
          durationInFrames: getCurrentDuration(),
          frame: lastTimelinePositionWhileScrolling.frame
        });
      }
    }
  }, [playing]);
  return null;
};

// src/components/Timeline/TimelineScrollable.tsx


var outer2 = {
  width: "100%",
  height: "100%",
  overflowX: "auto",
  overflowY: "hidden",
  position: "relative",
  backgroundColor: TIMELINE_BACKGROUND
};
var TimelineScrollable = ({ children }) => {
  const containerStyle3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      width: "100%",
      minHeight: "100%"
    };
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    ref: scrollableRef,
    style: outer2,
    className: HORIZONTAL_SCROLLBAR_CLASSNAME,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: containerStyle3,
      children
    })
  });
};

// src/components/Timeline/TimelineTracks.tsx


// src/components/Timeline/TimelineSequence.tsx



// src/helpers/get-timeline-sequence-layout.ts
var SEQUENCE_BORDER_WIDTH = 1;
var getWidthOfTrack = ({
  durationInFrames,
  lastFrame,
  windowWidth,
  spatialDuration,
  nonNegativeMarginLeft
}) => {
  const fullWidth9 = windowWidth - TIMELINE_PADDING * 2;
  const base = durationInFrames === Infinity || lastFrame === 0 ? fullWidth9 : spatialDuration / lastFrame * fullWidth9;
  return base - SEQUENCE_BORDER_WIDTH + nonNegativeMarginLeft;
};
var getTimelineSequenceLayout = ({
  durationInFrames,
  startFrom,
  maxMediaDuration,
  startFromMedia,
  video,
  windowWidth,
  premountDisplay,
  postmountDisplay
}) => {
  const maxMediaSequenceDuration = (maxMediaDuration ?? Infinity) - startFromMedia;
  const lastFrame = (video.durationInFrames ?? 1) - 1;
  let spatialDuration = Math.min(maxMediaSequenceDuration, durationInFrames - 1, lastFrame - startFrom);
  let naturalSpatialDuration = Math.min(maxMediaSequenceDuration, durationInFrames - 1);
  const shouldAddHalfAFrameAtEnd = startFrom + durationInFrames < lastFrame;
  const shouldAddHalfAFrameAtStart = startFrom > 0;
  if (shouldAddHalfAFrameAtEnd) {
    spatialDuration += 0.5;
    naturalSpatialDuration += 0.5;
  }
  if (shouldAddHalfAFrameAtStart) {
    spatialDuration += 0.5;
    naturalSpatialDuration += 0.5;
  }
  const startFromWithOffset = shouldAddHalfAFrameAtStart ? startFrom - 0.5 : startFrom;
  const marginLeft = lastFrame === 0 ? 0 : startFromWithOffset / lastFrame * (windowWidth - TIMELINE_PADDING * 2);
  const nonNegativeMarginLeft = Math.min(marginLeft, 0);
  const width = getWidthOfTrack({
    durationInFrames,
    lastFrame,
    nonNegativeMarginLeft,
    spatialDuration,
    windowWidth
  });
  const naturalWidth = getWidthOfTrack({
    durationInFrames,
    lastFrame,
    nonNegativeMarginLeft,
    spatialDuration: naturalSpatialDuration,
    windowWidth
  });
  const premountWidth = premountDisplay ? getWidthOfTrack({
    durationInFrames: premountDisplay,
    lastFrame,
    nonNegativeMarginLeft,
    spatialDuration: premountDisplay,
    windowWidth
  }) : null;
  const postmountWidth = postmountDisplay ? getWidthOfTrack({
    durationInFrames: postmountDisplay,
    lastFrame,
    nonNegativeMarginLeft,
    spatialDuration: postmountDisplay,
    windowWidth
  }) : null;
  return {
    marginLeft: Math.max(marginLeft, 0) - (premountWidth ?? 0),
    width: width + (premountWidth ?? 0) + (postmountWidth ?? 0),
    naturalWidth: naturalWidth + (premountWidth ?? 0) + (postmountWidth ?? 0),
    premountWidth,
    postmountWidth
  };
};

// src/helpers/use-max-media-duration.ts



var cache = new Map;
var getSrc = (s) => {
  if (s.type === "video") {
    return s.src;
  }
  if (s.type === "audio") {
    return s.src;
  }
  return null;
};
var useMaxMediaDuration = (s, fps) => {
  const src = getSrc(s);
  const [maxMediaDuration, setMaxMediaDuration] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(src ? cache.get(src) ?? null : Infinity);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!src) {
      return;
    }
    const input2 = new mediabunny__WEBPACK_IMPORTED_MODULE_9__/* .Input */ .p({
      formats: mediabunny__WEBPACK_IMPORTED_MODULE_8__/* .ALL_FORMATS */ .XE,
      source: new mediabunny__WEBPACK_IMPORTED_MODULE_7__/* .UrlSource */ .Ts(src)
    });
    input2.computeDuration().then((duration) => {
      cache.set(src, Math.floor(duration * fps));
      setMaxMediaDuration(Math.floor(duration * fps));
    }).catch((e) => {
      if (e instanceof mediabunny__WEBPACK_IMPORTED_MODULE_9__/* .InputDisposedError */ .Q) {
        return;
      }
      return (0,_remotion_media_utils__WEBPACK_IMPORTED_MODULE_10__.getVideoMetadata)(src).then((metadata) => {
        const durationOrInfinity = metadata.durationInSeconds ?? Infinity;
        cache.set(src, Math.floor(durationOrInfinity * fps));
        setMaxMediaDuration(Math.floor(durationOrInfinity * fps));
      }).catch(() => {});
    });
    return () => {
      input2.dispose();
    };
  }, [src, fps]);
  if (maxMediaDuration !== null && (s.type === "audio" || s.type === "video")) {
    return maxMediaDuration / s.playbackRate;
  }
  return maxMediaDuration;
};

// src/components/AudioWaveform.tsx




// src/components/AudioWaveformBar.tsx


var WAVEFORM_BAR_LENGTH = 2;
var WAVEFORM_BAR_MARGIN = 1;
var container43 = {
  width: WAVEFORM_BAR_LENGTH,
  backgroundColor: "rgba(255, 255, 255, 0.6)",
  marginLeft: WAVEFORM_BAR_MARGIN,
  borderRadius: 2
};
var AudioWaveformBar = ({ amplitude }) => {
  const style11 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...container43,
      height: getTimelineLayerHeight("other") * amplitude * (1 / 0.6366)
    };
  }, [amplitude]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: style11
  });
};

// src/components/AudioWaveform.tsx

var container44 = {
  display: "flex",
  flexDirection: "row",
  alignItems: "flex-end",
  position: "absolute",
  height: getTimelineLayerHeight("other")
};
var errorMessage = {
  fontSize: 13,
  paddingTop: 6,
  paddingBottom: 6,
  paddingLeft: 12,
  paddingRight: 12,
  alignSelf: "flex-start",
  maxWidth: 450,
  opacity: 0.75
};
var canvasStyle = {
  position: "absolute"
};
var AudioWaveform = ({
  src,
  startFrom,
  durationInFrames,
  visualizationWidth,
  volume,
  doesVolumeChange,
  playbackRate
}) => {
  const [metadata, setMetadata] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const [error, setError] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const mountState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)({ isMounted: true });
  const vidConf = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useUnsafeVideoConfig();
  if (vidConf === null) {
    throw new Error("Expected video config");
  }
  const canvas = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const { current } = mountState;
    current.isMounted = true;
    return () => {
      current.isMounted = false;
    };
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!canvas.current) {
      return;
    }
    const context = canvas.current.getContext("2d");
    if (!context) {
      return;
    }
    context.clearRect(0, 0, visualizationWidth, getTimelineLayerHeight("other"));
    if (!doesVolumeChange || typeof volume === "number") {
      return;
    }
    const volumes = volume.split(",").map((v) => Number(v));
    context.beginPath();
    context.moveTo(0, getTimelineLayerHeight("other"));
    volumes.forEach((v, index) => {
      const x = index / (volumes.length - 1) * visualizationWidth;
      const y = (1 - v) * (getTimelineLayerHeight("other") - TIMELINE_BORDER * 2) + 1;
      if (index === 0) {
        context.moveTo(x, y);
      } else {
        context.lineTo(x, y);
      }
    });
    context.strokeStyle = LIGHT_TRANSPARENT;
    context.stroke();
  }, [visualizationWidth, metadata, startFrom, volume, doesVolumeChange]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    setError(null);
    (0,_remotion_media_utils__WEBPACK_IMPORTED_MODULE_10__.getAudioData)(src).then((data) => {
      if (mountState.current.isMounted) {
        setMetadata(data);
      }
    }).catch((err) => {
      if (mountState.current.isMounted) {
        setError(err);
      }
    });
  }, [src, vidConf.fps]);
  const normalized = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!metadata || metadata.numberOfChannels === 0) {
      return [];
    }
    const numberOfSamples = Math.floor(visualizationWidth / (WAVEFORM_BAR_LENGTH + WAVEFORM_BAR_MARGIN));
    return (0,_remotion_media_utils__WEBPACK_IMPORTED_MODULE_10__.getWaveformPortion)({
      audioData: metadata,
      startTimeInSeconds: startFrom / vidConf.fps,
      durationInSeconds: Math.min(durationInFrames / vidConf.fps * playbackRate, metadata.durationInSeconds),
      numberOfSamples,
      normalize: false
    });
  }, [
    durationInFrames,
    vidConf.fps,
    metadata,
    playbackRate,
    startFrom,
    visualizationWidth
  ]);
  if (error) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
      style: container44,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: errorMessage,
        children: "No waveform available. Audio might not support CORS."
      })
    });
  }
  if (!metadata) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container44,
    children: [
      normalized.map((w) => {
        return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(AudioWaveformBar, {
          amplitude: w.amplitude * (typeof volume === "number" ? volume : 1)
        }, w.index);
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("canvas", {
        ref: canvas,
        style: canvasStyle,
        width: visualizationWidth,
        height: getTimelineLayerHeight("other")
      })
    ]
  });
};

// src/components/Timeline/LoopedTimelineIndicators.tsx



// src/components/Timeline/LoopedIndicator.tsx


var width = {
  width: 0,
  flexDirection: "row",
  display: "flex",
  position: "relative"
};
var icon5 = {
  height: 12
};
var Icon = () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
  viewBox: "0 0 512 512",
  style: icon5,
  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
    fill: LIGHT_COLOR,
    d: "M512 256c0 88.224-71.775 160-160 160H170.067l34.512 32.419c9.875 9.276 10.119 24.883.539 34.464l-10.775 10.775c-9.373 9.372-24.568 9.372-33.941 0l-92.686-92.686c-9.373-9.373-9.373-24.568 0-33.941l92.686-92.686c9.373-9.373 24.568-9.373 33.941 0l10.775 10.775c9.581 9.581 9.337 25.187-.539 34.464L170.067 352H352c52.935 0 96-43.065 96-96 0-13.958-2.996-27.228-8.376-39.204-4.061-9.039-2.284-19.626 4.723-26.633l12.183-12.183c11.499-11.499 30.965-8.526 38.312 5.982C505.814 205.624 512 230.103 512 256zM72.376 295.204C66.996 283.228 64 269.958 64 256c0-52.935 43.065-96 96-96h181.933l-34.512 32.419c-9.875 9.276-10.119 24.883-.539 34.464l10.775 10.775c9.373 9.372 24.568 9.372 33.941 0l92.686-92.686c9.373-9.373 9.373-24.568 0-33.941l-92.686-92.686c-9.373-9.373-24.568-9.373-33.941 0L306.882 29.12c-9.581 9.581-9.337 25.187.539 34.464L341.933 96H160C71.775 96 0 167.776 0 256c0 25.897 6.186 50.376 17.157 72.039 7.347 14.508 26.813 17.481 38.312 5.982l12.183-12.183c7.008-7.008 8.786-17.595 4.724-26.634z"
  })
});
var topLine = {
  top: 0,
  height: 2,
  width: 1,
  background: LIGHT_COLOR
};
var bottomLine = {
  top: 0,
  height: 2,
  width: 1,
  background: LIGHT_COLOR
};
var topContainer = {
  justifyContent: "flex-start",
  alignItems: "center"
};
var centerContainer = {
  justifyContent: "center",
  alignItems: "center"
};
var bottomContainer = {
  justifyContent: "flex-end",
  alignItems: "center"
};
var LoopedIndicator = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: width,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_2__.AbsoluteFill, {
        style: topContainer,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: topLine
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_2__.AbsoluteFill, {
        style: bottomContainer,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: bottomLine
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_2__.AbsoluteFill, {
        style: centerContainer,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Icon, {})
      })
    ]
  });
};

// src/components/Timeline/LoopedTimelineIndicators.tsx

var row7 = {
  flexDirection: "row"
};
var LoopedTimelineIndicator = ({ loops }) => {
  const leftOver = loops % 1;
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(remotion__WEBPACK_IMPORTED_MODULE_2__.AbsoluteFill, {
    style: row7,
    children: [
      new Array(Math.floor(loops)).fill(true).map((_l, i) => {
        return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
          children: [
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {}),
            i === loops - 1 ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(LoopedIndicator, {})
          ]
        }, i);
      }),
      leftOver > 0 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: { flex: leftOver }
      }) : null
    ]
  });
};

// src/components/Timeline/TimelineSequenceFrame.tsx

var relativeFrameStyle = {
  fontSize: 11,
  fontFamily: "Arial, Helvetica, sans-serif",
  color: "white",
  opacity: 0.5
};
var TimelineSequenceFrame = ({ roundedFrame, premounted, postmounted }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: relativeFrameStyle,
    children: premounted ? "0 (Premounted)" : postmounted !== null ? `${postmounted} (Postmounted)` : roundedFrame
  });
};

// src/components/Timeline/TimelineVideoInfo.tsx



// src/helpers/extract-frames.ts

async function extractFrames({
  src,
  timestampsInSeconds,
  onVideoSample,
  signal
}) {
  const input2 = new mediabunny__WEBPACK_IMPORTED_MODULE_9__/* .Input */ .p({
    formats: mediabunny__WEBPACK_IMPORTED_MODULE_8__/* .ALL_FORMATS */ .XE,
    source: new mediabunny__WEBPACK_IMPORTED_MODULE_7__/* .UrlSource */ .Ts(src)
  });
  const dispose = () => {
    input2.dispose();
  };
  if (signal) {
    signal.addEventListener("abort", dispose, { once: true });
  }
  try {
    const [durationInSeconds, format, videoTrack] = await Promise.all([
      input2.computeDuration(),
      input2.getFormat(),
      input2.getPrimaryVideoTrack()
    ]);
    if (!videoTrack) {
      throw new Error("No video track found in the input");
    }
    const timestamps = typeof timestampsInSeconds === "function" ? await timestampsInSeconds({
      track: {
        width: videoTrack.displayWidth,
        height: videoTrack.displayHeight
      },
      container: format.name,
      durationInSeconds
    }) : timestampsInSeconds;
    if (timestamps.length === 0) {
      return;
    }
    const sink = new mediabunny__WEBPACK_IMPORTED_MODULE_13__/* .VideoSampleSink */ .lc(videoTrack);
    for await (const videoSample of sink.samplesAtTimestamps(timestamps)) {
      if (signal?.aborted) {
        videoSample?.close();
        break;
      }
      if (!videoSample) {
        continue;
      }
      onVideoSample(videoSample);
    }
  } catch (error) {
    if (error instanceof mediabunny__WEBPACK_IMPORTED_MODULE_9__/* .InputDisposedError */ .Q) {
      return;
    }
    throw error;
  } finally {
    dispose();
    if (signal) {
      signal.removeEventListener("abort", dispose);
    }
  }
}

// src/helpers/frame-database.ts
var KEY_SEPARATOR = "|";
var makeFrameDatabaseKey = (src, timestamp) => `${src}${KEY_SEPARATOR}${timestamp}`;
var getFrameDatabaseKeyPrefix = (src) => {
  return `${src}${KEY_SEPARATOR}`;
};
var frameDatabase = new Map;
var aspectRatioCache = new Map;
var getTimestampFromFrameDatabaseKey = (key4) => {
  const split = key4.split(KEY_SEPARATOR);
  return Number(split[split.length - 1]);
};
var getAspectRatioFromCache = (src) => {
  const cached = aspectRatioCache.get(src);
  if (cached) {
    return cached;
  }
  return null;
};
var MAX_FRAMES_IN_CACHE = 12340;
var clearOldFrames = () => {
  if (frameDatabase.size <= MAX_FRAMES_IN_CACHE) {
    return;
  }
  const framesToRemove = Array.from(frameDatabase.entries()).sort((a, b) => a[1].lastUsed - b[1].lastUsed);
  for (const [key4, frame2] of framesToRemove.slice(0, framesToRemove.length - MAX_FRAMES_IN_CACHE)) {
    frame2.frame.close();
    frameDatabase.delete(key4);
  }
};
var clearFramesForSrc = (src) => {
  const keysToRemove = [];
  const prefix = getFrameDatabaseKeyPrefix(src);
  for (const [key4, frame2] of frameDatabase.entries()) {
    if (key4.startsWith(prefix)) {
      frame2.frame.close();
      keysToRemove.push(key4);
    }
  }
  for (const key4 of keysToRemove) {
    frameDatabase.delete(key4);
  }
};

// src/helpers/resize-video-frame.ts
var calculateNewDimensionsFromScale = ({
  width: width2,
  height,
  scale
}) => {
  const scaledWidth = Math.round(width2 * scale);
  const scaledHeight = Math.round(height * scale);
  return {
    width: scaledWidth,
    height: scaledHeight
  };
};
var resizeVideoFrame = ({
  frame: frame2,
  scale
}) => {
  if (scale === 1) {
    return frame2;
  }
  const { width: width2, height } = calculateNewDimensionsFromScale({
    height: frame2.displayHeight,
    width: frame2.displayWidth,
    scale
  });
  const canvas = new OffscreenCanvas(width2, height);
  const ctx = canvas.getContext("2d");
  if (!ctx) {
    throw new Error("Could not get 2d context");
  }
  canvas.width = width2;
  canvas.height = height;
  ctx.scale(scale, scale);
  ctx.drawImage(frame2, 0, 0);
  return new VideoFrame(canvas, {
    displayHeight: height,
    displayWidth: width2,
    duration: frame2.duration ?? undefined,
    timestamp: frame2.timestamp
  });
};

// src/components/Timeline/TimelineVideoInfo.tsx

var HEIGHT = getTimelineLayerHeight("video") - 2;
var containerStyle3 = {
  height: HEIGHT,
  width: "100%",
  backgroundColor: "rgba(0, 0, 0, 0.3)",
  display: "flex",
  borderTopLeftRadius: 2,
  borderBottomLeftRadius: 2,
  fontSize: 10,
  fontFamily: "Arial, Helvetica"
};
var WEBCODECS_TIMESCALE = 1e6;
var MAX_TIME_DEVIATION = WEBCODECS_TIMESCALE * 0.05;
var getDurationOfOneFrame = ({
  visualizationWidth,
  aspectRatio,
  segmentDuration
}) => {
  const framesFitInWidthUnrounded = visualizationWidth / (HEIGHT * aspectRatio);
  return segmentDuration / framesFitInWidthUnrounded * WEBCODECS_TIMESCALE;
};
var fixRounding = (value) => {
  if (value % 1 >= 0.49999999) {
    return Math.ceil(value);
  }
  return Math.floor(value);
};
var calculateTimestampSlots = ({
  visualizationWidth,
  fromSeconds,
  segmentDuration,
  aspectRatio
}) => {
  const framesFitInWidthUnrounded = visualizationWidth / (HEIGHT * aspectRatio);
  const framesFitInWidth = Math.ceil(framesFitInWidthUnrounded);
  const durationOfOneFrame = getDurationOfOneFrame({
    visualizationWidth,
    aspectRatio,
    segmentDuration
  });
  const timestampTargets = [];
  for (let i = 0;i < framesFitInWidth + 1; i++) {
    const target = fromSeconds * WEBCODECS_TIMESCALE + durationOfOneFrame * (i + 0.5);
    const snappedToDuration = (Math.round(fixRounding(target / durationOfOneFrame)) - 1) * durationOfOneFrame;
    timestampTargets.push(snappedToDuration);
  }
  return timestampTargets;
};
var ensureSlots = ({
  filledSlots,
  naturalWidth,
  fromSeconds,
  toSeconds,
  aspectRatio
}) => {
  const segmentDuration = toSeconds - fromSeconds;
  const timestampTargets = calculateTimestampSlots({
    visualizationWidth: naturalWidth,
    fromSeconds,
    segmentDuration,
    aspectRatio
  });
  for (const timestamp of timestampTargets) {
    if (!filledSlots.has(timestamp)) {
      filledSlots.set(timestamp, undefined);
    }
  }
};
var drawSlot = ({
  frame: frame2,
  ctx,
  filledSlots,
  visualizationWidth,
  timestamp,
  segmentDuration,
  fromSeconds
}) => {
  const durationOfOneFrame = getDurationOfOneFrame({
    visualizationWidth,
    aspectRatio: frame2.displayWidth / frame2.displayHeight,
    segmentDuration
  });
  const relativeTimestamp = timestamp - fromSeconds * WEBCODECS_TIMESCALE;
  const frameIndex = relativeTimestamp / durationOfOneFrame;
  const left3 = Math.floor(frameIndex * frame2.displayWidth / window.devicePixelRatio);
  ctx.drawImage(frame2, left3, 0, frame2.displayWidth / window.devicePixelRatio, frame2.displayHeight / window.devicePixelRatio);
  filledSlots.set(timestamp, frame2.timestamp);
};
var fillWithCachedFrames = ({
  ctx,
  naturalWidth,
  filledSlots,
  src,
  segmentDuration,
  fromSeconds
}) => {
  const prefix = getFrameDatabaseKeyPrefix(src);
  const keys = Array.from(frameDatabase.keys()).filter((k) => k.startsWith(prefix));
  const targets = Array.from(filledSlots.keys());
  for (const timestamp of targets) {
    let bestKey;
    let bestDistance = Infinity;
    for (const key4 of keys) {
      const distance = Math.abs(getTimestampFromFrameDatabaseKey(key4) - timestamp);
      if (distance < bestDistance) {
        bestDistance = distance;
        bestKey = key4;
      }
    }
    if (!bestKey) {
      continue;
    }
    const frame2 = frameDatabase.get(bestKey);
    if (!frame2) {
      continue;
    }
    const alreadyFilled = filledSlots.get(timestamp);
    if (alreadyFilled && Math.abs(alreadyFilled - timestamp) <= Math.abs(frame2.frame.timestamp - timestamp)) {
      continue;
    }
    frame2.lastUsed = Date.now();
    drawSlot({
      ctx,
      frame: frame2.frame,
      filledSlots,
      visualizationWidth: naturalWidth,
      timestamp,
      segmentDuration,
      fromSeconds
    });
  }
};
var fillFrameWhereItFits = ({
  frame: frame2,
  filledSlots,
  ctx,
  visualizationWidth,
  segmentDuration,
  fromSeconds
}) => {
  const slots = Array.from(filledSlots.keys());
  for (let i = 0;i < slots.length; i++) {
    const slot = slots[i];
    if (Math.abs(slot - frame2.timestamp) > MAX_TIME_DEVIATION) {
      continue;
    }
    const filled = filledSlots.get(slot);
    if (filled && Math.abs(filled - slot) <= Math.abs(filled - frame2.timestamp)) {
      continue;
    }
    drawSlot({
      ctx,
      frame: frame2,
      filledSlots,
      visualizationWidth,
      timestamp: slot,
      segmentDuration,
      fromSeconds
    });
  }
};
var TimelineVideoInfo = ({
  src,
  visualizationWidth,
  naturalWidth,
  trimBefore,
  durationInFrames,
  playbackRate
}) => {
  const { fps } = (0,remotion__WEBPACK_IMPORTED_MODULE_2__.useVideoConfig)();
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const [error, setError] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const aspectRatio = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(getAspectRatioFromCache(src));
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    return () => {
      clearFramesForSrc(src);
    };
  }, [src]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (error) {
      return;
    }
    const { current } = ref;
    if (!current) {
      return;
    }
    const controller = new AbortController;
    const canvas = document.createElement("canvas");
    canvas.width = visualizationWidth;
    canvas.height = HEIGHT;
    const ctx = canvas.getContext("2d");
    if (!ctx) {
      return;
    }
    current.appendChild(canvas);
    const filledSlots = new Map;
    const fromSeconds = trimBefore / fps;
    const toSeconds = fromSeconds + durationInFrames * playbackRate / fps;
    if (aspectRatio.current !== null) {
      ensureSlots({
        filledSlots,
        naturalWidth,
        fromSeconds,
        toSeconds,
        aspectRatio: aspectRatio.current
      });
      fillWithCachedFrames({
        ctx,
        naturalWidth,
        filledSlots,
        src,
        segmentDuration: toSeconds - fromSeconds,
        fromSeconds
      });
      const unfilled = Array.from(filledSlots.keys()).filter((timestamp) => !filledSlots.get(timestamp));
      if (unfilled.length === 0) {
        return () => {
          current.removeChild(canvas);
          clearOldFrames();
        };
      }
    }
    clearOldFrames();
    extractFrames({
      timestampsInSeconds: ({
        track
      }) => {
        aspectRatio.current = track.width / track.height;
        aspectRatioCache.set(src, aspectRatio.current);
        ensureSlots({
          filledSlots,
          fromSeconds,
          toSeconds,
          naturalWidth,
          aspectRatio: aspectRatio.current
        });
        return Array.from(filledSlots.keys()).map((timestamp) => timestamp / WEBCODECS_TIMESCALE);
      },
      src,
      onVideoSample: (sample) => {
        const frame2 = sample.toVideoFrame();
        const scale = HEIGHT / frame2.displayHeight * window.devicePixelRatio;
        const transformed = resizeVideoFrame({
          frame: frame2,
          scale
        });
        if (transformed !== frame2) {
          frame2.close();
        }
        const databaseKey = makeFrameDatabaseKey(src, transformed.timestamp);
        const existingFrame = frameDatabase.get(databaseKey);
        if (existingFrame) {
          existingFrame.frame.close();
        }
        frameDatabase.set(databaseKey, {
          frame: transformed,
          lastUsed: Date.now()
        });
        if (aspectRatio.current === null) {
          throw new Error("Aspect ratio is not set");
        }
        ensureSlots({
          filledSlots,
          fromSeconds,
          toSeconds,
          naturalWidth,
          aspectRatio: aspectRatio.current
        });
        fillFrameWhereItFits({
          ctx,
          filledSlots,
          visualizationWidth: naturalWidth,
          frame: transformed,
          segmentDuration: toSeconds - fromSeconds,
          fromSeconds
        });
        sample.close();
      },
      signal: controller.signal
    }).then(() => {
      fillWithCachedFrames({
        ctx,
        naturalWidth,
        filledSlots,
        src,
        segmentDuration: toSeconds - fromSeconds,
        fromSeconds
      });
    }).catch((e) => {
      setError(e);
    }).finally(() => {
      clearOldFrames();
    });
    return () => {
      controller.abort();
      current.removeChild(canvas);
    };
  }, [
    durationInFrames,
    error,
    fps,
    naturalWidth,
    playbackRate,
    src,
    trimBefore,
    visualizationWidth
  ]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    ref,
    style: containerStyle3
  });
};

// src/components/Timeline/TimelineSequence.tsx

var AUDIO_GRADIENT = "linear-gradient(rgb(16 171 58), rgb(43 165 63) 60%)";
var VIDEO_GRADIENT = "linear-gradient(to top, #8e44ad, #9b59b6)";
var TimelineSequence = ({ s }) => {
  const windowWidth = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(TimelineWidthContext);
  if (windowWidth === null) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Inner4, {
    windowWidth,
    s
  });
};
var Inner4 = ({ s, windowWidth }) => {
  const video = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useVideo();
  const maxMediaDuration = useMaxMediaDuration(s, video?.fps ?? 30);
  if (!video) {
    throw new TypeError("Expected video config");
  }
  const frame2 = (0,remotion__WEBPACK_IMPORTED_MODULE_2__.useCurrentFrame)();
  const relativeFrame = frame2 - s.from;
  const relativeFrameWithPremount = relativeFrame + (s.premountDisplay ?? 0);
  const relativeFrameWithPostmount = relativeFrame - s.duration;
  const roundedFrame = Math.round(relativeFrame * 100) / 100;
  const isInRange = relativeFrame >= 0 && relativeFrame < s.duration;
  const isPremounting = relativeFrameWithPremount >= 0 && relativeFrameWithPremount < s.duration && !isInRange;
  const isPostmounting = relativeFrameWithPostmount >= 0 && relativeFrameWithPostmount < (s.postmountDisplay ?? 0) && !isInRange;
  const { marginLeft, width: width2, naturalWidth, premountWidth, postmountWidth } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return getTimelineSequenceLayout({
      durationInFrames: s.loopDisplay ? s.loopDisplay.durationInFrames * s.loopDisplay.numberOfTimes : s.duration,
      startFrom: s.loopDisplay ? s.from + s.loopDisplay.startOffset : s.from,
      startFromMedia: s.type === "sequence" ? 0 : s.startMediaFrom,
      maxMediaDuration,
      video,
      windowWidth,
      premountDisplay: s.premountDisplay,
      postmountDisplay: s.postmountDisplay
    });
  }, [maxMediaDuration, s, video, windowWidth]);
  const style11 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      background: s.type === "audio" ? AUDIO_GRADIENT : s.type === "video" ? VIDEO_GRADIENT : BLUE,
      border: SEQUENCE_BORDER_WIDTH + "px solid rgba(255, 255, 255, 0.2)",
      borderRadius: 2,
      position: "absolute",
      height: getTimelineLayerHeight(s.type === "video" ? "video" : "other"),
      marginLeft,
      width: width2,
      color: "white",
      overflow: "hidden",
      opacity: isInRange ? 1 : 0.5
    };
  }, [isInRange, marginLeft, s.type, width2]);
  if (maxMediaDuration === null) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: style11,
    title: s.displayName,
    children: [
      premountWidth ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: {
          width: premountWidth,
          height: "100%",
          background: `repeating-linear-gradient(
							-45deg,
							transparent,
							transparent 2px,
							rgba(255, 255, 255, ${isPremounting ? 0.5 : 0.2}) 2px,
							rgba(255, 255, 255, ${isPremounting ? 0.5 : 0.2}) 4px
						)`,
          position: "absolute"
        }
      }) : null,
      postmountWidth ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: {
          width: postmountWidth,
          height: "100%",
          background: `repeating-linear-gradient(
							-45deg,
							transparent,
							transparent 2px,
							rgba(255, 255, 255, ${isPostmounting ? 0.5 : 0.2}) 2px,
							rgba(255, 255, 255, ${isPostmounting ? 0.5 : 0.2}) 4px
						)`,
          position: "absolute",
          right: 0
        }
      }) : null,
      s.type === "audio" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(AudioWaveform, {
        src: s.src,
        doesVolumeChange: s.doesVolumeChange,
        visualizationWidth: width2,
        startFrom: s.startMediaFrom,
        durationInFrames: s.duration,
        volume: s.volume,
        playbackRate: s.playbackRate
      }) : null,
      s.type === "video" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineVideoInfo, {
        src: s.src,
        visualizationWidth: width2,
        naturalWidth,
        trimBefore: s.startMediaFrom,
        durationInFrames: s.duration,
        playbackRate: s.playbackRate
      }) : null,
      s.loopDisplay === undefined ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(LoopedTimelineIndicator, {
        loops: s.loopDisplay.numberOfTimes
      }),
      s.type !== "audio" && s.type !== "video" && s.loopDisplay === undefined && (isInRange || isPremounting || isPostmounting) ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: {
          paddingLeft: 5 + (premountWidth ?? 0),
          height: "100%",
          display: "flex",
          alignItems: "center"
        },
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineSequenceFrame, {
          premounted: isPremounting,
          postmounted: isPostmounting ? s.duration - 1 : null,
          roundedFrame
        })
      }) : null
    ]
  }, s.id);
};

// src/components/Timeline/TimelineTracks.tsx

var content = {
  paddingLeft: TIMELINE_PADDING,
  paddingRight: TIMELINE_PADDING,
  paddingTop: 1
};
var timelineContent = {
  minHeight: "100%"
};
var getExpandedPlaceholderStyle = (controls) => ({
  height: getExpandedTrackHeight(controls) + TIMELINE_ITEM_BORDER_BOTTOM
});
var TimelineTracks = ({ timeline, hasBeenCut }) => {
  const { expandedTracks } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ExpandedTracksContext);
  const visualModeEnabled = Boolean(false);
  const timelineStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...timelineContent,
      width: 100 + "%"
    };
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: timelineStyle,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: content,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineTimePadding, {}),
          timeline.map((track) => {
            if (isTrackHidden(track)) {
              return null;
            }
            const isExpanded = expandedTracks[track.sequence.id] ?? false;
            return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
              children: [
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                  style: {
                    height: getTimelineLayerHeight(track.sequence.type === "video" ? "video" : "other"),
                    marginBottom: TIMELINE_ITEM_BORDER_BOTTOM
                  },
                  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineSequence, {
                    s: track.sequence
                  })
                }),
                visualModeEnabled && isExpanded ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                  style: getExpandedPlaceholderStyle(track.sequence.controls)
                }) : null
              ]
            }, track.sequence.id);
          })
        ]
      }),
      hasBeenCut ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MaxTimelineTracksReached, {}) : null
    ]
  });
};

// src/components/Timeline/Timeline.tsx

var container45 = {
  minHeight: "100%",
  flex: 1,
  display: "flex",
  height: 0,
  overflowY: "auto",
  backgroundColor: BACKGROUND
};
var noop3 = () => {
  return;
};
var Timeline = () => {
  const { sequences } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.SequenceManager);
  const videoConfig = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useUnsafeVideoConfig();
  const timeline = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!videoConfig) {
      return [];
    }
    return calculateTimeline({
      sequences,
      sequenceDuration: videoConfig.durationInFrames
    });
  }, [sequences, videoConfig]);
  const durationInFrames = videoConfig?.durationInFrames ?? 0;
  const filtered = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const withoutHidden = timeline.filter((t) => !isTrackHidden(t));
    const withoutAfter = withoutHidden.filter((t) => {
      return t.sequence.from <= durationInFrames && t.sequence.duration > 0;
    });
    return withoutAfter.filter((t) => t.sequence.showInTimeline);
  }, [durationInFrames, timeline]);
  const shown = filtered.slice(0, MAX_TIMELINE_TRACKS);
  const hasBeenCut = filtered.length > shown.length;
  const inner2 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      height: shown.reduce((acc, track) => {
        return acc + getTimelineLayerHeight(track.sequence.type === "video" ? "video" : "other") + Number(TIMELINE_ITEM_BORDER_BOTTOM);
      }, 0) + TIMELINE_ITEM_BORDER_BOTTOM + (hasBeenCut ? MAX_TIMELINE_TRACKS_NOTICE_HEIGHT : 0) + TIMELINE_TIME_INDICATOR_HEIGHT,
      display: "flex",
      flex: 1,
      minHeight: "100%",
      overflowX: "hidden"
    };
  }, [hasBeenCut, shown]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    ref: timelineVerticalScroll,
    style: container45,
    className: "css-reset " + VERTICAL_SCROLLBAR_CLASSNAME,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineWidthProvider, {
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: inner2,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(SplitterContainer, {
          orientation: "vertical",
          defaultFlex: 0.2,
          id: "names-to-timeline",
          maxFlex: 0.5,
          minFlex: 0.15,
          children: [
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SplitterElement, {
              type: "flexer",
              sticky: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineTimePlaceholders, {}),
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineList, {
                timeline: shown
              })
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SplitterHandle, {
              onCollapse: noop3,
              allowToCollapse: "none"
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SplitterElement, {
              type: "anti-flexer",
              sticky: null,
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(TimelineScrollable, {
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineTracks, {
                    timeline: shown,
                    hasBeenCut
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineInOutPointer, {}),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelinePlayCursorSyncer, {}),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineDragHandler, {}),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineTimeIndicators, {}),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineSlider, {})
                ]
              })
            })
          ]
        })
      })
    })
  });
};

// src/components/EditorContent.tsx

var noop4 = () => {
  return;
};
var container46 = {
  display: "flex",
  flexDirection: "column",
  flex: 1,
  height: 0
};
var EditorContent = ({ readOnlyStudio, children }) => {
  const isStill = useIsStill();
  const { canvasContent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const onlyTopPanel = canvasContent === null || isStill || canvasContent.type !== "composition";
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container46,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InitialCompositionLoader, {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MenuToolbar, {
        readOnlyStudio
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(SplitterContainer, {
        orientation: "horizontal",
        id: "top-to-bottom",
        maxFlex: 0.9,
        minFlex: 0.2,
        defaultFlex: 0.75,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SplitterElement, {
            sticky: null,
            type: "flexer",
            children
          }),
          onlyTopPanel ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SplitterHandle, {
                allowToCollapse: "none",
                onCollapse: noop4
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SplitterElement, {
                sticky: null,
                type: "anti-flexer",
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Timeline, {})
              })
            ]
          })
        ]
      })
    ]
  });
};

// src/components/GlobalKeybindings.tsx

var GlobalKeybindings = () => {
  const keybindings = useKeybinding();
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const { setCheckerboard } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(CheckerboardContext);
  const { navigateToNextComposition, navigateToPreviousComposition } = useCompositionNavigation();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const nKey = keybindings.registerKeybinding({
      event: "keypress",
      key: "n",
      callback: () => {
        showNotification(`To make a new composition, right-click an existing one and select "Duplicate"`, 5000);
      },
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const cmdKKey = keybindings.registerKeybinding({
      event: "keydown",
      key: "k",
      callback: () => {
        setSelectedModal({
          type: "quick-switcher",
          mode: "compositions",
          invocationTimestamp: Date.now()
        });
      },
      triggerIfInputFieldFocused: true,
      keepRegisteredWhenNotHighestContext: false,
      commandCtrlKey: true,
      preventDefault: true
    });
    const cmdIKey =  true ? keybindings.registerKeybinding({
      event: "keydown",
      key: "i",
      callback: () => {
        askAiModalRef.current?.toggle();
      },
      triggerIfInputFieldFocused: true,
      keepRegisteredWhenNotHighestContext: true,
      commandCtrlKey: true,
      preventDefault: true
    }) : 0;
    const cKey = keybindings.registerKeybinding({
      event: "keypress",
      key: "t",
      callback: () => {
        setCheckerboard((c) => !c);
      },
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const questionMark = keybindings.registerKeybinding({
      event: "keypress",
      key: "?",
      callback: () => {
        setSelectedModal({
          type: "quick-switcher",
          mode: "docs",
          invocationTimestamp: Date.now()
        });
      },
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const pageDown = keybindings.registerKeybinding({
      event: "keydown",
      key: "PageDown",
      callback: navigateToNextComposition,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    const pageUp = keybindings.registerKeybinding({
      event: "keydown",
      key: "PageUp",
      callback: navigateToPreviousComposition,
      commandCtrlKey: false,
      preventDefault: true,
      triggerIfInputFieldFocused: false,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      nKey.unregister();
      cKey.unregister();
      questionMark.unregister();
      cmdKKey.unregister();
      cmdIKey?.unregister();
      pageDown.unregister();
      pageUp.unregister();
    };
  }, [
    keybindings,
    setCheckerboard,
    setSelectedModal,
    navigateToNextComposition,
    navigateToPreviousComposition
  ]);
  return null;
};

// src/components/Modals.tsx


// src/components/InstallPackage.tsx




// src/api/install-package.ts

var installPackages = (packageNames) => {
  if (!(0,remotion__WEBPACK_IMPORTED_MODULE_2__.getRemotionEnvironment)().isStudio) {
    throw new Error("installPackages() is only available in the Studio");
  }
  if (window.remotion_isReadOnlyStudio) {
    throw new Error("installPackages() is not available in Read-Only Studio");
  }
  return callApi("/api/install-package", { packageNames });
};

// src/components/InstallablePackage.tsx

var FONT_SIZE = 13;
var InstallablePackageComp = ({ isInstalled, pkg, link, description }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: {
      fontSize: FONT_SIZE,
      lineHeight: 1.2,
      paddingBottom: 4,
      paddingTop: 4
    },
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("a", {
        href: link,
        style: {
          fontSize: FONT_SIZE,
          color: TEXT_COLOR,
          textDecoration: "none"
        },
        target: "_blank",
        children: pkg
      }),
      " ",
      isInstalled ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
        style: { opacity: 0.3, fontSize: "inherit" },
        children: "(installed)"
      }) : null,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("br", {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
        style: { color: LIGHT_TEXT, fontSize: FONT_SIZE },
        children: description
      })
    ]
  });
};

// src/components/ModalButton.tsx


var buttonStyle5 = {
  backgroundColor: BLUE,
  color: "white"
};
var ModalButton = (props) => {
  const style11 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...buttonStyle5,
      backgroundColor: props.disabled ? BLUE_DISABLED : BLUE
    };
  }, [props.disabled]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
    ...props,
    style: style11
  });
};

// src/components/ModalFooter.tsx

var content2 = {
  padding: 12,
  paddingRight: 12,
  flex: 1,
  fontSize: 13,
  minWidth: 500
};
var ModalFooterContainer = ({ children }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: { ...content2, borderTop: "1px solid black" },
    children
  });
};

// src/components/NewComposition/DismissableModal.tsx


var DismissableModal = ({ children }) => {
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const onQuit = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSelectedModal(null);
  }, [setSelectedModal]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalContainer, {
    onOutsideClick: onQuit,
    onEscape: onQuit,
    children
  });
};

// src/components/InstallPackage.tsx

var container47 = {
  padding: 20,
  maxHeight: 400,
  overflowY: "auto"
};
var text2 = {
  fontSize: 14
};
var InstallPackageModal = ({ packageManager }) => {
  const [state, setState] = react__WEBPACK_IMPORTED_MODULE_0__.useState({ type: "idle" });
  const [map, setMap] = react__WEBPACK_IMPORTED_MODULE_0__.useState({});
  const { previewServerState: ctx } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx);
  const selectedPackages = Object.keys(map).filter((pkg) => map[pkg]);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(async () => {
    if (state.type === "done") {
      setState({ type: "restarting" });
      restartStudio();
      return;
    }
    setState({ type: "installing" });
    try {
      await installPackages(selectedPackages);
      setState({ type: "done" });
    } catch (err) {
      setState({ type: "error", error: err });
    }
  }, [selectedPackages, state.type]);
  const canSelectPackages = state.type === "idle" && ctx.type === "connected";
  const disabled = !(canSelectPackages || state.type === "done") || selectedPackages.length === 0;
  const { registerKeybinding } = useKeybinding();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (disabled) {
      return;
    }
    const enter = registerKeybinding({
      callback() {
        onClick();
      },
      commandCtrlKey: true,
      key: "Enter",
      event: "keydown",
      preventDefault: true,
      triggerIfInputFieldFocused: true,
      keepRegisteredWhenNotHighestContext: true
    });
    return () => {
      enter.unregister();
    };
  }, [disabled, onClick, registerKeybinding]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(DismissableModal, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalHeader, {
        title: "Install packages"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: container47,
        className: VERTICAL_SCROLLBAR_CLASSNAME,
        children: state.type === "done" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
          style: text2,
          children: [
            "Installed package",
            selectedPackages.length === 1 ? "" : "s",
            " ",
            "successfully. Restart the server to complete."
          ]
        }) : state.type === "restarting" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: text2,
          children: "Restarting the Studio server..."
        }) : state.type === "installing" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
          style: text2,
          children: [
            "Installing package",
            selectedPackages.length === 1 ? "" : "s",
            ". Check your terminal for progress."
          ]
        }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
          style: text2,
          children: [
            Object.entries(_remotion_studio_shared__WEBPACK_IMPORTED_MODULE_6__/* .installableMap */ .W3).filter(([, install]) => install).map(([pkgShort]) => {
              const pkg = pkgShort === "core" ? "remotion" : `@remotion/${pkgShort}`;
              const isInstalled = window.remotion_installedPackages?.includes(pkg) ?? false;
              const link = _remotion_studio_shared__WEBPACK_IMPORTED_MODULE_6__/* .apiDocs */ .aO[pkgShort];
              const description = _remotion_studio_shared__WEBPACK_IMPORTED_MODULE_6__/* .descriptions */ .eH[pkgShort];
              if (!link) {
                throw new Error("No link for " + pkg);
              }
              if (!description) {
                throw new Error("No description for " + pkg);
              }
              return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
                    checked: map[pkg],
                    name: pkg,
                    onChange: () => {
                      setMap((prev) => ({ ...prev, [pkg]: !prev[pkg] }));
                    },
                    disabled: !canSelectPackages || isInstalled
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                    x: 1.5
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InstallablePackageComp, {
                    description,
                    isInstalled,
                    link,
                    pkg
                  })
                ]
              }, pkg);
            }),
            _remotion_studio_shared__WEBPACK_IMPORTED_MODULE_6__/* .extraPackages */ .IJ.map((extraPkg) => {
              const isInstalled = window.remotion_installedPackages?.includes(extraPkg.name) ?? false;
              return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
                    checked: map[extraPkg.name],
                    name: extraPkg.name,
                    onChange: () => {
                      setMap((prev) => ({
                        ...prev,
                        [extraPkg.name]: !prev[extraPkg.name]
                      }));
                    },
                    disabled: !canSelectPackages || isInstalled
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                    x: 1.5
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InstallablePackageComp, {
                    description: extraPkg.description,
                    isInstalled,
                    link: extraPkg.docsUrl,
                    pkg: `${extraPkg.name}@${extraPkg.version}`
                  })
                ]
              }, extraPkg.name);
            })
          ]
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalFooterContainer, {
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
          align: "center",
          children: [
            state.type === "idle" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("span", {
              style: { color: LIGHT_TEXT, fontSize: 13, lineHeight: 1.2 },
              children: [
                "This will install ",
                selectedPackages.length,
                " package",
                selectedPackages.length === 1 ? "" : "s",
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("br", {}),
                "using ",
                packageManager,
                ", Remotion v",
                remotion__WEBPACK_IMPORTED_MODULE_2__.VERSION
              ]
            }) : null,
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {}),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(ModalButton, {
              onClick,
              disabled,
              children: [
                state.type === "restarting" ? "Restarting..." : state.type === "installing" ? "Installing..." : state.type === "done" ? "Restart Server" : "Install",
                disabled ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ShortcutHint, {
                  keyToPress: "↵",
                  cmdOrCtrl: true
                })
              ]
            })
          ]
        })
      })
    ]
  });
};

// src/components/NewComposition/DeleteComposition.tsx


// src/components/RenderModal/ResolveCompositionBeforeModal.tsx



var loaderContainer2 = {
  paddingTop: 40,
  paddingBottom: 40,
  paddingLeft: 100,
  paddingRight: 100,
  display: "flex",
  justifyContent: "center",
  alignItems: "center",
  flexDirection: "column"
};
var loaderLabel2 = {
  fontSize: 14,
  color: LIGHT_TEXT,
  fontFamily: "sans-serif",
  lineHeight: 1.5
};
var ResolvedCompositionContext = react__WEBPACK_IMPORTED_MODULE_0__.createContext(null);
var ResolveCompositionBeforeModal = ({ compositionId, children }) => {
  const resolved = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.useResolvedVideoConfig(compositionId);
  const unresolvedContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const unresolved = unresolvedContext.compositions.find((c) => compositionId === c.id);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const { current } = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.resolveCompositionsRef;
    if (!current) {
      throw new Error("No ref to trigger composition calc");
    }
    current.setCurrentRenderModalComposition(compositionId);
    return () => {
      current.setCurrentRenderModalComposition(null);
    };
  }, [compositionId]);
  if (!unresolved) {
    throw new Error("Composition not found: " + compositionId);
  }
  const value = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      resolved,
      unresolved
    };
  }, [resolved, unresolved]);
  if (!resolved || resolved.type === "loading") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RunningCalculateMetadata, {});
  }
  if (resolved.type === "error") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
      style: loaderContainer2,
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
          y: 2
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
          style: loaderLabel2,
          children: [
            "Running ",
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
              style: inlineCodeSnippet,
              children: "calculateMetadata()"
            }),
            " ",
            "yielded an error:"
          ]
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
          y: 1
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: loaderLabel2,
          children: resolved.error.message || "Unknown error"
        })
      ]
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ResolvedCompositionContext.Provider, {
    value,
    children
  });
};

// src/components/NewComposition/CodemodFooter.tsx


// src/components/NewComposition/DiffPreview.tsx

var CodemodDiffPreview = ({ status }) => {
  if (status.type === "loading") {
    return null;
  }
  if (status.type === "fail") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
      style: { color: FAIL_COLOR, fontSize: 13, lineHeight: 1.2 },
      children: status.error
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: { lineHeight: 1.2 },
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
        style: { color: LIGHT_TEXT, fontSize: 13, lineHeight: 1.2 },
        children: "This will edit your Root file."
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("br", {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("span", {
        style: { color: BLUE, fontSize: 13, lineHeight: 1.2 },
        children: [
          status.diff.additions,
          " addition",
          status.diff.additions === 1 ? "" : "s",
          ","
        ]
      }),
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("span", {
        style: {
          color: SELECTED_GUIDE,
          fontSize: 13,
          lineHeight: 1.2
        },
        children: [
          status.diff.deletions,
          " deletion",
          status.diff.deletions === 1 ? "" : "s"
        ]
      })
    ]
  });
};

// src/components/NewComposition/CodemodFooter.tsx

var CodemodFooter = ({
  codemod,
  valid,
  loadingNotification,
  successNotification,
  errorNotification,
  genericSubmitLabel,
  submitLabel,
  onSuccess
}) => {
  const [submitting, setSubmitting] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const [codemodStatus, setCanApplyCodemod] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({
    type: "loading"
  });
  const [projectInfo, setProjectInfo] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const controller = new AbortController;
    getProjectInfo(controller.signal).then((info) => {
      setProjectInfo(info.projectInfo);
    }).catch((err) => {
      showNotification(`Could not get project info: ${err.message}. Unable to duplicate composition`, 3000);
    });
    return () => {
      controller.abort();
    };
  }, []);
  const trigger = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSubmitting(true);
    setSelectedModal(null);
    const notification2 = showNotification(loadingNotification, null);
    applyCodemod({
      codemod,
      dryRun: false,
      signal: new AbortController().signal
    }).then(() => {
      notification2.replaceContent(successNotification, 2000);
      onSuccess?.();
    }).catch((err) => {
      notification2.replaceContent(`${errorNotification}: ${err.message}`, 2000);
    });
  }, [
    codemod,
    errorNotification,
    loadingNotification,
    onSuccess,
    setSelectedModal,
    successNotification
  ]);
  const getCanApplyCodemod = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(async (signal) => {
    const res = await applyCodemod({
      codemod,
      dryRun: true,
      signal
    });
    if (res.success) {
      setCanApplyCodemod({ type: "success", diff: res.diff });
    } else {
      setCanApplyCodemod({
        type: "fail",
        error: res.reason
      });
    }
  }, [codemod]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const abortController = new AbortController;
    let aborted = false;
    getCanApplyCodemod(abortController.signal).then(() => {
      return;
    }).catch((err) => {
      if (aborted) {
        return;
      }
      showNotification(`Cannot duplicate composition: ${err.message}`, 3000);
    });
    return () => {
      aborted = true;
      abortController.abort();
    };
  }, [getCanApplyCodemod]);
  const disabled = !valid || submitting || projectInfo === null || codemodStatus.type !== "success";
  const { registerKeybinding } = useKeybinding();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (disabled) {
      return;
    }
    const enter = registerKeybinding({
      callback() {
        trigger();
      },
      commandCtrlKey: true,
      key: "Enter",
      event: "keydown",
      preventDefault: true,
      triggerIfInputFieldFocused: true,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      enter.unregister();
    };
  }, [disabled, registerKeybinding, trigger, valid]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
    align: "center",
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CodemodDiffPreview, {
        status: codemodStatus
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        block: true,
        x: 2
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(ModalButton, {
        onClick: trigger,
        disabled,
        children: [
          projectInfo && projectInfo.relativeRootFile ? submitLabel({ relativeRootPath: projectInfo.relativeRootFile }) : genericSubmitLabel,
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ShortcutHint, {
            keyToPress: "↵",
            cmdOrCtrl: true
          })
        ]
      })
    ]
  });
};

// src/components/NewComposition/DeleteComposition.tsx

var content3 = {
  padding: 16,
  fontSize: 14,
  flex: 1,
  minWidth: 500
};
var DeleteCompositionLoaded = ({ compositionId }) => {
  const context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ResolvedCompositionContext);
  if (!context) {
    throw new Error("Resolved composition context");
  }
  const { unresolved } = context;
  const codemod = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      type: "delete-composition",
      idToDelete: compositionId
    };
  }, [compositionId]);
  const onSubmit = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.preventDefault();
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalHeader, {
        title: "Delete composition"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("form", {
        onSubmit,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: content3,
            children: [
              "Do you want to delete the",
              " ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
                style: inlineCodeSnippet,
                children: unresolved.durationInFrames === 1 ? `<Still>` : "<Composition>"
              }),
              " ",
              "with ID ",
              '"',
              unresolved.id,
              '"',
              "?",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("br", {}),
              "The associated ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
                style: inlineCodeSnippet,
                children: "component"
              }),
              " will remain in your code."
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalFooterContainer, {
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CodemodFooter, {
              errorNotification: `Could not delete composition`,
              loadingNotification: "Deleting",
              successNotification: `Deleted ${unresolved.id}`,
              genericSubmitLabel: `Delete`,
              submitLabel: ({ relativeRootPath }) => `Delete from ${relativeRootPath}`,
              codemod,
              valid: true,
              onSuccess: null
            })
          })
        ]
      })
    ]
  });
};
var DeleteComposition = ({ compositionId }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DismissableModal, {
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ResolveCompositionBeforeModal, {
      compositionId,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DeleteCompositionLoaded, {
        compositionId
      })
    })
  });
};

// src/components/NewComposition/DuplicateComposition.tsx



// src/helpers/validate-new-comp-data.ts

var validateCompositionName = (compName, compositions) => {
  if (!remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.isCompositionIdValid(compName)) {
    return remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.invalidCompositionErrorMessage;
  }
  if (compositions.find((c) => c.id === compName)) {
    return `A composition with that name already exists.`;
  }
  return null;
};
var validateCompositionDimension = (dimension, value) => {
  if (Number(value) % 2 !== 0) {
    return `${dimension} should be divisible by 2, since H264 codec doesn't support odd dimensions.`;
  }
  if (Number.isNaN(Number(value))) {
    return "Invalid number.";
  }
  if (Number(value) === 0) {
    return dimension + " cannot be zero.";
  }
  return null;
};
var validateCompositionDuration = (value) => {
  if (value % 1 !== 0) {
    return `Duration must be an integer.`;
  }
  if (Number.isNaN(value)) {
    return "Invalid number.";
  }
  if (value === 0) {
    return "Duration cannot be zero.";
  }
  return null;
};

// src/components/NewComposition/NewCompDuration.tsx


var NewCompDuration = ({ durationInFrames, setDurationInFrames }) => {
  const onDurationInFramesChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newValue) => {
    setDurationInFrames(Number(newValue));
  }, [setDurationInFrames]);
  const onDurationChangedDirectly = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newVal) => {
    setDurationInFrames(newVal);
  }, [setDurationInFrames]);
  const compDurationErrMessage = validateCompositionDuration(durationInFrames);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: optionRow,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: label5,
        children: "Duration in frames"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: rightRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InputDragger, {
            type: "number",
            value: durationInFrames,
            onTextChange: onDurationInFramesChanged,
            placeholder: "Duration (frames)",
            name: "durationInFrames",
            min: 1,
            step: 1,
            required: true,
            status: "ok",
            max: 300000,
            onValueChange: onDurationChangedDirectly,
            rightAlign: false
          }),
          compDurationErrMessage ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                y: 1,
                block: true
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ValidationMessage, {
                align: "flex-start",
                message: compDurationErrMessage,
                type: "error"
              })
            ]
          }) : null
        ]
      })
    ]
  });
};

// src/components/NewComposition/DuplicateComposition.tsx

var content4 = {
  padding: 12,
  paddingRight: 12,
  flex: 1,
  fontSize: 13,
  minWidth: 500
};
var comboBoxStyle = {
  width: 190
};
var DuplicateCompositionLoaded = ({ initialType }) => {
  const context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ResolvedCompositionContext);
  if (!context) {
    throw new Error("Resolved composition context");
  }
  const { resolved, unresolved } = context;
  const [initialCompType] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialType);
  const hadDimensionsDefined = unresolved.width && unresolved.height;
  const hadFpsDefined = unresolved.fps !== undefined;
  const hadDurationDefined = unresolved.durationInFrames !== undefined;
  const [selectedFrameRate, setFrameRate] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(resolved.result.fps);
  const { compositions } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const [type, setType] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialCompType);
  const [newId, setName] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => {
    const numberAtEnd = resolved.result.id.match(/([0-9]+)$/)?.[0];
    let prefix = numberAtEnd ? Number(numberAtEnd) : 1;
    const initialName = resolved.result.id.replace(/([0-9]+)$/, "");
    let currentName = initialName;
    while (true) {
      currentName = initialName + prefix;
      const err = validateCompositionName(currentName, compositions);
      if (!err) {
        break;
      }
      prefix++;
    }
    return currentName;
  });
  const [size4, setSize] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => ({
    width: resolved.result.width,
    height: resolved.result.height
  }));
  const [durationInFrames, setDurationInFrames] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(resolved.result.durationInFrames);
  const onTypeChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newType) => {
    setType(newType);
  }, []);
  const onWidthChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newValue) => {
    setSize((s) => {
      const { height } = s;
      const newWidth = Number(newValue);
      return {
        height,
        width: newWidth
      };
    });
  }, []);
  const onWidthDirectlyChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newWidth) => {
    setSize((s) => {
      const { height } = s;
      return {
        height,
        width: newWidth
      };
    });
  }, []);
  const onHeightDirectlyChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newHeight) => {
    setSize((s) => {
      const { width: width2 } = s;
      return {
        width: width2,
        height: newHeight
      };
    });
  }, []);
  const onHeightChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newValue) => {
    setSize((s) => {
      const { width: width2 } = s;
      const newHeight = Number(newValue);
      return {
        width: width2,
        height: newHeight
      };
    });
  }, []);
  const onNameChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setName(e.target.value);
  }, []);
  const onTextFpsChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newFps) => {
    setFrameRate(Number(newFps));
  }, []);
  const onFpsChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newFps) => {
    setFrameRate(newFps);
  }, []);
  const compNameErrMessage = validateCompositionName(newId, compositions);
  const compWidthErrMessage = validateCompositionDimension("Width", size4.width);
  const compHeightErrMessage = validateCompositionDimension("Height", size4.height);
  const typeValues = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return [
      {
        id: "composition",
        keyHint: null,
        label: "<Composition />",
        leftItem: null,
        onClick: () => onTypeChanged("composition"),
        subMenu: null,
        type: "item",
        value: "composition",
        quickSwitcherLabel: null
      },
      {
        id: "still",
        keyHint: null,
        label: "<Still />",
        leftItem: null,
        onClick: () => onTypeChanged("still"),
        subMenu: null,
        type: "item",
        value: "still",
        quickSwitcherLabel: null
      }
    ];
  }, [onTypeChanged]);
  const valid = compNameErrMessage === null && compWidthErrMessage === null && compHeightErrMessage === null;
  const codemod = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      type: "duplicate-composition",
      idToDuplicate: resolved.result.id,
      newDurationInFrames: hadDurationDefined ? Number(durationInFrames) : null,
      newFps: hadFpsDefined ? Number(selectedFrameRate) : null,
      newHeight: hadDimensionsDefined ? Number(size4.height) : null,
      newWidth: hadDimensionsDefined ? Number(size4.width) : null,
      newId,
      tag: type === "still" ? "Still" : "Composition"
    };
  }, [
    durationInFrames,
    hadDimensionsDefined,
    hadDurationDefined,
    hadFpsDefined,
    newId,
    resolved.result.id,
    selectedFrameRate,
    size4.height,
    size4.width,
    type
  ]);
  const onDuplicateSuccess = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    pushUrl(`/${newId}`);
  }, [newId]);
  const onSubmit = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.preventDefault();
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalHeader, {
        title: `Duplicate ${resolved.result.id}`
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("form", {
        onSubmit,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: content4,
            children: [
              initialCompType === "composition" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                style: optionRow,
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: label5,
                    children: "Type"
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: rightRow,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
                      title: "Type of composition",
                      style: comboBoxStyle,
                      values: typeValues,
                      selectedId: type
                    })
                  })
                ]
              }) : null,
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                style: optionRow,
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: label5,
                    children: "ID"
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: rightRow,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                      children: [
                        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
                          value: newId,
                          onChange: onNameChange,
                          type: "text",
                          autoFocus: true,
                          placeholder: "Composition ID",
                          status: "ok",
                          rightAlign: true
                        }),
                        compNameErrMessage ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
                          children: [
                            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                              y: 1,
                              block: true
                            }),
                            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ValidationMessage, {
                              align: "flex-start",
                              message: compNameErrMessage,
                              type: "error"
                            })
                          ]
                        }) : null
                      ]
                    })
                  })
                ]
              }),
              hadDimensionsDefined ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                    style: optionRow,
                    children: [
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                        style: label5,
                        children: "Width"
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                        style: rightRow,
                        children: [
                          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InputDragger, {
                            type: "number",
                            value: size4.width,
                            placeholder: "Width",
                            onTextChange: onWidthChanged,
                            name: "width",
                            step: 2,
                            min: 2,
                            required: true,
                            status: "ok",
                            formatter: (w) => `${w}px`,
                            max: 1e8,
                            onValueChange: onWidthDirectlyChanged,
                            rightAlign: false
                          }),
                          compWidthErrMessage ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
                            children: [
                              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                                y: 1,
                                block: true
                              }),
                              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ValidationMessage, {
                                align: "flex-start",
                                message: compWidthErrMessage,
                                type: "error"
                              })
                            ]
                          }) : null
                        ]
                      })
                    ]
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                    style: optionRow,
                    children: [
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                        style: label5,
                        children: "Height"
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                        style: rightRow,
                        children: [
                          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InputDragger, {
                            type: "number",
                            value: size4.height,
                            onTextChange: onHeightChanged,
                            placeholder: "Height",
                            name: "height",
                            step: 2,
                            required: true,
                            formatter: (h) => `${h}px`,
                            min: 2,
                            status: "ok",
                            max: 1e8,
                            onValueChange: onHeightDirectlyChanged,
                            rightAlign: false
                          }),
                          compHeightErrMessage ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
                            children: [
                              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                                y: 1,
                                block: true
                              }),
                              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ValidationMessage, {
                                align: "flex-start",
                                message: compHeightErrMessage,
                                type: "error"
                              })
                            ]
                          }) : null
                        ]
                      })
                    ]
                  })
                ]
              }) : null,
              type === "composition" && hadDurationDefined ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NewCompDuration, {
                durationInFrames,
                setDurationInFrames
              }) : null,
              type === "composition" && hadFpsDefined ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                style: optionRow,
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: label5,
                    children: "FPS"
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: rightRow,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InputDragger, {
                      type: "number",
                      value: selectedFrameRate,
                      onTextChange: onTextFpsChange,
                      placeholder: "Frame rate (fps)",
                      name: "fps",
                      min: 1,
                      required: true,
                      status: "ok",
                      max: 240,
                      step: 0.01,
                      onValueChange: onFpsChange,
                      rightAlign: false
                    })
                  })
                ]
              }) : null
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalFooterContainer, {
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CodemodFooter, {
              loadingNotification: "Duplicating...",
              errorNotification: "Could not duplicate composition",
              successNotification: `Duplicated ${unresolved.id} as ${newId}`,
              genericSubmitLabel: "Duplicate",
              submitLabel: ({ relativeRootPath }) => `Add to ${relativeRootPath}`,
              codemod,
              valid,
              onSuccess: onDuplicateSuccess
            })
          })
        ]
      })
    ]
  });
};
var DuplicateComposition = ({ compositionId, compositionType }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DismissableModal, {
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ResolveCompositionBeforeModal, {
      compositionId,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DuplicateCompositionLoaded, {
        initialType: compositionType
      })
    })
  });
};

// src/components/NewComposition/RenameComposition.tsx



var content5 = {
  padding: 12,
  paddingRight: 12,
  flex: 1,
  fontSize: 13,
  minWidth: 500
};
var RenameCompositionLoaded = () => {
  const context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ResolvedCompositionContext);
  if (!context) {
    throw new Error("Resolved composition context");
  }
  const { resolved } = context;
  const { compositions } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const [newId, setName] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => {
    return resolved.result.id;
  });
  const onNameChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setName(e.target.value);
  }, []);
  const compNameErrMessage = newId === resolved.result.id ? null : validateCompositionName(newId, compositions);
  const valid = compNameErrMessage === null && resolved.result.id !== newId;
  const codemod = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      type: "rename-composition",
      idToRename: resolved.result.id,
      newId
    };
  }, [newId, resolved.result.id]);
  const onSubmit = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    e.preventDefault();
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalHeader, {
        title: `Rename ${resolved.result.id}`
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("form", {
        onSubmit,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: content5,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
              style: optionRow,
              children: [
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                  style: label5,
                  children: "ID"
                }),
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                  style: rightRow,
                  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                    children: [
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
                        value: newId,
                        onChange: onNameChange,
                        type: "text",
                        autoFocus: true,
                        placeholder: "Composition ID",
                        status: "ok",
                        rightAlign: true
                      }),
                      compNameErrMessage ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
                        children: [
                          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                            y: 1,
                            block: true
                          }),
                          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ValidationMessage, {
                            align: "flex-start",
                            message: compNameErrMessage,
                            type: "error"
                          })
                        ]
                      }) : null
                    ]
                  })
                })
              ]
            })
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalFooterContainer, {
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CodemodFooter, {
              loadingNotification: "Renaming...",
              errorNotification: "Could not rename composition",
              successNotification: `Renamed to ${newId}`,
              genericSubmitLabel: "Rename",
              submitLabel: ({ relativeRootPath }) => `Modify ${relativeRootPath}`,
              codemod,
              valid,
              onSuccess: null
            })
          })
        ]
      })
    ]
  });
};
var RenameComposition = ({ compositionId }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DismissableModal, {
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ResolveCompositionBeforeModal, {
      compositionId,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenameCompositionLoaded, {})
    })
  });
};

// src/components/OverrideInputProps.tsx



var style11 = {
  padding: 12,
  width: 500
};
var label8 = {
  color: LIGHT_TEXT,
  fontSize: 14,
  marginBottom: 10
};
var textAreaStyle = {
  fontFamily: "monospace",
  minHeight: 200
};
var codeSnippet2 = {
  fontSize: 14,
  color: BLUE,
  fontFamily: "monospace"
};
var row8 = {
  display: "flex",
  flexDirection: "row",
  alignItems: "center",
  justifyContent: "space-between"
};
var isValidJSON = (value) => {
  try {
    JSON.parse(value);
    return true;
  } catch {
    return false;
  }
};
var Inner5 = () => {
  const [value, setValue] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => {
    const override = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.getInputPropsOverride();
    if (override) {
      return JSON.stringify(override, null, 2);
    }
    return null;
  });
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const valid = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!value)
      return true;
    return isValidJSON(value);
  }, [value]);
  const onChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newValue) => {
    if (newValue.trim() === "") {
      setValue(null);
      remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.setInputPropsOverride(null);
      return;
    }
    setValue(newValue);
    if (!isValidJSON(newValue)) {
      return;
    }
    remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.setInputPropsOverride(JSON.parse(newValue));
  }, [setValue]);
  const onReset = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onChange("");
  }, [onChange]);
  const onReloadPage = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    window.location.reload();
  }, []);
  const onDone = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSelectedModal(null);
  }, [setSelectedModal]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: style11,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: label8,
        children: [
          "Enter a valid JSON to override the value that",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: codeSnippet2,
            children: "getInputProps()"
          }),
          " returns to preview a composition with different props. The Studio must be reloaded to see the changes."
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemTextarea, {
        onChange: (e) => onChange(e.target.value),
        value: value ?? "",
        status: valid ? "ok" : "error",
        style: textAreaStyle
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: row8,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
            onClick: onReset,
            children: "Reset"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 0.5
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
            onClick: onReloadPage,
            children: "Reload page"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {}),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
            onClick: onDone,
            children: "Done"
          })
        ]
      })
    ]
  });
};
var OverrideInputPropsModal = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DismissableModal, {
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Inner5, {})
  });
};

// src/components/QuickSwitcher/QuickSwitcherContent.tsx



// src/icons/keys.tsx

var iconStyle5 = {
  width: 10,
  display: "inline"
};
var ShiftIcon = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    style: iconStyle5,
    viewBox: "0 0 448 512",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: "currentColor",
      d: "M48.048 304h73.798v128c0 26.51 21.49 48 48 48h108.308c26.51 0 48-21.49 48-48V304h73.789c42.638 0 64.151-51.731 33.941-81.941l-175.943-176c-18.745-18.745-49.137-18.746-67.882 0l-175.952 176C-16.042 252.208 5.325 304 48.048 304zM224 80l176 176H278.154v176H169.846V256H48L224 80z"
    })
  });
};
var ArrowLeft = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    style: iconStyle5,
    viewBox: "0 0 448 512",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: "currentColor",
      d: "M257.5 445.1l-22.2 22.2c-9.4 9.4-24.6 9.4-33.9 0L7 273c-9.4-9.4-9.4-24.6 0-33.9L201.4 44.7c9.4-9.4 24.6-9.4 33.9 0l22.2 22.2c9.5 9.5 9.3 25-.4 34.3L136.6 216H424c13.3 0 24 10.7 24 24v32c0 13.3-10.7 24-24 24H136.6l120.5 114.8c9.8 9.3 10 24.8.4 34.3z"
    })
  });
};
var ArrowRight = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    style: iconStyle5,
    viewBox: "0 0 448 512",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: "currentColor",
      d: "M190.5 66.9l22.2-22.2c9.4-9.4 24.6-9.4 33.9 0L441 239c9.4 9.4 9.4 24.6 0 33.9L246.6 467.3c-9.4 9.4-24.6 9.4-33.9 0l-22.2-22.2c-9.5-9.5-9.3-25 .4-34.3L311.4 296H24c-13.3 0-24-10.7-24-24v-32c0-13.3 10.7-24 24-24h287.4L190.9 101.2c-9.8-9.3-10-24.8-.4-34.3z"
    })
  });
};

// src/components/KeyboardShortcutsExplainer.tsx

var left3 = {
  width: 85,
  paddingTop: 8,
  paddingBottom: 8
};
var key4 = {
  background: INPUT_BACKGROUND,
  padding: "3px 6px",
  color: "white",
  borderRadius: 3,
  border: "1px solid " + INPUT_BORDER_COLOR_UNHOVERED,
  borderBottomWidth: 3,
  fontSize: 14,
  fontFamily: "monospace"
};
var right2 = {
  fontSize: 14,
  color: "#eee"
};
var container48 = {
  paddingLeft: 20,
  paddingRight: 40,
  paddingTop: 10,
  paddingBottom: 10
};
var title5 = {
  fontWeight: "bold",
  color: "white",
  fontSize: 14,
  marginBottom: 10
};
var keyboardShortcutsDisabled = {
  padding: 12,
  width: "100%",
  fontSize: 14,
  backgroundColor: "rgba(255, 255, 255, 0.1)"
};
var ul = {
  marginTop: 0,
  marginBottom: 0
};
var li = {
  fontSize: 14
};
var KeyboardShortcutsExplainer = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    children: [
      areKeyboardShortcutsDisabled() ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: keyboardShortcutsDisabled,
        children: [
          "Keyboard shortcuts disabled either due to:",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("ul", {
            style: ul,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("li", {
                style: li,
                children: "a) --disable-keyboard-shortcuts being passed"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("li", {
                style: li,
                children: "b) Config.setKeyboardShortcutsEnabled(false) being set or"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("li", {
                style: li,
                children: " c) a Remotion version mismatch."
              })
            ]
          })
        ]
      }) : null,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
        style: container48,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Column, {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: title5,
                children: "Playback"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                    style: left3,
                    children: [
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                        style: key4,
                        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ShiftIcon, {})
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                        x: 0.3
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                        style: key4,
                        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ArrowLeft, {})
                      })
                    ]
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "1 second back"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ArrowLeft, {})
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Previous frame"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "Space"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Play / Pause"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ArrowRight, {})
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Next frame"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                    style: left3,
                    children: [
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                        style: key4,
                        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ShiftIcon, {})
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                        x: 0.3
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                        style: key4,
                        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ArrowRight, {})
                      })
                    ]
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "1 second forward"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "A"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Jump to beginning"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "E"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Jump to end"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "J"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Reverse playback"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "K"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Pause"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "L"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Play / Speed up"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "G"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Go to frame"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "Enter"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Pause & return to playback start"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("br", {}),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: title5,
                children: "Sidebar"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                    style: left3,
                    children: [
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                        style: key4,
                        children: cmdOrCtrlCharacter
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                        x: 0.3
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                        style: key4,
                        children: "B"
                      })
                    ]
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Toggle left sidebar"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                    style: left3,
                    children: [
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                        style: key4,
                        children: cmdOrCtrlCharacter
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                        x: 0.3
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                        style: key4,
                        children: "J"
                      })
                    ]
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Toggle right sidebar"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                    style: left3,
                    children: [
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                        style: key4,
                        children: cmdOrCtrlCharacter
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                        x: 0.3
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                        style: key4,
                        children: "G"
                      })
                    ]
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Toggle both sidebars"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("br", {}),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: title5,
                children: "View"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "F"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Enter fullscreen"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "Esc"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Exit fullscreen"
                  })
                ]
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 8
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Column, {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: title5,
                children: "Navigation"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "PageUp"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Previous composition"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "PageDown"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Next composition"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "R"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Render composition"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "T"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Toggle checkerboard background"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "?"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Show keyboard shortcuts"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                    style: left3,
                    children: [
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                        style: key4,
                        children: cmdOrCtrlCharacter
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                        x: 0.3
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                        style: key4,
                        children: "K"
                      })
                    ]
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Quick Switcher"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("br", {}),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: title5,
                children: "Playback range"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "I"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Set In Point"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "O"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Set Out Point"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "X"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Clear In/Out Points"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("br", {}),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: title5,
                children: "Zoom"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "+"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Zoom in"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "-"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Zoom out"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: left3,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                      style: key4,
                      children: "0"
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Reset zoom"
                  })
                ]
              }),
              " ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("br", {}),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: title5,
                children: "Props Editor"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                align: "center",
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                    style: left3,
                    children: [
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                        style: key4,
                        children: cmdOrCtrlCharacter
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                        x: 0.3
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                        style: key4,
                        children: "S"
                      })
                    ]
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: right2,
                    children: "Save"
                  })
                ]
              }),
               true && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("br", {}),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: title5,
                    children: "AI"
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
                    align: "center",
                    children: [
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                        style: left3,
                        children: [
                          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                            style: key4,
                            children: cmdOrCtrlCharacter
                          }),
                          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                            x: 0.3
                          }),
                          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("kbd", {
                            style: key4,
                            children: "I"
                          })
                        ]
                      }),
                      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                        style: right2,
                        children: "Ask AI"
                      })
                    ]
                  })
                ]
              })
            ]
          })
        ]
      })
    ]
  });
};

// src/components/QuickSwitcher/algolia-search.ts

var ALGOLIA_API_KEY = "3e42dbd4f895fe93ff5cf40d860c4a85";
var ALGOLIA_APPLICATION_ID = "PLSDUOL1CA";
var AGOLIA_SEARCH_URL = "https://plsduol1ca-dsn.algolia.net/1/indexes/*/queries";
var algoliaSearch = async (query) => {
  const url = new URL(AGOLIA_SEARCH_URL);
  url.searchParams.set("x-algolia-agen", encodeURIComponent("Remotion Studio DocSearch"));
  url.searchParams.set("x-algolia-api-key", ALGOLIA_API_KEY);
  url.searchParams.set("x-algolia-application-id", ALGOLIA_APPLICATION_ID);
  const { results } = await fetch(url.toString(), {
    headers: {
      "content-type": "application/x-www-form-urlencoded"
    },
    body: JSON.stringify({
      requests: [
        {
          query,
          indexName: "remotion",
          params: 'attributesToRetrieve=["hierarchy.lvl0","hierarchy.lvl1","hierarchy.lvl2","hierarchy.lvl3","hierarchy.lvl4","hierarchy.lvl5","hierarchy.lvl6","content","type","url"]&attributesToSnippet=["hierarchy.lvl1:10","hierarchy.lvl2:10","hierarchy.lvl3:10","hierarchy.lvl4:10","hierarchy.lvl5:10","hierarchy.lvl6:10","content:10"]&hitsPerPage=20'
        }
      ]
    }),
    method: "POST"
  }).then((res) => res.json());
  const { hits } = results[0];
  return hits.map((hit) => {
    const entries = Object.values(hit._highlightResult.hierarchy);
    const result = entries.find((value) => value.matchLevel === "full") ?? entries.find((value) => value.matchLevel === "partial");
    const { subtitle: subtitle4, title: title6 } = splitMatchIntoTitleAndSubtitle(hit);
    if (!result) {
      return null;
    }
    return {
      type: "search-result",
      id: hit.objectID,
      title: "Should not display",
      titleLine: title6,
      subtitleLine: subtitle4,
      onSelected: () => {
        window.open(hit.url);
      }
    };
  }).filter(remotion_no_react__WEBPACK_IMPORTED_MODULE_5__.NoReactInternals.truthy);
};
var splitMatchIntoTitleAndSubtitle = (match) => {
  const main = match.type === "content" ? match._highlightResult.content : match._highlightResult.hierarchy[match.type];
  const title6 = main.value;
  const subtitle4 = Object.entries(match._highlightResult.hierarchy).filter(([level]) => level !== match.type).map((value) => value[1].value).join(" • ");
  return { title: title6, subtitle: subtitle4 };
};

// src/components/QuickSwitcher/AlgoliaCredit.tsx

var link = {
  display: "inline-flex"
};
var AlgoliaCredit = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("a", {
    style: link,
    href: "https://www.algolia.com/ref/docsearch/?utm_source=www.remotion.dev&utm_medium=referral&utm_content=powered_by&utm_campaign=docsearch",
    target: "_blank",
    rel: "noopener noreferrer",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      width: "77",
      height: "19",
      "aria-label": "Algolia",
      role: "img",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        d: "M2.5067 0h14.0245c1.384.001 2.5058 1.1205 2.5068 2.5017V16.5c-.0014 1.3808-1.1232 2.4995-2.5068 2.5H2.5067C1.1232 18.9995.0014 17.8808 0 16.5V2.4958A2.495 2.495 0 01.735.7294 2.505 2.505 0 012.5068 0zM37.95 15.0695c-3.7068.0168-3.7068-2.986-3.7068-3.4634L34.2372.3576 36.498 0v11.1794c0 .2715 0 1.9889 1.452 1.994v1.8961zm-9.1666-1.8388c.694 0 1.2086-.0397 1.5678-.1088v-2.2934a5.3639 5.3639 0 00-1.3303-.1679 4.8283 4.8283 0 00-.758.0582 2.2845 2.2845 0 00-.688.2024c-.2029.0979-.371.2362-.4919.4142-.1268.1788-.185.2826-.185.5533 0 .5297.185.8359.5205 1.0375.3355.2016.7928.3053 1.365.3053v-.0008zm-.1969-8.1817c.7463 0 1.3768.092 1.8856.2767.5088.1838.9195.4428 1.2204.7717.3068.334.5147.7777.6423 1.251.1327.4723.196.991.196 1.5603v5.798c-.5235.1036-1.05.192-1.5787.2649-.7048.1037-1.4976.156-2.3774.156-.5832 0-1.1215-.0582-1.6016-.167a3.385 3.385 0 01-1.2432-.5364 2.6034 2.6034 0 01-.8037-.9565c-.191-.3922-.29-.9447-.29-1.5208 0-.5533.11-.905.3246-1.2863a2.7351 2.7351 0 01.8849-.9329c.376-.242.8029-.415 1.2948-.5187a7.4517 7.4517 0 011.5381-.156 7.1162 7.1162 0 011.6667.2024V8.886c0-.259-.0296-.5061-.093-.7372a1.5847 1.5847 0 00-.3245-.6158 1.5079 1.5079 0 00-.6119-.4158 2.6788 2.6788 0 00-.966-.173c-.5206 0-.9948.0634-1.4283.1384a6.5481 6.5481 0 00-1.065.259l-.2712-1.849c.2831-.0986.7048-.1964 1.2491-.2943a9.2979 9.2979 0 011.752-.1501v.0008zm44.6597 8.1193c.6947 0 1.2086-.0405 1.567-.1097v-2.2942a5.3743 5.3743 0 00-1.3303-.1679c-.2485 0-.503.0177-.7573.0582a2.2853 2.2853 0 00-.688.2024 1.2333 1.2333 0 00-.4918.4142c-.1268.1788-.1843.2826-.1843.5533 0 .5297.1843.8359.5198 1.0375.3414.2066.7927.3053 1.365.3053v.0009zm-.191-8.1767c.7463 0 1.3768.0912 1.8856.2759.5087.1847.9195.4436 1.2204.7717.3.329.5147.7786.6414 1.251a5.7248 5.7248 0 01.197 1.562v5.7972c-.3466.0742-.874.1602-1.5788.2648-.7049.1038-1.4976.1552-2.3774.1552-.5832 0-1.1215-.0573-1.6016-.167a3.385 3.385 0 01-1.2432-.5356 2.6034 2.6034 0 01-.8038-.9565c-.191-.3922-.2898-.9447-.2898-1.5216 0-.5533.1098-.905.3245-1.2854a2.7373 2.7373 0 01.8849-.9338c.376-.2412.8029-.4141 1.2947-.5178a7.4545 7.4545 0 012.325-.1097c.2781.0287.5672.081.879.156v-.3686a2.7781 2.7781 0 00-.092-.738 1.5788 1.5788 0 00-.3246-.6166 1.5079 1.5079 0 00-.612-.415 2.6797 2.6797 0 00-.966-.1729c-.5205 0-.9947.0633-1.4282.1384a6.5608 6.5608 0 00-1.065.259l-.2712-1.8498c.283-.0979.7048-.1957 1.2491-.2935a9.8597 9.8597 0 011.752-.1494zm-6.79-1.072c-.7576.001-1.373-.6103-1.3759-1.3664 0-.755.6128-1.3664 1.376-1.3664.764 0 1.3775.6115 1.3775 1.3664s-.6195 1.3664-1.3776 1.3664zm1.1393 11.1507h-2.2726V5.3409l2.2734-.3568v10.0845l-.0008.0017zm-3.984 0c-3.707.0168-3.707-2.986-3.707-3.4642L59.7069.3576 61.9685 0v11.1794c0 .2715 0 1.9889 1.452 1.994V15.0703zm-7.3512-4.979c0-.975-.2138-1.7873-.6305-2.3516-.4167-.571-.9998-.852-1.747-.852-.7454 0-1.3302.281-1.7452.852-.4166.5702-.6195 1.3765-.6195 2.3516 0 .9851.208 1.6473.6254 2.2183.4158.576.9998.8587 1.7461.8587.7454 0 1.3303-.2885 1.747-.8595.4158-.5761.6237-1.2315.6237-2.2184v.0009zm2.3132-.006c0 .7609-.1099 1.3361-.3356 1.9654a4.654 4.654 0 01-.9533 1.6076A4.214 4.214 0 0155.613 14.69c-.579.2412-1.4697.3795-1.9143.3795-.4462-.005-1.3303-.1324-1.9033-.3795a4.307 4.307 0 01-1.474-1.0316c-.4115-.4445-.7293-.9801-.9609-1.6076a5.3423 5.3423 0 01-.3465-1.9653c0-.7608.104-1.493.3356-2.1155a4.683 4.683 0 01.9719-1.5958 4.3383 4.3383 0 011.479-1.0257c.5739-.242 1.2043-.3567 1.8864-.3567.6829 0 1.3125.1197 1.8906.3567a4.1245 4.1245 0 011.4816 1.0257 4.7587 4.7587 0 01.9592 1.5958c.2426.6225.3643 1.3547.3643 2.1155zm-17.0198 0c0 .9448.208 1.9932.6238 2.431.4166.4386.955.6579 1.6142.6579.3584 0 .6998-.0523 1.0176-.1502.3186-.0978.5721-.2134.775-.3517V7.0784a8.8706 8.8706 0 00-1.4926-.1906c-.8206-.0236-1.4452.312-1.8847.8468-.4335.5365-.6533 1.476-.6533 2.3516v-.0008zm6.2863 4.4485c0 1.5385-.3938 2.662-1.1866 3.3773-.791.7136-2.0005 1.0712-3.6308 1.0712-.5958 0-1.834-.1156-2.8228-.334l.3643-1.7865c.8282.173 1.9202.2193 2.4932.2193.9077 0 1.555-.1847 1.943-.5533.388-.3686.578-.916.578-1.643v-.3687a6.8289 6.8289 0 01-.8848.3349c-.3634.1096-.786.167-1.261.167-.6246 0-1.1917-.0979-1.7055-.2944a3.5554 3.5554 0 01-1.3244-.8645c-.3642-.3796-.6541-.8579-.8561-1.4289-.2028-.571-.3068-1.59-.3068-2.339 0-.7034.1099-1.5856.3245-2.1735.2198-.5871.5316-1.0949.9542-1.515.4167-.42.9255-.743 1.5213-.98a5.5923 5.5923 0 012.052-.3855c.7353 0 1.4114.092 2.0707.2024.6592.1088 1.2204.2236 1.6776.35v8.945-.0008zM11.5026 4.2418v-.6511c-.0005-.4553-.3704-.8241-.8266-.8241H8.749c-.4561 0-.826.3688-.8265.824v.669c0 .0742.0693.1264.1445.1096a6.0346 6.0346 0 011.6768-.2362 6.125 6.125 0 011.6202.2185.1116.1116 0 00.1386-.1097zm-5.2806.852l-.3296-.3282a.8266.8266 0 00-1.168 0l-.393.3922a.8199.8199 0 000 1.164l.3237.323c.0524.0515.1268.0397.1733-.0117.191-.259.3989-.507.6305-.7372.2374-.2362.48-.4437.7462-.6335.0575-.0354.0634-.1155.017-.1687zm3.5159 2.069v2.818c0 .081.0879.1392.1622.0987l2.5102-1.2964c.0574-.0287.0752-.0987.0464-.1552a3.1237 3.1237 0 00-2.603-1.574c-.0575 0-.115.0456-.115.1097l-.0008-.0009zm.0008 6.789c-2.0933.0005-3.7915-1.6912-3.7947-3.7804C5.9468 8.0821 7.6452 6.39 9.7387 6.391c2.0932-.0005 3.7911 1.6914 3.794 3.7804a3.7783 3.7783 0 01-1.1124 2.675 3.7936 3.7936 0 01-2.6824 1.1054h.0008zM9.738 4.8002c-1.9218 0-3.6975 1.0232-4.6584 2.6841a5.359 5.359 0 000 5.3683c.9609 1.661 2.7366 2.6841 4.6584 2.6841a5.3891 5.3891 0 003.8073-1.5725 5.3675 5.3675 0 001.578-3.7987 5.3574 5.3574 0 00-1.5771-3.797A5.379 5.379 0 009.7387 4.801l-.0008-.0008z",
        fill: "currentColor",
        fillRule: "evenodd"
      })
    })
  });
};

// src/components/QuickSwitcher/fuzzy-search.ts
function fuzzySearch(query, dataset) {
  const q = query ? query.trim().toLowerCase() : "";
  const matchingIndices = [];
  if (q.length === 0) {
    for (let i = 0;i < dataset.length; i++) {
      matchingIndices.push(i);
    }
    return dataset.filter((_, i) => matchingIndices.includes(i));
  }
  dataset.forEach((d, index) => {
    const s = d.title.trim().toLowerCase();
    let i = 0;
    let n = -1;
    let l;
    for (;l = q[i++]; )
      if (!~(n = s.indexOf(l, n + 1)))
        return;
    matchingIndices.push(index);
  });
  return dataset.filter((_, i) => matchingIndices.includes(i));
}

// src/components/QuickSwitcher/NoResults.tsx

var container49 = {
  padding: 80,
  color: LIGHT_TEXT,
  textAlign: "center",
  fontSize: 14
};
var MODE_TO_STRING = {
  commands: "commands",
  compositions: "compositions",
  docs: "documentation"
};
var QuickSwitcherNoResults = ({ query, mode }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container49,
    children: [
      "No ",
      MODE_TO_STRING[mode],
      " matching ",
      '"',
      query,
      '"'
    ]
  });
};

// src/components/QuickSwitcher/QuickSwitcherResult.tsx


var container50 = {
  paddingLeft: 16,
  paddingRight: 16,
  display: "flex",
  flexDirection: "row",
  alignItems: "center",
  cursor: "pointer"
};
var label9 = {
  whiteSpace: "nowrap",
  textOverflow: "ellipsis"
};
var searchLabel = {
  ...label9,
  lineHeight: 1.25
};
var iconStyle6 = {
  width: 14,
  height: 14
};
var labelContainer = {
  overflow: "hidden",
  flex: 1,
  paddingTop: 5,
  paddingBottom: 5
};
var QuickSwitcherResult = ({ result, selected }) => {
  const [hovered, setIsHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const keybindings = useKeybinding();
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const { current } = ref;
    if (!current) {
      return;
    }
    const onMouseEnter = () => setIsHovered(true);
    const onMouseLeave = () => setIsHovered(false);
    current.addEventListener("mouseenter", onMouseEnter);
    current.addEventListener("mouseleave", onMouseLeave);
    return () => {
      current.removeEventListener("mouseenter", onMouseEnter);
      current.removeEventListener("mouseleave", onMouseLeave);
    };
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!selected) {
      return;
    }
    const binding = keybindings.registerKeybinding({
      key: "Enter",
      callback: result.onSelected,
      commandCtrlKey: false,
      event: "keydown",
      preventDefault: true,
      triggerIfInputFieldFocused: true,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      binding.unregister();
    };
  }, [keybindings, result.onSelected, selected]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (selected) {
      ref.current?.scrollIntoView({
        block: "nearest",
        inline: "center"
      });
    }
  }, [selected]);
  const style12 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...container50,
      backgroundColor: getBackgroundFromHoverState({
        hovered,
        selected
      })
    };
  }, [hovered, selected]);
  const labelStyle5 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...result.type === "search-result" ? searchLabel : label9,
      color: result.type === "search-result" ? LIGHT_TEXT : selected || hovered ? "white" : LIGHT_TEXT,
      fontSize: 15
    };
  }, [hovered, result.type, selected]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    ref,
    style: style12,
    onClick: result.onSelected,
    children: [
      result.type === "composition" ? result.compositionType === "still" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(StillIcon, {
        color: selected ? "white" : LIGHT_TEXT,
        style: iconStyle6
      }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FilmIcon, {
        color: selected ? "white" : LIGHT_TEXT,
        style: iconStyle6
      }) : null,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: labelContainer,
        children: result.type === "search-result" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
          children: [
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              dangerouslySetInnerHTML: {
                __html: result.titleLine
              },
              style: labelStyle5
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              dangerouslySetInnerHTML: {
                __html: result.subtitleLine
              },
              style: labelStyle5
            })
          ]
        }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: labelStyle5,
          children: result.title
        })
      })
    ]
  }, result.id);
};

// src/components/QuickSwitcher/QuickSwitcherContent.tsx

var input2 = {
  width: "100%"
};
var modeSelector = {
  paddingLeft: 16,
  paddingRight: 16,
  display: "flex",
  flexDirection: "row",
  paddingTop: 8,
  paddingBottom: 5
};
var modeItem = {
  appearance: "none",
  border: "none",
  fontFamily: "inherit",
  padding: 0,
  fontSize: 13,
  cursor: "pointer"
};
var modeInactive = {
  ...modeItem,
  color: LIGHT_TEXT
};
var modeActive = {
  ...modeItem,
  color: "white",
  fontWeight: "bold"
};
var content6 = {
  paddingLeft: 16,
  paddingRight: 16,
  paddingTop: 4,
  paddingBottom: 10,
  display: "flex",
  flexDirection: "row",
  alignItems: "center"
};
var loopIndex = (index, length) => {
  if (index < 0) {
    index += length;
  }
  return index % length;
};
var stripQuery = (query) => {
  if (query.startsWith(">") || query.startsWith("?")) {
    return query.substring(1).trim();
  }
  return query.trim();
};
var mapQueryToMode = (query) => {
  return query.startsWith(">") ? "commands" : query.startsWith("?") ? "docs" : "compositions";
};
var mapModeToQuery = (mode) => {
  if (mode === "commands") {
    return "> ";
  }
  if (mode === "compositions") {
    return "";
  }
  if (mode === "docs") {
    return "? ";
  }
  throw new Error("no mode" + mode);
};
var QuickSwitcherContent = ({ initialMode, invocationTimestamp, readOnlyStudio }) => {
  const { compositions } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const [state, setState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => {
    return {
      query: mapModeToQuery(initialMode),
      selectedIndex: 0
    };
  });
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    setState({
      query: mapModeToQuery(initialMode),
      selectedIndex: 0
    });
  }, [initialMode, invocationTimestamp]);
  const inputRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(null);
  const selectComposition = useSelectComposition();
  const closeMenu = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    return;
  }, []);
  const actions = useMenuStructure(closeMenu, readOnlyStudio);
  const [docResults, setDocResults] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({ type: "initial" });
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const keybindings = useKeybinding();
  const mode = mapQueryToMode(state.query);
  const actualQuery = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return stripQuery(state.query);
  }, [state.query]);
  const menuActions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (mode !== "commands") {
      return [];
    }
    return makeSearchResults(actions, setSelectedModal);
  }, [actions, mode, setSelectedModal]);
  const resultsArray = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (mode === "commands") {
      return fuzzySearch(actualQuery, menuActions);
    }
    if (mode === "docs" && docResults.type === "results") {
      return docResults.results;
    }
    return fuzzySearch(actualQuery, compositions.map((c) => {
      return {
        id: "composition-" + c.id,
        title: c.id,
        type: "composition",
        onSelected: () => {
          selectComposition(c, true);
          setSelectedModal(null);
          const selector = `.__remotion-composition[data-compname="${c.id}"]`;
          remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.compositionSelectorRef.current?.expandComposition(c.id);
          waitForElm(selector).then(() => {
            document.querySelector(selector)?.scrollIntoView({ block: "center" });
          });
        },
        compositionType: isCompositionStill(c) ? "still" : "composition"
      };
    }));
  }, [
    mode,
    actualQuery,
    compositions,
    menuActions,
    docResults,
    selectComposition,
    setSelectedModal
  ]);
  const onArrowDown = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setState((s) => {
      return {
        ...s,
        selectedIndex: s.selectedIndex + 1
      };
    });
  }, []);
  const onArrowUp = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setState((s) => {
      return {
        ...s,
        selectedIndex: s.selectedIndex - 1
      };
    });
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const binding = keybindings.registerKeybinding({
      key: "ArrowUp",
      callback: onArrowUp,
      commandCtrlKey: false,
      event: "keydown",
      preventDefault: true,
      triggerIfInputFieldFocused: true,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      binding.unregister();
    };
  }, [keybindings, onArrowDown, onArrowUp]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (mode !== "docs") {
      return;
    }
    if (actualQuery.trim() === "") {
      setDocResults({ type: "initial" });
      return;
    }
    let cancelled = false;
    setDocResults({ type: "loading" });
    algoliaSearch(actualQuery).then((agoliaResults) => {
      if (cancelled) {
        return;
      }
      setDocResults({ type: "results", results: agoliaResults });
    }).catch((err) => {
      if (cancelled) {
        return;
      }
      setDocResults({ type: "error", error: err });
    });
    return () => {
      cancelled = true;
    };
  }, [actualQuery, mode]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const binding = keybindings.registerKeybinding({
      key: "ArrowDown",
      callback: onArrowDown,
      commandCtrlKey: false,
      event: "keydown",
      preventDefault: true,
      triggerIfInputFieldFocused: true,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      binding.unregister();
    };
  }, [keybindings, onArrowDown]);
  const onTextChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setState({ query: e.target.value, selectedIndex: 0 });
  }, []);
  const selectedIndexRounded = loopIndex(state.selectedIndex, resultsArray.length);
  const onActionsSelected = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setState((s) => ({
      query: `> ${stripQuery(s.query)}`,
      selectedIndex: 0
    }));
    inputRef.current?.focus();
  }, []);
  const onCompositionsSelected = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setState((s) => ({
      query: stripQuery(s.query),
      selectedIndex: 0
    }));
    inputRef.current?.focus();
  }, []);
  const onDocSearchSelected = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setState((s) => ({
      query: `? ${stripQuery(s.query)}`,
      selectedIndex: 0
    }));
    setDocResults({ type: "initial" });
    inputRef.current?.focus();
  }, []);
  const showKeyboardShortcuts = mode === "docs" && actualQuery.trim() === "";
  const showSearchLoadingState = mode === "docs" && docResults.type === "loading";
  const container51 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      width: showKeyboardShortcuts ? 800 : 500
    };
  }, [showKeyboardShortcuts]);
  const results = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (showKeyboardShortcuts) {
      return {
        maxHeight: 600,
        overflowY: "auto"
      };
    }
    return {
      overflowY: "auto",
      height: 300
    };
  }, [showKeyboardShortcuts]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container51,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: modeSelector,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
            onClick: onCompositionsSelected,
            style: mode === "compositions" ? modeActive : modeInactive,
            type: "button",
            children: "Compositions"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 1
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
            onClick: onActionsSelected,
            style: mode === "commands" ? modeActive : modeInactive,
            type: "button",
            children: "Actions"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 1
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
            onClick: onDocSearchSelected,
            style: mode === "docs" ? modeActive : modeInactive,
            type: "button",
            children: "Documentation"
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: content6,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
            ref: inputRef,
            type: "text",
            style: input2,
            autoFocus: true,
            status: "ok",
            value: state.query,
            onChange: onTextChange,
            placeholder: "Search compositions...",
            rightAlign: false
          }),
          showKeyboardShortcuts ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 2
              }),
              " ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(AlgoliaCredit, {})
            ]
          }) : null
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: results,
        className: VERTICAL_SCROLLBAR_CLASSNAME,
        children: showKeyboardShortcuts ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(KeyboardShortcutsExplainer, {}) : showSearchLoadingState ? null : resultsArray.length === 0 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(QuickSwitcherNoResults, {
          mode,
          query: actualQuery
        }) : resultsArray.map((result, i) => {
          return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(QuickSwitcherResult, {
            selected: selectedIndexRounded === i,
            result
          }, result.id);
        })
      })
    ]
  });
};
function waitForElm(selector) {
  return new Promise((resolve) => {
    if (document.querySelector(selector)) {
      resolve(document.querySelector(selector));
      return;
    }
    const observer = new MutationObserver(() => {
      if (document.querySelector(selector)) {
        resolve(document.querySelector(selector));
        observer.disconnect();
      }
    });
    observer.observe(document.body, {
      childList: true,
      subtree: true
    });
  });
}

// src/components/QuickSwitcher/QuickSwitcher.tsx

var QuickSwitcher = ({ initialMode, invocationTimestamp, readOnlyStudio }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DismissableModal, {
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(QuickSwitcherContent, {
      readOnlyStudio,
      invocationTimestamp,
      initialMode
    })
  });
};
var QuickSwitcher_default = QuickSwitcher;

// src/components/RenderModal/RenderStatusModal.tsx


// src/components/RenderModal/ClientRenderProgress.tsx


// src/components/RenderQueue/SuccessIcon.tsx

var iconStyle7 = {
  height: RENDER_STATUS_INDICATOR_SIZE,
  width: RENDER_STATUS_INDICATOR_SIZE
};
var SuccessIcon = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    style: iconStyle7,
    viewBox: "0 0 512 512",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: LIGHT_TEXT,
      d: "M256 512c141.4 0 256-114.6 256-256S397.4 0 256 0S0 114.6 0 256S114.6 512 256 512zM369 209L241 337l-17 17-17-17-64-64-17-17L160 222.1l17 17 47 47L335 175l17-17L385.9 192l-17 17z"
    })
  });
};

// src/components/RenderModal/ClientRenderProgress.tsx

var progressItem = {
  padding: 10,
  display: "flex",
  flexDirection: "row",
  alignItems: "center"
};
var label10 = {
  fontSize: 14,
  width: 400,
  color: "white"
};
var right3 = {
  fontSize: 14,
  color: LIGHT_TEXT,
  textAlign: "right",
  flex: 1
};
var EncodingProgress = ({ encodedFrames, totalFrames }) => {
  const done = encodedFrames === totalFrames;
  const progress = totalFrames > 0 ? encodedFrames / totalFrames : 0;
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: progressItem,
    children: [
      done ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SuccessIcon, {}) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CircularProgress, {
        progress
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: label10,
        children: done ? `Encoded ${totalFrames} frames` : `Encoding ${encodedFrames} / ${totalFrames} frames`
      })
    ]
  });
};
var DoneStatus = ({ job }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: progressItem,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SuccessIcon, {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: label10,
        children: job.outName
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: right3,
        children: (0,_remotion_studio_shared__WEBPACK_IMPORTED_MODULE_6__/* .formatBytes */ .z3)(job.metadata.sizeInBytes)
      })
    ]
  });
};
var ClientRenderProgress = ({ job }) => {
  if (job.status === "idle" || job.status === "failed" || job.status === "cancelled") {
    throw new Error("This component should not be rendered when the job is idle, failed, or cancelled");
  }
  if (job.status === "done") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
          y: 0.5
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DoneStatus, {
          job
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
          y: 1
        })
      ]
    });
  }
  if (job.status === "saving") {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
          y: 0.5
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: label10,
          children: "Saving to out/..."
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
          y: 1
        })
      ]
    });
  }
  const { encodedFrames, totalFrames } = job.progress;
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 0.5
      }),
      job.type === "client-video" && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(EncodingProgress, {
        encodedFrames,
        totalFrames
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 1
      })
    ]
  });
};

// src/components/RenderModal/GuiRenderStatus.tsx


var progressItem2 = {
  padding: 10,
  display: "flex",
  flexDirection: "row",
  alignItems: "center"
};
var label11 = {
  fontSize: 14,
  width: 400,
  color: "white"
};
var right4 = {
  fontSize: 14,
  color: LIGHT_TEXT,
  textAlign: "right",
  flex: 1
};
var BundlingProgress = ({ progress, doneIn }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: progressItem2,
    children: [
      progress === 1 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SuccessIcon, {}) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CircularProgress, {
        progress
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: label11,
        children: progress === 1 ? "Bundled" : `Bundling ${progress * 100}%`
      }),
      doneIn ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: right4,
        children: [
          doneIn,
          "ms"
        ]
      }) : null
    ]
  });
};
var BrowserSetupProgress = ({ progress, doneIn, startedBundling, alreadyAvailable }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: progressItem2,
    children: [
      progress === 1 || alreadyAvailable ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SuccessIcon, {}) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CircularProgress, {
        progress
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: label11,
        children: alreadyAvailable && startedBundling ? "Headless browser already available" : progress === 1 ? "Downloaded Headless Shell" : `Downloading Headless Shell ${Math.round(progress * 100)}%`
      }),
      doneIn ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: right4,
        children: [
          doneIn,
          "ms"
        ]
      }) : null
    ]
  });
};
var RenderingProgress = ({ progress }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: progressItem2,
    children: [
      progress.frames === progress.totalFrames ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SuccessIcon, {}) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CircularProgress, {
        progress: progress.frames / progress.totalFrames
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: label11,
        children: progress.doneIn ? `Rendered ${progress.totalFrames} frames` : `Rendering ${progress.frames} / ${progress.totalFrames} frames`
      }),
      progress.doneIn ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: right4,
        children: [
          progress.doneIn,
          "ms"
        ]
      }) : null
    ]
  });
};
var StitchingProgress = ({ progress }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: progressItem2,
    children: [
      progress.frames === progress.totalFrames ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SuccessIcon, {}) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CircularProgress, {
        progress: progress.frames / progress.totalFrames
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: label11,
        children: progress.doneIn ? `Encoded ${progress.totalFrames} frames` : `Encoding ${progress.frames} / ${progress.totalFrames} frames`
      }),
      progress.doneIn ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: right4,
        children: [
          progress.doneIn,
          "ms"
        ]
      }) : null
    ]
  });
};
var DownloadsProgress = ({ downloads }) => {
  const allHaveProgress = downloads.every((a) => a.totalBytes);
  const totalBytes = allHaveProgress ? downloads.reduce((a, b) => a + b.totalBytes, 0) : null;
  const downloaded = allHaveProgress ? downloads.reduce((a, b) => a + b.downloaded, 0) : null;
  const progress = allHaveProgress ? downloaded / totalBytes : 0.1;
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: progressItem2,
    children: [
      progress === 1 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SuccessIcon, {}) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CircularProgress, {
        progress
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: label11,
        children: [
          "Downloading ",
          downloads.length,
          " file",
          downloads.length === 1 ? "" : "s"
        ]
      })
    ]
  });
};
var OpenFile = ({ job }) => {
  const labelStyle5 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...label11,
      textAlign: "left",
      appearance: "none",
      border: 0,
      paddingLeft: 0,
      cursor: job.deletedOutputLocation ? "inherit" : "pointer",
      textDecoration: job.deletedOutputLocation ? "line-through" : "none"
    };
  }, [job.deletedOutputLocation]);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    openInFileExplorer({ directory: job.outName });
  }, [job.outName]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: progressItem2,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SuccessIcon, {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
        style: labelStyle5,
        type: "button",
        onClick,
        children: job.outName
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: right4,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderQueueOpenInFinderItem, {
          job
        })
      })
    ]
  });
};
var GuiRenderStatus = ({ job }) => {
  if (job.status === "idle" || job.status === "failed") {
    throw new Error("This component should not be rendered when the job is idle");
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 0.5
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(BrowserSetupProgress, {
        ...job.progress.browser,
        startedBundling: Boolean(job.progress.bundling)
      }),
      job.progress.bundling && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(BundlingProgress, {
        progress: job.progress.bundling.progress,
        doneIn: job.progress.bundling.doneIn
      }),
      job.progress.rendering ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderingProgress, {
        progress: job.progress.rendering
      }) : null,
      job.progress.stitching ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(StitchingProgress, {
        progress: job.progress.stitching
      }) : null,
      job.progress.downloads.length > 0 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DownloadsProgress, {
        downloads: job.progress.downloads
      }) : null,
      job.status === "done" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OpenFile, {
        job
      }) : null,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 1
      })
    ]
  });
};

// src/components/RenderModal/RenderStatusModal.tsx

var container51 = {
  padding: 20,
  maxWidth: 900,
  paddingTop: 0
};
var codeBlock = {
  backgroundColor: "#222",
  whiteSpace: "pre",
  padding: 12,
  borderRadius: 4,
  fontFamily: "monospace",
  overflow: "auto",
  maxHeight: 300
};
var spacer3 = {
  height: SPACING_UNIT,
  width: SPACING_UNIT
};
var buttonRow = {
  display: "flex",
  flexDirection: "row",
  justifyContent: "flex-end"
};
var RenderStatusModal = ({
  jobId
}) => {
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const { jobs, removeClientJob, cancelClientJob } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(RenderQueueContext);
  const job = jobs.find((j) => j.id === jobId);
  if (!job) {
    throw new Error("job not found");
  }
  const isClientJob = isClientRenderJob(job);
  const onQuit = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSelectedModal(null);
  }, [setSelectedModal]);
  const onRetry = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (isClientJob) {
      if (isRestoredClientJob(job)) {
        return;
      }
      const retryPayload = makeClientRetryPayload(job);
      setSelectedModal(retryPayload);
    } else {
      const retryPayload = makeRetryPayload(job);
      setSelectedModal(retryPayload);
    }
  }, [job, isClientJob, setSelectedModal]);
  const onClickOnRemove = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSelectedModal(null);
    if (isClientJob) {
      removeClientJob(job.id);
      showNotification("Removed render", 2000);
    } else {
      removeRenderJob(job).catch((err) => {
        showNotification(`Could not remove job: ${err.message}`, 2000);
      });
    }
  }, [job, isClientJob, removeClientJob, setSelectedModal]);
  const onClickOnCancel = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (isClientJob) {
      cancelClientJob(job.id);
    } else {
      cancelRenderJob(job).catch((err) => {
        showNotification(`Could not cancel job: ${err.message}`, 2000);
      });
    }
  }, [job, isClientJob, cancelClientJob]);
  if (job.status === "idle") {
    throw new Error("should not have rendered this modal");
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(ModalContainer, {
    onOutsideClick: onQuit,
    onEscape: onQuit,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalHeader, {
        title: `Render ${job.compositionId}`
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: container51,
        children: [
          job.status === "failed" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("p", {
                children: "The render failed because of the following error:"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                className: HORIZONTAL_SCROLLBAR_CLASSNAME,
                style: codeBlock,
                children: job.error.stack
              })
            ]
          }) : null,
          (job.status === "done" || job.status === "running") && (isClientJob ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ClientRenderProgress, {
            job
          }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(GuiRenderStatus, {
            job
          })),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: spacer3
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: buttonRow,
            children: [
              job.status === "running" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
                onClick: onClickOnCancel,
                children: "Cancel render"
              }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
                onClick: onClickOnRemove,
                children: "Remove render"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {}),
              job.status === "failed" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
                onClick: onRetry,
                children: "Retry"
              }) : null,
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: spacer3
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
                onClick: onQuit,
                children: "Close"
              })
            ]
          })
        ]
      })
    ]
  });
};

// src/components/RenderModal/ServerRenderModal.tsx




// src/helpers/convert-env-variables.ts
var envVariablesObjectToArray = (envVariables) => {
  return Object.entries(envVariables).map(([key5, one]) => [
    key5.trim().toUpperCase(),
    one.trim()
  ]);
};
var envVariablesArrayToObject = (envVariables) => {
  return envVariables.map(([key5, val]) => [key5.trim(), val.trim()]).filter(([key5, val]) => key5 && val).reduce((acc, [key5, value]) => {
    acc[key5.toUpperCase()] = value;
    return acc;
  }, {});
};

// src/helpers/render-modal-sections.ts

var useRenderModalSections = (renderMode, codec) => {
  const [selectedTab, setTab] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)("general");
  const shownTabs = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (renderMode === "audio") {
      return ["general", "data", "audio", "advanced"];
    }
    if (renderMode === "still") {
      return ["general", "data", "picture", "advanced"];
    }
    if (renderMode === "sequence") {
      return ["general", "data", "picture", "advanced"];
    }
    if (renderMode === "video") {
      if (codec === "gif") {
        return ["general", "data", "picture", "gif", "advanced"];
      }
      return ["general", "data", "picture", "audio", "advanced"];
    }
    throw new TypeError("Unknown render mode");
  }, [codec, renderMode]);
  const tab = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!shownTabs.includes(selectedTab)) {
      return shownTabs[0];
    }
    return selectedTab;
  }, [selectedTab, shownTabs]);
  return (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return { tab, setTab, shownTabs };
  }, [tab, shownTabs]);
};

// src/icons/audio.tsx

var AudioIcon = (props) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
  xmlns: "http://www.w3.org/2000/svg",
  viewBox: "0 0 512 512",
  ...props,
  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
    fill: "currentcolor",
    d: "M243 32.32C105.5 39.15 0 157.8 0 295.5v120.4C0 451.3 28.63 480 64 480h32c17.62 0 32-14.38 32-32V288c0-17.62-14.38-32-32-32H64c-10.79 0-20.8 2.9-29.72 7.7 14.2-106.8 100.5-193.9 210.4-199.4 120.5-5.965 221.7 83.92 234 199.9-9.08-5.1-19.48-8.2-30.68-8.2h-32c-17.62 0-32 14.38-32 32v160c0 17.62 14.38 32 32 32h32c35.38 0 64-28.75 64-64.13V287.9c0-145.4-122-262.88-269-255.58zM64 288h32v160H64c-17.62 0-32-14.5-32-32.13v-95.75C32 302.5 46.38 288 64 288zm416 127.9c0 17.6-14.4 32.1-32 32.1h-32V288h32c17.62 0 32 14.5 32 32.13v95.77z"
  })
});

// src/icons/data.tsx

var DataIcon = (props) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    xmlns: "http://www.w3.org/2000/svg",
    viewBox: "0 0 448 512",
    ...props,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: "currentcolor",
      d: "M224 512C100.3 512 0 476.2 0 432V80C0 35.82 100.3 0 224 0C347.7 0 448 35.82 448 80V432C448 476.2 347.7 512 224 512zM416 80.45C415.7 79.69 414.4 77.27 409.8 73.31C402.4 67.11 389.9 60.09 371.6 53.57C335.4 40.62 283.2 32 224 32C164.8 32 112.6 40.62 76.37 53.57C58.1 60.09 45.59 67.11 38.25 73.31C33.55 77.27 32.29 79.69 32 80.45V182.1C46.47 192.7 69.9 202.8 100.9 210.4C135.5 218.9 177.1 224 224 224C270 224 312.5 218.9 347.1 210.4C378.1 202.8 401.5 192.7 416 182.1V80.45zM416 219.5C398.8 228.4 377.9 235.8 354.8 241.5C317.3 250.7 272.2 256 224 256C175.8 256 130.7 250.7 93.22 241.5C70.11 235.8 49.18 228.4 32 219.5V310.1C46.47 320.7 69.9 330.8 100.9 338.4C135.5 346.9 177.1 352 224 352C270 352 312.5 346.9 347.1 338.4C378.1 330.8 401.5 320.7 416 310.1V219.5zM38.25 438.7C45.59 444.9 58.1 451.9 76.37 458.4C112.6 471.4 164.8 480 224 480C283.2 480 335.4 471.4 371.6 458.4C389.9 451.9 402.4 444.9 409.8 438.7C414.4 434.7 415.7 432.3 416 431.6V347.5C398.8 356.4 377.9 363.8 354.8 369.5C317.3 378.7 272.2 384 224 384C175.8 384 130.7 378.7 93.22 369.5C70.11 363.8 49.18 356.4 32 347.5V431.6C32.29 432.3 33.55 434.7 38.25 438.7zM416 431.4C416.1 431.3 416.1 431.3 416.1 431.3L416 431.4zM31.96 431.4C31.94 431.3 31.93 431.3 31.92 431.3L31.96 431.4zM31.96 80.56C31.93 80.65 31.92 80.7 31.92 80.7L31.96 80.56zM416.1 80.7C416.1 80.7 416.1 80.65 416 80.56z"
    })
  });
};

// src/icons/frame.tsx

var PicIcon = (props) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
  xmlns: "http://www.w3.org/2000/svg",
  viewBox: "0 0 512 512",
  ...props,
  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
    fill: "currentcolor",
    d: "M324.9 157.8c-11.38-17.38-39.89-17.31-51.23-.063L200.5 268.5l-16.4-22.6c-11.4-16.8-38.2-16-49.7 0l-64.52 89.16c-6.797 9.406-7.75 21.72-2.547 32C72.53 377.5 83.05 384 94.75 384h322.5c11.41 0 21.8-6.281 27.14-16.38a30.922 30.922 0 0 0-1.516-31.56L324.9 157.8zM95.8 352l62.39-87.38 29.91 41.34c3.1 4.24 8.3 7.24 13.3 6.64 5.25-.125 10.12-2.781 13.02-7.188l83.83-129.9L415 352H95.8zM447.1 32h-384C28.65 32-.01 60.65-.01 96v320c0 35.35 28.65 64 63.1 64h384c35.35 0 64-28.65 64-64V96c.01-35.35-27.79-64-63.99-64zM480 416c0 17.64-14.36 32-32 32H64c-17.64 0-32-14.36-32-32V96c0-17.64 14.36-32 32-32h384c17.64 0 32 14.36 32 32v320zM144 192c26.5 0 48-21.5 48-48s-21.5-48-48-48-48 21.5-48 48 21.5 48 48 48zm0-64c8.822 0 15.1 7.178 15.1 16s-6.3 16-15.1 16-16-7.2-16-16 7.2-16 16-16z"
  })
});

// src/icons/gear.tsx

var GearIcon = (props) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
  xmlns: "http://www.w3.org/2000/svg",
  viewBox: "0 0 512 512",
  ...props,
  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
    fill: "currentcolor",
    d: "M168 255.1c0-47.7 39.4-88 88-88s88 40.3 88 88c0 49.5-39.4 88.9-88 88.9s-88-39.4-88-88.9zm88-56c-30.9 0-56 26-56 56 0 31.8 25.1 56 56 56s56-24.2 56-56c0-30-25.1-56-56-56zM65.67 230.6l-40.33-36.8c-11.12-10.1-13.68-26.6-6.16-39.6l30.24-52.4c7.52-13.02 23.09-19.05 37.42-14.48l51.96 16.58c13.4-10.34 28.2-18.94 44-25.47l11.7-53.27C197.7 10.47 210.7 0 225.8 0h60.4c15.1 0 28.1 10.47 31.3 25.16l11.7 53.27c14.9 6.53 30.6 15.13 44 25.47l52-16.58c14.3-4.57 29.9 1.46 37.4 14.48l30.2 52.4c7.5 13 5 29.5-6.1 39.6l-40.4 36.8c1.1 8.3 1.7 16.8 1.7 24.5 0 9.5-.6 18-1.7 26.3l40.4 36.8c11.1 10.1 13.6 26.6 6.1 39.6l-30.2 52.4c-7.5 13-23.1 19-37.4 14.5l-52-16.6c-13.4 10.3-29.1 18.9-44 25.5l-11.7 53.2c-3.2 14.7-16.2 25.2-31.3 25.2h-60.4c-15.1 0-28.1-10.5-31.3-25.2l-11.7-53.2c-15.8-6.6-30.6-15.2-44-25.5l-51.96 16.6c-14.33 4.5-29.9-1.5-37.42-14.5l-30.24-52.4c-7.52-13-4.96-29.5 6.16-39.6l40.33-36.8c-1.1-8.3-1.67-16.8-1.67-26.3 0-7.7.57-16.2 1.67-24.5zm92.73-101.4-13.3 10.3-67.97-21.7-30.24 52.4 52.69 48-2.19 16.6c-.92 6.9-1.39 14-1.39 20.3 0 8.1.47 15.2 1.39 22.1l2.19 16.6-52.69 48 30.24 52.4 67.97-21.7 13.3 10.3c11.1 8.6 23.5 15.8 36.6 20.3l15.5 7.3 15.3 69.6h60.4l15.3-69.6 14.6-7.3c14-4.5 26.4-11.7 37.5-20.3l13.3-10.3 68 21.7 30.2-52.4-52.7-48 2.2-16.6c.9-6.9 1.4-14 1.4-21.2 0-7.2-.5-14.3-1.4-21.2l-2.2-16.6 52.7-48-30.2-52.4-68 21.7-13.3-10.3c-11.1-8.6-23.5-15.8-37.5-21.2l-14.6-6.4L286.2 32h-60.4l-15.3 69.6L195 108c-13.1 5.4-25.5 12.6-36.6 21.2z"
  })
});

// src/icons/gif.tsx

var GifIcon = (props) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
  xmlns: "http://www.w3.org/2000/svg",
  viewBox: "0 0 576 512",
  ...props,
  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
    fill: "currentcolor",
    d: "M512 32H64C28.65 32 0 60.65 0 96v320c0 35.35 28.65 64 64 64h448c35.35 0 64-28.65 64-64V96c0-35.35-28.7-64-64-64zm32 384c0 17.64-14.36 32-32 32H64c-17.64 0-32-14.36-32-32V96c0-17.64 14.36-32 32-32h448c17.64 0 32 14.36 32 32v320zm-80-256h-96c-8.8 0-16 7.2-16 16v160c0 8.844 7.156 16 16 16s16-7.156 16-16v-64h56c8.844 0 16-7.156 16-16s-7.156-16-16-16h-56v-48h80c8.8 0 16-7.2 16-16s-7.2-16-16-16zm-160 0c-8.8 0-16 7.2-16 16v160c0 8.844 7.156 16 16 16s16-7.156 16-16V176c0-8.8-7.2-16-16-16zm-64 80h-64c-8.8 0-16 7.2-16 16s7.156 16 16 16h48v33.45c-24.83 19.91-69.13 18.16-91.48-4.203-24.95-24.95-24.95-65.55 0-90.5 25.03-25 64.19-25 89.22 0 6.25 6.25 16.38 6.25 22.62 0s6.25-16.38 0-22.62c-37.69-37.72-96.78-37.72-134.5 0-37.42 37.42-37.42 98.33 0 135.8C127.8 341.8 153.5 352 180.6 352c27.06 0 52.84-10.25 70.7-28.12 3-2.98 4.7-7.08 4.7-11.28V256c0-8.8-7.2-16-16-16z"
  })
});

// src/components/Tabs/vertical.tsx


var selectorButton2 = {
  border: "none",
  flex: 1,
  padding: 8,
  paddingLeft: 16,
  display: "flex",
  flexDirection: "row",
  fontSize: 14,
  color: "inherit",
  alignItems: "center",
  userSelect: "none",
  WebkitUserSelect: "none"
};
var VerticalTab = ({ children, onClick, style: style12, selected }) => {
  const [hovered, setHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const { tabIndex } = useZIndex();
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(true);
  }, []);
  const onPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(false);
  }, []);
  const definiteStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...selectorButton2,
      backgroundColor: selected ? SELECTED_BACKGROUND : hovered ? CLEAR_HOVER : "transparent",
      color: selected ? "white" : LIGHT_TEXT,
      boxShadow: selected ? "none" : undefined,
      ...style12
    };
  }, [hovered, selected, style12]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
    style: definiteStyle,
    type: "button",
    onClick,
    tabIndex,
    onPointerLeave,
    onPointerEnter,
    children
  });
};

// src/components/RenderModal/CrfSetting.tsx



// src/components/RenderModal/NumberSetting.tsx


// src/components/RenderModal/OptionExplainerBubble.tsx


// src/components/RenderModal/CliCopyButton.tsx


var svgStyle2 = {
  width: 16,
  height: 16,
  verticalAlign: "sub"
};
var copiedStyle = {
  fontSize: "14px",
  minHeight: "30px",
  minWidth: "30px",
  display: "flex",
  alignItems: "center",
  justifyContent: "center"
};
var buttonStyle6 = {
  width: "30px",
  height: "30px",
  border: "none",
  cursor: "pointer",
  display: "flex",
  alignItems: "center",
  justifyContent: "center"
};
var CliCopyButton = ({
  valueToCopy
}) => {
  const [copied, setCopied] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const [hovered, setHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const fillColor = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return hovered ? "white" : LIGHT_TEXT;
  }, [hovered]);
  const clipboardIcon = /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ClipboardIcon, {
    color: fillColor,
    style: svgStyle2
  });
  const checkSvg = /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    xmlns: "http://www.w3.org/2000/svg",
    viewBox: "0 0 448 512",
    style: svgStyle2,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: fillColor,
      d: "M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"
    })
  });
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(true);
  }, []);
  const onPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(false);
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!copied) {
      return;
    }
    const handleClear = () => {
      setCopied(false);
      setHovered(false);
    };
    const to = setTimeout(() => handleClear(), 2000);
    return () => clearTimeout(to);
  }, [copied]);
  return copied ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
    style: copiedStyle,
    children: checkSvg
  }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
    type: "button",
    onPointerEnter,
    onPointerLeave,
    style: buttonStyle6,
    onClick: () => {
      navigator.clipboard.writeText(valueToCopy);
      setCopied(true);
    },
    children: clipboardIcon
  });
};

// src/components/RenderModal/OptionExplainer.tsx

var container52 = {
  fontSize: 14,
  paddingTop: 10,
  paddingBottom: 10,
  backgroundColor: INPUT_BACKGROUND
};
var padding3 = {
  paddingLeft: 20,
  paddingRight: 20
};
var title6 = {
  fontSize: 14
};
var description = {
  fontSize: 14,
  maxWidth: 400
};
var link2 = {
  fontSize: 14,
  maxWidth: 200,
  color: "#0b84f3",
  wordWrap: "break-word",
  textDecoration: "none"
};
var infoRow = {
  ...padding3,
  fontSize: 14,
  display: "flex",
  flexDirection: "row",
  alignItems: "center"
};
var infoRowLabel = {
  width: 150,
  fontSize: 14,
  color: "white"
};
var flexSpacer = {
  display: "flex",
  flex: 1
};
var copyWrapper = {
  display: "flex",
  justifyContent: "flex-end"
};
var OptionExplainer = ({ option }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container52,
    className: "__remotion-info-button-container",
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: padding3,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("strong", {
                style: title6,
                children: option.name
              }),
              option.docLink ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                    x: 1
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("a", {
                    style: link2,
                    href: option.docLink,
                    target: "_blank",
                    children: "Docs"
                  })
                ]
              }) : null
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: description,
            children: option.description("ssr")
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 0.5,
        block: true
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MenuDivider, {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 0.5,
        block: true
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: infoRow,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: infoRowLabel,
                children: "CLI flag"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: flexSpacer
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("code", {
                children: [
                  "--",
                  option.cliFlag
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: copyWrapper,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CliCopyButton, {
                  valueToCopy: option.cliFlag
                })
              })
            ]
          }),
          option.ssrName ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: infoRow,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: infoRowLabel,
                children: "Node.JS option"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: flexSpacer
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
                children: option.ssrName
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 3.75
              })
            ]
          }) : null,
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: infoRow
          })
        ]
      })
    ]
  });
};

// src/components/RenderModal/OptionExplainerBubble.tsx

var OptionExplainerBubble = ({ id }) => {
  const option = _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.options[id];
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InfoBubble, {
    title: "Learn more about this option",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainer, {
      option
    })
  });
};

// src/components/RenderModal/NumberSetting.tsx

var NumberSetting = ({ name, value, step, hint, onValueChanged, max, min, formatter }) => {
  const onTextChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    onValueChanged((q) => {
      const newSetting = step < 1 ? parseFloat(e) : parseInt(e, 10);
      if (Number.isNaN(newSetting)) {
        return q;
      }
      return Math.min(max ?? Infinity, Math.max(newSetting, min));
    });
  }, [max, min, onValueChanged, step]);
  const onValueChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newConcurrency) => {
    onValueChanged(newConcurrency);
  }, [onValueChanged]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: optionRow,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: label5,
        children: [
          name,
          hint ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: hint
              })
            ]
          }) : null
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: rightRow,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RightAlignInput, {
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InputDragger, {
            value,
            name: name.toLowerCase(),
            onTextChange: onTextChanged,
            onValueChange,
            step,
            placeholder: [min, max].map((f) => f !== null && f !== undefined ? f : "").join("-"),
            min,
            max,
            formatter,
            status: "ok",
            rightAlign: true
          })
        })
      })
    ]
  });
};

// src/components/RenderModal/CrfSetting.tsx

var getDefaultCrfState = () => {
  return _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.validCodecs.map((c) => {
    return [c, _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.getDefaultCrfForCodec(c)];
  }).reduce((acc, [codec, crf]) => {
    return {
      ...acc,
      [codec]: crf
    };
  }, {});
};
var useCrfState = (codec) => {
  const [state, setState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => getDefaultCrfState());
  const range = _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.getValidCrfRanges(codec);
  const setCrf = (updater) => {
    setState((q) => {
      const val = q[codec];
      if (val === null) {
        throw new TypeError(`Got unexpected codec "${codec}"`);
      }
      return {
        ...q,
        [codec]: typeof updater === "number" ? updater : updater(val)
      };
    });
  };
  return {
    crf: state[codec],
    setCrf,
    minCrf: range[0],
    maxCrf: range[1]
  };
};
var CrfSetting = ({ crf, setCrf, min, max, option }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NumberSetting, {
    min,
    max,
    name: "CRF",
    onValueChanged: setCrf,
    value: crf,
    step: 1,
    hint: option
  });
};

// src/components/RenderModal/get-default-codecs.ts


var getDefaultCodecs = ({
  defaultConfigurationVideoCodec,
  compositionDefaultVideoCodec,
  renderType,
  defaultConfigurationAudioCodec
}) => {
  const userPreferredVideoCodec = compositionDefaultVideoCodec ?? defaultConfigurationVideoCodec ?? "h264";
  const userPreferredVideoCodecForAudioTab = userPreferredVideoCodec === "aac" ? "aac" : userPreferredVideoCodec === "mp3" ? "mp3" : userPreferredVideoCodec === "wav" ? "wav" : defaultConfigurationAudioCodec === "pcm-16" ? "wav" : defaultConfigurationAudioCodec === "mp3" ? "mp3" : "aac";
  const isVideoCodecAnAudioCodec = _remotion_renderer_pure__WEBPACK_IMPORTED_MODULE_15__/* .NoReactAPIs */ .c.isAudioCodec(userPreferredVideoCodec);
  if (isVideoCodecAnAudioCodec) {
    return {
      initialAudioCodec: null,
      initialRenderType: "audio",
      initialVideoCodec: userPreferredVideoCodec,
      initialVideoCodecForAudioTab: userPreferredVideoCodecForAudioTab,
      initialVideoCodecForVideoTab: _remotion_renderer_pure__WEBPACK_IMPORTED_MODULE_15__/* .NoReactAPIs */ .c.isAudioCodec(defaultConfigurationVideoCodec) ? "h264" : defaultConfigurationVideoCodec
    };
  }
  const suitableAudioCodecForVideoCodec = _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.defaultAudioCodecs[userPreferredVideoCodec].compressed;
  return {
    initialAudioCodec: defaultConfigurationAudioCodec ?? suitableAudioCodecForVideoCodec,
    initialVideoCodec: userPreferredVideoCodec,
    initialRenderType: renderType,
    initialVideoCodecForAudioTab: userPreferredVideoCodecForAudioTab,
    initialVideoCodecForVideoTab: userPreferredVideoCodec
  };
};

// src/components/RenderModal/get-string-before-suffix.ts
var getStringBeforeSuffix = (fileName) => {
  const dotPos = fileName.lastIndexOf(".");
  if (dotPos === -1) {
    return fileName;
  }
  return fileName.substring(0, dotPos);
};

// src/components/RenderModal/out-name-checker.ts

var invalidCharacters = ["?", "*", "+", ":", "%"];
var isValidStillExtension = (extension, stillImageFormat) => {
  if (stillImageFormat === "jpeg" && extension === "jpg") {
    return true;
  }
  return extension === stillImageFormat;
};
var validateOutnameGui = ({
  outName,
  codec,
  audioCodec,
  renderMode,
  stillImageFormat,
  separateAudioTo
}) => {
  try {
    isValidOutName({
      audioCodec,
      codec,
      outName,
      renderMode,
      stillImageFormat,
      separateAudioTo
    });
    return { valid: true };
  } catch (err) {
    return { valid: false, error: err };
  }
};
var isValidOutName = ({
  outName,
  codec,
  audioCodec,
  renderMode,
  stillImageFormat,
  separateAudioTo
}) => {
  const extension = outName.substring(outName.lastIndexOf(".") + 1);
  const prefix = outName.substring(0, outName.lastIndexOf("."));
  const map = _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.defaultFileExtensionMap[codec];
  if (_remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.supportedAudioCodecs[codec].length > 0 && !(audioCodec in map.forAudioCodec)) {
    throw new Error(`Audio codec ${audioCodec} is not supported for codec ${codec}`);
  }
  const hasDotAfterSlash = () => {
    const substrings = prefix.split("/");
    for (const str of substrings) {
      if (str[0] === ".") {
        return true;
      }
    }
    return false;
  };
  const hasInvalidChar = () => {
    return prefix.split("").some((char) => invalidCharacters.includes(char));
  };
  if (renderMode === "video" || renderMode === "audio") {
    _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.validateOutputFilename({
      codec,
      audioCodecSetting: audioCodec ?? null,
      extension,
      preferLossless: false,
      separateAudioTo
    });
  }
  if (prefix.length < 1 && renderMode !== "sequence") {
    throw new Error("The prefix must be at least 1 character long");
  }
  if (prefix[0] === "." || hasDotAfterSlash()) {
    throw new Error("The output name must not start with a dot");
  }
  if (hasInvalidChar()) {
    throw new Error("Filename can't contain the following characters:  ?, *, +, %, :");
  }
  if (renderMode === "still" && stillImageFormat && !isValidStillExtension(extension, stillImageFormat)) {
    throw new Error(`The extension ${extension} is not supported for still image format ${stillImageFormat}`);
  }
  if (renderMode === "sequence") {
    if (outName.includes(".")) {
      throw new Error("Folder names must not contain a dot");
    }
  }
};

// src/components/RenderModal/render-modals.ts
var outerModalStyle = {
  width: getMaxModalWidth(1000),
  height: getMaxModalHeight(640),
  overflow: "hidden",
  display: "flex",
  flexDirection: "column"
};
var container53 = {
  display: "flex",
  flexDirection: "row",
  alignItems: "center",
  padding: "12px 16px",
  borderBottom: "1px solid black"
};
var optionsPanel = {
  display: "flex",
  width: "100%"
};
var horizontalLayout = {
  display: "flex",
  flexDirection: "row",
  overflowY: "auto",
  flex: 1
};
var leftSidebar = {
  padding: 12
};
var horizontalTab = {
  width: 250,
  display: "flex",
  flexDirection: "row",
  alignItems: "center",
  textAlign: "left",
  fontSize: 16,
  fontWeight: "bold",
  paddingLeft: 15,
  paddingTop: 12,
  paddingBottom: 12
};
var iconContainer = {
  width: 20,
  height: 20,
  marginRight: 15,
  display: "inline-flex",
  justifyContent: "center",
  alignItems: "center"
};
var icon6 = {
  color: "currentcolor",
  height: 20
};
var buttonStyle7 = {
  backgroundColor: BLUE,
  color: "white"
};
var flexer = {
  flex: 1
};

// src/components/RenderModal/RenderModalAdvanced.tsx



// src/helpers/presets-labels.ts
var labelx264Preset = (profile) => {
  if (profile === "ultrafast") {
    return "ultrafast";
  }
  if (profile === "superfast") {
    return "superfast";
  }
  if (profile === "veryfast") {
    return "veryfast";
  }
  if (profile === "faster") {
    return "faster";
  }
  if (profile === "fast") {
    return "fast";
  }
  if (profile === "medium") {
    return "medium";
  }
  if (profile === "slow") {
    return "slow";
  }
  if (profile === "slower") {
    return "slower";
  }
  if (profile === "veryslow") {
    return "veryslow";
  }
  if (profile === "placebo") {
    return "placebo";
  }
  throw new TypeError(`Unknown x264 preset: ${profile}`);
};

// src/components/RenderModal/RenderModalEnvironmentVariables.tsx


// src/components/RenderModal/EnvInput.tsx


// src/components/RenderModal/InlineEyeIcon.tsx


var clearIcon2 = {
  height: 14,
  color: "currentColor"
};
var InlineEyeButton = ({ onClick, enabled }) => {
  const renderAction = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((color) => {
    return enabled ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      style: clearIcon2,
      viewBox: "0 0 640 512",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        fill: color,
        d: "M25.9 3.4C19-2 8.9-.8 3.4 6.1S-.8 23.1 6.1 28.6l608 480c6.9 5.5 17 4.3 22.5-2.6s4.3-17-2.6-22.5L25.9 3.4zM605.5 268.3c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C465.5 68.8 400.8 32 320 32c-51.2 0-96 14.8-133.9 36.8l27.3 21.5C244.6 74.2 280.2 64 320 64c70.4 0 127.7 32 170.8 72c43.1 40 71.9 88 85.2 120c-9.2 22.1-25.9 52-49.5 81.5l25.1 19.8c25.6-32 43.7-64.4 53.9-89zM88.4 154.7c-25.6 32-43.7 64.4-53.9 89c-3.3 7.9-3.3 16.7 0 24.6c14.9 35.7 46.2 87.7 93 131.1C174.5 443.2 239.2 480 320 480c51.2 0 96-14.8 133.9-36.8l-27.3-21.5C395.4 437.8 359.8 448 320 448c-70.4 0-127.7-32-170.8-72C106.1 336 77.3 288 64 256c9.2-22.1 25.9-52 49.5-81.5L88.4 154.7zM320 384c16.7 0 32.7-3.2 47.4-9.1l-30.9-24.4c-5.4 .9-10.9 1.4-16.5 1.4c-51 0-92.8-39.8-95.8-90.1l-30.9-24.4c-.9 6-1.3 12.2-1.3 18.5c0 70.7 57.3 128 128 128zM448 256c0-70.7-57.3-128-128-128c-16.7 0-32.7 3.2-47.4 9.1l30.9 24.4c5.4-.9 10.9-1.4 16.5-1.4c51 0 92.8 39.8 95.8 90.1l30.9 24.4c.9-6 1.3-12.2 1.3-18.5z"
      })
    }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
      style: clearIcon2,
      viewBox: "0 0 576 512",
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
        fill: color,
        d: "M117.2 136C160.3 96 217.6 64 288 64s127.7 32 170.8 72c43.1 40 71.9 88 85.2 120c-13.3 32-42.1 80-85.2 120c-43.1 40-100.4 72-170.8 72s-127.7-32-170.8-72C74.1 336 45.3 288 32 256c13.3-32 42.1-80 85.2-120zM288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM192 256a96 96 0 1 1 192 0 96 96 0 1 1 -192 0zm224 0a128 128 0 1 0 -256 0 128 128 0 1 0 256 0z"
      })
    });
  }, [enabled]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineAction, {
    renderAction,
    onClick
  });
};

// src/components/RenderModal/EnvInput.tsx

var input3 = {
  flex: 1,
  width: "100%"
};
var validationStyle = {
  paddingLeft: optionRow.paddingLeft,
  paddingRight: optionRow.paddingRight
};
var EnvInput = ({
  onEnvKeyChange,
  onEnvValChange,
  envKey,
  envVal,
  onDelete,
  index,
  autoFocus,
  isDuplicate
}) => {
  const [showInPlainText, setShowInPlainText] = react__WEBPACK_IMPORTED_MODULE_0__.useState(false);
  const [initialWarningKeyMissing, setKeyWarningEligible] = react__WEBPACK_IMPORTED_MODULE_0__.useState(() => {
    return envKey.trim() === "" && envVal.trim() !== "";
  });
  const [initialWarningValMissing, setValueWarningEligible] = react__WEBPACK_IMPORTED_MODULE_0__.useState(() => {
    return envKey.trim() !== "" && envVal.trim() === "";
  });
  const isKeyMissing = envKey.trim() === "" && initialWarningKeyMissing && envVal.trim() !== "";
  const isValMissing = envVal.trim() === "" && initialWarningValMissing && envKey.trim() !== "";
  const handleDelete = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    onDelete(index);
  }, [index, onDelete]);
  const togglePlainText = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setShowInPlainText((prev) => !prev);
  }, []);
  const handleKeyChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    onEnvKeyChange(index, e.target.value);
  }, [index, onEnvKeyChange]);
  const handleValueChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    onEnvValChange(index, e.target.value);
  }, [index, onEnvValChange]);
  const makeKeyWarningEligible = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setKeyWarningEligible(true);
  }, []);
  const makeValueWarningEligible = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setValueWarningEligible(true);
  }, []);
  const isNodeEnvKey = envKey.trim() === "NODE_ENV";
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
        align: "center",
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
            status: isNodeEnvKey || isDuplicate || isKeyMissing ? "warning" : "ok",
            type: "text",
            placeholder: "Key",
            style: input3,
            value: envKey,
            onBlur: makeKeyWarningEligible,
            autoFocus,
            onChange: handleKeyChange,
            rightAlign: false
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 1
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
            status: isValMissing ? "warning" : "ok",
            placeholder: "Value",
            type: showInPlainText ? "text" : "password",
            style: input3,
            value: envVal,
            onBlur: makeValueWarningEligible,
            onChange: handleValueChange,
            rightAlign: false
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 1.5
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineEyeButton, {
            enabled: !showInPlainText,
            onClick: togglePlainText
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InlineRemoveButton, {
            onClick: handleDelete
          })
        ]
      }),
      isNodeEnvKey ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: validationStyle,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ValidationMessage, {
          align: "flex-start",
          type: "warning",
          message: "NODE_ENV will be overwritten by Remotion during the render process."
        })
      }) : null,
      isDuplicate ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: validationStyle,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ValidationMessage, {
          align: "flex-start",
          type: "warning",
          message: `${envKey.toUpperCase()} is already defined.`
        })
      }) : null,
      isKeyMissing ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: validationStyle,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ValidationMessage, {
          align: "flex-start",
          type: "warning",
          message: "Key is missing."
        })
      }) : null,
      isValMissing ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: validationStyle,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ValidationMessage, {
          align: "flex-start",
          type: "warning",
          message: "Value is missing."
        })
      }) : null
    ]
  });
};

// src/components/RenderModal/RenderModalEnvironmentVariables.tsx

var title7 = {
  fontSize: 14,
  fontWeight: "bold",
  color: LIGHT_TEXT,
  marginLeft: 16
};
var container54 = {
  marginTop: 20
};
var button3 = {
  marginLeft: 16
};
var RenderModalEnvironmentVariables = ({ envVariables, setEnvVariables }) => {
  const onEnvValChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((index, value) => {
    setEnvVariables((oldEnv) => {
      const newEnv = [...oldEnv];
      newEnv[index][1] = value;
      return newEnv;
    });
  }, [setEnvVariables]);
  const onEnvKeyChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((index, value) => {
    setEnvVariables((oldEnv) => {
      const newEnv = [...oldEnv];
      newEnv[index][0] = value;
      return newEnv;
    });
  }, [setEnvVariables]);
  const onDelete = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((index) => {
    setEnvVariables((oldEnv) => oldEnv.filter((_, idx) => idx !== index));
  }, [setEnvVariables]);
  const addField = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setEnvVariables((oldEnv) => [...oldEnv, ["", ""]]);
  }, [setEnvVariables]);
  const usedKeys = [];
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container54,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("strong", {
        style: title7,
        children: "Environment variables"
      }),
      envVariables.map((env, i) => {
        let isDuplicate = false;
        if (usedKeys.includes(env[0].toUpperCase())) {
          isDuplicate = true;
        }
        usedKeys.push(env[0].toUpperCase());
        return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(EnvInput, {
          onEnvKeyChange,
          onEnvValChange,
          envKey: env[0],
          envVal: env[1],
          onDelete,
          index: i,
          isDuplicate,
          autoFocus: i === envVariables.length - 1 && env[0] === ""
        }, i);
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 1,
        block: true
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Button, {
        style: button3,
        onClick: addField,
        children: "+ Add env variable"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        y: 1,
        block: true
      })
    ]
  });
};

// src/components/RenderModal/RenderModalHr.tsx

var hrStyle = {
  margin: "0 0 0 0",
  padding: "0 0 0 0",
  border: "none",
  borderTop: "1px solid #000",
  marginRight: 16,
  marginLeft: 16,
  marginTop: 8,
  marginBottom: 8
};
var RenderModalHr = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: hrStyle
  });
};

// src/components/RenderModal/RenderModalAdvanced.tsx

var container55 = {
  flex: 1,
  overflowY: "auto"
};
var RenderModalAdvanced = ({
  renderMode,
  maxConcurrency,
  minConcurrency,
  setConcurrency,
  concurrency,
  delayRenderTimeout,
  setDelayRenderTimeout,
  disallowParallelEncoding,
  setDisallowParallelEncoding,
  setDisableWebSecurity,
  setIgnoreCertificateErrors,
  setHeadless,
  headless,
  ignoreCertificateErrors,
  disableWebSecurity,
  openGlOption,
  setOpenGlOption,
  setEnvVariables,
  envVariables,
  setx264Preset,
  x264Preset,
  codec,
  setMediaCacheSizeInBytes,
  mediaCacheSizeInBytes,
  offthreadVideoCacheSizeInBytes,
  setOffthreadVideoCacheSizeInBytes,
  offthreadVideoThreads,
  setOffthreadVideoThreads,
  enableMultiProcessOnLinux,
  setChromiumMultiProcessOnLinux,
  setUserAgent,
  userAgent,
  beep,
  setBeep,
  repro,
  setRepro,
  hardwareAcceleration,
  chromeModeOption,
  setChromeModeOption,
  setHardwareAcceleration,
  darkMode,
  setDarkMode
}) => {
  const extendedOpenGlOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return [
      "angle",
      "egl",
      "swangle",
      "swiftshader",
      "vulkan",
      "angle-egl",
      "default"
    ];
  }, []);
  const toggleCustomMediaCacheSizeInBytes = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setMediaCacheSizeInBytes((previous) => {
      if (previous === null) {
        return 1000 * 1000 * 1000;
      }
      return null;
    });
  }, [setMediaCacheSizeInBytes]);
  const toggleCustomOffthreadVideoCacheSizeInBytes = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setOffthreadVideoCacheSizeInBytes((previous) => {
      if (previous === null) {
        return 512 * 1024 * 1024;
      }
      return null;
    });
  }, [setOffthreadVideoCacheSizeInBytes]);
  const toggleCustomOffthreadVideoThreads = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setOffthreadVideoThreads((previous) => {
      if (previous === null) {
        return 2;
      }
      return null;
    });
  }, [setOffthreadVideoThreads]);
  const toggleCustomUserAgent = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setUserAgent((previous) => {
      if (previous === null) {
        return "Mozilla/5.0 (Remotion)";
      }
      return null;
    });
  }, [setUserAgent]);
  const onDisallowParallelEncodingChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setDisallowParallelEncoding(e.target.checked);
  }, [setDisallowParallelEncoding]);
  const onDisableWebSecurityChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setDisableWebSecurity(e.target.checked);
  }, [setDisableWebSecurity]);
  const onEnableMultiProcessOnLinux = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setChromiumMultiProcessOnLinux(e.target.checked);
  }, [setChromiumMultiProcessOnLinux]);
  const onIgnoreCertificatErrors = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setIgnoreCertificateErrors(e.target.checked);
  }, [setIgnoreCertificateErrors]);
  const onHeadless = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setHeadless(e.target.checked);
  }, [setHeadless]);
  const onUserAgentChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setUserAgent(e.target.value);
  }, [setUserAgent]);
  const onDarkMode = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setDarkMode(e.target.checked);
  }, [setDarkMode]);
  const onPlayBeepSound = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setBeep(e.target.checked);
  }, [setBeep]);
  const onReproToggle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setRepro(e.target.checked);
  }, [setRepro]);
  const openGlOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return extendedOpenGlOptions.map((option) => {
      return {
        label: option === "default" ? "Default" : option,
        onClick: () => setOpenGlOption(option),
        key: option,
        leftItem: openGlOption === option ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        id: option,
        keyHint: null,
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: option
      };
    });
  }, [extendedOpenGlOptions, openGlOption, setOpenGlOption]);
  const chromeModeOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.validChromeModeOptions.map((option) => {
      return {
        label: option,
        onClick: () => setChromeModeOption(option),
        key: option,
        leftItem: chromeModeOption === option ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        id: option,
        keyHint: null,
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: option
      };
    });
  }, [chromeModeOption, setChromeModeOption]);
  const x264PresetOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.x264PresetOptions.map((option) => {
      return {
        label: labelx264Preset(option),
        onClick: () => setx264Preset(option),
        key: option,
        type: "item",
        id: option,
        keyHint: null,
        leftItem: x264Preset === option ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        quickSwitcherLabel: null,
        subMenu: null,
        value: option
      };
    });
  }, [setx264Preset, x264Preset]);
  const hardwareAccelerationValues = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.hardwareAccelerationOptions.map((option) => {
      return {
        label: option,
        onClick: () => setHardwareAcceleration(option),
        leftItem: hardwareAcceleration === option ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        subMenu: null,
        quickSwitcherLabel: null,
        type: "item",
        id: option,
        keyHint: null,
        value: option
      };
    });
  }, [hardwareAcceleration, setHardwareAcceleration]);
  const changeMediaCacheSizeInBytes = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((cb) => {
    setMediaCacheSizeInBytes((prev) => {
      if (prev === null) {
        throw new TypeError("Expected previous value");
      }
      if (typeof cb === "function") {
        return cb(prev);
      }
      return cb;
    });
  }, [setMediaCacheSizeInBytes]);
  const changeOffthreadVideoCacheSizeInBytes = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((cb) => {
    setOffthreadVideoCacheSizeInBytes((prev) => {
      if (prev === null) {
        throw new TypeError("Expected previous value");
      }
      if (typeof cb === "function") {
        return cb(prev);
      }
      return cb;
    });
  }, [setOffthreadVideoCacheSizeInBytes]);
  const changeOffthreadVideoThreads = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((cb) => {
    setOffthreadVideoThreads((prev) => {
      if (prev === null) {
        throw new TypeError("Expected previous value");
      }
      if (typeof cb === "function") {
        return cb(prev);
      }
      return cb;
    });
  }, [setOffthreadVideoThreads]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container55,
    className: VERTICAL_SCROLLBAR_CLASSNAME,
    children: [
      renderMode === "still" ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NumberSetting, {
        min: minConcurrency,
        max: maxConcurrency,
        step: 1,
        name: "Concurrency",
        formatter: (w) => `${w}x`,
        onValueChanged: setConcurrency,
        value: concurrency
      }),
      renderMode === "video" && codec === "h264" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "x264 Preset",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "x264Option"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
              title: x264Preset,
              selectedId: x264Preset,
              values: x264PresetOptions
            })
          })
        ]
      }) : null,
      renderMode === "video" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Hardware acceleration",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "hardwareAccelerationOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
              title: hardwareAcceleration,
              selectedId: hardwareAcceleration,
              values: hardwareAccelerationValues
            })
          })
        ]
      }) : null,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NumberSetting, {
        min: 7000,
        max: 900000,
        name: "delayRender() timeout",
        onValueChanged: setDelayRenderTimeout,
        formatter: (w) => `${w}ms`,
        step: 1000,
        hint: "delayRenderTimeoutInMillisecondsOption",
        value: delayRenderTimeout
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: label5,
            children: "No parallel encoding"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: disallowParallelEncoding,
              onChange: onDisallowParallelEncodingChanged,
              name: "disallow-parallel-encoding"
            })
          })
        ]
      }),
      renderMode === "audio" ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Custom @remotion/media cache size",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "mediaCacheSizeInBytesOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: mediaCacheSizeInBytes !== null,
              onChange: toggleCustomMediaCacheSizeInBytes,
              name: "media-cache-size"
            })
          })
        ]
      }),
      renderMode === "audio" || mediaCacheSizeInBytes === null ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NumberSetting, {
        min: 0,
        max: 2000 * 1024 * 1024,
        step: 1024,
        name: "@remotion/media cache size",
        formatter: (w) => `${w} bytes`,
        onValueChanged: changeMediaCacheSizeInBytes,
        value: mediaCacheSizeInBytes
      }),
      renderMode === "audio" ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Custom OffthreadVideo cache",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "offthreadVideoCacheSizeInBytesOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: offthreadVideoCacheSizeInBytes !== null,
              onChange: toggleCustomOffthreadVideoCacheSizeInBytes,
              name: "custom-audio-bitrate"
            })
          })
        ]
      }),
      renderMode === "audio" || offthreadVideoCacheSizeInBytes === null ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NumberSetting, {
        min: 0,
        max: 2000 * 1024 * 1024,
        step: 1024,
        name: "OffthreadVideo cache size",
        formatter: (w) => `${w} bytes`,
        onValueChanged: changeOffthreadVideoCacheSizeInBytes,
        value: offthreadVideoCacheSizeInBytes
      }),
      renderMode === "audio" ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "OffthreadVideo threads ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "offthreadVideoThreadsOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: offthreadVideoThreads !== null,
              onChange: toggleCustomOffthreadVideoThreads,
              name: "offthread-video-threads"
            })
          })
        ]
      }),
      renderMode === "audio" || offthreadVideoThreads === null ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NumberSetting, {
        min: 0,
        max: 16,
        step: 1,
        name: "OffthreadVideo threads",
        formatter: (w) => `${w}x`,
        onValueChanged: changeOffthreadVideoThreads,
        value: offthreadVideoThreads
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalHr, {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: label5,
            children: "Disable web security"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: disableWebSecurity,
              onChange: onDisableWebSecurityChanged,
              name: "disable-web-security"
            })
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: label5,
            children: "Ignore certificate errors"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: ignoreCertificateErrors,
              onChange: onIgnoreCertificatErrors,
              name: "ignore-certificate-errors"
            })
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Headless mode",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "headlessOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: headless,
              onChange: onHeadless,
              name: "headless"
            })
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Chrome Mode ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "chromeModeOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
              values: chromeModeOptions,
              selectedId: chromeModeOption,
              title: "Chrome mode"
            })
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "OpenGL render backend ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "glOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
              values: openGlOptions,
              selectedId: openGlOption,
              title: "OpenGl option"
            })
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Multi-process Chrome on Linux",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "enableMultiprocessOnLinuxOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: enableMultiProcessOnLinux,
              onChange: onEnableMultiProcessOnLinux,
              name: "enable-multi-process-on-linux"
            })
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Dark Mode",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "darkModeOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: darkMode,
              onChange: onDarkMode,
              name: "dark-mode"
            })
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: label5,
            children: "Custom User Agent"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: userAgent !== null,
              onChange: toggleCustomUserAgent,
              name: "custom-user-agent"
            })
          })
        ]
      }),
      userAgent === null ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: label5,
            children: "User Agent"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
                style: input,
                value: userAgent,
                onChange: onUserAgentChanged,
                status: "ok",
                rightAlign: true
              })
            })
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Create a reproduction ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "reproOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: repro,
              onChange: onReproToggle,
              name: "repro"
            })
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Beep when finished ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "beepOnFinishOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: beep,
              onChange: onPlayBeepSound,
              name: "beep-when-finished"
            })
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalHr, {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalEnvironmentVariables, {
        envVariables,
        setEnvVariables
      })
    ]
  });
};

// src/components/RenderModal/RenderModalAudio.tsx



// src/components/RenderModal/EnforceAudioTrackSetting.tsx


var EnforceAudioTrackSetting = ({ enforceAudioTrack, muted, setEnforceAudioTrack }) => {
  const onEnforceAudioTrackChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setEnforceAudioTrack(e.target.checked);
  }, [setEnforceAudioTrack]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: optionRow,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: label5,
        children: [
          "Enforce Audio Track",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 0.5
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
            id: "enforceAudioOption"
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: rightRow,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
          disabled: muted && !enforceAudioTrack,
          checked: enforceAudioTrack,
          onChange: onEnforceAudioTrackChanged,
          name: "enforce-audio-track"
        })
      })
    ]
  });
};

// src/components/RenderModal/human-readable-audio-codecs.ts
var humanReadableAudioCodec = (audioCodec) => {
  if (audioCodec === "aac") {
    return "AAC";
  }
  if (audioCodec === "mp3") {
    return "MP3";
  }
  if (audioCodec === "pcm-16") {
    return "Lossless";
  }
  if (audioCodec === "opus") {
    return "Opus";
  }
};

// src/components/RenderModal/MutedSetting.tsx


var MutedSetting = ({ muted, setMuted, enforceAudioTrack }) => {
  const onMutedChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setMuted(e.target.checked);
  }, [setMuted]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: optionRow,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: label5,
        children: [
          "Muted",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            x: 0.5
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
            id: "mutedOption"
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 0.25
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: rightRow,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
          checked: muted,
          disabled: enforceAudioTrack && !muted,
          onChange: onMutedChanged,
          name: "muted"
        })
      })
    ]
  });
};

// src/components/RenderModal/SeparateAudioOption.tsx



// src/helpers/use-file-existence.ts

var useFileExistence = (outName) => {
  const [exists, setExists] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const { previewServerState: state, subscribeToEvent } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx);
  const clientId = state.type === "connected" ? state.clientId : undefined;
  const currentOutName = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)("");
  currentOutName.current = outName;
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!clientId) {
      return;
    }
    subscribeToFileExistenceWatcher({
      file: outName,
      clientId
    }).then((_exists) => {
      if (currentOutName.current === outName) {
        setExists(_exists);
      }
    });
    return () => {
      unsubscribeFromFileExistenceWatcher({ file: outName, clientId });
    };
  }, [clientId, outName]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const listener = (event) => {
      if (event.type !== "watched-file-deleted") {
        return;
      }
      if (event.file !== currentOutName.current) {
        return;
      }
      if (currentOutName.current === outName) {
        setExists(false);
      }
    };
    const unsub = subscribeToEvent("watched-file-deleted", listener);
    return () => {
      unsub();
    };
  }, [outName, subscribeToEvent]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const listener = (event) => {
      if (event.type !== "watched-file-undeleted") {
        return;
      }
      if (event.file !== outName) {
        return;
      }
      if (currentOutName.current === outName) {
        setExists(true);
      }
    };
    const unsub = subscribeToEvent("watched-file-undeleted", listener);
    return () => {
      unsub();
    };
  }, [outName, subscribeToEvent]);
  return exists;
};

// src/components/RenderModal/RenderModalOutputName.tsx

var RenderModalOutputName = ({
  existence,
  inputStyle: inputStyle2,
  outName,
  onValueChange,
  validationMessage,
  label: labelText
}) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: optionRow,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Column, {
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
          style: label5,
          children: labelText
        })
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: rightRow,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
          children: [
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
              status: validationMessage ? "error" : existence ? "warning" : "ok",
              style: inputStyle2,
              type: "text",
              value: outName,
              onChange: onValueChange,
              rightAlign: true
            }),
            validationMessage ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
              children: [
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                  y: 1,
                  block: true
                }),
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ValidationMessage, {
                  align: "flex-end",
                  message: validationMessage,
                  type: "error"
                })
              ]
            }) : existence ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
              children: [
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                  y: 1,
                  block: true
                }),
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ValidationMessage, {
                  align: "flex-end",
                  message: "Will be overwritten",
                  type: "warning"
                })
              ]
            }) : null
          ]
        })
      })
    ]
  });
};

// src/components/RenderModal/SeparateAudioOption.tsx

var SeparateAudioOptionInput = ({ separateAudioTo, setSeparateAudioTo, audioCodec }) => {
  const existence = useFileExistence(separateAudioTo);
  const onValueChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setSeparateAudioTo(e.target.value);
  }, [setSeparateAudioTo]);
  const validationMessage = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const expectedExtension = _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.getExtensionFromAudioCodec(audioCodec);
    const actualExtension = separateAudioTo.split(".").pop();
    if (actualExtension !== expectedExtension) {
      return `Expected extension: .${expectedExtension}`;
    }
    return null;
  }, [audioCodec, separateAudioTo]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalOutputName, {
    existence,
    inputStyle: input,
    onValueChange,
    outName: separateAudioTo,
    label: "Separate audio to",
    validationMessage
  });
};
var SeparateAudioOption = ({ separateAudioTo, setSeparateAudioTo, audioCodec, outName }) => {
  const onSeparateAudioChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    if (e.target.checked) {
      const extension = _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.getExtensionFromAudioCodec(audioCodec);
      setSeparateAudioTo(`${getStringBeforeSuffix(outName)}.${extension}`);
    } else {
      setSeparateAudioTo(null);
    }
  }, [audioCodec, outName, setSeparateAudioTo]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Separate audio",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "separateAudioOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              disabled: false,
              checked: Boolean(separateAudioTo),
              onChange: onSeparateAudioChange,
              name: "separate-audio-to"
            })
          })
        ]
      }),
      separateAudioTo === null ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SeparateAudioOptionInput, {
        separateAudioTo,
        setSeparateAudioTo,
        audioCodec
      })
    ]
  });
};

// src/components/RenderModal/RenderModalAudio.tsx

var container56 = {
  flex: 1,
  overflowY: "auto"
};
var RenderModalAudio = ({
  muted,
  setMuted,
  renderMode,
  enforceAudioTrack,
  setEnforceAudioTrackState,
  setShouldHaveCustomTargetAudioBitrate,
  shouldHaveCustomTargetAudioBitrate,
  setCustomTargetAudioBitrateValue,
  customTargetAudioBitrate,
  audioCodec,
  codec,
  setAudioCodec,
  forSeamlessAacConcatenation,
  setForSeamlessAacConcatenation,
  separateAudioTo,
  setSeparateAudioTo,
  outName
}) => {
  const onShouldHaveTargetAudioBitrateChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setShouldHaveCustomTargetAudioBitrate(e.target.checked);
  }, [setShouldHaveCustomTargetAudioBitrate]);
  const onTargetAudioBitrateChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setCustomTargetAudioBitrateValue(e.target.value);
  }, [setCustomTargetAudioBitrateValue]);
  const onSeamlessAacConcatenationChanges = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setForSeamlessAacConcatenation(e.target.checked);
  }, [setForSeamlessAacConcatenation]);
  const audioCodecOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((currentCodec) => {
    return _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.supportedAudioCodecs[currentCodec].map((audioCodecOption) => {
      return {
        label: humanReadableAudioCodec(audioCodecOption),
        onClick: () => setAudioCodec(audioCodecOption),
        key: audioCodecOption,
        leftItem: codec === audioCodecOption ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        id: audioCodecOption,
        keyHint: null,
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: audioCodecOption
      };
    });
  }, [codec, setAudioCodec]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container56,
    className: VERTICAL_SCROLLBAR_CLASSNAME,
    children: [
      renderMode === "video" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MutedSetting, {
            enforceAudioTrack,
            muted,
            setMuted
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalHr, {})
        ]
      }) : null,
      renderMode === "video" && audioCodecOptions(codec).length >= 2 && !muted ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Audio Codec ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "audioCodecOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
              values: audioCodecOptions(codec),
              selectedId: audioCodec,
              title: "AudioCodec"
            })
          })
        ]
      }) : null,
      (renderMode === "video" || renderMode === "audio") && !muted && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(EnforceAudioTrackSetting, {
            muted,
            enforceAudioTrack,
            setEnforceAudioTrack: setEnforceAudioTrackState
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalHr, {})
        ]
      }),
      renderMode === "video" && !muted ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SeparateAudioOption, {
        separateAudioTo,
        setSeparateAudioTo,
        audioCodec,
        outName
      }) : null,
      audioCodec === "aac" && !muted ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "For seamless AAC concatenation",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "forSeamlessAacConcatenationOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              disabled: false,
              checked: forSeamlessAacConcatenation,
              onChange: onSeamlessAacConcatenationChanges,
              name: "enforce-audio-track"
            })
          })
        ]
      }) : null,
      renderMode === "still" || muted ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Custom audio bitrate",
              " ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "audioBitrateOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: shouldHaveCustomTargetAudioBitrate,
              onChange: onShouldHaveTargetAudioBitrateChanged,
              name: "custom-audio-bitrate"
            })
          })
        ]
      }),
      shouldHaveCustomTargetAudioBitrate && renderMode !== "still" && !muted ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: label5,
            children: "Target audio bitrate"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
                style: input,
                value: customTargetAudioBitrate,
                onChange: onTargetAudioBitrateChanged,
                status: "ok",
                rightAlign: true
              })
            })
          })
        ]
      }) : null
    ]
  });
};

// src/components/RenderModal/RenderModalBasic.tsx




// src/helpers/prores-labels.ts
var labelProResProfile = (profile) => {
  if (profile === "4444") {
    return "4444";
  }
  if (profile === "4444-xq") {
    return "4444 XQ (Best)";
  }
  if (profile === "hq") {
    return "HQ";
  }
  if (profile === "proxy") {
    return "Proxy (Worst)";
  }
  if (profile === "light") {
    return "Light";
  }
  if (profile === "standard") {
    return "Standard";
  }
  throw new TypeError(`Unknown ProRes profile: ${profile}`);
};

// src/components/RenderModal/FrameRangeSetting.tsx


// src/components/RenderModal/MultiRangeSlider.tsx


var container57 = {
  borderColor: "black",
  borderStyle: "solid",
  borderWidth: "2px",
  height: 39,
  width: 220,
  position: "relative",
  backgroundColor: INPUT_BACKGROUND,
  marginLeft: 8,
  marginRight: 8,
  borderRadius: 2
};
var sliderRange = {
  position: "absolute",
  top: 0,
  backgroundColor: BLUE,
  height: 35
};
var MultiRangeSlider = ({
  min,
  max,
  start,
  end,
  step,
  onLeftThumbDrag,
  onRightThumbDrag
}) => {
  const getPercent = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((value) => Math.round((value - min) / (max - min) * 100), [min, max]);
  const rangeStyle = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const minPercent = getPercent(start);
    const maxPercent = getPercent(end);
    return {
      ...sliderRange,
      left: `${minPercent}%`,
      width: `${maxPercent - minPercent}%`
    };
  }, [end, getPercent, start]);
  const onChangeLeft = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((event) => {
    const value = Math.min(Number(event.target.value), end - 1);
    onLeftThumbDrag(value);
  }, [end, onLeftThumbDrag]);
  const onChangeRight = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((event) => {
    const value = Math.max(Number(event.target.value), start + 1);
    onRightThumbDrag(value);
  }, [onRightThumbDrag, start]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container57,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("input", {
        type: "range",
        min,
        max,
        value: start,
        step,
        onChange: onChangeLeft,
        className: "__remotion_thumb"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("input", {
        type: "range",
        min,
        max,
        value: end,
        step,
        onChange: onChangeRight,
        className: "__remotion_thumb"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: rangeStyle
      })
    ]
  });
};

// src/components/RenderModal/FrameRangeSetting.tsx

var INPUT_WIDTH = 40;
var FrameRangeSetting = ({ startFrame, endFrame, setEndFrame, durationInFrames, setStartFrame }) => {
  const minStartFrame = 0;
  const maxEndFrame = durationInFrames - 1;
  const onStartFrameChangedDirectly = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newStartFrame) => {
    setStartFrame(newStartFrame);
  }, [setStartFrame]);
  const onEndFrameChangedDirectly = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newEndFrame) => {
    setEndFrame(newEndFrame);
  }, [setEndFrame]);
  const onStartFrameChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newVal) => {
    onStartFrameChangedDirectly(parseInt(newVal, 10));
  }, [onStartFrameChangedDirectly]);
  const onEndFrameChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newVal) => {
    onEndFrameChangedDirectly(parseInt(newVal, 10));
  }, [onEndFrameChangedDirectly]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: optionRow,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: label5,
        children: "Frame range"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: rightRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: { width: INPUT_WIDTH },
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InputDragger, {
              min: minStartFrame,
              max: endFrame - 1,
              name: "Start frame",
              value: startFrame,
              step: 1,
              onTextChange: onStartFrameChanged,
              onValueChange: onStartFrameChangedDirectly,
              status: "ok",
              rightAlign: true,
              style: { width: INPUT_WIDTH }
            })
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MultiRangeSlider, {
            min: minStartFrame,
            max: maxEndFrame,
            start: startFrame,
            end: endFrame,
            step: 1,
            onLeftThumbDrag: onStartFrameChangedDirectly,
            onRightThumbDrag: onEndFrameChangedDirectly
          }),
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: { width: INPUT_WIDTH },
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InputDragger, {
              min: startFrame + 1,
              max: maxEndFrame,
              name: "End frame",
              value: endFrame,
              step: 1,
              onTextChange: onEndFrameChanged,
              onValueChange: onEndFrameChangedDirectly,
              status: "ok",
              rightAlign: true,
              style: { width: INPUT_WIDTH }
            })
          })
        ]
      })
    ]
  });
};

// src/components/RenderModal/human-readable-codec.ts
var humanReadableCodec = (codec) => {
  if (codec === "aac") {
    return "AAC";
  }
  if (codec === "mp3") {
    return "MP3";
  }
  if (codec === "gif") {
    return "GIF";
  }
  if (codec === "h264") {
    return "H.264";
  }
  if (codec === "h264-mkv") {
    return "H.264 (Matroska)";
  }
  if (codec === "h264-ts") {
    return "H.264 (Transport Stream)";
  }
  if (codec === "h265") {
    return "H.265";
  }
  if (codec === "prores") {
    return "ProRes";
  }
  if (codec === "vp8") {
    return "VP8";
  }
  if (codec === "vp9") {
    return "VP9";
  }
  if (codec === "wav") {
    return "Waveform";
  }
  throw new TypeError(`Got unexpected codec "${codec}"`);
};

// src/components/RenderModal/human-readable-loglevel.ts
var humanReadableLogLevel = (logLevel) => {
  if (logLevel === "trace") {
    return "Trace";
  }
  if (logLevel === "verbose") {
    return "Verbose";
  }
  if (logLevel === "info") {
    return "Info";
  }
  if (logLevel === "warn") {
    return "Warn";
  }
  if (logLevel === "error") {
    return "Error";
  }
  throw new TypeError(`Got unexpected log level "${logLevel}"`);
};

// src/components/RenderModal/RenderModalBasic.tsx

var container58 = {
  flex: 1
};
var RenderModalBasic = ({
  renderMode,
  imageFormatOptions,
  outName,
  codec,
  setVideoCodec: setCodec,
  proResProfile,
  setProResProfile,
  frame: frame2,
  setFrame,
  resolvedComposition,
  setOutName,
  setEndFrame,
  endFrame,
  setStartFrame,
  startFrame,
  validationMessage,
  setVerboseLogging,
  logLevel
}) => {
  const existence = useFileExistence(outName);
  const videoCodecOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.validCodecs.filter((c) => {
      return _remotion_renderer_pure__WEBPACK_IMPORTED_MODULE_15__/* .NoReactAPIs */ .c.isAudioCodec(c) === (renderMode === "audio");
    }).map((codecOption) => {
      return {
        label: humanReadableCodec(codecOption),
        onClick: () => setCodec(codecOption),
        key: codecOption,
        leftItem: codec === codecOption ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        id: codecOption,
        keyHint: null,
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: codecOption
      };
    });
  }, [renderMode, setCodec, codec]);
  const proResProfileOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.proResProfileOptions.map((option) => {
      return {
        label: labelProResProfile(option),
        onClick: () => setProResProfile(option),
        key: option,
        selected: proResProfile === option,
        type: "item",
        id: option,
        keyHint: null,
        leftItem: null,
        quickSwitcherLabel: null,
        subMenu: null,
        value: option
      };
    });
  }, [proResProfile, setProResProfile]);
  const onFrameSetDirectly = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newFrame) => {
    setFrame(newFrame);
  }, [setFrame]);
  const onFrameChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setFrame((q) => {
      const newFrame = parseFloat(e);
      if (Number.isNaN(newFrame)) {
        return q;
      }
      return newFrame;
    });
  }, [setFrame]);
  const onValueChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setOutName(e.target.value);
  }, [setOutName]);
  const logLevelOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return ["trace", "verbose", "info", "warn", "error"].map((level) => {
      return {
        label: humanReadableLogLevel(level),
        onClick: () => setVerboseLogging(level),
        leftItem: logLevel === level ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        id: level,
        keyHint: null,
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: level
      };
    });
  }, [logLevel, setVerboseLogging]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container58,
    children: [
      renderMode === "still" || renderMode === "sequence" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: label5,
            children: "Format"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SegmentedControl, {
              items: imageFormatOptions,
              needsWrapping: true
            })
          })
        ]
      }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Codec",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "videoCodecOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
              values: videoCodecOptions,
              selectedId: codec,
              title: "Codec"
            })
          })
        ]
      }),
      renderMode === "still" && resolvedComposition.durationInFrames > 1 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: label5,
            children: "Frame"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RightAlignInput, {
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InputDragger, {
                value: frame2,
                onTextChange: onFrameChanged,
                placeholder: `0-${resolvedComposition.durationInFrames - 1}`,
                onValueChange: onFrameSetDirectly,
                name: "frame",
                step: 1,
                min: 0,
                status: "ok",
                max: resolvedComposition.durationInFrames - 1,
                rightAlign: true
              })
            })
          })
        ]
      }) : null,
      renderMode === "video" && codec === "prores" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: label5,
            children: "ProRes profile"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
              title: "proResProfile",
              selectedId: proResProfile,
              values: proResProfileOptions
            })
          })
        ]
      }) : null,
      renderMode === "still" ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FrameRangeSetting, {
        durationInFrames: resolvedComposition.durationInFrames,
        endFrame,
        setEndFrame,
        setStartFrame,
        startFrame
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalOutputName, {
        existence,
        inputStyle: input,
        outName,
        onValueChange,
        validationMessage,
        label: renderMode === "sequence" ? "Folder name" : "Output name"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Log Level ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "logLevelOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
              values: logLevelOptions,
              selectedId: logLevel,
              title: "Log Level"
            })
          })
        ]
      })
    ]
  });
};

// src/components/RenderModal/RenderModalGif.tsx


// src/components/RenderModal/NumberOfLoopsSetting.tsx


var min = 0;
var NumberOfLoopsSetting = ({ numberOfGifLoops, setNumberOfGifLoops }) => {
  const onNumberOfGifLoopsChangedDirectly = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newConcurrency) => {
    setNumberOfGifLoops(newConcurrency);
  }, [setNumberOfGifLoops]);
  const onNumberOfGifLoopsChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setNumberOfGifLoops((q) => {
      const newConcurrency = parseInt(e, 10);
      if (Number.isNaN(newConcurrency)) {
        return q;
      }
      const newConcurrencyClamped = Math.max(newConcurrency, min);
      return newConcurrencyClamped;
    });
  }, [setNumberOfGifLoops]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: optionRow,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: label5,
        children: "Number of loops"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: rightRow,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RightAlignInput, {
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InputDragger, {
            value: numberOfGifLoops,
            onTextChange: onNumberOfGifLoopsChanged,
            placeholder: `${min}-`,
            onValueChange: onNumberOfGifLoopsChangedDirectly,
            name: "number-of-gif-loops",
            step: 1,
            min,
            status: "ok",
            rightAlign: true
          })
        })
      })
    ]
  });
};

// src/components/RenderModal/RenderModalGif.tsx

var container59 = {
  flex: 1
};
var RenderModalGif = ({
  everyNthFrame,
  limitNumberOfGifLoops,
  numberOfGifLoopsSetting,
  setEveryNthFrameSetting,
  setLimitNumberOfGifLoops,
  setNumberOfGifLoopsSetting
}) => {
  const onShouldLimitNumberOfGifLoops = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setLimitNumberOfGifLoops(e.target.checked);
  }, [setLimitNumberOfGifLoops]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container59,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NumberSetting, {
        name: "Every nth frame",
        min: 1,
        onValueChanged: setEveryNthFrameSetting,
        value: everyNthFrame,
        step: 1
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Limit GIF loops ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "numberOfGifLoopsOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: limitNumberOfGifLoops,
              onChange: onShouldLimitNumberOfGifLoops,
              name: "limitNumberOfGifLoops"
            })
          })
        ]
      }),
      limitNumberOfGifLoops ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NumberOfLoopsSetting, {
        numberOfGifLoops: numberOfGifLoopsSetting,
        setNumberOfGifLoops: setNumberOfGifLoopsSetting
      }) : null
    ]
  });
};

// src/components/RenderModal/RenderModalPicture.tsx



// src/components/RenderModal/JpegQualitySetting.tsx

var MIN_JPEG_QUALITY = 1;
var MAX_JPEG_QUALITY = 100;
var JpegQualitySetting = ({ jpegQuality, setJpegQuality }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NumberSetting, {
    min: MIN_JPEG_QUALITY,
    max: MAX_JPEG_QUALITY,
    step: 1,
    name: "JPEG Quality",
    onValueChanged: setJpegQuality,
    value: jpegQuality,
    hint: "jpegQualityOption"
  });
};

// src/components/RenderModal/ScaleSetting.tsx


var MIN_SCALE = 0.1;
var MAX_SCALE = 10;
var outputDimensionsStyle = {
  fontSize: 13,
  color: LIGHT_TEXT,
  fontFamily: "sans-serif",
  paddingRight: 16,
  textAlign: "right",
  marginBottom: 14,
  marginTop: -10
};
var ScaleSetting = ({ scale, setScale, compositionWidth, compositionHeight }) => {
  const outputDimensions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const outputWidth = Math.round(compositionWidth * scale);
    const outputHeight = Math.round(compositionHeight * scale);
    return `${outputWidth}×${outputHeight}`;
  }, [compositionWidth, compositionHeight, scale]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NumberSetting, {
        min: MIN_SCALE,
        max: MAX_SCALE,
        step: 0.1,
        name: "Scale",
        formatter: (w) => {
          if (typeof w === "number") {
            return `${w.toFixed(1)}x`;
          }
          return `${w}x`;
        },
        onValueChanged: setScale,
        value: scale,
        hint: "scaleOption"
      }),
      scale !== 1 && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: outputDimensionsStyle,
        children: [
          "Output resolution: ",
          outputDimensions
        ]
      })
    ]
  });
};

// src/components/RenderModal/RenderModalPicture.tsx

var qualityControlModes = ["crf", "bitrate"];
var container60 = {
  flex: 1,
  overflowY: "auto"
};
var RenderModalPicture = ({
  renderMode,
  scale,
  setScale,
  pixelFormat,
  imageFormatOptions,
  setQualityControl,
  qualityControlType,
  videoImageFormat,
  setJpegQuality,
  jpegQuality,
  maxCrf,
  minCrf,
  setCrf,
  shouldDisplayQualityControlPicker,
  setCustomTargetVideoBitrateValue,
  crf,
  customTargetVideoBitrate,
  stillImageFormat,
  colorSpace,
  setColorSpace,
  pixelFormatOptions,
  encodingBufferSize,
  encodingMaxRate,
  setEncodingBufferSize,
  setEncodingMaxRate,
  compositionWidth,
  compositionHeight
}) => {
  const colorSpaceOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.validColorSpaces.map((option) => {
      return {
        label: option,
        onClick: () => setColorSpace(option),
        key: option,
        id: option,
        keyHint: null,
        leftItem: colorSpace === option ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: option
      };
    });
  }, [colorSpace, setColorSpace]);
  const qualityControlOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return qualityControlModes.map((option) => {
      return {
        label: option === "crf" ? "CRF" : "Bitrate",
        onClick: () => setQualityControl(option),
        key: option,
        selected: qualityControlType === option
      };
    });
  }, [qualityControlType, setQualityControl]);
  const onTargetVideoBitrateChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setCustomTargetVideoBitrateValue(e.target.value);
  }, [setCustomTargetVideoBitrateValue]);
  const onEncodingBufferSizeToggled = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setEncodingBufferSize(e.target.checked ? "10000k" : null);
  }, [setEncodingBufferSize]);
  const onEncodingMaxRateToggled = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setEncodingMaxRate(e.target.checked ? "5000k" : null);
  }, [setEncodingMaxRate]);
  const onEncodingBufferSizeChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setEncodingBufferSize(e.target.value);
  }, [setEncodingBufferSize]);
  const onEncodingMaxRateChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setEncodingMaxRate(e.target.value);
  }, [setEncodingMaxRate]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container60,
    className: VERTICAL_SCROLLBAR_CLASSNAME,
    children: [
      renderMode === "video" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: label5,
            children: "Image Format"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SegmentedControl, {
              items: imageFormatOptions,
              needsWrapping: false
            })
          })
        ]
      }) : null,
      renderMode === "video" && videoImageFormat === "jpeg" && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(JpegQualitySetting, {
        jpegQuality,
        setJpegQuality
      }),
      renderMode === "still" && stillImageFormat === "jpeg" && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(JpegQualitySetting, {
        jpegQuality,
        setJpegQuality
      }),
      renderMode === "video" && qualityControlType !== null ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalHr, {}) : null,
      shouldDisplayQualityControlPicker && renderMode === "video" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: label5,
            children: "Quality control"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SegmentedControl, {
              items: qualityControlOptions,
              needsWrapping: true
            })
          })
        ]
      }) : null,
      qualityControlType === "crf" && renderMode !== "still" && renderMode !== "sequence" && crf !== null ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CrfSetting, {
        crf,
        min: minCrf,
        max: maxCrf,
        setCrf,
        option: "crfOption"
      }) : null,
      qualityControlType === "bitrate" && renderMode === "video" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Target video bitrate",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "videoBitrateOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
                style: input,
                value: customTargetVideoBitrate,
                onChange: onTargetVideoBitrateChanged,
                status: "ok",
                rightAlign: true
              })
            })
          })
        ]
      }) : null,
      renderMode === "video" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: optionRow,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                style: label5,
                children: [
                  "Custom FFmpeg -bufsize",
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                    x: 0.5
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                    id: "encodingBufferSizeOption"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: rightRow,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
                  checked: encodingBufferSize !== null,
                  onChange: onEncodingBufferSizeToggled,
                  name: "encoding-buffer-size"
                })
              })
            ]
          }),
          encodingBufferSize === null ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: optionRow,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: label5,
                children: "-bufsize value"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: rightRow,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
                    style: input,
                    value: encodingBufferSize,
                    onChange: onEncodingBufferSizeChanged,
                    status: "ok",
                    rightAlign: true
                  })
                })
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: optionRow,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                style: label5,
                children: [
                  "Custom FFmpeg -maxrate",
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                    x: 0.5
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                    id: "encodingMaxRateOption"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: rightRow,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
                  checked: encodingMaxRate !== null,
                  onChange: onEncodingMaxRateToggled,
                  name: "encoding-max-rate"
                })
              })
            ]
          }),
          encodingMaxRate === null ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: optionRow,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: label5,
                children: "-maxrate value"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: rightRow,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
                    style: input,
                    value: encodingMaxRate,
                    onChange: onEncodingMaxRateChanged,
                    status: "ok",
                    rightAlign: true
                  })
                })
              })
            ]
          })
        ]
      }) : null,
      renderMode === "video" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalHr, {}) : null,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ScaleSetting, {
        scale,
        setScale,
        compositionWidth,
        compositionHeight
      }),
      renderMode === "video" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalHr, {}) : null,
      renderMode === "video" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: label5,
            children: "Pixel format"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
              values: pixelFormatOptions,
              selectedId: pixelFormat,
              title: "Pixel Format"
            })
          })
        ]
      }) : null,
      renderMode === "video" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Color space",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "colorSpaceOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
              values: colorSpaceOptions,
              selectedId: colorSpace,
              title: "Color Space"
            })
          })
        ]
      }) : null
    ]
  });
};

// src/components/RenderModal/ServerRenderModal.tsx

var initialState2 = { type: "idle" };
var reducer2 = (state, action) => {
  if (action.type === "start") {
    return {
      type: "load"
    };
  }
  if (action.type === "fail") {
    return {
      type: "error"
    };
  }
  if (action.type === "succeed") {
    return {
      type: "success"
    };
  }
  return state;
};
var RenderModal = ({
  initialFrame,
  initialVideoImageFormat,
  initialStillImageFormat,
  initialJpegQuality,
  initialScale,
  initialLogLevel,
  initialConcurrency,
  maxConcurrency,
  minConcurrency,
  initialMuted,
  initialEnforceAudioTrack,
  initialProResProfile,
  initialx264Preset,
  initialPixelFormat,
  initialVideoBitrate,
  initialAudioBitrate,
  initialEveryNthFrame,
  initialNumberOfGifLoops,
  initialDelayRenderTimeout,
  initialOffthreadVideoCacheSizeInBytes,
  initialEnvVariables,
  initialDisableWebSecurity,
  initialGl,
  initialHeadless,
  initialIgnoreCertificateErrors,
  initialEncodingBufferSize,
  initialEncodingMaxRate,
  initialOffthreadVideoThreads,
  initialMediaCacheSizeInBytes,
  initialDarkMode,
  initialUserAgent,
  defaultProps,
  inFrameMark,
  outFrameMark,
  initialColorSpace,
  initialMultiProcessOnLinux,
  defaultConfigurationAudioCodec,
  defaultConfigurationVideoCodec,
  initialBeep,
  initialRepro,
  initialForSeamlessAacConcatenation,
  renderTypeOfLastRender,
  initialHardwareAcceleration,
  defaultMetadata,
  initialChromeMode,
  renderDefaults
}) => {
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ResolvedCompositionContext);
  if (!context) {
    throw new Error("Should not be able to render without resolving comp first");
  }
  const {
    resolved: { result: resolvedComposition },
    unresolved: unresolvedComposition
  } = context;
  const isMounted = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(true);
  const [isVideo] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => {
    return typeof resolvedComposition.durationInFrames === "undefined" ? true : resolvedComposition.durationInFrames > 1;
  });
  const [
    {
      initialAudioCodec,
      initialRenderType,
      initialVideoCodec,
      initialVideoCodecForAudioTab,
      initialVideoCodecForVideoTab
    }
  ] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => {
    return getDefaultCodecs({
      defaultConfigurationVideoCodec,
      compositionDefaultVideoCodec: resolvedComposition.defaultCodec,
      defaultConfigurationAudioCodec,
      renderType: renderTypeOfLastRender ?? (isVideo ? "video" : "still")
    });
  });
  const [state, dispatch] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useReducer)(reducer2, initialState2);
  const [unclampedFrame, setFrame] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialFrame);
  const [saving, setSaving] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const [stillImageFormat, setStillImageFormat] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialStillImageFormat);
  const [videoImageFormat, setVideoImageFormat] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialVideoImageFormat ?? resolvedComposition.defaultVideoImageFormat ?? renderDefaults.videoImageFormat);
  const [sequenceImageFormat, setSequenceImageFormat] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialStillImageFormat === "jpeg" ? "jpeg" : "png");
  const [concurrency, setConcurrency] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialConcurrency);
  const [videoCodecForVideoTab, setVideoCodecForVideoTab] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialVideoCodecForVideoTab);
  const [userSelectedAudioCodec, setUserSelectedAudioCodec] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialAudioCodec);
  const [separateAudioTo, setSeparateAudioTo] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const [envVariables, setEnvVariables] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => envVariablesObjectToArray(initialEnvVariables).filter(([key5]) => key5 !== "NODE_ENV"));
  const [initialOutName] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => {
    return (0,_remotion_studio_shared__WEBPACK_IMPORTED_MODULE_6__/* .getDefaultOutLocation */ .LE)({
      compositionName: resolvedComposition.id,
      defaultExtension: initialRenderType === "still" ? initialStillImageFormat : isVideo ? _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.getFileExtensionFromCodec(initialVideoCodec, initialAudioCodec) : initialStillImageFormat,
      type: "asset",
      compositionDefaultOutName: resolvedComposition.defaultOutName,
      outputLocation: renderDefaults.outputLocation
    });
  });
  const [videoCodecForAudioTab, setVideoCodecForAudioTab] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialVideoCodecForAudioTab);
  const [mutedState, setMuted] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialMuted);
  const [repro, setRepro] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialRepro);
  const [enforceAudioTrackState, setEnforceAudioTrackState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialEnforceAudioTrack);
  const [forSeamlessAacConcatenation, setForSeamlessAacConcatenation] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialForSeamlessAacConcatenation);
  const [renderMode, setRenderModeState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialRenderType);
  const [jpegQuality, setJpegQuality] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialJpegQuality);
  const [scale, setScale] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialScale);
  const [logLevel, setLogLevel] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialLogLevel);
  const [disallowParallelEncoding, setDisallowParallelEncoding] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const [disableWebSecurity, setDisableWebSecurity] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialDisableWebSecurity);
  const [headless, setHeadless] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialHeadless);
  const [beepOnFinish, setBeepOnFinish] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialBeep);
  const [ignoreCertificateErrors, setIgnoreCertificateErrors] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialIgnoreCertificateErrors);
  const [multiProcessOnLinux, setChromiumMultiProcessOnLinux] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialMultiProcessOnLinux);
  const [darkMode, setDarkMode] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialDarkMode);
  const [openGlOption, setOpenGlOption] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialGl ?? "default");
  const [colorSpace, setColorSpace] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialColorSpace);
  const [userAgent, setUserAgent] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialUserAgent === null ? null : initialUserAgent.trim() === "" ? null : initialUserAgent);
  const chromiumOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      headless,
      disableWebSecurity,
      ignoreCertificateErrors,
      gl: openGlOption === "default" ? null : openGlOption,
      userAgent: userAgent === null ? null : userAgent.trim() === "" ? null : userAgent,
      enableMultiProcessOnLinux: multiProcessOnLinux,
      darkMode
    };
  }, [
    headless,
    disableWebSecurity,
    ignoreCertificateErrors,
    openGlOption,
    userAgent,
    multiProcessOnLinux,
    darkMode
  ]);
  const [outName, setOutName] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialOutName);
  const [endFrameOrNull, setEndFrame] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => outFrameMark ?? null);
  const [startFrameOrNull, setStartFrame] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => inFrameMark ?? null);
  const [proResProfileSetting, setProResProfile] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialProResProfile ?? resolvedComposition.defaultProResProfile ?? "hq");
  const [x264PresetSetting, setx264Preset] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialx264Preset);
  const [hardwareAcceleration, setHardwareAcceleration] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialHardwareAcceleration);
  const [userPreferredPixelFormat, setPixelFormat] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialPixelFormat ?? resolvedComposition.defaultPixelFormat ?? renderDefaults.pixelFormat);
  const [preferredQualityControlType, setQualityControl] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialVideoBitrate === null ? "crf" : "bitrate");
  const [
    shouldHaveCustomTargetAudioBitrate,
    setShouldHaveCustomTargetAudioBitrate
  ] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialAudioBitrate !== null);
  const [customTargetAudioBitrate, setCustomTargetAudioBitrateValue] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialAudioBitrate ?? "320K");
  const [customTargetVideoBitrate, setCustomTargetVideoBitrateValue] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialVideoBitrate ?? "1M");
  const [encodingMaxRate, setEncodingMaxRate] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialEncodingMaxRate ?? null);
  const [encodingBufferSize, setEncodingBufferSize] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialEncodingBufferSize ?? null);
  const [limitNumberOfGifLoops, setLimitNumberOfGifLoops] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialNumberOfGifLoops !== null);
  const [numberOfGifLoopsSetting, setNumberOfGifLoopsSetting] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialNumberOfGifLoops ?? 0);
  const [delayRenderTimeout, setDelayRenderTimeout] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialDelayRenderTimeout);
  const [chromeMode, setChromeMode] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialChromeMode);
  const [offthreadVideoCacheSizeInBytes, setOffthreadVideoCacheSizeInBytes] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialOffthreadVideoCacheSizeInBytes);
  const [mediaCacheSizeInBytes, setMediaCacheSizeInBytes] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialMediaCacheSizeInBytes);
  const [offthreadVideoThreads, setOffthreadVideoThreads] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialOffthreadVideoThreads);
  const codec = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (renderMode === "audio") {
      return videoCodecForAudioTab;
    }
    return videoCodecForVideoTab;
  }, [videoCodecForAudioTab, renderMode, videoCodecForVideoTab]);
  const numberOfGifLoops = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (codec === "gif" && limitNumberOfGifLoops) {
      return numberOfGifLoopsSetting;
    }
    return null;
  }, [codec, limitNumberOfGifLoops, numberOfGifLoopsSetting]);
  const audioBitrate = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (shouldHaveCustomTargetAudioBitrate) {
      return customTargetAudioBitrate;
    }
    return null;
  }, [customTargetAudioBitrate, shouldHaveCustomTargetAudioBitrate]);
  const supportsCrf = _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.codecSupportsCrf(codec);
  const supportsVideoBitrate = _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.codecSupportsVideoBitrate(codec);
  const supportsBothQualityControls = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return supportsCrf && supportsVideoBitrate && hardwareAcceleration !== "if-possible" && hardwareAcceleration !== "required";
  }, [hardwareAcceleration, supportsCrf, supportsVideoBitrate]);
  const qualityControlType = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (hardwareAcceleration === "if-possible" || hardwareAcceleration === "required") {
      if (supportsVideoBitrate) {
        return "bitrate";
      }
      return null;
    }
    if (supportsBothQualityControls) {
      return preferredQualityControlType;
    }
    if (supportsCrf) {
      return "crf";
    }
    if (supportsVideoBitrate) {
      return "bitrate";
    }
    return null;
  }, [
    hardwareAcceleration,
    preferredQualityControlType,
    supportsBothQualityControls,
    supportsCrf,
    supportsVideoBitrate
  ]);
  const videoBitrate = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (qualityControlType === "bitrate") {
      return customTargetVideoBitrate;
    }
    return null;
  }, [customTargetVideoBitrate, qualityControlType]);
  const { crf, maxCrf, minCrf, setCrf } = useCrfState(codec);
  const dispatchIfMounted = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((payload) => {
    if (isMounted.current === false)
      return;
    dispatch(payload);
  }, []);
  const muted = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (renderMode === "video") {
      return mutedState;
    }
    return false;
  }, [mutedState, renderMode]);
  const enforceAudioTrack = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (renderMode === "video") {
      return enforceAudioTrackState;
    }
    if (renderMode === "audio") {
      return enforceAudioTrackState;
    }
    return false;
  }, [enforceAudioTrackState, renderMode]);
  const proResProfile = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (renderMode === "video" && codec === "prores") {
      return proResProfileSetting;
    }
    return null;
  }, [codec, proResProfileSetting, renderMode]);
  const x264Preset = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (renderMode === "video" && codec === "h264") {
      return x264PresetSetting;
    }
    return null;
  }, [codec, x264PresetSetting, renderMode]);
  const [inputProps, setInputProps] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => defaultProps);
  const [metadata] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => defaultMetadata);
  const endFrame = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (endFrameOrNull === null) {
      return resolvedComposition.durationInFrames - 1;
    }
    return Math.max(0, Math.min(resolvedComposition.durationInFrames - 1, endFrameOrNull));
  }, [resolvedComposition.durationInFrames, endFrameOrNull]);
  const startFrame = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (startFrameOrNull === null) {
      return 0;
    }
    return Math.max(0, Math.min(endFrame - 1, startFrameOrNull));
  }, [endFrame, startFrameOrNull]);
  const frame2 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const parsed = Math.floor(unclampedFrame);
    return Math.max(0, Math.min(resolvedComposition.durationInFrames - 1, parsed));
  }, [resolvedComposition.durationInFrames, unclampedFrame]);
  const deriveFinalAudioCodec = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((passedVideoCodec, passedAudioCodec) => {
    if (passedAudioCodec !== null && _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.supportedAudioCodecs[passedVideoCodec].includes(passedAudioCodec)) {
      return passedAudioCodec;
    }
    return _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.defaultAudioCodecs[passedVideoCodec].compressed;
  }, []);
  const setDefaultOutName = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((options) => {
    if (options.type === "still") {
      setOutName((prev) => {
        const newFileName = getStringBeforeSuffix(prev) + "." + options.imageFormat;
        return newFileName;
      });
    } else if (options.type === "sequence") {
      setOutName((prev) => {
        const folderName = getStringBeforeSuffix(prev);
        return folderName;
      });
    } else {
      setOutName((prev) => {
        const codecSuffix = _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.getFileExtensionFromCodec(options.codec, deriveFinalAudioCodec(options.codec, options.audioCodec));
        const newFileName = getStringBeforeSuffix(prev) + "." + codecSuffix;
        return newFileName;
      });
    }
  }, [deriveFinalAudioCodec]);
  const setAudioCodec = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newAudioCodec) => {
    setUserSelectedAudioCodec(newAudioCodec);
    setDefaultOutName({
      type: "render",
      codec: videoCodecForVideoTab,
      audioCodec: newAudioCodec
    });
    setSeparateAudioTo((prev) => {
      if (prev === null) {
        return null;
      }
      const newExtension = _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.getExtensionFromAudioCodec(newAudioCodec);
      const newFileName = getStringBeforeSuffix(prev) + "." + newExtension;
      return newFileName;
    });
  }, [setDefaultOutName, videoCodecForVideoTab]);
  const setCodec = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newCodec) => {
    if (renderMode === "audio") {
      setVideoCodecForAudioTab(newCodec);
    } else {
      setVideoCodecForVideoTab(newCodec);
    }
    setDefaultOutName({
      type: "render",
      codec: newCodec,
      audioCodec: deriveFinalAudioCodec(newCodec, userSelectedAudioCodec)
    });
  }, [
    userSelectedAudioCodec,
    deriveFinalAudioCodec,
    renderMode,
    setDefaultOutName
  ]);
  const setStillFormat = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((format) => {
    setStillImageFormat(format);
    setDefaultOutName({ type: "still", imageFormat: format });
  }, [setDefaultOutName]);
  const { setSidebarCollapsedState } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SidebarContext);
  const onClickStill = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSidebarCollapsedState({ left: null, right: "expanded" });
    persistSelectedOptionsSidebarPanel2("renders");
    optionsSidebarTabs.current?.selectRendersPanel();
    dispatchIfMounted({ type: "start" });
    addStillRenderJob({
      compositionId: resolvedComposition.id,
      outName,
      imageFormat: stillImageFormat,
      jpegQuality,
      frame: frame2,
      scale,
      logLevel,
      chromiumOptions,
      delayRenderTimeout,
      envVariables: envVariablesArrayToObject(envVariables),
      inputProps,
      offthreadVideoCacheSizeInBytes,
      multiProcessOnLinux,
      beepOnFinish,
      metadata,
      chromeMode,
      offthreadVideoThreads,
      mediaCacheSizeInBytes
    }).then(() => {
      dispatchIfMounted({ type: "succeed" });
      setSelectedModal(null);
    }).catch(() => {
      dispatchIfMounted({ type: "fail" });
    });
  }, [
    setSidebarCollapsedState,
    dispatchIfMounted,
    resolvedComposition.id,
    outName,
    stillImageFormat,
    jpegQuality,
    frame2,
    scale,
    logLevel,
    chromiumOptions,
    delayRenderTimeout,
    envVariables,
    inputProps,
    offthreadVideoCacheSizeInBytes,
    multiProcessOnLinux,
    beepOnFinish,
    setSelectedModal,
    metadata,
    chromeMode,
    offthreadVideoThreads,
    mediaCacheSizeInBytes
  ]);
  const [everyNthFrameSetting, setEveryNthFrameSetting] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialEveryNthFrame);
  const everyNthFrame = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (codec === "gif") {
      return everyNthFrameSetting;
    }
    return 1;
  }, [codec, everyNthFrameSetting]);
  const audioCodec = deriveFinalAudioCodec(codec, userSelectedAudioCodec);
  const availablePixelFormats = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return _remotion_renderer_client__WEBPACK_IMPORTED_MODULE_14__/* .BrowserSafeApis */ .B.validPixelFormatsForCodec(codec);
  }, [codec]);
  const pixelFormat = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (availablePixelFormats.includes(userPreferredPixelFormat)) {
      return userPreferredPixelFormat;
    }
    return availablePixelFormats[0];
  }, [availablePixelFormats, userPreferredPixelFormat]);
  const onClickVideo = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSidebarCollapsedState({ left: null, right: "expanded" });
    persistSelectedOptionsSidebarPanel2("renders");
    optionsSidebarTabs.current?.selectRendersPanel();
    dispatchIfMounted({ type: "start" });
    addVideoRenderJob({
      compositionId: resolvedComposition.id,
      outName,
      imageFormat: videoImageFormat,
      jpegQuality: stillImageFormat === "jpeg" ? jpegQuality : null,
      scale,
      logLevel,
      codec,
      concurrency,
      crf: qualityControlType === "crf" && hardwareAcceleration !== "if-possible" && hardwareAcceleration !== "required" ? crf : null,
      endFrame,
      startFrame,
      muted,
      enforceAudioTrack,
      proResProfile,
      x264Preset,
      pixelFormat,
      audioBitrate,
      videoBitrate,
      everyNthFrame,
      numberOfGifLoops,
      delayRenderTimeout,
      audioCodec,
      disallowParallelEncoding,
      chromiumOptions,
      envVariables: envVariablesArrayToObject(envVariables),
      inputProps,
      offthreadVideoCacheSizeInBytes,
      colorSpace,
      multiProcessOnLinux,
      encodingBufferSize,
      encodingMaxRate,
      beepOnFinish,
      repro,
      forSeamlessAacConcatenation,
      separateAudioTo,
      metadata,
      hardwareAcceleration,
      chromeMode,
      offthreadVideoThreads,
      mediaCacheSizeInBytes
    }).then(() => {
      dispatchIfMounted({ type: "succeed" });
      setSelectedModal(null);
    }).catch(() => {
      dispatchIfMounted({ type: "fail" });
    });
  }, [
    setSidebarCollapsedState,
    dispatchIfMounted,
    resolvedComposition.id,
    outName,
    videoImageFormat,
    stillImageFormat,
    jpegQuality,
    scale,
    logLevel,
    codec,
    concurrency,
    qualityControlType,
    crf,
    endFrame,
    startFrame,
    muted,
    enforceAudioTrack,
    proResProfile,
    x264Preset,
    pixelFormat,
    audioBitrate,
    videoBitrate,
    everyNthFrame,
    numberOfGifLoops,
    delayRenderTimeout,
    audioCodec,
    disallowParallelEncoding,
    chromiumOptions,
    envVariables,
    inputProps,
    offthreadVideoCacheSizeInBytes,
    colorSpace,
    multiProcessOnLinux,
    encodingBufferSize,
    encodingMaxRate,
    beepOnFinish,
    repro,
    forSeamlessAacConcatenation,
    separateAudioTo,
    setSelectedModal,
    metadata,
    hardwareAcceleration,
    chromeMode,
    offthreadVideoThreads,
    mediaCacheSizeInBytes
  ]);
  const onClickSequence = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setSidebarCollapsedState({ left: null, right: "expanded" });
    persistSelectedOptionsSidebarPanel2("renders");
    optionsSidebarTabs.current?.selectRendersPanel();
    dispatchIfMounted({ type: "start" });
    addSequenceRenderJob({
      compositionId: resolvedComposition.id,
      outName,
      imageFormat: sequenceImageFormat,
      scale,
      logLevel,
      concurrency,
      endFrame,
      jpegQuality,
      startFrame,
      delayRenderTimeout,
      chromiumOptions,
      envVariables: envVariablesArrayToObject(envVariables),
      inputProps,
      offthreadVideoCacheSizeInBytes,
      disallowParallelEncoding,
      multiProcessOnLinux,
      beepOnFinish,
      repro,
      metadata,
      chromeMode,
      offthreadVideoThreads,
      mediaCacheSizeInBytes
    }).then(() => {
      dispatchIfMounted({ type: "succeed" });
      setSelectedModal(null);
    }).catch(() => {
      dispatchIfMounted({ type: "fail" });
    });
  }, [
    setSidebarCollapsedState,
    dispatchIfMounted,
    resolvedComposition.id,
    outName,
    sequenceImageFormat,
    scale,
    logLevel,
    concurrency,
    endFrame,
    jpegQuality,
    startFrame,
    delayRenderTimeout,
    chromiumOptions,
    envVariables,
    inputProps,
    offthreadVideoCacheSizeInBytes,
    disallowParallelEncoding,
    multiProcessOnLinux,
    beepOnFinish,
    repro,
    setSelectedModal,
    metadata,
    chromeMode,
    offthreadVideoThreads,
    mediaCacheSizeInBytes
  ]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    return () => {
      isMounted.current = false;
    };
  }, []);
  const imageFormatOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (renderMode === "still") {
      return [
        {
          label: "PNG",
          onClick: () => setStillFormat("png"),
          key: "png",
          selected: stillImageFormat === "png"
        },
        {
          label: "JPEG",
          onClick: () => setStillFormat("jpeg"),
          key: "jpeg",
          selected: stillImageFormat === "jpeg"
        },
        {
          label: "PDF",
          onClick: () => setStillFormat("pdf"),
          key: "pdf",
          selected: stillImageFormat === "pdf"
        },
        {
          label: "WebP",
          onClick: () => setStillFormat("webp"),
          key: "webp",
          selected: stillImageFormat === "webp"
        }
      ];
    }
    if (renderMode === "sequence") {
      return [
        {
          label: "PNG",
          onClick: () => setSequenceImageFormat("png"),
          key: "png",
          selected: sequenceImageFormat === "png"
        },
        {
          label: "JPEG",
          onClick: () => setSequenceImageFormat("jpeg"),
          key: "jpeg",
          selected: sequenceImageFormat === "jpeg"
        }
      ];
    }
    return [
      {
        label: "PNG",
        onClick: () => setVideoImageFormat("png"),
        key: "png",
        selected: videoImageFormat === "png"
      },
      {
        label: "JPEG",
        onClick: () => setVideoImageFormat("jpeg"),
        key: "jpeg",
        selected: videoImageFormat === "jpeg"
      }
    ];
  }, [
    renderMode,
    videoImageFormat,
    stillImageFormat,
    setStillFormat,
    sequenceImageFormat
  ]);
  const setRenderMode = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newRenderMode) => {
    setRenderModeState(newRenderMode);
    if (newRenderMode === "audio") {
      setDefaultOutName({
        type: "render",
        codec: videoCodecForAudioTab,
        audioCodec: deriveFinalAudioCodec(videoCodecForAudioTab, userSelectedAudioCodec)
      });
    }
    if (newRenderMode === "video") {
      setDefaultOutName({
        type: "render",
        codec: videoCodecForVideoTab,
        audioCodec: deriveFinalAudioCodec(videoCodecForVideoTab, userSelectedAudioCodec)
      });
    }
    if (newRenderMode === "still") {
      setDefaultOutName({ type: "still", imageFormat: stillImageFormat });
    }
    if (newRenderMode === "sequence") {
      setDefaultOutName({ type: "sequence" });
    }
  }, [
    videoCodecForAudioTab,
    userSelectedAudioCodec,
    deriveFinalAudioCodec,
    setDefaultOutName,
    stillImageFormat,
    videoCodecForVideoTab
  ]);
  const renderTabOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (resolvedComposition?.durationInFrames < 2) {
      return [
        {
          label: "Still",
          onClick: () => {
            setRenderMode("still");
          },
          key: "still",
          selected: renderMode === "still"
        }
      ];
    }
    return [
      {
        label: "Still",
        onClick: () => {
          setRenderMode("still");
        },
        key: "still",
        selected: renderMode === "still"
      },
      {
        label: "Video",
        onClick: () => {
          setRenderMode("video");
        },
        key: "video",
        selected: renderMode === "video"
      },
      {
        label: "Audio",
        onClick: () => {
          setRenderMode("audio");
        },
        key: "audio",
        selected: renderMode === "audio"
      },
      {
        label: "Image sequence",
        onClick: () => {
          setRenderMode("sequence");
        },
        key: "sequence",
        selected: renderMode === "sequence"
      }
    ];
  }, [resolvedComposition?.durationInFrames, renderMode, setRenderMode]);
  const outnameValidation = validateOutnameGui({
    outName,
    codec,
    audioCodec,
    renderMode,
    stillImageFormat,
    separateAudioTo
  });
  const { tab, setTab, shownTabs } = useRenderModalSections(renderMode, codec);
  const { registerKeybinding } = useKeybinding();
  const renderDisabled = state.type === "load" || !outnameValidation.valid;
  const trigger = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    if (renderMode === "still") {
      onClickStill();
    } else if (renderMode === "sequence") {
      onClickSequence();
    } else {
      onClickVideo();
    }
  }, [renderMode, onClickStill, onClickSequence, onClickVideo]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (renderDisabled) {
      return;
    }
    const enter = registerKeybinding({
      callback() {
        trigger();
      },
      commandCtrlKey: true,
      key: "Enter",
      event: "keydown",
      preventDefault: true,
      triggerIfInputFieldFocused: true,
      keepRegisteredWhenNotHighestContext: false
    });
    return () => {
      enter.unregister();
    };
  }, [registerKeybinding, renderDisabled, trigger]);
  const pixelFormatOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return availablePixelFormats.map((option) => {
      return {
        label: option,
        onClick: () => setPixelFormat(option),
        key: option,
        id: option,
        keyHint: null,
        leftItem: pixelFormat === option ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: option
      };
    });
  }, [availablePixelFormats, pixelFormat]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: outerModalStyle,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalHeader, {
        title: `Render ${resolvedComposition.id}`
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: container53,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SegmentedControl, {
            items: renderTabOptions,
            needsWrapping: false
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: flexer
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Button, {
            autoFocus: true,
            onClick: trigger,
            disabled: renderDisabled,
            style: {
              ...buttonStyle7,
              backgroundColor: outnameValidation.valid ? BLUE : BLUE_DISABLED
            },
            children: [
              state.type === "idle" ? `Render ${renderMode}` : "Rendering...",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ShortcutHint, {
                keyToPress: "↵",
                cmdOrCtrl: true
              })
            ]
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: horizontalLayout,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: leftSidebar,
            children: [
              shownTabs.includes("general") ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(VerticalTab, {
                style: horizontalTab,
                selected: tab === "general",
                onClick: () => setTab("general"),
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: iconContainer,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FileIcon, {
                      style: icon6
                    })
                  }),
                  "General"
                ]
              }) : null,
              shownTabs.includes("data") ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(VerticalTab, {
                style: horizontalTab,
                selected: tab === "data",
                onClick: () => setTab("data"),
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: iconContainer,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DataIcon, {
                      style: icon6
                    })
                  }),
                  "Input Props"
                ]
              }) : null,
              shownTabs.includes("picture") ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(VerticalTab, {
                style: horizontalTab,
                selected: tab === "picture",
                onClick: () => setTab("picture"),
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: iconContainer,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(PicIcon, {
                      style: icon6
                    })
                  }),
                  "Picture"
                ]
              }) : null,
              shownTabs.includes("audio") ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(VerticalTab, {
                style: horizontalTab,
                selected: tab === "audio",
                onClick: () => setTab("audio"),
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: iconContainer,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(AudioIcon, {
                      style: icon6
                    })
                  }),
                  "Audio"
                ]
              }) : null,
              shownTabs.includes("gif") ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(VerticalTab, {
                style: horizontalTab,
                selected: tab === "gif",
                onClick: () => setTab("gif"),
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: iconContainer,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(GifIcon, {
                      style: icon6
                    })
                  }),
                  "GIF"
                ]
              }) : null,
              shownTabs.includes("advanced") ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(VerticalTab, {
                style: horizontalTab,
                selected: tab === "advanced",
                onClick: () => setTab("advanced"),
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: iconContainer,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(GearIcon, {
                      style: icon6
                    })
                  }),
                  "Other"
                ]
              }) : null
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: optionsPanel,
            className: VERTICAL_SCROLLBAR_CLASSNAME,
            children: tab === "general" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalBasic, {
              codec,
              resolvedComposition,
              frame: frame2,
              imageFormatOptions,
              outName,
              proResProfile,
              renderMode,
              setVideoCodec: setCodec,
              setFrame,
              setOutName,
              setProResProfile,
              endFrame,
              setEndFrame,
              setStartFrame,
              setVerboseLogging: setLogLevel,
              logLevel,
              startFrame,
              validationMessage: outnameValidation.valid ? null : outnameValidation.error.message
            }) : tab === "picture" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalPicture, {
              renderMode,
              scale,
              setScale,
              pixelFormat,
              pixelFormatOptions,
              imageFormatOptions,
              crf,
              setCrf,
              customTargetVideoBitrate,
              maxCrf,
              minCrf,
              jpegQuality,
              qualityControlType,
              setJpegQuality,
              setColorSpace,
              colorSpace,
              setCustomTargetVideoBitrateValue,
              setQualityControl,
              videoImageFormat,
              stillImageFormat,
              shouldDisplayQualityControlPicker: supportsBothQualityControls,
              encodingBufferSize,
              setEncodingBufferSize,
              encodingMaxRate,
              setEncodingMaxRate,
              compositionWidth: resolvedComposition.width,
              compositionHeight: resolvedComposition.height
            }) : tab === "audio" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalAudio, {
              muted,
              renderMode,
              setMuted,
              codec,
              audioCodec,
              setAudioCodec,
              enforceAudioTrack,
              setEnforceAudioTrackState,
              customTargetAudioBitrate,
              setCustomTargetAudioBitrateValue,
              setShouldHaveCustomTargetAudioBitrate,
              shouldHaveCustomTargetAudioBitrate,
              forSeamlessAacConcatenation,
              setForSeamlessAacConcatenation,
              separateAudioTo,
              setSeparateAudioTo,
              outName
            }) : tab === "gif" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalGif, {
              everyNthFrame,
              limitNumberOfGifLoops,
              numberOfGifLoopsSetting,
              setEveryNthFrameSetting,
              setLimitNumberOfGifLoops,
              setNumberOfGifLoopsSetting
            }) : tab === "data" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DataEditor, {
              defaultProps: inputProps,
              setDefaultProps: setInputProps,
              unresolvedComposition,
              mayShowSaveButton: false,
              propsEditType: "input-props",
              saving,
              setSaving,
              readOnlyStudio: false
            }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalAdvanced, {
              x264Preset,
              setx264Preset,
              concurrency,
              maxConcurrency,
              minConcurrency,
              renderMode,
              setConcurrency,
              delayRenderTimeout,
              setDelayRenderTimeout,
              disallowParallelEncoding,
              setDisallowParallelEncoding,
              setDisableWebSecurity,
              setIgnoreCertificateErrors,
              setHeadless,
              headless,
              ignoreCertificateErrors,
              disableWebSecurity,
              openGlOption,
              setOpenGlOption,
              setEnvVariables,
              envVariables,
              offthreadVideoCacheSizeInBytes,
              setMediaCacheSizeInBytes,
              mediaCacheSizeInBytes,
              setOffthreadVideoCacheSizeInBytes,
              offthreadVideoThreads,
              setOffthreadVideoThreads,
              enableMultiProcessOnLinux: multiProcessOnLinux,
              setChromiumMultiProcessOnLinux,
              codec,
              userAgent,
              setUserAgent,
              setBeep: setBeepOnFinish,
              beep: beepOnFinish,
              repro,
              setRepro,
              hardwareAcceleration,
              setHardwareAcceleration,
              chromeModeOption: chromeMode,
              setChromeModeOption: setChromeMode,
              darkMode,
              setDarkMode
            })
          })
        ]
      })
    ]
  });
};
var RenderModalWithLoader = (props) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DismissableModal, {
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ResolveCompositionBeforeModal, {
      compositionId: props.compositionId,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModal, {
        ...props
      })
    })
  });
};

// src/components/RenderModal/WebRenderModal.tsx




// src/icons/certificate.tsx

var CertificateIcon = (props) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
  xmlns: "http://www.w3.org/2000/svg",
  viewBox: "0 0 576 512",
  ...props,
  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
    fill: "currentcolor",
    d: "M192 32l128 0 0 96c0 35.3 28.7 64 64 64l96 0 0 256c0 17.7-14.3 32-32 32l-192 0 0 32 192 0c35.3 0 64-28.7 64-64l0-261.5c0-17-6.7-33.3-18.7-45.3L370.7 18.7C358.7 6.7 342.5 0 325.5 0L192 0c-35.3 0-64 28.7-64 64l0 80c10.9 0 21.6 1 32 2.9L160 64c0-17.7 14.3-32 32-32zM352 45.3L466.7 160 384 160c-17.7 0-32-14.3-32-32l0-82.7zM32 320a96 96 0 1 1 192 0 96 96 0 1 1 -192 0zM176 438.7l0 66.3-40.1-22.9c-4.9-2.8-11-2.8-15.9 0L80 505 80 438.7c14.8 6 31 9.3 48 9.3s33.2-3.3 48-9.3zm32-18.8c29.3-23.5 48-59.5 48-99.9 0-70.7-57.3-128-128-128S0 249.3 0 320c0 40.4 18.7 76.5 48 99.9l0 101.8c0 12.3 10 22.3 22.3 22.3 3.9 0 7.7-1 11.1-2.9l46.6-26.6 46.6 26.6c3.4 1.9 7.2 2.9 11.1 2.9 12.3 0 22.3-10 22.3-22.3l0-101.8zM128 344a24 24 0 1 1 0-48 24 24 0 1 1 0 48zm0-80a56 56 0 1 0 0 112 56 56 0 1 0 0-112z"
  })
});

// src/components/RenderModal/use-encodable-audio-codecs.ts


var useEncodableAudioCodecs = (container61) => {
  const cacheRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)({});
  const [codecsByContainer, setCodecsByContainer] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => {
    return {
      [container61]: (0,_remotion_web_renderer__WEBPACK_IMPORTED_MODULE_12__/* .getSupportedAudioCodecsForContainer */ .w_)(container61)
    };
  });
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const cached = cacheRef.current[container61];
    if (cached) {
      return;
    }
    const supported = (0,_remotion_web_renderer__WEBPACK_IMPORTED_MODULE_12__/* .getSupportedAudioCodecsForContainer */ .w_)(container61);
    cacheRef.current[container61] = {
      codecs: supported,
      status: "fetching"
    };
    (0,_remotion_web_renderer__WEBPACK_IMPORTED_MODULE_12__/* .getEncodableAudioCodecs */ .Xq)(container61).then((encodable) => {
      cacheRef.current[container61] = {
        codecs: encodable,
        status: "done"
      };
      setCodecsByContainer((prev) => ({
        ...prev,
        [container61]: encodable
      }));
    }).catch(() => {
      cacheRef.current[container61] = {
        codecs: supported,
        status: "done"
      };
    });
  }, [container61]);
  return codecsByContainer[container61] ?? (0,_remotion_web_renderer__WEBPACK_IMPORTED_MODULE_12__/* .getSupportedAudioCodecsForContainer */ .w_)(container61);
};

// src/components/RenderModal/use-encodable-video-codecs.ts


var useEncodableVideoCodecs = (container61) => {
  const cacheRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)({});
  const [codecsByContainer, setCodecsByContainer] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => {
    return {
      [container61]: (0,_remotion_web_renderer__WEBPACK_IMPORTED_MODULE_12__/* .getSupportedVideoCodecsForContainer */ .lT)(container61)
    };
  });
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    const cached = cacheRef.current[container61];
    if (cached) {
      return;
    }
    const supported = (0,_remotion_web_renderer__WEBPACK_IMPORTED_MODULE_12__/* .getSupportedVideoCodecsForContainer */ .lT)(container61);
    cacheRef.current[container61] = {
      codecs: supported,
      status: "fetching"
    };
    (0,_remotion_web_renderer__WEBPACK_IMPORTED_MODULE_12__/* .getEncodableVideoCodecs */ .cQ)(container61).then((encodable) => {
      cacheRef.current[container61] = {
        codecs: encodable,
        status: "done"
      };
      setCodecsByContainer((prev) => ({
        ...prev,
        [container61]: encodable
      }));
    }).catch(() => {
      cacheRef.current[container61] = {
        codecs: supported,
        status: "done"
      };
    });
  }, [container61]);
  return codecsByContainer[container61] ?? (0,_remotion_web_renderer__WEBPACK_IMPORTED_MODULE_12__/* .getSupportedVideoCodecsForContainer */ .lT)(container61);
};

// src/components/RenderModal/WebRendererExperimentalBadge.tsx

var row9 = {
  display: "flex",
  flexDirection: "row",
  alignItems: "center",
  justifyContent: "center"
};
var text3 = {
  fontSize: 14,
  fontFamily: "sans-serif",
  color: LIGHT_TEXT
};
var icon7 = {
  width: 14,
  height: 14,
  flexShrink: 0,
  fill: WARNING_COLOR,
  marginRight: 8
};
var link3 = {
  color: "inherit",
  textDecoration: "underline",
  fontSize: 14
};
var WebRendererExperimentalBadge = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: row9,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(WarningTriangle, {
        type: "warning",
        style: icon7
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: text3,
        children: [
          "The Remotion Web Renderer is experimental.",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("a", {
            href: "https://github.com/remotion-dev/remotion/issues/5913",
            target: "_blank",
            rel: "noopener noreferrer",
            style: link3,
            children: "Track progress on GitHub"
          }),
          " ",
          "and discuss in the",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("a", {
            href: "https://remotion.dev/discord",
            target: "_blank",
            rel: "noopener noreferrer",
            style: link3,
            children: "#web-renderer"
          }),
          " ",
          "channel on Discord."
        ]
      })
    ]
  });
};

// src/components/RenderModal/WebRenderModalAdvanced.tsx


var tabContainer = {
  flex: 1
};
var WebRenderModalAdvanced = ({
  renderMode,
  delayRenderTimeout,
  setDelayRenderTimeout,
  mediaCacheSizeInBytes,
  setMediaCacheSizeInBytes,
  hardwareAcceleration,
  setHardwareAcceleration
}) => {
  const toggleCustomMediaCacheSizeInBytes = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setMediaCacheSizeInBytes((previous) => {
      if (previous === null) {
        return 1000 * 1000 * 1000;
      }
      return null;
    });
  }, [setMediaCacheSizeInBytes]);
  const changeMediaCacheSizeInBytes = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((cb) => {
    setMediaCacheSizeInBytes((prev) => {
      if (prev === null) {
        throw new TypeError("Expected previous value");
      }
      if (typeof cb === "function") {
        return cb(prev);
      }
      return cb;
    });
  }, [setMediaCacheSizeInBytes]);
  const hardwareAccelerationOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return [
      {
        label: "No Preference",
        onClick: () => setHardwareAcceleration("no-preference"),
        leftItem: hardwareAcceleration === "no-preference" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        id: "no-preference",
        keyHint: null,
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: "no-preference"
      },
      {
        label: "Prefer Hardware",
        onClick: () => setHardwareAcceleration("prefer-hardware"),
        leftItem: hardwareAcceleration === "prefer-hardware" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        id: "prefer-hardware",
        keyHint: null,
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: "prefer-hardware"
      },
      {
        label: "Prefer Software",
        onClick: () => setHardwareAcceleration("prefer-software"),
        leftItem: hardwareAcceleration === "prefer-software" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        id: "prefer-software",
        keyHint: null,
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: "prefer-software"
      }
    ];
  }, [hardwareAcceleration, setHardwareAcceleration]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: tabContainer,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NumberSetting, {
        name: "Delay Render Timeout",
        formatter: (v) => `${v}ms`,
        min: 0,
        max: 1e9,
        step: 1000,
        value: delayRenderTimeout,
        onValueChanged: setDelayRenderTimeout,
        hint: "delayRenderTimeoutInMillisecondsOption"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Custom @remotion/media cache size ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "mediaCacheSizeInBytesOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: mediaCacheSizeInBytes !== null,
              onChange: toggleCustomMediaCacheSizeInBytes,
              name: "media-cache-size"
            })
          })
        ]
      }),
      mediaCacheSizeInBytes === null ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NumberSetting, {
        name: "@remotion/media cache size",
        formatter: (w) => `${w} bytes`,
        min: 0,
        max: 10000000000,
        step: 10 * 1024 * 1024,
        value: mediaCacheSizeInBytes,
        onValueChanged: changeMediaCacheSizeInBytes
      }),
      renderMode === "video" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: label5,
            children: "Hardware Acceleration"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
              values: hardwareAccelerationOptions,
              selectedId: hardwareAcceleration,
              title: "Hardware Acceleration"
            })
          })
        ]
      }) : null
    ]
  });
};

// src/components/RenderModal/WebRenderModalAudio.tsx



// src/components/RenderModal/quality-options.tsx

var QUALITY_OPTIONS = [
  { value: "very-low", label: "Very Low" },
  { value: "low", label: "Low" },
  { value: "medium", label: "Medium" },
  { value: "high", label: "High" },
  { value: "very-high", label: "Very High" }
];
var getQualityOptions = (selectedQuality, setQuality) => {
  return QUALITY_OPTIONS.map(({ value, label: label12 }) => ({
    label: label12,
    onClick: () => setQuality(value),
    leftItem: selectedQuality === value ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
    id: value,
    keyHint: null,
    quickSwitcherLabel: null,
    subMenu: null,
    type: "item",
    value
  }));
};

// src/components/RenderModal/WebRenderModalAudio.tsx

var container61 = {
  flex: 1,
  overflowY: "auto"
};
var fallbackNoticeStyle = {
  backgroundColor: "rgba(59, 130, 246, 0.15)",
  border: "1px solid rgba(59, 130, 246, 0.4)",
  borderRadius: 4,
  padding: "8px 12px",
  marginLeft: 16,
  marginRight: 16,
  marginTop: 8,
  fontSize: 13,
  lineHeight: 1.4,
  color: "#60a5fa"
};
var humanReadableWebAudioCodec = (audioCodec) => {
  switch (audioCodec) {
    case "aac":
      return "AAC";
    case "opus":
      return "Opus";
    default:
      return audioCodec;
  }
};
var WebRenderModalAudio = ({
  muted,
  setMuted,
  audioCodec,
  setAudioCodec,
  audioBitrate,
  setAudioBitrate,
  container: videoContainer,
  encodableCodecs,
  effectiveAudioCodec
}) => {
  const containerSupported = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => (0,_remotion_web_renderer__WEBPACK_IMPORTED_MODULE_12__/* .getSupportedAudioCodecsForContainer */ .w_)(videoContainer), [videoContainer]);
  const audioCodecOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return containerSupported.map((codec) => {
      const isEncodable = encodableCodecs.includes(codec);
      return {
        label: humanReadableWebAudioCodec(codec),
        onClick: () => setAudioCodec(codec),
        leftItem: audioCodec === codec ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        id: codec,
        keyHint: null,
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: codec,
        disabled: !isEncodable
      };
    });
  }, [containerSupported, encodableCodecs, audioCodec, setAudioCodec]);
  const audioBitrateOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => getQualityOptions(audioBitrate, setAudioBitrate), [audioBitrate, setAudioBitrate]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: container61,
    className: VERTICAL_SCROLLBAR_CLASSNAME,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MutedSetting, {
        enforceAudioTrack: false,
        muted,
        setMuted
      }),
      !muted ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalHr, {}),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: optionRow,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                style: label5,
                children: [
                  "Audio Quality",
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                    x: 0.5
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: rightRow,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
                  values: audioBitrateOptions,
                  selectedId: audioBitrate,
                  title: "Audio Quality"
                })
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: optionRow,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                style: label5,
                children: [
                  "Audio Codec",
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                    x: 0.5
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: rightRow,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
                  values: audioCodecOptions,
                  selectedId: audioCodec,
                  title: "Audio Codec"
                })
              })
            ]
          }),
          effectiveAudioCodec !== audioCodec ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: fallbackNoticeStyle,
            children: [
              humanReadableWebAudioCodec(audioCodec),
              " is not available in this browser. Using ",
              humanReadableWebAudioCodec(effectiveAudioCodec),
              " ",
              "instead."
            ]
          }) : null
        ]
      }) : null
    ]
  });
};

// src/components/RenderModal/WebRenderModalBasic.tsx


var tabContainer2 = {
  flex: 1
};
var WebRenderModalBasic = ({
  renderMode,
  resolvedComposition,
  imageFormat,
  setStillFormat,
  frame: frame2,
  onFrameChanged,
  onFrameSetDirectly,
  container: container62,
  setContainerFormat,
  setCodec,
  encodableVideoCodecs,
  effectiveVideoCodec,
  startFrame,
  setStartFrame,
  endFrame,
  setEndFrame,
  outName,
  onOutNameChange,
  validationMessage,
  logLevel,
  setLogLevel
}) => {
  const imageFormatOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return [
      {
        label: "PNG",
        onClick: () => setStillFormat("png"),
        key: "png",
        selected: imageFormat === "png"
      },
      {
        label: "JPEG",
        onClick: () => setStillFormat("jpeg"),
        key: "jpeg",
        selected: imageFormat === "jpeg"
      },
      {
        label: "WebP",
        onClick: () => setStillFormat("webp"),
        key: "webp",
        selected: imageFormat === "webp"
      }
    ];
  }, [imageFormat, setStillFormat]);
  const logLevelOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return ["trace", "verbose", "info", "warn", "error"].map((level) => {
      return {
        label: humanReadableLogLevel(level),
        onClick: () => setLogLevel(level),
        leftItem: logLevel === level ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        id: level,
        keyHint: null,
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: level
      };
    });
  }, [logLevel, setLogLevel]);
  const containerOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return [
      {
        label: "MP4",
        onClick: () => setContainerFormat("mp4"),
        leftItem: container62 === "mp4" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        id: "mp4",
        keyHint: null,
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: "mp4"
      },
      {
        label: "WebM",
        onClick: () => setContainerFormat("webm"),
        leftItem: container62 === "webm" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
        id: "webm",
        keyHint: null,
        quickSwitcherLabel: null,
        subMenu: null,
        type: "item",
        value: "webm"
      }
    ];
  }, [container62, setContainerFormat]);
  const codecLabels = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => ({
    h264: "H.264",
    h265: "H.265",
    vp8: "VP8",
    vp9: "VP9",
    av1: "AV1"
  }), []);
  const codecOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return encodableVideoCodecs.map((c) => ({
      label: codecLabels[c],
      onClick: () => setCodec(c),
      leftItem: effectiveVideoCodec === c ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkmark, {}) : null,
      id: c,
      keyHint: null,
      quickSwitcherLabel: null,
      subMenu: null,
      type: "item",
      value: c
    }));
  }, [encodableVideoCodecs, effectiveVideoCodec, setCodec, codecLabels]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: tabContainer2,
    children: [
      renderMode === "still" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: optionRow,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: label5,
                children: "Format"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: rightRow,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SegmentedControl, {
                  items: imageFormatOptions,
                  needsWrapping: true
                })
              })
            ]
          }),
          resolvedComposition.durationInFrames > 1 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: optionRow,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: label5,
                children: "Frame"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: rightRow,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RightAlignInput, {
                  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InputDragger, {
                    value: frame2,
                    onTextChange: onFrameChanged,
                    placeholder: `0-${resolvedComposition.durationInFrames - 1}`,
                    onValueChange: onFrameSetDirectly,
                    name: "frame",
                    step: 1,
                    min: 0,
                    status: "ok",
                    max: resolvedComposition.durationInFrames - 1,
                    rightAlign: true
                  })
                })
              })
            ]
          }) : null
        ]
      }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: optionRow,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: label5,
                children: "Container"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: rightRow,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
                  values: containerOptions,
                  selectedId: container62,
                  title: "Container"
                })
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: optionRow,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                style: label5,
                children: [
                  "Codec",
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                    x: 0.5
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                    id: "videoCodecOption"
                  })
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: rightRow,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
                  values: codecOptions,
                  selectedId: effectiveVideoCodec,
                  title: "Codec"
                })
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FrameRangeSetting, {
            durationInFrames: resolvedComposition.durationInFrames,
            startFrame: startFrame ?? 0,
            endFrame: endFrame ?? resolvedComposition.durationInFrames - 1,
            setStartFrame,
            setEndFrame
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalOutputName, {
        existence: false,
        inputStyle: input,
        outName,
        onValueChange: onOutNameChange,
        validationMessage,
        label: window.remotion_isReadOnlyStudio ? "Download name" : "Output name"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: optionRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: label5,
            children: [
              "Log Level ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 0.5
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OptionExplainerBubble, {
                id: "logLevelOption"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: rightRow,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
              values: logLevelOptions,
              selectedId: logLevel,
              title: "Log Level"
            })
          })
        ]
      })
    ]
  });
};

// src/components/RenderModal/WebRenderModalLicense.tsx


// src/icons/check-circle-filled.tsx

var CheckCircleFilled = (props) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
  xmlns: "http://www.w3.org/2000/svg",
  style: { width: 14, height: 14 },
  viewBox: "0 0 512 512",
  ...props,
  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
    d: "M256 512a256 256 0 1 1 0-512 256 256 0 1 1 0 512zM374 145.7c-10.7-7.8-25.7-5.4-33.5 5.3L221.1 315.2 169 263.1c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l72 72c5 5 11.8 7.5 18.8 7s13.4-4.1 17.5-9.8L379.3 179.2c7.8-10.7 5.4-25.7-5.3-33.5z"
  })
});

// src/components/RenderModal/WebRenderModalLicenseKeyDetails.tsx

var textStyle2 = {
  color: LIGHT_TEXT,
  fontSize: 14,
  fontFamily: "sans-serif",
  lineHeight: 1.5,
  display: "flex",
  alignItems: "center"
};
var linkStyle = {
  fontSize: 14,
  fontFamily: "sans-serif",
  lineHeight: 1.5,
  cursor: "pointer"
};
var bulletStyle = {
  display: "flex",
  alignItems: "center",
  gap: 6
};
var icon8 = {
  width: 14,
  height: 14,
  flexShrink: 0
};
var PRO_HOST = "https://remotion.pro";
var fetchLicenseKeyDetails = async (licenseKey) => {
  const response = await fetch(`${PRO_HOST}/api/validate-license-key`, {
    method: "POST",
    body: JSON.stringify({
      licenseKey
    }),
    headers: {
      "Content-Type": "application/json"
    }
  });
  return response.json();
};
var WebRenderModalLicenseKeyDetails = ({ details }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: bulletStyle,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CheckCircleFilled, {
            style: { ...icon8, fill: LIGHT_TEXT }
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: textStyle2,
            children: [
              "Belongs to ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("a", {
                href: `${PRO_HOST}/projects/${details.projectSlug}`,
                target: "_blank",
                style: linkStyle,
                children: details.projectName
              }),
              " - ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("a", {
                href: `${PRO_HOST}/projects/${details.projectSlug}/usage#client-renders-usage`,
                target: "_blank",
                style: linkStyle,
                children: "View usage"
              })
            ]
          })
        ]
      }),
      details.hasActiveSubscription ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: bulletStyle,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CheckCircleFilled, {
            style: { ...icon8, fill: LIGHT_TEXT }
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: textStyle2,
            children: "Active Company License"
          })
        ]
      }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: bulletStyle,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(WarningTriangle, {
            type: "warning",
            style: { ...icon8, fill: WARNING_COLOR }
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: textStyle2,
            children: "No active Company License"
          })
        ]
      })
    ]
  });
};

// src/components/RenderModal/WebRenderModalLicense.tsx

var row10 = {
  display: "flex",
  flexDirection: "row",
  paddingLeft: 16,
  paddingRight: 16
};
var tabContainer3 = {
  flex: 1
};
var descriptionStyle = {
  color: LIGHT_TEXT,
  fontSize: 14,
  fontFamily: "sans-serif",
  paddingLeft: 16,
  paddingRight: 16,
  paddingTop: 16,
  paddingBottom: 8,
  lineHeight: 1.5
};
var paddedDescriptionStyle = {
  color: LIGHT_TEXT,
  fontSize: 14,
  fontFamily: "sans-serif",
  padding: 9,
  border: "1px solid " + INPUT_BORDER_COLOR_UNHOVERED,
  borderRadius: 8,
  lineHeight: 1.5,
  marginLeft: 16,
  marginRight: 16
};
var descriptionLink = {
  color: "white",
  fontSize: 14
};
var checkboxLabel = {
  fontSize: 14,
  lineHeight: "40px",
  color: LIGHT_TEXT,
  flex: 1,
  fontFamily: "sans-serif",
  cursor: "pointer",
  userSelect: "none"
};
var inputStyle2 = {
  minWidth: 250
};
var justifyCenter = {
  display: "flex",
  alignItems: "center",
  gap: 10,
  flex: 1
};
var codeStyle = {
  fontSize: 14,
  fontFamily: "monospace",
  color: BLUE
};
var codeLine = {
  fontSize: 14,
  fontFamily: "monospace",
  color: LIGHT_TEXT,
  backgroundColor: INPUT_BACKGROUND,
  padding: 6,
  borderRadius: 3,
  marginTop: 6,
  overflowX: "auto",
  maxWidth: "100%"
};
var codeLineSmall = {
  ...codeLine,
  fontSize: 11
};
var LICENSE_KEY_LENGTH = 55;
var LICENSE_KEY_PREFIX = "rm_pub_";
var validateLicenseKey = (key5) => {
  if (key5.length === 0) {
    return { valid: false, message: null, details: null };
  }
  if (!key5.startsWith(LICENSE_KEY_PREFIX)) {
    return {
      valid: false,
      message: `License key must start with "${LICENSE_KEY_PREFIX}"`,
      details: null
    };
  }
  const afterPrefix = key5.slice(LICENSE_KEY_PREFIX.length);
  if (!/^[a-zA-Z0-9]*$/.test(afterPrefix)) {
    return {
      valid: false,
      message: "License key must contain only alphanumeric characters after the prefix",
      details: null
    };
  }
  if (key5.length !== LICENSE_KEY_LENGTH) {
    return {
      valid: false,
      message: `License key must be ${LICENSE_KEY_LENGTH} characters long`,
      details: null
    };
  }
  return { valid: true, message: null, details: null };
};
var WebRenderModalLicense = ({
  licenseKey,
  setLicenseKey,
  initialPublicLicenseKey
}) => {
  const [licenseValidation, setLicenseValidation] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({ valid: true, message: null, details: null });
  const [isLoading, setIsLoading] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (licenseKey === null || licenseKey === "free-license") {
      return setLicenseValidation({
        valid: true,
        message: null,
        details: null
      });
    }
    const validation = validateLicenseKey(licenseKey);
    if (!validation.valid) {
      return setLicenseValidation(validation);
    }
    setLicenseValidation({ valid: true, message: null, details: null });
    setIsLoading(true);
    fetchLicenseKeyDetails(licenseKey).then((details) => {
      setIsLoading(false);
      if (details.isValid) {
        setLicenseValidation({ valid: true, message: null, details });
      } else {
        setLicenseValidation({
          valid: false,
          message: "License key is invalid or has been reset",
          details: null
        });
      }
    }).catch(() => {
      setIsLoading(false);
      setLicenseValidation({
        valid: false,
        message: "Failed to fetch license key details",
        details: null
      });
    });
  }, [licenseKey]);
  const onFreeLicenseChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setLicenseKey("free-license");
  }, [setLicenseKey]);
  const onCompanyLicenseChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setLicenseKey(initialPublicLicenseKey ?? "");
  }, [initialPublicLicenseKey, setLicenseKey]);
  const onLicenseKeyChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setLicenseKey(e.target.value);
  }, [setLicenseKey]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: tabContainer3,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: descriptionStyle,
        children: [
          "Remotion is free if you are an individual or company with a headcount of 3 or less. See",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("a", {
            style: descriptionLink,
            href: "https://remotion.dev/license",
            children: "LICENSE.md"
          }),
          "."
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: row10,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
          style: justifyCenter,
          children: [
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: licenseKey === "free-license",
              onChange: onFreeLicenseChange,
              name: "free-license",
              rounded: true
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
              style: checkboxLabel,
              onClick: onFreeLicenseChange,
              children: [
                "I am eligible for the Free License, ",
                "don't",
                " print a warning"
              ]
            })
          ]
        })
      }),
      licenseKey === "free-license" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: paddedDescriptionStyle,
        children: [
          "Enjoy Remotion! Add the following to",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
            style: codeStyle,
            children: "remotion.config.ts"
          }),
          " to persist this setting:",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: codeLine,
            children: "Config.setPublicLicenseKey('free-license');"
          })
        ]
      }) : null,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: row10,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
          style: justifyCenter,
          children: [
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
              checked: licenseKey !== "free-license" && licenseKey !== null,
              onChange: onCompanyLicenseChange,
              name: "company-license",
              rounded: true
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
              style: checkboxLabel,
              onClick: onCompanyLicenseChange,
              children: "I have a Company License"
            })
          ]
        })
      }),
      licenseKey !== "free-license" && licenseKey !== null ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: paddedDescriptionStyle,
        children: [
          "Add your public license key from",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("a", {
            href: "https://remotion.pro/dashboard",
            target: "_blank",
            style: descriptionLink,
            children: "remotion.pro"
          }),
          " ",
          "below.",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
            y: 1,
            block: true
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RemotionInput, {
            value: licenseKey,
            onChange: onLicenseKeyChange,
            placeholder: "remotion.pro public license key (starts with rm_pub_)",
            status: licenseValidation.valid || licenseKey.length === 0 ? "ok" : "error",
            rightAlign: false,
            style: inputStyle2,
            autoFocus: true
          }),
          licenseValidation.message ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                y: 1,
                block: true
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ValidationMessage, {
                message: licenseValidation.message,
                align: "flex-start",
                type: "error"
              })
            ]
          }) : null,
          licenseValidation.valid && licenseKey.length > 0 ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                y: 1,
                block: true
              }),
              "Add the following to",
              " ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
                style: codeStyle,
                children: "remotion.config.ts"
              }),
              " to persist this setting:",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: codeLineSmall,
                children: "Config.setPublicLicenseKey('" + licenseKey + "');"
              })
            ]
          }) : null,
          isLoading && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                y: 1,
                block: true
              }),
              "Loading license key details..."
            ]
          }),
          licenseValidation.details && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                y: 1,
                block: true
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(WebRenderModalLicenseKeyDetails, {
                details: licenseValidation.details
              })
            ]
          })
        ]
      }) : null,
      licenseKey === null ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: descriptionStyle,
        children: [
          "If you are not eligible for the free license, you need to obtain a",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("a", {
            style: descriptionLink,
            target: "_blank",
            href: "https://remotion.pro/license",
            children: "Company License"
          }),
          "."
        ]
      }) : null
    ]
  });
};

// src/components/RenderModal/WebRenderModalPicture.tsx


var tabContainer4 = {
  flex: 1
};
var WebRenderModalPicture = ({
  renderMode,
  videoBitrate,
  setVideoBitrate,
  keyframeIntervalInSeconds,
  setKeyframeIntervalInSeconds,
  transparent,
  setTransparent,
  scale,
  setScale,
  compositionWidth,
  compositionHeight
}) => {
  const qualityOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => getQualityOptions(videoBitrate, setVideoBitrate), [videoBitrate, setVideoBitrate]);
  const onTransparentChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setTransparent(e.target.checked);
  }, [setTransparent]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: tabContainer4,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ScaleSetting, {
        scale,
        setScale,
        compositionWidth,
        compositionHeight
      }),
      renderMode !== "video" ? null : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: optionRow,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: label5,
                children: "Quality"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: rightRow,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Combobox, {
                  values: qualityOptions,
                  selectedId: videoBitrate,
                  title: "Quality"
                })
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NumberSetting, {
            name: "Keyframe Interval",
            formatter: (v) => `${v}s`,
            min: 1,
            max: 300,
            step: 1,
            value: keyframeIntervalInSeconds,
            onValueChanged: setKeyframeIntervalInSeconds
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: optionRow,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: label5,
                children: "Transparent"
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: rightRow,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Checkbox, {
                  checked: transparent,
                  onChange: onTransparentChanged,
                  name: "transparent"
                })
              })
            ]
          })
        ]
      })
    ]
  });
};

// src/components/RenderModal/WebRenderModal.tsx

var invalidCharacters2 = ["?", "*", "+", ":", "%"];
var isValidStillExtension2 = (extension, stillImageFormat) => {
  if (stillImageFormat === "jpeg" && extension === "jpg") {
    return true;
  }
  return extension === stillImageFormat;
};
var validateOutnameForStill = ({
  outName,
  stillImageFormat
}) => {
  try {
    const extension = outName.substring(outName.lastIndexOf(".") + 1);
    const prefix = outName.substring(0, outName.lastIndexOf("."));
    const hasDotAfterSlash = () => {
      const substrings = prefix.split("/");
      for (const str of substrings) {
        if (str[0] === ".") {
          return true;
        }
      }
      return false;
    };
    const hasInvalidChar = () => {
      return prefix.split("").some((char) => invalidCharacters2.includes(char));
    };
    if (prefix.length < 1) {
      throw new Error("The prefix must be at least 1 character long");
    }
    if (prefix[0] === "." || hasDotAfterSlash()) {
      throw new Error("The output name must not start with a dot");
    }
    if (hasInvalidChar()) {
      throw new Error("Filename can't contain the following characters:  ?, *, +, %, :");
    }
    if (!isValidStillExtension2(extension, stillImageFormat)) {
      throw new Error(`The extension ${extension} is not supported for still image format ${stillImageFormat}`);
    }
    return { valid: true };
  } catch (err) {
    return { valid: false, error: err };
  }
};
var WebRenderModal = ({
  initialFrame,
  defaultProps,
  inFrameMark,
  outFrameMark,
  initialLogLevel,
  initialLicenseKey,
  initialStillImageFormat,
  initialDefaultOutName,
  initialScale,
  initialDelayRenderTimeout,
  initialMediaCacheSizeInBytes,
  initialContainer,
  initialVideoCodec,
  initialAudioCodec,
  initialAudioBitrate,
  initialVideoBitrate,
  initialHardwareAcceleration,
  initialKeyframeIntervalInSeconds,
  initialTransparent,
  initialMuted
}) => {
  const context = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ResolvedCompositionContext);
  const { setSelectedModal } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const { setSidebarCollapsedState } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(SidebarContext);
  const { addClientStillJob, addClientVideoJob } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(RenderQueueContext);
  if (!context) {
    throw new Error("Should not be able to render without resolving comp first");
  }
  const {
    resolved: { result: resolvedComposition },
    unresolved: unresolvedComposition
  } = context;
  const [isVideo] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => {
    return typeof resolvedComposition.durationInFrames === "undefined" ? true : resolvedComposition.durationInFrames > 1;
  });
  const [renderMode, setRenderMode] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(isVideo ? "video" : "still");
  const [tab, setTab] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)("general");
  const [imageFormat, setImageFormat] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialStillImageFormat ?? "png");
  const [frame2, setFrame] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialFrame);
  const [logLevel, setLogLevel] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialLogLevel);
  const [inputProps, setInputProps] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => defaultProps);
  const [delayRenderTimeout, setDelayRenderTimeout] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialDelayRenderTimeout ?? 30000);
  const [mediaCacheSizeInBytes, setMediaCacheSizeInBytes] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialMediaCacheSizeInBytes);
  const [saving, setSaving] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const [codec, setCodec] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialVideoCodec ?? "h264");
  const [container62, setContainer] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialContainer ?? "mp4");
  const [audioCodec, setAudioCodec] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialAudioCodec ?? "aac");
  const [audioBitrate, setAudioBitrate] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialAudioBitrate ?? "medium");
  const [videoBitrate, setVideoBitrate] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialVideoBitrate ?? "high");
  const [hardwareAcceleration, setHardwareAcceleration] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialHardwareAcceleration ?? "no-preference");
  const [keyframeIntervalInSeconds, setKeyframeIntervalInSeconds] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialKeyframeIntervalInSeconds ?? 5);
  const [startFrame, setStartFrame] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => inFrameMark);
  const [endFrame, setEndFrame] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => outFrameMark);
  const [transparent, setTransparent] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialTransparent ?? false);
  const [muted, setMuted] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialMuted ?? false);
  const [scale, setScale] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialScale ?? 1);
  const [licenseKey, setLicenseKey] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(initialLicenseKey);
  const encodableAudioCodecs = useEncodableAudioCodecs(container62);
  const encodableVideoCodecs = useEncodableVideoCodecs(container62);
  const effectiveAudioCodec = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (encodableAudioCodecs.includes(audioCodec)) {
      return audioCodec;
    }
    return encodableAudioCodecs[0] ?? audioCodec;
  }, [audioCodec, encodableAudioCodecs]);
  const effectiveVideoCodec = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (encodableVideoCodecs.includes(codec)) {
      return codec;
    }
    return encodableVideoCodecs[0] ?? codec;
  }, [codec, encodableVideoCodecs]);
  const finalEndFrame = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (endFrame === null) {
      return resolvedComposition.durationInFrames - 1;
    }
    return Math.max(0, Math.min(resolvedComposition.durationInFrames - 1, endFrame));
  }, [endFrame, resolvedComposition.durationInFrames]);
  const finalStartFrame = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (startFrame === null) {
      return 0;
    }
    return Math.max(0, Math.min(finalEndFrame, startFrame));
  }, [finalEndFrame, startFrame]);
  const [initialOutNameState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => {
    if (initialDefaultOutName) {
      return initialDefaultOutName;
    }
    const defaultOut = (0,_remotion_studio_shared__WEBPACK_IMPORTED_MODULE_6__/* .getDefaultOutLocation */ .LE)({
      compositionName: resolvedComposition.id,
      defaultExtension: renderMode === "still" ? imageFormat : isVideo ? container62 : imageFormat,
      type: "asset",
      compositionDefaultOutName: resolvedComposition.defaultOutName,
      outputLocation: window.remotion_renderDefaults?.outputLocation ?? null
    });
    if (window.remotion_isReadOnlyStudio) {
      return defaultOut.replace(/^out\//, "");
    }
    return defaultOut;
  });
  const [outName, setOutName] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => initialOutNameState);
  const setStillFormat = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((format) => {
    setImageFormat(format);
    setOutName((prev) => {
      const newFileName = getStringBeforeSuffix(prev) + "." + format;
      return newFileName;
    });
  }, []);
  const setContainerFormat = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newContainer) => {
    setContainer(newContainer);
    setAudioCodec((0,_remotion_web_renderer__WEBPACK_IMPORTED_MODULE_12__/* .getDefaultAudioCodecForContainer */ .A4)(newContainer));
    setOutName((prev) => {
      const newFileName = getStringBeforeSuffix(prev) + "." + newContainer;
      return newFileName;
    });
  }, []);
  const onRenderModeChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newMode) => {
    setRenderMode(newMode);
    if (newMode === "video") {
      setOutName((prev) => {
        const newFileName = getStringBeforeSuffix(prev) + "." + container62;
        return newFileName;
      });
    } else if (newMode === "still") {
      setOutName((prev) => {
        const newFileName = getStringBeforeSuffix(prev) + "." + imageFormat;
        return newFileName;
      });
    }
  }, [container62, imageFormat]);
  const renderTabOptions = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const options = [
      {
        label: "Still",
        onClick: () => {
          onRenderModeChange("still");
        },
        key: "still",
        selected: renderMode === "still"
      }
    ];
    if (resolvedComposition.durationInFrames > 1) {
      options.push({
        label: "Video",
        onClick: () => {
          onRenderModeChange("video");
        },
        key: "video",
        selected: renderMode === "video"
      });
    }
    return options;
  }, [renderMode, resolvedComposition.durationInFrames, onRenderModeChange]);
  const onFrameSetDirectly = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newFrame) => {
    setFrame(newFrame);
  }, [setFrame]);
  const onFrameChanged = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setFrame((q) => {
      const newFrame = parseFloat(e);
      if (Number.isNaN(newFrame)) {
        return q;
      }
      return newFrame;
    });
  }, [setFrame]);
  const onOutNameChange = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((e) => {
    setOutName(e.target.value);
  }, []);
  const outnameValidation = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (renderMode === "still") {
      return validateOutnameForStill({
        outName,
        stillImageFormat: imageFormat
      });
    }
    try {
      const extension = outName.substring(outName.lastIndexOf(".") + 1);
      const prefix = outName.substring(0, outName.lastIndexOf("."));
      const hasDotAfterSlash = () => {
        const substrings = prefix.split("/");
        for (const str of substrings) {
          if (str[0] === ".") {
            return true;
          }
        }
        return false;
      };
      const hasInvalidChar = () => {
        return prefix.split("").some((char) => invalidCharacters2.includes(char));
      };
      if (prefix.length < 1) {
        throw new Error("The prefix must be at least 1 character long");
      }
      if (prefix[0] === "." || hasDotAfterSlash()) {
        throw new Error("The output name must not start with a dot");
      }
      if (hasInvalidChar()) {
        throw new Error("Filename can't contain the following characters:  ?, *, +, %, :");
      }
      if (extension !== container62) {
        throw new Error(`The extension ${extension} is not supported for container format ${container62}`);
      }
      return { valid: true };
    } catch (err) {
      return { valid: false, error: err };
    }
  }, [outName, imageFormat, renderMode, container62]);
  const onAddToQueue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    const compositionRef = {
      component: unresolvedComposition.component,
      calculateMetadata: unresolvedComposition.calculateMetadata ?? null,
      width: resolvedComposition.width,
      height: resolvedComposition.height,
      fps: resolvedComposition.fps,
      durationInFrames: resolvedComposition.durationInFrames,
      defaultProps: resolvedComposition.defaultProps
    };
    if (renderMode === "still") {
      addClientStillJob({
        type: "client-still",
        compositionId: resolvedComposition.id,
        outName,
        imageFormat,
        frame: frame2,
        inputProps,
        delayRenderTimeout,
        mediaCacheSizeInBytes,
        logLevel,
        licenseKey,
        scale
      }, compositionRef);
    } else {
      addClientVideoJob({
        type: "client-video",
        compositionId: resolvedComposition.id,
        outName,
        container: container62,
        videoCodec: effectiveVideoCodec,
        audioCodec: effectiveAudioCodec,
        startFrame: finalStartFrame,
        endFrame: finalEndFrame,
        audioBitrate,
        videoBitrate,
        hardwareAcceleration,
        keyframeIntervalInSeconds,
        transparent,
        muted,
        inputProps,
        delayRenderTimeout,
        mediaCacheSizeInBytes,
        logLevel,
        licenseKey,
        scale
      }, compositionRef);
    }
    setSidebarCollapsedState({ left: null, right: "expanded" });
    persistSelectedOptionsSidebarPanel2("renders");
    optionsSidebarTabs.current?.selectRendersPanel();
    setSelectedModal(null);
  }, [
    renderMode,
    unresolvedComposition.component,
    unresolvedComposition.calculateMetadata,
    resolvedComposition.width,
    resolvedComposition.height,
    resolvedComposition.fps,
    resolvedComposition.durationInFrames,
    resolvedComposition.defaultProps,
    resolvedComposition.id,
    setSidebarCollapsedState,
    outName,
    imageFormat,
    frame2,
    inputProps,
    delayRenderTimeout,
    mediaCacheSizeInBytes,
    logLevel,
    licenseKey,
    container62,
    effectiveVideoCodec,
    effectiveAudioCodec,
    finalStartFrame,
    finalEndFrame,
    audioBitrate,
    videoBitrate,
    hardwareAcceleration,
    keyframeIntervalInSeconds,
    transparent,
    muted,
    setSelectedModal,
    addClientStillJob,
    addClientVideoJob,
    scale
  ]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
    style: outerModalStyle,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalHeader, {
        title: `Render ${resolvedComposition.id}`
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: container53,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SegmentedControl, {
            items: renderTabOptions,
            needsWrapping: false
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: flexer
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Button, {
            autoFocus: true,
            onClick: onAddToQueue,
            style: buttonStyle7,
            disabled: !outnameValidation.valid,
            children: [
              "Render ",
              renderMode,
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ShortcutHint, {
                keyToPress: "↵",
                cmdOrCtrl: true
              })
            ]
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
        style: container53,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(WebRendererExperimentalBadge, {})
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: horizontalLayout,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: leftSidebar,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(VerticalTab, {
                style: horizontalTab,
                selected: tab === "general",
                onClick: () => setTab("general"),
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: iconContainer,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FileIcon, {
                      style: icon6
                    })
                  }),
                  "General"
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(VerticalTab, {
                style: horizontalTab,
                selected: tab === "data",
                onClick: () => setTab("data"),
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: iconContainer,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DataIcon, {
                      style: icon6
                    })
                  }),
                  "Input Props"
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(VerticalTab, {
                style: horizontalTab,
                selected: tab === "picture",
                onClick: () => setTab("picture"),
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: iconContainer,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(PicIcon, {
                      style: icon6
                    })
                  }),
                  "Picture"
                ]
              }),
              renderMode === "video" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(VerticalTab, {
                style: horizontalTab,
                selected: tab === "audio",
                onClick: () => setTab("audio"),
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: iconContainer,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(AudioIcon, {
                      style: icon6
                    })
                  }),
                  "Audio"
                ]
              }) : null,
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(VerticalTab, {
                style: horizontalTab,
                selected: tab === "advanced",
                onClick: () => setTab("advanced"),
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: iconContainer,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(GearIcon, {
                      style: icon6
                    })
                  }),
                  "Other"
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(VerticalTab, {
                style: horizontalTab,
                selected: tab === "license",
                onClick: () => setTab("license"),
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                    style: iconContainer,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CertificateIcon, {
                      style: icon6
                    })
                  }),
                  "License"
                ]
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: optionsPanel,
            className: VERTICAL_SCROLLBAR_CLASSNAME,
            children: tab === "general" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(WebRenderModalBasic, {
              renderMode,
              resolvedComposition,
              imageFormat,
              setStillFormat,
              frame: frame2,
              onFrameChanged,
              onFrameSetDirectly,
              container: container62,
              setContainerFormat,
              setCodec,
              encodableVideoCodecs,
              effectiveVideoCodec,
              startFrame: finalStartFrame,
              setStartFrame,
              endFrame: finalEndFrame,
              setEndFrame,
              outName,
              onOutNameChange,
              validationMessage: outnameValidation.valid ? null : outnameValidation.error.message,
              logLevel,
              setLogLevel
            }) : tab === "data" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DataEditor, {
              defaultProps: inputProps,
              setDefaultProps: setInputProps,
              unresolvedComposition,
              mayShowSaveButton: false,
              propsEditType: "input-props",
              saving,
              setSaving,
              readOnlyStudio: false
            }) : tab === "picture" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(WebRenderModalPicture, {
              renderMode,
              videoBitrate,
              setVideoBitrate,
              keyframeIntervalInSeconds,
              setKeyframeIntervalInSeconds,
              transparent,
              setTransparent,
              scale,
              setScale,
              compositionWidth: resolvedComposition.width,
              compositionHeight: resolvedComposition.height
            }) : tab === "audio" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(WebRenderModalAudio, {
              muted,
              setMuted,
              audioCodec,
              setAudioCodec,
              audioBitrate,
              setAudioBitrate,
              container: container62,
              encodableCodecs: encodableAudioCodecs,
              effectiveAudioCodec
            }) : tab === "advanced" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(WebRenderModalAdvanced, {
              renderMode,
              delayRenderTimeout,
              setDelayRenderTimeout,
              mediaCacheSizeInBytes,
              setMediaCacheSizeInBytes,
              hardwareAcceleration,
              setHardwareAcceleration
            }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(WebRenderModalLicense, {
              licenseKey,
              setLicenseKey,
              initialPublicLicenseKey: initialLicenseKey
            })
          })
        ]
      })
    ]
  });
};
var WebRenderModalWithLoader = (props) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DismissableModal, {
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ResolveCompositionBeforeModal, {
      compositionId: props.compositionId,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(WebRenderModal, {
        ...props
      })
    })
  });
};

// src/components/UpdateModal/UpdateModal.tsx


// src/components/CopyButton.tsx


var iconStyle8 = {
  width: 16,
  height: 16,
  color: "white"
};
var buttonContainerStyle = {
  display: "flex",
  minWidth: "114px"
};
var copyIcon = /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
  "aria-hidden": "true",
  focusable: "false",
  "data-prefix": "far",
  "data-icon": "clipboard",
  className: "svg-inline--fa fa-clipboard fa-w-12",
  role: "img",
  xmlns: "http://www.w3.org/2000/svg",
  viewBox: "0 0 384 512",
  style: iconStyle8,
  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
    fill: "currentColor",
    d: "M336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 40c13.3 0 24 10.7 24 24s-10.7 24-24 24-24-10.7-24-24 10.7-24 24-24zm144 418c0 3.3-2.7 6-6 6H54c-3.3 0-6-2.7-6-6V118c0-3.3 2.7-6 6-6h42v36c0 6.6 5.4 12 12 12h168c6.6 0 12-5.4 12-12v-36h42c3.3 0 6 2.7 6 6z"
  })
});
var labelStyle5 = {
  fontSize: 14
};
var CopyButton = ({ textToCopy, label: label12, labelWhenCopied }) => {
  const [copied, setCopied] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    copyText(textToCopy).then(() => {
      setCopied(Date.now());
    }).catch((err) => {
      showNotification(`Could not copy: ${err.message}`, 2000);
    });
  }, [textToCopy]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (!copied) {
      return;
    }
    const to = setTimeout(() => setCopied(false), 2000);
    return () => clearTimeout(to);
  }, [copied]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Button, {
    onClick,
    buttonContainerStyle,
    children: [
      copyIcon,
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
        x: 1.5
      }),
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
        style: labelStyle5,
        children: copied ? labelWhenCopied : label12
      })
    ]
  });
};

// src/components/UpdateModal/OpenIssueButton.tsx


var svgStyle3 = {
  width: "11px",
  height: "11px"
};
var buttonStyle8 = {
  border: "none",
  width: "24px",
  height: "24px",
  display: "flex",
  justifyContent: "center",
  alignItems: "center"
};
var OpenIssueButton = ({ link: link4 }) => {
  const [hovered, setHovered] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(false);
  const buttonTooltip = `Open GitHub issue in new Tab`;
  const handleClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    window.open(link4, "_blank");
  }, [link4]);
  const svgFillColor = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return hovered ? "white" : LIGHT_TEXT;
  }, [hovered]);
  const openInEditorSvg = /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("svg", {
    viewBox: "0 0 512 512",
    style: svgStyle3,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("path", {
      fill: svgFillColor,
      d: "M320 0c-17.7 0-32 14.3-32 32s14.3 32 32 32h82.7L201.4 265.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L448 109.3V192c0 17.7 14.3 32 32 32s32-14.3 32-32V32c0-17.7-14.3-32-32-32H320zM80 32C35.8 32 0 67.8 0 112V432c0 44.2 35.8 80 80 80H400c44.2 0 80-35.8 80-80V320c0-17.7-14.3-32-32-32s-32 14.3-32 32V432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V112c0-8.8 7.2-16 16-16H192c17.7 0 32-14.3 32-32s-14.3-32-32-32H80z"
    })
  });
  const onPointerEnter = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(true);
  }, []);
  const onPointerLeave = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setHovered(false);
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("button", {
    title: buttonTooltip,
    type: "button",
    onPointerEnter,
    onPointerLeave,
    style: buttonStyle8,
    onClick: handleClick,
    children: openInEditorSvg
  });
};

// src/components/KnownBugs.tsx

var container62 = {
  display: "flex",
  flexDirection: "row",
  alignItems: "center"
};
var text4 = {
  fontSize: 14,
  flex: 1
};
var KnownBugs = ({ bugs }) => {
  const bugElements = bugs.map((bug) => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
      style: container62,
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
          style: text4,
          children: [
            "\uD83E\uDEB2 ",
            bug.title
          ]
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OpenIssueButton, {
          link: bug.link
        })
      ]
    }, bug.description + bug.link);
  });
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    children: bugElements
  });
};

// src/components/UpdateModal/UpdateModal.tsx

var container63 = {
  padding: 20,
  paddingTop: 0
};
var text5 = {
  fontSize: 14
};
var title8 = {
  paddingTop: 12,
  paddingBottom: 8,
  ...text5
};
var code = {
  background: SELECTED_BACKGROUND,
  padding: "12px 10px",
  fontSize: 14,
  marginTop: 10,
  marginBottom: 10
};
var link4 = {
  fontWeight: "bold",
  color: BLUE,
  textDecoration: "none",
  ...text5
};
var commands = {
  npm: "npx remotion upgrade",
  yarn: "yarn remotion upgrade",
  pnpm: "pnpm exec remotion upgrade",
  bun: "bun remotion upgrade",
  unknown: "npx remotion upgrade"
};
var UpdateModal = ({ info, knownBugs }) => {
  const hasKnownBugs = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return knownBugs && knownBugs?.length > 0;
  }, [knownBugs]);
  const command = commands[info.packageManager];
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    copyText(command).catch((err) => {
      showNotification(`Could not copy: ${err.message}`, 2000);
    });
  }, [command]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(DismissableModal, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalHeader, {
        title: "Update available"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
        style: container63,
        children: [
          hasKnownBugs ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
                style: title8,
                children: [
                  "The currently installed version ",
                  info.currentVersion,
                  " has the following known bugs:"
                ]
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(KnownBugs, {
                bugs: knownBugs
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: { height: "20px" }
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
                style: text5,
                children: "To upgrade, run the following command:"
              })
            ]
          }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
            style: title8,
            children: "A new update for Remotion is available! Run the following command:"
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(Row, {
            align: "center",
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Flex, {
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("pre", {
                  onClick,
                  style: code,
                  children: command
                })
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Spacing, {
                x: 1
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CopyButton, {
                textToCopy: command,
                label: "Copy",
                labelWhenCopied: "Copied!"
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: text5,
            children: [
              "This will upgrade Remotion from ",
              info.currentVersion,
              " to",
              " ",
              info.latestVersion,
              "."
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: text5,
            children: [
              "Read the",
              " ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("a", {
                style: link4,
                target: "_blank",
                href: "https://github.com/remotion-dev/remotion/releases",
                children: "Release notes"
              }),
              " ",
              "to know what",
              "'s",
              " new in Remotion."
            ]
          })
        ]
      })
    ]
  });
};

// src/components/Modals.tsx

var Modals = ({ readOnlyStudio }) => {
  const { selectedModal: modalContextType } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(ModalsContext);
  const canRender = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx).previewServerState.type === "connected";
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
    children: [
      modalContextType && modalContextType.type === "duplicate-comp" && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DuplicateComposition, {
        compositionType: modalContextType.compositionType,
        compositionId: modalContextType.compositionId
      }),
      modalContextType && modalContextType.type === "delete-comp" && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(DeleteComposition, {
        compositionId: modalContextType.compositionId
      }),
      modalContextType && modalContextType.type === "rename-comp" && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenameComposition, {
        compositionId: modalContextType.compositionId
      }),
      modalContextType && modalContextType.type === "input-props-override" && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(OverrideInputPropsModal, {}),
      modalContextType && modalContextType.type === "web-render" && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(WebRenderModalWithLoader, {
        ...modalContextType
      }),
      modalContextType && canRender && modalContextType.type === "server-render" && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderModalWithLoader, {
        initialFrame: modalContextType.initialFrame,
        initialDarkMode: modalContextType.initialDarkMode,
        compositionId: modalContextType.compositionId,
        initialVideoImageFormat: modalContextType.initialVideoImageFormat,
        initialJpegQuality: modalContextType.initialJpegQuality,
        initialScale: modalContextType.initialScale,
        initialLogLevel: modalContextType.initialLogLevel,
        initialOffthreadVideoCacheSizeInBytes: modalContextType.initialOffthreadVideoCacheSizeInBytes,
        initialOffthreadVideoThreads: modalContextType.initialOffthreadVideoThreads,
        initialMediaCacheSizeInBytes: modalContextType.initialMediaCacheSizeInBytes,
        initialConcurrency: modalContextType.initialConcurrency,
        maxConcurrency: modalContextType.maxConcurrency,
        minConcurrency: modalContextType.minConcurrency,
        initialStillImageFormat: modalContextType.initialStillImageFormat,
        initialMuted: modalContextType.initialMuted,
        initialEnforceAudioTrack: modalContextType.initialEnforceAudioTrack,
        initialProResProfile: modalContextType.initialProResProfile,
        initialx264Preset: modalContextType.initialx264Preset,
        initialPixelFormat: modalContextType.initialPixelFormat,
        initialAudioBitrate: modalContextType.initialAudioBitrate,
        initialVideoBitrate: modalContextType.initialVideoBitrate,
        initialEveryNthFrame: modalContextType.initialEveryNthFrame,
        initialNumberOfGifLoops: modalContextType.initialNumberOfGifLoops,
        initialDelayRenderTimeout: modalContextType.initialDelayRenderTimeout,
        initialEnvVariables: modalContextType.initialEnvVariables,
        initialDisableWebSecurity: modalContextType.initialDisableWebSecurity,
        initialGl: modalContextType.initialOpenGlRenderer,
        initialHeadless: modalContextType.initialHeadless,
        initialIgnoreCertificateErrors: modalContextType.initialIgnoreCertificateErrors,
        initialEncodingBufferSize: modalContextType.initialEncodingBufferSize,
        initialEncodingMaxRate: modalContextType.initialEncodingMaxRate,
        initialUserAgent: modalContextType.initialUserAgent,
        initialColorSpace: modalContextType.initialColorSpace,
        initialMultiProcessOnLinux: modalContextType.initialMultiProcessOnLinux,
        initialRepro: modalContextType.initialRepro,
        initialBeep: modalContextType.initialBeep,
        initialForSeamlessAacConcatenation: modalContextType.initialForSeamlessAacConcatenation,
        defaultProps: modalContextType.defaultProps,
        inFrameMark: modalContextType.inFrameMark,
        outFrameMark: modalContextType.outFrameMark,
        defaultConfigurationAudioCodec: modalContextType.defaultConfigurationAudioCodec,
        defaultConfigurationVideoCodec: modalContextType.defaultConfigurationVideoCodec,
        renderTypeOfLastRender: modalContextType.renderTypeOfLastRender,
        defaultMetadata: modalContextType.defaulMetadata,
        initialHardwareAcceleration: modalContextType.initialHardwareAcceleration,
        initialChromeMode: modalContextType.initialChromeMode,
        renderDefaults: modalContextType.renderDefaults
      }),
      modalContextType && modalContextType.type === "render-progress" && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(RenderStatusModal, {
        jobId: modalContextType.jobId
      }),
      modalContextType && modalContextType.type === "update" && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(UpdateModal, {
        info: modalContextType.info,
        knownBugs: modalContextType.knownBugs
      }),
      modalContextType && modalContextType.type === "install-packages" && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(InstallPackageModal, {
        packageManager: modalContextType.packageManager
      }),
      modalContextType && modalContextType.type === "quick-switcher" && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(QuickSwitcher_default, {
        readOnlyStudio,
        invocationTimestamp: modalContextType.invocationTimestamp,
        initialMode: modalContextType.mode
      }),
       true && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(AskAiModal, {})
    ]
  });
};

// src/components/Editor.tsx

var background2 = {
  backgroundColor: BACKGROUND,
  display: "flex",
  width: "100%",
  height: "100%",
  flexDirection: "column",
  position: "absolute"
};
var DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS = 300;
var BUFFER_STATE_DELAY_IN_MILLISECONDS =  true ? DEFAULT_BUFFER_STATE_DELAY_IN_MILLISECONDS : 0;
var Editor = ({ Root, readOnlyStudio }) => {
  const size4 = _remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.useElementSize(drawRef, {
    triggerOnWindowResize: false,
    shouldApplyCssTransforms: true
  });
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (readOnlyStudio) {
      return;
    }
    const listenToChanges = (e) => {
      if (window.remotion_unsavedProps) {
        e.returnValue = "Are you sure you want to leave?";
      }
    };
    window.addEventListener("beforeunload", listenToChanges);
    return () => {
      window.removeEventListener("beforeunload", listenToChanges);
    };
  }, [readOnlyStudio]);
  const [canvasMounted, setCanvasMounted] = react__WEBPACK_IMPORTED_MODULE_0__.useState(false);
  const onMounted = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setCanvasMounted(true);
  }, []);
  const value = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    if (!size4) {
      return null;
    }
    return {
      type: "canvas-size",
      canvasSize: size4
    };
  }, [size4]);
  const MemoRoot = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return react__WEBPACK_IMPORTED_MODULE_0__.memo(Root);
  }, [Root]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(HigherZIndex, {
    onEscape: noop,
    onOutsideClick: noop,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(TimelineZoomContext, {
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CurrentScaleContext.Provider, {
          value,
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
            style: background2,
            children: [
              canvasMounted ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MemoRoot, {}) : null,
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CanUseRemotionHooksProvider, {
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(EditorContent, {
                    readOnlyStudio,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TopPanel, {
                      drawRef,
                      bufferStateDelayInMilliseconds: BUFFER_STATE_DELAY_IN_MILLISECONDS,
                      onMounted,
                      readOnlyStudio
                    })
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(GlobalKeybindings, {})
                ]
              })
            ]
          })
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Modals, {
          readOnlyStudio
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(NotificationCenter, {})
      ]
    })
  });
};

// src/components/EditorContexts.tsx


// src/state/preview-size.tsx



var key5 = "remotion.previewSize";
var persistPreviewSizeOption = (option) => {
  localStorage.setItem(key5, JSON.stringify(option));
};
var loadPreviewSizeOption = () => {
  const item2 = localStorage.getItem(key5);
  if (item2 === null) {
    return {
      size: "auto",
      translation: {
        x: 0,
        y: 0
      }
    };
  }
  return JSON.parse(item2);
};
var PreviewSizeProvider = ({ children }) => {
  const [size4, setSizeState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => loadPreviewSizeOption());
  const [translation, setTranslation] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => {
    return {
      x: 0,
      y: 0
    };
  });
  const { editorZoomGestures } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(EditorZoomGesturesContext);
  const setSize = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newValue) => {
    setSizeState((prevState) => {
      const newVal = newValue(prevState);
      persistPreviewSizeOption(newVal);
      return newVal;
    });
  }, []);
  const previewSizeCtx = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      size: editorZoomGestures ? size4 : {
        size: size4.size,
        translation: {
          x: 0,
          y: 0
        }
      },
      setSize,
      translation,
      setTranslation
    };
  }, [editorZoomGestures, size4, setSize, translation]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.PreviewSizeContext.Provider, {
    value: previewSizeCtx,
    children
  });
};

// src/components/CheckerboardProvider.tsx


var CheckerboardProvider = ({ children }) => {
  const [checkerboard, setCheckerboardState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => loadCheckerboardOption());
  const setCheckerboard = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newValue) => {
    setCheckerboardState((prevState) => {
      const newVal = newValue(prevState);
      persistCheckerboardOption(newVal);
      return newVal;
    });
  }, []);
  const checkerboardCtx = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      checkerboard,
      setCheckerboard
    };
  }, [checkerboard, setCheckerboard]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CheckerboardContext.Provider, {
    value: checkerboardCtx,
    children
  });
};

// src/components/MediaVolumeProvider.tsx



var MediaVolumeProvider = ({ children }) => {
  const [mediaMuted, setMediaMuted] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => loadMuteOption());
  const [mediaVolume, setMediaVolume] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(1);
  const mediaVolumeContextValue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      mediaMuted,
      mediaVolume
    };
  }, [mediaMuted, mediaVolume]);
  const setMediaVolumeContextValue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      setMediaMuted,
      setMediaVolume
    };
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.MediaVolumeContext.Provider, {
    value: mediaVolumeContextValue,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.SetMediaVolumeContext.Provider, {
      value: setMediaVolumeContextValue,
      children
    })
  });
};

// src/components/ModalsProvider.tsx


var ModalsProvider = ({ children }) => {
  const [modalContextType, setModalContextType] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const modalsContext = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      selectedModal: modalContextType,
      setSelectedModal: setModalContextType
    };
  }, [modalContextType]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalsContext.Provider, {
    value: modalsContext,
    children
  });
};

// src/components/SetTimelineInOutProvider.tsx


// src/state/marks.ts
var localStorageKey5 = () => `remotion.editor.marksv2`;
var persistMarks = (marks) => {
  localStorage.setItem(localStorageKey5(), JSON.stringify(marks));
};
var loadMarks = () => {
  const item2 = localStorage.getItem(localStorageKey5());
  if (item2 === null) {
    return {};
  }
  return JSON.parse(item2);
};

// src/components/SetTimelineInOutProvider.tsx

var SetTimelineInOutProvider = ({ children }) => {
  const [inAndOutFrames, setInAndOutFrames] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => loadMarks());
  const setTimelineInOutContextValue = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      setInAndOutFrames
    };
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    persistMarks(inAndOutFrames);
  }, [inAndOutFrames]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(TimelineInOutContext.Provider, {
    value: inAndOutFrames,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SetTimelineInOutContext.Provider, {
      value: setTimelineInOutContextValue,
      children
    })
  });
};

// src/components/ShowGuidesProvider.tsx


var ShowGuidesProvider = ({ children }) => {
  const [guidesList, setGuidesList] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => loadGuidesList());
  const [selectedGuideId, setSelectedGuideId] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const [hoveredGuideId, setHoveredGuideId] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const [editorShowGuides, setEditorShowGuidesState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => loadEditorShowGuidesOption());
  const shouldCreateGuideRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(false);
  const shouldDeleteGuideRef = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)(false);
  const setEditorShowGuides = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newValue) => {
    setEditorShowGuidesState((prevState) => {
      const newVal = newValue(prevState);
      persistEditorShowGuidesOption(newVal);
      return newVal;
    });
  }, []);
  const editorShowGuidesCtx = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      editorShowGuides,
      setEditorShowGuides,
      guidesList,
      setGuidesList,
      selectedGuideId,
      setSelectedGuideId,
      shouldCreateGuideRef,
      shouldDeleteGuideRef,
      hoveredGuideId,
      setHoveredGuideId
    };
  }, [
    editorShowGuides,
    setEditorShowGuides,
    guidesList,
    selectedGuideId,
    hoveredGuideId
  ]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(EditorShowGuidesContext.Provider, {
    value: editorShowGuidesCtx,
    children
  });
};

// src/components/ShowRulersProvider.tsx


var ShowRulersProvider = ({ children }) => {
  const [editorShowRulers, setEditorShowRulersState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => loadEditorShowRulersOption());
  const setEditorShowRulers = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newValue) => {
    setEditorShowRulersState((prevState) => {
      const newVal = newValue(prevState);
      persistEditorShowRulersOption(newVal);
      return newVal;
    });
  }, []);
  const editorShowRulersCtx = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      editorShowRulers,
      setEditorShowRulers
    };
  }, [editorShowRulers, setEditorShowRulers]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(EditorShowRulersContext.Provider, {
    value: editorShowRulersCtx,
    children
  });
};

// src/components/ZoomGesturesProvider.tsx


var ZoomGesturesProvider = ({ children }) => {
  const [editorZoomGestures, setEditorZoomGesturesState] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(() => loadEditorZoomGesturesOption());
  const setEditorZoomGestures = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)((newValue) => {
    setEditorZoomGesturesState((prevState) => {
      const newVal = newValue(prevState);
      persistEditorZoomGesturesOption(newVal);
      return newVal;
    });
  }, []);
  const editorZoomGesturesCtx = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      editorZoomGestures,
      setEditorZoomGestures
    };
  }, [editorZoomGestures, setEditorZoomGestures]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(EditorZoomGesturesContext.Provider, {
    value: editorZoomGesturesCtx,
    children
  });
};

// src/components/EditorContexts.tsx

var EditorContexts = ({ children, readOnlyStudio }) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZodProvider, {
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(VisualControlsProvider, {
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(PreviewServerConnection, {
        readOnlyStudio,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(RenderQueueContextProvider, {
          children: [
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ClientRenderQueueProcessor, {}),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(KeybindingContextProvider, {
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(CheckerboardProvider, {
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ZoomGesturesProvider, {
                  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ShowRulersProvider, {
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ShowGuidesProvider, {
                      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(PreviewSizeProvider, {
                        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ModalsProvider, {
                          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(MediaVolumeProvider, {
                            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(_remotion_player__WEBPACK_IMPORTED_MODULE_3__/* .PlayerInternals */ .Cb.PlayerEmitterProvider, {
                              currentPlaybackRate: null,
                              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SidebarContextProvider, {
                                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FolderContextProvider, {
                                  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(HighestZIndexProvider, {
                                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(SetTimelineInOutProvider, {
                                      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ExpandedTracksProvider, {
                                        children
                                      })
                                    })
                                  })
                                })
                              })
                            })
                          })
                        })
                      })
                    })
                  })
                })
              })
            })
          ]
        })
      })
    })
  });
};

// src/components/Notifications/ServerDisconnected.tsx


var container64 = {
  position: "fixed",
  justifyContent: "flex-end",
  alignItems: "flex-start",
  display: "flex",
  width: "100%",
  height: "100%",
  flexDirection: "column",
  padding: 30,
  pointerEvents: "none",
  backgroundColor: "transparent",
  fontFamily: "SF Pro, Arial, Helvetica, sans-serif"
};
var message = {
  backgroundColor: "#e74c3c",
  color: "white",
  paddingLeft: 20,
  paddingRight: 20,
  paddingTop: 12,
  paddingBottom: 12,
  borderRadius: 4,
  boxShadow: "0 2px 4px rgba(0, 0, 0, 0.4)",
  lineHeight: 1.5
};
var inlineCode = {
  fontSize: 16,
  fontFamily: "monospace"
};
var pageIsGoingToReload = false;
window.addEventListener("beforeunload", () => {
  pageIsGoingToReload = true;
});
var ServerDisconnected = () => {
  const { previewServerState: ctx } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(StudioServerConnectionCtx);
  const fav = document.getElementById("__remotion_favicon");
  if (ctx.type !== "disconnected") {
    fav.setAttribute("href", "/favicon.ico");
    return null;
  }
  if (pageIsGoingToReload) {
    return null;
  }
  const base64Favicon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAARiSURBVHgB7d1NThRBFAfw/2tGgru5gXMD8QZ4AmVjAi6kN0TiAm8gnkBcGARNumcx4E48Ae0JaE9gewLHlQSZelaNgyHGL/RVd1X3+y10RQL58+rVx1QBKKWUUkoppZRSSimllFJKKVUjQs32stEiJcktZiwxzKL9Fvqzb6S0/44JVBKbtwa9aj29U6JjagtkJzsYzBEyBi9d5utsQIULCcxvelgo03R5jBarJZCXw/17E+bt82r4Hy4gtuEQekUbK8h7IHvDV5vMZht+VAlRfmYw3EhXKrSA10Ce2X7RIzpGDVzlgM1wPb2bI2JeA9nN99/b/waoV+XCmTAex1g13gLZyUZrdjjJ0CAbTB5bMN4C2ctHxwxaRABiCsZLIG6KmxC/R2BiCCaBBwn4NgJk10B2GOWj3Wz/IQLlpUL28oOjyy4AG1AZppuhVYt4hWRZ1o8gDGc6rL4YHjxCQMQDOcNCEI38bxnmLTc9d30PARAPZAITZP/4A1ctx3bjcw0NEw8koeQ64tRnu25qeggTb+q2/BmRcyv9K7yw3MTOsmiFuLMOtICblJzS5+Mm+opoIBOgFYHMuL5yVHcoooFQuwJxag9FNJCIG/rv1BqKaCDfzshbqbZQxAJxK3SJI9qATUPJstdef0axQGJbof+jwRc6eQ2PxAIx4DZXx3duSrybv3oCTyR7yACdYR762sIXDKQbFfId4ZGPJi8YCA3QLf05YvF+IhYIEV1Dx9hNu8XdbLQFQV6OcDuFaFNyKiwWiJ19DNBN/VN8XoMQrRABDFqCEJ32CiBisT08rRAZAwjRQAKjgcgQO+rVQARMb3gJ0UAkML+DEA1EwAQkdkNMcnOx1Zcxf8V9ol7y88GSm4tdDKRy1xsgSIes/0BM4ndN5HZ7OzZkMePperqSQ5jkkFWhO6r76WrYJ4b2N+YTumF60QeeSG6/d2DI4rHvW1eCPaT9Q9YZw/sVOMlZVoUWM8zpg/Su97dVJGdZFVrKhbFR05MdYoFcwWmF1rF9kbG8UeP7KaI3qBp628QTHrueUccwdZHw/ZDWNHY7tU1u1B2GIxqIYSO2Dd0Ud79wnq/eaOpBgR4EMVDW/oijINu87d7U6hYaJBrInA0k0iu4bvVtZ1KrBRrm4Vr06GNkF3cO7RCVhvK4pmiFOISkjOStk1lVrBQIiPh5SAyN3fWKWeMuEBjxCmEkh3bVvokAzd5idL2iQqDEA1nASXmK+XFIfeTCo5gFAudllvo8G20TUeNVElMQ58QrxLHD1jbB3GumSnhsz7qHE9BhTEGc87aOm16KJHi7rfqj8yfI53E1j/l9eK8L651stJUQeXx/iuzU1QztZLGIsRp+xvtOh3Qo3/qCedumEC6qZetpJztwz7O6UAa4FNsP7ELTfXbWbskUdjgq9M9VCJoFcwvTlfyPDd9t3XNJjA+2IZcGpmxi+7tpjW3OupurJziZhtKWPzWhlFJKKaWUUkoppZRSSiml/uwrgZ/Bfwo/wccAAAAASUVORK5CYII=";
  fav.setAttribute("href", base64Favicon);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("div", {
    style: container64,
    className: "css-reset",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("div", {
      style: message,
      children: [
        "The studio server has disconnected. ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("br", {}),
        window.remotion_studioServerCommand ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)("span", {
          children: [
            "Run",
            " ",
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("code", {
              style: inlineCode,
              children: window.remotion_studioServerCommand
            }),
            " ",
            "to run it again."
          ]
        }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)("span", {
          children: "Fast refresh will not work."
        })
      ]
    })
  });
};

// src/FastRefreshProvider.tsx


var FastRefreshProvider = ({ children }) => {
  const [fastRefreshes, setFastRefreshes] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(0);
  const [manualRefreshes, setManualRefreshes] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(0);
  const increaseManualRefreshes = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(() => {
    setManualRefreshes((i) => i + 1);
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (true) {
      if (__webpack_internal_module__.hot) {
        __webpack_internal_module__.hot.addStatusHandler((status) => {
          if (status === "idle") {
            setFastRefreshes((i) => i + 1);
          }
        });
      }
    }
  }, []);
  const value = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => ({ fastRefreshes, manualRefreshes, increaseManualRefreshes }), [fastRefreshes, manualRefreshes, increaseManualRefreshes]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FastRefreshContext.Provider, {
    value,
    children
  });
};

// src/helpers/inject-css.ts

var makeDefaultGlobalCSS = () => {
  const unhoveredDragAreaFactor = 2;
  const fromMiddle = 50 / unhoveredDragAreaFactor;
  const hoveredDragAreaFactor = 6;
  const fromMiddleHovered = 50 / hoveredDragAreaFactor;
  return `
  html {
    --remotion-cli-internals-blue: #0b84f3;
    overscroll-behavior-y: none;
    overscroll-behavior-x: none;
  }
  
  body {
    overscroll-behavior-y: none;
    overscroll-behavior-x: none;
    /* Override Chakra UI position: relative on body */
    position: static !important;
  }

  .remotion-splitter {
    user-select: none;
    -webkit-user-select: none;
  }
  
  .remotion-splitter-horizontal {
    transform: scaleY(${unhoveredDragAreaFactor});
    background: linear-gradient(
      to bottom,
      transparent ${50 - fromMiddle}%,
      black ${50 - fromMiddle}%,
      black ${50 + fromMiddle}%,
      transparent ${50 + fromMiddle}%
    );
  }
  
  .remotion-splitter-horizontal.remotion-splitter-active, .remotion-splitter-horizontal.remotion-splitter-hover {
    background: linear-gradient(
      to bottom,
      transparent ${50 - fromMiddleHovered}%,
      var(--remotion-cli-internals-blue) ${50 - fromMiddleHovered}%,
      var(--remotion-cli-internals-blue) ${50 + fromMiddleHovered}%,
      transparent ${50 + fromMiddleHovered}%
    );
    cursor: row-resize;
    transform: scaleY(${hoveredDragAreaFactor});
    z-index: 1000;
  }
  
  .remotion-splitter-vertical {
    transform: scaleX(${unhoveredDragAreaFactor});
    background: linear-gradient(
      to right,
      transparent ${50 - fromMiddle}%,
      black ${50 - fromMiddle}%,
      black ${50 + fromMiddle}%,
      transparent ${50 + fromMiddle}%
    );
  }
  
  .remotion-splitter-vertical.remotion-splitter-active, .remotion-splitter-vertical.remotion-splitter-hover {
    background: linear-gradient(
      to right,
      transparent ${50 - fromMiddleHovered}%,
      var(--remotion-cli-internals-blue) ${50 - fromMiddleHovered}%,
      var(--remotion-cli-internals-blue) ${50 + fromMiddleHovered}%,
      transparent ${50 + fromMiddleHovered}%
    );
    transform: scaleX(${hoveredDragAreaFactor});
    cursor: col-resize;
    z-index: 1000;
  }
  
  input::-webkit-outer-spin-button,
  input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
  }
  
  input:focus,
  textarea:focus,
  button:focus,
  a:focus {
    outline: none;
    box-shadow:
      inset 1px 1px #555,
      inset -1px -1px #555,
      inset 1px -1px #555,
      inset -1px 1px #555;
  }
  
  input[type='color'].__remotion_color_picker::-webkit-color-swatch-wrapper {
    padding: 0;
  }
  input[type='color'].__remotion_color_picker::-webkit-color-swatch {
    border: none;
  }
  
  .__remotion_thumb,
  .__remotion_thumb::-webkit-slider-thumb {
    -webkit-appearance: none;
    -webkit-tap-highlight-color: transparent;
  }
  
  .__remotion_thumb {
    pointer-events: none;
    position: absolute;
    height: 0;
    outline: none;
    top: 15.5px;
    width: 221px;
    margin-left: -2px;
    z-index: 2;
  }
  
  /* For Firefox browsers */
  .__remotion_thumb::-moz-range-thumb {
    border: 1px solid black;
    border-radius: 2px;
    cursor: pointer;
    height: 37px;
    width: 10px;
    pointer-events: all;
    border-color: black;
    background-color: white;
    position: relative;
  }
  
  /* For Chrome browsers */
  .__remotion_thumb::-webkit-slider-thumb {
    border: 1px solid black;
    border-radius: 2px;
    cursor: pointer;
    height: 39px;
    width: 10px;
    pointer-events: all;
    border-color: black;
    background-color: white;
    position: relative;
  }  

  .${DEFAULT_PROPS_PATH_ACTIVE_CLASSNAME} span {
    color: var(--remotion-cli-internals-blue) !important;
    transition: color 0.2s ease-in-out;
  }
  `.trim();
};
var injected = false;
var injectCSS = () => {
  if (injected) {
    return;
  }
  remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CSSUtils.injectCSS(makeDefaultGlobalCSS());
  injected = true;
};

// src/ResolveCompositionConfigInStudio.tsx



var ResolveCompositionConfigInStudio = ({ children }) => {
  const [currentRenderModalComposition, setCurrentRenderModalComposition] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null);
  const { compositions, canvasContent, currentCompositionMetadata } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManager);
  const { fastRefreshes, manualRefreshes } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(FastRefreshContext);
  if (manualRefreshes) {}
  const selectedComposition = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return compositions.find((c) => canvasContent && canvasContent.type === "composition" && canvasContent.compositionId === c.id);
  }, [canvasContent, compositions]);
  const renderModalComposition = compositions.find((c) => c.id === currentRenderModalComposition);
  const { props: allEditorProps } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.EditorPropsContext);
  const env = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.getRemotionEnvironment();
  const inputProps = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return typeof window === "undefined" || env.isPlayer ? {} : (0,remotion__WEBPACK_IMPORTED_MODULE_2__.getInputProps)() ?? {};
  }, [env.isPlayer]);
  const [resolvedConfigs, setResolvedConfigs] = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)({});
  const selectedEditorProps = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return selectedComposition ? allEditorProps[selectedComposition.id] ?? {} : {};
  }, [allEditorProps, selectedComposition]);
  const renderModalProps = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return renderModalComposition ? allEditorProps[renderModalComposition.id] ?? {} : {};
  }, [allEditorProps, renderModalComposition]);
  const hasResolution = Boolean(currentCompositionMetadata);
  const doResolution = (0,react__WEBPACK_IMPORTED_MODULE_0__.useCallback)(({
    calculateMetadata,
    combinedProps,
    compositionDurationInFrames,
    compositionFps,
    compositionHeight,
    compositionId,
    compositionWidth,
    defaultProps
  }) => {
    const controller = new AbortController;
    if (hasResolution) {
      return controller;
    }
    const { signal } = controller;
    const result = remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.resolveVideoConfigOrCatch({
      compositionId,
      calculateMetadata,
      inputProps: combinedProps,
      signal,
      defaultProps,
      compositionDurationInFrames,
      compositionFps,
      compositionHeight,
      compositionWidth
    });
    if (result.type === "error") {
      setResolvedConfigs((r) => ({
        ...r,
        [compositionId]: {
          type: "error",
          error: result.error
        }
      }));
      return controller;
    }
    const promOrNot = result.result;
    if (typeof promOrNot === "object" && "then" in promOrNot) {
      setResolvedConfigs((r) => {
        const prev = r[compositionId];
        if (prev?.type === "success" || prev?.type === "success-and-refreshing") {
          return {
            ...r,
            [compositionId]: {
              type: "success-and-refreshing",
              result: prev.result
            }
          };
        }
        return {
          ...r,
          [compositionId]: {
            type: "loading"
          }
        };
      });
      promOrNot.then((c) => {
        if (controller.signal.aborted) {
          return;
        }
        setResolvedConfigs((r) => ({
          ...r,
          [compositionId]: {
            type: "success",
            result: c
          }
        }));
      }).catch((err) => {
        if (controller.signal.aborted) {
          return;
        }
        setResolvedConfigs((r) => ({
          ...r,
          [compositionId]: {
            type: "error",
            error: err
          }
        }));
      });
    } else {
      setResolvedConfigs((r) => ({
        ...r,
        [compositionId]: {
          type: "success",
          result: promOrNot
        }
      }));
    }
    return controller;
  }, [hasResolution]);
  const currentComposition = canvasContent?.type === "composition" ? canvasContent.compositionId : null;
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useImperativeHandle)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.resolveCompositionsRef, () => {
    return {
      setCurrentRenderModalComposition: (id) => {
        setCurrentRenderModalComposition(id);
      },
      reloadCurrentlySelectedComposition: () => {
        if (!currentComposition) {
          return;
        }
        const composition = compositions.find((c) => c.id === currentComposition);
        if (!composition) {
          throw new Error(`Could not find composition with id ${currentComposition}`);
        }
        const editorProps = allEditorProps[currentComposition] ?? {};
        const defaultProps = {
          ...composition.defaultProps ?? {},
          ...editorProps ?? {}
        };
        const props = {
          ...defaultProps,
          ...inputProps ?? {}
        };
        doResolution({
          defaultProps,
          calculateMetadata: composition.calculateMetadata,
          combinedProps: props,
          compositionDurationInFrames: composition.durationInFrames ?? null,
          compositionFps: composition.fps ?? null,
          compositionHeight: composition.height ?? null,
          compositionWidth: composition.width ?? null,
          compositionId: composition.id
        });
      }
    };
  }, [
    allEditorProps,
    compositions,
    currentComposition,
    doResolution,
    inputProps
  ]);
  const isTheSame = selectedComposition?.id === renderModalComposition?.id;
  const currentDefaultProps = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...selectedComposition?.defaultProps ?? {},
      ...selectedEditorProps ?? {}
    };
  }, [selectedComposition?.defaultProps, selectedEditorProps]);
  const originalProps = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    return {
      ...currentDefaultProps,
      ...inputProps ?? {}
    };
  }, [currentDefaultProps, inputProps]);
  const canResolve = selectedComposition && Boolean(selectedComposition.calculateMetadata);
  const shouldIgnoreUpdate = typeof window !== "undefined" && window.remotion_ignoreFastRefreshUpdate && fastRefreshes <= window.remotion_ignoreFastRefreshUpdate;
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (shouldIgnoreUpdate) {
      return;
    }
    if (canResolve) {
      const controller = doResolution({
        calculateMetadata: selectedComposition.calculateMetadata,
        combinedProps: originalProps,
        compositionDurationInFrames: selectedComposition.durationInFrames ?? null,
        compositionFps: selectedComposition.fps ?? null,
        compositionHeight: selectedComposition.height ?? null,
        compositionWidth: selectedComposition.width ?? null,
        defaultProps: currentDefaultProps,
        compositionId: selectedComposition.id
      });
      return () => {
        controller.abort();
      };
    }
  }, [
    canResolve,
    currentDefaultProps,
    doResolution,
    originalProps,
    selectedComposition?.calculateMetadata,
    selectedComposition?.durationInFrames,
    selectedComposition?.fps,
    selectedComposition?.height,
    selectedComposition?.id,
    selectedComposition?.width,
    shouldIgnoreUpdate
  ]);
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(() => {
    if (renderModalComposition && !isTheSame) {
      const combinedProps = {
        ...renderModalComposition.defaultProps ?? {},
        ...renderModalProps ?? {},
        ...inputProps ?? {}
      };
      const controller = doResolution({
        calculateMetadata: renderModalComposition.calculateMetadata,
        compositionDurationInFrames: renderModalComposition.durationInFrames ?? null,
        compositionFps: renderModalComposition.fps ?? null,
        compositionHeight: renderModalComposition.height ?? null,
        compositionId: renderModalComposition.id,
        compositionWidth: renderModalComposition.width ?? null,
        defaultProps: currentDefaultProps,
        combinedProps
      });
      return () => {
        controller.abort();
      };
    }
  }, [
    currentDefaultProps,
    doResolution,
    inputProps,
    isTheSame,
    renderModalComposition,
    renderModalProps
  ]);
  const resolvedConfigsIncludingStaticOnes = (0,react__WEBPACK_IMPORTED_MODULE_0__.useMemo)(() => {
    const staticComps = compositions.filter((c) => {
      return c.calculateMetadata === null;
    });
    return {
      ...resolvedConfigs,
      ...staticComps.reduce((acc, curr) => {
        return {
          ...acc,
          [curr.id]: {
            type: "success",
            result: { ...curr, defaultProps: curr.defaultProps ?? {} }
          }
        };
      }, {})
    };
  }, [compositions, resolvedConfigs]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.ResolveCompositionContext.Provider, {
    value: resolvedConfigsIncludingStaticOnes,
    children
  });
};

// src/Studio.tsx

var getServerDisconnectedDomElement = () => {
  return document.getElementById("server-disconnected-overlay");
};
var StudioInner = ({ rootComponent, readOnly }) => {
  const { fastRefreshes, manualRefreshes } = (0,react__WEBPACK_IMPORTED_MODULE_0__.useContext)(FastRefreshContext);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.CompositionManagerProvider, {
    onlyRenderComposition: null,
    currentCompositionMetadata: null,
    initialCompositions: [],
    initialCanvasContent: null,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_2__.Internals.RemotionRootContexts, {
      frameState: null,
      audioEnabled: window.remotion_audioEnabled,
      videoEnabled: window.remotion_videoEnabled,
      logLevel: window.remotion_logLevel,
      numberOfAudioTags: window.remotion_numberOfAudioTags,
      audioLatencyHint: window.remotion_audioLatencyHint ?? "interactive",
      nonceContextSeed: fastRefreshes + manualRefreshes,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(StaticFilesProvider, {
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ResolveCompositionConfigInStudio, {
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxs)(EditorContexts, {
            readOnlyStudio: readOnly,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(Editor, {
                readOnlyStudio: readOnly,
                Root: rootComponent
              }),
              readOnly ? null : (0,react_dom__WEBPACK_IMPORTED_MODULE_1__.createPortal)(/* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(ServerDisconnected, {}), getServerDisconnectedDomElement())
            ]
          })
        })
      })
    })
  });
};
var Studio = ({ rootComponent, readOnly }) => {
  (0,react__WEBPACK_IMPORTED_MODULE_0__.useLayoutEffect)(() => {
    injectCSS();
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(FastRefreshProvider, {
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_4__.jsx)(StudioInner, {
      rootComponent,
      readOnly
    })
  });
};

// src/internals.ts
var StudioInternals = {
  Studio
};



/***/ },

/***/ 735
(__unused_webpack_module, exports) {

/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

/**
 * A data structure which is a combination of an array and a set. Adding a new
 * member is O(1), testing for membership is O(1), and finding the index of an
 * element is O(1). Removing elements from the set is not supported. Only
 * strings are supported for membership.
 */
class ArraySet {
  constructor() {
    this._array = [];
    this._set = new Map();
  }

  /**
   * Static method for creating ArraySet instances from an existing array.
   */
  static fromArray(aArray, aAllowDuplicates) {
    const set = new ArraySet();
    for (let i = 0, len = aArray.length; i < len; i++) {
      set.add(aArray[i], aAllowDuplicates);
    }
    return set;
  }

  /**
   * Return how many unique items are in this ArraySet. If duplicates have been
   * added, than those do not count towards the size.
   *
   * @returns Number
   */
  size() {
    return this._set.size;
  }

  /**
   * Add the given string to this set.
   *
   * @param String aStr
   */
  add(aStr, aAllowDuplicates) {
    const isDuplicate = this.has(aStr);
    const idx = this._array.length;
    if (!isDuplicate || aAllowDuplicates) {
      this._array.push(aStr);
    }
    if (!isDuplicate) {
      this._set.set(aStr, idx);
    }
  }

  /**
   * Is the given string a member of this set?
   *
   * @param String aStr
   */
  has(aStr) {
      return this._set.has(aStr);
  }

  /**
   * What is the index of the given string in the array?
   *
   * @param String aStr
   */
  indexOf(aStr) {
    const idx = this._set.get(aStr);
    if (idx >= 0) {
        return idx;
    }
    throw new Error('"' + aStr + '" is not in the set.');
  }

  /**
   * What is the element at the given index?
   *
   * @param Number aIdx
   */
  at(aIdx) {
    if (aIdx >= 0 && aIdx < this._array.length) {
      return this._array[aIdx];
    }
    throw new Error("No element indexed by " + aIdx);
  }

  /**
   * Returns the array representation of this set (which has the proper indices
   * indicated by indexOf). Note that this is a copy of the internal array used
   * for storing the members so that no one can mess with internal state.
   */
  toArray() {
    return this._array.slice();
  }
}
exports.C = ArraySet;


/***/ },

/***/ 7092
(__unused_webpack_module, exports, __webpack_require__) {

/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 *
 * Based on the Base 64 VLQ implementation in Closure Compiler:
 * https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
 *
 * Copyright 2011 The Closure Compiler Authors. All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above
 *    copyright notice, this list of conditions and the following
 *    disclaimer in the documentation and/or other materials provided
 *    with the distribution.
 *  * Neither the name of Google Inc. nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

const base64 = __webpack_require__(2364);

// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
// the next four bits are the actual value, and the 6th bit is the
// continuation bit. The continuation bit tells us whether there are more
// digits in this value following this digit.
//
//   Continuation
//   |    Sign
//   |    |
//   V    V
//   101011

const VLQ_BASE_SHIFT = 5;

// binary: 100000
const VLQ_BASE = 1 << VLQ_BASE_SHIFT;

// binary: 011111
const VLQ_BASE_MASK = VLQ_BASE - 1;

// binary: 100000
const VLQ_CONTINUATION_BIT = VLQ_BASE;

/**
 * Converts from a two-complement value to a value where the sign bit is
 * placed in the least significant bit.  For example, as decimals:
 *   1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
 *   2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
 */
function toVLQSigned(aValue) {
  return aValue < 0
    ? ((-aValue) << 1) + 1
    : (aValue << 1) + 0;
}

/**
 * Converts to a two-complement value from a value where the sign bit is
 * placed in the least significant bit.  For example, as decimals:
 *   2 (10 binary) becomes 1, 3 (11 binary) becomes -1
 *   4 (100 binary) becomes 2, 5 (101 binary) becomes -2
 */
// eslint-disable-next-line no-unused-vars
function fromVLQSigned(aValue) {
  const isNegative = (aValue & 1) === 1;
  const shifted = aValue >> 1;
  return isNegative
    ? -shifted
    : shifted;
}

/**
 * Returns the base 64 VLQ encoded value.
 */
exports.encode = function base64VLQ_encode(aValue) {
  let encoded = "";
  let digit;

  let vlq = toVLQSigned(aValue);

  do {
    digit = vlq & VLQ_BASE_MASK;
    vlq >>>= VLQ_BASE_SHIFT;
    if (vlq > 0) {
      // There are still more digits in this value, so we must make sure the
      // continuation bit is marked.
      digit |= VLQ_CONTINUATION_BIT;
    }
    encoded += base64.encode(digit);
  } while (vlq > 0);

  return encoded;
};


/***/ },

/***/ 2364
(__unused_webpack_module, exports) {

/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

const intToCharMap = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");

/**
 * Encode an integer in the range of 0 to 63 to a single base 64 digit.
 */
exports.encode = function(number) {
  if (0 <= number && number < intToCharMap.length) {
    return intToCharMap[number];
  }
  throw new TypeError("Must be between 0 and 63: " + number);
};


/***/ },

/***/ 1163
(__unused_webpack_module, exports) {

/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

exports.GREATEST_LOWER_BOUND = 1;
exports.LEAST_UPPER_BOUND = 2;

/**
 * Recursive implementation of binary search.
 *
 * @param aLow Indices here and lower do not contain the needle.
 * @param aHigh Indices here and higher do not contain the needle.
 * @param aNeedle The element being searched for.
 * @param aHaystack The non-empty array being searched.
 * @param aCompare Function which takes two elements and returns -1, 0, or 1.
 * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
 *     'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
 *     closest element that is smaller than or greater than the one we are
 *     searching for, respectively, if the exact element cannot be found.
 */
function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) {
  // This function terminates when one of the following is true:
  //
  //   1. We find the exact element we are looking for.
  //
  //   2. We did not find the exact element, but we can return the index of
  //      the next-closest element.
  //
  //   3. We did not find the exact element, and there is no next-closest
  //      element than the one we are searching for, so we return -1.
  const mid = Math.floor((aHigh - aLow) / 2) + aLow;
  const cmp = aCompare(aNeedle, aHaystack[mid], true);
  if (cmp === 0) {
    // Found the element we are looking for.
    return mid;
  } else if (cmp > 0) {
    // Our needle is greater than aHaystack[mid].
    if (aHigh - mid > 1) {
      // The element is in the upper half.
      return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias);
    }

    // The exact needle element was not found in this haystack. Determine if
    // we are in termination case (3) or (2) and return the appropriate thing.
    if (aBias == exports.LEAST_UPPER_BOUND) {
      return aHigh < aHaystack.length ? aHigh : -1;
    }
    return mid;
  }

  // Our needle is less than aHaystack[mid].
  if (mid - aLow > 1) {
    // The element is in the lower half.
    return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias);
  }

  // we are in termination case (3) or (2) and return the appropriate thing.
  if (aBias == exports.LEAST_UPPER_BOUND) {
    return mid;
  }
  return aLow < 0 ? -1 : aLow;
}

/**
 * This is an implementation of binary search which will always try and return
 * the index of the closest element if there is no exact hit. This is because
 * mappings between original and generated line/col pairs are single points,
 * and there is an implicit region between each of them, so a miss just means
 * that you aren't on the very start of a region.
 *
 * @param aNeedle The element you are looking for.
 * @param aHaystack The array that is being searched.
 * @param aCompare A function which takes the needle and an element in the
 *     array and returns -1, 0, or 1 depending on whether the needle is less
 *     than, equal to, or greater than the element, respectively.
 * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or
 *     'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the
 *     closest element that is smaller than or greater than the one we are
 *     searching for, respectively, if the exact element cannot be found.
 *     Defaults to 'binarySearch.GREATEST_LOWER_BOUND'.
 */
exports.search = function search(aNeedle, aHaystack, aCompare, aBias) {
  if (aHaystack.length === 0) {
    return -1;
  }

  let index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack,
                              aCompare, aBias || exports.GREATEST_LOWER_BOUND);
  if (index < 0) {
    return -1;
  }

  // We have found either the exact element, or the next-closest element than
  // the one we are searching for. However, there may be more than one such
  // element. Make sure we always return the smallest of these.
  while (index - 1 >= 0) {
    if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) {
      break;
    }
    --index;
  }

  return index;
};


/***/ },

/***/ 3302
(__unused_webpack_module, exports, __webpack_require__) {

/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2014 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

const util = __webpack_require__(251);

/**
 * Determine whether mappingB is after mappingA with respect to generated
 * position.
 */
function generatedPositionAfter(mappingA, mappingB) {
  // Optimized for most common case
  const lineA = mappingA.generatedLine;
  const lineB = mappingB.generatedLine;
  const columnA = mappingA.generatedColumn;
  const columnB = mappingB.generatedColumn;
  return lineB > lineA || lineB == lineA && columnB >= columnA ||
         util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
}

/**
 * A data structure to provide a sorted view of accumulated mappings in a
 * performance conscious manner. It trades a negligible overhead in general
 * case for a large speedup in case of mappings being added in order.
 */
class MappingList {
  constructor() {
    this._array = [];
    this._sorted = true;
    // Serves as infimum
    this._last = {generatedLine: -1, generatedColumn: 0};
  }

  /**
   * Iterate through internal items. This method takes the same arguments that
   * `Array.prototype.forEach` takes.
   *
   * NOTE: The order of the mappings is NOT guaranteed.
   */
  unsortedForEach(aCallback, aThisArg) {
    this._array.forEach(aCallback, aThisArg);
  }

  /**
   * Add the given source mapping.
   *
   * @param Object aMapping
   */
  add(aMapping) {
    if (generatedPositionAfter(this._last, aMapping)) {
      this._last = aMapping;
      this._array.push(aMapping);
    } else {
      this._sorted = false;
      this._array.push(aMapping);
    }
  }

  /**
   * Returns the flat, sorted array of mappings. The mappings are sorted by
   * generated position.
   *
   * WARNING: This method returns internal data without copying, for
   * performance. The return value must NOT be mutated, and should be treated as
   * an immutable borrow. If you want to take ownership, you must make your own
   * copy.
   */
  toArray() {
    if (!this._sorted) {
      this._array.sort(util.compareByGeneratedPositionsInflated);
      this._sorted = true;
    }
    return this._array;
  }
}

exports.P = MappingList;


/***/ },

/***/ 6576
(module, __unused_webpack_exports, __webpack_require__) {

var __webpack_dirname__ = "/";
if (typeof fetch === "function") {
  // Web version of reading a wasm file into an array buffer.

  let mappingsWasmUrl = null;

  module.exports = function readWasm() {
    if (typeof mappingsWasmUrl !== "string") {
      throw new Error("You must provide the URL of lib/mappings.wasm by calling " +
                      "SourceMapConsumer.initialize({ 'lib/mappings.wasm': ... }) " +
                      "before using SourceMapConsumer");
    }

    return fetch(mappingsWasmUrl)
      .then(response => response.arrayBuffer());
  };

  module.exports.initialize = url => mappingsWasmUrl = url;
} else {
  // Node version of reading a wasm file into an array buffer.
  const fs = __webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module 'fs'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));
  const path = __webpack_require__(Object(function webpackMissingModule() { var e = new Error("Cannot find module 'path'"); e.code = 'MODULE_NOT_FOUND'; throw e; }()));

  module.exports = function readWasm() {
    return new Promise((resolve, reject) => {
      const wasmPath = path.join(__webpack_dirname__, "mappings.wasm");
      fs.readFile(wasmPath, null, (error, data) => {
        if (error) {
          reject(error);
          return;
        }

        resolve(data.buffer);
      });
    });
  };

  module.exports.initialize = _ => {
    console.debug("SourceMapConsumer.initialize is a no-op when running in node.js");
  };
}


/***/ },

/***/ 7446
(__unused_webpack_module, exports, __webpack_require__) {

var __webpack_unused_export__;
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

const util = __webpack_require__(251);
const binarySearch = __webpack_require__(1163);
const ArraySet = (__webpack_require__(735)/* .ArraySet */ .C);
const base64VLQ = __webpack_require__(7092); // eslint-disable-line no-unused-vars
const readWasm = __webpack_require__(6576);
const wasm = __webpack_require__(8991);

const INTERNAL = Symbol("smcInternal");

class SourceMapConsumer {
  constructor(aSourceMap, aSourceMapURL) {
    // If the constructor was called by super(), just return Promise<this>.
    // Yes, this is a hack to retain the pre-existing API of the base-class
    // constructor also being an async factory function.
    if (aSourceMap == INTERNAL) {
      return Promise.resolve(this);
    }

    return _factory(aSourceMap, aSourceMapURL);
  }

  static initialize(opts) {
    readWasm.initialize(opts["lib/mappings.wasm"]);
  }

  static fromSourceMap(aSourceMap, aSourceMapURL) {
    return _factoryBSM(aSourceMap, aSourceMapURL);
  }

  /**
   * Construct a new `SourceMapConsumer` from `rawSourceMap` and `sourceMapUrl`
   * (see the `SourceMapConsumer` constructor for details. Then, invoke the `async
   * function f(SourceMapConsumer) -> T` with the newly constructed consumer, wait
   * for `f` to complete, call `destroy` on the consumer, and return `f`'s return
   * value.
   *
   * You must not use the consumer after `f` completes!
   *
   * By using `with`, you do not have to remember to manually call `destroy` on
   * the consumer, since it will be called automatically once `f` completes.
   *
   * ```js
   * const xSquared = await SourceMapConsumer.with(
   *   myRawSourceMap,
   *   null,
   *   async function (consumer) {
   *     // Use `consumer` inside here and don't worry about remembering
   *     // to call `destroy`.
   *
   *     const x = await whatever(consumer);
   *     return x * x;
   *   }
   * );
   *
   * // You may not use that `consumer` anymore out here; it has
   * // been destroyed. But you can use `xSquared`.
   * console.log(xSquared);
   * ```
   */
  static with(rawSourceMap, sourceMapUrl, f) {
    // Note: The `acorn` version that `webpack` currently depends on doesn't
    // support `async` functions, and the nodes that we support don't all have
    // `.finally`. Therefore, this is written a bit more convolutedly than it
    // should really be.

    let consumer = null;
    const promise = new SourceMapConsumer(rawSourceMap, sourceMapUrl);
    return promise
      .then(c => {
        consumer = c;
        return f(c);
      })
      .then(x => {
        if (consumer) {
          consumer.destroy();
        }
        return x;
      }, e => {
        if (consumer) {
          consumer.destroy();
        }
        throw e;
      });
  }

  /**
   * Parse the mappings in a string in to a data structure which we can easily
   * query (the ordered arrays in the `this.__generatedMappings` and
   * `this.__originalMappings` properties).
   */
  _parseMappings(aStr, aSourceRoot) {
    throw new Error("Subclasses must implement _parseMappings");
  }

  /**
   * Iterate over each mapping between an original source/line/column and a
   * generated line/column in this source map.
   *
   * @param Function aCallback
   *        The function that is called with each mapping.
   * @param Object aContext
   *        Optional. If specified, this object will be the value of `this` every
   *        time that `aCallback` is called.
   * @param aOrder
   *        Either `SourceMapConsumer.GENERATED_ORDER` or
   *        `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to
   *        iterate over the mappings sorted by the generated file's line/column
   *        order or the original's source/line/column order, respectively. Defaults to
   *        `SourceMapConsumer.GENERATED_ORDER`.
   */
  eachMapping(aCallback, aContext, aOrder) {
    throw new Error("Subclasses must implement eachMapping");
  }

  /**
   * Returns all generated line and column information for the original source,
   * line, and column provided. If no column is provided, returns all mappings
   * corresponding to a either the line we are searching for or the next
   * closest line that has any mappings. Otherwise, returns all mappings
   * corresponding to the given line and either the column we are searching for
   * or the next closest column that has any offsets.
   *
   * The only argument is an object with the following properties:
   *
   *   - source: The filename of the original source.
   *   - line: The line number in the original source.  The line number is 1-based.
   *   - column: Optional. the column number in the original source.
   *    The column number is 0-based.
   *
   * and an array of objects is returned, each with the following properties:
   *
   *   - line: The line number in the generated source, or null.  The
   *    line number is 1-based.
   *   - column: The column number in the generated source, or null.
   *    The column number is 0-based.
   */
  allGeneratedPositionsFor(aArgs) {
    throw new Error("Subclasses must implement allGeneratedPositionsFor");
  }

  destroy() {
    throw new Error("Subclasses must implement destroy");
  }
}

/**
 * The version of the source mapping spec that we are consuming.
 */
SourceMapConsumer.prototype._version = 3;
SourceMapConsumer.GENERATED_ORDER = 1;
SourceMapConsumer.ORIGINAL_ORDER = 2;

SourceMapConsumer.GREATEST_LOWER_BOUND = 1;
SourceMapConsumer.LEAST_UPPER_BOUND = 2;

exports.SourceMapConsumer = SourceMapConsumer;

/**
 * A BasicSourceMapConsumer instance represents a parsed source map which we can
 * query for information about the original file positions by giving it a file
 * position in the generated source.
 *
 * The first parameter is the raw source map (either as a JSON string, or
 * already parsed to an object). According to the spec, source maps have the
 * following attributes:
 *
 *   - version: Which version of the source map spec this map is following.
 *   - sources: An array of URLs to the original source files.
 *   - names: An array of identifiers which can be referenced by individual mappings.
 *   - sourceRoot: Optional. The URL root from which all sources are relative.
 *   - sourcesContent: Optional. An array of contents of the original source files.
 *   - mappings: A string of base64 VLQs which contain the actual mappings.
 *   - file: Optional. The generated file this source map is associated with.
 *
 * Here is an example source map, taken from the source map spec[0]:
 *
 *     {
 *       version : 3,
 *       file: "out.js",
 *       sourceRoot : "",
 *       sources: ["foo.js", "bar.js"],
 *       names: ["src", "maps", "are", "fun"],
 *       mappings: "AA,AB;;ABCDE;"
 *     }
 *
 * The second parameter, if given, is a string whose value is the URL
 * at which the source map was found.  This URL is used to compute the
 * sources array.
 *
 * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
 */
class BasicSourceMapConsumer extends SourceMapConsumer {
  constructor(aSourceMap, aSourceMapURL) {
    return super(INTERNAL).then(that => {
      let sourceMap = aSourceMap;
      if (typeof aSourceMap === "string") {
        sourceMap = util.parseSourceMapInput(aSourceMap);
      }

      const version = util.getArg(sourceMap, "version");
      let sources = util.getArg(sourceMap, "sources");
      // Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
      // requires the array) to play nice here.
      const names = util.getArg(sourceMap, "names", []);
      let sourceRoot = util.getArg(sourceMap, "sourceRoot", null);
      const sourcesContent = util.getArg(sourceMap, "sourcesContent", null);
      const mappings = util.getArg(sourceMap, "mappings");
      const file = util.getArg(sourceMap, "file", null);

      // Once again, Sass deviates from the spec and supplies the version as a
      // string rather than a number, so we use loose equality checking here.
      if (version != that._version) {
        throw new Error("Unsupported version: " + version);
      }

      if (sourceRoot) {
        sourceRoot = util.normalize(sourceRoot);
      }

      sources = sources
        .map(String)
        // Some source maps produce relative source paths like "./foo.js" instead of
        // "foo.js".  Normalize these first so that future comparisons will succeed.
        // See bugzil.la/1090768.
        .map(util.normalize)
        // Always ensure that absolute sources are internally stored relative to
        // the source root, if the source root is absolute. Not doing this would
        // be particularly problematic when the source root is a prefix of the
        // source (valid, but why??). See github issue #199 and bugzil.la/1188982.
        .map(function(source) {
          return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source)
            ? util.relative(sourceRoot, source)
            : source;
        });

      // Pass `true` below to allow duplicate names and sources. While source maps
      // are intended to be compressed and deduplicated, the TypeScript compiler
      // sometimes generates source maps with duplicates in them. See Github issue
      // #72 and bugzil.la/889492.
      that._names = ArraySet.fromArray(names.map(String), true);
      that._sources = ArraySet.fromArray(sources, true);

      that._absoluteSources = that._sources.toArray().map(function(s) {
        return util.computeSourceURL(sourceRoot, s, aSourceMapURL);
      });

      that.sourceRoot = sourceRoot;
      that.sourcesContent = sourcesContent;
      that._mappings = mappings;
      that._sourceMapURL = aSourceMapURL;
      that.file = file;

      that._computedColumnSpans = false;
      that._mappingsPtr = 0;
      that._wasm = null;

      return wasm().then(w => {
        that._wasm = w;
        return that;
      });
    });
  }

  /**
   * Utility function to find the index of a source.  Returns -1 if not
   * found.
   */
  _findSourceIndex(aSource) {
    let relativeSource = aSource;
    if (this.sourceRoot != null) {
      relativeSource = util.relative(this.sourceRoot, relativeSource);
    }

    if (this._sources.has(relativeSource)) {
      return this._sources.indexOf(relativeSource);
    }

    // Maybe aSource is an absolute URL as returned by |sources|.  In
    // this case we can't simply undo the transform.
    for (let i = 0; i < this._absoluteSources.length; ++i) {
      if (this._absoluteSources[i] == aSource) {
        return i;
      }
    }

    return -1;
  }

  /**
   * Create a BasicSourceMapConsumer from a SourceMapGenerator.
   *
   * @param SourceMapGenerator aSourceMap
   *        The source map that will be consumed.
   * @param String aSourceMapURL
   *        The URL at which the source map can be found (optional)
   * @returns BasicSourceMapConsumer
   */
  static fromSourceMap(aSourceMap, aSourceMapURL) {
    return new BasicSourceMapConsumer(aSourceMap.toString());
  }

  get sources() {
    return this._absoluteSources.slice();
  }

  _getMappingsPtr() {
    if (this._mappingsPtr === 0) {
      this._parseMappings(this._mappings, this.sourceRoot);
    }

    return this._mappingsPtr;
  }

  /**
   * Parse the mappings in a string in to a data structure which we can easily
   * query (the ordered arrays in the `this.__generatedMappings` and
   * `this.__originalMappings` properties).
   */
  _parseMappings(aStr, aSourceRoot) {
    const size = aStr.length;

    const mappingsBufPtr = this._wasm.exports.allocate_mappings(size);
    const mappingsBuf = new Uint8Array(this._wasm.exports.memory.buffer, mappingsBufPtr, size);
    for (let i = 0; i < size; i++) {
      mappingsBuf[i] = aStr.charCodeAt(i);
    }

    const mappingsPtr = this._wasm.exports.parse_mappings(mappingsBufPtr);

    if (!mappingsPtr) {
      const error = this._wasm.exports.get_last_error();
      let msg = `Error parsing mappings (code ${error}): `;

      // XXX: keep these error codes in sync with `fitzgen/source-map-mappings`.
      switch (error) {
        case 1:
          msg += "the mappings contained a negative line, column, source index, or name index";
          break;
        case 2:
          msg += "the mappings contained a number larger than 2**32";
          break;
        case 3:
          msg += "reached EOF while in the middle of parsing a VLQ";
          break;
        case 4:
          msg += "invalid base 64 character while parsing a VLQ";
          break;
        default:
          msg += "unknown error code";
          break;
      }

      throw new Error(msg);
    }

    this._mappingsPtr = mappingsPtr;
  }

  eachMapping(aCallback, aContext, aOrder) {
    const context = aContext || null;
    const order = aOrder || SourceMapConsumer.GENERATED_ORDER;
    const sourceRoot = this.sourceRoot;

    this._wasm.withMappingCallback(
      mapping => {
        if (mapping.source !== null) {
          mapping.source = this._sources.at(mapping.source);
          mapping.source = util.computeSourceURL(sourceRoot, mapping.source, this._sourceMapURL);

          if (mapping.name !== null) {
            mapping.name = this._names.at(mapping.name);
          }
        }

        aCallback.call(context, mapping);
      },
      () => {
        switch (order) {
        case SourceMapConsumer.GENERATED_ORDER:
          this._wasm.exports.by_generated_location(this._getMappingsPtr());
          break;
        case SourceMapConsumer.ORIGINAL_ORDER:
          this._wasm.exports.by_original_location(this._getMappingsPtr());
          break;
        default:
          throw new Error("Unknown order of iteration.");
        }
      }
    );
  }

  allGeneratedPositionsFor(aArgs) {
    let source = util.getArg(aArgs, "source");
    const originalLine = util.getArg(aArgs, "line");
    const originalColumn = aArgs.column || 0;

    source = this._findSourceIndex(source);
    if (source < 0) {
      return [];
    }

    if (originalLine < 1) {
      throw new Error("Line numbers must be >= 1");
    }

    if (originalColumn < 0) {
      throw new Error("Column numbers must be >= 0");
    }

    const mappings = [];

    this._wasm.withMappingCallback(
      m => {
        let lastColumn = m.lastGeneratedColumn;
        if (this._computedColumnSpans && lastColumn === null) {
          lastColumn = Infinity;
        }
        mappings.push({
          line: m.generatedLine,
          column: m.generatedColumn,
          lastColumn,
        });
      }, () => {
        this._wasm.exports.all_generated_locations_for(
          this._getMappingsPtr(),
          source,
          originalLine - 1,
          "column" in aArgs,
          originalColumn
        );
      }
    );

    return mappings;
  }

  destroy() {
    if (this._mappingsPtr !== 0) {
      this._wasm.exports.free_mappings(this._mappingsPtr);
      this._mappingsPtr = 0;
    }
  }

  /**
   * Compute the last column for each generated mapping. The last column is
   * inclusive.
   */
  computeColumnSpans() {
    if (this._computedColumnSpans) {
      return;
    }

    this._wasm.exports.compute_column_spans(this._getMappingsPtr());
    this._computedColumnSpans = true;
  }

  /**
   * Returns the original source, line, and column information for the generated
   * source's line and column positions provided. The only argument is an object
   * with the following properties:
   *
   *   - line: The line number in the generated source.  The line number
   *     is 1-based.
   *   - column: The column number in the generated source.  The column
   *     number is 0-based.
   *   - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
   *     'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
   *     closest element that is smaller than or greater than the one we are
   *     searching for, respectively, if the exact element cannot be found.
   *     Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
   *
   * and an object is returned with the following properties:
   *
   *   - source: The original source file, or null.
   *   - line: The line number in the original source, or null.  The
   *     line number is 1-based.
   *   - column: The column number in the original source, or null.  The
   *     column number is 0-based.
   *   - name: The original identifier, or null.
   */
  originalPositionFor(aArgs) {
    const needle = {
      generatedLine: util.getArg(aArgs, "line"),
      generatedColumn: util.getArg(aArgs, "column")
    };

    if (needle.generatedLine < 1) {
      throw new Error("Line numbers must be >= 1");
    }

    if (needle.generatedColumn < 0) {
      throw new Error("Column numbers must be >= 0");
    }

    let bias = util.getArg(aArgs, "bias", SourceMapConsumer.GREATEST_LOWER_BOUND);
    if (bias == null) {
      bias = SourceMapConsumer.GREATEST_LOWER_BOUND;
    }

    let mapping;
    this._wasm.withMappingCallback(m => mapping = m, () => {
      this._wasm.exports.original_location_for(
        this._getMappingsPtr(),
        needle.generatedLine - 1,
        needle.generatedColumn,
        bias
      );
    });

    if (mapping) {
      if (mapping.generatedLine === needle.generatedLine) {
        let source = util.getArg(mapping, "source", null);
        if (source !== null) {
          source = this._sources.at(source);
          source = util.computeSourceURL(this.sourceRoot, source, this._sourceMapURL);
        }

        let name = util.getArg(mapping, "name", null);
        if (name !== null) {
          name = this._names.at(name);
        }

        return {
          source,
          line: util.getArg(mapping, "originalLine", null),
          column: util.getArg(mapping, "originalColumn", null),
          name
        };
      }
    }

    return {
      source: null,
      line: null,
      column: null,
      name: null
    };
  }

  /**
   * Return true if we have the source content for every source in the source
   * map, false otherwise.
   */
  hasContentsOfAllSources() {
    if (!this.sourcesContent) {
      return false;
    }
    return this.sourcesContent.length >= this._sources.size() &&
      !this.sourcesContent.some(function(sc) { return sc == null; });
  }

  /**
   * Returns the original source content. The only argument is the url of the
   * original source file. Returns null if no original source content is
   * available.
   */
  sourceContentFor(aSource, nullOnMissing) {
    if (!this.sourcesContent) {
      return null;
    }

    const index = this._findSourceIndex(aSource);
    if (index >= 0) {
      return this.sourcesContent[index];
    }

    let relativeSource = aSource;
    if (this.sourceRoot != null) {
      relativeSource = util.relative(this.sourceRoot, relativeSource);
    }

    let url;
    if (this.sourceRoot != null
        && (url = util.urlParse(this.sourceRoot))) {
      // XXX: file:// URIs and absolute paths lead to unexpected behavior for
      // many users. We can help them out when they expect file:// URIs to
      // behave like it would if they were running a local HTTP server. See
      // https://bugzilla.mozilla.org/show_bug.cgi?id=885597.
      const fileUriAbsPath = relativeSource.replace(/^file:\/\//, "");
      if (url.scheme == "file"
          && this._sources.has(fileUriAbsPath)) {
        return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)];
      }

      if ((!url.path || url.path == "/")
          && this._sources.has("/" + relativeSource)) {
        return this.sourcesContent[this._sources.indexOf("/" + relativeSource)];
      }
    }

    // This function is used recursively from
    // IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we
    // don't want to throw if we can't find the source - we just want to
    // return null, so we provide a flag to exit gracefully.
    if (nullOnMissing) {
      return null;
    }

    throw new Error('"' + relativeSource + '" is not in the SourceMap.');
  }

  /**
   * Returns the generated line and column information for the original source,
   * line, and column positions provided. The only argument is an object with
   * the following properties:
   *
   *   - source: The filename of the original source.
   *   - line: The line number in the original source.  The line number
   *     is 1-based.
   *   - column: The column number in the original source.  The column
   *     number is 0-based.
   *   - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
   *     'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
   *     closest element that is smaller than or greater than the one we are
   *     searching for, respectively, if the exact element cannot be found.
   *     Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
   *
   * and an object is returned with the following properties:
   *
   *   - line: The line number in the generated source, or null.  The
   *     line number is 1-based.
   *   - column: The column number in the generated source, or null.
   *     The column number is 0-based.
   */
  generatedPositionFor(aArgs) {
    let source = util.getArg(aArgs, "source");
    source = this._findSourceIndex(source);
    if (source < 0) {
      return {
        line: null,
        column: null,
        lastColumn: null
      };
    }

    const needle = {
      source,
      originalLine: util.getArg(aArgs, "line"),
      originalColumn: util.getArg(aArgs, "column")
    };

    if (needle.originalLine < 1) {
      throw new Error("Line numbers must be >= 1");
    }

    if (needle.originalColumn < 0) {
      throw new Error("Column numbers must be >= 0");
    }

    let bias = util.getArg(aArgs, "bias", SourceMapConsumer.GREATEST_LOWER_BOUND);
    if (bias == null) {
      bias = SourceMapConsumer.GREATEST_LOWER_BOUND;
    }

    let mapping;
    this._wasm.withMappingCallback(m => mapping = m, () => {
      this._wasm.exports.generated_location_for(
        this._getMappingsPtr(),
        needle.source,
        needle.originalLine - 1,
        needle.originalColumn,
        bias
      );
    });

    if (mapping) {
      if (mapping.source === needle.source) {
        let lastColumn = mapping.lastGeneratedColumn;
        if (this._computedColumnSpans && lastColumn === null) {
          lastColumn = Infinity;
        }
        return {
          line: util.getArg(mapping, "generatedLine", null),
          column: util.getArg(mapping, "generatedColumn", null),
          lastColumn,
        };
      }
    }

    return {
      line: null,
      column: null,
      lastColumn: null
    };
  }
}

BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer;
__webpack_unused_export__ = BasicSourceMapConsumer;

/**
 * An IndexedSourceMapConsumer instance represents a parsed source map which
 * we can query for information. It differs from BasicSourceMapConsumer in
 * that it takes "indexed" source maps (i.e. ones with a "sections" field) as
 * input.
 *
 * The first parameter is a raw source map (either as a JSON string, or already
 * parsed to an object). According to the spec for indexed source maps, they
 * have the following attributes:
 *
 *   - version: Which version of the source map spec this map is following.
 *   - file: Optional. The generated file this source map is associated with.
 *   - sections: A list of section definitions.
 *
 * Each value under the "sections" field has two fields:
 *   - offset: The offset into the original specified at which this section
 *       begins to apply, defined as an object with a "line" and "column"
 *       field.
 *   - map: A source map definition. This source map could also be indexed,
 *       but doesn't have to be.
 *
 * Instead of the "map" field, it's also possible to have a "url" field
 * specifying a URL to retrieve a source map from, but that's currently
 * unsupported.
 *
 * Here's an example source map, taken from the source map spec[0], but
 * modified to omit a section which uses the "url" field.
 *
 *  {
 *    version : 3,
 *    file: "app.js",
 *    sections: [{
 *      offset: {line:100, column:10},
 *      map: {
 *        version : 3,
 *        file: "section.js",
 *        sources: ["foo.js", "bar.js"],
 *        names: ["src", "maps", "are", "fun"],
 *        mappings: "AAAA,E;;ABCDE;"
 *      }
 *    }],
 *  }
 *
 * The second parameter, if given, is a string whose value is the URL
 * at which the source map was found.  This URL is used to compute the
 * sources array.
 *
 * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
 */
class IndexedSourceMapConsumer extends SourceMapConsumer {
  constructor(aSourceMap, aSourceMapURL) {
    return super(INTERNAL).then(that => {
      let sourceMap = aSourceMap;
      if (typeof aSourceMap === "string") {
        sourceMap = util.parseSourceMapInput(aSourceMap);
      }

      const version = util.getArg(sourceMap, "version");
      const sections = util.getArg(sourceMap, "sections");

      if (version != that._version) {
        throw new Error("Unsupported version: " + version);
      }

      that._sources = new ArraySet();
      that._names = new ArraySet();
      that.__generatedMappings = null;
      that.__originalMappings = null;
      that.__generatedMappingsUnsorted = null;
      that.__originalMappingsUnsorted = null;

      let lastOffset = {
        line: -1,
        column: 0
      };
      return Promise.all(sections.map(s => {
        if (s.url) {
          // The url field will require support for asynchronicity.
          // See https://github.com/mozilla/source-map/issues/16
          throw new Error("Support for url field in sections not implemented.");
        }
        const offset = util.getArg(s, "offset");
        const offsetLine = util.getArg(offset, "line");
        const offsetColumn = util.getArg(offset, "column");

        if (offsetLine < lastOffset.line ||
            (offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {
          throw new Error("Section offsets must be ordered and non-overlapping.");
        }
        lastOffset = offset;

        const cons = new SourceMapConsumer(util.getArg(s, "map"), aSourceMapURL);
        return cons.then(consumer => {
          return {
            generatedOffset: {
              // The offset fields are 0-based, but we use 1-based indices when
              // encoding/decoding from VLQ.
              generatedLine: offsetLine + 1,
              generatedColumn: offsetColumn + 1
            },
            consumer
          };
        });
      })).then(s => {
        that._sections = s;
        return that;
      });
    });
  }

  // `__generatedMappings` and `__originalMappings` are arrays that hold the
  // parsed mapping coordinates from the source map's "mappings" attribute. They
  // are lazily instantiated, accessed via the `_generatedMappings` and
  // `_originalMappings` getters respectively, and we only parse the mappings
  // and create these arrays once queried for a source location. We jump through
  // these hoops because there can be many thousands of mappings, and parsing
  // them is expensive, so we only want to do it if we must.
  //
  // Each object in the arrays is of the form:
  //
  //     {
  //       generatedLine: The line number in the generated code,
  //       generatedColumn: The column number in the generated code,
  //       source: The path to the original source file that generated this
  //               chunk of code,
  //       originalLine: The line number in the original source that
  //                     corresponds to this chunk of generated code,
  //       originalColumn: The column number in the original source that
  //                       corresponds to this chunk of generated code,
  //       name: The name of the original symbol which generated this chunk of
  //             code.
  //     }
  //
  // All properties except for `generatedLine` and `generatedColumn` can be
  // `null`.
  //
  // `_generatedMappings` is ordered by the generated positions.
  //
  // `_originalMappings` is ordered by the original positions.
  get _generatedMappings() {
    if (!this.__generatedMappings) {
      this._sortGeneratedMappings();
    }

    return this.__generatedMappings;
  }

  get _originalMappings() {
    if (!this.__originalMappings) {
      this._sortOriginalMappings();
    }

    return this.__originalMappings;
  }

  get _generatedMappingsUnsorted() {
    if (!this.__generatedMappingsUnsorted) {
      this._parseMappings(this._mappings, this.sourceRoot);
    }

    return this.__generatedMappingsUnsorted;
  }

  get _originalMappingsUnsorted() {
    if (!this.__originalMappingsUnsorted) {
      this._parseMappings(this._mappings, this.sourceRoot);
    }

    return this.__originalMappingsUnsorted;
  }

  _sortGeneratedMappings() {
    const mappings = this._generatedMappingsUnsorted;
    mappings.sort(util.compareByGeneratedPositionsDeflated);
    this.__generatedMappings = mappings;
  }

  _sortOriginalMappings() {
    const mappings = this._originalMappingsUnsorted;
    mappings.sort(util.compareByOriginalPositions);
    this.__originalMappings = mappings;
  }

  /**
   * The list of original sources.
   */
  get sources() {
    const sources = [];
    for (let i = 0; i < this._sections.length; i++) {
      for (let j = 0; j < this._sections[i].consumer.sources.length; j++) {
        sources.push(this._sections[i].consumer.sources[j]);
      }
    }
    return sources;
  }

  /**
   * Returns the original source, line, and column information for the generated
   * source's line and column positions provided. The only argument is an object
   * with the following properties:
   *
   *   - line: The line number in the generated source.  The line number
   *     is 1-based.
   *   - column: The column number in the generated source.  The column
   *     number is 0-based.
   *
   * and an object is returned with the following properties:
   *
   *   - source: The original source file, or null.
   *   - line: The line number in the original source, or null.  The
   *     line number is 1-based.
   *   - column: The column number in the original source, or null.  The
   *     column number is 0-based.
   *   - name: The original identifier, or null.
   */
  originalPositionFor(aArgs) {
    const needle = {
      generatedLine: util.getArg(aArgs, "line"),
      generatedColumn: util.getArg(aArgs, "column")
    };

    // Find the section containing the generated position we're trying to map
    // to an original position.
    const sectionIndex = binarySearch.search(needle, this._sections,
      function(aNeedle, section) {
        const cmp = aNeedle.generatedLine - section.generatedOffset.generatedLine;
        if (cmp) {
          return cmp;
        }

        return (aNeedle.generatedColumn -
                section.generatedOffset.generatedColumn);
      });
    const section = this._sections[sectionIndex];

    if (!section) {
      return {
        source: null,
        line: null,
        column: null,
        name: null
      };
    }

    return section.consumer.originalPositionFor({
      line: needle.generatedLine -
        (section.generatedOffset.generatedLine - 1),
      column: needle.generatedColumn -
        (section.generatedOffset.generatedLine === needle.generatedLine
         ? section.generatedOffset.generatedColumn - 1
         : 0),
      bias: aArgs.bias
    });
  }

  /**
   * Return true if we have the source content for every source in the source
   * map, false otherwise.
   */
  hasContentsOfAllSources() {
    return this._sections.every(function(s) {
      return s.consumer.hasContentsOfAllSources();
    });
  }

  /**
   * Returns the original source content. The only argument is the url of the
   * original source file. Returns null if no original source content is
   * available.
   */
  sourceContentFor(aSource, nullOnMissing) {
    for (let i = 0; i < this._sections.length; i++) {
      const section = this._sections[i];

      const content = section.consumer.sourceContentFor(aSource, true);
      if (content) {
        return content;
      }
    }
    if (nullOnMissing) {
      return null;
    }
    throw new Error('"' + aSource + '" is not in the SourceMap.');
  }

  /**
   * Returns the generated line and column information for the original source,
   * line, and column positions provided. The only argument is an object with
   * the following properties:
   *
   *   - source: The filename of the original source.
   *   - line: The line number in the original source.  The line number
   *     is 1-based.
   *   - column: The column number in the original source.  The column
   *     number is 0-based.
   *
   * and an object is returned with the following properties:
   *
   *   - line: The line number in the generated source, or null.  The
   *     line number is 1-based.
   *   - column: The column number in the generated source, or null.
   *     The column number is 0-based.
   */
  generatedPositionFor(aArgs) {
    for (let i = 0; i < this._sections.length; i++) {
      const section = this._sections[i];

      // Only consider this section if the requested source is in the list of
      // sources of the consumer.
      if (section.consumer._findSourceIndex(util.getArg(aArgs, "source")) === -1) {
        continue;
      }
      const generatedPosition = section.consumer.generatedPositionFor(aArgs);
      if (generatedPosition) {
        const ret = {
          line: generatedPosition.line +
            (section.generatedOffset.generatedLine - 1),
          column: generatedPosition.column +
            (section.generatedOffset.generatedLine === generatedPosition.line
             ? section.generatedOffset.generatedColumn - 1
             : 0)
        };
        return ret;
      }
    }

    return {
      line: null,
      column: null
    };
  }

  /**
   * Parse the mappings in a string in to a data structure which we can easily
   * query (the ordered arrays in the `this.__generatedMappings` and
   * `this.__originalMappings` properties).
   */
  _parseMappings(aStr, aSourceRoot) {
    const generatedMappings = this.__generatedMappingsUnsorted = [];
    const originalMappings = this.__originalMappingsUnsorted = [];
    for (let i = 0; i < this._sections.length; i++) {
      const section = this._sections[i];

      const sectionMappings = [];
      section.consumer.eachMapping(m => sectionMappings.push(m));

      for (let j = 0; j < sectionMappings.length; j++) {
        const mapping = sectionMappings[j];

        // TODO: test if null is correct here.  The original code used
        // `source`, which would actually have gotten used as null because
        // var's get hoisted.
        // See: https://github.com/mozilla/source-map/issues/333
        let source = util.computeSourceURL(section.consumer.sourceRoot, null, this._sourceMapURL);
        this._sources.add(source);
        source = this._sources.indexOf(source);

        let name = null;
        if (mapping.name) {
          this._names.add(mapping.name);
          name = this._names.indexOf(mapping.name);
        }

        // The mappings coming from the consumer for the section have
        // generated positions relative to the start of the section, so we
        // need to offset them to be relative to the start of the concatenated
        // generated file.
        const adjustedMapping = {
          source,
          generatedLine: mapping.generatedLine +
            (section.generatedOffset.generatedLine - 1),
          generatedColumn: mapping.generatedColumn +
            (section.generatedOffset.generatedLine === mapping.generatedLine
            ? section.generatedOffset.generatedColumn - 1
            : 0),
          originalLine: mapping.originalLine,
          originalColumn: mapping.originalColumn,
          name
        };

        generatedMappings.push(adjustedMapping);
        if (typeof adjustedMapping.originalLine === "number") {
          originalMappings.push(adjustedMapping);
        }
      }
    }
  }

  eachMapping(aCallback, aContext, aOrder) {
    const context = aContext || null;
    const order = aOrder || SourceMapConsumer.GENERATED_ORDER;

    let mappings;
    switch (order) {
    case SourceMapConsumer.GENERATED_ORDER:
      mappings = this._generatedMappings;
      break;
    case SourceMapConsumer.ORIGINAL_ORDER:
      mappings = this._originalMappings;
      break;
    default:
      throw new Error("Unknown order of iteration.");
    }

    const sourceRoot = this.sourceRoot;
    mappings.map(function(mapping) {
      let source = null;
      if (mapping.source !== null) {
        source = this._sources.at(mapping.source);
        source = util.computeSourceURL(sourceRoot, source, this._sourceMapURL);
      }
      return {
        source,
        generatedLine: mapping.generatedLine,
        generatedColumn: mapping.generatedColumn,
        originalLine: mapping.originalLine,
        originalColumn: mapping.originalColumn,
        name: mapping.name === null ? null : this._names.at(mapping.name)
      };
    }, this).forEach(aCallback, context);
  }

  /**
   * Find the mapping that best matches the hypothetical "needle" mapping that
   * we are searching for in the given "haystack" of mappings.
   */
  _findMapping(aNeedle, aMappings, aLineName,
              aColumnName, aComparator, aBias) {
    // To return the position we are searching for, we must first find the
    // mapping for the given position and then return the opposite position it
    // points to. Because the mappings are sorted, we can use binary search to
    // find the best mapping.

    if (aNeedle[aLineName] <= 0) {
      throw new TypeError("Line must be greater than or equal to 1, got "
                          + aNeedle[aLineName]);
    }
    if (aNeedle[aColumnName] < 0) {
      throw new TypeError("Column must be greater than or equal to 0, got "
                          + aNeedle[aColumnName]);
    }

    return binarySearch.search(aNeedle, aMappings, aComparator, aBias);
  }

  allGeneratedPositionsFor(aArgs) {
    const line = util.getArg(aArgs, "line");

    // When there is no exact match, BasicSourceMapConsumer.prototype._findMapping
    // returns the index of the closest mapping less than the needle. By
    // setting needle.originalColumn to 0, we thus find the last mapping for
    // the given line, provided such a mapping exists.
    const needle = {
      source: util.getArg(aArgs, "source"),
      originalLine: line,
      originalColumn: util.getArg(aArgs, "column", 0)
    };

    needle.source = this._findSourceIndex(needle.source);
    if (needle.source < 0) {
      return [];
    }

    if (needle.originalLine < 1) {
      throw new Error("Line numbers must be >= 1");
    }

    if (needle.originalColumn < 0) {
      throw new Error("Column numbers must be >= 0");
    }

    const mappings = [];

    let index = this._findMapping(needle,
                                  this._originalMappings,
                                  "originalLine",
                                  "originalColumn",
                                  util.compareByOriginalPositions,
                                  binarySearch.LEAST_UPPER_BOUND);
    if (index >= 0) {
      let mapping = this._originalMappings[index];

      if (aArgs.column === undefined) {
        const originalLine = mapping.originalLine;

        // Iterate until either we run out of mappings, or we run into
        // a mapping for a different line than the one we found. Since
        // mappings are sorted, this is guaranteed to find all mappings for
        // the line we found.
        while (mapping && mapping.originalLine === originalLine) {
          let lastColumn = mapping.lastGeneratedColumn;
          if (this._computedColumnSpans && lastColumn === null) {
            lastColumn = Infinity;
          }
          mappings.push({
            line: util.getArg(mapping, "generatedLine", null),
            column: util.getArg(mapping, "generatedColumn", null),
            lastColumn,
          });

          mapping = this._originalMappings[++index];
        }
      } else {
        const originalColumn = mapping.originalColumn;

        // Iterate until either we run out of mappings, or we run into
        // a mapping for a different line than the one we were searching for.
        // Since mappings are sorted, this is guaranteed to find all mappings for
        // the line we are searching for.
        while (mapping &&
               mapping.originalLine === line &&
               mapping.originalColumn == originalColumn) {
          let lastColumn = mapping.lastGeneratedColumn;
          if (this._computedColumnSpans && lastColumn === null) {
            lastColumn = Infinity;
          }
          mappings.push({
            line: util.getArg(mapping, "generatedLine", null),
            column: util.getArg(mapping, "generatedColumn", null),
            lastColumn,
          });

          mapping = this._originalMappings[++index];
        }
      }
    }

    return mappings;
  }

  destroy() {
    for (let i = 0; i < this._sections.length; i++) {
      this._sections[i].consumer.destroy();
    }
  }
}
__webpack_unused_export__ = IndexedSourceMapConsumer;

/*
 * Cheat to get around inter-twingled classes.  `factory()` can be at the end
 * where it has access to non-hoisted classes, but it gets hoisted itself.
 */
function _factory(aSourceMap, aSourceMapURL) {
  let sourceMap = aSourceMap;
  if (typeof aSourceMap === "string") {
    sourceMap = util.parseSourceMapInput(aSourceMap);
  }

  const consumer = sourceMap.sections != null
      ? new IndexedSourceMapConsumer(sourceMap, aSourceMapURL)
      : new BasicSourceMapConsumer(sourceMap, aSourceMapURL);
  return Promise.resolve(consumer);
}

function _factoryBSM(aSourceMap, aSourceMapURL) {
  return BasicSourceMapConsumer.fromSourceMap(aSourceMap, aSourceMapURL);
}


/***/ },

/***/ 4041
(__unused_webpack_module, exports, __webpack_require__) {

/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

const base64VLQ = __webpack_require__(7092);
const util = __webpack_require__(251);
const ArraySet = (__webpack_require__(735)/* .ArraySet */ .C);
const MappingList = (__webpack_require__(3302)/* .MappingList */ .P);

/**
 * An instance of the SourceMapGenerator represents a source map which is
 * being built incrementally. You may pass an object with the following
 * properties:
 *
 *   - file: The filename of the generated source.
 *   - sourceRoot: A root for all relative URLs in this source map.
 */
class SourceMapGenerator {
  constructor(aArgs) {
    if (!aArgs) {
      aArgs = {};
    }
    this._file = util.getArg(aArgs, "file", null);
    this._sourceRoot = util.getArg(aArgs, "sourceRoot", null);
    this._skipValidation = util.getArg(aArgs, "skipValidation", false);
    this._sources = new ArraySet();
    this._names = new ArraySet();
    this._mappings = new MappingList();
    this._sourcesContents = null;
  }

  /**
   * Creates a new SourceMapGenerator based on a SourceMapConsumer
   *
   * @param aSourceMapConsumer The SourceMap.
   */
  static fromSourceMap(aSourceMapConsumer) {
    const sourceRoot = aSourceMapConsumer.sourceRoot;
    const generator = new SourceMapGenerator({
      file: aSourceMapConsumer.file,
      sourceRoot
    });
    aSourceMapConsumer.eachMapping(function(mapping) {
      const newMapping = {
        generated: {
          line: mapping.generatedLine,
          column: mapping.generatedColumn
        }
      };

      if (mapping.source != null) {
        newMapping.source = mapping.source;
        if (sourceRoot != null) {
          newMapping.source = util.relative(sourceRoot, newMapping.source);
        }

        newMapping.original = {
          line: mapping.originalLine,
          column: mapping.originalColumn
        };

        if (mapping.name != null) {
          newMapping.name = mapping.name;
        }
      }

      generator.addMapping(newMapping);
    });
    aSourceMapConsumer.sources.forEach(function(sourceFile) {
      let sourceRelative = sourceFile;
      if (sourceRoot !== null) {
        sourceRelative = util.relative(sourceRoot, sourceFile);
      }

      if (!generator._sources.has(sourceRelative)) {
        generator._sources.add(sourceRelative);
      }

      const content = aSourceMapConsumer.sourceContentFor(sourceFile);
      if (content != null) {
        generator.setSourceContent(sourceFile, content);
      }
    });
    return generator;
  }

  /**
   * Add a single mapping from original source line and column to the generated
   * source's line and column for this source map being created. The mapping
   * object should have the following properties:
   *
   *   - generated: An object with the generated line and column positions.
   *   - original: An object with the original line and column positions.
   *   - source: The original source file (relative to the sourceRoot).
   *   - name: An optional original token name for this mapping.
   */
  addMapping(aArgs) {
    const generated = util.getArg(aArgs, "generated");
    const original = util.getArg(aArgs, "original", null);
    let source = util.getArg(aArgs, "source", null);
    let name = util.getArg(aArgs, "name", null);

    if (!this._skipValidation) {
      this._validateMapping(generated, original, source, name);
    }

    if (source != null) {
      source = String(source);
      if (!this._sources.has(source)) {
        this._sources.add(source);
      }
    }

    if (name != null) {
      name = String(name);
      if (!this._names.has(name)) {
        this._names.add(name);
      }
    }

    this._mappings.add({
      generatedLine: generated.line,
      generatedColumn: generated.column,
      originalLine: original != null && original.line,
      originalColumn: original != null && original.column,
      source,
      name
    });
  }

  /**
   * Set the source content for a source file.
   */
  setSourceContent(aSourceFile, aSourceContent) {
    let source = aSourceFile;
    if (this._sourceRoot != null) {
      source = util.relative(this._sourceRoot, source);
    }

    if (aSourceContent != null) {
      // Add the source content to the _sourcesContents map.
      // Create a new _sourcesContents map if the property is null.
      if (!this._sourcesContents) {
        this._sourcesContents = Object.create(null);
      }
      this._sourcesContents[util.toSetString(source)] = aSourceContent;
    } else if (this._sourcesContents) {
      // Remove the source file from the _sourcesContents map.
      // If the _sourcesContents map is empty, set the property to null.
      delete this._sourcesContents[util.toSetString(source)];
      if (Object.keys(this._sourcesContents).length === 0) {
        this._sourcesContents = null;
      }
    }
  }

  /**
   * Applies the mappings of a sub-source-map for a specific source file to the
   * source map being generated. Each mapping to the supplied source file is
   * rewritten using the supplied source map. Note: The resolution for the
   * resulting mappings is the minimium of this map and the supplied map.
   *
   * @param aSourceMapConsumer The source map to be applied.
   * @param aSourceFile Optional. The filename of the source file.
   *        If omitted, SourceMapConsumer's file property will be used.
   * @param aSourceMapPath Optional. The dirname of the path to the source map
   *        to be applied. If relative, it is relative to the SourceMapConsumer.
   *        This parameter is needed when the two source maps aren't in the same
   *        directory, and the source map to be applied contains relative source
   *        paths. If so, those relative source paths need to be rewritten
   *        relative to the SourceMapGenerator.
   */
  applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
    let sourceFile = aSourceFile;
    // If aSourceFile is omitted, we will use the file property of the SourceMap
    if (aSourceFile == null) {
      if (aSourceMapConsumer.file == null) {
        throw new Error(
          "SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, " +
          'or the source map\'s "file" property. Both were omitted.'
        );
      }
      sourceFile = aSourceMapConsumer.file;
    }
    const sourceRoot = this._sourceRoot;
    // Make "sourceFile" relative if an absolute Url is passed.
    if (sourceRoot != null) {
      sourceFile = util.relative(sourceRoot, sourceFile);
    }
    // Applying the SourceMap can add and remove items from the sources and
    // the names array.
    const newSources = this._mappings.toArray().length > 0
      ? new ArraySet()
      : this._sources;
    const newNames = new ArraySet();

    // Find mappings for the "sourceFile"
    this._mappings.unsortedForEach(function(mapping) {
      if (mapping.source === sourceFile && mapping.originalLine != null) {
        // Check if it can be mapped by the source map, then update the mapping.
        const original = aSourceMapConsumer.originalPositionFor({
          line: mapping.originalLine,
          column: mapping.originalColumn
        });
        if (original.source != null) {
          // Copy mapping
          mapping.source = original.source;
          if (aSourceMapPath != null) {
            mapping.source = util.join(aSourceMapPath, mapping.source);
          }
          if (sourceRoot != null) {
            mapping.source = util.relative(sourceRoot, mapping.source);
          }
          mapping.originalLine = original.line;
          mapping.originalColumn = original.column;
          if (original.name != null) {
            mapping.name = original.name;
          }
        }
      }

      const source = mapping.source;
      if (source != null && !newSources.has(source)) {
        newSources.add(source);
      }

      const name = mapping.name;
      if (name != null && !newNames.has(name)) {
        newNames.add(name);
      }

    }, this);
    this._sources = newSources;
    this._names = newNames;

    // Copy sourcesContents of applied map.
    aSourceMapConsumer.sources.forEach(function(srcFile) {
      const content = aSourceMapConsumer.sourceContentFor(srcFile);
      if (content != null) {
        if (aSourceMapPath != null) {
          srcFile = util.join(aSourceMapPath, srcFile);
        }
        if (sourceRoot != null) {
          srcFile = util.relative(sourceRoot, srcFile);
        }
        this.setSourceContent(srcFile, content);
      }
    }, this);
  }

  /**
   * A mapping can have one of the three levels of data:
   *
   *   1. Just the generated position.
   *   2. The Generated position, original position, and original source.
   *   3. Generated and original position, original source, as well as a name
   *      token.
   *
   * To maintain consistency, we validate that any new mapping being added falls
   * in to one of these categories.
   */
  _validateMapping(aGenerated, aOriginal, aSource, aName) {
    // When aOriginal is truthy but has empty values for .line and .column,
    // it is most likely a programmer error. In this case we throw a very
    // specific error message to try to guide them the right way.
    // For example: https://github.com/Polymer/polymer-bundler/pull/519
    if (aOriginal && typeof aOriginal.line !== "number" && typeof aOriginal.column !== "number") {
        throw new Error(
            "original.line and original.column are not numbers -- you probably meant to omit " +
            "the original mapping entirely and only map the generated position. If so, pass " +
            "null for the original mapping instead of an object with empty or null values."
        );
    }

    if (aGenerated && "line" in aGenerated && "column" in aGenerated
        && aGenerated.line > 0 && aGenerated.column >= 0
        && !aOriginal && !aSource && !aName) {
      // Case 1.

    } else if (aGenerated && "line" in aGenerated && "column" in aGenerated
             && aOriginal && "line" in aOriginal && "column" in aOriginal
             && aGenerated.line > 0 && aGenerated.column >= 0
             && aOriginal.line > 0 && aOriginal.column >= 0
             && aSource) {
      // Cases 2 and 3.

    } else {
      throw new Error("Invalid mapping: " + JSON.stringify({
        generated: aGenerated,
        source: aSource,
        original: aOriginal,
        name: aName
      }));
    }
  }

  /**
   * Serialize the accumulated mappings in to the stream of base 64 VLQs
   * specified by the source map format.
   */
  _serializeMappings() {
    let previousGeneratedColumn = 0;
    let previousGeneratedLine = 1;
    let previousOriginalColumn = 0;
    let previousOriginalLine = 0;
    let previousName = 0;
    let previousSource = 0;
    let result = "";
    let next;
    let mapping;
    let nameIdx;
    let sourceIdx;

    const mappings = this._mappings.toArray();
    for (let i = 0, len = mappings.length; i < len; i++) {
      mapping = mappings[i];
      next = "";

      if (mapping.generatedLine !== previousGeneratedLine) {
        previousGeneratedColumn = 0;
        while (mapping.generatedLine !== previousGeneratedLine) {
          next += ";";
          previousGeneratedLine++;
        }
      } else if (i > 0) {
        if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
          continue;
        }
        next += ",";
      }

      next += base64VLQ.encode(mapping.generatedColumn
                                 - previousGeneratedColumn);
      previousGeneratedColumn = mapping.generatedColumn;

      if (mapping.source != null) {
        sourceIdx = this._sources.indexOf(mapping.source);
        next += base64VLQ.encode(sourceIdx - previousSource);
        previousSource = sourceIdx;

        // lines are stored 0-based in SourceMap spec version 3
        next += base64VLQ.encode(mapping.originalLine - 1
                                   - previousOriginalLine);
        previousOriginalLine = mapping.originalLine - 1;

        next += base64VLQ.encode(mapping.originalColumn
                                   - previousOriginalColumn);
        previousOriginalColumn = mapping.originalColumn;

        if (mapping.name != null) {
          nameIdx = this._names.indexOf(mapping.name);
          next += base64VLQ.encode(nameIdx - previousName);
          previousName = nameIdx;
        }
      }

      result += next;
    }

    return result;
  }

  _generateSourcesContent(aSources, aSourceRoot) {
    return aSources.map(function(source) {
      if (!this._sourcesContents) {
        return null;
      }
      if (aSourceRoot != null) {
        source = util.relative(aSourceRoot, source);
      }
      const key = util.toSetString(source);
      return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
        ? this._sourcesContents[key]
        : null;
    }, this);
  }

  /**
   * Externalize the source map.
   */
  toJSON() {
    const map = {
      version: this._version,
      sources: this._sources.toArray(),
      names: this._names.toArray(),
      mappings: this._serializeMappings()
    };
    if (this._file != null) {
      map.file = this._file;
    }
    if (this._sourceRoot != null) {
      map.sourceRoot = this._sourceRoot;
    }
    if (this._sourcesContents) {
      map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
    }

    return map;
  }

  /**
   * Render the source map being generated to a string.
   */
  toString() {
    return JSON.stringify(this.toJSON());
  }
}

SourceMapGenerator.prototype._version = 3;
exports.x = SourceMapGenerator;


/***/ },

/***/ 1683
(__unused_webpack_module, exports, __webpack_require__) {

var __webpack_unused_export__;
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

const SourceMapGenerator = (__webpack_require__(4041)/* .SourceMapGenerator */ .x);
const util = __webpack_require__(251);

// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
// operating systems these days (capturing the result).
const REGEX_NEWLINE = /(\r?\n)/;

// Newline character code for charCodeAt() comparisons
const NEWLINE_CODE = 10;

// Private symbol for identifying `SourceNode`s when multiple versions of
// the source-map library are loaded. This MUST NOT CHANGE across
// versions!
const isSourceNode = "$$$isSourceNode$$$";

/**
 * SourceNodes provide a way to abstract over interpolating/concatenating
 * snippets of generated JavaScript source code while maintaining the line and
 * column information associated with the original source code.
 *
 * @param aLine The original line number.
 * @param aColumn The original column number.
 * @param aSource The original source's filename.
 * @param aChunks Optional. An array of strings which are snippets of
 *        generated JS, or other SourceNodes.
 * @param aName The original identifier.
 */
class SourceNode {
  constructor(aLine, aColumn, aSource, aChunks, aName) {
    this.children = [];
    this.sourceContents = {};
    this.line = aLine == null ? null : aLine;
    this.column = aColumn == null ? null : aColumn;
    this.source = aSource == null ? null : aSource;
    this.name = aName == null ? null : aName;
    this[isSourceNode] = true;
    if (aChunks != null) this.add(aChunks);
  }

  /**
   * Creates a SourceNode from generated code and a SourceMapConsumer.
   *
   * @param aGeneratedCode The generated code
   * @param aSourceMapConsumer The SourceMap for the generated code
   * @param aRelativePath Optional. The path that relative sources in the
   *        SourceMapConsumer should be relative to.
   */
  static fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) {
    // The SourceNode we want to fill with the generated code
    // and the SourceMap
    const node = new SourceNode();

    // All even indices of this array are one line of the generated code,
    // while all odd indices are the newlines between two adjacent lines
    // (since `REGEX_NEWLINE` captures its match).
    // Processed fragments are accessed by calling `shiftNextLine`.
    const remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
    let remainingLinesIndex = 0;
    const shiftNextLine = function() {
      const lineContents = getNextLine();
      // The last line of a file might not have a newline.
      const newLine = getNextLine() || "";
      return lineContents + newLine;

      function getNextLine() {
        return remainingLinesIndex < remainingLines.length ?
            remainingLines[remainingLinesIndex++] : undefined;
      }
    };

    // We need to remember the position of "remainingLines"
    let lastGeneratedLine = 1, lastGeneratedColumn = 0;

    // The generate SourceNodes we need a code range.
    // To extract it current and last mapping is used.
    // Here we store the last mapping.
    let lastMapping = null;
    let nextLine;

    aSourceMapConsumer.eachMapping(function(mapping) {
      if (lastMapping !== null) {
        // We add the code from "lastMapping" to "mapping":
        // First check if there is a new line in between.
        if (lastGeneratedLine < mapping.generatedLine) {
          // Associate first line with "lastMapping"
          addMappingWithCode(lastMapping, shiftNextLine());
          lastGeneratedLine++;
          lastGeneratedColumn = 0;
          // The remaining code is added without mapping
        } else {
          // There is no new line in between.
          // Associate the code between "lastGeneratedColumn" and
          // "mapping.generatedColumn" with "lastMapping"
          nextLine = remainingLines[remainingLinesIndex] || "";
          const code = nextLine.substr(0, mapping.generatedColumn -
                                        lastGeneratedColumn);
          remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn -
                                              lastGeneratedColumn);
          lastGeneratedColumn = mapping.generatedColumn;
          addMappingWithCode(lastMapping, code);
          // No more remaining code, continue
          lastMapping = mapping;
          return;
        }
      }
      // We add the generated code until the first mapping
      // to the SourceNode without any mapping.
      // Each line is added as separate string.
      while (lastGeneratedLine < mapping.generatedLine) {
        node.add(shiftNextLine());
        lastGeneratedLine++;
      }
      if (lastGeneratedColumn < mapping.generatedColumn) {
        nextLine = remainingLines[remainingLinesIndex] || "";
        node.add(nextLine.substr(0, mapping.generatedColumn));
        remainingLines[remainingLinesIndex] = nextLine.substr(mapping.generatedColumn);
        lastGeneratedColumn = mapping.generatedColumn;
      }
      lastMapping = mapping;
    }, this);
    // We have processed all mappings.
    if (remainingLinesIndex < remainingLines.length) {
      if (lastMapping) {
        // Associate the remaining code in the current line with "lastMapping"
        addMappingWithCode(lastMapping, shiftNextLine());
      }
      // and add the remaining lines without any mapping
      node.add(remainingLines.splice(remainingLinesIndex).join(""));
    }

    // Copy sourcesContent into SourceNode
    aSourceMapConsumer.sources.forEach(function(sourceFile) {
      const content = aSourceMapConsumer.sourceContentFor(sourceFile);
      if (content != null) {
        if (aRelativePath != null) {
          sourceFile = util.join(aRelativePath, sourceFile);
        }
        node.setSourceContent(sourceFile, content);
      }
    });

    return node;

    function addMappingWithCode(mapping, code) {
      if (mapping === null || mapping.source === undefined) {
        node.add(code);
      } else {
        const source = aRelativePath
          ? util.join(aRelativePath, mapping.source)
          : mapping.source;
        node.add(new SourceNode(mapping.originalLine,
                                mapping.originalColumn,
                                source,
                                code,
                                mapping.name));
      }
    }
  }

  /**
   * Add a chunk of generated JS to this source node.
   *
   * @param aChunk A string snippet of generated JS code, another instance of
   *        SourceNode, or an array where each member is one of those things.
   */
  add(aChunk) {
    if (Array.isArray(aChunk)) {
      aChunk.forEach(function(chunk) {
        this.add(chunk);
      }, this);
    } else if (aChunk[isSourceNode] || typeof aChunk === "string") {
      if (aChunk) {
        this.children.push(aChunk);
      }
    } else {
      throw new TypeError(
        "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
      );
    }
    return this;
  }

  /**
   * Add a chunk of generated JS to the beginning of this source node.
   *
   * @param aChunk A string snippet of generated JS code, another instance of
   *        SourceNode, or an array where each member is one of those things.
   */
  prepend(aChunk) {
    if (Array.isArray(aChunk)) {
      for (let i = aChunk.length - 1; i >= 0; i--) {
        this.prepend(aChunk[i]);
      }
    } else if (aChunk[isSourceNode] || typeof aChunk === "string") {
      this.children.unshift(aChunk);
    } else {
      throw new TypeError(
        "Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
      );
    }
    return this;
  }

  /**
   * Walk over the tree of JS snippets in this node and its children. The
   * walking function is called once for each snippet of JS and is passed that
   * snippet and the its original associated source's line/column location.
   *
   * @param aFn The traversal function.
   */
  walk(aFn) {
    let chunk;
    for (let i = 0, len = this.children.length; i < len; i++) {
      chunk = this.children[i];
      if (chunk[isSourceNode]) {
        chunk.walk(aFn);
      } else if (chunk !== "") {
        aFn(chunk, { source: this.source,
                      line: this.line,
                      column: this.column,
                      name: this.name });
      }
    }
  }

  /**
   * Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between
   * each of `this.children`.
   *
   * @param aSep The separator.
   */
  join(aSep) {
    let newChildren;
    let i;
    const len = this.children.length;
    if (len > 0) {
      newChildren = [];
      for (i = 0; i < len - 1; i++) {
        newChildren.push(this.children[i]);
        newChildren.push(aSep);
      }
      newChildren.push(this.children[i]);
      this.children = newChildren;
    }
    return this;
  }

  /**
   * Call String.prototype.replace on the very right-most source snippet. Useful
   * for trimming whitespace from the end of a source node, etc.
   *
   * @param aPattern The pattern to replace.
   * @param aReplacement The thing to replace the pattern with.
   */
  replaceRight(aPattern, aReplacement) {
    const lastChild = this.children[this.children.length - 1];
    if (lastChild[isSourceNode]) {
      lastChild.replaceRight(aPattern, aReplacement);
    } else if (typeof lastChild === "string") {
      this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);
    } else {
      this.children.push("".replace(aPattern, aReplacement));
    }
    return this;
  }

  /**
   * Set the source content for a source file. This will be added to the SourceMapGenerator
   * in the sourcesContent field.
   *
   * @param aSourceFile The filename of the source file
   * @param aSourceContent The content of the source file
   */
  setSourceContent(aSourceFile, aSourceContent) {
    this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;
  }

  /**
   * Walk over the tree of SourceNodes. The walking function is called for each
   * source file content and is passed the filename and source content.
   *
   * @param aFn The traversal function.
   */
  walkSourceContents(aFn) {
    for (let i = 0, len = this.children.length; i < len; i++) {
      if (this.children[i][isSourceNode]) {
        this.children[i].walkSourceContents(aFn);
      }
    }

    const sources = Object.keys(this.sourceContents);
    for (let i = 0, len = sources.length; i < len; i++) {
      aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);
    }
  }

  /**
   * Return the string representation of this source node. Walks over the tree
   * and concatenates all the various snippets together to one string.
   */
  toString() {
    let str = "";
    this.walk(function(chunk) {
      str += chunk;
    });
    return str;
  }

  /**
   * Returns the string representation of this source node along with a source
   * map.
   */
  toStringWithSourceMap(aArgs) {
    const generated = {
      code: "",
      line: 1,
      column: 0
    };
    const map = new SourceMapGenerator(aArgs);
    let sourceMappingActive = false;
    let lastOriginalSource = null;
    let lastOriginalLine = null;
    let lastOriginalColumn = null;
    let lastOriginalName = null;
    this.walk(function(chunk, original) {
      generated.code += chunk;
      if (original.source !== null
          && original.line !== null
          && original.column !== null) {
        if (lastOriginalSource !== original.source
          || lastOriginalLine !== original.line
          || lastOriginalColumn !== original.column
          || lastOriginalName !== original.name) {
          map.addMapping({
            source: original.source,
            original: {
              line: original.line,
              column: original.column
            },
            generated: {
              line: generated.line,
              column: generated.column
            },
            name: original.name
          });
        }
        lastOriginalSource = original.source;
        lastOriginalLine = original.line;
        lastOriginalColumn = original.column;
        lastOriginalName = original.name;
        sourceMappingActive = true;
      } else if (sourceMappingActive) {
        map.addMapping({
          generated: {
            line: generated.line,
            column: generated.column
          }
        });
        lastOriginalSource = null;
        sourceMappingActive = false;
      }
      for (let idx = 0, length = chunk.length; idx < length; idx++) {
        if (chunk.charCodeAt(idx) === NEWLINE_CODE) {
          generated.line++;
          generated.column = 0;
          // Mappings end at eol
          if (idx + 1 === length) {
            lastOriginalSource = null;
            sourceMappingActive = false;
          } else if (sourceMappingActive) {
            map.addMapping({
              source: original.source,
              original: {
                line: original.line,
                column: original.column
              },
              generated: {
                line: generated.line,
                column: generated.column
              },
              name: original.name
            });
          }
        } else {
          generated.column++;
        }
      }
    });
    this.walkSourceContents(function(sourceFile, sourceContent) {
      map.setSourceContent(sourceFile, sourceContent);
    });

    return { code: generated.code, map };
  }
}

__webpack_unused_export__ = SourceNode;


/***/ },

/***/ 251
(__unused_webpack_module, exports) {

/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

/**
 * This is a helper function for getting values from parameter/options
 * objects.
 *
 * @param args The object we are extracting values from
 * @param name The name of the property we are getting.
 * @param defaultValue An optional value to return if the property is missing
 * from the object. If this is not specified and the property is missing, an
 * error will be thrown.
 */
function getArg(aArgs, aName, aDefaultValue) {
  if (aName in aArgs) {
    return aArgs[aName];
  } else if (arguments.length === 3) {
    return aDefaultValue;
  }
    throw new Error('"' + aName + '" is a required argument.');

}
exports.getArg = getArg;

const urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.-]*)(?::(\d+))?(.*)$/;
const dataUrlRegexp = /^data:.+\,.+$/;

function urlParse(aUrl) {
  const match = aUrl.match(urlRegexp);
  if (!match) {
    return null;
  }
  return {
    scheme: match[1],
    auth: match[2],
    host: match[3],
    port: match[4],
    path: match[5]
  };
}
exports.urlParse = urlParse;

function urlGenerate(aParsedUrl) {
  let url = "";
  if (aParsedUrl.scheme) {
    url += aParsedUrl.scheme + ":";
  }
  url += "//";
  if (aParsedUrl.auth) {
    url += aParsedUrl.auth + "@";
  }
  if (aParsedUrl.host) {
    url += aParsedUrl.host;
  }
  if (aParsedUrl.port) {
    url += ":" + aParsedUrl.port;
  }
  if (aParsedUrl.path) {
    url += aParsedUrl.path;
  }
  return url;
}
exports.urlGenerate = urlGenerate;

const MAX_CACHED_INPUTS = 32;

/**
 * Takes some function `f(input) -> result` and returns a memoized version of
 * `f`.
 *
 * We keep at most `MAX_CACHED_INPUTS` memoized results of `f` alive. The
 * memoization is a dumb-simple, linear least-recently-used cache.
 */
function lruMemoize(f) {
  const cache = [];

  return function(input) {
    for (let i = 0; i < cache.length; i++) {
      if (cache[i].input === input) {
        const temp = cache[0];
        cache[0] = cache[i];
        cache[i] = temp;
        return cache[0].result;
      }
    }

    const result = f(input);

    cache.unshift({
      input,
      result,
    });

    if (cache.length > MAX_CACHED_INPUTS) {
      cache.pop();
    }

    return result;
  };
}

/**
 * Normalizes a path, or the path portion of a URL:
 *
 * - Replaces consecutive slashes with one slash.
 * - Removes unnecessary '.' parts.
 * - Removes unnecessary '<dir>/..' parts.
 *
 * Based on code in the Node.js 'path' core module.
 *
 * @param aPath The path or url to normalize.
 */
const normalize = lruMemoize(function normalize(aPath) {
  let path = aPath;
  const url = urlParse(aPath);
  if (url) {
    if (!url.path) {
      return aPath;
    }
    path = url.path;
  }
  const isAbsolute = exports.isAbsolute(path);

  // Split the path into parts between `/` characters. This is much faster than
  // using `.split(/\/+/g)`.
  const parts = [];
  let start = 0;
  let i = 0;
  while (true) {
    start = i;
    i = path.indexOf("/", start);
    if (i === -1) {
      parts.push(path.slice(start));
      break;
    } else {
      parts.push(path.slice(start, i));
      while (i < path.length && path[i] === "/") {
        i++;
      }
    }
  }

  let up = 0;
  for (i = parts.length - 1; i >= 0; i--) {
    const part = parts[i];
    if (part === ".") {
      parts.splice(i, 1);
    } else if (part === "..") {
      up++;
    } else if (up > 0) {
      if (part === "") {
        // The first part is blank if the path is absolute. Trying to go
        // above the root is a no-op. Therefore we can remove all '..' parts
        // directly after the root.
        parts.splice(i + 1, up);
        up = 0;
      } else {
        parts.splice(i, 2);
        up--;
      }
    }
  }
  path = parts.join("/");

  if (path === "") {
    path = isAbsolute ? "/" : ".";
  }

  if (url) {
    url.path = path;
    return urlGenerate(url);
  }
  return path;
});
exports.normalize = normalize;

/**
 * Joins two paths/URLs.
 *
 * @param aRoot The root path or URL.
 * @param aPath The path or URL to be joined with the root.
 *
 * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a
 *   scheme-relative URL: Then the scheme of aRoot, if any, is prepended
 *   first.
 * - Otherwise aPath is a path. If aRoot is a URL, then its path portion
 *   is updated with the result and aRoot is returned. Otherwise the result
 *   is returned.
 *   - If aPath is absolute, the result is aPath.
 *   - Otherwise the two paths are joined with a slash.
 * - Joining for example 'http://' and 'www.example.com' is also supported.
 */
function join(aRoot, aPath) {
  if (aRoot === "") {
    aRoot = ".";
  }
  if (aPath === "") {
    aPath = ".";
  }
  const aPathUrl = urlParse(aPath);
  const aRootUrl = urlParse(aRoot);
  if (aRootUrl) {
    aRoot = aRootUrl.path || "/";
  }

  // `join(foo, '//www.example.org')`
  if (aPathUrl && !aPathUrl.scheme) {
    if (aRootUrl) {
      aPathUrl.scheme = aRootUrl.scheme;
    }
    return urlGenerate(aPathUrl);
  }

  if (aPathUrl || aPath.match(dataUrlRegexp)) {
    return aPath;
  }

  // `join('http://', 'www.example.com')`
  if (aRootUrl && !aRootUrl.host && !aRootUrl.path) {
    aRootUrl.host = aPath;
    return urlGenerate(aRootUrl);
  }

  const joined = aPath.charAt(0) === "/"
    ? aPath
    : normalize(aRoot.replace(/\/+$/, "") + "/" + aPath);

  if (aRootUrl) {
    aRootUrl.path = joined;
    return urlGenerate(aRootUrl);
  }
  return joined;
}
exports.join = join;

exports.isAbsolute = function(aPath) {
  return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
};

/**
 * Make a path relative to a URL or another path.
 *
 * @param aRoot The root path or URL.
 * @param aPath The path or URL to be made relative to aRoot.
 */
function relative(aRoot, aPath) {
  if (aRoot === "") {
    aRoot = ".";
  }

  aRoot = aRoot.replace(/\/$/, "");

  // It is possible for the path to be above the root. In this case, simply
  // checking whether the root is a prefix of the path won't work. Instead, we
  // need to remove components from the root one by one, until either we find
  // a prefix that fits, or we run out of components to remove.
  let level = 0;
  while (aPath.indexOf(aRoot + "/") !== 0) {
    const index = aRoot.lastIndexOf("/");
    if (index < 0) {
      return aPath;
    }

    // If the only part of the root that is left is the scheme (i.e. http://,
    // file:///, etc.), one or more slashes (/), or simply nothing at all, we
    // have exhausted all components, so the path is not relative to the root.
    aRoot = aRoot.slice(0, index);
    if (aRoot.match(/^([^\/]+:\/)?\/*$/)) {
      return aPath;
    }

    ++level;
  }

  // Make sure we add a "../" for each component we removed from the root.
  return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1);
}
exports.relative = relative;

const supportsNullProto = (function() {
  const obj = Object.create(null);
  return !("__proto__" in obj);
}());

function identity(s) {
  return s;
}

/**
 * Because behavior goes wacky when you set `__proto__` on objects, we
 * have to prefix all the strings in our set with an arbitrary character.
 *
 * See https://github.com/mozilla/source-map/pull/31 and
 * https://github.com/mozilla/source-map/issues/30
 *
 * @param String aStr
 */
function toSetString(aStr) {
  if (isProtoString(aStr)) {
    return "$" + aStr;
  }

  return aStr;
}
exports.toSetString = supportsNullProto ? identity : toSetString;

function fromSetString(aStr) {
  if (isProtoString(aStr)) {
    return aStr.slice(1);
  }

  return aStr;
}
exports.fromSetString = supportsNullProto ? identity : fromSetString;

function isProtoString(s) {
  if (!s) {
    return false;
  }

  const length = s.length;

  if (length < 9 /* "__proto__".length */) {
    return false;
  }

  /* eslint-disable no-multi-spaces */
  if (s.charCodeAt(length - 1) !== 95  /* '_' */ ||
      s.charCodeAt(length - 2) !== 95  /* '_' */ ||
      s.charCodeAt(length - 3) !== 111 /* 'o' */ ||
      s.charCodeAt(length - 4) !== 116 /* 't' */ ||
      s.charCodeAt(length - 5) !== 111 /* 'o' */ ||
      s.charCodeAt(length - 6) !== 114 /* 'r' */ ||
      s.charCodeAt(length - 7) !== 112 /* 'p' */ ||
      s.charCodeAt(length - 8) !== 95  /* '_' */ ||
      s.charCodeAt(length - 9) !== 95  /* '_' */) {
    return false;
  }
  /* eslint-enable no-multi-spaces */

  for (let i = length - 10; i >= 0; i--) {
    if (s.charCodeAt(i) !== 36 /* '$' */) {
      return false;
    }
  }

  return true;
}

/**
 * Comparator between two mappings where the original positions are compared.
 *
 * Optionally pass in `true` as `onlyCompareGenerated` to consider two
 * mappings with the same original source/line/column, but different generated
 * line and column the same. Useful when searching for a mapping with a
 * stubbed out mapping.
 */
function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) {
  let cmp = strcmp(mappingA.source, mappingB.source);
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.originalLine - mappingB.originalLine;
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.originalColumn - mappingB.originalColumn;
  if (cmp !== 0 || onlyCompareOriginal) {
    return cmp;
  }

  cmp = mappingA.generatedColumn - mappingB.generatedColumn;
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.generatedLine - mappingB.generatedLine;
  if (cmp !== 0) {
    return cmp;
  }

  return strcmp(mappingA.name, mappingB.name);
}
exports.compareByOriginalPositions = compareByOriginalPositions;

/**
 * Comparator between two mappings with deflated source and name indices where
 * the generated positions are compared.
 *
 * Optionally pass in `true` as `onlyCompareGenerated` to consider two
 * mappings with the same generated line and column, but different
 * source/name/original line and column the same. Useful when searching for a
 * mapping with a stubbed out mapping.
 */
function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) {
  let cmp = mappingA.generatedLine - mappingB.generatedLine;
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.generatedColumn - mappingB.generatedColumn;
  if (cmp !== 0 || onlyCompareGenerated) {
    return cmp;
  }

  cmp = strcmp(mappingA.source, mappingB.source);
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.originalLine - mappingB.originalLine;
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.originalColumn - mappingB.originalColumn;
  if (cmp !== 0) {
    return cmp;
  }

  return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated;

function strcmp(aStr1, aStr2) {
  if (aStr1 === aStr2) {
    return 0;
  }

  if (aStr1 === null) {
    return 1; // aStr2 !== null
  }

  if (aStr2 === null) {
    return -1; // aStr1 !== null
  }

  if (aStr1 > aStr2) {
    return 1;
  }

  return -1;
}

/**
 * Comparator between two mappings with inflated source and name strings where
 * the generated positions are compared.
 */
function compareByGeneratedPositionsInflated(mappingA, mappingB) {
  let cmp = mappingA.generatedLine - mappingB.generatedLine;
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.generatedColumn - mappingB.generatedColumn;
  if (cmp !== 0) {
    return cmp;
  }

  cmp = strcmp(mappingA.source, mappingB.source);
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.originalLine - mappingB.originalLine;
  if (cmp !== 0) {
    return cmp;
  }

  cmp = mappingA.originalColumn - mappingB.originalColumn;
  if (cmp !== 0) {
    return cmp;
  }

  return strcmp(mappingA.name, mappingB.name);
}
exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated;

/**
 * Strip any JSON XSSI avoidance prefix from the string (as documented
 * in the source maps specification), and then parse the string as
 * JSON.
 */
function parseSourceMapInput(str) {
  return JSON.parse(str.replace(/^\)]}'[^\n]*\n/, ""));
}
exports.parseSourceMapInput = parseSourceMapInput;

/**
 * Compute the URL of a source given the the source root, the source's
 * URL, and the source map's URL.
 */
function computeSourceURL(sourceRoot, sourceURL, sourceMapURL) {
  sourceURL = sourceURL || "";

  if (sourceRoot) {
    // This follows what Chrome does.
    if (sourceRoot[sourceRoot.length - 1] !== "/" && sourceURL[0] !== "/") {
      sourceRoot += "/";
    }
    // The spec says:
    //   Line 4: An optional source root, useful for relocating source
    //   files on a server or removing repeated values in the
    //   “sources” entry.  This value is prepended to the individual
    //   entries in the “source” field.
    sourceURL = sourceRoot + sourceURL;
  }

  // Historically, SourceMapConsumer did not take the sourceMapURL as
  // a parameter.  This mode is still somewhat supported, which is why
  // this code block is conditional.  However, it's preferable to pass
  // the source map URL to SourceMapConsumer, so that this function
  // can implement the source URL resolution algorithm as outlined in
  // the spec.  This block is basically the equivalent of:
  //    new URL(sourceURL, sourceMapURL).toString()
  // ... except it avoids using URL, which wasn't available in the
  // older releases of node still supported by this library.
  //
  // The spec says:
  //   If the sources are not absolute URLs after prepending of the
  //   “sourceRoot”, the sources are resolved relative to the
  //   SourceMap (like resolving script src in a html document).
  if (sourceMapURL) {
    const parsed = urlParse(sourceMapURL);
    if (!parsed) {
      throw new Error("sourceMapURL could not be parsed");
    }
    if (parsed.path) {
      // Strip the last path component, but keep the "/".
      const index = parsed.path.lastIndexOf("/");
      if (index >= 0) {
        parsed.path = parsed.path.substring(0, index + 1);
      }
    }
    sourceURL = join(urlGenerate(parsed), sourceURL);
  }

  return normalize(sourceURL);
}
exports.computeSourceURL = computeSourceURL;


/***/ },

/***/ 8991
(module, __unused_webpack_exports, __webpack_require__) {

const readWasm = __webpack_require__(6576);

/**
 * Provide the JIT with a nice shape / hidden class.
 */
function Mapping() {
  this.generatedLine = 0;
  this.generatedColumn = 0;
  this.lastGeneratedColumn = null;
  this.source = null;
  this.originalLine = null;
  this.originalColumn = null;
  this.name = null;
}

let cachedWasm = null;

module.exports = function wasm() {
  if (cachedWasm) {
    return cachedWasm;
  }

  const callbackStack = [];

  cachedWasm = readWasm().then(buffer => {
      return WebAssembly.instantiate(buffer, {
        env: {
          mapping_callback(
            generatedLine,
            generatedColumn,

            hasLastGeneratedColumn,
            lastGeneratedColumn,

            hasOriginal,
            source,
            originalLine,
            originalColumn,

            hasName,
            name
          ) {
            const mapping = new Mapping();
            // JS uses 1-based line numbers, wasm uses 0-based.
            mapping.generatedLine = generatedLine + 1;
            mapping.generatedColumn = generatedColumn;

            if (hasLastGeneratedColumn) {
              // JS uses inclusive last generated column, wasm uses exclusive.
              mapping.lastGeneratedColumn = lastGeneratedColumn - 1;
            }

            if (hasOriginal) {
              mapping.source = source;
              // JS uses 1-based line numbers, wasm uses 0-based.
              mapping.originalLine = originalLine + 1;
              mapping.originalColumn = originalColumn;

              if (hasName) {
                mapping.name = name;
              }
            }

            callbackStack[callbackStack.length - 1](mapping);
          },

          start_all_generated_locations_for() { console.time("all_generated_locations_for"); },
          end_all_generated_locations_for() { console.timeEnd("all_generated_locations_for"); },

          start_compute_column_spans() { console.time("compute_column_spans"); },
          end_compute_column_spans() { console.timeEnd("compute_column_spans"); },

          start_generated_location_for() { console.time("generated_location_for"); },
          end_generated_location_for() { console.timeEnd("generated_location_for"); },

          start_original_location_for() { console.time("original_location_for"); },
          end_original_location_for() { console.timeEnd("original_location_for"); },

          start_parse_mappings() { console.time("parse_mappings"); },
          end_parse_mappings() { console.timeEnd("parse_mappings"); },

          start_sort_by_generated_location() { console.time("sort_by_generated_location"); },
          end_sort_by_generated_location() { console.timeEnd("sort_by_generated_location"); },

          start_sort_by_original_location() { console.time("sort_by_original_location"); },
          end_sort_by_original_location() { console.timeEnd("sort_by_original_location"); },
        }
      });
  }).then(Wasm => {
    return {
      exports: Wasm.instance.exports,
      withMappingCallback: (mappingCallback, f) => {
        callbackStack.push(mappingCallback);
        try {
          f();
        } finally {
          callbackStack.pop();
        }
      }
    };
  }).then(null, e => {
    cachedWasm = null;
    throw e;
  });

  return cachedWasm;
};


/***/ },

/***/ 9665
(__unused_webpack_module, exports, __webpack_require__) {

/*
 * Copyright 2009-2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE.txt or:
 * http://opensource.org/licenses/BSD-3-Clause
 */
/* unused reexport */ __webpack_require__(4041)/* .SourceMapGenerator */ .x;
exports.SourceMapConsumer = __webpack_require__(7446).SourceMapConsumer;
/* unused reexport */ __webpack_require__(1683);


/***/ },

/***/ 3742
(module) {

"use strict";
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

var Mediabunny = (() => {
  var __create = Object.create;
  var __defProp = Object.defineProperty;
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  var __getOwnPropNames = Object.getOwnPropertyNames;
  var __getProtoOf = Object.getPrototypeOf;
  var __hasOwnProp = Object.prototype.hasOwnProperty;
  var __commonJS = (cb, mod) => function __require() {
    return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
  };
  var __export = (target, all) => {
    for (var name in all)
      __defProp(target, name, { get: all[name], enumerable: true });
  };
  var __copyProps = (to, from, except, desc) => {
    if (from && typeof from === "object" || typeof from === "function") {
      for (let key of __getOwnPropNames(from))
        if (!__hasOwnProp.call(to, key) && key !== except)
          __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
    }
    return to;
  };
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
    // If the importer is in node compatibility mode or this is not an ESM
    // file that has been converted to a CommonJS file using a Babel-
    // compatible transform (i.e. "__esModule" has not been set), then set
    // "default" to the CommonJS "module.exports" for node compatibility.
    isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
    mod
  ));
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);

  // (disabled):src/node
  var require_node = __commonJS({
    "(disabled):src/node"() {
    }
  });

  // src/index.ts
  var index_exports = {};
  __export(index_exports, {
    ADTS: () => ADTS,
    ALL_FORMATS: () => ALL_FORMATS,
    ALL_TRACK_TYPES: () => ALL_TRACK_TYPES,
    AUDIO_CODECS: () => AUDIO_CODECS,
    AdtsInputFormat: () => AdtsInputFormat,
    AdtsOutputFormat: () => AdtsOutputFormat,
    AttachedFile: () => AttachedFile,
    AudioBufferSink: () => AudioBufferSink,
    AudioBufferSource: () => AudioBufferSource,
    AudioSample: () => AudioSample,
    AudioSampleSink: () => AudioSampleSink,
    AudioSampleSource: () => AudioSampleSource,
    AudioSource: () => AudioSource,
    BaseMediaSampleSink: () => BaseMediaSampleSink,
    BlobSource: () => BlobSource,
    BufferSource: () => BufferSource,
    BufferTarget: () => BufferTarget,
    CanvasSink: () => CanvasSink,
    CanvasSource: () => CanvasSource,
    Conversion: () => Conversion,
    ConversionCanceledError: () => ConversionCanceledError,
    CustomAudioDecoder: () => CustomAudioDecoder,
    CustomAudioEncoder: () => CustomAudioEncoder,
    CustomVideoDecoder: () => CustomVideoDecoder,
    CustomVideoEncoder: () => CustomVideoEncoder,
    EncodedAudioPacketSource: () => EncodedAudioPacketSource,
    EncodedPacket: () => EncodedPacket,
    EncodedPacketSink: () => EncodedPacketSink,
    EncodedVideoPacketSource: () => EncodedVideoPacketSource,
    FLAC: () => FLAC,
    FilePathSource: () => FilePathSource,
    FilePathTarget: () => FilePathTarget,
    FlacInputFormat: () => FlacInputFormat,
    FlacOutputFormat: () => FlacOutputFormat,
    Input: () => Input,
    InputAudioTrack: () => InputAudioTrack,
    InputDisposedError: () => InputDisposedError,
    InputFormat: () => InputFormat,
    InputTrack: () => InputTrack,
    InputVideoTrack: () => InputVideoTrack,
    IsobmffInputFormat: () => IsobmffInputFormat,
    IsobmffOutputFormat: () => IsobmffOutputFormat2,
    MATROSKA: () => MATROSKA,
    MP3: () => MP3,
    MP4: () => MP4,
    MPEG_TS: () => MPEG_TS,
    MatroskaInputFormat: () => MatroskaInputFormat,
    MediaSource: () => MediaSource,
    MediaStreamAudioTrackSource: () => MediaStreamAudioTrackSource,
    MediaStreamVideoTrackSource: () => MediaStreamVideoTrackSource,
    MkvOutputFormat: () => MkvOutputFormat2,
    MovOutputFormat: () => MovOutputFormat,
    Mp3InputFormat: () => Mp3InputFormat,
    Mp3OutputFormat: () => Mp3OutputFormat,
    Mp4InputFormat: () => Mp4InputFormat,
    Mp4OutputFormat: () => Mp4OutputFormat,
    MpegTsInputFormat: () => MpegTsInputFormat,
    MpegTsOutputFormat: () => MpegTsOutputFormat,
    NON_PCM_AUDIO_CODECS: () => NON_PCM_AUDIO_CODECS,
    NullTarget: () => NullTarget,
    OGG: () => OGG,
    OggInputFormat: () => OggInputFormat,
    OggOutputFormat: () => OggOutputFormat,
    Output: () => Output,
    OutputFormat: () => OutputFormat,
    PCM_AUDIO_CODECS: () => PCM_AUDIO_CODECS,
    QTFF: () => QTFF,
    QUALITY_HIGH: () => QUALITY_HIGH,
    QUALITY_LOW: () => QUALITY_LOW,
    QUALITY_MEDIUM: () => QUALITY_MEDIUM,
    QUALITY_VERY_HIGH: () => QUALITY_VERY_HIGH,
    QUALITY_VERY_LOW: () => QUALITY_VERY_LOW,
    Quality: () => Quality,
    QuickTimeInputFormat: () => QuickTimeInputFormat,
    ReadableStreamSource: () => ReadableStreamSource,
    RichImageData: () => RichImageData,
    SUBTITLE_CODECS: () => SUBTITLE_CODECS,
    Source: () => Source,
    StreamSource: () => StreamSource,
    StreamTarget: () => StreamTarget,
    SubtitleSource: () => SubtitleSource,
    Target: () => Target,
    TextSubtitleSource: () => TextSubtitleSource,
    UrlSource: () => UrlSource,
    VIDEO_CODECS: () => VIDEO_CODECS,
    VIDEO_SAMPLE_PIXEL_FORMATS: () => VIDEO_SAMPLE_PIXEL_FORMATS,
    VideoSample: () => VideoSample,
    VideoSampleColorSpace: () => VideoSampleColorSpace,
    VideoSampleSink: () => VideoSampleSink,
    VideoSampleSource: () => VideoSampleSource,
    VideoSource: () => VideoSource,
    WAVE: () => WAVE,
    WEBM: () => WEBM,
    WavOutputFormat: () => WavOutputFormat,
    WaveInputFormat: () => WaveInputFormat,
    WebMInputFormat: () => WebMInputFormat,
    WebMOutputFormat: () => WebMOutputFormat,
    canEncode: () => canEncode,
    canEncodeAudio: () => canEncodeAudio,
    canEncodeSubtitles: () => canEncodeSubtitles,
    canEncodeVideo: () => canEncodeVideo,
    getEncodableAudioCodecs: () => getEncodableAudioCodecs,
    getEncodableCodecs: () => getEncodableCodecs,
    getEncodableSubtitleCodecs: () => getEncodableSubtitleCodecs,
    getEncodableVideoCodecs: () => getEncodableVideoCodecs,
    getFirstEncodableAudioCodec: () => getFirstEncodableAudioCodec,
    getFirstEncodableSubtitleCodec: () => getFirstEncodableSubtitleCodec,
    getFirstEncodableVideoCodec: () => getFirstEncodableVideoCodec,
    registerDecoder: () => registerDecoder,
    registerEncoder: () => registerEncoder
  });

  // src/misc.ts
  function assert(x) {
    if (!x) {
      throw new Error("Assertion failed.");
    }
  }
  var normalizeRotation = (rotation) => {
    const mappedRotation = (rotation % 360 + 360) % 360;
    if (mappedRotation === 0 || mappedRotation === 90 || mappedRotation === 180 || mappedRotation === 270) {
      return mappedRotation;
    } else {
      throw new Error(`Invalid rotation ${rotation}.`);
    }
  };
  var last = (arr) => {
    return arr && arr[arr.length - 1];
  };
  var isU32 = (value) => {
    return value >= 0 && value < 2 ** 32;
  };
  var Bitstream = class _Bitstream {
    constructor(bytes2) {
      this.bytes = bytes2;
      /** Current offset in bits. */
      this.pos = 0;
    }
    seekToByte(byteOffset) {
      this.pos = 8 * byteOffset;
    }
    readBit() {
      const byteIndex = Math.floor(this.pos / 8);
      const byte = this.bytes[byteIndex] ?? 0;
      const bitIndex = 7 - (this.pos & 7);
      const bit = (byte & 1 << bitIndex) >> bitIndex;
      this.pos++;
      return bit;
    }
    readBits(n) {
      if (n === 1) {
        return this.readBit();
      }
      let result = 0;
      for (let i = 0; i < n; i++) {
        result <<= 1;
        result |= this.readBit();
      }
      return result;
    }
    writeBits(n, value) {
      const end = this.pos + n;
      for (let i = this.pos; i < end; i++) {
        const byteIndex = Math.floor(i / 8);
        let byte = this.bytes[byteIndex];
        const bitIndex = 7 - (i & 7);
        byte &= ~(1 << bitIndex);
        byte |= (value & 1 << end - i - 1) >> end - i - 1 << bitIndex;
        this.bytes[byteIndex] = byte;
      }
      this.pos = end;
    }
    readAlignedByte() {
      if (this.pos % 8 !== 0) {
        throw new Error("Bitstream is not byte-aligned.");
      }
      const byteIndex = this.pos / 8;
      const byte = this.bytes[byteIndex] ?? 0;
      this.pos += 8;
      return byte;
    }
    skipBits(n) {
      this.pos += n;
    }
    getBitsLeft() {
      return this.bytes.length * 8 - this.pos;
    }
    clone() {
      const clone = new _Bitstream(this.bytes);
      clone.pos = this.pos;
      return clone;
    }
  };
  var readExpGolomb = (bitstream) => {
    let leadingZeroBits = 0;
    while (bitstream.readBits(1) === 0 && leadingZeroBits < 32) {
      leadingZeroBits++;
    }
    if (leadingZeroBits >= 32) {
      throw new Error("Invalid exponential-Golomb code.");
    }
    const result = (1 << leadingZeroBits) - 1 + bitstream.readBits(leadingZeroBits);
    return result;
  };
  var readSignedExpGolomb = (bitstream) => {
    const codeNum = readExpGolomb(bitstream);
    return (codeNum & 1) === 0 ? -(codeNum >> 1) : codeNum + 1 >> 1;
  };
  var writeBits = (bytes2, start, end, value) => {
    for (let i = start; i < end; i++) {
      const byteIndex = Math.floor(i / 8);
      let byte = bytes2[byteIndex];
      const bitIndex = 7 - (i & 7);
      byte &= ~(1 << bitIndex);
      byte |= (value & 1 << end - i - 1) >> end - i - 1 << bitIndex;
      bytes2[byteIndex] = byte;
    }
  };
  var toUint8Array = (source) => {
    if (source.constructor === Uint8Array) {
      return source;
    } else if (ArrayBuffer.isView(source)) {
      return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
    } else {
      return new Uint8Array(source);
    }
  };
  var toDataView = (source) => {
    if (source.constructor === DataView) {
      return source;
    } else if (ArrayBuffer.isView(source)) {
      return new DataView(source.buffer, source.byteOffset, source.byteLength);
    } else {
      return new DataView(source);
    }
  };
  var textDecoder = /* @__PURE__ */ new TextDecoder();
  var textEncoder = /* @__PURE__ */ new TextEncoder();
  var isIso88591Compatible = (text) => {
    for (let i = 0; i < text.length; i++) {
      const code = text.charCodeAt(i);
      if (code > 255) {
        return false;
      }
    }
    return true;
  };
  var invertObject = (object) => {
    return Object.fromEntries(Object.entries(object).map(([key, value]) => [value, key]));
  };
  var COLOR_PRIMARIES_MAP = {
    bt709: 1,
    // ITU-R BT.709
    bt470bg: 5,
    // ITU-R BT.470BG
    smpte170m: 6,
    // ITU-R BT.601 525 - SMPTE 170M
    bt2020: 9,
    // ITU-R BT.202
    smpte432: 12
    // SMPTE EG 432-1
  };
  var COLOR_PRIMARIES_MAP_INVERSE = /* @__PURE__ */ invertObject(COLOR_PRIMARIES_MAP);
  var TRANSFER_CHARACTERISTICS_MAP = {
    "bt709": 1,
    // ITU-R BT.709
    "smpte170m": 6,
    // SMPTE 170M
    "linear": 8,
    // Linear transfer characteristics
    "iec61966-2-1": 13,
    // IEC 61966-2-1
    "pq": 16,
    // Rec. ITU-R BT.2100-2 perceptual quantization (PQ) system
    "hlg": 18
    // Rec. ITU-R BT.2100-2 hybrid loggamma (HLG) system
  };
  var TRANSFER_CHARACTERISTICS_MAP_INVERSE = /* @__PURE__ */ invertObject(TRANSFER_CHARACTERISTICS_MAP);
  var MATRIX_COEFFICIENTS_MAP = {
    "rgb": 0,
    // Identity
    "bt709": 1,
    // ITU-R BT.709
    "bt470bg": 5,
    // ITU-R BT.470BG
    "smpte170m": 6,
    // SMPTE 170M
    "bt2020-ncl": 9
    // ITU-R BT.2020-2 (non-constant luminance)
  };
  var MATRIX_COEFFICIENTS_MAP_INVERSE = /* @__PURE__ */ invertObject(MATRIX_COEFFICIENTS_MAP);
  var colorSpaceIsComplete = (colorSpace) => {
    return !!colorSpace && !!colorSpace.primaries && !!colorSpace.transfer && !!colorSpace.matrix && colorSpace.fullRange !== void 0;
  };
  var isAllowSharedBufferSource = (x) => {
    return x instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && x instanceof SharedArrayBuffer || ArrayBuffer.isView(x);
  };
  var AsyncMutex = class {
    constructor() {
      this.currentPromise = Promise.resolve();
      this.pending = 0;
    }
    async acquire() {
      let resolver;
      const nextPromise = new Promise((resolve) => {
        let resolved = false;
        resolver = () => {
          if (resolved) {
            return;
          }
          resolve();
          this.pending--;
          resolved = true;
        };
      });
      const currentPromiseAlias = this.currentPromise;
      this.currentPromise = nextPromise;
      this.pending++;
      await currentPromiseAlias;
      return resolver;
    }
  };
  var bytesToHexString = (bytes2) => {
    return [...bytes2].map((x) => x.toString(16).padStart(2, "0")).join("");
  };
  var reverseBitsU32 = (x) => {
    x = x >> 1 & 1431655765 | (x & 1431655765) << 1;
    x = x >> 2 & 858993459 | (x & 858993459) << 2;
    x = x >> 4 & 252645135 | (x & 252645135) << 4;
    x = x >> 8 & 16711935 | (x & 16711935) << 8;
    x = x >> 16 & 65535 | (x & 65535) << 16;
    return x >>> 0;
  };
  var binarySearchExact = (arr, key, valueGetter) => {
    let low = 0;
    let high = arr.length - 1;
    let ans = -1;
    while (low <= high) {
      const mid = low + high >> 1;
      const midVal = valueGetter(arr[mid]);
      if (midVal === key) {
        ans = mid;
        high = mid - 1;
      } else if (midVal < key) {
        low = mid + 1;
      } else {
        high = mid - 1;
      }
    }
    return ans;
  };
  var binarySearchLessOrEqual = (arr, key, valueGetter) => {
    let low = 0;
    let high = arr.length - 1;
    let ans = -1;
    while (low <= high) {
      const mid = low + (high - low + 1) / 2 | 0;
      const midVal = valueGetter(arr[mid]);
      if (midVal <= key) {
        ans = mid;
        low = mid + 1;
      } else {
        high = mid - 1;
      }
    }
    return ans;
  };
  var insertSorted = (arr, item, valueGetter) => {
    const insertionIndex = binarySearchLessOrEqual(arr, valueGetter(item), valueGetter);
    arr.splice(insertionIndex + 1, 0, item);
  };
  var promiseWithResolvers = () => {
    let resolve;
    let reject;
    const promise = new Promise((res, rej) => {
      resolve = res;
      reject = rej;
    });
    return { promise, resolve, reject };
  };
  var findLast = (arr, predicate) => {
    for (let i = arr.length - 1; i >= 0; i--) {
      if (predicate(arr[i])) {
        return arr[i];
      }
    }
    return void 0;
  };
  var findLastIndex = (arr, predicate) => {
    for (let i = arr.length - 1; i >= 0; i--) {
      if (predicate(arr[i])) {
        return i;
      }
    }
    return -1;
  };
  var toAsyncIterator = async function* (source) {
    if (Symbol.iterator in source) {
      yield* source[Symbol.iterator]();
    } else {
      yield* source[Symbol.asyncIterator]();
    }
  };
  var validateAnyIterable = (iterable) => {
    if (!(Symbol.iterator in iterable) && !(Symbol.asyncIterator in iterable)) {
      throw new TypeError("Argument must be an iterable or async iterable.");
    }
  };
  var assertNever = (x) => {
    throw new Error(`Unexpected value: ${x}`);
  };
  var getUint24 = (view2, byteOffset, littleEndian) => {
    const byte1 = view2.getUint8(byteOffset);
    const byte2 = view2.getUint8(byteOffset + 1);
    const byte3 = view2.getUint8(byteOffset + 2);
    if (littleEndian) {
      return byte1 | byte2 << 8 | byte3 << 16;
    } else {
      return byte1 << 16 | byte2 << 8 | byte3;
    }
  };
  var getInt24 = (view2, byteOffset, littleEndian) => {
    return getUint24(view2, byteOffset, littleEndian) << 8 >> 8;
  };
  var setUint24 = (view2, byteOffset, value, littleEndian) => {
    value = value >>> 0;
    value = value & 16777215;
    if (littleEndian) {
      view2.setUint8(byteOffset, value & 255);
      view2.setUint8(byteOffset + 1, value >>> 8 & 255);
      view2.setUint8(byteOffset + 2, value >>> 16 & 255);
    } else {
      view2.setUint8(byteOffset, value >>> 16 & 255);
      view2.setUint8(byteOffset + 1, value >>> 8 & 255);
      view2.setUint8(byteOffset + 2, value & 255);
    }
  };
  var setInt24 = (view2, byteOffset, value, littleEndian) => {
    value = clamp(value, -8388608, 8388607);
    if (value < 0) {
      value = value + 16777216 & 16777215;
    }
    setUint24(view2, byteOffset, value, littleEndian);
  };
  var setInt64 = (view2, byteOffset, value, littleEndian) => {
    if (littleEndian) {
      view2.setUint32(byteOffset + 0, value, true);
      view2.setInt32(byteOffset + 4, Math.floor(value / 2 ** 32), true);
    } else {
      view2.setInt32(byteOffset + 0, Math.floor(value / 2 ** 32), true);
      view2.setUint32(byteOffset + 4, value, true);
    }
  };
  var mapAsyncGenerator = (generator, map) => {
    return {
      async next() {
        const result = await generator.next();
        if (result.done) {
          return { value: void 0, done: true };
        } else {
          return { value: map(result.value), done: false };
        }
      },
      return() {
        return generator.return();
      },
      throw(error) {
        return generator.throw(error);
      },
      [Symbol.asyncIterator]() {
        return this;
      }
    };
  };
  var clamp = (value, min, max) => {
    return Math.max(min, Math.min(max, value));
  };
  var UNDETERMINED_LANGUAGE = "und";
  var roundIfAlmostInteger = (value) => {
    const rounded = Math.round(value);
    if (Math.abs(value / rounded - 1) < 10 * Number.EPSILON) {
      return rounded;
    } else {
      return value;
    }
  };
  var roundToMultiple = (value, multiple) => {
    return Math.round(value / multiple) * multiple;
  };
  var floorToMultiple = (value, multiple) => {
    return Math.floor(value / multiple) * multiple;
  };
  var ilog = (x) => {
    let ret = 0;
    while (x) {
      ret++;
      x >>= 1;
    }
    return ret;
  };
  var ISO_639_2_REGEX = /^[a-z]{3}$/;
  var isIso639Dash2LanguageCode = (x) => {
    return ISO_639_2_REGEX.test(x);
  };
  var SECOND_TO_MICROSECOND_FACTOR = 1e6 * (1 + Number.EPSILON);
  var mergeRequestInit = (init1, init2) => {
    const merged = { ...init1, ...init2 };
    if (init1.headers || init2.headers) {
      const headers1 = init1.headers ? normalizeHeaders(init1.headers) : {};
      const headers2 = init2.headers ? normalizeHeaders(init2.headers) : {};
      const mergedHeaders = { ...headers1 };
      Object.entries(headers2).forEach(([key2, value2]) => {
        const existingKey = Object.keys(mergedHeaders).find(
          (key1) => key1.toLowerCase() === key2.toLowerCase()
        );
        if (existingKey) {
          delete mergedHeaders[existingKey];
        }
        mergedHeaders[key2] = value2;
      });
      merged.headers = mergedHeaders;
    }
    return merged;
  };
  var normalizeHeaders = (headers) => {
    if (headers instanceof Headers) {
      const result = {};
      headers.forEach((value, key) => {
        result[key] = value;
      });
      return result;
    }
    if (Array.isArray(headers)) {
      const result = {};
      headers.forEach(([key, value]) => {
        result[key] = value;
      });
      return result;
    }
    return headers;
  };
  var retriedFetch = async (fetchFn, url2, requestInit, getRetryDelay, shouldStop) => {
    let attempts = 0;
    while (true) {
      try {
        return await fetchFn(url2, requestInit);
      } catch (error) {
        if (shouldStop()) {
          throw error;
        }
        attempts++;
        const retryDelayInSeconds = getRetryDelay(attempts, error, url2);
        if (retryDelayInSeconds === null) {
          throw error;
        }
        console.error("Retrying failed fetch. Error:", error);
        if (!Number.isFinite(retryDelayInSeconds) || retryDelayInSeconds < 0) {
          throw new TypeError("Retry delay must be a non-negative finite number.");
        }
        if (retryDelayInSeconds > 0) {
          await new Promise((resolve) => setTimeout(resolve, 1e3 * retryDelayInSeconds));
        }
        if (shouldStop()) {
          throw error;
        }
      }
    }
  };
  var computeRationalApproximation = (x, maxDenominator) => {
    const sign = x < 0 ? -1 : 1;
    x = Math.abs(x);
    let prevNumerator = 0, prevDenominator = 1;
    let currNumerator = 1, currDenominator = 0;
    let remainder = x;
    while (true) {
      const integer = Math.floor(remainder);
      const nextNumerator = integer * currNumerator + prevNumerator;
      const nextDenominator = integer * currDenominator + prevDenominator;
      if (nextDenominator > maxDenominator) {
        return {
          numerator: sign * currNumerator,
          denominator: currDenominator
        };
      }
      prevNumerator = currNumerator;
      prevDenominator = currDenominator;
      currNumerator = nextNumerator;
      currDenominator = nextDenominator;
      remainder = 1 / (remainder - integer);
      if (!isFinite(remainder)) {
        break;
      }
    }
    return {
      numerator: sign * currNumerator,
      denominator: currDenominator
    };
  };
  var CallSerializer = class {
    constructor() {
      this.currentPromise = Promise.resolve();
    }
    call(fn) {
      return this.currentPromise = this.currentPromise.then(fn);
    }
  };
  var isWebKitCache = null;
  var isWebKit = () => {
    if (isWebKitCache !== null) {
      return isWebKitCache;
    }
    return isWebKitCache = !!(typeof navigator !== "undefined" && (navigator.vendor?.match(/apple/i) || /AppleWebKit/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent) || /\b(iPad|iPhone|iPod)\b/.test(navigator.userAgent)));
  };
  var isFirefoxCache = null;
  var isFirefox = () => {
    if (isFirefoxCache !== null) {
      return isFirefoxCache;
    }
    return isFirefoxCache = typeof navigator !== "undefined" && navigator.userAgent?.includes("Firefox");
  };
  var isChromiumCache = null;
  var isChromium = () => {
    if (isChromiumCache !== null) {
      return isChromiumCache;
    }
    return isChromiumCache = !!(typeof navigator !== "undefined" && (navigator.vendor?.includes("Google Inc") || /Chrome/.test(navigator.userAgent)));
  };
  var chromiumVersionCache = null;
  var getChromiumVersion = () => {
    if (chromiumVersionCache !== null) {
      return chromiumVersionCache;
    }
    if (typeof navigator === "undefined") {
      return null;
    }
    const match = /\bChrome\/(\d+)/.exec(navigator.userAgent);
    if (!match) {
      return null;
    }
    return chromiumVersionCache = Number(match[1]);
  };
  var coalesceIndex = (a, b) => {
    return a !== -1 ? a : b;
  };
  var closedIntervalsOverlap = (startA, endA, startB, endB) => {
    return startA <= endB && startB <= endA;
  };
  var keyValueIterator = function* (object) {
    for (const key in object) {
      const value = object[key];
      if (value === void 0) {
        continue;
      }
      yield { key, value };
    }
  };
  var imageMimeTypeToExtension = (mimeType) => {
    switch (mimeType.toLowerCase()) {
      case "image/jpeg":
      case "image/jpg":
        return ".jpg";
      case "image/png":
        return ".png";
      case "image/gif":
        return ".gif";
      case "image/webp":
        return ".webp";
      case "image/bmp":
        return ".bmp";
      case "image/svg+xml":
        return ".svg";
      case "image/tiff":
        return ".tiff";
      case "image/avif":
        return ".avif";
      case "image/x-icon":
      case "image/vnd.microsoft.icon":
        return ".ico";
      default:
        return null;
    }
  };
  var base64ToBytes = (base64) => {
    const decoded = atob(base64);
    const bytes2 = new Uint8Array(decoded.length);
    for (let i = 0; i < decoded.length; i++) {
      bytes2[i] = decoded.charCodeAt(i);
    }
    return bytes2;
  };
  var bytesToBase64 = (bytes2) => {
    let string = "";
    for (let i = 0; i < bytes2.length; i++) {
      string += String.fromCharCode(bytes2[i]);
    }
    return btoa(string);
  };
  var uint8ArraysAreEqual = (a, b) => {
    if (a.length !== b.length) {
      return false;
    }
    for (let i = 0; i < a.length; i++) {
      if (a[i] !== b[i]) {
        return false;
      }
    }
    return true;
  };
  var polyfillSymbolDispose = () => {
    Symbol.dispose ??= Symbol("Symbol.dispose");
  };
  var isNumber = (x) => {
    return typeof x === "number" && !Number.isNaN(x);
  };

  // src/metadata.ts
  var RichImageData = class {
    /** Creates a new {@link RichImageData}. */
    constructor(data, mimeType) {
      this.data = data;
      this.mimeType = mimeType;
      if (!(data instanceof Uint8Array)) {
        throw new TypeError("data must be a Uint8Array.");
      }
      if (typeof mimeType !== "string") {
        throw new TypeError("mimeType must be a string.");
      }
    }
  };
  var AttachedFile = class {
    /** Creates a new {@link AttachedFile}. */
    constructor(data, mimeType, name, description) {
      this.data = data;
      this.mimeType = mimeType;
      this.name = name;
      this.description = description;
      if (!(data instanceof Uint8Array)) {
        throw new TypeError("data must be a Uint8Array.");
      }
      if (mimeType !== void 0 && typeof mimeType !== "string") {
        throw new TypeError("mimeType, when provided, must be a string.");
      }
      if (name !== void 0 && typeof name !== "string") {
        throw new TypeError("name, when provided, must be a string.");
      }
      if (description !== void 0 && typeof description !== "string") {
        throw new TypeError("description, when provided, must be a string.");
      }
    }
  };
  var validateMetadataTags = (tags) => {
    if (!tags || typeof tags !== "object") {
      throw new TypeError("tags must be an object.");
    }
    if (tags.title !== void 0 && typeof tags.title !== "string") {
      throw new TypeError("tags.title, when provided, must be a string.");
    }
    if (tags.description !== void 0 && typeof tags.description !== "string") {
      throw new TypeError("tags.description, when provided, must be a string.");
    }
    if (tags.artist !== void 0 && typeof tags.artist !== "string") {
      throw new TypeError("tags.artist, when provided, must be a string.");
    }
    if (tags.album !== void 0 && typeof tags.album !== "string") {
      throw new TypeError("tags.album, when provided, must be a string.");
    }
    if (tags.albumArtist !== void 0 && typeof tags.albumArtist !== "string") {
      throw new TypeError("tags.albumArtist, when provided, must be a string.");
    }
    if (tags.trackNumber !== void 0 && (!Number.isInteger(tags.trackNumber) || tags.trackNumber <= 0)) {
      throw new TypeError("tags.trackNumber, when provided, must be a positive integer.");
    }
    if (tags.tracksTotal !== void 0 && (!Number.isInteger(tags.tracksTotal) || tags.tracksTotal <= 0)) {
      throw new TypeError("tags.tracksTotal, when provided, must be a positive integer.");
    }
    if (tags.discNumber !== void 0 && (!Number.isInteger(tags.discNumber) || tags.discNumber <= 0)) {
      throw new TypeError("tags.discNumber, when provided, must be a positive integer.");
    }
    if (tags.discsTotal !== void 0 && (!Number.isInteger(tags.discsTotal) || tags.discsTotal <= 0)) {
      throw new TypeError("tags.discsTotal, when provided, must be a positive integer.");
    }
    if (tags.genre !== void 0 && typeof tags.genre !== "string") {
      throw new TypeError("tags.genre, when provided, must be a string.");
    }
    if (tags.date !== void 0 && (!(tags.date instanceof Date) || Number.isNaN(tags.date.getTime()))) {
      throw new TypeError("tags.date, when provided, must be a valid Date.");
    }
    if (tags.lyrics !== void 0 && typeof tags.lyrics !== "string") {
      throw new TypeError("tags.lyrics, when provided, must be a string.");
    }
    if (tags.images !== void 0) {
      if (!Array.isArray(tags.images)) {
        throw new TypeError("tags.images, when provided, must be an array.");
      }
      for (const image of tags.images) {
        if (!image || typeof image !== "object") {
          throw new TypeError("Each image in tags.images must be an object.");
        }
        if (!(image.data instanceof Uint8Array)) {
          throw new TypeError("Each image.data must be a Uint8Array.");
        }
        if (typeof image.mimeType !== "string") {
          throw new TypeError("Each image.mimeType must be a string.");
        }
        if (!["coverFront", "coverBack", "unknown"].includes(image.kind)) {
          throw new TypeError("Each image.kind must be 'coverFront', 'coverBack', or 'unknown'.");
        }
      }
    }
    if (tags.comment !== void 0 && typeof tags.comment !== "string") {
      throw new TypeError("tags.comment, when provided, must be a string.");
    }
    if (tags.raw !== void 0) {
      if (!tags.raw || typeof tags.raw !== "object") {
        throw new TypeError("tags.raw, when provided, must be an object.");
      }
      for (const value of Object.values(tags.raw)) {
        if (value !== null && typeof value !== "string" && !(value instanceof Uint8Array) && !(value instanceof RichImageData) && !(value instanceof AttachedFile)) {
          throw new TypeError(
            "Each value in tags.raw must be a string, Uint8Array, RichImageData, AttachedFile, or null."
          );
        }
      }
    }
  };
  var metadataTagsAreEmpty = (tags) => {
    return tags.title === void 0 && tags.description === void 0 && tags.artist === void 0 && tags.album === void 0 && tags.albumArtist === void 0 && tags.trackNumber === void 0 && tags.tracksTotal === void 0 && tags.discNumber === void 0 && tags.discsTotal === void 0 && tags.genre === void 0 && tags.date === void 0 && tags.lyrics === void 0 && (!tags.images || tags.images.length === 0) && tags.comment === void 0 && (tags.raw === void 0 || Object.keys(tags.raw).length === 0);
  };
  var DEFAULT_TRACK_DISPOSITION = {
    default: true,
    forced: false,
    original: false,
    commentary: false,
    hearingImpaired: false,
    visuallyImpaired: false
  };
  var validateTrackDisposition = (disposition) => {
    if (!disposition || typeof disposition !== "object") {
      throw new TypeError("disposition must be an object.");
    }
    if (disposition.default !== void 0 && typeof disposition.default !== "boolean") {
      throw new TypeError("disposition.default must be a boolean.");
    }
    if (disposition.forced !== void 0 && typeof disposition.forced !== "boolean") {
      throw new TypeError("disposition.forced must be a boolean.");
    }
    if (disposition.original !== void 0 && typeof disposition.original !== "boolean") {
      throw new TypeError("disposition.original must be a boolean.");
    }
    if (disposition.commentary !== void 0 && typeof disposition.commentary !== "boolean") {
      throw new TypeError("disposition.commentary must be a boolean.");
    }
    if (disposition.hearingImpaired !== void 0 && typeof disposition.hearingImpaired !== "boolean") {
      throw new TypeError("disposition.hearingImpaired must be a boolean.");
    }
    if (disposition.visuallyImpaired !== void 0 && typeof disposition.visuallyImpaired !== "boolean") {
      throw new TypeError("disposition.visuallyImpaired must be a boolean.");
    }
  };

  // src/codec.ts
  var VIDEO_CODECS = [
    "avc",
    "hevc",
    "vp9",
    "av1",
    "vp8"
  ];
  var PCM_AUDIO_CODECS = [
    "pcm-s16",
    // We don't prefix 'le' so we're compatible with the WebCodecs-registered PCM codec strings
    "pcm-s16be",
    "pcm-s24",
    "pcm-s24be",
    "pcm-s32",
    "pcm-s32be",
    "pcm-f32",
    "pcm-f32be",
    "pcm-f64",
    "pcm-f64be",
    "pcm-u8",
    "pcm-s8",
    "ulaw",
    "alaw"
  ];
  var NON_PCM_AUDIO_CODECS = [
    "aac",
    "opus",
    "mp3",
    "vorbis",
    "flac",
    "ac3",
    "eac3"
  ];
  var AUDIO_CODECS = [
    ...NON_PCM_AUDIO_CODECS,
    ...PCM_AUDIO_CODECS
  ];
  var SUBTITLE_CODECS = [
    "webvtt"
  ];
  var AVC_LEVEL_TABLE = [
    { maxMacroblocks: 99, maxBitrate: 64e3, maxDpbMbs: 396, level: 10 },
    // Level 1
    { maxMacroblocks: 396, maxBitrate: 192e3, maxDpbMbs: 900, level: 11 },
    // Level 1.1
    { maxMacroblocks: 396, maxBitrate: 384e3, maxDpbMbs: 2376, level: 12 },
    // Level 1.2
    { maxMacroblocks: 396, maxBitrate: 768e3, maxDpbMbs: 2376, level: 13 },
    // Level 1.3
    { maxMacroblocks: 396, maxBitrate: 2e6, maxDpbMbs: 2376, level: 20 },
    // Level 2
    { maxMacroblocks: 792, maxBitrate: 4e6, maxDpbMbs: 4752, level: 21 },
    // Level 2.1
    { maxMacroblocks: 1620, maxBitrate: 4e6, maxDpbMbs: 8100, level: 22 },
    // Level 2.2
    { maxMacroblocks: 1620, maxBitrate: 1e7, maxDpbMbs: 8100, level: 30 },
    // Level 3
    { maxMacroblocks: 3600, maxBitrate: 14e6, maxDpbMbs: 18e3, level: 31 },
    // Level 3.1
    { maxMacroblocks: 5120, maxBitrate: 2e7, maxDpbMbs: 20480, level: 32 },
    // Level 3.2
    { maxMacroblocks: 8192, maxBitrate: 2e7, maxDpbMbs: 32768, level: 40 },
    // Level 4
    { maxMacroblocks: 8192, maxBitrate: 5e7, maxDpbMbs: 32768, level: 41 },
    // Level 4.1
    { maxMacroblocks: 8704, maxBitrate: 5e7, maxDpbMbs: 34816, level: 42 },
    // Level 4.2
    { maxMacroblocks: 22080, maxBitrate: 135e6, maxDpbMbs: 110400, level: 50 },
    // Level 5
    { maxMacroblocks: 36864, maxBitrate: 24e7, maxDpbMbs: 184320, level: 51 },
    // Level 5.1
    { maxMacroblocks: 36864, maxBitrate: 24e7, maxDpbMbs: 184320, level: 52 },
    // Level 5.2
    { maxMacroblocks: 139264, maxBitrate: 24e7, maxDpbMbs: 696320, level: 60 },
    // Level 6
    { maxMacroblocks: 139264, maxBitrate: 48e7, maxDpbMbs: 696320, level: 61 },
    // Level 6.1
    { maxMacroblocks: 139264, maxBitrate: 8e8, maxDpbMbs: 696320, level: 62 }
    // Level 6.2
  ];
  var HEVC_LEVEL_TABLE = [
    { maxPictureSize: 36864, maxBitrate: 128e3, tier: "L", level: 30 },
    // Level 1 (Low Tier)
    { maxPictureSize: 122880, maxBitrate: 15e5, tier: "L", level: 60 },
    // Level 2 (Low Tier)
    { maxPictureSize: 245760, maxBitrate: 3e6, tier: "L", level: 63 },
    // Level 2.1 (Low Tier)
    { maxPictureSize: 552960, maxBitrate: 6e6, tier: "L", level: 90 },
    // Level 3 (Low Tier)
    { maxPictureSize: 983040, maxBitrate: 1e7, tier: "L", level: 93 },
    // Level 3.1 (Low Tier)
    { maxPictureSize: 2228224, maxBitrate: 12e6, tier: "L", level: 120 },
    // Level 4 (Low Tier)
    { maxPictureSize: 2228224, maxBitrate: 3e7, tier: "H", level: 120 },
    // Level 4 (High Tier)
    { maxPictureSize: 2228224, maxBitrate: 2e7, tier: "L", level: 123 },
    // Level 4.1 (Low Tier)
    { maxPictureSize: 2228224, maxBitrate: 5e7, tier: "H", level: 123 },
    // Level 4.1 (High Tier)
    { maxPictureSize: 8912896, maxBitrate: 25e6, tier: "L", level: 150 },
    // Level 5 (Low Tier)
    { maxPictureSize: 8912896, maxBitrate: 1e8, tier: "H", level: 150 },
    // Level 5 (High Tier)
    { maxPictureSize: 8912896, maxBitrate: 4e7, tier: "L", level: 153 },
    // Level 5.1 (Low Tier)
    { maxPictureSize: 8912896, maxBitrate: 16e7, tier: "H", level: 153 },
    // Level 5.1 (High Tier)
    { maxPictureSize: 8912896, maxBitrate: 6e7, tier: "L", level: 156 },
    // Level 5.2 (Low Tier)
    { maxPictureSize: 8912896, maxBitrate: 24e7, tier: "H", level: 156 },
    // Level 5.2 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 6e7, tier: "L", level: 180 },
    // Level 6 (Low Tier)
    { maxPictureSize: 35651584, maxBitrate: 24e7, tier: "H", level: 180 },
    // Level 6 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 12e7, tier: "L", level: 183 },
    // Level 6.1 (Low Tier)
    { maxPictureSize: 35651584, maxBitrate: 48e7, tier: "H", level: 183 },
    // Level 6.1 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 24e7, tier: "L", level: 186 },
    // Level 6.2 (Low Tier)
    { maxPictureSize: 35651584, maxBitrate: 8e8, tier: "H", level: 186 }
    // Level 6.2 (High Tier)
  ];
  var VP9_LEVEL_TABLE = [
    { maxPictureSize: 36864, maxBitrate: 2e5, level: 10 },
    // Level 1
    { maxPictureSize: 73728, maxBitrate: 8e5, level: 11 },
    // Level 1.1
    { maxPictureSize: 122880, maxBitrate: 18e5, level: 20 },
    // Level 2
    { maxPictureSize: 245760, maxBitrate: 36e5, level: 21 },
    // Level 2.1
    { maxPictureSize: 552960, maxBitrate: 72e5, level: 30 },
    // Level 3
    { maxPictureSize: 983040, maxBitrate: 12e6, level: 31 },
    // Level 3.1
    { maxPictureSize: 2228224, maxBitrate: 18e6, level: 40 },
    // Level 4
    { maxPictureSize: 2228224, maxBitrate: 3e7, level: 41 },
    // Level 4.1
    { maxPictureSize: 8912896, maxBitrate: 6e7, level: 50 },
    // Level 5
    { maxPictureSize: 8912896, maxBitrate: 12e7, level: 51 },
    // Level 5.1
    { maxPictureSize: 8912896, maxBitrate: 18e7, level: 52 },
    // Level 5.2
    { maxPictureSize: 35651584, maxBitrate: 18e7, level: 60 },
    // Level 6
    { maxPictureSize: 35651584, maxBitrate: 24e7, level: 61 },
    // Level 6.1
    { maxPictureSize: 35651584, maxBitrate: 48e7, level: 62 }
    // Level 6.2
  ];
  var AV1_LEVEL_TABLE = [
    { maxPictureSize: 147456, maxBitrate: 15e5, tier: "M", level: 0 },
    // Level 2.0 (Main Tier)
    { maxPictureSize: 278784, maxBitrate: 3e6, tier: "M", level: 1 },
    // Level 2.1 (Main Tier)
    { maxPictureSize: 665856, maxBitrate: 6e6, tier: "M", level: 4 },
    // Level 3.0 (Main Tier)
    { maxPictureSize: 1065024, maxBitrate: 1e7, tier: "M", level: 5 },
    // Level 3.1 (Main Tier)
    { maxPictureSize: 2359296, maxBitrate: 12e6, tier: "M", level: 8 },
    // Level 4.0 (Main Tier)
    { maxPictureSize: 2359296, maxBitrate: 3e7, tier: "H", level: 8 },
    // Level 4.0 (High Tier)
    { maxPictureSize: 2359296, maxBitrate: 2e7, tier: "M", level: 9 },
    // Level 4.1 (Main Tier)
    { maxPictureSize: 2359296, maxBitrate: 5e7, tier: "H", level: 9 },
    // Level 4.1 (High Tier)
    { maxPictureSize: 8912896, maxBitrate: 3e7, tier: "M", level: 12 },
    // Level 5.0 (Main Tier)
    { maxPictureSize: 8912896, maxBitrate: 1e8, tier: "H", level: 12 },
    // Level 5.0 (High Tier)
    { maxPictureSize: 8912896, maxBitrate: 4e7, tier: "M", level: 13 },
    // Level 5.1 (Main Tier)
    { maxPictureSize: 8912896, maxBitrate: 16e7, tier: "H", level: 13 },
    // Level 5.1 (High Tier)
    { maxPictureSize: 8912896, maxBitrate: 6e7, tier: "M", level: 14 },
    // Level 5.2 (Main Tier)
    { maxPictureSize: 8912896, maxBitrate: 24e7, tier: "H", level: 14 },
    // Level 5.2 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 6e7, tier: "M", level: 15 },
    // Level 5.3 (Main Tier)
    { maxPictureSize: 35651584, maxBitrate: 24e7, tier: "H", level: 15 },
    // Level 5.3 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 6e7, tier: "M", level: 16 },
    // Level 6.0 (Main Tier)
    { maxPictureSize: 35651584, maxBitrate: 24e7, tier: "H", level: 16 },
    // Level 6.0 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 1e8, tier: "M", level: 17 },
    // Level 6.1 (Main Tier)
    { maxPictureSize: 35651584, maxBitrate: 48e7, tier: "H", level: 17 },
    // Level 6.1 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 16e7, tier: "M", level: 18 },
    // Level 6.2 (Main Tier)
    { maxPictureSize: 35651584, maxBitrate: 8e8, tier: "H", level: 18 },
    // Level 6.2 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 16e7, tier: "M", level: 19 },
    // Level 6.3 (Main Tier)
    { maxPictureSize: 35651584, maxBitrate: 8e8, tier: "H", level: 19 }
    // Level 6.3 (High Tier)
  ];
  var VP9_DEFAULT_SUFFIX = ".01.01.01.01.00";
  var AV1_DEFAULT_SUFFIX = ".0.110.01.01.01.0";
  var buildVideoCodecString = (codec, width, height, bitrate) => {
    if (codec === "avc") {
      const profileIndication = 100;
      const totalMacroblocks = Math.ceil(width / 16) * Math.ceil(height / 16);
      const levelInfo = AVC_LEVEL_TABLE.find(
        (level) => totalMacroblocks <= level.maxMacroblocks && bitrate <= level.maxBitrate
      ) ?? last(AVC_LEVEL_TABLE);
      const levelIndication = levelInfo ? levelInfo.level : 0;
      const hexProfileIndication = profileIndication.toString(16).padStart(2, "0");
      const hexProfileCompatibility = "00";
      const hexLevelIndication = levelIndication.toString(16).padStart(2, "0");
      return `avc1.${hexProfileIndication}${hexProfileCompatibility}${hexLevelIndication}`;
    } else if (codec === "hevc") {
      const profilePrefix = "";
      const profileIdc = 1;
      const compatibilityFlags = "6";
      const pictureSize = width * height;
      const levelInfo = HEVC_LEVEL_TABLE.find(
        (level) => pictureSize <= level.maxPictureSize && bitrate <= level.maxBitrate
      ) ?? last(HEVC_LEVEL_TABLE);
      const constraintFlags = "B0";
      return `hev1.${profilePrefix}${profileIdc}.${compatibilityFlags}.${levelInfo.tier}${levelInfo.level}.${constraintFlags}`;
    } else if (codec === "vp8") {
      return "vp8";
    } else if (codec === "vp9") {
      const profile = "00";
      const pictureSize = width * height;
      const levelInfo = VP9_LEVEL_TABLE.find(
        (level) => pictureSize <= level.maxPictureSize && bitrate <= level.maxBitrate
      ) ?? last(VP9_LEVEL_TABLE);
      const bitDepth = "08";
      return `vp09.${profile}.${levelInfo.level.toString().padStart(2, "0")}.${bitDepth}`;
    } else if (codec === "av1") {
      const profile = 0;
      const pictureSize = width * height;
      const levelInfo = AV1_LEVEL_TABLE.find(
        (level2) => pictureSize <= level2.maxPictureSize && bitrate <= level2.maxBitrate
      ) ?? last(AV1_LEVEL_TABLE);
      const level = levelInfo.level.toString().padStart(2, "0");
      const bitDepth = "08";
      return `av01.${profile}.${level}${levelInfo.tier}.${bitDepth}`;
    }
    throw new TypeError(`Unhandled codec '${codec}'.`);
  };
  var generateVp9CodecConfigurationFromCodecString = (codecString) => {
    const parts = codecString.split(".");
    const profile = Number(parts[1]);
    const level = Number(parts[2]);
    const bitDepth = Number(parts[3]);
    const chromaSubsampling = parts[4] ? Number(parts[4]) : 1;
    return [
      1,
      1,
      profile,
      2,
      1,
      level,
      3,
      1,
      bitDepth,
      4,
      1,
      chromaSubsampling
    ];
  };
  var generateAv1CodecConfigurationFromCodecString = (codecString) => {
    const parts = codecString.split(".");
    const marker = 1;
    const version = 1;
    const firstByte = (marker << 7) + version;
    const profile = Number(parts[1]);
    const levelAndTier = parts[2];
    const level = Number(levelAndTier.slice(0, -1));
    const secondByte = (profile << 5) + level;
    const tier = levelAndTier.slice(-1) === "H" ? 1 : 0;
    const bitDepth = Number(parts[3]);
    const highBitDepth = bitDepth === 8 ? 0 : 1;
    const twelveBit = 0;
    const monochrome = parts[4] ? Number(parts[4]) : 0;
    const chromaSubsamplingX = parts[5] ? Number(parts[5][0]) : 1;
    const chromaSubsamplingY = parts[5] ? Number(parts[5][1]) : 1;
    const chromaSamplePosition = parts[5] ? Number(parts[5][2]) : 0;
    const thirdByte = (tier << 7) + (highBitDepth << 6) + (twelveBit << 5) + (monochrome << 4) + (chromaSubsamplingX << 3) + (chromaSubsamplingY << 2) + chromaSamplePosition;
    const initialPresentationDelayPresent = 0;
    const fourthByte = initialPresentationDelayPresent;
    return [firstByte, secondByte, thirdByte, fourthByte];
  };
  var extractVideoCodecString = (trackInfo) => {
    const { codec, codecDescription, colorSpace, avcCodecInfo, hevcCodecInfo, vp9CodecInfo, av1CodecInfo } = trackInfo;
    if (codec === "avc") {
      assert(trackInfo.avcType !== null);
      if (avcCodecInfo) {
        const bytes2 = new Uint8Array([
          avcCodecInfo.avcProfileIndication,
          avcCodecInfo.profileCompatibility,
          avcCodecInfo.avcLevelIndication
        ]);
        return `avc${trackInfo.avcType}.${bytesToHexString(bytes2)}`;
      }
      if (!codecDescription || codecDescription.byteLength < 4) {
        throw new TypeError("AVC decoder description is not provided or is not at least 4 bytes long.");
      }
      return `avc${trackInfo.avcType}.${bytesToHexString(codecDescription.subarray(1, 4))}`;
    } else if (codec === "hevc") {
      let generalProfileSpace;
      let generalProfileIdc;
      let compatibilityFlags;
      let generalTierFlag;
      let generalLevelIdc;
      let constraintFlags;
      if (hevcCodecInfo) {
        generalProfileSpace = hevcCodecInfo.generalProfileSpace;
        generalProfileIdc = hevcCodecInfo.generalProfileIdc;
        compatibilityFlags = reverseBitsU32(hevcCodecInfo.generalProfileCompatibilityFlags);
        generalTierFlag = hevcCodecInfo.generalTierFlag;
        generalLevelIdc = hevcCodecInfo.generalLevelIdc;
        constraintFlags = [...hevcCodecInfo.generalConstraintIndicatorFlags];
      } else {
        if (!codecDescription || codecDescription.byteLength < 23) {
          throw new TypeError("HEVC decoder description is not provided or is not at least 23 bytes long.");
        }
        const view2 = toDataView(codecDescription);
        const profileByte = view2.getUint8(1);
        generalProfileSpace = profileByte >> 6 & 3;
        generalProfileIdc = profileByte & 31;
        compatibilityFlags = reverseBitsU32(view2.getUint32(2));
        generalTierFlag = profileByte >> 5 & 1;
        generalLevelIdc = view2.getUint8(12);
        constraintFlags = [];
        for (let i = 0; i < 6; i++) {
          constraintFlags.push(view2.getUint8(6 + i));
        }
      }
      let codecString = "hev1.";
      codecString += ["", "A", "B", "C"][generalProfileSpace] + generalProfileIdc;
      codecString += ".";
      codecString += compatibilityFlags.toString(16).toUpperCase();
      codecString += ".";
      codecString += generalTierFlag === 0 ? "L" : "H";
      codecString += generalLevelIdc;
      while (constraintFlags.length > 0 && constraintFlags[constraintFlags.length - 1] === 0) {
        constraintFlags.pop();
      }
      if (constraintFlags.length > 0) {
        codecString += ".";
        codecString += constraintFlags.map((x) => x.toString(16).toUpperCase()).join(".");
      }
      return codecString;
    } else if (codec === "vp8") {
      return "vp8";
    } else if (codec === "vp9") {
      if (!vp9CodecInfo) {
        const pictureSize = trackInfo.width * trackInfo.height;
        let level2 = last(VP9_LEVEL_TABLE).level;
        for (const entry of VP9_LEVEL_TABLE) {
          if (pictureSize <= entry.maxPictureSize) {
            level2 = entry.level;
            break;
          }
        }
        return `vp09.00.${level2.toString().padStart(2, "0")}.08`;
      }
      const profile = vp9CodecInfo.profile.toString().padStart(2, "0");
      const level = vp9CodecInfo.level.toString().padStart(2, "0");
      const bitDepth = vp9CodecInfo.bitDepth.toString().padStart(2, "0");
      const chromaSubsampling = vp9CodecInfo.chromaSubsampling.toString().padStart(2, "0");
      const colourPrimaries = vp9CodecInfo.colourPrimaries.toString().padStart(2, "0");
      const transferCharacteristics = vp9CodecInfo.transferCharacteristics.toString().padStart(2, "0");
      const matrixCoefficients = vp9CodecInfo.matrixCoefficients.toString().padStart(2, "0");
      const videoFullRangeFlag = vp9CodecInfo.videoFullRangeFlag.toString().padStart(2, "0");
      let string = `vp09.${profile}.${level}.${bitDepth}.${chromaSubsampling}`;
      string += `.${colourPrimaries}.${transferCharacteristics}.${matrixCoefficients}.${videoFullRangeFlag}`;
      if (string.endsWith(VP9_DEFAULT_SUFFIX)) {
        string = string.slice(0, -VP9_DEFAULT_SUFFIX.length);
      }
      return string;
    } else if (codec === "av1") {
      if (!av1CodecInfo) {
        const pictureSize = trackInfo.width * trackInfo.height;
        let level2 = last(VP9_LEVEL_TABLE).level;
        for (const entry of VP9_LEVEL_TABLE) {
          if (pictureSize <= entry.maxPictureSize) {
            level2 = entry.level;
            break;
          }
        }
        return `av01.0.${level2.toString().padStart(2, "0")}M.08`;
      }
      const profile = av1CodecInfo.profile;
      const level = av1CodecInfo.level.toString().padStart(2, "0");
      const tier = av1CodecInfo.tier ? "H" : "M";
      const bitDepth = av1CodecInfo.bitDepth.toString().padStart(2, "0");
      const monochrome = av1CodecInfo.monochrome ? "1" : "0";
      const chromaSubsampling = 100 * av1CodecInfo.chromaSubsamplingX + 10 * av1CodecInfo.chromaSubsamplingY + 1 * (av1CodecInfo.chromaSubsamplingX && av1CodecInfo.chromaSubsamplingY ? av1CodecInfo.chromaSamplePosition : 0);
      const colorPrimaries = colorSpace?.primaries ? COLOR_PRIMARIES_MAP[colorSpace.primaries] : 1;
      const transferCharacteristics = colorSpace?.transfer ? TRANSFER_CHARACTERISTICS_MAP[colorSpace.transfer] : 1;
      const matrixCoefficients = colorSpace?.matrix ? MATRIX_COEFFICIENTS_MAP[colorSpace.matrix] : 1;
      const videoFullRangeFlag = colorSpace?.fullRange ? 1 : 0;
      let string = `av01.${profile}.${level}${tier}.${bitDepth}`;
      string += `.${monochrome}.${chromaSubsampling.toString().padStart(3, "0")}`;
      string += `.${colorPrimaries.toString().padStart(2, "0")}`;
      string += `.${transferCharacteristics.toString().padStart(2, "0")}`;
      string += `.${matrixCoefficients.toString().padStart(2, "0")}`;
      string += `.${videoFullRangeFlag}`;
      if (string.endsWith(AV1_DEFAULT_SUFFIX)) {
        string = string.slice(0, -AV1_DEFAULT_SUFFIX.length);
      }
      return string;
    }
    throw new TypeError(`Unhandled codec '${codec}'.`);
  };
  var buildAudioCodecString = (codec, numberOfChannels, sampleRate) => {
    if (codec === "aac") {
      if (numberOfChannels >= 2 && sampleRate <= 24e3) {
        return "mp4a.40.29";
      }
      if (sampleRate <= 24e3) {
        return "mp4a.40.5";
      }
      return "mp4a.40.2";
    } else if (codec === "mp3") {
      return "mp3";
    } else if (codec === "opus") {
      return "opus";
    } else if (codec === "vorbis") {
      return "vorbis";
    } else if (codec === "flac") {
      return "flac";
    } else if (codec === "ac3") {
      return "ac-3";
    } else if (codec === "eac3") {
      return "ec-3";
    } else if (PCM_AUDIO_CODECS.includes(codec)) {
      return codec;
    }
    throw new TypeError(`Unhandled codec '${codec}'.`);
  };
  var extractAudioCodecString = (trackInfo) => {
    const { codec, codecDescription, aacCodecInfo } = trackInfo;
    if (codec === "aac") {
      if (!aacCodecInfo) {
        throw new TypeError("AAC codec info must be provided.");
      }
      if (aacCodecInfo.isMpeg2) {
        return "mp4a.67";
      } else {
        let objectType;
        if (aacCodecInfo.objectType !== null) {
          objectType = aacCodecInfo.objectType;
        } else {
          const audioSpecificConfig = parseAacAudioSpecificConfig(codecDescription);
          objectType = audioSpecificConfig.objectType;
        }
        return `mp4a.40.${objectType}`;
      }
    } else if (codec === "mp3") {
      return "mp3";
    } else if (codec === "opus") {
      return "opus";
    } else if (codec === "vorbis") {
      return "vorbis";
    } else if (codec === "flac") {
      return "flac";
    } else if (codec === "ac3") {
      return "ac-3";
    } else if (codec === "eac3") {
      return "ec-3";
    } else if (codec && PCM_AUDIO_CODECS.includes(codec)) {
      return codec;
    }
    throw new TypeError(`Unhandled codec '${codec}'.`);
  };
  var aacFrequencyTable = [
    96e3,
    88200,
    64e3,
    48e3,
    44100,
    32e3,
    24e3,
    22050,
    16e3,
    12e3,
    11025,
    8e3,
    7350
  ];
  var aacChannelMap = [-1, 1, 2, 3, 4, 5, 6, 8];
  var parseAacAudioSpecificConfig = (bytes2) => {
    if (!bytes2 || bytes2.byteLength < 2) {
      throw new TypeError("AAC description must be at least 2 bytes long.");
    }
    const bitstream = new Bitstream(bytes2);
    let objectType = bitstream.readBits(5);
    if (objectType === 31) {
      objectType = 32 + bitstream.readBits(6);
    }
    const frequencyIndex = bitstream.readBits(4);
    let sampleRate = null;
    if (frequencyIndex === 15) {
      sampleRate = bitstream.readBits(24);
    } else {
      if (frequencyIndex < aacFrequencyTable.length) {
        sampleRate = aacFrequencyTable[frequencyIndex];
      }
    }
    const channelConfiguration = bitstream.readBits(4);
    let numberOfChannels = null;
    if (channelConfiguration >= 1 && channelConfiguration <= 7) {
      numberOfChannels = aacChannelMap[channelConfiguration];
    }
    return {
      objectType,
      frequencyIndex,
      sampleRate,
      channelConfiguration,
      numberOfChannels
    };
  };
  var buildAacAudioSpecificConfig = (config) => {
    let frequencyIndex = aacFrequencyTable.indexOf(config.sampleRate);
    let customSampleRate = null;
    if (frequencyIndex === -1) {
      frequencyIndex = 15;
      customSampleRate = config.sampleRate;
    }
    const channelConfiguration = aacChannelMap.indexOf(config.numberOfChannels);
    if (channelConfiguration === -1) {
      throw new TypeError(`Unsupported number of channels: ${config.numberOfChannels}`);
    }
    let bitCount = 5 + 4 + 4;
    if (config.objectType >= 32) {
      bitCount += 6;
    }
    if (frequencyIndex === 15) {
      bitCount += 24;
    }
    const byteCount = Math.ceil(bitCount / 8);
    const bytes2 = new Uint8Array(byteCount);
    const bitstream = new Bitstream(bytes2);
    if (config.objectType < 32) {
      bitstream.writeBits(5, config.objectType);
    } else {
      bitstream.writeBits(5, 31);
      bitstream.writeBits(6, config.objectType - 32);
    }
    bitstream.writeBits(4, frequencyIndex);
    if (frequencyIndex === 15) {
      bitstream.writeBits(24, customSampleRate);
    }
    bitstream.writeBits(4, channelConfiguration);
    return bytes2;
  };
  var OPUS_SAMPLE_RATE = 48e3;
  var PCM_CODEC_REGEX = /^pcm-([usf])(\d+)+(be)?$/;
  var parsePcmCodec = (codec) => {
    assert(PCM_AUDIO_CODECS.includes(codec));
    if (codec === "ulaw") {
      return { dataType: "ulaw", sampleSize: 1, littleEndian: true, silentValue: 255 };
    } else if (codec === "alaw") {
      return { dataType: "alaw", sampleSize: 1, littleEndian: true, silentValue: 213 };
    }
    const match = PCM_CODEC_REGEX.exec(codec);
    assert(match);
    let dataType;
    if (match[1] === "u") {
      dataType = "unsigned";
    } else if (match[1] === "s") {
      dataType = "signed";
    } else {
      dataType = "float";
    }
    const sampleSize = Number(match[2]) / 8;
    const littleEndian = match[3] !== "be";
    const silentValue = codec === "pcm-u8" ? 2 ** 7 : 0;
    return { dataType, sampleSize, littleEndian, silentValue };
  };
  var inferCodecFromCodecString = (codecString) => {
    if (codecString.startsWith("avc1") || codecString.startsWith("avc3")) {
      return "avc";
    } else if (codecString.startsWith("hev1") || codecString.startsWith("hvc1")) {
      return "hevc";
    } else if (codecString === "vp8") {
      return "vp8";
    } else if (codecString.startsWith("vp09")) {
      return "vp9";
    } else if (codecString.startsWith("av01")) {
      return "av1";
    }
    if (codecString.startsWith("mp4a.40") || codecString === "mp4a.67") {
      return "aac";
    } else if (codecString === "mp3" || codecString === "mp4a.69" || codecString === "mp4a.6B" || codecString === "mp4a.6b") {
      return "mp3";
    } else if (codecString === "opus") {
      return "opus";
    } else if (codecString === "vorbis") {
      return "vorbis";
    } else if (codecString === "flac") {
      return "flac";
    } else if (codecString === "ac-3" || codecString === "ac3") {
      return "ac3";
    } else if (codecString === "ec-3" || codecString === "eac3") {
      return "eac3";
    } else if (codecString === "ulaw") {
      return "ulaw";
    } else if (codecString === "alaw") {
      return "alaw";
    } else if (PCM_CODEC_REGEX.test(codecString)) {
      return codecString;
    }
    if (codecString === "webvtt") {
      return "webvtt";
    }
    return null;
  };
  var getVideoEncoderConfigExtension = (codec) => {
    if (codec === "avc") {
      return {
        avc: {
          format: "avc"
          // Ensure the format is not Annex B
        }
      };
    } else if (codec === "hevc") {
      return {
        hevc: {
          format: "hevc"
          // Ensure the format is not Annex B
        }
      };
    }
    return {};
  };
  var getAudioEncoderConfigExtension = (codec) => {
    if (codec === "aac") {
      return {
        aac: {
          format: "aac"
          // Ensure the format is not ADTS
        }
      };
    } else if (codec === "opus") {
      return {
        opus: {
          format: "opus"
        }
      };
    }
    return {};
  };
  var VALID_VIDEO_CODEC_STRING_PREFIXES = ["avc1", "avc3", "hev1", "hvc1", "vp8", "vp09", "av01"];
  var AVC_CODEC_STRING_REGEX = /^(avc1|avc3)\.[0-9a-fA-F]{6}$/;
  var HEVC_CODEC_STRING_REGEX = /^(hev1|hvc1)\.(?:[ABC]?\d+)\.[0-9a-fA-F]{1,8}\.[LH]\d+(?:\.[0-9a-fA-F]{1,2}){0,6}$/;
  var VP9_CODEC_STRING_REGEX = /^vp09(?:\.\d{2}){3}(?:(?:\.\d{2}){5})?$/;
  var AV1_CODEC_STRING_REGEX = /^av01\.\d\.\d{2}[MH]\.\d{2}(?:\.\d\.\d{3}\.\d{2}\.\d{2}\.\d{2}\.\d)?$/;
  var validateVideoChunkMetadata = (metadata) => {
    if (!metadata) {
      throw new TypeError("Video chunk metadata must be provided.");
    }
    if (typeof metadata !== "object") {
      throw new TypeError("Video chunk metadata must be an object.");
    }
    if (!metadata.decoderConfig) {
      throw new TypeError("Video chunk metadata must include a decoder configuration.");
    }
    if (typeof metadata.decoderConfig !== "object") {
      throw new TypeError("Video chunk metadata decoder configuration must be an object.");
    }
    if (typeof metadata.decoderConfig.codec !== "string") {
      throw new TypeError("Video chunk metadata decoder configuration must specify a codec string.");
    }
    if (!VALID_VIDEO_CODEC_STRING_PREFIXES.some((prefix) => metadata.decoderConfig.codec.startsWith(prefix))) {
      throw new TypeError(
        "Video chunk metadata decoder configuration codec string must be a valid video codec string as specified in the Mediabunny Codec Registry."
      );
    }
    if (!Number.isInteger(metadata.decoderConfig.codedWidth) || metadata.decoderConfig.codedWidth <= 0) {
      throw new TypeError(
        "Video chunk metadata decoder configuration must specify a valid codedWidth (positive integer)."
      );
    }
    if (!Number.isInteger(metadata.decoderConfig.codedHeight) || metadata.decoderConfig.codedHeight <= 0) {
      throw new TypeError(
        "Video chunk metadata decoder configuration must specify a valid codedHeight (positive integer)."
      );
    }
    if (metadata.decoderConfig.description !== void 0) {
      if (!isAllowSharedBufferSource(metadata.decoderConfig.description)) {
        throw new TypeError(
          "Video chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view."
        );
      }
    }
    if (metadata.decoderConfig.colorSpace !== void 0) {
      const { colorSpace } = metadata.decoderConfig;
      if (typeof colorSpace !== "object") {
        throw new TypeError(
          "Video chunk metadata decoder configuration colorSpace, when provided, must be an object."
        );
      }
      const primariesValues = Object.keys(COLOR_PRIMARIES_MAP);
      if (colorSpace.primaries != null && !primariesValues.includes(colorSpace.primaries)) {
        throw new TypeError(
          `Video chunk metadata decoder configuration colorSpace primaries, when defined, must be one of ${primariesValues.join(", ")}.`
        );
      }
      const transferValues = Object.keys(TRANSFER_CHARACTERISTICS_MAP);
      if (colorSpace.transfer != null && !transferValues.includes(colorSpace.transfer)) {
        throw new TypeError(
          `Video chunk metadata decoder configuration colorSpace transfer, when defined, must be one of ${transferValues.join(", ")}.`
        );
      }
      const matrixValues = Object.keys(MATRIX_COEFFICIENTS_MAP);
      if (colorSpace.matrix != null && !matrixValues.includes(colorSpace.matrix)) {
        throw new TypeError(
          `Video chunk metadata decoder configuration colorSpace matrix, when defined, must be one of ${matrixValues.join(", ")}.`
        );
      }
      if (colorSpace.fullRange != null && typeof colorSpace.fullRange !== "boolean") {
        throw new TypeError(
          "Video chunk metadata decoder configuration colorSpace fullRange, when defined, must be a boolean."
        );
      }
    }
    if (metadata.decoderConfig.codec.startsWith("avc1") || metadata.decoderConfig.codec.startsWith("avc3")) {
      if (!AVC_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {
        throw new TypeError(
          "Video chunk metadata decoder configuration codec string for AVC must be a valid AVC codec string as specified in Section 3.4 of RFC 6381."
        );
      }
    } else if (metadata.decoderConfig.codec.startsWith("hev1") || metadata.decoderConfig.codec.startsWith("hvc1")) {
      if (!HEVC_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {
        throw new TypeError(
          "Video chunk metadata decoder configuration codec string for HEVC must be a valid HEVC codec string as specified in Section E.3 of ISO 14496-15."
        );
      }
    } else if (metadata.decoderConfig.codec.startsWith("vp8")) {
      if (metadata.decoderConfig.codec !== "vp8") {
        throw new TypeError('Video chunk metadata decoder configuration codec string for VP8 must be "vp8".');
      }
    } else if (metadata.decoderConfig.codec.startsWith("vp09")) {
      if (!VP9_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {
        throw new TypeError(
          'Video chunk metadata decoder configuration codec string for VP9 must be a valid VP9 codec string as specified in Section "Codecs Parameter String" of https://www.webmproject.org/vp9/mp4/.'
        );
      }
    } else if (metadata.decoderConfig.codec.startsWith("av01")) {
      if (!AV1_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {
        throw new TypeError(
          'Video chunk metadata decoder configuration codec string for AV1 must be a valid AV1 codec string as specified in Section "Codecs Parameter String" of https://aomediacodec.github.io/av1-isobmff/.'
        );
      }
    }
  };
  var VALID_AUDIO_CODEC_STRING_PREFIXES = [
    "mp4a",
    "mp3",
    "opus",
    "vorbis",
    "flac",
    "ulaw",
    "alaw",
    "pcm",
    "ac-3",
    "ec-3"
  ];
  var validateAudioChunkMetadata = (metadata) => {
    if (!metadata) {
      throw new TypeError("Audio chunk metadata must be provided.");
    }
    if (typeof metadata !== "object") {
      throw new TypeError("Audio chunk metadata must be an object.");
    }
    if (!metadata.decoderConfig) {
      throw new TypeError("Audio chunk metadata must include a decoder configuration.");
    }
    if (typeof metadata.decoderConfig !== "object") {
      throw new TypeError("Audio chunk metadata decoder configuration must be an object.");
    }
    if (typeof metadata.decoderConfig.codec !== "string") {
      throw new TypeError("Audio chunk metadata decoder configuration must specify a codec string.");
    }
    if (!VALID_AUDIO_CODEC_STRING_PREFIXES.some((prefix) => metadata.decoderConfig.codec.startsWith(prefix))) {
      throw new TypeError(
        "Audio chunk metadata decoder configuration codec string must be a valid audio codec string as specified in the Mediabunny Codec Registry."
      );
    }
    if (!Number.isInteger(metadata.decoderConfig.sampleRate) || metadata.decoderConfig.sampleRate <= 0) {
      throw new TypeError(
        "Audio chunk metadata decoder configuration must specify a valid sampleRate (positive integer)."
      );
    }
    if (!Number.isInteger(metadata.decoderConfig.numberOfChannels) || metadata.decoderConfig.numberOfChannels <= 0) {
      throw new TypeError(
        "Audio chunk metadata decoder configuration must specify a valid numberOfChannels (positive integer)."
      );
    }
    if (metadata.decoderConfig.description !== void 0) {
      if (!isAllowSharedBufferSource(metadata.decoderConfig.description)) {
        throw new TypeError(
          "Audio chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view."
        );
      }
    }
    if (metadata.decoderConfig.codec.startsWith("mp4a") && metadata.decoderConfig.codec !== "mp4a.69" && metadata.decoderConfig.codec !== "mp4a.6B" && metadata.decoderConfig.codec !== "mp4a.6b") {
      const validStrings = ["mp4a.40.2", "mp4a.40.02", "mp4a.40.5", "mp4a.40.05", "mp4a.40.29", "mp4a.67"];
      if (!validStrings.includes(metadata.decoderConfig.codec)) {
        throw new TypeError(
          "Audio chunk metadata decoder configuration codec string for AAC must be a valid AAC codec string as specified in https://www.w3.org/TR/webcodecs-aac-codec-registration/."
        );
      }
    } else if (metadata.decoderConfig.codec.startsWith("mp3") || metadata.decoderConfig.codec.startsWith("mp4a")) {
      if (metadata.decoderConfig.codec !== "mp3" && metadata.decoderConfig.codec !== "mp4a.69" && metadata.decoderConfig.codec !== "mp4a.6B" && metadata.decoderConfig.codec !== "mp4a.6b") {
        throw new TypeError(
          'Audio chunk metadata decoder configuration codec string for MP3 must be "mp3", "mp4a.69" or "mp4a.6B".'
        );
      }
    } else if (metadata.decoderConfig.codec.startsWith("opus")) {
      if (metadata.decoderConfig.codec !== "opus") {
        throw new TypeError('Audio chunk metadata decoder configuration codec string for Opus must be "opus".');
      }
      if (metadata.decoderConfig.description && metadata.decoderConfig.description.byteLength < 18) {
        throw new TypeError(
          "Audio chunk metadata decoder configuration description, when specified, is expected to be an Identification Header as specified in Section 5.1 of RFC 7845."
        );
      }
    } else if (metadata.decoderConfig.codec.startsWith("vorbis")) {
      if (metadata.decoderConfig.codec !== "vorbis") {
        throw new TypeError('Audio chunk metadata decoder configuration codec string for Vorbis must be "vorbis".');
      }
      if (!metadata.decoderConfig.description) {
        throw new TypeError(
          "Audio chunk metadata decoder configuration for Vorbis must include a description, which is expected to adhere to the format described in https://www.w3.org/TR/webcodecs-vorbis-codec-registration/."
        );
      }
    } else if (metadata.decoderConfig.codec.startsWith("flac")) {
      if (metadata.decoderConfig.codec !== "flac") {
        throw new TypeError('Audio chunk metadata decoder configuration codec string for FLAC must be "flac".');
      }
      const minDescriptionSize = 4 + 4 + 34;
      if (!metadata.decoderConfig.description || metadata.decoderConfig.description.byteLength < minDescriptionSize) {
        throw new TypeError(
          "Audio chunk metadata decoder configuration for FLAC must include a description, which is expected to adhere to the format described in https://www.w3.org/TR/webcodecs-flac-codec-registration/."
        );
      }
    } else if (metadata.decoderConfig.codec.startsWith("ac-3") || metadata.decoderConfig.codec.startsWith("ac3")) {
      if (metadata.decoderConfig.codec !== "ac-3") {
        throw new TypeError('Audio chunk metadata decoder configuration codec string for AC-3 must be "ac-3".');
      }
    } else if (metadata.decoderConfig.codec.startsWith("ec-3") || metadata.decoderConfig.codec.startsWith("eac3")) {
      if (metadata.decoderConfig.codec !== "ec-3") {
        throw new TypeError('Audio chunk metadata decoder configuration codec string for EC-3 must be "ec-3".');
      }
    } else if (metadata.decoderConfig.codec.startsWith("pcm") || metadata.decoderConfig.codec.startsWith("ulaw") || metadata.decoderConfig.codec.startsWith("alaw")) {
      if (!PCM_AUDIO_CODECS.includes(metadata.decoderConfig.codec)) {
        throw new TypeError(
          `Audio chunk metadata decoder configuration codec string for PCM must be one of the supported PCM codecs (${PCM_AUDIO_CODECS.join(", ")}).`
        );
      }
    }
  };
  var validateSubtitleMetadata = (metadata) => {
    if (!metadata) {
      throw new TypeError("Subtitle metadata must be provided.");
    }
    if (typeof metadata !== "object") {
      throw new TypeError("Subtitle metadata must be an object.");
    }
    if (!metadata.config) {
      throw new TypeError("Subtitle metadata must include a config object.");
    }
    if (typeof metadata.config !== "object") {
      throw new TypeError("Subtitle metadata config must be an object.");
    }
    if (typeof metadata.config.description !== "string") {
      throw new TypeError("Subtitle metadata config description must be a string.");
    }
  };

  // shared/mp3-misc.ts
  var FRAME_HEADER_SIZE = 4;
  var SAMPLING_RATES = [44100, 48e3, 32e3];
  var KILOBIT_RATES = [
    // lowSamplingFrequency === 0
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    // layer = 0
    -1,
    32,
    40,
    48,
    56,
    64,
    80,
    96,
    112,
    128,
    160,
    192,
    224,
    256,
    320,
    -1,
    // layer 1
    -1,
    32,
    48,
    56,
    64,
    80,
    96,
    112,
    128,
    160,
    192,
    224,
    256,
    320,
    384,
    -1,
    // layer = 2
    -1,
    32,
    64,
    96,
    128,
    160,
    192,
    224,
    256,
    288,
    320,
    352,
    384,
    416,
    448,
    -1,
    // layer = 3
    // lowSamplingFrequency === 1
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    -1,
    // layer = 0
    -1,
    8,
    16,
    24,
    32,
    40,
    48,
    56,
    64,
    80,
    96,
    112,
    128,
    144,
    160,
    -1,
    // layer = 1
    -1,
    8,
    16,
    24,
    32,
    40,
    48,
    56,
    64,
    80,
    96,
    112,
    128,
    144,
    160,
    -1,
    // layer = 2
    -1,
    32,
    48,
    56,
    64,
    80,
    96,
    112,
    128,
    144,
    160,
    176,
    192,
    224,
    256,
    -1
    // layer = 3
  ];
  var XING = 1483304551;
  var INFO = 1231971951;
  var computeMp3FrameSize = (lowSamplingFrequency, layer, bitrate, sampleRate, padding) => {
    if (layer === 0) {
      return 0;
    } else if (layer === 1) {
      return Math.floor(144 * bitrate / (sampleRate << lowSamplingFrequency)) + padding;
    } else if (layer === 2) {
      return Math.floor(144 * bitrate / sampleRate) + padding;
    } else {
      return (Math.floor(12 * bitrate / sampleRate) + padding) * 4;
    }
  };
  var getXingOffset = (mpegVersionId, channel) => {
    return mpegVersionId === 3 ? channel === 3 ? 21 : 36 : channel === 3 ? 13 : 21;
  };
  var readMp3FrameHeader = (word, remainingBytes) => {
    const firstByte = word >>> 24;
    const secondByte = word >>> 16 & 255;
    const thirdByte = word >>> 8 & 255;
    const fourthByte = word & 255;
    if (firstByte !== 255 && secondByte !== 255 && thirdByte !== 255 && fourthByte !== 255) {
      return {
        header: null,
        bytesAdvanced: 4
      };
    }
    if (firstByte !== 255) {
      return { header: null, bytesAdvanced: 1 };
    }
    if ((secondByte & 224) !== 224) {
      return { header: null, bytesAdvanced: 1 };
    }
    let lowSamplingFrequency = 0;
    let mpeg25 = 0;
    if (secondByte & 1 << 4) {
      lowSamplingFrequency = secondByte & 1 << 3 ? 0 : 1;
    } else {
      lowSamplingFrequency = 1;
      mpeg25 = 1;
    }
    const mpegVersionId = secondByte >> 3 & 3;
    const layer = secondByte >> 1 & 3;
    const bitrateIndex = thirdByte >> 4 & 15;
    const frequencyIndex = (thirdByte >> 2 & 3) % 3;
    const padding = thirdByte >> 1 & 1;
    const channel = fourthByte >> 6 & 3;
    const modeExtension = fourthByte >> 4 & 3;
    const copyright = fourthByte >> 3 & 1;
    const original = fourthByte >> 2 & 1;
    const emphasis = fourthByte & 3;
    const kilobitRate = KILOBIT_RATES[lowSamplingFrequency * 16 * 4 + layer * 16 + bitrateIndex];
    if (kilobitRate === -1) {
      return { header: null, bytesAdvanced: 1 };
    }
    const bitrate = kilobitRate * 1e3;
    const sampleRate = SAMPLING_RATES[frequencyIndex] >> lowSamplingFrequency + mpeg25;
    const frameLength = computeMp3FrameSize(lowSamplingFrequency, layer, bitrate, sampleRate, padding);
    if (remainingBytes !== null && remainingBytes < frameLength) {
      return { header: null, bytesAdvanced: 1 };
    }
    let audioSamplesInFrame;
    if (mpegVersionId === 3) {
      audioSamplesInFrame = layer === 3 ? 384 : 1152;
    } else {
      if (layer === 3) {
        audioSamplesInFrame = 384;
      } else if (layer === 2) {
        audioSamplesInFrame = 1152;
      } else {
        audioSamplesInFrame = 576;
      }
    }
    return {
      header: {
        totalSize: frameLength,
        mpegVersionId,
        layer,
        bitrate,
        frequencyIndex,
        sampleRate,
        channel,
        modeExtension,
        copyright,
        original,
        emphasis,
        audioSamplesInFrame
      },
      bytesAdvanced: 1
    };
  };
  var encodeSynchsafe = (unsynchsafed) => {
    let mask = 127;
    let synchsafed = 0;
    let unsynchsafedRest = unsynchsafed;
    while ((mask ^ 2147483647) !== 0) {
      synchsafed = unsynchsafedRest & ~mask;
      synchsafed <<= 1;
      synchsafed |= unsynchsafedRest & mask;
      mask = (mask + 1 << 8) - 1;
      unsynchsafedRest = synchsafed;
    }
    return synchsafed;
  };
  var decodeSynchsafe = (synchsafed) => {
    let mask = 2130706432;
    let unsynchsafed = 0;
    while (mask !== 0) {
      unsynchsafed >>= 1;
      unsynchsafed |= synchsafed & mask;
      mask >>= 8;
    }
    return unsynchsafed;
  };

  // shared/ac3-misc.ts
  var AC3_SAMPLE_RATES = [48e3, 44100, 32e3];
  var EAC3_REDUCED_SAMPLE_RATES = [24e3, 22050, 16e3];

  // src/codec-data.ts
  var iterateNalUnitsInAnnexB = function* (packetData) {
    let i = 0;
    let nalStart = -1;
    while (i < packetData.length - 2) {
      const zeroIndex = packetData.indexOf(0, i);
      if (zeroIndex === -1 || zeroIndex >= packetData.length - 2) {
        break;
      }
      i = zeroIndex;
      let startCodeLength = 0;
      if (i + 3 < packetData.length && packetData[i + 1] === 0 && packetData[i + 2] === 0 && packetData[i + 3] === 1) {
        startCodeLength = 4;
      } else if (packetData[i + 1] === 0 && packetData[i + 2] === 1) {
        startCodeLength = 3;
      }
      if (startCodeLength === 0) {
        i++;
        continue;
      }
      if (nalStart !== -1 && i > nalStart) {
        yield {
          offset: nalStart,
          length: i - nalStart
        };
      }
      nalStart = i + startCodeLength;
      i = nalStart;
    }
    if (nalStart !== -1 && nalStart < packetData.length) {
      yield {
        offset: nalStart,
        length: packetData.length - nalStart
      };
    }
  };
  var iterateNalUnitsInLengthPrefixed = function* (packetData, lengthSize) {
    let offset = 0;
    const dataView = new DataView(packetData.buffer, packetData.byteOffset, packetData.byteLength);
    while (offset + lengthSize <= packetData.length) {
      let nalUnitLength;
      if (lengthSize === 1) {
        nalUnitLength = dataView.getUint8(offset);
      } else if (lengthSize === 2) {
        nalUnitLength = dataView.getUint16(offset, false);
      } else if (lengthSize === 3) {
        nalUnitLength = getUint24(dataView, offset, false);
      } else {
        assert(lengthSize === 4);
        nalUnitLength = dataView.getUint32(offset, false);
      }
      offset += lengthSize;
      yield {
        offset,
        length: nalUnitLength
      };
      offset += nalUnitLength;
    }
  };
  var iterateAvcNalUnits = (packetData, decoderConfig) => {
    if (decoderConfig.description) {
      const bytes2 = toUint8Array(decoderConfig.description);
      const lengthSizeMinusOne = bytes2[4] & 3;
      const lengthSize = lengthSizeMinusOne + 1;
      return iterateNalUnitsInLengthPrefixed(packetData, lengthSize);
    } else {
      return iterateNalUnitsInAnnexB(packetData);
    }
  };
  var extractNalUnitTypeForAvc = (byte) => {
    return byte & 31;
  };
  var removeEmulationPreventionBytes = (data) => {
    const result = [];
    const len = data.length;
    for (let i = 0; i < len; i++) {
      if (i + 2 < len && data[i] === 0 && data[i + 1] === 0 && data[i + 2] === 3) {
        result.push(0, 0);
        i += 2;
      } else {
        result.push(data[i]);
      }
    }
    return new Uint8Array(result);
  };
  var ANNEX_B_START_CODE = new Uint8Array([0, 0, 0, 1]);
  var concatNalUnitsInAnnexB = (nalUnits) => {
    const totalLength = nalUnits.reduce((a, b) => a + ANNEX_B_START_CODE.byteLength + b.byteLength, 0);
    const result = new Uint8Array(totalLength);
    let offset = 0;
    for (const nalUnit of nalUnits) {
      result.set(ANNEX_B_START_CODE, offset);
      offset += ANNEX_B_START_CODE.byteLength;
      result.set(nalUnit, offset);
      offset += nalUnit.byteLength;
    }
    return result;
  };
  var concatNalUnitsInLengthPrefixed = (nalUnits, lengthSize) => {
    const totalLength = nalUnits.reduce((a, b) => a + lengthSize + b.byteLength, 0);
    const result = new Uint8Array(totalLength);
    let offset = 0;
    for (const nalUnit of nalUnits) {
      const dataView = new DataView(result.buffer, result.byteOffset, result.byteLength);
      switch (lengthSize) {
        case 1:
          dataView.setUint8(offset, nalUnit.byteLength);
          break;
        case 2:
          dataView.setUint16(offset, nalUnit.byteLength, false);
          break;
        case 3:
          setUint24(dataView, offset, nalUnit.byteLength, false);
          break;
        case 4:
          dataView.setUint32(offset, nalUnit.byteLength, false);
          break;
      }
      offset += lengthSize;
      result.set(nalUnit, offset);
      offset += nalUnit.byteLength;
    }
    return result;
  };
  var concatAvcNalUnits = (nalUnits, decoderConfig) => {
    if (decoderConfig.description) {
      const bytes2 = toUint8Array(decoderConfig.description);
      const lengthSizeMinusOne = bytes2[4] & 3;
      const lengthSize = lengthSizeMinusOne + 1;
      return concatNalUnitsInLengthPrefixed(nalUnits, lengthSize);
    } else {
      return concatNalUnitsInAnnexB(nalUnits);
    }
  };
  var extractAvcDecoderConfigurationRecord = (packetData) => {
    try {
      const spsUnits = [];
      const ppsUnits = [];
      const spsExtUnits = [];
      for (const loc of iterateNalUnitsInAnnexB(packetData)) {
        const nalUnit = packetData.subarray(loc.offset, loc.offset + loc.length);
        const type = extractNalUnitTypeForAvc(nalUnit[0]);
        if (type === 7 /* SPS */) {
          spsUnits.push(nalUnit);
        } else if (type === 8 /* PPS */) {
          ppsUnits.push(nalUnit);
        } else if (type === 13 /* SPS_EXT */) {
          spsExtUnits.push(nalUnit);
        }
      }
      if (spsUnits.length === 0) {
        return null;
      }
      if (ppsUnits.length === 0) {
        return null;
      }
      const spsData = spsUnits[0];
      const spsInfo = parseAvcSps(spsData);
      assert(spsInfo !== null);
      const hasExtendedData = spsInfo.profileIdc === 100 || spsInfo.profileIdc === 110 || spsInfo.profileIdc === 122 || spsInfo.profileIdc === 144;
      return {
        configurationVersion: 1,
        avcProfileIndication: spsInfo.profileIdc,
        profileCompatibility: spsInfo.constraintFlags,
        avcLevelIndication: spsInfo.levelIdc,
        lengthSizeMinusOne: 3,
        // Typically 4 bytes for length field
        sequenceParameterSets: spsUnits,
        pictureParameterSets: ppsUnits,
        chromaFormat: hasExtendedData ? spsInfo.chromaFormatIdc : null,
        bitDepthLumaMinus8: hasExtendedData ? spsInfo.bitDepthLumaMinus8 : null,
        bitDepthChromaMinus8: hasExtendedData ? spsInfo.bitDepthChromaMinus8 : null,
        sequenceParameterSetExt: hasExtendedData ? spsExtUnits : null
      };
    } catch (error) {
      console.error("Error building AVC Decoder Configuration Record:", error);
      return null;
    }
  };
  var serializeAvcDecoderConfigurationRecord = (record) => {
    const bytes2 = [];
    bytes2.push(record.configurationVersion);
    bytes2.push(record.avcProfileIndication);
    bytes2.push(record.profileCompatibility);
    bytes2.push(record.avcLevelIndication);
    bytes2.push(252 | record.lengthSizeMinusOne & 3);
    bytes2.push(224 | record.sequenceParameterSets.length & 31);
    for (const sps of record.sequenceParameterSets) {
      const length = sps.byteLength;
      bytes2.push(length >> 8);
      bytes2.push(length & 255);
      for (let i = 0; i < length; i++) {
        bytes2.push(sps[i]);
      }
    }
    bytes2.push(record.pictureParameterSets.length);
    for (const pps of record.pictureParameterSets) {
      const length = pps.byteLength;
      bytes2.push(length >> 8);
      bytes2.push(length & 255);
      for (let i = 0; i < length; i++) {
        bytes2.push(pps[i]);
      }
    }
    if (record.avcProfileIndication === 100 || record.avcProfileIndication === 110 || record.avcProfileIndication === 122 || record.avcProfileIndication === 144) {
      assert(record.chromaFormat !== null);
      assert(record.bitDepthLumaMinus8 !== null);
      assert(record.bitDepthChromaMinus8 !== null);
      assert(record.sequenceParameterSetExt !== null);
      bytes2.push(252 | record.chromaFormat & 3);
      bytes2.push(248 | record.bitDepthLumaMinus8 & 7);
      bytes2.push(248 | record.bitDepthChromaMinus8 & 7);
      bytes2.push(record.sequenceParameterSetExt.length);
      for (const spsExt of record.sequenceParameterSetExt) {
        const length = spsExt.byteLength;
        bytes2.push(length >> 8);
        bytes2.push(length & 255);
        for (let i = 0; i < length; i++) {
          bytes2.push(spsExt[i]);
        }
      }
    }
    return new Uint8Array(bytes2);
  };
  var deserializeAvcDecoderConfigurationRecord = (data) => {
    try {
      const view2 = toDataView(data);
      let offset = 0;
      const configurationVersion = view2.getUint8(offset++);
      const avcProfileIndication = view2.getUint8(offset++);
      const profileCompatibility = view2.getUint8(offset++);
      const avcLevelIndication = view2.getUint8(offset++);
      const lengthSizeMinusOne = view2.getUint8(offset++) & 3;
      const numOfSequenceParameterSets = view2.getUint8(offset++) & 31;
      const sequenceParameterSets = [];
      for (let i = 0; i < numOfSequenceParameterSets; i++) {
        const length = view2.getUint16(offset, false);
        offset += 2;
        sequenceParameterSets.push(data.subarray(offset, offset + length));
        offset += length;
      }
      const numOfPictureParameterSets = view2.getUint8(offset++);
      const pictureParameterSets = [];
      for (let i = 0; i < numOfPictureParameterSets; i++) {
        const length = view2.getUint16(offset, false);
        offset += 2;
        pictureParameterSets.push(data.subarray(offset, offset + length));
        offset += length;
      }
      const record = {
        configurationVersion,
        avcProfileIndication,
        profileCompatibility,
        avcLevelIndication,
        lengthSizeMinusOne,
        sequenceParameterSets,
        pictureParameterSets,
        chromaFormat: null,
        bitDepthLumaMinus8: null,
        bitDepthChromaMinus8: null,
        sequenceParameterSetExt: null
      };
      if ((avcProfileIndication === 100 || avcProfileIndication === 110 || avcProfileIndication === 122 || avcProfileIndication === 144) && offset + 4 <= data.length) {
        const chromaFormat = view2.getUint8(offset++) & 3;
        const bitDepthLumaMinus8 = view2.getUint8(offset++) & 7;
        const bitDepthChromaMinus8 = view2.getUint8(offset++) & 7;
        const numOfSequenceParameterSetExt = view2.getUint8(offset++);
        record.chromaFormat = chromaFormat;
        record.bitDepthLumaMinus8 = bitDepthLumaMinus8;
        record.bitDepthChromaMinus8 = bitDepthChromaMinus8;
        const sequenceParameterSetExt = [];
        for (let i = 0; i < numOfSequenceParameterSetExt; i++) {
          const length = view2.getUint16(offset, false);
          offset += 2;
          sequenceParameterSetExt.push(data.subarray(offset, offset + length));
          offset += length;
        }
        record.sequenceParameterSetExt = sequenceParameterSetExt;
      }
      return record;
    } catch (error) {
      console.error("Error deserializing AVC Decoder Configuration Record:", error);
      return null;
    }
  };
  var parseAvcSps = (sps) => {
    try {
      const bitstream = new Bitstream(removeEmulationPreventionBytes(sps));
      bitstream.skipBits(1);
      bitstream.skipBits(2);
      const nalUnitType = bitstream.readBits(5);
      if (nalUnitType !== 7) {
        return null;
      }
      const profileIdc = bitstream.readAlignedByte();
      const constraintFlags = bitstream.readAlignedByte();
      const levelIdc = bitstream.readAlignedByte();
      readExpGolomb(bitstream);
      let chromaFormatIdc = 1;
      let bitDepthLumaMinus8 = 0;
      let bitDepthChromaMinus8 = 0;
      let separateColourPlaneFlag = 0;
      if (profileIdc === 100 || profileIdc === 110 || profileIdc === 122 || profileIdc === 244 || profileIdc === 44 || profileIdc === 83 || profileIdc === 86 || profileIdc === 118 || profileIdc === 128) {
        chromaFormatIdc = readExpGolomb(bitstream);
        if (chromaFormatIdc === 3) {
          separateColourPlaneFlag = bitstream.readBits(1);
        }
        bitDepthLumaMinus8 = readExpGolomb(bitstream);
        bitDepthChromaMinus8 = readExpGolomb(bitstream);
        bitstream.skipBits(1);
        const seqScalingMatrixPresentFlag = bitstream.readBits(1);
        if (seqScalingMatrixPresentFlag) {
          for (let i = 0; i < (chromaFormatIdc !== 3 ? 8 : 12); i++) {
            const seqScalingListPresentFlag = bitstream.readBits(1);
            if (seqScalingListPresentFlag) {
              const sizeOfScalingList = i < 6 ? 16 : 64;
              let lastScale = 8;
              let nextScale = 8;
              for (let j = 0; j < sizeOfScalingList; j++) {
                if (nextScale !== 0) {
                  const deltaScale = readSignedExpGolomb(bitstream);
                  nextScale = (lastScale + deltaScale + 256) % 256;
                }
                lastScale = nextScale === 0 ? lastScale : nextScale;
              }
            }
          }
        }
      }
      readExpGolomb(bitstream);
      const picOrderCntType = readExpGolomb(bitstream);
      if (picOrderCntType === 0) {
        readExpGolomb(bitstream);
      } else if (picOrderCntType === 1) {
        bitstream.skipBits(1);
        readSignedExpGolomb(bitstream);
        readSignedExpGolomb(bitstream);
        const numRefFramesInPicOrderCntCycle = readExpGolomb(bitstream);
        for (let i = 0; i < numRefFramesInPicOrderCntCycle; i++) {
          readSignedExpGolomb(bitstream);
        }
      }
      readExpGolomb(bitstream);
      bitstream.skipBits(1);
      const picWidthInMbsMinus1 = readExpGolomb(bitstream);
      const picHeightInMapUnitsMinus1 = readExpGolomb(bitstream);
      const codedWidth = 16 * (picWidthInMbsMinus1 + 1);
      const codedHeight = 16 * (picHeightInMapUnitsMinus1 + 1);
      let displayWidth = codedWidth;
      let displayHeight = codedHeight;
      const frameMbsOnlyFlag = bitstream.readBits(1);
      if (!frameMbsOnlyFlag) {
        bitstream.skipBits(1);
      }
      bitstream.skipBits(1);
      const frameCroppingFlag = bitstream.readBits(1);
      if (frameCroppingFlag) {
        const frameCropLeftOffset = readExpGolomb(bitstream);
        const frameCropRightOffset = readExpGolomb(bitstream);
        const frameCropTopOffset = readExpGolomb(bitstream);
        const frameCropBottomOffset = readExpGolomb(bitstream);
        let cropUnitX;
        let cropUnitY;
        const chromaArrayType = separateColourPlaneFlag === 0 ? chromaFormatIdc : 0;
        if (chromaArrayType === 0) {
          cropUnitX = 1;
          cropUnitY = 2 - frameMbsOnlyFlag;
        } else {
          const subWidthC = chromaFormatIdc === 3 ? 1 : 2;
          const subHeightC = chromaFormatIdc === 1 ? 2 : 1;
          cropUnitX = subWidthC;
          cropUnitY = subHeightC * (2 - frameMbsOnlyFlag);
        }
        displayWidth -= cropUnitX * (frameCropLeftOffset + frameCropRightOffset);
        displayHeight -= cropUnitY * (frameCropTopOffset + frameCropBottomOffset);
      }
      let colourPrimaries = 2;
      let transferCharacteristics = 2;
      let matrixCoefficients = 2;
      let fullRangeFlag = 0;
      let numReorderFrames = null;
      let maxDecFrameBuffering = null;
      const vuiParametersPresentFlag = bitstream.readBits(1);
      if (vuiParametersPresentFlag) {
        const aspectRatioInfoPresentFlag = bitstream.readBits(1);
        if (aspectRatioInfoPresentFlag) {
          const aspectRatioIdc = bitstream.readBits(8);
          if (aspectRatioIdc === 255) {
            bitstream.skipBits(16);
            bitstream.skipBits(16);
          }
        }
        const overscanInfoPresentFlag = bitstream.readBits(1);
        if (overscanInfoPresentFlag) {
          bitstream.skipBits(1);
        }
        const videoSignalTypePresentFlag = bitstream.readBits(1);
        if (videoSignalTypePresentFlag) {
          bitstream.skipBits(3);
          fullRangeFlag = bitstream.readBits(1);
          const colourDescriptionPresentFlag = bitstream.readBits(1);
          if (colourDescriptionPresentFlag) {
            colourPrimaries = bitstream.readBits(8);
            transferCharacteristics = bitstream.readBits(8);
            matrixCoefficients = bitstream.readBits(8);
          }
        }
        const chromaLocInfoPresentFlag = bitstream.readBits(1);
        if (chromaLocInfoPresentFlag) {
          readExpGolomb(bitstream);
          readExpGolomb(bitstream);
        }
        const timingInfoPresentFlag = bitstream.readBits(1);
        if (timingInfoPresentFlag) {
          bitstream.skipBits(32);
          bitstream.skipBits(32);
          bitstream.skipBits(1);
        }
        const nalHrdParametersPresentFlag = bitstream.readBits(1);
        if (nalHrdParametersPresentFlag) {
          skipAvcHrdParameters(bitstream);
        }
        const vclHrdParametersPresentFlag = bitstream.readBits(1);
        if (vclHrdParametersPresentFlag) {
          skipAvcHrdParameters(bitstream);
        }
        if (nalHrdParametersPresentFlag || vclHrdParametersPresentFlag) {
          bitstream.skipBits(1);
        }
        bitstream.skipBits(1);
        const bitstreamRestrictionFlag = bitstream.readBits(1);
        if (bitstreamRestrictionFlag) {
          bitstream.skipBits(1);
          readExpGolomb(bitstream);
          readExpGolomb(bitstream);
          readExpGolomb(bitstream);
          readExpGolomb(bitstream);
          numReorderFrames = readExpGolomb(bitstream);
          maxDecFrameBuffering = readExpGolomb(bitstream);
        }
      }
      if (numReorderFrames === null) {
        assert(maxDecFrameBuffering === null);
        const constraintSet3Flag = constraintFlags & 16;
        if ((profileIdc === 44 || profileIdc === 86 || profileIdc === 100 || profileIdc === 110 || profileIdc === 122 || profileIdc === 244) && constraintSet3Flag) {
          numReorderFrames = 0;
          maxDecFrameBuffering = 0;
        } else {
          const picWidthInMbs = picWidthInMbsMinus1 + 1;
          const picHeightInMapUnits = picHeightInMapUnitsMinus1 + 1;
          const frameHeightInMbs = (2 - frameMbsOnlyFlag) * picHeightInMapUnits;
          const levelInfo = AVC_LEVEL_TABLE.find(
            (x) => x.level >= levelIdc
          ) ?? last(AVC_LEVEL_TABLE);
          const maxDpbFrames = Math.min(
            Math.floor(levelInfo.maxDpbMbs / (picWidthInMbs * frameHeightInMbs)),
            16
          );
          numReorderFrames = maxDpbFrames;
          maxDecFrameBuffering = maxDpbFrames;
        }
      }
      assert(maxDecFrameBuffering !== null);
      return {
        profileIdc,
        constraintFlags,
        levelIdc,
        frameMbsOnlyFlag,
        chromaFormatIdc,
        bitDepthLumaMinus8,
        bitDepthChromaMinus8,
        codedWidth,
        codedHeight,
        displayWidth,
        displayHeight,
        colourPrimaries,
        matrixCoefficients,
        transferCharacteristics,
        fullRangeFlag,
        numReorderFrames,
        maxDecFrameBuffering
      };
    } catch (error) {
      console.error("Error parsing AVC SPS:", error);
      return null;
    }
  };
  var skipAvcHrdParameters = (bitstream) => {
    const cpb_cnt_minus1 = readExpGolomb(bitstream);
    bitstream.skipBits(4);
    bitstream.skipBits(4);
    for (let i = 0; i <= cpb_cnt_minus1; i++) {
      readExpGolomb(bitstream);
      readExpGolomb(bitstream);
      bitstream.skipBits(1);
    }
    bitstream.skipBits(5);
    bitstream.skipBits(5);
    bitstream.skipBits(5);
    bitstream.skipBits(5);
  };
  var iterateHevcNalUnits = (packetData, decoderConfig) => {
    if (decoderConfig.description) {
      const bytes2 = toUint8Array(decoderConfig.description);
      const lengthSizeMinusOne = bytes2[21] & 3;
      const lengthSize = lengthSizeMinusOne + 1;
      return iterateNalUnitsInLengthPrefixed(packetData, lengthSize);
    } else {
      return iterateNalUnitsInAnnexB(packetData);
    }
  };
  var extractNalUnitTypeForHevc = (byte) => {
    return byte >> 1 & 63;
  };
  var parseHevcSps = (sps) => {
    try {
      const bitstream = new Bitstream(removeEmulationPreventionBytes(sps));
      bitstream.skipBits(16);
      bitstream.readBits(4);
      const spsMaxSubLayersMinus1 = bitstream.readBits(3);
      const spsTemporalIdNestingFlag = bitstream.readBits(1);
      const {
        general_profile_space,
        general_tier_flag,
        general_profile_idc,
        general_profile_compatibility_flags,
        general_constraint_indicator_flags,
        general_level_idc
      } = parseProfileTierLevel(bitstream, spsMaxSubLayersMinus1);
      readExpGolomb(bitstream);
      const chromaFormatIdc = readExpGolomb(bitstream);
      let separateColourPlaneFlag = 0;
      if (chromaFormatIdc === 3) {
        separateColourPlaneFlag = bitstream.readBits(1);
      }
      const picWidthInLumaSamples = readExpGolomb(bitstream);
      const picHeightInLumaSamples = readExpGolomb(bitstream);
      let displayWidth = picWidthInLumaSamples;
      let displayHeight = picHeightInLumaSamples;
      if (bitstream.readBits(1)) {
        const confWinLeftOffset = readExpGolomb(bitstream);
        const confWinRightOffset = readExpGolomb(bitstream);
        const confWinTopOffset = readExpGolomb(bitstream);
        const confWinBottomOffset = readExpGolomb(bitstream);
        let subWidthC = 1;
        let subHeightC = 1;
        const chromaArrayType = separateColourPlaneFlag === 0 ? chromaFormatIdc : 0;
        if (chromaArrayType === 1) {
          subWidthC = 2;
          subHeightC = 2;
        } else if (chromaArrayType === 2) {
          subWidthC = 2;
          subHeightC = 1;
        }
        displayWidth -= (confWinLeftOffset + confWinRightOffset) * subWidthC;
        displayHeight -= (confWinTopOffset + confWinBottomOffset) * subHeightC;
      }
      const bitDepthLumaMinus8 = readExpGolomb(bitstream);
      const bitDepthChromaMinus8 = readExpGolomb(bitstream);
      readExpGolomb(bitstream);
      const spsSubLayerOrderingInfoPresentFlag = bitstream.readBits(1);
      const startI = spsSubLayerOrderingInfoPresentFlag ? 0 : spsMaxSubLayersMinus1;
      let spsMaxNumReorderPics = 0;
      for (let i = startI; i <= spsMaxSubLayersMinus1; i++) {
        readExpGolomb(bitstream);
        spsMaxNumReorderPics = readExpGolomb(bitstream);
        readExpGolomb(bitstream);
      }
      readExpGolomb(bitstream);
      readExpGolomb(bitstream);
      readExpGolomb(bitstream);
      readExpGolomb(bitstream);
      readExpGolomb(bitstream);
      readExpGolomb(bitstream);
      if (bitstream.readBits(1)) {
        if (bitstream.readBits(1)) {
          skipScalingListData(bitstream);
        }
      }
      bitstream.skipBits(1);
      bitstream.skipBits(1);
      if (bitstream.readBits(1)) {
        bitstream.skipBits(4);
        bitstream.skipBits(4);
        readExpGolomb(bitstream);
        readExpGolomb(bitstream);
        bitstream.skipBits(1);
      }
      const numShortTermRefPicSets = readExpGolomb(bitstream);
      skipAllStRefPicSets(bitstream, numShortTermRefPicSets);
      if (bitstream.readBits(1)) {
        const numLongTermRefPicsSps = readExpGolomb(bitstream);
        for (let i = 0; i < numLongTermRefPicsSps; i++) {
          readExpGolomb(bitstream);
          bitstream.skipBits(1);
        }
      }
      bitstream.skipBits(1);
      bitstream.skipBits(1);
      let colourPrimaries = 2;
      let transferCharacteristics = 2;
      let matrixCoefficients = 2;
      let fullRangeFlag = 0;
      let minSpatialSegmentationIdc = 0;
      if (bitstream.readBits(1)) {
        const vui = parseHevcVui(bitstream, spsMaxSubLayersMinus1);
        colourPrimaries = vui.colourPrimaries;
        transferCharacteristics = vui.transferCharacteristics;
        matrixCoefficients = vui.matrixCoefficients;
        fullRangeFlag = vui.fullRangeFlag;
        minSpatialSegmentationIdc = vui.minSpatialSegmentationIdc;
      }
      return {
        displayWidth,
        displayHeight,
        colourPrimaries,
        transferCharacteristics,
        matrixCoefficients,
        fullRangeFlag,
        maxDecFrameBuffering: spsMaxNumReorderPics + 1,
        spsMaxSubLayersMinus1,
        spsTemporalIdNestingFlag,
        generalProfileSpace: general_profile_space,
        generalTierFlag: general_tier_flag,
        generalProfileIdc: general_profile_idc,
        generalProfileCompatibilityFlags: general_profile_compatibility_flags,
        generalConstraintIndicatorFlags: general_constraint_indicator_flags,
        generalLevelIdc: general_level_idc,
        chromaFormatIdc,
        bitDepthLumaMinus8,
        bitDepthChromaMinus8,
        minSpatialSegmentationIdc
      };
    } catch (error) {
      console.error("Error parsing HEVC SPS:", error);
      return null;
    }
  };
  var extractHevcDecoderConfigurationRecord = (packetData) => {
    try {
      const vpsUnits = [];
      const spsUnits = [];
      const ppsUnits = [];
      const seiUnits = [];
      for (const loc of iterateNalUnitsInAnnexB(packetData)) {
        const nalUnit = packetData.subarray(loc.offset, loc.offset + loc.length);
        const type = extractNalUnitTypeForHevc(nalUnit[0]);
        if (type === 32 /* VPS_NUT */) {
          vpsUnits.push(nalUnit);
        } else if (type === 33 /* SPS_NUT */) {
          spsUnits.push(nalUnit);
        } else if (type === 34 /* PPS_NUT */) {
          ppsUnits.push(nalUnit);
        } else if (type === 39 /* PREFIX_SEI_NUT */ || type === 40 /* SUFFIX_SEI_NUT */) {
          seiUnits.push(nalUnit);
        }
      }
      if (spsUnits.length === 0 || ppsUnits.length === 0) return null;
      const spsInfo = parseHevcSps(spsUnits[0]);
      if (!spsInfo) return null;
      let parallelismType = 0;
      if (ppsUnits.length > 0) {
        const pps = ppsUnits[0];
        const ppsBitstream = new Bitstream(removeEmulationPreventionBytes(pps));
        ppsBitstream.skipBits(16);
        readExpGolomb(ppsBitstream);
        readExpGolomb(ppsBitstream);
        ppsBitstream.skipBits(1);
        ppsBitstream.skipBits(1);
        ppsBitstream.skipBits(3);
        ppsBitstream.skipBits(1);
        ppsBitstream.skipBits(1);
        readExpGolomb(ppsBitstream);
        readExpGolomb(ppsBitstream);
        readSignedExpGolomb(ppsBitstream);
        ppsBitstream.skipBits(1);
        ppsBitstream.skipBits(1);
        if (ppsBitstream.readBits(1)) {
          readExpGolomb(ppsBitstream);
        }
        readSignedExpGolomb(ppsBitstream);
        readSignedExpGolomb(ppsBitstream);
        ppsBitstream.skipBits(1);
        ppsBitstream.skipBits(1);
        ppsBitstream.skipBits(1);
        ppsBitstream.skipBits(1);
        const tiles_enabled_flag = ppsBitstream.readBits(1);
        const entropy_coding_sync_enabled_flag = ppsBitstream.readBits(1);
        if (!tiles_enabled_flag && !entropy_coding_sync_enabled_flag) parallelismType = 0;
        else if (tiles_enabled_flag && !entropy_coding_sync_enabled_flag) parallelismType = 2;
        else if (!tiles_enabled_flag && entropy_coding_sync_enabled_flag) parallelismType = 3;
        else parallelismType = 0;
      }
      const arrays = [
        ...vpsUnits.length ? [
          {
            arrayCompleteness: 1,
            nalUnitType: 32 /* VPS_NUT */,
            nalUnits: vpsUnits
          }
        ] : [],
        ...spsUnits.length ? [
          {
            arrayCompleteness: 1,
            nalUnitType: 33 /* SPS_NUT */,
            nalUnits: spsUnits
          }
        ] : [],
        ...ppsUnits.length ? [
          {
            arrayCompleteness: 1,
            nalUnitType: 34 /* PPS_NUT */,
            nalUnits: ppsUnits
          }
        ] : [],
        ...seiUnits.length ? [
          {
            arrayCompleteness: 1,
            nalUnitType: extractNalUnitTypeForHevc(seiUnits[0][0]),
            nalUnits: seiUnits
          }
        ] : []
      ];
      const record = {
        configurationVersion: 1,
        generalProfileSpace: spsInfo.generalProfileSpace,
        generalTierFlag: spsInfo.generalTierFlag,
        generalProfileIdc: spsInfo.generalProfileIdc,
        generalProfileCompatibilityFlags: spsInfo.generalProfileCompatibilityFlags,
        generalConstraintIndicatorFlags: spsInfo.generalConstraintIndicatorFlags,
        generalLevelIdc: spsInfo.generalLevelIdc,
        minSpatialSegmentationIdc: spsInfo.minSpatialSegmentationIdc,
        parallelismType,
        chromaFormatIdc: spsInfo.chromaFormatIdc,
        bitDepthLumaMinus8: spsInfo.bitDepthLumaMinus8,
        bitDepthChromaMinus8: spsInfo.bitDepthChromaMinus8,
        avgFrameRate: 0,
        constantFrameRate: 0,
        numTemporalLayers: spsInfo.spsMaxSubLayersMinus1 + 1,
        temporalIdNested: spsInfo.spsTemporalIdNestingFlag,
        lengthSizeMinusOne: 3,
        arrays
      };
      return record;
    } catch (error) {
      console.error("Error building HEVC Decoder Configuration Record:", error);
      return null;
    }
  };
  var parseProfileTierLevel = (bitstream, maxNumSubLayersMinus1) => {
    const general_profile_space = bitstream.readBits(2);
    const general_tier_flag = bitstream.readBits(1);
    const general_profile_idc = bitstream.readBits(5);
    let general_profile_compatibility_flags = 0;
    for (let i = 0; i < 32; i++) {
      general_profile_compatibility_flags = general_profile_compatibility_flags << 1 | bitstream.readBits(1);
    }
    const general_constraint_indicator_flags = new Uint8Array(6);
    for (let i = 0; i < 6; i++) {
      general_constraint_indicator_flags[i] = bitstream.readBits(8);
    }
    const general_level_idc = bitstream.readBits(8);
    const sub_layer_profile_present_flag = [];
    const sub_layer_level_present_flag = [];
    for (let i = 0; i < maxNumSubLayersMinus1; i++) {
      sub_layer_profile_present_flag.push(bitstream.readBits(1));
      sub_layer_level_present_flag.push(bitstream.readBits(1));
    }
    if (maxNumSubLayersMinus1 > 0) {
      for (let i = maxNumSubLayersMinus1; i < 8; i++) {
        bitstream.skipBits(2);
      }
    }
    for (let i = 0; i < maxNumSubLayersMinus1; i++) {
      if (sub_layer_profile_present_flag[i]) bitstream.skipBits(88);
      if (sub_layer_level_present_flag[i]) bitstream.skipBits(8);
    }
    return {
      general_profile_space,
      general_tier_flag,
      general_profile_idc,
      general_profile_compatibility_flags,
      general_constraint_indicator_flags,
      general_level_idc
    };
  };
  var skipScalingListData = (bitstream) => {
    for (let sizeId = 0; sizeId < 4; sizeId++) {
      for (let matrixId = 0; matrixId < (sizeId === 3 ? 2 : 6); matrixId++) {
        const scaling_list_pred_mode_flag = bitstream.readBits(1);
        if (!scaling_list_pred_mode_flag) {
          readExpGolomb(bitstream);
        } else {
          const coefNum = Math.min(64, 1 << 4 + (sizeId << 1));
          if (sizeId > 1) {
            readSignedExpGolomb(bitstream);
          }
          for (let i = 0; i < coefNum; i++) {
            readSignedExpGolomb(bitstream);
          }
        }
      }
    }
  };
  var skipAllStRefPicSets = (bitstream, num_short_term_ref_pic_sets) => {
    const NumDeltaPocs = [];
    for (let stRpsIdx = 0; stRpsIdx < num_short_term_ref_pic_sets; stRpsIdx++) {
      NumDeltaPocs[stRpsIdx] = skipStRefPicSet(bitstream, stRpsIdx, num_short_term_ref_pic_sets, NumDeltaPocs);
    }
  };
  var skipStRefPicSet = (bitstream, stRpsIdx, num_short_term_ref_pic_sets, NumDeltaPocs) => {
    let NumDeltaPocsThis = 0;
    let inter_ref_pic_set_prediction_flag = 0;
    let RefRpsIdx = 0;
    if (stRpsIdx !== 0) {
      inter_ref_pic_set_prediction_flag = bitstream.readBits(1);
    }
    if (inter_ref_pic_set_prediction_flag) {
      if (stRpsIdx === num_short_term_ref_pic_sets) {
        const delta_idx_minus1 = readExpGolomb(bitstream);
        RefRpsIdx = stRpsIdx - (delta_idx_minus1 + 1);
      } else {
        RefRpsIdx = stRpsIdx - 1;
      }
      bitstream.readBits(1);
      readExpGolomb(bitstream);
      const numDelta = NumDeltaPocs[RefRpsIdx] ?? 0;
      for (let j = 0; j <= numDelta; j++) {
        const used_by_curr_pic_flag = bitstream.readBits(1);
        if (!used_by_curr_pic_flag) {
          bitstream.readBits(1);
        }
      }
      NumDeltaPocsThis = NumDeltaPocs[RefRpsIdx];
    } else {
      const num_negative_pics = readExpGolomb(bitstream);
      const num_positive_pics = readExpGolomb(bitstream);
      for (let i = 0; i < num_negative_pics; i++) {
        readExpGolomb(bitstream);
        bitstream.readBits(1);
      }
      for (let i = 0; i < num_positive_pics; i++) {
        readExpGolomb(bitstream);
        bitstream.readBits(1);
      }
      NumDeltaPocsThis = num_negative_pics + num_positive_pics;
    }
    return NumDeltaPocsThis;
  };
  var parseHevcVui = (bitstream, sps_max_sub_layers_minus1) => {
    let colourPrimaries = 2;
    let transferCharacteristics = 2;
    let matrixCoefficients = 2;
    let fullRangeFlag = 0;
    let minSpatialSegmentationIdc = 0;
    if (bitstream.readBits(1)) {
      const aspect_ratio_idc = bitstream.readBits(8);
      if (aspect_ratio_idc === 255) {
        bitstream.readBits(16);
        bitstream.readBits(16);
      }
    }
    if (bitstream.readBits(1)) {
      bitstream.readBits(1);
    }
    if (bitstream.readBits(1)) {
      bitstream.readBits(3);
      fullRangeFlag = bitstream.readBits(1);
      if (bitstream.readBits(1)) {
        colourPrimaries = bitstream.readBits(8);
        transferCharacteristics = bitstream.readBits(8);
        matrixCoefficients = bitstream.readBits(8);
      }
    }
    if (bitstream.readBits(1)) {
      readExpGolomb(bitstream);
      readExpGolomb(bitstream);
    }
    bitstream.readBits(1);
    bitstream.readBits(1);
    bitstream.readBits(1);
    if (bitstream.readBits(1)) {
      readExpGolomb(bitstream);
      readExpGolomb(bitstream);
      readExpGolomb(bitstream);
      readExpGolomb(bitstream);
    }
    if (bitstream.readBits(1)) {
      bitstream.readBits(32);
      bitstream.readBits(32);
      if (bitstream.readBits(1)) {
        readExpGolomb(bitstream);
      }
      if (bitstream.readBits(1)) {
        skipHevcHrdParameters(bitstream, true, sps_max_sub_layers_minus1);
      }
    }
    if (bitstream.readBits(1)) {
      bitstream.readBits(1);
      bitstream.readBits(1);
      bitstream.readBits(1);
      minSpatialSegmentationIdc = readExpGolomb(bitstream);
      readExpGolomb(bitstream);
      readExpGolomb(bitstream);
      readExpGolomb(bitstream);
      readExpGolomb(bitstream);
    }
    return {
      colourPrimaries,
      transferCharacteristics,
      matrixCoefficients,
      fullRangeFlag,
      minSpatialSegmentationIdc
    };
  };
  var skipHevcHrdParameters = (bitstream, commonInfPresentFlag, maxNumSubLayersMinus1) => {
    let nal_hrd_parameters_present_flag = false;
    let vcl_hrd_parameters_present_flag = false;
    let sub_pic_hrd_params_present_flag = false;
    if (commonInfPresentFlag) {
      nal_hrd_parameters_present_flag = bitstream.readBits(1) === 1;
      vcl_hrd_parameters_present_flag = bitstream.readBits(1) === 1;
      if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) {
        sub_pic_hrd_params_present_flag = bitstream.readBits(1) === 1;
        if (sub_pic_hrd_params_present_flag) {
          bitstream.readBits(8);
          bitstream.readBits(5);
          bitstream.readBits(1);
          bitstream.readBits(5);
        }
        bitstream.readBits(4);
        bitstream.readBits(4);
        if (sub_pic_hrd_params_present_flag) {
          bitstream.readBits(4);
        }
        bitstream.readBits(5);
        bitstream.readBits(5);
        bitstream.readBits(5);
      }
    }
    for (let i = 0; i <= maxNumSubLayersMinus1; i++) {
      const fixed_pic_rate_general_flag = bitstream.readBits(1) === 1;
      let fixed_pic_rate_within_cvs_flag = true;
      if (!fixed_pic_rate_general_flag) {
        fixed_pic_rate_within_cvs_flag = bitstream.readBits(1) === 1;
      }
      let low_delay_hrd_flag = false;
      if (fixed_pic_rate_within_cvs_flag) {
        readExpGolomb(bitstream);
      } else {
        low_delay_hrd_flag = bitstream.readBits(1) === 1;
      }
      let CpbCnt = 1;
      if (!low_delay_hrd_flag) {
        const cpb_cnt_minus1 = readExpGolomb(bitstream);
        CpbCnt = cpb_cnt_minus1 + 1;
      }
      if (nal_hrd_parameters_present_flag) {
        skipSubLayerHrdParameters(bitstream, CpbCnt, sub_pic_hrd_params_present_flag);
      }
      if (vcl_hrd_parameters_present_flag) {
        skipSubLayerHrdParameters(bitstream, CpbCnt, sub_pic_hrd_params_present_flag);
      }
    }
  };
  var skipSubLayerHrdParameters = (bitstream, CpbCnt, sub_pic_hrd_params_present_flag) => {
    for (let i = 0; i < CpbCnt; i++) {
      readExpGolomb(bitstream);
      readExpGolomb(bitstream);
      if (sub_pic_hrd_params_present_flag) {
        readExpGolomb(bitstream);
        readExpGolomb(bitstream);
      }
      bitstream.readBits(1);
    }
  };
  var serializeHevcDecoderConfigurationRecord = (record) => {
    const bytes2 = [];
    bytes2.push(record.configurationVersion);
    bytes2.push(
      (record.generalProfileSpace & 3) << 6 | (record.generalTierFlag & 1) << 5 | record.generalProfileIdc & 31
    );
    bytes2.push(record.generalProfileCompatibilityFlags >>> 24 & 255);
    bytes2.push(record.generalProfileCompatibilityFlags >>> 16 & 255);
    bytes2.push(record.generalProfileCompatibilityFlags >>> 8 & 255);
    bytes2.push(record.generalProfileCompatibilityFlags & 255);
    bytes2.push(...record.generalConstraintIndicatorFlags);
    bytes2.push(record.generalLevelIdc & 255);
    bytes2.push(240 | record.minSpatialSegmentationIdc >> 8 & 15);
    bytes2.push(record.minSpatialSegmentationIdc & 255);
    bytes2.push(252 | record.parallelismType & 3);
    bytes2.push(252 | record.chromaFormatIdc & 3);
    bytes2.push(248 | record.bitDepthLumaMinus8 & 7);
    bytes2.push(248 | record.bitDepthChromaMinus8 & 7);
    bytes2.push(record.avgFrameRate >> 8 & 255);
    bytes2.push(record.avgFrameRate & 255);
    bytes2.push(
      (record.constantFrameRate & 3) << 6 | (record.numTemporalLayers & 7) << 3 | (record.temporalIdNested & 1) << 2 | record.lengthSizeMinusOne & 3
    );
    bytes2.push(record.arrays.length & 255);
    for (const arr of record.arrays) {
      bytes2.push(
        (arr.arrayCompleteness & 1) << 7 | 0 << 6 | arr.nalUnitType & 63
      );
      bytes2.push(arr.nalUnits.length >> 8 & 255);
      bytes2.push(arr.nalUnits.length & 255);
      for (const nal of arr.nalUnits) {
        bytes2.push(nal.length >> 8 & 255);
        bytes2.push(nal.length & 255);
        for (let i = 0; i < nal.length; i++) {
          bytes2.push(nal[i]);
        }
      }
    }
    return new Uint8Array(bytes2);
  };
  var deserializeHevcDecoderConfigurationRecord = (data) => {
    try {
      const view2 = toDataView(data);
      let offset = 0;
      const configurationVersion = view2.getUint8(offset++);
      const byte1 = view2.getUint8(offset++);
      const generalProfileSpace = byte1 >> 6 & 3;
      const generalTierFlag = byte1 >> 5 & 1;
      const generalProfileIdc = byte1 & 31;
      const generalProfileCompatibilityFlags = view2.getUint32(offset, false);
      offset += 4;
      const generalConstraintIndicatorFlags = data.subarray(offset, offset + 6);
      offset += 6;
      const generalLevelIdc = view2.getUint8(offset++);
      const minSpatialSegmentationIdc = (view2.getUint8(offset++) & 15) << 8 | view2.getUint8(offset++);
      const parallelismType = view2.getUint8(offset++) & 3;
      const chromaFormatIdc = view2.getUint8(offset++) & 3;
      const bitDepthLumaMinus8 = view2.getUint8(offset++) & 7;
      const bitDepthChromaMinus8 = view2.getUint8(offset++) & 7;
      const avgFrameRate = view2.getUint16(offset, false);
      offset += 2;
      const byte21 = view2.getUint8(offset++);
      const constantFrameRate = byte21 >> 6 & 3;
      const numTemporalLayers = byte21 >> 3 & 7;
      const temporalIdNested = byte21 >> 2 & 1;
      const lengthSizeMinusOne = byte21 & 3;
      const numOfArrays = view2.getUint8(offset++);
      const arrays = [];
      for (let i = 0; i < numOfArrays; i++) {
        const arrByte = view2.getUint8(offset++);
        const arrayCompleteness = arrByte >> 7 & 1;
        const nalUnitType = arrByte & 63;
        const numNalus = view2.getUint16(offset, false);
        offset += 2;
        const nalUnits = [];
        for (let j = 0; j < numNalus; j++) {
          const nalUnitLength = view2.getUint16(offset, false);
          offset += 2;
          nalUnits.push(data.subarray(offset, offset + nalUnitLength));
          offset += nalUnitLength;
        }
        arrays.push({
          arrayCompleteness,
          nalUnitType,
          nalUnits
        });
      }
      return {
        configurationVersion,
        generalProfileSpace,
        generalTierFlag,
        generalProfileIdc,
        generalProfileCompatibilityFlags,
        generalConstraintIndicatorFlags,
        generalLevelIdc,
        minSpatialSegmentationIdc,
        parallelismType,
        chromaFormatIdc,
        bitDepthLumaMinus8,
        bitDepthChromaMinus8,
        avgFrameRate,
        constantFrameRate,
        numTemporalLayers,
        temporalIdNested,
        lengthSizeMinusOne,
        arrays
      };
    } catch (error) {
      console.error("Error deserializing HEVC Decoder Configuration Record:", error);
      return null;
    }
  };
  var extractVp9CodecInfoFromPacket = (packet) => {
    const bitstream = new Bitstream(packet);
    const frameMarker = bitstream.readBits(2);
    if (frameMarker !== 2) {
      return null;
    }
    const profileLowBit = bitstream.readBits(1);
    const profileHighBit = bitstream.readBits(1);
    const profile = (profileHighBit << 1) + profileLowBit;
    if (profile === 3) {
      bitstream.skipBits(1);
    }
    const showExistingFrame = bitstream.readBits(1);
    if (showExistingFrame === 1) {
      return null;
    }
    const frameType = bitstream.readBits(1);
    if (frameType !== 0) {
      return null;
    }
    bitstream.skipBits(2);
    const syncCode = bitstream.readBits(24);
    if (syncCode !== 4817730) {
      return null;
    }
    let bitDepth = 8;
    if (profile >= 2) {
      const tenOrTwelveBit = bitstream.readBits(1);
      bitDepth = tenOrTwelveBit ? 12 : 10;
    }
    const colorSpace = bitstream.readBits(3);
    let chromaSubsampling = 0;
    let videoFullRangeFlag = 0;
    if (colorSpace !== 7) {
      const colorRange = bitstream.readBits(1);
      videoFullRangeFlag = colorRange;
      if (profile === 1 || profile === 3) {
        const subsamplingX = bitstream.readBits(1);
        const subsamplingY = bitstream.readBits(1);
        chromaSubsampling = !subsamplingX && !subsamplingY ? 3 : subsamplingX && !subsamplingY ? 2 : 1;
        bitstream.skipBits(1);
      } else {
        chromaSubsampling = 1;
      }
    } else {
      chromaSubsampling = 3;
      videoFullRangeFlag = 1;
    }
    const widthMinusOne = bitstream.readBits(16);
    const heightMinusOne = bitstream.readBits(16);
    const width = widthMinusOne + 1;
    const height = heightMinusOne + 1;
    const pictureSize = width * height;
    let level = last(VP9_LEVEL_TABLE).level;
    for (const entry of VP9_LEVEL_TABLE) {
      if (pictureSize <= entry.maxPictureSize) {
        level = entry.level;
        break;
      }
    }
    const matrixCoefficients = colorSpace === 7 ? 0 : colorSpace === 2 ? 1 : colorSpace === 1 ? 6 : 2;
    const colourPrimaries = colorSpace === 2 ? 1 : colorSpace === 1 ? 6 : 2;
    const transferCharacteristics = colorSpace === 2 ? 1 : colorSpace === 1 ? 6 : 2;
    return {
      profile,
      level,
      bitDepth,
      chromaSubsampling,
      videoFullRangeFlag,
      colourPrimaries,
      transferCharacteristics,
      matrixCoefficients
    };
  };
  var iterateAv1PacketObus = function* (packet) {
    const bitstream = new Bitstream(packet);
    const readLeb128 = () => {
      let value = 0;
      for (let i = 0; i < 8; i++) {
        const byte = bitstream.readAlignedByte();
        value |= (byte & 127) << i * 7;
        if (!(byte & 128)) {
          break;
        }
        if (i === 7 && byte & 128) {
          return null;
        }
      }
      if (value >= 2 ** 32 - 1) {
        return null;
      }
      return value;
    };
    while (bitstream.getBitsLeft() >= 8) {
      bitstream.skipBits(1);
      const obuType = bitstream.readBits(4);
      const obuExtension = bitstream.readBits(1);
      const obuHasSizeField = bitstream.readBits(1);
      bitstream.skipBits(1);
      if (obuExtension) {
        bitstream.skipBits(8);
      }
      let obuSize;
      if (obuHasSizeField) {
        const obuSizeValue = readLeb128();
        if (obuSizeValue === null) return;
        obuSize = obuSizeValue;
      } else {
        obuSize = Math.floor(bitstream.getBitsLeft() / 8);
      }
      assert(bitstream.pos % 8 === 0);
      yield {
        type: obuType,
        data: packet.subarray(bitstream.pos / 8, bitstream.pos / 8 + obuSize)
      };
      bitstream.skipBits(obuSize * 8);
    }
  };
  var extractAv1CodecInfoFromPacket = (packet) => {
    for (const { type, data } of iterateAv1PacketObus(packet)) {
      if (type !== 1) {
        continue;
      }
      const bitstream = new Bitstream(data);
      const seqProfile = bitstream.readBits(3);
      const stillPicture = bitstream.readBits(1);
      const reducedStillPictureHeader = bitstream.readBits(1);
      let seqLevel = 0;
      let seqTier = 0;
      let bufferDelayLengthMinus1 = 0;
      if (reducedStillPictureHeader) {
        seqLevel = bitstream.readBits(5);
      } else {
        const timingInfoPresentFlag = bitstream.readBits(1);
        if (timingInfoPresentFlag) {
          bitstream.skipBits(32);
          bitstream.skipBits(32);
          const equalPictureInterval = bitstream.readBits(1);
          if (equalPictureInterval) {
            return null;
          }
        }
        const decoderModelInfoPresentFlag = bitstream.readBits(1);
        if (decoderModelInfoPresentFlag) {
          bufferDelayLengthMinus1 = bitstream.readBits(5);
          bitstream.skipBits(32);
          bitstream.skipBits(5);
          bitstream.skipBits(5);
        }
        const operatingPointsCntMinus1 = bitstream.readBits(5);
        for (let i = 0; i <= operatingPointsCntMinus1; i++) {
          bitstream.skipBits(12);
          const seqLevelIdx = bitstream.readBits(5);
          if (i === 0) {
            seqLevel = seqLevelIdx;
          }
          if (seqLevelIdx > 7) {
            const seqTierTemp = bitstream.readBits(1);
            if (i === 0) {
              seqTier = seqTierTemp;
            }
          }
          if (decoderModelInfoPresentFlag) {
            const decoderModelPresentForThisOp = bitstream.readBits(1);
            if (decoderModelPresentForThisOp) {
              const n = bufferDelayLengthMinus1 + 1;
              bitstream.skipBits(n);
              bitstream.skipBits(n);
              bitstream.skipBits(1);
            }
          }
          const initialDisplayDelayPresentFlag = bitstream.readBits(1);
          if (initialDisplayDelayPresentFlag) {
            bitstream.skipBits(4);
          }
        }
      }
      const frameWidthBitsMinus1 = bitstream.readBits(4);
      const frameHeightBitsMinus1 = bitstream.readBits(4);
      const n1 = frameWidthBitsMinus1 + 1;
      bitstream.skipBits(n1);
      const n2 = frameHeightBitsMinus1 + 1;
      bitstream.skipBits(n2);
      let frameIdNumbersPresentFlag = 0;
      if (reducedStillPictureHeader) {
        frameIdNumbersPresentFlag = 0;
      } else {
        frameIdNumbersPresentFlag = bitstream.readBits(1);
      }
      if (frameIdNumbersPresentFlag) {
        bitstream.skipBits(4);
        bitstream.skipBits(3);
      }
      bitstream.skipBits(1);
      bitstream.skipBits(1);
      bitstream.skipBits(1);
      if (!reducedStillPictureHeader) {
        bitstream.skipBits(1);
        bitstream.skipBits(1);
        bitstream.skipBits(1);
        bitstream.skipBits(1);
        const enableOrderHint = bitstream.readBits(1);
        if (enableOrderHint) {
          bitstream.skipBits(1);
          bitstream.skipBits(1);
        }
        const seqChooseScreenContentTools = bitstream.readBits(1);
        let seqForceScreenContentTools = 0;
        if (seqChooseScreenContentTools) {
          seqForceScreenContentTools = 2;
        } else {
          seqForceScreenContentTools = bitstream.readBits(1);
        }
        if (seqForceScreenContentTools > 0) {
          const seqChooseIntegerMv = bitstream.readBits(1);
          if (!seqChooseIntegerMv) {
            bitstream.skipBits(1);
          }
        }
        if (enableOrderHint) {
          bitstream.skipBits(3);
        }
      }
      bitstream.skipBits(1);
      bitstream.skipBits(1);
      bitstream.skipBits(1);
      const highBitdepth = bitstream.readBits(1);
      let bitDepth = 8;
      if (seqProfile === 2 && highBitdepth) {
        const twelveBit = bitstream.readBits(1);
        bitDepth = twelveBit ? 12 : 10;
      } else if (seqProfile <= 2) {
        bitDepth = highBitdepth ? 10 : 8;
      }
      let monochrome = 0;
      if (seqProfile !== 1) {
        monochrome = bitstream.readBits(1);
      }
      let chromaSubsamplingX = 1;
      let chromaSubsamplingY = 1;
      let chromaSamplePosition = 0;
      if (!monochrome) {
        if (seqProfile === 0) {
          chromaSubsamplingX = 1;
          chromaSubsamplingY = 1;
        } else if (seqProfile === 1) {
          chromaSubsamplingX = 0;
          chromaSubsamplingY = 0;
        } else {
          if (bitDepth === 12) {
            chromaSubsamplingX = bitstream.readBits(1);
            if (chromaSubsamplingX) {
              chromaSubsamplingY = bitstream.readBits(1);
            }
          }
        }
        if (chromaSubsamplingX && chromaSubsamplingY) {
          chromaSamplePosition = bitstream.readBits(2);
        }
      }
      return {
        profile: seqProfile,
        level: seqLevel,
        tier: seqTier,
        bitDepth,
        monochrome,
        chromaSubsamplingX,
        chromaSubsamplingY,
        chromaSamplePosition
      };
    }
    return null;
  };
  var parseOpusIdentificationHeader = (bytes2) => {
    const view2 = toDataView(bytes2);
    const outputChannelCount = view2.getUint8(9);
    const preSkip = view2.getUint16(10, true);
    const inputSampleRate = view2.getUint32(12, true);
    const outputGain = view2.getInt16(16, true);
    const channelMappingFamily = view2.getUint8(18);
    let channelMappingTable = null;
    if (channelMappingFamily) {
      channelMappingTable = bytes2.subarray(19, 19 + 2 + outputChannelCount);
    }
    return {
      outputChannelCount,
      preSkip,
      inputSampleRate,
      outputGain,
      channelMappingFamily,
      channelMappingTable
    };
  };
  var OPUS_FRAME_DURATION_TABLE = [
    480,
    960,
    1920,
    2880,
    480,
    960,
    1920,
    2880,
    480,
    960,
    1920,
    2880,
    480,
    960,
    480,
    960,
    120,
    240,
    480,
    960,
    120,
    240,
    480,
    960,
    120,
    240,
    480,
    960,
    120,
    240,
    480,
    960
  ];
  var parseOpusTocByte = (packet) => {
    const config = packet[0] >> 3;
    return {
      durationInSamples: OPUS_FRAME_DURATION_TABLE[config]
    };
  };
  var parseModesFromVorbisSetupPacket = (setupHeader) => {
    if (setupHeader.length < 7) {
      throw new Error("Setup header is too short.");
    }
    if (setupHeader[0] !== 5) {
      throw new Error("Wrong packet type in Setup header.");
    }
    const signature = String.fromCharCode(...setupHeader.slice(1, 7));
    if (signature !== "vorbis") {
      throw new Error("Invalid packet signature in Setup header.");
    }
    const bufSize = setupHeader.length;
    const revBuffer = new Uint8Array(bufSize);
    for (let i = 0; i < bufSize; i++) {
      revBuffer[i] = setupHeader[bufSize - 1 - i];
    }
    const bitstream = new Bitstream(revBuffer);
    let gotFramingBit = 0;
    while (bitstream.getBitsLeft() > 97) {
      if (bitstream.readBits(1) === 1) {
        gotFramingBit = bitstream.pos;
        break;
      }
    }
    if (gotFramingBit === 0) {
      throw new Error("Invalid Setup header: framing bit not found.");
    }
    let modeCount = 0;
    let gotModeHeader = false;
    let lastModeCount = 0;
    while (bitstream.getBitsLeft() >= 97) {
      const tempPos = bitstream.pos;
      const a = bitstream.readBits(8);
      const b = bitstream.readBits(16);
      const c = bitstream.readBits(16);
      if (a > 63 || b !== 0 || c !== 0) {
        bitstream.pos = tempPos;
        break;
      }
      bitstream.skipBits(1);
      modeCount++;
      if (modeCount > 64) {
        break;
      }
      const bsClone = bitstream.clone();
      const candidate = bsClone.readBits(6) + 1;
      if (candidate === modeCount) {
        gotModeHeader = true;
        lastModeCount = modeCount;
      }
    }
    if (!gotModeHeader) {
      throw new Error("Invalid Setup header: mode header not found.");
    }
    if (lastModeCount > 63) {
      throw new Error(`Unsupported mode count: ${lastModeCount}.`);
    }
    const finalModeCount = lastModeCount;
    bitstream.pos = 0;
    bitstream.skipBits(gotFramingBit);
    const modeBlockflags = Array(finalModeCount).fill(0);
    for (let i = finalModeCount - 1; i >= 0; i--) {
      bitstream.skipBits(40);
      modeBlockflags[i] = bitstream.readBits(1);
    }
    return { modeBlockflags };
  };
  var determineVideoPacketType = (codec, decoderConfig, packetData) => {
    switch (codec) {
      case "avc":
        {
          for (const loc of iterateAvcNalUnits(packetData, decoderConfig)) {
            const nalTypeByte = packetData[loc.offset];
            const type = extractNalUnitTypeForAvc(nalTypeByte);
            if (type >= 1 /* NON_IDR_SLICE */ && type <= 4 /* SLICE_DPC */) {
              return "delta";
            }
            if (type === 5 /* IDR */) {
              return "key";
            }
            if (type === 6 /* SEI */ && (!isChromium() || getChromiumVersion() >= 144)) {
              const nalUnit = packetData.subarray(loc.offset, loc.offset + loc.length);
              const bytes2 = removeEmulationPreventionBytes(nalUnit);
              let pos = 1;
              do {
                let payloadType = 0;
                while (true) {
                  const nextByte = bytes2[pos++];
                  if (nextByte === void 0) break;
                  payloadType += nextByte;
                  if (nextByte < 255) {
                    break;
                  }
                }
                let payloadSize = 0;
                while (true) {
                  const nextByte = bytes2[pos++];
                  if (nextByte === void 0) break;
                  payloadSize += nextByte;
                  if (nextByte < 255) {
                    break;
                  }
                }
                const PAYLOAD_TYPE_RECOVERY_POINT = 6;
                if (payloadType === PAYLOAD_TYPE_RECOVERY_POINT) {
                  const bitstream = new Bitstream(bytes2);
                  bitstream.pos = 8 * pos;
                  const recoveryFrameCount = readExpGolomb(bitstream);
                  const exactMatchFlag = bitstream.readBits(1);
                  if (recoveryFrameCount === 0 && exactMatchFlag === 1) {
                    return "key";
                  }
                }
                pos += payloadSize;
              } while (pos < bytes2.length - 1);
            }
          }
          return "delta";
        }
        // removed by dead control flow

      case "hevc":
        {
          for (const loc of iterateHevcNalUnits(packetData, decoderConfig)) {
            const type = extractNalUnitTypeForHevc(packetData[loc.offset]);
            if (type < 16 /* BLA_W_LP */) {
              return "delta";
            }
            if (type <= 23 /* RSV_IRAP_VCL23 */) {
              return "key";
            }
          }
          return "delta";
        }
        // removed by dead control flow

      case "vp8":
        {
          const frameType = packetData[0] & 1;
          return frameType === 0 ? "key" : "delta";
        }
        // removed by dead control flow

      case "vp9":
        {
          const bitstream = new Bitstream(packetData);
          if (bitstream.readBits(2) !== 2) {
            return null;
          }
          ;
          const profileLowBit = bitstream.readBits(1);
          const profileHighBit = bitstream.readBits(1);
          const profile = (profileHighBit << 1) + profileLowBit;
          if (profile === 3) {
            bitstream.skipBits(1);
          }
          const showExistingFrame = bitstream.readBits(1);
          if (showExistingFrame) {
            return null;
          }
          const frameType = bitstream.readBits(1);
          return frameType === 0 ? "key" : "delta";
        }
        // removed by dead control flow

      case "av1":
        {
          let reducedStillPictureHeader = false;
          for (const { type, data } of iterateAv1PacketObus(packetData)) {
            if (type === 1) {
              const bitstream = new Bitstream(data);
              bitstream.skipBits(4);
              reducedStillPictureHeader = !!bitstream.readBits(1);
            } else if (type === 3 || type === 6 || type === 7) {
              if (reducedStillPictureHeader) {
                return "key";
              }
              const bitstream = new Bitstream(data);
              const showExistingFrame = bitstream.readBits(1);
              if (showExistingFrame) {
                return null;
              }
              const frameType = bitstream.readBits(2);
              return frameType === 0 ? "key" : "delta";
            }
          }
          return null;
        }
        // removed by dead control flow

      default:
        {
          assertNever(codec);
          assert(false);
        }
        ;
    }
  };
  var readVorbisComments = (bytes2, metadataTags) => {
    const commentView = toDataView(bytes2);
    let commentPos = 0;
    const vendorStringLength = commentView.getUint32(commentPos, true);
    commentPos += 4;
    const vendorString = textDecoder.decode(
      bytes2.subarray(commentPos, commentPos + vendorStringLength)
    );
    commentPos += vendorStringLength;
    if (vendorStringLength > 0) {
      metadataTags.raw ??= {};
      metadataTags.raw["vendor"] ??= vendorString;
    }
    const listLength = commentView.getUint32(commentPos, true);
    commentPos += 4;
    for (let i = 0; i < listLength; i++) {
      const stringLength = commentView.getUint32(commentPos, true);
      commentPos += 4;
      const string = textDecoder.decode(
        bytes2.subarray(commentPos, commentPos + stringLength)
      );
      commentPos += stringLength;
      const separatorIndex = string.indexOf("=");
      if (separatorIndex === -1) {
        continue;
      }
      const key = string.slice(0, separatorIndex).toUpperCase();
      const value = string.slice(separatorIndex + 1);
      metadataTags.raw ??= {};
      metadataTags.raw[key] ??= value;
      switch (key) {
        case "TITLE":
          {
            metadataTags.title ??= value;
          }
          ;
          break;
        case "DESCRIPTION":
          {
            metadataTags.description ??= value;
          }
          ;
          break;
        case "ARTIST":
          {
            metadataTags.artist ??= value;
          }
          ;
          break;
        case "ALBUM":
          {
            metadataTags.album ??= value;
          }
          ;
          break;
        case "ALBUMARTIST":
          {
            metadataTags.albumArtist ??= value;
          }
          ;
          break;
        case "COMMENT":
          {
            metadataTags.comment ??= value;
          }
          ;
          break;
        case "LYRICS":
          {
            metadataTags.lyrics ??= value;
          }
          ;
          break;
        case "TRACKNUMBER":
          {
            const parts = value.split("/");
            const trackNum = Number.parseInt(parts[0], 10);
            const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);
            if (Number.isInteger(trackNum) && trackNum > 0) {
              metadataTags.trackNumber ??= trackNum;
            }
            if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {
              metadataTags.tracksTotal ??= tracksTotal;
            }
          }
          ;
          break;
        case "TRACKTOTAL":
          {
            const tracksTotal = Number.parseInt(value, 10);
            if (Number.isInteger(tracksTotal) && tracksTotal > 0) {
              metadataTags.tracksTotal ??= tracksTotal;
            }
          }
          ;
          break;
        case "DISCNUMBER":
          {
            const parts = value.split("/");
            const discNum = Number.parseInt(parts[0], 10);
            const discsTotal = parts[1] && Number.parseInt(parts[1], 10);
            if (Number.isInteger(discNum) && discNum > 0) {
              metadataTags.discNumber ??= discNum;
            }
            if (discsTotal && Number.isInteger(discsTotal) && discsTotal > 0) {
              metadataTags.discsTotal ??= discsTotal;
            }
          }
          ;
          break;
        case "DISCTOTAL":
          {
            const discsTotal = Number.parseInt(value, 10);
            if (Number.isInteger(discsTotal) && discsTotal > 0) {
              metadataTags.discsTotal ??= discsTotal;
            }
          }
          ;
          break;
        case "DATE":
          {
            const date = new Date(value);
            if (!Number.isNaN(date.getTime())) {
              metadataTags.date ??= date;
            }
          }
          ;
          break;
        case "GENRE":
          {
            metadataTags.genre ??= value;
          }
          ;
          break;
        case "METADATA_BLOCK_PICTURE":
          {
            const decoded = base64ToBytes(value);
            const view2 = toDataView(decoded);
            const pictureType = view2.getUint32(0, false);
            const mediaTypeLength = view2.getUint32(4, false);
            const mediaType = String.fromCharCode(...decoded.subarray(8, 8 + mediaTypeLength));
            const descriptionLength = view2.getUint32(8 + mediaTypeLength, false);
            const description = textDecoder.decode(decoded.subarray(
              12 + mediaTypeLength,
              12 + mediaTypeLength + descriptionLength
            ));
            const dataLength = view2.getUint32(mediaTypeLength + descriptionLength + 28);
            const data = decoded.subarray(
              mediaTypeLength + descriptionLength + 32,
              mediaTypeLength + descriptionLength + 32 + dataLength
            );
            metadataTags.images ??= [];
            metadataTags.images.push({
              data,
              mimeType: mediaType,
              kind: pictureType === 3 ? "coverFront" : pictureType === 4 ? "coverBack" : "unknown",
              name: void 0,
              description: description || void 0
            });
          }
          ;
          break;
      }
    }
  };
  var createVorbisComments = (headerBytes, tags, writeImages) => {
    const commentHeaderParts = [
      headerBytes
    ];
    const vendorString = "Mediabunny";
    const encodedVendorString = textEncoder.encode(vendorString);
    let currentBuffer = new Uint8Array(4 + encodedVendorString.length);
    let currentView = new DataView(currentBuffer.buffer);
    currentView.setUint32(0, encodedVendorString.length, true);
    currentBuffer.set(encodedVendorString, 4);
    commentHeaderParts.push(currentBuffer);
    const writtenTags = /* @__PURE__ */ new Set();
    const addCommentTag = (key, value) => {
      const joined = `${key}=${value}`;
      const encoded = textEncoder.encode(joined);
      currentBuffer = new Uint8Array(4 + encoded.length);
      currentView = new DataView(currentBuffer.buffer);
      currentView.setUint32(0, encoded.length, true);
      currentBuffer.set(encoded, 4);
      commentHeaderParts.push(currentBuffer);
      writtenTags.add(key);
    };
    for (const { key, value } of keyValueIterator(tags)) {
      switch (key) {
        case "title":
          {
            addCommentTag("TITLE", value);
          }
          ;
          break;
        case "description":
          {
            addCommentTag("DESCRIPTION", value);
          }
          ;
          break;
        case "artist":
          {
            addCommentTag("ARTIST", value);
          }
          ;
          break;
        case "album":
          {
            addCommentTag("ALBUM", value);
          }
          ;
          break;
        case "albumArtist":
          {
            addCommentTag("ALBUMARTIST", value);
          }
          ;
          break;
        case "genre":
          {
            addCommentTag("GENRE", value);
          }
          ;
          break;
        case "date":
          {
            const rawVersion = tags.raw?.["DATE"] ?? tags.raw?.["date"];
            if (rawVersion && typeof rawVersion === "string") {
              addCommentTag("DATE", rawVersion);
            } else {
              addCommentTag("DATE", value.toISOString().slice(0, 10));
            }
          }
          ;
          break;
        case "comment":
          {
            addCommentTag("COMMENT", value);
          }
          ;
          break;
        case "lyrics":
          {
            addCommentTag("LYRICS", value);
          }
          ;
          break;
        case "trackNumber":
          {
            addCommentTag("TRACKNUMBER", value.toString());
          }
          ;
          break;
        case "tracksTotal":
          {
            addCommentTag("TRACKTOTAL", value.toString());
          }
          ;
          break;
        case "discNumber":
          {
            addCommentTag("DISCNUMBER", value.toString());
          }
          ;
          break;
        case "discsTotal":
          {
            addCommentTag("DISCTOTAL", value.toString());
          }
          ;
          break;
        case "images":
          {
            if (!writeImages) {
              break;
            }
            for (const image of value) {
              const pictureType = image.kind === "coverFront" ? 3 : image.kind === "coverBack" ? 4 : 0;
              const encodedMediaType = new Uint8Array(image.mimeType.length);
              for (let i = 0; i < image.mimeType.length; i++) {
                encodedMediaType[i] = image.mimeType.charCodeAt(i);
              }
              const encodedDescription = textEncoder.encode(image.description ?? "");
              const buffer = new Uint8Array(
                4 + 4 + encodedMediaType.length + 4 + encodedDescription.length + 16 + 4 + image.data.length
                // Picture data
              );
              const view2 = toDataView(buffer);
              view2.setUint32(0, pictureType, false);
              view2.setUint32(4, encodedMediaType.length, false);
              buffer.set(encodedMediaType, 8);
              view2.setUint32(8 + encodedMediaType.length, encodedDescription.length, false);
              buffer.set(encodedDescription, 12 + encodedMediaType.length);
              view2.setUint32(
                28 + encodedMediaType.length + encodedDescription.length,
                image.data.length,
                false
              );
              buffer.set(
                image.data,
                32 + encodedMediaType.length + encodedDescription.length
              );
              const encoded = bytesToBase64(buffer);
              addCommentTag("METADATA_BLOCK_PICTURE", encoded);
            }
          }
          ;
          break;
        case "raw":
          {
          }
          ;
          break;
        default:
          assertNever(key);
      }
    }
    if (tags.raw) {
      for (const key in tags.raw) {
        const value = tags.raw[key] ?? tags.raw[key.toLowerCase()];
        if (key === "vendor" || value == null || writtenTags.has(key)) {
          continue;
        }
        if (typeof value === "string") {
          addCommentTag(key, value);
        }
      }
    }
    const listLengthBuffer = new Uint8Array(4);
    toDataView(listLengthBuffer).setUint32(0, writtenTags.size, true);
    commentHeaderParts.splice(2, 0, listLengthBuffer);
    const commentHeaderLength = commentHeaderParts.reduce((a, b) => a + b.length, 0);
    const commentHeader = new Uint8Array(commentHeaderLength);
    let pos = 0;
    for (const part of commentHeaderParts) {
      commentHeader.set(part, pos);
      pos += part.length;
    }
    return commentHeader;
  };
  var AC3_ACMOD_CHANNEL_COUNTS = [2, 1, 2, 3, 3, 4, 4, 5];
  var parseAc3SyncFrame = (data) => {
    if (data.length < 7) {
      return null;
    }
    if (data[0] !== 11 || data[1] !== 119) {
      return null;
    }
    const bitstream = new Bitstream(data);
    bitstream.skipBits(16);
    bitstream.skipBits(16);
    const fscod = bitstream.readBits(2);
    if (fscod === 3) {
      return null;
    }
    const frmsizecod = bitstream.readBits(6);
    const bsid = bitstream.readBits(5);
    if (bsid > 8) {
      return null;
    }
    const bsmod = bitstream.readBits(3);
    const acmod = bitstream.readBits(3);
    if ((acmod & 1) !== 0 && acmod !== 1) {
      bitstream.skipBits(2);
    }
    if ((acmod & 4) !== 0) {
      bitstream.skipBits(2);
    }
    if (acmod === 2) {
      bitstream.skipBits(2);
    }
    const lfeon = bitstream.readBits(1);
    const bitRateCode = Math.floor(frmsizecod / 2);
    return { fscod, bsid, bsmod, acmod, lfeon, bitRateCode };
  };
  var AC3_FRAME_SIZES = [
    // frmsizecod, [48kHz, 44.1kHz, 32kHz] in bytes
    64 * 2,
    69 * 2,
    96 * 2,
    64 * 2,
    70 * 2,
    96 * 2,
    80 * 2,
    87 * 2,
    120 * 2,
    80 * 2,
    88 * 2,
    120 * 2,
    96 * 2,
    104 * 2,
    144 * 2,
    96 * 2,
    105 * 2,
    144 * 2,
    112 * 2,
    121 * 2,
    168 * 2,
    112 * 2,
    122 * 2,
    168 * 2,
    128 * 2,
    139 * 2,
    192 * 2,
    128 * 2,
    140 * 2,
    192 * 2,
    160 * 2,
    174 * 2,
    240 * 2,
    160 * 2,
    175 * 2,
    240 * 2,
    192 * 2,
    208 * 2,
    288 * 2,
    192 * 2,
    209 * 2,
    288 * 2,
    224 * 2,
    243 * 2,
    336 * 2,
    224 * 2,
    244 * 2,
    336 * 2,
    256 * 2,
    278 * 2,
    384 * 2,
    256 * 2,
    279 * 2,
    384 * 2,
    320 * 2,
    348 * 2,
    480 * 2,
    320 * 2,
    349 * 2,
    480 * 2,
    384 * 2,
    417 * 2,
    576 * 2,
    384 * 2,
    418 * 2,
    576 * 2,
    448 * 2,
    487 * 2,
    672 * 2,
    448 * 2,
    488 * 2,
    672 * 2,
    512 * 2,
    557 * 2,
    768 * 2,
    512 * 2,
    558 * 2,
    768 * 2,
    640 * 2,
    696 * 2,
    960 * 2,
    640 * 2,
    697 * 2,
    960 * 2,
    768 * 2,
    835 * 2,
    1152 * 2,
    768 * 2,
    836 * 2,
    1152 * 2,
    896 * 2,
    975 * 2,
    1344 * 2,
    896 * 2,
    976 * 2,
    1344 * 2,
    1024 * 2,
    1114 * 2,
    1536 * 2,
    1024 * 2,
    1115 * 2,
    1536 * 2,
    1152 * 2,
    1253 * 2,
    1728 * 2,
    1152 * 2,
    1254 * 2,
    1728 * 2,
    1280 * 2,
    1393 * 2,
    1920 * 2,
    1280 * 2,
    1394 * 2,
    1920 * 2
  ];
  var AC3_SAMPLES_PER_FRAME = 1536;
  var AC3_REGISTRATION_DESCRIPTOR = new Uint8Array([5, 4, 65, 67, 45, 51]);
  var EAC3_REGISTRATION_DESCRIPTOR = new Uint8Array([5, 4, 69, 65, 67, 51]);
  var EAC3_NUMBLKS_TABLE = [1, 2, 3, 6];
  var parseEac3SyncFrame = (data) => {
    if (data.length < 6) {
      return null;
    }
    if (data[0] !== 11 || data[1] !== 119) {
      return null;
    }
    const bitstream = new Bitstream(data);
    bitstream.skipBits(16);
    const strmtyp = bitstream.readBits(2);
    bitstream.skipBits(3);
    if (strmtyp !== 0 && strmtyp !== 2) {
      return null;
    }
    const frmsiz = bitstream.readBits(11);
    const fscod = bitstream.readBits(2);
    let fscod2 = 0;
    let numblkscod;
    if (fscod === 3) {
      fscod2 = bitstream.readBits(2);
      numblkscod = 3;
    } else {
      numblkscod = bitstream.readBits(2);
    }
    const acmod = bitstream.readBits(3);
    const lfeon = bitstream.readBits(1);
    const bsid = bitstream.readBits(5);
    if (bsid < 11 || bsid > 16) {
      return null;
    }
    const numblks = EAC3_NUMBLKS_TABLE[numblkscod];
    let fs;
    if (fscod < 3) {
      fs = AC3_SAMPLE_RATES[fscod] / 1e3;
    } else {
      fs = EAC3_REDUCED_SAMPLE_RATES[fscod2] / 1e3;
    }
    const dataRate = Math.round((frmsiz + 1) * fs / (numblks * 16));
    const bsmod = 0;
    const numDepSub = 0;
    const chanLoc = 0;
    const substream = {
      fscod,
      fscod2,
      bsid,
      bsmod,
      acmod,
      lfeon,
      numDepSub,
      chanLoc
    };
    return {
      dataRate,
      substreams: [substream]
    };
  };
  var parseEac3Config = (data) => {
    if (data.length < 2) {
      return null;
    }
    const bitstream = new Bitstream(data);
    const dataRate = bitstream.readBits(13);
    const numIndSub = bitstream.readBits(3);
    const substreams = [];
    for (let i = 0; i <= numIndSub; i++) {
      if (Math.ceil(bitstream.pos / 8) + 3 > data.length) {
        break;
      }
      const fscod = bitstream.readBits(2);
      const bsid = bitstream.readBits(5);
      bitstream.skipBits(1);
      bitstream.skipBits(1);
      const bsmod = bitstream.readBits(3);
      const acmod = bitstream.readBits(3);
      const lfeon = bitstream.readBits(1);
      bitstream.skipBits(3);
      const numDepSub = bitstream.readBits(4);
      let chanLoc = 0;
      if (numDepSub > 0) {
        chanLoc = bitstream.readBits(9);
      } else {
        bitstream.skipBits(1);
      }
      substreams.push({
        fscod,
        fscod2: null,
        bsid,
        bsmod,
        acmod,
        lfeon,
        numDepSub,
        chanLoc
      });
    }
    if (substreams.length === 0) {
      return null;
    }
    return { dataRate, substreams };
  };
  var getEac3SampleRate = (config) => {
    const sub = config.substreams[0];
    assert(sub);
    if (sub.fscod < 3) {
      return AC3_SAMPLE_RATES[sub.fscod];
    } else if (sub.fscod2 !== null && sub.fscod2 < 3) {
      return EAC3_REDUCED_SAMPLE_RATES[sub.fscod2];
    }
    return null;
  };
  var getEac3ChannelCount = (config) => {
    const sub = config.substreams[0];
    assert(sub);
    let channels = AC3_ACMOD_CHANNEL_COUNTS[sub.acmod] + sub.lfeon;
    if (sub.numDepSub > 0) {
      const CHAN_LOC_COUNTS = [2, 2, 1, 1, 2, 2, 2, 1, 1];
      for (let bit = 0; bit < 9; bit++) {
        if (sub.chanLoc & 1 << 8 - bit) {
          channels += CHAN_LOC_COUNTS[bit];
        }
      }
    }
    return channels;
  };

  // src/demuxer.ts
  var Demuxer = class {
    constructor(input) {
      this.input = input;
    }
  };

  // src/custom-coder.ts
  var CustomVideoDecoder = class {
    /** Returns true if and only if the decoder can decode the given codec configuration. */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    static supports(codec, config) {
      return false;
    }
  };
  var CustomAudioDecoder = class {
    /** Returns true if and only if the decoder can decode the given codec configuration. */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    static supports(codec, config) {
      return false;
    }
  };
  var CustomVideoEncoder = class {
    /** Returns true if and only if the encoder can encode the given codec configuration. */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    static supports(codec, config) {
      return false;
    }
  };
  var CustomAudioEncoder = class {
    /** Returns true if and only if the encoder can encode the given codec configuration. */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    static supports(codec, config) {
      return false;
    }
  };
  var customVideoDecoders = [];
  var customAudioDecoders = [];
  var customVideoEncoders = [];
  var customAudioEncoders = [];
  var registerDecoder = (decoder) => {
    if (decoder.prototype instanceof CustomVideoDecoder) {
      const casted = decoder;
      if (customVideoDecoders.includes(casted)) {
        console.warn("Video decoder already registered.");
        return;
      }
      customVideoDecoders.push(casted);
    } else if (decoder.prototype instanceof CustomAudioDecoder) {
      const casted = decoder;
      if (customAudioDecoders.includes(casted)) {
        console.warn("Audio decoder already registered.");
        return;
      }
      customAudioDecoders.push(casted);
    } else {
      throw new TypeError("Decoder must be a CustomVideoDecoder or CustomAudioDecoder.");
    }
  };
  var registerEncoder = (encoder) => {
    if (encoder.prototype instanceof CustomVideoEncoder) {
      const casted = encoder;
      if (customVideoEncoders.includes(casted)) {
        console.warn("Video encoder already registered.");
        return;
      }
      customVideoEncoders.push(casted);
    } else if (encoder.prototype instanceof CustomAudioEncoder) {
      const casted = encoder;
      if (customAudioEncoders.includes(casted)) {
        console.warn("Audio encoder already registered.");
        return;
      }
      customAudioEncoders.push(casted);
    } else {
      throw new TypeError("Encoder must be a CustomVideoEncoder or CustomAudioEncoder.");
    }
  };

  // src/packet.ts
  var PLACEHOLDER_DATA = /* @__PURE__ */ new Uint8Array(0);
  var EncodedPacket = class _EncodedPacket {
    /** Creates a new {@link EncodedPacket} from raw bytes and timing information. */
    constructor(data, type, timestamp, duration, sequenceNumber = -1, byteLength, sideData) {
      this.data = data;
      this.type = type;
      this.timestamp = timestamp;
      this.duration = duration;
      this.sequenceNumber = sequenceNumber;
      if (data === PLACEHOLDER_DATA && byteLength === void 0) {
        throw new Error(
          "Internal error: byteLength must be explicitly provided when constructing metadata-only packets."
        );
      }
      if (byteLength === void 0) {
        byteLength = data.byteLength;
      }
      if (!(data instanceof Uint8Array)) {
        throw new TypeError("data must be a Uint8Array.");
      }
      if (type !== "key" && type !== "delta") {
        throw new TypeError('type must be either "key" or "delta".');
      }
      if (!Number.isFinite(timestamp)) {
        throw new TypeError("timestamp must be a number.");
      }
      if (!Number.isFinite(duration) || duration < 0) {
        throw new TypeError("duration must be a non-negative number.");
      }
      if (!Number.isFinite(sequenceNumber)) {
        throw new TypeError("sequenceNumber must be a number.");
      }
      if (!Number.isInteger(byteLength) || byteLength < 0) {
        throw new TypeError("byteLength must be a non-negative integer.");
      }
      if (sideData !== void 0 && (typeof sideData !== "object" || !sideData)) {
        throw new TypeError("sideData, when provided, must be an object.");
      }
      if (sideData?.alpha !== void 0 && !(sideData.alpha instanceof Uint8Array)) {
        throw new TypeError("sideData.alpha, when provided, must be a Uint8Array.");
      }
      if (sideData?.alphaByteLength !== void 0 && (!Number.isInteger(sideData.alphaByteLength) || sideData.alphaByteLength < 0)) {
        throw new TypeError("sideData.alphaByteLength, when provided, must be a non-negative integer.");
      }
      this.byteLength = byteLength;
      this.sideData = sideData ?? {};
      if (this.sideData.alpha && this.sideData.alphaByteLength === void 0) {
        this.sideData.alphaByteLength = this.sideData.alpha.byteLength;
      }
    }
    /**
     * If this packet is a metadata-only packet. Metadata-only packets don't contain their packet data. They are the
     * result of retrieving packets with {@link PacketRetrievalOptions.metadataOnly} set to `true`.
     */
    get isMetadataOnly() {
      return this.data === PLACEHOLDER_DATA;
    }
    /** The timestamp of this packet in microseconds. */
    get microsecondTimestamp() {
      return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.timestamp);
    }
    /** The duration of this packet in microseconds. */
    get microsecondDuration() {
      return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.duration);
    }
    /** Converts this packet to an
     * [`EncodedVideoChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) for use with the
     * WebCodecs API. */
    toEncodedVideoChunk() {
      if (this.isMetadataOnly) {
        throw new TypeError("Metadata-only packets cannot be converted to a video chunk.");
      }
      if (typeof EncodedVideoChunk === "undefined") {
        throw new Error("Your browser does not support EncodedVideoChunk.");
      }
      return new EncodedVideoChunk({
        data: this.data,
        type: this.type,
        timestamp: this.microsecondTimestamp,
        duration: this.microsecondDuration
      });
    }
    /**
     * Converts this packet to an
     * [`EncodedVideoChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) for use with the
     * WebCodecs API, using the alpha side data instead of the color data. Throws if no alpha side data is defined.
     */
    alphaToEncodedVideoChunk(type = this.type) {
      if (!this.sideData.alpha) {
        throw new TypeError("This packet does not contain alpha side data.");
      }
      if (this.isMetadataOnly) {
        throw new TypeError("Metadata-only packets cannot be converted to a video chunk.");
      }
      if (typeof EncodedVideoChunk === "undefined") {
        throw new Error("Your browser does not support EncodedVideoChunk.");
      }
      return new EncodedVideoChunk({
        data: this.sideData.alpha,
        type,
        timestamp: this.microsecondTimestamp,
        duration: this.microsecondDuration
      });
    }
    /** Converts this packet to an
     * [`EncodedAudioChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedAudioChunk) for use with the
     * WebCodecs API. */
    toEncodedAudioChunk() {
      if (this.isMetadataOnly) {
        throw new TypeError("Metadata-only packets cannot be converted to an audio chunk.");
      }
      if (typeof EncodedAudioChunk === "undefined") {
        throw new Error("Your browser does not support EncodedAudioChunk.");
      }
      return new EncodedAudioChunk({
        data: this.data,
        type: this.type,
        timestamp: this.microsecondTimestamp,
        duration: this.microsecondDuration
      });
    }
    /**
     * Creates an {@link EncodedPacket} from an
     * [`EncodedVideoChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) or
     * [`EncodedAudioChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedAudioChunk). This method is useful
     * for converting chunks from the WebCodecs API to `EncodedPacket` instances.
     */
    static fromEncodedChunk(chunk, sideData) {
      if (!(chunk instanceof EncodedVideoChunk || chunk instanceof EncodedAudioChunk)) {
        throw new TypeError("chunk must be an EncodedVideoChunk or EncodedAudioChunk.");
      }
      const data = new Uint8Array(chunk.byteLength);
      chunk.copyTo(data);
      return new _EncodedPacket(
        data,
        chunk.type,
        chunk.timestamp / 1e6,
        (chunk.duration ?? 0) / 1e6,
        void 0,
        void 0,
        sideData
      );
    }
    /** Clones this packet while optionally modifying the new packet's data. */
    clone(options) {
      if (options !== void 0 && (typeof options !== "object" || options === null)) {
        throw new TypeError("options, when provided, must be an object.");
      }
      if (options?.data !== void 0 && !(options.data instanceof Uint8Array)) {
        throw new TypeError("options.data, when provided, must be a Uint8Array.");
      }
      if (options?.type !== void 0 && options.type !== "key" && options.type !== "delta") {
        throw new TypeError('options.type, when provided, must be either "key" or "delta".');
      }
      if (options?.timestamp !== void 0 && !Number.isFinite(options.timestamp)) {
        throw new TypeError("options.timestamp, when provided, must be a number.");
      }
      if (options?.duration !== void 0 && !Number.isFinite(options.duration)) {
        throw new TypeError("options.duration, when provided, must be a number.");
      }
      if (options?.sequenceNumber !== void 0 && !Number.isFinite(options.sequenceNumber)) {
        throw new TypeError("options.sequenceNumber, when provided, must be a number.");
      }
      if (options?.sideData !== void 0 && (typeof options.sideData !== "object" || options.sideData === null)) {
        throw new TypeError("options.sideData, when provided, must be an object.");
      }
      return new _EncodedPacket(
        options?.data ?? this.data,
        options?.type ?? this.type,
        options?.timestamp ?? this.timestamp,
        options?.duration ?? this.duration,
        options?.sequenceNumber ?? this.sequenceNumber,
        this.byteLength,
        options?.sideData ?? this.sideData
      );
    }
  };

  // src/pcm.ts
  var toUlaw = (s16) => {
    const MULAW_MAX = 8191;
    const MULAW_BIAS = 33;
    let number = s16;
    let mask = 4096;
    let sign = 0;
    let position = 12;
    let lsb = 0;
    if (number < 0) {
      number = -number;
      sign = 128;
    }
    number += MULAW_BIAS;
    if (number > MULAW_MAX) {
      number = MULAW_MAX;
    }
    while ((number & mask) !== mask && position >= 5) {
      mask >>= 1;
      position--;
    }
    lsb = number >> position - 4 & 15;
    return ~(sign | position - 5 << 4 | lsb) & 255;
  };
  var fromUlaw = (u82) => {
    const MULAW_BIAS = 33;
    let sign = 0;
    let position = 0;
    let number = ~u82;
    if (number & 128) {
      number &= ~(1 << 7);
      sign = -1;
    }
    position = ((number & 240) >> 4) + 5;
    const decoded = (1 << position | (number & 15) << position - 4 | 1 << position - 5) - MULAW_BIAS;
    return sign === 0 ? decoded : -decoded;
  };
  var toAlaw = (s16) => {
    const ALAW_MAX = 4095;
    let mask = 2048;
    let sign = 0;
    let position = 11;
    let lsb = 0;
    let number = s16;
    if (number < 0) {
      number = -number;
      sign = 128;
    }
    if (number > ALAW_MAX) {
      number = ALAW_MAX;
    }
    while ((number & mask) !== mask && position >= 5) {
      mask >>= 1;
      position--;
    }
    lsb = number >> (position === 4 ? 1 : position - 4) & 15;
    return (sign | position - 4 << 4 | lsb) ^ 85;
  };
  var fromAlaw = (u82) => {
    let sign = 0;
    let position = 0;
    let number = u82 ^ 85;
    if (number & 128) {
      number &= ~(1 << 7);
      sign = -1;
    }
    position = ((number & 240) >> 4) + 4;
    let decoded = 0;
    if (position !== 4) {
      decoded = 1 << position | (number & 15) << position - 4 | 1 << position - 5;
    } else {
      decoded = number << 1 | 1;
    }
    return sign === 0 ? decoded : -decoded;
  };

  // src/sample.ts
  polyfillSymbolDispose();
  var lastVideoGcErrorLog = -Infinity;
  var lastAudioGcErrorLog = -Infinity;
  var finalizationRegistry = null;
  if (typeof FinalizationRegistry !== "undefined") {
    finalizationRegistry = new FinalizationRegistry((value) => {
      const now = Date.now();
      if (value.type === "video") {
        if (now - lastVideoGcErrorLog >= 1e3) {
          console.error(
            `A VideoSample was garbage collected without first being closed. For proper resource management, make sure to call close() on all your VideoSamples as soon as you're done using them.`
          );
          lastVideoGcErrorLog = now;
        }
        if (typeof VideoFrame !== "undefined" && value.data instanceof VideoFrame) {
          value.data.close();
        }
      } else {
        if (now - lastAudioGcErrorLog >= 1e3) {
          console.error(
            `An AudioSample was garbage collected without first being closed. For proper resource management, make sure to call close() on all your AudioSamples as soon as you're done using them.`
          );
          lastAudioGcErrorLog = now;
        }
        if (typeof AudioData !== "undefined" && value.data instanceof AudioData) {
          value.data.close();
        }
      }
    });
  }
  var VIDEO_SAMPLE_PIXEL_FORMATS = [
    // 4:2:0 Y, U, V
    "I420",
    "I420P10",
    "I420P12",
    // 4:2:0 Y, U, V, A
    "I420A",
    "I420AP10",
    "I420AP12",
    // 4:2:2 Y, U, V
    "I422",
    "I422P10",
    "I422P12",
    // 4:2:2 Y, U, V, A
    "I422A",
    "I422AP10",
    "I422AP12",
    // 4:4:4 Y, U, V
    "I444",
    "I444P10",
    "I444P12",
    // 4:4:4 Y, U, V, A
    "I444A",
    "I444AP10",
    "I444AP12",
    // 4:2:0 Y, UV
    "NV12",
    // 4:4:4 RGBA
    "RGBA",
    // 4:4:4 RGBX (opaque)
    "RGBX",
    // 4:4:4 BGRA
    "BGRA",
    // 4:4:4 BGRX (opaque)
    "BGRX"
  ];
  var VIDEO_SAMPLE_PIXEL_FORMATS_SET = new Set(VIDEO_SAMPLE_PIXEL_FORMATS);
  var VideoSample = class _VideoSample {
    constructor(data, init) {
      /** @internal */
      this._closed = false;
      if (data instanceof ArrayBuffer || typeof SharedArrayBuffer !== "undefined" && data instanceof SharedArrayBuffer || ArrayBuffer.isView(data)) {
        if (!init || typeof init !== "object") {
          throw new TypeError("init must be an object.");
        }
        if (init.format === void 0 || !VIDEO_SAMPLE_PIXEL_FORMATS_SET.has(init.format)) {
          throw new TypeError("init.format must be one of: " + VIDEO_SAMPLE_PIXEL_FORMATS.join(", "));
        }
        if (!Number.isInteger(init.codedWidth) || init.codedWidth <= 0) {
          throw new TypeError("init.codedWidth must be a positive integer.");
        }
        if (!Number.isInteger(init.codedHeight) || init.codedHeight <= 0) {
          throw new TypeError("init.codedHeight must be a positive integer.");
        }
        if (init.rotation !== void 0 && ![0, 90, 180, 270].includes(init.rotation)) {
          throw new TypeError("init.rotation, when provided, must be 0, 90, 180, or 270.");
        }
        if (!Number.isFinite(init.timestamp)) {
          throw new TypeError("init.timestamp must be a number.");
        }
        if (init.duration !== void 0 && (!Number.isFinite(init.duration) || init.duration < 0)) {
          throw new TypeError("init.duration, when provided, must be a non-negative number.");
        }
        this._data = toUint8Array(data).slice();
        this._layout = init.layout ?? createDefaultPlaneLayout(init.format, init.codedWidth, init.codedHeight);
        this.format = init.format;
        this.codedWidth = init.codedWidth;
        this.codedHeight = init.codedHeight;
        this.rotation = init.rotation ?? 0;
        this.timestamp = init.timestamp;
        this.duration = init.duration ?? 0;
        this.colorSpace = new VideoSampleColorSpace(init.colorSpace);
      } else if (typeof VideoFrame !== "undefined" && data instanceof VideoFrame) {
        if (init?.rotation !== void 0 && ![0, 90, 180, 270].includes(init.rotation)) {
          throw new TypeError("init.rotation, when provided, must be 0, 90, 180, or 270.");
        }
        if (init?.timestamp !== void 0 && !Number.isFinite(init?.timestamp)) {
          throw new TypeError("init.timestamp, when provided, must be a number.");
        }
        if (init?.duration !== void 0 && (!Number.isFinite(init.duration) || init.duration < 0)) {
          throw new TypeError("init.duration, when provided, must be a non-negative number.");
        }
        this._data = data;
        this._layout = null;
        this.format = data.format;
        this.codedWidth = data.displayWidth;
        this.codedHeight = data.displayHeight;
        this.rotation = init?.rotation ?? 0;
        this.timestamp = init?.timestamp ?? data.timestamp / 1e6;
        this.duration = init?.duration ?? (data.duration ?? 0) / 1e6;
        this.colorSpace = new VideoSampleColorSpace(data.colorSpace);
      } else if (typeof HTMLImageElement !== "undefined" && data instanceof HTMLImageElement || typeof SVGImageElement !== "undefined" && data instanceof SVGImageElement || typeof ImageBitmap !== "undefined" && data instanceof ImageBitmap || typeof HTMLVideoElement !== "undefined" && data instanceof HTMLVideoElement || typeof HTMLCanvasElement !== "undefined" && data instanceof HTMLCanvasElement || typeof OffscreenCanvas !== "undefined" && data instanceof OffscreenCanvas) {
        if (!init || typeof init !== "object") {
          throw new TypeError("init must be an object.");
        }
        if (init.rotation !== void 0 && ![0, 90, 180, 270].includes(init.rotation)) {
          throw new TypeError("init.rotation, when provided, must be 0, 90, 180, or 270.");
        }
        if (!Number.isFinite(init.timestamp)) {
          throw new TypeError("init.timestamp must be a number.");
        }
        if (init.duration !== void 0 && (!Number.isFinite(init.duration) || init.duration < 0)) {
          throw new TypeError("init.duration, when provided, must be a non-negative number.");
        }
        if (typeof VideoFrame !== "undefined") {
          return new _VideoSample(
            new VideoFrame(data, {
              timestamp: Math.trunc(init.timestamp * SECOND_TO_MICROSECOND_FACTOR),
              // Drag 0 to undefined
              duration: Math.trunc((init.duration ?? 0) * SECOND_TO_MICROSECOND_FACTOR) || void 0
            }),
            init
          );
        }
        let width = 0;
        let height = 0;
        if ("naturalWidth" in data) {
          width = data.naturalWidth;
          height = data.naturalHeight;
        } else if ("videoWidth" in data) {
          width = data.videoWidth;
          height = data.videoHeight;
        } else if ("width" in data) {
          width = Number(data.width);
          height = Number(data.height);
        }
        if (!width || !height) {
          throw new TypeError("Could not determine dimensions.");
        }
        const canvas = new OffscreenCanvas(width, height);
        const context = canvas.getContext("2d", {
          alpha: isFirefox(),
          // Firefox has VideoFrame glitches with opaque canvases
          willReadFrequently: true
        });
        assert(context);
        context.drawImage(data, 0, 0);
        this._data = canvas;
        this._layout = null;
        this.format = "RGBX";
        this.codedWidth = width;
        this.codedHeight = height;
        this.rotation = init.rotation ?? 0;
        this.timestamp = init.timestamp;
        this.duration = init.duration ?? 0;
        this.colorSpace = new VideoSampleColorSpace({
          matrix: "rgb",
          primaries: "bt709",
          transfer: "iec61966-2-1",
          fullRange: true
        });
      } else {
        throw new TypeError("Invalid data type: Must be a BufferSource or CanvasImageSource.");
      }
      finalizationRegistry?.register(this, { type: "video", data: this._data }, this);
    }
    /** The width of the frame in pixels after rotation. */
    get displayWidth() {
      return this.rotation % 180 === 0 ? this.codedWidth : this.codedHeight;
    }
    /** The height of the frame in pixels after rotation. */
    get displayHeight() {
      return this.rotation % 180 === 0 ? this.codedHeight : this.codedWidth;
    }
    /** The presentation timestamp of the frame in microseconds. */
    get microsecondTimestamp() {
      return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.timestamp);
    }
    /** The duration of the frame in microseconds. */
    get microsecondDuration() {
      return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.duration);
    }
    /**
     * Whether this sample uses a pixel format that can hold transparency data. Note that this doesn't necessarily mean
     * that the sample is transparent.
     */
    get hasAlpha() {
      return this.format && this.format.includes("A");
    }
    /** Clones this video sample. */
    clone() {
      if (this._closed) {
        throw new Error("VideoSample is closed.");
      }
      assert(this._data !== null);
      if (isVideoFrame(this._data)) {
        return new _VideoSample(this._data.clone(), {
          timestamp: this.timestamp,
          duration: this.duration,
          rotation: this.rotation
        });
      } else if (this._data instanceof Uint8Array) {
        assert(this._layout);
        return new _VideoSample(this._data, {
          format: this.format,
          layout: this._layout,
          codedWidth: this.codedWidth,
          codedHeight: this.codedHeight,
          timestamp: this.timestamp,
          duration: this.duration,
          colorSpace: this.colorSpace,
          rotation: this.rotation
        });
      } else {
        return new _VideoSample(this._data, {
          format: this.format,
          codedWidth: this.codedWidth,
          codedHeight: this.codedHeight,
          timestamp: this.timestamp,
          duration: this.duration,
          colorSpace: this.colorSpace,
          rotation: this.rotation
        });
      }
    }
    /**
     * Closes this video sample, releasing held resources. Video samples should be closed as soon as they are not
     * needed anymore.
     */
    close() {
      if (this._closed) {
        return;
      }
      finalizationRegistry?.unregister(this);
      if (isVideoFrame(this._data)) {
        this._data.close();
      } else {
        this._data = null;
      }
      this._closed = true;
    }
    /**
     * Returns the number of bytes required to hold this video sample's pixel data. Throws if `format` is `null`.
     */
    allocationSize(options = {}) {
      validateVideoFrameCopyToOptions(options);
      if (this._closed) {
        throw new Error("VideoSample is closed.");
      }
      if (this.format === null) {
        throw new Error("Cannot get allocation size when format is null. Sorry!");
      }
      assert(this._data !== null);
      if (!isVideoFrame(this._data)) {
        if (options.colorSpace || options.format && options.format !== this.format || options.layout || options.rect) {
          const videoFrame = this.toVideoFrame();
          const size = videoFrame.allocationSize(options);
          videoFrame.close();
          return size;
        }
      }
      if (isVideoFrame(this._data)) {
        return this._data.allocationSize(options);
      } else if (this._data instanceof Uint8Array) {
        return this._data.byteLength;
      } else {
        return this.codedWidth * this.codedHeight * 4;
      }
    }
    /**
     * Copies this video sample's pixel data to an ArrayBuffer or ArrayBufferView. Throws if `format` is `null`.
     * @returns The byte layout of the planes of the copied data.
     */
    async copyTo(destination, options = {}) {
      if (!isAllowSharedBufferSource(destination)) {
        throw new TypeError("destination must be an ArrayBuffer or an ArrayBuffer view.");
      }
      validateVideoFrameCopyToOptions(options);
      if (this._closed) {
        throw new Error("VideoSample is closed.");
      }
      if (this.format === null) {
        throw new Error("Cannot copy video sample data when format is null. Sorry!");
      }
      assert(this._data !== null);
      if (!isVideoFrame(this._data)) {
        if (options.colorSpace || options.format && options.format !== this.format || options.layout || options.rect) {
          const videoFrame = this.toVideoFrame();
          const layout = await videoFrame.copyTo(destination, options);
          videoFrame.close();
          return layout;
        }
      }
      if (isVideoFrame(this._data)) {
        return this._data.copyTo(destination, options);
      } else if (this._data instanceof Uint8Array) {
        assert(this._layout);
        const dest = toUint8Array(destination);
        dest.set(this._data);
        return this._layout;
      } else {
        const canvas = this._data;
        const context = canvas.getContext("2d");
        assert(context);
        const imageData = context.getImageData(0, 0, this.codedWidth, this.codedHeight);
        const dest = toUint8Array(destination);
        dest.set(imageData.data);
        return [{
          offset: 0,
          stride: 4 * this.codedWidth
        }];
      }
    }
    /**
     * Converts this video sample to a VideoFrame for use with the WebCodecs API. The VideoFrame returned by this
     * method *must* be closed separately from this video sample.
     */
    toVideoFrame() {
      if (this._closed) {
        throw new Error("VideoSample is closed.");
      }
      assert(this._data !== null);
      if (isVideoFrame(this._data)) {
        return new VideoFrame(this._data, {
          timestamp: this.microsecondTimestamp,
          duration: this.microsecondDuration || void 0
          // Drag 0 duration to undefined, glitches some codecs
        });
      } else if (this._data instanceof Uint8Array) {
        return new VideoFrame(this._data, {
          format: this.format,
          codedWidth: this.codedWidth,
          codedHeight: this.codedHeight,
          timestamp: this.microsecondTimestamp,
          duration: this.microsecondDuration || void 0,
          colorSpace: this.colorSpace
        });
      } else {
        return new VideoFrame(this._data, {
          timestamp: this.microsecondTimestamp,
          duration: this.microsecondDuration || void 0
        });
      }
    }
    draw(context, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) {
      let sx = 0;
      let sy = 0;
      let sWidth = this.displayWidth;
      let sHeight = this.displayHeight;
      let dx = 0;
      let dy = 0;
      let dWidth = this.displayWidth;
      let dHeight = this.displayHeight;
      if (arg5 !== void 0) {
        sx = arg1;
        sy = arg2;
        sWidth = arg3;
        sHeight = arg4;
        dx = arg5;
        dy = arg6;
        if (arg7 !== void 0) {
          dWidth = arg7;
          dHeight = arg8;
        } else {
          dWidth = sWidth;
          dHeight = sHeight;
        }
      } else {
        dx = arg1;
        dy = arg2;
        if (arg3 !== void 0) {
          dWidth = arg3;
          dHeight = arg4;
        }
      }
      if (!(typeof CanvasRenderingContext2D !== "undefined" && context instanceof CanvasRenderingContext2D || typeof OffscreenCanvasRenderingContext2D !== "undefined" && context instanceof OffscreenCanvasRenderingContext2D)) {
        throw new TypeError("context must be a CanvasRenderingContext2D or OffscreenCanvasRenderingContext2D.");
      }
      if (!Number.isFinite(sx)) {
        throw new TypeError("sx must be a number.");
      }
      if (!Number.isFinite(sy)) {
        throw new TypeError("sy must be a number.");
      }
      if (!Number.isFinite(sWidth) || sWidth < 0) {
        throw new TypeError("sWidth must be a non-negative number.");
      }
      if (!Number.isFinite(sHeight) || sHeight < 0) {
        throw new TypeError("sHeight must be a non-negative number.");
      }
      if (!Number.isFinite(dx)) {
        throw new TypeError("dx must be a number.");
      }
      if (!Number.isFinite(dy)) {
        throw new TypeError("dy must be a number.");
      }
      if (!Number.isFinite(dWidth) || dWidth < 0) {
        throw new TypeError("dWidth must be a non-negative number.");
      }
      if (!Number.isFinite(dHeight) || dHeight < 0) {
        throw new TypeError("dHeight must be a non-negative number.");
      }
      if (this._closed) {
        throw new Error("VideoSample is closed.");
      }
      ({ sx, sy, sWidth, sHeight } = this._rotateSourceRegion(sx, sy, sWidth, sHeight, this.rotation));
      const source = this.toCanvasImageSource();
      context.save();
      const centerX = dx + dWidth / 2;
      const centerY = dy + dHeight / 2;
      context.translate(centerX, centerY);
      context.rotate(this.rotation * Math.PI / 180);
      const aspectRatioChange = this.rotation % 180 === 0 ? 1 : dWidth / dHeight;
      context.scale(1 / aspectRatioChange, aspectRatioChange);
      context.drawImage(
        source,
        sx,
        sy,
        sWidth,
        sHeight,
        -dWidth / 2,
        -dHeight / 2,
        dWidth,
        dHeight
      );
      context.restore();
    }
    /**
     * Draws the sample in the middle of the canvas corresponding to the context with the specified fit behavior.
     */
    drawWithFit(context, options) {
      if (!(typeof CanvasRenderingContext2D !== "undefined" && context instanceof CanvasRenderingContext2D || typeof OffscreenCanvasRenderingContext2D !== "undefined" && context instanceof OffscreenCanvasRenderingContext2D)) {
        throw new TypeError("context must be a CanvasRenderingContext2D or OffscreenCanvasRenderingContext2D.");
      }
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (!["fill", "contain", "cover"].includes(options.fit)) {
        throw new TypeError("options.fit must be 'fill', 'contain', or 'cover'.");
      }
      if (options.rotation !== void 0 && ![0, 90, 180, 270].includes(options.rotation)) {
        throw new TypeError("options.rotation, when provided, must be 0, 90, 180, or 270.");
      }
      if (options.crop !== void 0) {
        validateCropRectangle(options.crop, "options.");
      }
      const canvasWidth = context.canvas.width;
      const canvasHeight = context.canvas.height;
      const rotation = options.rotation ?? this.rotation;
      const [rotatedWidth, rotatedHeight] = rotation % 180 === 0 ? [this.codedWidth, this.codedHeight] : [this.codedHeight, this.codedWidth];
      if (options.crop) {
        clampCropRectangle(options.crop, rotatedWidth, rotatedHeight);
      }
      let dx;
      let dy;
      let newWidth;
      let newHeight;
      const { sx, sy, sWidth, sHeight } = this._rotateSourceRegion(
        options.crop?.left ?? 0,
        options.crop?.top ?? 0,
        options.crop?.width ?? rotatedWidth,
        options.crop?.height ?? rotatedHeight,
        rotation
      );
      if (options.fit === "fill") {
        dx = 0;
        dy = 0;
        newWidth = canvasWidth;
        newHeight = canvasHeight;
      } else {
        const [sampleWidth, sampleHeight] = options.crop ? [options.crop.width, options.crop.height] : [rotatedWidth, rotatedHeight];
        const scale = options.fit === "contain" ? Math.min(canvasWidth / sampleWidth, canvasHeight / sampleHeight) : Math.max(canvasWidth / sampleWidth, canvasHeight / sampleHeight);
        newWidth = sampleWidth * scale;
        newHeight = sampleHeight * scale;
        dx = (canvasWidth - newWidth) / 2;
        dy = (canvasHeight - newHeight) / 2;
      }
      context.save();
      const aspectRatioChange = rotation % 180 === 0 ? 1 : newWidth / newHeight;
      context.translate(canvasWidth / 2, canvasHeight / 2);
      context.rotate(rotation * Math.PI / 180);
      context.scale(1 / aspectRatioChange, aspectRatioChange);
      context.translate(-canvasWidth / 2, -canvasHeight / 2);
      context.drawImage(this.toCanvasImageSource(), sx, sy, sWidth, sHeight, dx, dy, newWidth, newHeight);
      context.restore();
    }
    /** @internal */
    _rotateSourceRegion(sx, sy, sWidth, sHeight, rotation) {
      if (rotation === 90) {
        [sx, sy, sWidth, sHeight] = [
          sy,
          this.codedHeight - sx - sWidth,
          sHeight,
          sWidth
        ];
      } else if (rotation === 180) {
        [sx, sy] = [
          this.codedWidth - sx - sWidth,
          this.codedHeight - sy - sHeight
        ];
      } else if (rotation === 270) {
        [sx, sy, sWidth, sHeight] = [
          this.codedWidth - sy - sHeight,
          sx,
          sHeight,
          sWidth
        ];
      }
      return { sx, sy, sWidth, sHeight };
    }
    /**
     * Converts this video sample to a
     * [`CanvasImageSource`](https://udn.realityripple.com/docs/Web/API/CanvasImageSource) for drawing to a canvas.
     *
     * You must use the value returned by this method immediately, as any VideoFrame created internally will
     * automatically be closed in the next microtask.
     */
    toCanvasImageSource() {
      if (this._closed) {
        throw new Error("VideoSample is closed.");
      }
      assert(this._data !== null);
      if (this._data instanceof Uint8Array) {
        const videoFrame = this.toVideoFrame();
        queueMicrotask(() => videoFrame.close());
        return videoFrame;
      } else {
        return this._data;
      }
    }
    /** Sets the rotation metadata of this video sample. */
    setRotation(newRotation) {
      if (![0, 90, 180, 270].includes(newRotation)) {
        throw new TypeError("newRotation must be 0, 90, 180, or 270.");
      }
      this.rotation = newRotation;
    }
    /** Sets the presentation timestamp of this video sample, in seconds. */
    setTimestamp(newTimestamp) {
      if (!Number.isFinite(newTimestamp)) {
        throw new TypeError("newTimestamp must be a number.");
      }
      this.timestamp = newTimestamp;
    }
    /** Sets the duration of this video sample, in seconds. */
    setDuration(newDuration) {
      if (!Number.isFinite(newDuration) || newDuration < 0) {
        throw new TypeError("newDuration must be a non-negative number.");
      }
      this.duration = newDuration;
    }
    /** Calls `.close()`. */
    [Symbol.dispose]() {
      this.close();
    }
  };
  var VideoSampleColorSpace = class {
    /** Creates a new VideoSampleColorSpace. */
    constructor(init) {
      this.primaries = init?.primaries ?? null;
      this.transfer = init?.transfer ?? null;
      this.matrix = init?.matrix ?? null;
      this.fullRange = init?.fullRange ?? null;
    }
    /** Serializes the color space to a JSON object. */
    toJSON() {
      return {
        primaries: this.primaries,
        transfer: this.transfer,
        matrix: this.matrix,
        fullRange: this.fullRange
      };
    }
  };
  var isVideoFrame = (x) => {
    return typeof VideoFrame !== "undefined" && x instanceof VideoFrame;
  };
  var clampCropRectangle = (crop, outerWidth, outerHeight) => {
    crop.left = Math.min(crop.left, outerWidth);
    crop.top = Math.min(crop.top, outerHeight);
    crop.width = Math.min(crop.width, outerWidth - crop.left);
    crop.height = Math.min(crop.height, outerHeight - crop.top);
    assert(crop.width >= 0);
    assert(crop.height >= 0);
  };
  var validateCropRectangle = (crop, prefix) => {
    if (!crop || typeof crop !== "object") {
      throw new TypeError(prefix + "crop, when provided, must be an object.");
    }
    if (!Number.isInteger(crop.left) || crop.left < 0) {
      throw new TypeError(prefix + "crop.left must be a non-negative integer.");
    }
    if (!Number.isInteger(crop.top) || crop.top < 0) {
      throw new TypeError(prefix + "crop.top must be a non-negative integer.");
    }
    if (!Number.isInteger(crop.width) || crop.width < 0) {
      throw new TypeError(prefix + "crop.width must be a non-negative integer.");
    }
    if (!Number.isInteger(crop.height) || crop.height < 0) {
      throw new TypeError(prefix + "crop.height must be a non-negative integer.");
    }
  };
  var validateVideoFrameCopyToOptions = (options) => {
    if (!options || typeof options !== "object") {
      throw new TypeError("options must be an object.");
    }
    if (options.colorSpace !== void 0 && !["display-p3", "srgb"].includes(options.colorSpace)) {
      throw new TypeError("options.colorSpace, when provided, must be 'display-p3' or 'srgb'.");
    }
    if (options.format !== void 0 && typeof options.format !== "string") {
      throw new TypeError("options.format, when provided, must be a string.");
    }
    if (options.layout !== void 0) {
      if (!Array.isArray(options.layout)) {
        throw new TypeError("options.layout, when provided, must be an array.");
      }
      for (const plane of options.layout) {
        if (!plane || typeof plane !== "object") {
          throw new TypeError("Each entry in options.layout must be an object.");
        }
        if (!Number.isInteger(plane.offset) || plane.offset < 0) {
          throw new TypeError("plane.offset must be a non-negative integer.");
        }
        if (!Number.isInteger(plane.stride) || plane.stride < 0) {
          throw new TypeError("plane.stride must be a non-negative integer.");
        }
      }
    }
    if (options.rect !== void 0) {
      if (!options.rect || typeof options.rect !== "object") {
        throw new TypeError("options.rect, when provided, must be an object.");
      }
      if (options.rect.x !== void 0 && (!Number.isInteger(options.rect.x) || options.rect.x < 0)) {
        throw new TypeError("options.rect.x, when provided, must be a non-negative integer.");
      }
      if (options.rect.y !== void 0 && (!Number.isInteger(options.rect.y) || options.rect.y < 0)) {
        throw new TypeError("options.rect.y, when provided, must be a non-negative integer.");
      }
      if (options.rect.width !== void 0 && (!Number.isInteger(options.rect.width) || options.rect.width < 0)) {
        throw new TypeError("options.rect.width, when provided, must be a non-negative integer.");
      }
      if (options.rect.height !== void 0 && (!Number.isInteger(options.rect.height) || options.rect.height < 0)) {
        throw new TypeError("options.rect.height, when provided, must be a non-negative integer.");
      }
    }
  };
  var createDefaultPlaneLayout = (format, codedWidth, codedHeight) => {
    const planes = getPlaneConfigs(format);
    const layouts = [];
    let currentOffset = 0;
    for (const plane of planes) {
      const planeWidth = Math.ceil(codedWidth / plane.widthDivisor);
      const planeHeight = Math.ceil(codedHeight / plane.heightDivisor);
      const stride = planeWidth * plane.sampleBytes;
      const planeSize = stride * planeHeight;
      layouts.push({
        offset: currentOffset,
        stride
      });
      currentOffset += planeSize;
    }
    return layouts;
  };
  var getPlaneConfigs = (format) => {
    const yuv = (yBytes, uvBytes, subX, subY, hasAlpha) => {
      const configs = [
        { sampleBytes: yBytes, widthDivisor: 1, heightDivisor: 1 },
        { sampleBytes: uvBytes, widthDivisor: subX, heightDivisor: subY },
        { sampleBytes: uvBytes, widthDivisor: subX, heightDivisor: subY }
      ];
      if (hasAlpha) {
        configs.push({ sampleBytes: yBytes, widthDivisor: 1, heightDivisor: 1 });
      }
      return configs;
    };
    switch (format) {
      case "I420":
        return yuv(1, 1, 2, 2, false);
      case "I420P10":
      case "I420P12":
        return yuv(2, 2, 2, 2, false);
      case "I420A":
        return yuv(1, 1, 2, 2, true);
      case "I420AP10":
      case "I420AP12":
        return yuv(2, 2, 2, 2, true);
      case "I422":
        return yuv(1, 1, 2, 1, false);
      case "I422P10":
      case "I422P12":
        return yuv(2, 2, 2, 1, false);
      case "I422A":
        return yuv(1, 1, 2, 1, true);
      case "I422AP10":
      case "I422AP12":
        return yuv(2, 2, 2, 1, true);
      case "I444":
        return yuv(1, 1, 1, 1, false);
      case "I444P10":
      case "I444P12":
        return yuv(2, 2, 1, 1, false);
      case "I444A":
        return yuv(1, 1, 1, 1, true);
      case "I444AP10":
      case "I444AP12":
        return yuv(2, 2, 1, 1, true);
      case "NV12":
        return [
          { sampleBytes: 1, widthDivisor: 1, heightDivisor: 1 },
          { sampleBytes: 2, widthDivisor: 2, heightDivisor: 2 }
          // Interleaved U and V
        ];
      case "RGBA":
      case "RGBX":
      case "BGRA":
      case "BGRX":
        return [
          { sampleBytes: 4, widthDivisor: 1, heightDivisor: 1 }
        ];
      default:
        assertNever(format);
        assert(false);
    }
  };
  var AUDIO_SAMPLE_FORMATS = /* @__PURE__ */ new Set(
    ["f32", "f32-planar", "s16", "s16-planar", "s32", "s32-planar", "u8", "u8-planar"]
  );
  var AudioSample = class _AudioSample {
    /**
     * Creates a new {@link AudioSample}, either from an existing
     * [`AudioData`](https://developer.mozilla.org/en-US/docs/Web/API/AudioData) or from raw bytes specified in
     * {@link AudioSampleInit}.
     */
    constructor(init) {
      /** @internal */
      this._closed = false;
      if (isAudioData(init)) {
        if (init.format === null) {
          throw new TypeError("AudioData with null format is not supported.");
        }
        this._data = init;
        this.format = init.format;
        this.sampleRate = init.sampleRate;
        this.numberOfFrames = init.numberOfFrames;
        this.numberOfChannels = init.numberOfChannels;
        this.timestamp = init.timestamp / 1e6;
        this.duration = init.numberOfFrames / init.sampleRate;
      } else {
        if (!init || typeof init !== "object") {
          throw new TypeError("Invalid AudioDataInit: must be an object.");
        }
        if (!AUDIO_SAMPLE_FORMATS.has(init.format)) {
          throw new TypeError("Invalid AudioDataInit: invalid format.");
        }
        if (!Number.isFinite(init.sampleRate) || init.sampleRate <= 0) {
          throw new TypeError("Invalid AudioDataInit: sampleRate must be > 0.");
        }
        if (!Number.isInteger(init.numberOfChannels) || init.numberOfChannels === 0) {
          throw new TypeError("Invalid AudioDataInit: numberOfChannels must be an integer > 0.");
        }
        if (!Number.isFinite(init?.timestamp)) {
          throw new TypeError("init.timestamp must be a number.");
        }
        const numberOfFrames = init.data.byteLength / (getBytesPerSample(init.format) * init.numberOfChannels);
        if (!Number.isInteger(numberOfFrames)) {
          throw new TypeError("Invalid AudioDataInit: data size is not a multiple of frame size.");
        }
        this.format = init.format;
        this.sampleRate = init.sampleRate;
        this.numberOfFrames = numberOfFrames;
        this.numberOfChannels = init.numberOfChannels;
        this.timestamp = init.timestamp;
        this.duration = numberOfFrames / init.sampleRate;
        let dataBuffer;
        if (init.data instanceof ArrayBuffer) {
          dataBuffer = new Uint8Array(init.data);
        } else if (ArrayBuffer.isView(init.data)) {
          dataBuffer = new Uint8Array(init.data.buffer, init.data.byteOffset, init.data.byteLength);
        } else {
          throw new TypeError("Invalid AudioDataInit: data is not a BufferSource.");
        }
        const expectedSize = this.numberOfFrames * this.numberOfChannels * getBytesPerSample(this.format);
        if (dataBuffer.byteLength < expectedSize) {
          throw new TypeError("Invalid AudioDataInit: insufficient data size.");
        }
        this._data = dataBuffer;
      }
      finalizationRegistry?.register(this, { type: "audio", data: this._data }, this);
    }
    /** The presentation timestamp of the sample in microseconds. */
    get microsecondTimestamp() {
      return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.timestamp);
    }
    /** The duration of the sample in microseconds. */
    get microsecondDuration() {
      return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.duration);
    }
    /** Returns the number of bytes required to hold the audio sample's data as specified by the given options. */
    allocationSize(options) {
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (!Number.isInteger(options.planeIndex) || options.planeIndex < 0) {
        throw new TypeError("planeIndex must be a non-negative integer.");
      }
      if (options.format !== void 0 && !AUDIO_SAMPLE_FORMATS.has(options.format)) {
        throw new TypeError("Invalid format.");
      }
      if (options.frameOffset !== void 0 && (!Number.isInteger(options.frameOffset) || options.frameOffset < 0)) {
        throw new TypeError("frameOffset must be a non-negative integer.");
      }
      if (options.frameCount !== void 0 && (!Number.isInteger(options.frameCount) || options.frameCount < 0)) {
        throw new TypeError("frameCount must be a non-negative integer.");
      }
      if (this._closed) {
        throw new Error("AudioSample is closed.");
      }
      const destFormat = options.format ?? this.format;
      const frameOffset = options.frameOffset ?? 0;
      if (frameOffset >= this.numberOfFrames) {
        throw new RangeError("frameOffset out of range");
      }
      const copyFrameCount = options.frameCount !== void 0 ? options.frameCount : this.numberOfFrames - frameOffset;
      if (copyFrameCount > this.numberOfFrames - frameOffset) {
        throw new RangeError("frameCount out of range");
      }
      const bytesPerSample = getBytesPerSample(destFormat);
      const isPlanar = formatIsPlanar(destFormat);
      if (isPlanar && options.planeIndex >= this.numberOfChannels) {
        throw new RangeError("planeIndex out of range");
      }
      if (!isPlanar && options.planeIndex !== 0) {
        throw new RangeError("planeIndex out of range");
      }
      const elementCount = isPlanar ? copyFrameCount : copyFrameCount * this.numberOfChannels;
      return elementCount * bytesPerSample;
    }
    /** Copies the audio sample's data to an ArrayBuffer or ArrayBufferView as specified by the given options. */
    copyTo(destination, options) {
      if (!isAllowSharedBufferSource(destination)) {
        throw new TypeError("destination must be an ArrayBuffer or an ArrayBuffer view.");
      }
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (!Number.isInteger(options.planeIndex) || options.planeIndex < 0) {
        throw new TypeError("planeIndex must be a non-negative integer.");
      }
      if (options.format !== void 0 && !AUDIO_SAMPLE_FORMATS.has(options.format)) {
        throw new TypeError("Invalid format.");
      }
      if (options.frameOffset !== void 0 && (!Number.isInteger(options.frameOffset) || options.frameOffset < 0)) {
        throw new TypeError("frameOffset must be a non-negative integer.");
      }
      if (options.frameCount !== void 0 && (!Number.isInteger(options.frameCount) || options.frameCount < 0)) {
        throw new TypeError("frameCount must be a non-negative integer.");
      }
      if (this._closed) {
        throw new Error("AudioSample is closed.");
      }
      const { planeIndex, format, frameCount: optFrameCount, frameOffset: optFrameOffset } = options;
      const srcFormat = this.format;
      const destFormat = format ?? this.format;
      if (!destFormat) throw new Error("Destination format not determined");
      const numFrames = this.numberOfFrames;
      const numChannels = this.numberOfChannels;
      const frameOffset = optFrameOffset ?? 0;
      if (frameOffset >= numFrames) {
        throw new RangeError("frameOffset out of range");
      }
      const copyFrameCount = optFrameCount !== void 0 ? optFrameCount : numFrames - frameOffset;
      if (copyFrameCount > numFrames - frameOffset) {
        throw new RangeError("frameCount out of range");
      }
      const destBytesPerSample = getBytesPerSample(destFormat);
      const destIsPlanar = formatIsPlanar(destFormat);
      if (destIsPlanar && planeIndex >= numChannels) {
        throw new RangeError("planeIndex out of range");
      }
      if (!destIsPlanar && planeIndex !== 0) {
        throw new RangeError("planeIndex out of range");
      }
      const destElementCount = destIsPlanar ? copyFrameCount : copyFrameCount * numChannels;
      const requiredSize = destElementCount * destBytesPerSample;
      if (destination.byteLength < requiredSize) {
        throw new RangeError("Destination buffer is too small");
      }
      const destView = toDataView(destination);
      const writeFn = getWriteFunction(destFormat);
      if (isAudioData(this._data)) {
        if (isWebKit() && numChannels > 2 && destFormat !== srcFormat) {
          doAudioDataCopyToWebKitWorkaround(
            this._data,
            destView,
            srcFormat,
            destFormat,
            numChannels,
            planeIndex,
            frameOffset,
            copyFrameCount
          );
        } else {
          this._data.copyTo(destination, {
            planeIndex,
            frameOffset,
            frameCount: copyFrameCount,
            format: destFormat
          });
        }
      } else {
        const uint8Data = this._data;
        const srcView = toDataView(uint8Data);
        const readFn = getReadFunction(srcFormat);
        const srcBytesPerSample = getBytesPerSample(srcFormat);
        const srcIsPlanar = formatIsPlanar(srcFormat);
        for (let i = 0; i < copyFrameCount; i++) {
          if (destIsPlanar) {
            const destOffset = i * destBytesPerSample;
            let srcOffset;
            if (srcIsPlanar) {
              srcOffset = (planeIndex * numFrames + (i + frameOffset)) * srcBytesPerSample;
            } else {
              srcOffset = ((i + frameOffset) * numChannels + planeIndex) * srcBytesPerSample;
            }
            const normalized = readFn(srcView, srcOffset);
            writeFn(destView, destOffset, normalized);
          } else {
            for (let ch = 0; ch < numChannels; ch++) {
              const destIndex = i * numChannels + ch;
              const destOffset = destIndex * destBytesPerSample;
              let srcOffset;
              if (srcIsPlanar) {
                srcOffset = (ch * numFrames + (i + frameOffset)) * srcBytesPerSample;
              } else {
                srcOffset = ((i + frameOffset) * numChannels + ch) * srcBytesPerSample;
              }
              const normalized = readFn(srcView, srcOffset);
              writeFn(destView, destOffset, normalized);
            }
          }
        }
      }
    }
    /** Clones this audio sample. */
    clone() {
      if (this._closed) {
        throw new Error("AudioSample is closed.");
      }
      if (isAudioData(this._data)) {
        const sample = new _AudioSample(this._data.clone());
        sample.setTimestamp(this.timestamp);
        return sample;
      } else {
        return new _AudioSample({
          format: this.format,
          sampleRate: this.sampleRate,
          numberOfFrames: this.numberOfFrames,
          numberOfChannels: this.numberOfChannels,
          timestamp: this.timestamp,
          data: this._data
        });
      }
    }
    /**
     * Closes this audio sample, releasing held resources. Audio samples should be closed as soon as they are not
     * needed anymore.
     */
    close() {
      if (this._closed) {
        return;
      }
      finalizationRegistry?.unregister(this);
      if (isAudioData(this._data)) {
        this._data.close();
      } else {
        this._data = new Uint8Array(0);
      }
      this._closed = true;
    }
    /**
     * Converts this audio sample to an AudioData for use with the WebCodecs API. The AudioData returned by this
     * method *must* be closed separately from this audio sample.
     */
    toAudioData() {
      if (this._closed) {
        throw new Error("AudioSample is closed.");
      }
      if (isAudioData(this._data)) {
        if (this._data.timestamp === this.microsecondTimestamp) {
          return this._data.clone();
        } else {
          if (formatIsPlanar(this.format)) {
            const size = this.allocationSize({ planeIndex: 0, format: this.format });
            const data = new ArrayBuffer(size * this.numberOfChannels);
            for (let i = 0; i < this.numberOfChannels; i++) {
              this.copyTo(new Uint8Array(data, i * size, size), { planeIndex: i, format: this.format });
            }
            return new AudioData({
              format: this.format,
              sampleRate: this.sampleRate,
              numberOfFrames: this.numberOfFrames,
              numberOfChannels: this.numberOfChannels,
              timestamp: this.microsecondTimestamp,
              data
            });
          } else {
            const data = new ArrayBuffer(this.allocationSize({ planeIndex: 0, format: this.format }));
            this.copyTo(data, { planeIndex: 0, format: this.format });
            return new AudioData({
              format: this.format,
              sampleRate: this.sampleRate,
              numberOfFrames: this.numberOfFrames,
              numberOfChannels: this.numberOfChannels,
              timestamp: this.microsecondTimestamp,
              data
            });
          }
        }
      } else {
        return new AudioData({
          format: this.format,
          sampleRate: this.sampleRate,
          numberOfFrames: this.numberOfFrames,
          numberOfChannels: this.numberOfChannels,
          timestamp: this.microsecondTimestamp,
          data: this._data.buffer instanceof ArrayBuffer ? this._data.buffer : this._data.slice()
          // In the case of SharedArrayBuffer, convert to ArrayBuffer
        });
      }
    }
    /** Convert this audio sample to an AudioBuffer for use with the Web Audio API. */
    toAudioBuffer() {
      if (this._closed) {
        throw new Error("AudioSample is closed.");
      }
      const audioBuffer = new AudioBuffer({
        numberOfChannels: this.numberOfChannels,
        length: this.numberOfFrames,
        sampleRate: this.sampleRate
      });
      const dataBytes = new Float32Array(this.allocationSize({ planeIndex: 0, format: "f32-planar" }) / 4);
      for (let i = 0; i < this.numberOfChannels; i++) {
        this.copyTo(dataBytes, { planeIndex: i, format: "f32-planar" });
        audioBuffer.copyToChannel(dataBytes, i);
      }
      return audioBuffer;
    }
    /** Sets the presentation timestamp of this audio sample, in seconds. */
    setTimestamp(newTimestamp) {
      if (!Number.isFinite(newTimestamp)) {
        throw new TypeError("newTimestamp must be a number.");
      }
      this.timestamp = newTimestamp;
    }
    /** Calls `.close()`. */
    [Symbol.dispose]() {
      this.close();
    }
    /** @internal */
    static *_fromAudioBuffer(audioBuffer, timestamp) {
      if (!(audioBuffer instanceof AudioBuffer)) {
        throw new TypeError("audioBuffer must be an AudioBuffer.");
      }
      const MAX_FLOAT_COUNT = 48e3 * 5;
      const numberOfChannels = audioBuffer.numberOfChannels;
      const sampleRate = audioBuffer.sampleRate;
      const totalFrames = audioBuffer.length;
      const maxFramesPerChunk = Math.floor(MAX_FLOAT_COUNT / numberOfChannels);
      let currentRelativeFrame = 0;
      let remainingFrames = totalFrames;
      while (remainingFrames > 0) {
        const framesToCopy = Math.min(maxFramesPerChunk, remainingFrames);
        const chunkData = new Float32Array(numberOfChannels * framesToCopy);
        for (let channel = 0; channel < numberOfChannels; channel++) {
          audioBuffer.copyFromChannel(
            chunkData.subarray(channel * framesToCopy, (channel + 1) * framesToCopy),
            channel,
            currentRelativeFrame
          );
        }
        yield new _AudioSample({
          format: "f32-planar",
          sampleRate,
          numberOfFrames: framesToCopy,
          numberOfChannels,
          timestamp: timestamp + currentRelativeFrame / sampleRate,
          data: chunkData
        });
        currentRelativeFrame += framesToCopy;
        remainingFrames -= framesToCopy;
      }
    }
    /**
     * Creates AudioSamples from an AudioBuffer, starting at the given timestamp in seconds. Typically creates exactly
     * one sample, but may create multiple if the AudioBuffer is exceedingly large.
     */
    static fromAudioBuffer(audioBuffer, timestamp) {
      if (!(audioBuffer instanceof AudioBuffer)) {
        throw new TypeError("audioBuffer must be an AudioBuffer.");
      }
      const MAX_FLOAT_COUNT = 48e3 * 5;
      const numberOfChannels = audioBuffer.numberOfChannels;
      const sampleRate = audioBuffer.sampleRate;
      const totalFrames = audioBuffer.length;
      const maxFramesPerChunk = Math.floor(MAX_FLOAT_COUNT / numberOfChannels);
      let currentRelativeFrame = 0;
      let remainingFrames = totalFrames;
      const result = [];
      while (remainingFrames > 0) {
        const framesToCopy = Math.min(maxFramesPerChunk, remainingFrames);
        const chunkData = new Float32Array(numberOfChannels * framesToCopy);
        for (let channel = 0; channel < numberOfChannels; channel++) {
          audioBuffer.copyFromChannel(
            chunkData.subarray(channel * framesToCopy, (channel + 1) * framesToCopy),
            channel,
            currentRelativeFrame
          );
        }
        const audioSample = new _AudioSample({
          format: "f32-planar",
          sampleRate,
          numberOfFrames: framesToCopy,
          numberOfChannels,
          timestamp: timestamp + currentRelativeFrame / sampleRate,
          data: chunkData
        });
        result.push(audioSample);
        currentRelativeFrame += framesToCopy;
        remainingFrames -= framesToCopy;
      }
      return result;
    }
  };
  var getBytesPerSample = (format) => {
    switch (format) {
      case "u8":
      case "u8-planar":
        return 1;
      case "s16":
      case "s16-planar":
        return 2;
      case "s32":
      case "s32-planar":
        return 4;
      case "f32":
      case "f32-planar":
        return 4;
      default:
        throw new Error("Unknown AudioSampleFormat");
    }
  };
  var formatIsPlanar = (format) => {
    switch (format) {
      case "u8-planar":
      case "s16-planar":
      case "s32-planar":
      case "f32-planar":
        return true;
      default:
        return false;
    }
  };
  var getReadFunction = (format) => {
    switch (format) {
      case "u8":
      case "u8-planar":
        return (view2, offset) => (view2.getUint8(offset) - 128) / 128;
      case "s16":
      case "s16-planar":
        return (view2, offset) => view2.getInt16(offset, true) / 32768;
      case "s32":
      case "s32-planar":
        return (view2, offset) => view2.getInt32(offset, true) / 2147483648;
      case "f32":
      case "f32-planar":
        return (view2, offset) => view2.getFloat32(offset, true);
    }
  };
  var getWriteFunction = (format) => {
    switch (format) {
      case "u8":
      case "u8-planar":
        return (view2, offset, value) => view2.setUint8(offset, clamp((value + 1) * 127.5, 0, 255));
      case "s16":
      case "s16-planar":
        return (view2, offset, value) => view2.setInt16(offset, clamp(Math.round(value * 32767), -32768, 32767), true);
      case "s32":
      case "s32-planar":
        return (view2, offset, value) => view2.setInt32(offset, clamp(Math.round(value * 2147483647), -2147483648, 2147483647), true);
      case "f32":
      case "f32-planar":
        return (view2, offset, value) => view2.setFloat32(offset, value, true);
    }
  };
  var isAudioData = (x) => {
    return typeof AudioData !== "undefined" && x instanceof AudioData;
  };
  var doAudioDataCopyToWebKitWorkaround = (audioData, destView, srcFormat, destFormat, numChannels, planeIndex, frameOffset, copyFrameCount) => {
    const readFn = getReadFunction(srcFormat);
    const writeFn = getWriteFunction(destFormat);
    const srcBytesPerSample = getBytesPerSample(srcFormat);
    const destBytesPerSample = getBytesPerSample(destFormat);
    const srcIsPlanar = formatIsPlanar(srcFormat);
    const destIsPlanar = formatIsPlanar(destFormat);
    if (destIsPlanar) {
      if (srcIsPlanar) {
        const data = new ArrayBuffer(copyFrameCount * srcBytesPerSample);
        const dataView = toDataView(data);
        audioData.copyTo(data, {
          planeIndex,
          frameOffset,
          frameCount: copyFrameCount,
          format: srcFormat
        });
        for (let i = 0; i < copyFrameCount; i++) {
          const srcOffset = i * srcBytesPerSample;
          const destOffset = i * destBytesPerSample;
          const sample = readFn(dataView, srcOffset);
          writeFn(destView, destOffset, sample);
        }
      } else {
        const data = new ArrayBuffer(copyFrameCount * numChannels * srcBytesPerSample);
        const dataView = toDataView(data);
        audioData.copyTo(data, {
          planeIndex: 0,
          frameOffset,
          frameCount: copyFrameCount,
          format: srcFormat
        });
        for (let i = 0; i < copyFrameCount; i++) {
          const srcOffset = (i * numChannels + planeIndex) * srcBytesPerSample;
          const destOffset = i * destBytesPerSample;
          const sample = readFn(dataView, srcOffset);
          writeFn(destView, destOffset, sample);
        }
      }
    } else {
      if (srcIsPlanar) {
        const planeSize = copyFrameCount * srcBytesPerSample;
        const data = new ArrayBuffer(planeSize);
        const dataView = toDataView(data);
        for (let ch = 0; ch < numChannels; ch++) {
          audioData.copyTo(data, {
            planeIndex: ch,
            frameOffset,
            frameCount: copyFrameCount,
            format: srcFormat
          });
          for (let i = 0; i < copyFrameCount; i++) {
            const srcOffset = i * srcBytesPerSample;
            const destOffset = (i * numChannels + ch) * destBytesPerSample;
            const sample = readFn(dataView, srcOffset);
            writeFn(destView, destOffset, sample);
          }
        }
      } else {
        const data = new ArrayBuffer(copyFrameCount * numChannels * srcBytesPerSample);
        const dataView = toDataView(data);
        audioData.copyTo(data, {
          planeIndex: 0,
          frameOffset,
          frameCount: copyFrameCount,
          format: srcFormat
        });
        for (let i = 0; i < copyFrameCount; i++) {
          for (let ch = 0; ch < numChannels; ch++) {
            const idx = i * numChannels + ch;
            const srcOffset = idx * srcBytesPerSample;
            const destOffset = idx * destBytesPerSample;
            const sample = readFn(dataView, srcOffset);
            writeFn(destView, destOffset, sample);
          }
        }
      }
    }
  };

  // src/media-sink.ts
  var validatePacketRetrievalOptions = (options) => {
    if (!options || typeof options !== "object") {
      throw new TypeError("options must be an object.");
    }
    if (options.metadataOnly !== void 0 && typeof options.metadataOnly !== "boolean") {
      throw new TypeError("options.metadataOnly, when defined, must be a boolean.");
    }
    if (options.verifyKeyPackets !== void 0 && typeof options.verifyKeyPackets !== "boolean") {
      throw new TypeError("options.verifyKeyPackets, when defined, must be a boolean.");
    }
    if (options.verifyKeyPackets && options.metadataOnly) {
      throw new TypeError("options.verifyKeyPackets and options.metadataOnly cannot be enabled together.");
    }
  };
  var validateTimestamp = (timestamp) => {
    if (!isNumber(timestamp)) {
      throw new TypeError("timestamp must be a number.");
    }
  };
  var maybeFixPacketType = (track, promise, options) => {
    if (options.verifyKeyPackets) {
      return promise.then(async (packet) => {
        if (!packet || packet.type === "delta") {
          return packet;
        }
        const determinedType = await track.determinePacketType(packet);
        if (determinedType) {
          packet.type = determinedType;
        }
        return packet;
      });
    } else {
      return promise;
    }
  };
  var EncodedPacketSink = class {
    /** Creates a new {@link EncodedPacketSink} for the given {@link InputTrack}. */
    constructor(track) {
      if (!(track instanceof InputTrack)) {
        throw new TypeError("track must be an InputTrack.");
      }
      this._track = track;
    }
    /**
     * Retrieves the track's first packet (in decode order), or null if it has no packets. The first packet is very
     * likely to be a key packet.
     */
    getFirstPacket(options = {}) {
      validatePacketRetrievalOptions(options);
      if (this._track.input._disposed) {
        throw new InputDisposedError();
      }
      return maybeFixPacketType(this._track, this._track._backing.getFirstPacket(options), options);
    }
    /**
     * Retrieves the packet corresponding to the given timestamp, in seconds. More specifically, returns the last packet
     * (in presentation order) with a start timestamp less than or equal to the given timestamp. This method can be
     * used to retrieve a track's last packet using `getPacket(Infinity)`. The method returns null if the timestamp
     * is before the first packet in the track.
     *
     * @param timestamp - The timestamp used for retrieval, in seconds.
     */
    getPacket(timestamp, options = {}) {
      validateTimestamp(timestamp);
      validatePacketRetrievalOptions(options);
      if (this._track.input._disposed) {
        throw new InputDisposedError();
      }
      return maybeFixPacketType(this._track, this._track._backing.getPacket(timestamp, options), options);
    }
    /**
     * Retrieves the packet following the given packet (in decode order), or null if the given packet is the
     * last packet.
     */
    getNextPacket(packet, options = {}) {
      if (!(packet instanceof EncodedPacket)) {
        throw new TypeError("packet must be an EncodedPacket.");
      }
      validatePacketRetrievalOptions(options);
      if (this._track.input._disposed) {
        throw new InputDisposedError();
      }
      return maybeFixPacketType(this._track, this._track._backing.getNextPacket(packet, options), options);
    }
    /**
     * Retrieves the key packet corresponding to the given timestamp, in seconds. More specifically, returns the last
     * key packet (in presentation order) with a start timestamp less than or equal to the given timestamp. A key packet
     * is a packet that doesn't require previous packets to be decoded. This method can be used to retrieve a track's
     * last key packet using `getKeyPacket(Infinity)`. The method returns null if the timestamp is before the first
     * key packet in the track.
     *
     * To ensure that the returned packet is guaranteed to be a real key frame, enable `options.verifyKeyPackets`.
     *
     * @param timestamp - The timestamp used for retrieval, in seconds.
     */
    async getKeyPacket(timestamp, options = {}) {
      validateTimestamp(timestamp);
      validatePacketRetrievalOptions(options);
      if (this._track.input._disposed) {
        throw new InputDisposedError();
      }
      if (!options.verifyKeyPackets) {
        return this._track._backing.getKeyPacket(timestamp, options);
      }
      const packet = await this._track._backing.getKeyPacket(timestamp, options);
      if (!packet) {
        return packet;
      }
      assert(packet.type === "key");
      const determinedType = await this._track.determinePacketType(packet);
      if (determinedType === "delta") {
        return this.getKeyPacket(packet.timestamp - 1 / this._track.timeResolution, options);
      }
      return packet;
    }
    /**
     * Retrieves the key packet following the given packet (in decode order), or null if the given packet is the last
     * key packet.
     *
     * To ensure that the returned packet is guaranteed to be a real key frame, enable `options.verifyKeyPackets`.
     */
    async getNextKeyPacket(packet, options = {}) {
      if (!(packet instanceof EncodedPacket)) {
        throw new TypeError("packet must be an EncodedPacket.");
      }
      validatePacketRetrievalOptions(options);
      if (this._track.input._disposed) {
        throw new InputDisposedError();
      }
      if (!options.verifyKeyPackets) {
        return this._track._backing.getNextKeyPacket(packet, options);
      }
      const nextPacket = await this._track._backing.getNextKeyPacket(packet, options);
      if (!nextPacket) {
        return nextPacket;
      }
      assert(nextPacket.type === "key");
      const determinedType = await this._track.determinePacketType(nextPacket);
      if (determinedType === "delta") {
        return this.getNextKeyPacket(nextPacket, options);
      }
      return nextPacket;
    }
    /**
     * Creates an async iterator that yields the packets in this track in decode order. To enable fast iteration, this
     * method will intelligently preload packets based on the speed of the consumer.
     *
     * @param startPacket - (optional) The packet from which iteration should begin. This packet will also be yielded.
     * @param endTimestamp - (optional) The timestamp at which iteration should end. This packet will _not_ be yielded.
     */
    packets(startPacket, endPacket, options = {}) {
      if (startPacket !== void 0 && !(startPacket instanceof EncodedPacket)) {
        throw new TypeError("startPacket must be an EncodedPacket.");
      }
      if (startPacket !== void 0 && startPacket.isMetadataOnly && !options?.metadataOnly) {
        throw new TypeError("startPacket can only be metadata-only if options.metadataOnly is enabled.");
      }
      if (endPacket !== void 0 && !(endPacket instanceof EncodedPacket)) {
        throw new TypeError("endPacket must be an EncodedPacket.");
      }
      validatePacketRetrievalOptions(options);
      if (this._track.input._disposed) {
        throw new InputDisposedError();
      }
      const packetQueue = [];
      let { promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers();
      let { promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers();
      let ended = false;
      let terminated = false;
      let outOfBandError = null;
      const timestamps = [];
      const maxQueueSize = () => Math.max(2, timestamps.length);
      (async () => {
        let packet = startPacket ?? await this.getFirstPacket(options);
        while (packet && !terminated && !this._track.input._disposed) {
          if (endPacket && packet.sequenceNumber >= endPacket?.sequenceNumber) {
            break;
          }
          if (packetQueue.length > maxQueueSize()) {
            ({ promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers());
            await queueDequeue;
            continue;
          }
          packetQueue.push(packet);
          onQueueNotEmpty();
          ({ promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers());
          packet = await this.getNextPacket(packet, options);
        }
        ended = true;
        onQueueNotEmpty();
      })().catch((error) => {
        if (!outOfBandError) {
          outOfBandError = error;
          onQueueNotEmpty();
        }
      });
      const track = this._track;
      return {
        async next() {
          while (true) {
            if (track.input._disposed) {
              throw new InputDisposedError();
            } else if (terminated) {
              return { value: void 0, done: true };
            } else if (outOfBandError) {
              throw outOfBandError;
            } else if (packetQueue.length > 0) {
              const value = packetQueue.shift();
              const now = performance.now();
              timestamps.push(now);
              while (timestamps.length > 0 && now - timestamps[0] >= 1e3) {
                timestamps.shift();
              }
              onQueueDequeue();
              return { value, done: false };
            } else if (ended) {
              return { value: void 0, done: true };
            } else {
              await queueNotEmpty;
            }
          }
        },
        async return() {
          terminated = true;
          onQueueDequeue();
          onQueueNotEmpty();
          return { value: void 0, done: true };
        },
        async throw(error) {
          throw error;
        },
        [Symbol.asyncIterator]() {
          return this;
        }
      };
    }
  };
  var DecoderWrapper = class {
    constructor(onSample, onError) {
      this.onSample = onSample;
      this.onError = onError;
    }
  };
  var BaseMediaSampleSink = class {
    /** @internal */
    mediaSamplesInRange(startTimestamp = 0, endTimestamp = Infinity) {
      validateTimestamp(startTimestamp);
      validateTimestamp(endTimestamp);
      const sampleQueue = [];
      let firstSampleQueued = false;
      let lastSample = null;
      let { promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers();
      let { promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers();
      let decoderIsFlushed = false;
      let ended = false;
      let terminated = false;
      let outOfBandError = null;
      (async () => {
        const decoder = await this._createDecoder((sample) => {
          onQueueDequeue();
          if (sample.timestamp >= endTimestamp) {
            ended = true;
          }
          if (ended) {
            sample.close();
            return;
          }
          if (lastSample) {
            if (sample.timestamp > startTimestamp) {
              sampleQueue.push(lastSample);
              firstSampleQueued = true;
            } else {
              lastSample.close();
            }
          }
          if (sample.timestamp >= startTimestamp) {
            sampleQueue.push(sample);
            firstSampleQueued = true;
          }
          lastSample = firstSampleQueued ? null : sample;
          if (sampleQueue.length > 0) {
            onQueueNotEmpty();
            ({ promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers());
          }
        }, (error) => {
          if (!outOfBandError) {
            outOfBandError = error;
            onQueueNotEmpty();
          }
        });
        const packetSink = this._createPacketSink();
        const keyPacket = await packetSink.getKeyPacket(startTimestamp, { verifyKeyPackets: true }) ?? await packetSink.getFirstPacket();
        let currentPacket = keyPacket;
        const endPacket = void 0;
        const packets = packetSink.packets(keyPacket ?? void 0, endPacket);
        await packets.next();
        while (currentPacket && !ended && !this._track.input._disposed) {
          const maxQueueSize = computeMaxQueueSize(sampleQueue.length);
          if (sampleQueue.length + decoder.getDecodeQueueSize() > maxQueueSize) {
            ({ promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers());
            await queueDequeue;
            continue;
          }
          decoder.decode(currentPacket);
          const packetResult = await packets.next();
          if (packetResult.done) {
            break;
          }
          currentPacket = packetResult.value;
        }
        await packets.return();
        if (!terminated && !this._track.input._disposed) {
          await decoder.flush();
        }
        decoder.close();
        if (!firstSampleQueued && lastSample) {
          sampleQueue.push(lastSample);
        }
        decoderIsFlushed = true;
        onQueueNotEmpty();
      })().catch((error) => {
        if (!outOfBandError) {
          outOfBandError = error;
          onQueueNotEmpty();
        }
      });
      const track = this._track;
      const closeSamples = () => {
        lastSample?.close();
        for (const sample of sampleQueue) {
          sample.close();
        }
      };
      return {
        async next() {
          while (true) {
            if (track.input._disposed) {
              closeSamples();
              throw new InputDisposedError();
            } else if (terminated) {
              return { value: void 0, done: true };
            } else if (outOfBandError) {
              closeSamples();
              throw outOfBandError;
            } else if (sampleQueue.length > 0) {
              const value = sampleQueue.shift();
              onQueueDequeue();
              return { value, done: false };
            } else if (!decoderIsFlushed) {
              await queueNotEmpty;
            } else {
              return { value: void 0, done: true };
            }
          }
        },
        async return() {
          terminated = true;
          ended = true;
          onQueueDequeue();
          onQueueNotEmpty();
          closeSamples();
          return { value: void 0, done: true };
        },
        async throw(error) {
          throw error;
        },
        [Symbol.asyncIterator]() {
          return this;
        }
      };
    }
    /** @internal */
    mediaSamplesAtTimestamps(timestamps) {
      validateAnyIterable(timestamps);
      const timestampIterator = toAsyncIterator(timestamps);
      const timestampsOfInterest = [];
      const sampleQueue = [];
      let { promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers();
      let { promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers();
      let decoderIsFlushed = false;
      let terminated = false;
      let outOfBandError = null;
      const pushToQueue = (sample) => {
        sampleQueue.push(sample);
        onQueueNotEmpty();
        ({ promise: queueNotEmpty, resolve: onQueueNotEmpty } = promiseWithResolvers());
      };
      (async () => {
        const decoder = await this._createDecoder((sample) => {
          onQueueDequeue();
          if (terminated) {
            sample.close();
            return;
          }
          let sampleUses = 0;
          while (timestampsOfInterest.length > 0 && sample.timestamp - timestampsOfInterest[0] > -1e-10) {
            sampleUses++;
            timestampsOfInterest.shift();
          }
          if (sampleUses > 0) {
            for (let i = 0; i < sampleUses; i++) {
              pushToQueue(i < sampleUses - 1 ? sample.clone() : sample);
            }
          } else {
            sample.close();
          }
        }, (error) => {
          if (!outOfBandError) {
            outOfBandError = error;
            onQueueNotEmpty();
          }
        });
        const packetSink = this._createPacketSink();
        let lastPacket = null;
        let lastKeyPacket = null;
        let maxSequenceNumber = -1;
        const decodePackets = async () => {
          assert(lastKeyPacket);
          let currentPacket = lastKeyPacket;
          decoder.decode(currentPacket);
          while (currentPacket.sequenceNumber < maxSequenceNumber) {
            const maxQueueSize = computeMaxQueueSize(sampleQueue.length);
            while (sampleQueue.length + decoder.getDecodeQueueSize() > maxQueueSize && !terminated) {
              ({ promise: queueDequeue, resolve: onQueueDequeue } = promiseWithResolvers());
              await queueDequeue;
            }
            if (terminated) {
              break;
            }
            const nextPacket = await packetSink.getNextPacket(currentPacket);
            assert(nextPacket);
            decoder.decode(nextPacket);
            currentPacket = nextPacket;
          }
          maxSequenceNumber = -1;
        };
        const flushDecoder = async () => {
          await decoder.flush();
          for (let i = 0; i < timestampsOfInterest.length; i++) {
            pushToQueue(null);
          }
          timestampsOfInterest.length = 0;
        };
        for await (const timestamp of timestampIterator) {
          validateTimestamp(timestamp);
          if (terminated || this._track.input._disposed) {
            break;
          }
          const targetPacket = await packetSink.getPacket(timestamp);
          const keyPacket = targetPacket && await packetSink.getKeyPacket(timestamp, { verifyKeyPackets: true });
          if (!keyPacket) {
            if (maxSequenceNumber !== -1) {
              await decodePackets();
              await flushDecoder();
            }
            pushToQueue(null);
            lastPacket = null;
            continue;
          }
          if (lastPacket && (keyPacket.sequenceNumber !== lastKeyPacket.sequenceNumber || targetPacket.timestamp < lastPacket.timestamp)) {
            await decodePackets();
            await flushDecoder();
          }
          timestampsOfInterest.push(targetPacket.timestamp);
          maxSequenceNumber = Math.max(targetPacket.sequenceNumber, maxSequenceNumber);
          lastPacket = targetPacket;
          lastKeyPacket = keyPacket;
        }
        if (!terminated && !this._track.input._disposed) {
          if (maxSequenceNumber !== -1) {
            await decodePackets();
          }
          await flushDecoder();
        }
        decoder.close();
        decoderIsFlushed = true;
        onQueueNotEmpty();
      })().catch((error) => {
        if (!outOfBandError) {
          outOfBandError = error;
          onQueueNotEmpty();
        }
      });
      const track = this._track;
      const closeSamples = () => {
        for (const sample of sampleQueue) {
          sample?.close();
        }
      };
      return {
        async next() {
          while (true) {
            if (track.input._disposed) {
              closeSamples();
              throw new InputDisposedError();
            } else if (terminated) {
              return { value: void 0, done: true };
            } else if (outOfBandError) {
              closeSamples();
              throw outOfBandError;
            } else if (sampleQueue.length > 0) {
              const value = sampleQueue.shift();
              assert(value !== void 0);
              onQueueDequeue();
              return { value, done: false };
            } else if (!decoderIsFlushed) {
              await queueNotEmpty;
            } else {
              return { value: void 0, done: true };
            }
          }
        },
        async return() {
          terminated = true;
          onQueueDequeue();
          onQueueNotEmpty();
          closeSamples();
          return { value: void 0, done: true };
        },
        async throw(error) {
          throw error;
        },
        [Symbol.asyncIterator]() {
          return this;
        }
      };
    }
  };
  var computeMaxQueueSize = (decodedSampleQueueSize) => {
    return decodedSampleQueueSize === 0 ? 40 : 8;
  };
  var VideoDecoderWrapper = class extends DecoderWrapper {
    // For HEVC stuff
    constructor(onSample, onError, codec, decoderConfig, rotation, timeResolution) {
      super(onSample, onError);
      this.codec = codec;
      this.decoderConfig = decoderConfig;
      this.rotation = rotation;
      this.timeResolution = timeResolution;
      this.decoder = null;
      this.customDecoder = null;
      this.customDecoderCallSerializer = new CallSerializer();
      this.customDecoderQueueSize = 0;
      this.inputTimestamps = [];
      // Timestamps input into the decoder, sorted.
      this.sampleQueue = [];
      // Safari-specific thing, check usage.
      this.currentPacketIndex = 0;
      this.raslSkipped = false;
      // For HEVC stuff
      // Alpha stuff
      this.alphaDecoder = null;
      this.alphaHadKeyframe = false;
      this.colorQueue = [];
      this.alphaQueue = [];
      this.merger = null;
      this.mergerCreationFailed = false;
      this.decodedAlphaChunkCount = 0;
      this.alphaDecoderQueueSize = 0;
      /** Each value is the number of decoded alpha chunks at which a null alpha frame should be added. */
      this.nullAlphaFrameQueue = [];
      this.currentAlphaPacketIndex = 0;
      this.alphaRaslSkipped = false;
      const MatchingCustomDecoder = customVideoDecoders.find((x) => x.supports(codec, decoderConfig));
      if (MatchingCustomDecoder) {
        this.customDecoder = new MatchingCustomDecoder();
        this.customDecoder.codec = codec;
        this.customDecoder.config = decoderConfig;
        this.customDecoder.onSample = (sample) => {
          if (!(sample instanceof VideoSample)) {
            throw new TypeError("The argument passed to onSample must be a VideoSample.");
          }
          this.finalizeAndEmitSample(sample);
        };
        void this.customDecoderCallSerializer.call(() => this.customDecoder.init());
      } else {
        const colorHandler = (frame) => {
          if (this.alphaQueue.length > 0) {
            const alphaFrame = this.alphaQueue.shift();
            assert(alphaFrame !== void 0);
            this.mergeAlpha(frame, alphaFrame);
          } else {
            this.colorQueue.push(frame);
          }
        };
        if (codec === "avc" && this.decoderConfig.description && isChromium()) {
          const record = deserializeAvcDecoderConfigurationRecord(toUint8Array(this.decoderConfig.description));
          if (record && record.sequenceParameterSets.length > 0) {
            const sps = parseAvcSps(record.sequenceParameterSets[0]);
            if (sps && sps.frameMbsOnlyFlag === 0) {
              this.decoderConfig = {
                ...this.decoderConfig,
                hardwareAcceleration: "prefer-software"
              };
            }
          }
        }
        const stack = new Error("Decoding error").stack;
        this.decoder = new VideoDecoder({
          output: (frame) => {
            try {
              colorHandler(frame);
            } catch (error) {
              this.onError(error);
            }
          },
          error: (error) => {
            error.stack = stack;
            this.onError(error);
          }
        });
        this.decoder.configure(this.decoderConfig);
      }
    }
    getDecodeQueueSize() {
      if (this.customDecoder) {
        return this.customDecoderQueueSize;
      } else {
        assert(this.decoder);
        return Math.max(
          this.decoder.decodeQueueSize,
          this.alphaDecoder?.decodeQueueSize ?? 0
        );
      }
    }
    decode(packet) {
      if (this.codec === "hevc" && this.currentPacketIndex > 0 && !this.raslSkipped) {
        if (this.hasHevcRaslPicture(packet.data)) {
          return;
        }
        this.raslSkipped = true;
      }
      if (this.customDecoder) {
        this.customDecoderQueueSize++;
        void this.customDecoderCallSerializer.call(() => this.customDecoder.decode(packet)).then(() => this.customDecoderQueueSize--);
      } else {
        assert(this.decoder);
        if (!isWebKit()) {
          insertSorted(this.inputTimestamps, packet.timestamp, (x) => x);
        }
        if (isChromium() && this.currentPacketIndex === 0 && this.codec === "avc") {
          const filteredNalUnits = [];
          for (const loc of iterateAvcNalUnits(packet.data, this.decoderConfig)) {
            const type = extractNalUnitTypeForAvc(packet.data[loc.offset]);
            if (!(type >= 20 && type <= 31)) {
              filteredNalUnits.push(packet.data.subarray(loc.offset, loc.offset + loc.length));
            }
          }
          const newData = concatAvcNalUnits(filteredNalUnits, this.decoderConfig);
          packet = new EncodedPacket(newData, packet.type, packet.timestamp, packet.duration);
        }
        this.decoder.decode(packet.toEncodedVideoChunk());
        this.decodeAlphaData(packet);
      }
      this.currentPacketIndex++;
    }
    decodeAlphaData(packet) {
      if (!packet.sideData.alpha || this.mergerCreationFailed) {
        this.pushNullAlphaFrame();
        return;
      }
      if (!this.merger) {
        try {
          this.merger = new ColorAlphaMerger();
        } catch (error) {
          console.error("Due to an error, only color data will be decoded.", error);
          this.mergerCreationFailed = true;
          this.decodeAlphaData(packet);
          return;
        }
      }
      if (!this.alphaDecoder) {
        const alphaHandler = (frame) => {
          this.alphaDecoderQueueSize--;
          if (this.colorQueue.length > 0) {
            const colorFrame = this.colorQueue.shift();
            assert(colorFrame !== void 0);
            this.mergeAlpha(colorFrame, frame);
          } else {
            this.alphaQueue.push(frame);
          }
          this.decodedAlphaChunkCount++;
          while (this.nullAlphaFrameQueue.length > 0 && this.nullAlphaFrameQueue[0] === this.decodedAlphaChunkCount) {
            this.nullAlphaFrameQueue.shift();
            if (this.colorQueue.length > 0) {
              const colorFrame = this.colorQueue.shift();
              assert(colorFrame !== void 0);
              this.mergeAlpha(colorFrame, null);
            } else {
              this.alphaQueue.push(null);
            }
          }
        };
        const stack = new Error("Decoding error").stack;
        this.alphaDecoder = new VideoDecoder({
          output: (frame) => {
            try {
              alphaHandler(frame);
            } catch (error) {
              this.onError(error);
            }
          },
          error: (error) => {
            error.stack = stack;
            this.onError(error);
          }
        });
        this.alphaDecoder.configure(this.decoderConfig);
      }
      const type = determineVideoPacketType(this.codec, this.decoderConfig, packet.sideData.alpha);
      if (!this.alphaHadKeyframe) {
        this.alphaHadKeyframe = type === "key";
      }
      if (this.alphaHadKeyframe) {
        if (this.codec === "hevc" && this.currentAlphaPacketIndex > 0 && !this.alphaRaslSkipped) {
          if (this.hasHevcRaslPicture(packet.sideData.alpha)) {
            this.pushNullAlphaFrame();
            return;
          }
          this.alphaRaslSkipped = true;
        }
        this.currentAlphaPacketIndex++;
        this.alphaDecoder.decode(packet.alphaToEncodedVideoChunk(type ?? packet.type));
        this.alphaDecoderQueueSize++;
      } else {
        this.pushNullAlphaFrame();
      }
    }
    pushNullAlphaFrame() {
      if (this.alphaDecoderQueueSize === 0) {
        this.alphaQueue.push(null);
      } else {
        this.nullAlphaFrameQueue.push(this.decodedAlphaChunkCount + this.alphaDecoderQueueSize);
      }
    }
    /**
     * If we're using HEVC, we need to make sure to skip any RASL slices that follow a non-IDR key frame such as
     * CRA_NUT. This is because RASL slices cannot be decoded without data before the CRA_NUT. Browsers behave
     * differently here: Chromium drops the packets, Safari throws a decoder error. Either way, it's not good
     * and causes bugs upstream. So, let's take the dropping into our own hands.
     */
    hasHevcRaslPicture(packetData) {
      for (const loc of iterateHevcNalUnits(packetData, this.decoderConfig)) {
        const type = extractNalUnitTypeForHevc(packetData[loc.offset]);
        if (type === 8 /* RASL_N */ || type === 9 /* RASL_R */) {
          return true;
        }
      }
      return false;
    }
    /** Handler for the WebCodecs VideoDecoder for ironing out browser differences. */
    sampleHandler(sample) {
      if (isWebKit()) {
        if (this.sampleQueue.length > 0 && sample.timestamp >= last(this.sampleQueue).timestamp) {
          for (const sample2 of this.sampleQueue) {
            this.finalizeAndEmitSample(sample2);
          }
          this.sampleQueue.length = 0;
        }
        insertSorted(this.sampleQueue, sample, (x) => x.timestamp);
      } else {
        const timestamp = this.inputTimestamps.shift();
        assert(timestamp !== void 0);
        sample.setTimestamp(timestamp);
        this.finalizeAndEmitSample(sample);
      }
    }
    finalizeAndEmitSample(sample) {
      sample.setTimestamp(Math.round(sample.timestamp * this.timeResolution) / this.timeResolution);
      sample.setDuration(Math.round(sample.duration * this.timeResolution) / this.timeResolution);
      sample.setRotation(this.rotation);
      this.onSample(sample);
    }
    mergeAlpha(color, alpha) {
      if (!alpha) {
        const finalSample2 = new VideoSample(color);
        this.sampleHandler(finalSample2);
        return;
      }
      assert(this.merger);
      this.merger.update(color, alpha);
      color.close();
      alpha.close();
      const finalFrame = new VideoFrame(this.merger.canvas, {
        timestamp: color.timestamp,
        duration: color.duration ?? void 0
      });
      const finalSample = new VideoSample(finalFrame);
      this.sampleHandler(finalSample);
    }
    async flush() {
      if (this.customDecoder) {
        await this.customDecoderCallSerializer.call(() => this.customDecoder.flush());
      } else {
        assert(this.decoder);
        await Promise.all([
          this.decoder.flush(),
          this.alphaDecoder?.flush()
        ]);
        this.colorQueue.forEach((x) => x.close());
        this.colorQueue.length = 0;
        this.alphaQueue.forEach((x) => x?.close());
        this.alphaQueue.length = 0;
        this.alphaHadKeyframe = false;
        this.decodedAlphaChunkCount = 0;
        this.alphaDecoderQueueSize = 0;
        this.nullAlphaFrameQueue.length = 0;
        this.currentAlphaPacketIndex = 0;
        this.alphaRaslSkipped = false;
      }
      if (isWebKit()) {
        for (const sample of this.sampleQueue) {
          this.finalizeAndEmitSample(sample);
        }
        this.sampleQueue.length = 0;
      }
      this.currentPacketIndex = 0;
      this.raslSkipped = false;
    }
    close() {
      if (this.customDecoder) {
        void this.customDecoderCallSerializer.call(() => this.customDecoder.close());
      } else {
        assert(this.decoder);
        this.decoder.close();
        this.alphaDecoder?.close();
        this.colorQueue.forEach((x) => x.close());
        this.colorQueue.length = 0;
        this.alphaQueue.forEach((x) => x?.close());
        this.alphaQueue.length = 0;
        this.merger?.close();
      }
      for (const sample of this.sampleQueue) {
        sample.close();
      }
      this.sampleQueue.length = 0;
    }
  };
  var ColorAlphaMerger = class {
    constructor() {
      if (typeof OffscreenCanvas !== "undefined") {
        this.canvas = new OffscreenCanvas(300, 150);
      } else {
        this.canvas = document.createElement("canvas");
      }
      const gl = this.canvas.getContext("webgl2", {
        premultipliedAlpha: false
      });
      if (!gl) {
        throw new Error("Couldn't acquire WebGL 2 context.");
      }
      this.gl = gl;
      this.program = this.createProgram();
      this.vao = this.createVAO();
      this.colorTexture = this.createTexture();
      this.alphaTexture = this.createTexture();
      this.gl.useProgram(this.program);
      this.gl.uniform1i(this.gl.getUniformLocation(this.program, "u_colorTexture"), 0);
      this.gl.uniform1i(this.gl.getUniformLocation(this.program, "u_alphaTexture"), 1);
    }
    createProgram() {
      const vertexShader = this.createShader(this.gl.VERTEX_SHADER, `#version 300 es
			in vec2 a_position;
			in vec2 a_texCoord;
			out vec2 v_texCoord;
			
			void main() {
				gl_Position = vec4(a_position, 0.0, 1.0);
				v_texCoord = a_texCoord;
			}
		`);
      const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, `#version 300 es
			precision highp float;
			
			uniform sampler2D u_colorTexture;
			uniform sampler2D u_alphaTexture;
			in vec2 v_texCoord;
			out vec4 fragColor;
			
			void main() {
				vec3 color = texture(u_colorTexture, v_texCoord).rgb;
				float alpha = texture(u_alphaTexture, v_texCoord).r;
				fragColor = vec4(color, alpha);
			}
		`);
      const program = this.gl.createProgram();
      this.gl.attachShader(program, vertexShader);
      this.gl.attachShader(program, fragmentShader);
      this.gl.linkProgram(program);
      return program;
    }
    createShader(type, source) {
      const shader = this.gl.createShader(type);
      this.gl.shaderSource(shader, source);
      this.gl.compileShader(shader);
      return shader;
    }
    createVAO() {
      const vao = this.gl.createVertexArray();
      this.gl.bindVertexArray(vao);
      const vertices = new Float32Array([
        -1,
        -1,
        0,
        1,
        1,
        -1,
        1,
        1,
        -1,
        1,
        0,
        0,
        1,
        1,
        1,
        0
      ]);
      const buffer = this.gl.createBuffer();
      this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
      this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);
      const positionLocation = this.gl.getAttribLocation(this.program, "a_position");
      const texCoordLocation = this.gl.getAttribLocation(this.program, "a_texCoord");
      this.gl.enableVertexAttribArray(positionLocation);
      this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 16, 0);
      this.gl.enableVertexAttribArray(texCoordLocation);
      this.gl.vertexAttribPointer(texCoordLocation, 2, this.gl.FLOAT, false, 16, 8);
      return vao;
    }
    createTexture() {
      const texture = this.gl.createTexture();
      this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
      this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
      this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
      this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
      this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
      return texture;
    }
    update(color, alpha) {
      if (color.displayWidth !== this.canvas.width || color.displayHeight !== this.canvas.height) {
        this.canvas.width = color.displayWidth;
        this.canvas.height = color.displayHeight;
      }
      this.gl.activeTexture(this.gl.TEXTURE0);
      this.gl.bindTexture(this.gl.TEXTURE_2D, this.colorTexture);
      this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, color);
      this.gl.activeTexture(this.gl.TEXTURE1);
      this.gl.bindTexture(this.gl.TEXTURE_2D, this.alphaTexture);
      this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, alpha);
      this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
      this.gl.clear(this.gl.COLOR_BUFFER_BIT);
      this.gl.bindVertexArray(this.vao);
      this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
    }
    close() {
      this.gl.getExtension("WEBGL_lose_context")?.loseContext();
      this.gl = null;
    }
  };
  var VideoSampleSink = class extends BaseMediaSampleSink {
    /** Creates a new {@link VideoSampleSink} for the given {@link InputVideoTrack}. */
    constructor(videoTrack) {
      if (!(videoTrack instanceof InputVideoTrack)) {
        throw new TypeError("videoTrack must be an InputVideoTrack.");
      }
      super();
      this._track = videoTrack;
    }
    /** @internal */
    async _createDecoder(onSample, onError) {
      if (!await this._track.canDecode()) {
        throw new Error(
          "This video track cannot be decoded by this browser. Make sure to check decodability before using a track."
        );
      }
      const codec = this._track.codec;
      const rotation = this._track.rotation;
      const decoderConfig = await this._track.getDecoderConfig();
      const timeResolution = this._track.timeResolution;
      assert(codec && decoderConfig);
      return new VideoDecoderWrapper(onSample, onError, codec, decoderConfig, rotation, timeResolution);
    }
    /** @internal */
    _createPacketSink() {
      return new EncodedPacketSink(this._track);
    }
    /**
     * Retrieves the video sample (frame) corresponding to the given timestamp, in seconds. More specifically, returns
     * the last video sample (in presentation order) with a start timestamp less than or equal to the given timestamp.
     * Returns null if the timestamp is before the track's first timestamp.
     *
     * @param timestamp - The timestamp used for retrieval, in seconds.
     */
    async getSample(timestamp) {
      validateTimestamp(timestamp);
      for await (const sample of this.mediaSamplesAtTimestamps([timestamp])) {
        return sample;
      }
      throw new Error("Internal error: Iterator returned nothing.");
    }
    /**
     * Creates an async iterator that yields the video samples (frames) of this track in presentation order. This method
     * will intelligently pre-decode a few frames ahead to enable fast iteration.
     *
     * @param startTimestamp - The timestamp in seconds at which to start yielding samples (inclusive).
     * @param endTimestamp - The timestamp in seconds at which to stop yielding samples (exclusive).
     */
    samples(startTimestamp = 0, endTimestamp = Infinity) {
      return this.mediaSamplesInRange(startTimestamp, endTimestamp);
    }
    /**
     * Creates an async iterator that yields a video sample (frame) for each timestamp in the argument. This method
     * uses an optimized decoding pipeline if these timestamps are monotonically sorted, decoding each packet at most
     * once, and is therefore more efficient than manually getting the sample for every timestamp. The iterator may
     * yield null if no frame is available for a given timestamp.
     *
     * @param timestamps - An iterable or async iterable of timestamps in seconds.
     */
    samplesAtTimestamps(timestamps) {
      return this.mediaSamplesAtTimestamps(timestamps);
    }
  };
  var CanvasSink = class {
    /** Creates a new {@link CanvasSink} for the given {@link InputVideoTrack}. */
    constructor(videoTrack, options = {}) {
      /** @internal */
      this._nextCanvasIndex = 0;
      if (!(videoTrack instanceof InputVideoTrack)) {
        throw new TypeError("videoTrack must be an InputVideoTrack.");
      }
      if (options && typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (options.alpha !== void 0 && typeof options.alpha !== "boolean") {
        throw new TypeError("options.alpha, when provided, must be a boolean.");
      }
      if (options.width !== void 0 && (!Number.isInteger(options.width) || options.width <= 0)) {
        throw new TypeError("options.width, when defined, must be a positive integer.");
      }
      if (options.height !== void 0 && (!Number.isInteger(options.height) || options.height <= 0)) {
        throw new TypeError("options.height, when defined, must be a positive integer.");
      }
      if (options.fit !== void 0 && !["fill", "contain", "cover"].includes(options.fit)) {
        throw new TypeError('options.fit, when provided, must be one of "fill", "contain", or "cover".');
      }
      if (options.width !== void 0 && options.height !== void 0 && options.fit === void 0) {
        throw new TypeError(
          "When both options.width and options.height are provided, options.fit must also be provided."
        );
      }
      if (options.rotation !== void 0 && ![0, 90, 180, 270].includes(options.rotation)) {
        throw new TypeError("options.rotation, when provided, must be 0, 90, 180 or 270.");
      }
      if (options.crop !== void 0) {
        validateCropRectangle(options.crop, "options.");
      }
      if (options.poolSize !== void 0 && (typeof options.poolSize !== "number" || !Number.isInteger(options.poolSize) || options.poolSize < 0)) {
        throw new TypeError("poolSize must be a non-negative integer.");
      }
      const rotation = options.rotation ?? videoTrack.rotation;
      const [rotatedWidth, rotatedHeight] = rotation % 180 === 0 ? [videoTrack.codedWidth, videoTrack.codedHeight] : [videoTrack.codedHeight, videoTrack.codedWidth];
      const crop = options.crop;
      if (crop) {
        clampCropRectangle(crop, rotatedWidth, rotatedHeight);
      }
      let [width, height] = crop ? [crop.width, crop.height] : [rotatedWidth, rotatedHeight];
      const originalAspectRatio = width / height;
      if (options.width !== void 0 && options.height === void 0) {
        width = options.width;
        height = Math.round(width / originalAspectRatio);
      } else if (options.width === void 0 && options.height !== void 0) {
        height = options.height;
        width = Math.round(height * originalAspectRatio);
      } else if (options.width !== void 0 && options.height !== void 0) {
        width = options.width;
        height = options.height;
      }
      this._videoTrack = videoTrack;
      this._alpha = options.alpha ?? false;
      this._width = width;
      this._height = height;
      this._rotation = rotation;
      this._crop = crop;
      this._fit = options.fit ?? "fill";
      this._videoSampleSink = new VideoSampleSink(videoTrack);
      this._canvasPool = Array.from({ length: options.poolSize ?? 0 }, () => null);
    }
    /** @internal */
    _videoSampleToWrappedCanvas(sample) {
      let canvas = this._canvasPool[this._nextCanvasIndex];
      let canvasIsNew = false;
      if (!canvas) {
        if (typeof document !== "undefined") {
          canvas = document.createElement("canvas");
          canvas.width = this._width;
          canvas.height = this._height;
        } else {
          canvas = new OffscreenCanvas(this._width, this._height);
        }
        if (this._canvasPool.length > 0) {
          this._canvasPool[this._nextCanvasIndex] = canvas;
        }
        canvasIsNew = true;
      }
      if (this._canvasPool.length > 0) {
        this._nextCanvasIndex = (this._nextCanvasIndex + 1) % this._canvasPool.length;
      }
      const context = canvas.getContext("2d", {
        alpha: this._alpha || isFirefox()
        // Firefox has VideoFrame glitches with opaque canvases
      });
      assert(context);
      context.resetTransform();
      if (!canvasIsNew) {
        if (!this._alpha && isFirefox()) {
          context.fillStyle = "black";
          context.fillRect(0, 0, this._width, this._height);
        } else {
          context.clearRect(0, 0, this._width, this._height);
        }
      }
      sample.drawWithFit(context, {
        fit: this._fit,
        rotation: this._rotation,
        crop: this._crop
      });
      const result = {
        canvas,
        timestamp: sample.timestamp,
        duration: sample.duration
      };
      sample.close();
      return result;
    }
    /**
     * Retrieves a canvas with the video frame corresponding to the given timestamp, in seconds. More specifically,
     * returns the last video frame (in presentation order) with a start timestamp less than or equal to the given
     * timestamp. Returns null if the timestamp is before the track's first timestamp.
     *
     * @param timestamp - The timestamp used for retrieval, in seconds.
     */
    async getCanvas(timestamp) {
      validateTimestamp(timestamp);
      const sample = await this._videoSampleSink.getSample(timestamp);
      return sample && this._videoSampleToWrappedCanvas(sample);
    }
    /**
     * Creates an async iterator that yields canvases with the video frames of this track in presentation order. This
     * method will intelligently pre-decode a few frames ahead to enable fast iteration.
     *
     * @param startTimestamp - The timestamp in seconds at which to start yielding canvases (inclusive).
     * @param endTimestamp - The timestamp in seconds at which to stop yielding canvases (exclusive).
     */
    canvases(startTimestamp = 0, endTimestamp = Infinity) {
      return mapAsyncGenerator(
        this._videoSampleSink.samples(startTimestamp, endTimestamp),
        (sample) => this._videoSampleToWrappedCanvas(sample)
      );
    }
    /**
     * Creates an async iterator that yields a canvas for each timestamp in the argument. This method uses an optimized
     * decoding pipeline if these timestamps are monotonically sorted, decoding each packet at most once, and is
     * therefore more efficient than manually getting the canvas for every timestamp. The iterator may yield null if
     * no frame is available for a given timestamp.
     *
     * @param timestamps - An iterable or async iterable of timestamps in seconds.
     */
    canvasesAtTimestamps(timestamps) {
      return mapAsyncGenerator(
        this._videoSampleSink.samplesAtTimestamps(timestamps),
        (sample) => sample && this._videoSampleToWrappedCanvas(sample)
      );
    }
  };
  var AudioDecoderWrapper = class extends DecoderWrapper {
    constructor(onSample, onError, codec, decoderConfig) {
      super(onSample, onError);
      this.decoder = null;
      this.customDecoder = null;
      this.customDecoderCallSerializer = new CallSerializer();
      this.customDecoderQueueSize = 0;
      // Internal state to accumulate a precise current timestamp based on audio durations, not the (potentially
      // inaccurate) packet timestamps.
      this.currentTimestamp = null;
      const sampleHandler = (sample) => {
        if (this.currentTimestamp === null || Math.abs(sample.timestamp - this.currentTimestamp) >= sample.duration) {
          this.currentTimestamp = sample.timestamp;
        }
        const preciseTimestamp = this.currentTimestamp;
        this.currentTimestamp += sample.duration;
        if (sample.numberOfFrames === 0) {
          sample.close();
          return;
        }
        const sampleRate = decoderConfig.sampleRate;
        sample.setTimestamp(Math.round(preciseTimestamp * sampleRate) / sampleRate);
        onSample(sample);
      };
      const MatchingCustomDecoder = customAudioDecoders.find((x) => x.supports(codec, decoderConfig));
      if (MatchingCustomDecoder) {
        this.customDecoder = new MatchingCustomDecoder();
        this.customDecoder.codec = codec;
        this.customDecoder.config = decoderConfig;
        this.customDecoder.onSample = (sample) => {
          if (!(sample instanceof AudioSample)) {
            throw new TypeError("The argument passed to onSample must be an AudioSample.");
          }
          sampleHandler(sample);
        };
        void this.customDecoderCallSerializer.call(() => this.customDecoder.init());
      } else {
        const stack = new Error("Decoding error").stack;
        this.decoder = new AudioDecoder({
          output: (data) => {
            try {
              sampleHandler(new AudioSample(data));
            } catch (error) {
              this.onError(error);
            }
          },
          error: (error) => {
            error.stack = stack;
            this.onError(error);
          }
        });
        this.decoder.configure(decoderConfig);
      }
    }
    getDecodeQueueSize() {
      if (this.customDecoder) {
        return this.customDecoderQueueSize;
      } else {
        assert(this.decoder);
        return this.decoder.decodeQueueSize;
      }
    }
    decode(packet) {
      if (this.customDecoder) {
        this.customDecoderQueueSize++;
        void this.customDecoderCallSerializer.call(() => this.customDecoder.decode(packet)).then(() => this.customDecoderQueueSize--);
      } else {
        assert(this.decoder);
        this.decoder.decode(packet.toEncodedAudioChunk());
      }
    }
    flush() {
      if (this.customDecoder) {
        return this.customDecoderCallSerializer.call(() => this.customDecoder.flush());
      } else {
        assert(this.decoder);
        return this.decoder.flush();
      }
    }
    close() {
      if (this.customDecoder) {
        void this.customDecoderCallSerializer.call(() => this.customDecoder.close());
      } else {
        assert(this.decoder);
        this.decoder.close();
      }
    }
  };
  var PcmAudioDecoderWrapper = class extends DecoderWrapper {
    constructor(onSample, onError, decoderConfig) {
      super(onSample, onError);
      this.decoderConfig = decoderConfig;
      // Internal state to accumulate a precise current timestamp based on audio durations, not the (potentially
      // inaccurate) packet timestamps.
      this.currentTimestamp = null;
      assert(PCM_AUDIO_CODECS.includes(decoderConfig.codec));
      this.codec = decoderConfig.codec;
      const { dataType, sampleSize, littleEndian } = parsePcmCodec(this.codec);
      this.inputSampleSize = sampleSize;
      switch (sampleSize) {
        case 1:
          {
            if (dataType === "unsigned") {
              this.readInputValue = (view2, byteOffset) => view2.getUint8(byteOffset) - 2 ** 7;
            } else if (dataType === "signed") {
              this.readInputValue = (view2, byteOffset) => view2.getInt8(byteOffset);
            } else if (dataType === "ulaw") {
              this.readInputValue = (view2, byteOffset) => fromUlaw(view2.getUint8(byteOffset));
            } else if (dataType === "alaw") {
              this.readInputValue = (view2, byteOffset) => fromAlaw(view2.getUint8(byteOffset));
            } else {
              assert(false);
            }
          }
          ;
          break;
        case 2:
          {
            if (dataType === "unsigned") {
              this.readInputValue = (view2, byteOffset) => view2.getUint16(byteOffset, littleEndian) - 2 ** 15;
            } else if (dataType === "signed") {
              this.readInputValue = (view2, byteOffset) => view2.getInt16(byteOffset, littleEndian);
            } else {
              assert(false);
            }
          }
          ;
          break;
        case 3:
          {
            if (dataType === "unsigned") {
              this.readInputValue = (view2, byteOffset) => getUint24(view2, byteOffset, littleEndian) - 2 ** 23;
            } else if (dataType === "signed") {
              this.readInputValue = (view2, byteOffset) => getInt24(view2, byteOffset, littleEndian);
            } else {
              assert(false);
            }
          }
          ;
          break;
        case 4:
          {
            if (dataType === "unsigned") {
              this.readInputValue = (view2, byteOffset) => view2.getUint32(byteOffset, littleEndian) - 2 ** 31;
            } else if (dataType === "signed") {
              this.readInputValue = (view2, byteOffset) => view2.getInt32(byteOffset, littleEndian);
            } else if (dataType === "float") {
              this.readInputValue = (view2, byteOffset) => view2.getFloat32(byteOffset, littleEndian);
            } else {
              assert(false);
            }
          }
          ;
          break;
        case 8:
          {
            if (dataType === "float") {
              this.readInputValue = (view2, byteOffset) => view2.getFloat64(byteOffset, littleEndian);
            } else {
              assert(false);
            }
          }
          ;
          break;
        default:
          {
            assertNever(sampleSize);
            assert(false);
          }
          ;
      }
      switch (sampleSize) {
        case 1:
          {
            if (dataType === "ulaw" || dataType === "alaw") {
              this.outputSampleSize = 2;
              this.outputFormat = "s16";
              this.writeOutputValue = (view2, byteOffset, value) => view2.setInt16(byteOffset, value, true);
            } else {
              this.outputSampleSize = 1;
              this.outputFormat = "u8";
              this.writeOutputValue = (view2, byteOffset, value) => view2.setUint8(byteOffset, value + 2 ** 7);
            }
          }
          ;
          break;
        case 2:
          {
            this.outputSampleSize = 2;
            this.outputFormat = "s16";
            this.writeOutputValue = (view2, byteOffset, value) => view2.setInt16(byteOffset, value, true);
          }
          ;
          break;
        case 3:
          {
            this.outputSampleSize = 4;
            this.outputFormat = "s32";
            this.writeOutputValue = (view2, byteOffset, value) => view2.setInt32(byteOffset, value << 8, true);
          }
          ;
          break;
        case 4:
          {
            this.outputSampleSize = 4;
            if (dataType === "float") {
              this.outputFormat = "f32";
              this.writeOutputValue = (view2, byteOffset, value) => view2.setFloat32(byteOffset, value, true);
            } else {
              this.outputFormat = "s32";
              this.writeOutputValue = (view2, byteOffset, value) => view2.setInt32(byteOffset, value, true);
            }
          }
          ;
          break;
        case 8:
          {
            this.outputSampleSize = 4;
            this.outputFormat = "f32";
            this.writeOutputValue = (view2, byteOffset, value) => view2.setFloat32(byteOffset, value, true);
          }
          ;
          break;
        default:
          {
            assertNever(sampleSize);
            assert(false);
          }
          ;
      }
      ;
    }
    getDecodeQueueSize() {
      return 0;
    }
    decode(packet) {
      const inputView = toDataView(packet.data);
      const numberOfFrames = packet.byteLength / this.decoderConfig.numberOfChannels / this.inputSampleSize;
      const outputBufferSize = numberOfFrames * this.decoderConfig.numberOfChannels * this.outputSampleSize;
      const outputBuffer = new ArrayBuffer(outputBufferSize);
      const outputView = new DataView(outputBuffer);
      for (let i = 0; i < numberOfFrames * this.decoderConfig.numberOfChannels; i++) {
        const inputIndex = i * this.inputSampleSize;
        const outputIndex = i * this.outputSampleSize;
        const value = this.readInputValue(inputView, inputIndex);
        this.writeOutputValue(outputView, outputIndex, value);
      }
      const preciseDuration = numberOfFrames / this.decoderConfig.sampleRate;
      if (this.currentTimestamp === null || Math.abs(packet.timestamp - this.currentTimestamp) >= preciseDuration) {
        this.currentTimestamp = packet.timestamp;
      }
      const preciseTimestamp = this.currentTimestamp;
      this.currentTimestamp += preciseDuration;
      const audioSample = new AudioSample({
        format: this.outputFormat,
        data: outputBuffer,
        numberOfChannels: this.decoderConfig.numberOfChannels,
        sampleRate: this.decoderConfig.sampleRate,
        numberOfFrames,
        timestamp: preciseTimestamp
      });
      this.onSample(audioSample);
    }
    async flush() {
    }
    close() {
    }
  };
  var AudioSampleSink = class extends BaseMediaSampleSink {
    /** Creates a new {@link AudioSampleSink} for the given {@link InputAudioTrack}. */
    constructor(audioTrack) {
      if (!(audioTrack instanceof InputAudioTrack)) {
        throw new TypeError("audioTrack must be an InputAudioTrack.");
      }
      super();
      this._track = audioTrack;
    }
    /** @internal */
    async _createDecoder(onSample, onError) {
      if (!await this._track.canDecode()) {
        throw new Error(
          "This audio track cannot be decoded by this browser. Make sure to check decodability before using a track."
        );
      }
      const codec = this._track.codec;
      const decoderConfig = await this._track.getDecoderConfig();
      assert(codec && decoderConfig);
      if (PCM_AUDIO_CODECS.includes(decoderConfig.codec)) {
        return new PcmAudioDecoderWrapper(onSample, onError, decoderConfig);
      } else {
        return new AudioDecoderWrapper(onSample, onError, codec, decoderConfig);
      }
    }
    /** @internal */
    _createPacketSink() {
      return new EncodedPacketSink(this._track);
    }
    /**
     * Retrieves the audio sample corresponding to the given timestamp, in seconds. More specifically, returns
     * the last audio sample (in presentation order) with a start timestamp less than or equal to the given timestamp.
     * Returns null if the timestamp is before the track's first timestamp.
     *
     * @param timestamp - The timestamp used for retrieval, in seconds.
     */
    async getSample(timestamp) {
      validateTimestamp(timestamp);
      for await (const sample of this.mediaSamplesAtTimestamps([timestamp])) {
        return sample;
      }
      throw new Error("Internal error: Iterator returned nothing.");
    }
    /**
     * Creates an async iterator that yields the audio samples of this track in presentation order. This method
     * will intelligently pre-decode a few samples ahead to enable fast iteration.
     *
     * @param startTimestamp - The timestamp in seconds at which to start yielding samples (inclusive).
     * @param endTimestamp - The timestamp in seconds at which to stop yielding samples (exclusive).
     */
    samples(startTimestamp = 0, endTimestamp = Infinity) {
      return this.mediaSamplesInRange(startTimestamp, endTimestamp);
    }
    /**
     * Creates an async iterator that yields an audio sample for each timestamp in the argument. This method
     * uses an optimized decoding pipeline if these timestamps are monotonically sorted, decoding each packet at most
     * once, and is therefore more efficient than manually getting the sample for every timestamp. The iterator may
     * yield null if no sample is available for a given timestamp.
     *
     * @param timestamps - An iterable or async iterable of timestamps in seconds.
     */
    samplesAtTimestamps(timestamps) {
      return this.mediaSamplesAtTimestamps(timestamps);
    }
  };
  var AudioBufferSink = class {
    /** Creates a new {@link AudioBufferSink} for the given {@link InputAudioTrack}. */
    constructor(audioTrack) {
      if (!(audioTrack instanceof InputAudioTrack)) {
        throw new TypeError("audioTrack must be an InputAudioTrack.");
      }
      this._audioSampleSink = new AudioSampleSink(audioTrack);
    }
    /** @internal */
    _audioSampleToWrappedArrayBuffer(sample) {
      const result = {
        buffer: sample.toAudioBuffer(),
        timestamp: sample.timestamp,
        duration: sample.duration
      };
      sample.close();
      return result;
    }
    /**
     * Retrieves the audio buffer corresponding to the given timestamp, in seconds. More specifically, returns
     * the last audio buffer (in presentation order) with a start timestamp less than or equal to the given timestamp.
     * Returns null if the timestamp is before the track's first timestamp.
     *
     * @param timestamp - The timestamp used for retrieval, in seconds.
     */
    async getBuffer(timestamp) {
      validateTimestamp(timestamp);
      const data = await this._audioSampleSink.getSample(timestamp);
      return data && this._audioSampleToWrappedArrayBuffer(data);
    }
    /**
     * Creates an async iterator that yields audio buffers of this track in presentation order. This method
     * will intelligently pre-decode a few buffers ahead to enable fast iteration.
     *
     * @param startTimestamp - The timestamp in seconds at which to start yielding buffers (inclusive).
     * @param endTimestamp - The timestamp in seconds at which to stop yielding buffers (exclusive).
     */
    buffers(startTimestamp = 0, endTimestamp = Infinity) {
      return mapAsyncGenerator(
        this._audioSampleSink.samples(startTimestamp, endTimestamp),
        (data) => this._audioSampleToWrappedArrayBuffer(data)
      );
    }
    /**
     * Creates an async iterator that yields an audio buffer for each timestamp in the argument. This method
     * uses an optimized decoding pipeline if these timestamps are monotonically sorted, decoding each packet at most
     * once, and is therefore more efficient than manually getting the buffer for every timestamp. The iterator may
     * yield null if no buffer is available for a given timestamp.
     *
     * @param timestamps - An iterable or async iterable of timestamps in seconds.
     */
    buffersAtTimestamps(timestamps) {
      return mapAsyncGenerator(
        this._audioSampleSink.samplesAtTimestamps(timestamps),
        (data) => data && this._audioSampleToWrappedArrayBuffer(data)
      );
    }
  };

  // src/input-track.ts
  var InputTrack = class {
    /** @internal */
    constructor(input, backing) {
      this.input = input;
      this._backing = backing;
    }
    /** Returns true if and only if this track is a video track. */
    isVideoTrack() {
      return this instanceof InputVideoTrack;
    }
    /** Returns true if and only if this track is an audio track. */
    isAudioTrack() {
      return this instanceof InputAudioTrack;
    }
    /** The unique ID of this track in the input file. */
    get id() {
      return this._backing.getId();
    }
    /**
     * The 1-based index of this track among all tracks of the same type in the input file. For example, the first
     * video track has number 1, the second video track has number 2, and so on. The index refers to the order in
     * which the tracks are returned by {@link Input.getTracks}.
     */
    get number() {
      return this._backing.getNumber();
    }
    /**
     * The identifier of the codec used internally by the container. It is not homogenized by Mediabunny
     * and depends entirely on the container format.
     *
     * This field can be used to determine the codec of a track in case Mediabunny doesn't know that codec.
     *
     * - For ISOBMFF files, this field returns the name of the Sample Description Box (e.g. `'avc1'`).
     * - For Matroska files, this field returns the value of the `CodecID` element.
     * - For WAVE files, this field returns the value of the format tag in the `'fmt '` chunk.
     * - For ADTS files, this field contains the `MPEG-4 Audio Object Type`.
     * - For MPEG-TS files, this field contains the `streamType` value from the Program Map Table.
     * - In all other cases, this field is `null`.
     */
    get internalCodecId() {
      return this._backing.getInternalCodecId();
    }
    /**
     * The ISO 639-2/T language code for this track. If the language is unknown, this field is `'und'` (undetermined).
     */
    get languageCode() {
      return this._backing.getLanguageCode();
    }
    /** A user-defined name for this track. */
    get name() {
      return this._backing.getName();
    }
    /**
     * A positive number x such that all timestamps and durations of all packets of this track are
     * integer multiples of 1/x.
     */
    get timeResolution() {
      return this._backing.getTimeResolution();
    }
    /** The track's disposition, i.e. information about its intended usage. */
    get disposition() {
      return this._backing.getDisposition();
    }
    /**
     * Returns the start timestamp of the first packet of this track, in seconds. While often near zero, this value
     * may be positive or even negative. A negative starting timestamp means the track's timing has been offset. Samples
     * with a negative timestamp should not be presented.
     */
    getFirstTimestamp() {
      return this._backing.getFirstTimestamp();
    }
    /** Returns the end timestamp of the last packet of this track, in seconds. */
    computeDuration() {
      return this._backing.computeDuration();
    }
    /**
     * Computes aggregate packet statistics for this track, such as average packet rate or bitrate.
     *
     * @param targetPacketCount - This optional parameter sets a target for how many packets this method must have
     * looked at before it can return early; this means, you can use it to aggregate only a subset (prefix) of all
     * packets. This is very useful for getting a great estimate of video frame rate without having to scan through the
     * entire file.
     */
    async computePacketStats(targetPacketCount = Infinity) {
      const sink = new EncodedPacketSink(this);
      let startTimestamp = Infinity;
      let endTimestamp = -Infinity;
      let packetCount = 0;
      let totalPacketBytes = 0;
      for await (const packet of sink.packets(void 0, void 0, { metadataOnly: true })) {
        if (packetCount >= targetPacketCount && packet.timestamp >= endTimestamp) {
          break;
        }
        startTimestamp = Math.min(startTimestamp, packet.timestamp);
        endTimestamp = Math.max(endTimestamp, packet.timestamp + packet.duration);
        packetCount++;
        totalPacketBytes += packet.byteLength;
      }
      return {
        packetCount,
        averagePacketRate: packetCount ? Number((packetCount / (endTimestamp - startTimestamp)).toPrecision(16)) : 0,
        averageBitrate: packetCount ? Number((8 * totalPacketBytes / (endTimestamp - startTimestamp)).toPrecision(16)) : 0
      };
    }
  };
  var InputVideoTrack = class extends InputTrack {
    /** @internal */
    constructor(input, backing) {
      super(input, backing);
      this._backing = backing;
    }
    get type() {
      return "video";
    }
    get codec() {
      return this._backing.getCodec();
    }
    /** The width in pixels of the track's coded samples, before any transformations or rotations. */
    get codedWidth() {
      return this._backing.getCodedWidth();
    }
    /** The height in pixels of the track's coded samples, before any transformations or rotations. */
    get codedHeight() {
      return this._backing.getCodedHeight();
    }
    /** The angle in degrees by which the track's frames should be rotated (clockwise). */
    get rotation() {
      return this._backing.getRotation();
    }
    /** The width in pixels of the track's frames after rotation. */
    get displayWidth() {
      const rotation = this._backing.getRotation();
      return rotation % 180 === 0 ? this._backing.getCodedWidth() : this._backing.getCodedHeight();
    }
    /** The height in pixels of the track's frames after rotation. */
    get displayHeight() {
      const rotation = this._backing.getRotation();
      return rotation % 180 === 0 ? this._backing.getCodedHeight() : this._backing.getCodedWidth();
    }
    /** Returns the color space of the track's samples. */
    getColorSpace() {
      return this._backing.getColorSpace();
    }
    /** If this method returns true, the track's samples use a high dynamic range (HDR). */
    async hasHighDynamicRange() {
      const colorSpace = await this._backing.getColorSpace();
      return colorSpace.primaries === "bt2020" || colorSpace.primaries === "smpte432" || colorSpace.transfer === "pg" || colorSpace.transfer === "hlg" || colorSpace.matrix === "bt2020-ncl";
    }
    /** Checks if this track may contain transparent samples with alpha data. */
    canBeTransparent() {
      return this._backing.canBeTransparent();
    }
    /**
     * Returns the [decoder configuration](https://www.w3.org/TR/webcodecs/#video-decoder-config) for decoding the
     * track's packets using a [`VideoDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/VideoDecoder). Returns
     * null if the track's codec is unknown.
     */
    getDecoderConfig() {
      return this._backing.getDecoderConfig();
    }
    async getCodecParameterString() {
      const decoderConfig = await this._backing.getDecoderConfig();
      return decoderConfig?.codec ?? null;
    }
    async canDecode() {
      try {
        const decoderConfig = await this._backing.getDecoderConfig();
        if (!decoderConfig) {
          return false;
        }
        const codec = this._backing.getCodec();
        assert(codec !== null);
        if (customVideoDecoders.some((x) => x.supports(codec, decoderConfig))) {
          return true;
        }
        if (typeof VideoDecoder === "undefined") {
          return false;
        }
        const support = await VideoDecoder.isConfigSupported(decoderConfig);
        return support.supported === true;
      } catch (error) {
        console.error("Error during decodability check:", error);
        return false;
      }
    }
    async determinePacketType(packet) {
      if (!(packet instanceof EncodedPacket)) {
        throw new TypeError("packet must be an EncodedPacket.");
      }
      if (packet.isMetadataOnly) {
        throw new TypeError("packet must not be metadata-only to determine its type.");
      }
      if (this.codec === null) {
        return null;
      }
      const decoderConfig = await this.getDecoderConfig();
      assert(decoderConfig);
      return determineVideoPacketType(this.codec, decoderConfig, packet.data);
    }
  };
  var InputAudioTrack = class extends InputTrack {
    /** @internal */
    constructor(input, backing) {
      super(input, backing);
      this._backing = backing;
    }
    get type() {
      return "audio";
    }
    get codec() {
      return this._backing.getCodec();
    }
    /** The number of audio channels in the track. */
    get numberOfChannels() {
      return this._backing.getNumberOfChannels();
    }
    /** The track's audio sample rate in hertz. */
    get sampleRate() {
      return this._backing.getSampleRate();
    }
    /**
     * Returns the [decoder configuration](https://www.w3.org/TR/webcodecs/#audio-decoder-config) for decoding the
     * track's packets using an [`AudioDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/AudioDecoder). Returns
     * null if the track's codec is unknown.
     */
    getDecoderConfig() {
      return this._backing.getDecoderConfig();
    }
    async getCodecParameterString() {
      const decoderConfig = await this._backing.getDecoderConfig();
      return decoderConfig?.codec ?? null;
    }
    async canDecode() {
      try {
        const decoderConfig = await this._backing.getDecoderConfig();
        if (!decoderConfig) {
          return false;
        }
        const codec = this._backing.getCodec();
        assert(codec !== null);
        if (customAudioDecoders.some((x) => x.supports(codec, decoderConfig))) {
          return true;
        }
        if (decoderConfig.codec.startsWith("pcm-")) {
          return true;
        } else {
          if (typeof AudioDecoder === "undefined") {
            return false;
          }
          const support = await AudioDecoder.isConfigSupported(decoderConfig);
          return support.supported === true;
        }
      } catch (error) {
        console.error("Error during decodability check:", error);
        return false;
      }
    }
    async determinePacketType(packet) {
      if (!(packet instanceof EncodedPacket)) {
        throw new TypeError("packet must be an EncodedPacket.");
      }
      if (this.codec === null) {
        return null;
      }
      return "key";
    }
  };

  // src/isobmff/isobmff-misc.ts
  var buildIsobmffMimeType = (info) => {
    const base = info.hasVideo ? "video/" : info.hasAudio ? "audio/" : "application/";
    let string = base + (info.isQuickTime ? "quicktime" : "mp4");
    if (info.codecStrings.length > 0) {
      const uniqueCodecMimeTypes = [...new Set(info.codecStrings)];
      string += `; codecs="${uniqueCodecMimeTypes.join(", ")}"`;
    }
    return string;
  };

  // src/isobmff/isobmff-reader.ts
  var MIN_BOX_HEADER_SIZE = 8;
  var MAX_BOX_HEADER_SIZE = 16;
  var readBoxHeader = (slice) => {
    let totalSize = readU32Be(slice);
    const name = readAscii(slice, 4);
    let headerSize = 8;
    const hasLargeSize = totalSize === 1;
    if (hasLargeSize) {
      totalSize = readU64Be(slice);
      headerSize = 16;
    }
    const contentSize = totalSize - headerSize;
    if (contentSize < 0) {
      return null;
    }
    return { name, totalSize, headerSize, contentSize };
  };
  var readFixed_16_16 = (slice) => {
    return readI32Be(slice) / 65536;
  };
  var readFixed_2_30 = (slice) => {
    return readI32Be(slice) / 1073741824;
  };
  var readIsomVariableInteger = (slice) => {
    let result = 0;
    for (let i = 0; i < 4; i++) {
      result <<= 7;
      const nextByte = readU8(slice);
      result |= nextByte & 127;
      if ((nextByte & 128) === 0) {
        break;
      }
    }
    return result;
  };
  var readMetadataStringShort = (slice) => {
    let stringLength = readU16Be(slice);
    slice.skip(2);
    stringLength = Math.min(stringLength, slice.remainingLength);
    return textDecoder.decode(readBytes(slice, stringLength));
  };
  var readDataBox = (slice) => {
    const header = readBoxHeader(slice);
    if (!header || header.name !== "data") {
      return null;
    }
    if (slice.remainingLength < 8) {
      return null;
    }
    const typeIndicator = readU32Be(slice);
    slice.skip(4);
    const data = readBytes(slice, header.contentSize - 8);
    switch (typeIndicator) {
      case 1:
        return textDecoder.decode(data);
      // UTF-8
      case 2:
        return new TextDecoder("utf-16be").decode(data);
      // UTF-16-BE
      case 13:
        return new RichImageData(data, "image/jpeg");
      case 14:
        return new RichImageData(data, "image/png");
      case 27:
        return new RichImageData(data, "image/bmp");
      default:
        return data;
    }
  };

  // src/isobmff/isobmff-demuxer.ts
  var IsobmffDemuxer = class extends Demuxer {
    constructor(input) {
      super(input);
      this.moovSlice = null;
      this.currentTrack = null;
      this.tracks = [];
      this.metadataPromise = null;
      this.movieTimescale = -1;
      this.movieDurationInTimescale = -1;
      this.isQuickTime = false;
      this.metadataTags = {};
      this.currentMetadataKeys = null;
      this.isFragmented = false;
      this.fragmentTrackDefaults = [];
      this.currentFragment = null;
      /**
       * Caches the last fragment that was read. Based on the assumption that there will be multiple reads to the
       * same fragment in quick succession.
       */
      this.lastReadFragment = null;
      this.reader = input._reader;
    }
    async computeDuration() {
      const tracks = await this.getTracks();
      const trackDurations = await Promise.all(tracks.map((x) => x.computeDuration()));
      return Math.max(0, ...trackDurations);
    }
    async getTracks() {
      await this.readMetadata();
      return this.tracks.map((track) => track.inputTrack);
    }
    async getMimeType() {
      await this.readMetadata();
      const codecStrings = await Promise.all(this.tracks.map((x) => x.inputTrack.getCodecParameterString()));
      return buildIsobmffMimeType({
        isQuickTime: this.isQuickTime,
        hasVideo: this.tracks.some((x) => x.info?.type === "video"),
        hasAudio: this.tracks.some((x) => x.info?.type === "audio"),
        codecStrings: codecStrings.filter(Boolean)
      });
    }
    async getMetadataTags() {
      await this.readMetadata();
      return this.metadataTags;
    }
    readMetadata() {
      return this.metadataPromise ??= (async () => {
        let currentPos = 0;
        while (true) {
          let slice = this.reader.requestSliceRange(currentPos, MIN_BOX_HEADER_SIZE, MAX_BOX_HEADER_SIZE);
          if (slice instanceof Promise) slice = await slice;
          if (!slice) break;
          const startPos = currentPos;
          const boxInfo = readBoxHeader(slice);
          if (!boxInfo) {
            break;
          }
          if (boxInfo.name === "ftyp") {
            const majorBrand = readAscii(slice, 4);
            this.isQuickTime = majorBrand === "qt  ";
          } else if (boxInfo.name === "moov") {
            let moovSlice = this.reader.requestSlice(slice.filePos, boxInfo.contentSize);
            if (moovSlice instanceof Promise) moovSlice = await moovSlice;
            if (!moovSlice) break;
            this.moovSlice = moovSlice;
            this.readContiguousBoxes(this.moovSlice);
            this.tracks.sort((a, b) => Number(b.disposition.default) - Number(a.disposition.default));
            for (const track of this.tracks) {
              const previousSegmentDurationsInSeconds = track.editListPreviousSegmentDurations / this.movieTimescale;
              track.editListOffset -= Math.round(previousSegmentDurationsInSeconds * track.timescale);
            }
            break;
          }
          currentPos = startPos + boxInfo.totalSize;
        }
        if (this.isFragmented && this.reader.fileSize !== null) {
          let lastWordSlice = this.reader.requestSlice(this.reader.fileSize - 4, 4);
          if (lastWordSlice instanceof Promise) lastWordSlice = await lastWordSlice;
          assert(lastWordSlice);
          const lastWord = readU32Be(lastWordSlice);
          const potentialMfraPos = this.reader.fileSize - lastWord;
          if (potentialMfraPos >= 0 && potentialMfraPos <= this.reader.fileSize - MAX_BOX_HEADER_SIZE) {
            let mfraHeaderSlice = this.reader.requestSliceRange(
              potentialMfraPos,
              MIN_BOX_HEADER_SIZE,
              MAX_BOX_HEADER_SIZE
            );
            if (mfraHeaderSlice instanceof Promise) mfraHeaderSlice = await mfraHeaderSlice;
            if (mfraHeaderSlice) {
              const boxInfo = readBoxHeader(mfraHeaderSlice);
              if (boxInfo && boxInfo.name === "mfra") {
                let mfraSlice = this.reader.requestSlice(mfraHeaderSlice.filePos, boxInfo.contentSize);
                if (mfraSlice instanceof Promise) mfraSlice = await mfraSlice;
                if (mfraSlice) {
                  this.readContiguousBoxes(mfraSlice);
                }
              }
            }
          }
        }
      })();
    }
    getSampleTableForTrack(internalTrack) {
      if (internalTrack.sampleTable) {
        return internalTrack.sampleTable;
      }
      const sampleTable = {
        sampleTimingEntries: [],
        sampleCompositionTimeOffsets: [],
        sampleSizes: [],
        keySampleIndices: null,
        chunkOffsets: [],
        sampleToChunk: [],
        presentationTimestamps: null,
        presentationTimestampIndexMap: null
      };
      internalTrack.sampleTable = sampleTable;
      assert(this.moovSlice);
      const stblContainerSlice = this.moovSlice.slice(internalTrack.sampleTableByteOffset);
      this.currentTrack = internalTrack;
      this.traverseBox(stblContainerSlice);
      this.currentTrack = null;
      const isPcmCodec = internalTrack.info?.type === "audio" && internalTrack.info.codec && PCM_AUDIO_CODECS.includes(internalTrack.info.codec);
      if (isPcmCodec && sampleTable.sampleCompositionTimeOffsets.length === 0) {
        assert(internalTrack.info?.type === "audio");
        const pcmInfo = parsePcmCodec(internalTrack.info.codec);
        const newSampleTimingEntries = [];
        const newSampleSizes = [];
        for (let i = 0; i < sampleTable.sampleToChunk.length; i++) {
          const chunkEntry = sampleTable.sampleToChunk[i];
          const nextEntry = sampleTable.sampleToChunk[i + 1];
          const chunkCount = (nextEntry ? nextEntry.startChunkIndex : sampleTable.chunkOffsets.length) - chunkEntry.startChunkIndex;
          for (let j = 0; j < chunkCount; j++) {
            const startSampleIndex = chunkEntry.startSampleIndex + j * chunkEntry.samplesPerChunk;
            const endSampleIndex = startSampleIndex + chunkEntry.samplesPerChunk;
            const startTimingEntryIndex = binarySearchLessOrEqual(
              sampleTable.sampleTimingEntries,
              startSampleIndex,
              (x) => x.startIndex
            );
            const startTimingEntry = sampleTable.sampleTimingEntries[startTimingEntryIndex];
            const endTimingEntryIndex = binarySearchLessOrEqual(
              sampleTable.sampleTimingEntries,
              endSampleIndex,
              (x) => x.startIndex
            );
            const endTimingEntry = sampleTable.sampleTimingEntries[endTimingEntryIndex];
            const firstSampleTimestamp = startTimingEntry.startDecodeTimestamp + (startSampleIndex - startTimingEntry.startIndex) * startTimingEntry.delta;
            const lastSampleTimestamp = endTimingEntry.startDecodeTimestamp + (endSampleIndex - endTimingEntry.startIndex) * endTimingEntry.delta;
            const delta = lastSampleTimestamp - firstSampleTimestamp;
            const lastSampleTimingEntry = last(newSampleTimingEntries);
            if (lastSampleTimingEntry && lastSampleTimingEntry.delta === delta) {
              lastSampleTimingEntry.count++;
            } else {
              newSampleTimingEntries.push({
                startIndex: chunkEntry.startChunkIndex + j,
                startDecodeTimestamp: firstSampleTimestamp,
                count: 1,
                delta
              });
            }
            const chunkSize = chunkEntry.samplesPerChunk * pcmInfo.sampleSize * internalTrack.info.numberOfChannels;
            newSampleSizes.push(chunkSize);
          }
          chunkEntry.startSampleIndex = chunkEntry.startChunkIndex;
          chunkEntry.samplesPerChunk = 1;
        }
        sampleTable.sampleTimingEntries = newSampleTimingEntries;
        sampleTable.sampleSizes = newSampleSizes;
      }
      if (sampleTable.sampleCompositionTimeOffsets.length > 0) {
        sampleTable.presentationTimestamps = [];
        for (const entry of sampleTable.sampleTimingEntries) {
          for (let i = 0; i < entry.count; i++) {
            sampleTable.presentationTimestamps.push({
              presentationTimestamp: entry.startDecodeTimestamp + i * entry.delta,
              sampleIndex: entry.startIndex + i
            });
          }
        }
        for (const entry of sampleTable.sampleCompositionTimeOffsets) {
          for (let i = 0; i < entry.count; i++) {
            const sampleIndex = entry.startIndex + i;
            const sample = sampleTable.presentationTimestamps[sampleIndex];
            if (!sample) {
              continue;
            }
            sample.presentationTimestamp += entry.offset;
          }
        }
        sampleTable.presentationTimestamps.sort((a, b) => a.presentationTimestamp - b.presentationTimestamp);
        sampleTable.presentationTimestampIndexMap = Array(sampleTable.presentationTimestamps.length).fill(-1);
        for (let i = 0; i < sampleTable.presentationTimestamps.length; i++) {
          sampleTable.presentationTimestampIndexMap[sampleTable.presentationTimestamps[i].sampleIndex] = i;
        }
      } else {
      }
      return sampleTable;
    }
    async readFragment(startPos) {
      if (this.lastReadFragment?.moofOffset === startPos) {
        return this.lastReadFragment;
      }
      let headerSlice = this.reader.requestSliceRange(startPos, MIN_BOX_HEADER_SIZE, MAX_BOX_HEADER_SIZE);
      if (headerSlice instanceof Promise) headerSlice = await headerSlice;
      assert(headerSlice);
      const moofBoxInfo = readBoxHeader(headerSlice);
      assert(moofBoxInfo?.name === "moof");
      let entireSlice = this.reader.requestSlice(startPos, moofBoxInfo.totalSize);
      if (entireSlice instanceof Promise) entireSlice = await entireSlice;
      assert(entireSlice);
      this.traverseBox(entireSlice);
      const fragment = this.lastReadFragment;
      assert(fragment && fragment.moofOffset === startPos);
      for (const [, trackData] of fragment.trackData) {
        const track = trackData.track;
        const { fragmentPositionCache } = track;
        if (!trackData.startTimestampIsFinal) {
          const lookupEntry = track.fragmentLookupTable.find((x) => x.moofOffset === fragment.moofOffset);
          if (lookupEntry) {
            offsetFragmentTrackDataByTimestamp(trackData, lookupEntry.timestamp);
          } else {
            const lastCacheIndex = binarySearchLessOrEqual(
              fragmentPositionCache,
              fragment.moofOffset - 1,
              (x) => x.moofOffset
            );
            if (lastCacheIndex !== -1) {
              const lastCache = fragmentPositionCache[lastCacheIndex];
              offsetFragmentTrackDataByTimestamp(trackData, lastCache.endTimestamp);
            } else {
            }
          }
          trackData.startTimestampIsFinal = true;
        }
        const insertionIndex = binarySearchLessOrEqual(
          fragmentPositionCache,
          trackData.startTimestamp,
          (x) => x.startTimestamp
        );
        if (insertionIndex === -1 || fragmentPositionCache[insertionIndex].moofOffset !== fragment.moofOffset) {
          fragmentPositionCache.splice(insertionIndex + 1, 0, {
            moofOffset: fragment.moofOffset,
            startTimestamp: trackData.startTimestamp,
            endTimestamp: trackData.endTimestamp
          });
        }
      }
      return fragment;
    }
    readContiguousBoxes(slice) {
      const startIndex = slice.filePos;
      while (slice.filePos - startIndex <= slice.length - MIN_BOX_HEADER_SIZE) {
        const foundBox = this.traverseBox(slice);
        if (!foundBox) {
          break;
        }
      }
    }
    // eslint-disable-next-line @stylistic/generator-star-spacing
    *iterateContiguousBoxes(slice) {
      const startIndex = slice.filePos;
      while (slice.filePos - startIndex <= slice.length - MIN_BOX_HEADER_SIZE) {
        const startPos = slice.filePos;
        const boxInfo = readBoxHeader(slice);
        if (!boxInfo) {
          break;
        }
        yield { boxInfo, slice };
        slice.filePos = startPos + boxInfo.totalSize;
      }
    }
    traverseBox(slice) {
      const startPos = slice.filePos;
      const boxInfo = readBoxHeader(slice);
      if (!boxInfo) {
        return false;
      }
      const contentStartPos = slice.filePos;
      const boxEndPos = startPos + boxInfo.totalSize;
      switch (boxInfo.name) {
        case "mdia":
        case "minf":
        case "dinf":
        case "mfra":
        case "edts":
          {
            this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
          }
          ;
          break;
        case "mvhd":
          {
            const version = readU8(slice);
            slice.skip(3);
            if (version === 1) {
              slice.skip(8 + 8);
              this.movieTimescale = readU32Be(slice);
              this.movieDurationInTimescale = readU64Be(slice);
            } else {
              slice.skip(4 + 4);
              this.movieTimescale = readU32Be(slice);
              this.movieDurationInTimescale = readU32Be(slice);
            }
          }
          ;
          break;
        case "trak":
          {
            const track = {
              id: -1,
              demuxer: this,
              inputTrack: null,
              disposition: {
                ...DEFAULT_TRACK_DISPOSITION
              },
              info: null,
              timescale: -1,
              durationInMovieTimescale: -1,
              durationInMediaTimescale: -1,
              rotation: 0,
              internalCodecId: null,
              name: null,
              languageCode: UNDETERMINED_LANGUAGE,
              sampleTableByteOffset: -1,
              sampleTable: null,
              fragmentLookupTable: [],
              currentFragmentState: null,
              fragmentPositionCache: [],
              editListPreviousSegmentDurations: 0,
              editListOffset: 0
            };
            this.currentTrack = track;
            this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
            if (track.id !== -1 && track.timescale !== -1 && track.info !== null) {
              if (track.info.type === "video" && track.info.width !== -1) {
                const videoTrack = track;
                track.inputTrack = new InputVideoTrack(this.input, new IsobmffVideoTrackBacking(videoTrack));
                this.tracks.push(track);
              } else if (track.info.type === "audio" && track.info.numberOfChannels !== -1) {
                const audioTrack = track;
                track.inputTrack = new InputAudioTrack(this.input, new IsobmffAudioTrackBacking(audioTrack));
                this.tracks.push(track);
              }
            }
            this.currentTrack = null;
          }
          ;
          break;
        case "tkhd":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            const version = readU8(slice);
            const flags = readU24Be(slice);
            const trackEnabled = !!(flags & 1);
            track.disposition.default = trackEnabled;
            if (version === 0) {
              slice.skip(8);
              track.id = readU32Be(slice);
              slice.skip(4);
              track.durationInMovieTimescale = readU32Be(slice);
            } else if (version === 1) {
              slice.skip(16);
              track.id = readU32Be(slice);
              slice.skip(4);
              track.durationInMovieTimescale = readU64Be(slice);
            } else {
              throw new Error(`Incorrect track header version ${version}.`);
            }
            slice.skip(2 * 4 + 2 + 2 + 2 + 2);
            const matrix = [
              readFixed_16_16(slice),
              readFixed_16_16(slice),
              readFixed_2_30(slice),
              readFixed_16_16(slice),
              readFixed_16_16(slice),
              readFixed_2_30(slice),
              readFixed_16_16(slice),
              readFixed_16_16(slice),
              readFixed_2_30(slice)
            ];
            const rotation = normalizeRotation(roundToMultiple(extractRotationFromMatrix(matrix), 90));
            assert(rotation === 0 || rotation === 90 || rotation === 180 || rotation === 270);
            track.rotation = rotation;
          }
          ;
          break;
        case "elst":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            const version = readU8(slice);
            slice.skip(3);
            let relevantEntryFound = false;
            let previousSegmentDurations = 0;
            const entryCount = readU32Be(slice);
            for (let i = 0; i < entryCount; i++) {
              const segmentDuration = version === 1 ? readU64Be(slice) : readU32Be(slice);
              const mediaTime = version === 1 ? readI64Be(slice) : readI32Be(slice);
              const mediaRate = readFixed_16_16(slice);
              if (segmentDuration === 0) {
                continue;
              }
              if (relevantEntryFound) {
                console.warn(
                  "Unsupported edit list: multiple edits are not currently supported. Only using first edit."
                );
                break;
              }
              if (mediaTime === -1) {
                previousSegmentDurations += segmentDuration;
                continue;
              }
              if (mediaRate !== 1) {
                console.warn("Unsupported edit list entry: media rate must be 1.");
                break;
              }
              track.editListPreviousSegmentDurations = previousSegmentDurations;
              track.editListOffset = mediaTime;
              relevantEntryFound = true;
            }
          }
          ;
          break;
        case "mdhd":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            const version = readU8(slice);
            slice.skip(3);
            if (version === 0) {
              slice.skip(8);
              track.timescale = readU32Be(slice);
              track.durationInMediaTimescale = readU32Be(slice);
            } else if (version === 1) {
              slice.skip(16);
              track.timescale = readU32Be(slice);
              track.durationInMediaTimescale = readU64Be(slice);
            }
            let language = readU16Be(slice);
            if (language > 0) {
              track.languageCode = "";
              for (let i = 0; i < 3; i++) {
                track.languageCode = String.fromCharCode(96 + (language & 31)) + track.languageCode;
                language >>= 5;
              }
              if (!isIso639Dash2LanguageCode(track.languageCode)) {
                track.languageCode = UNDETERMINED_LANGUAGE;
              }
            }
          }
          ;
          break;
        case "hdlr":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            slice.skip(8);
            const handlerType = readAscii(slice, 4);
            if (handlerType === "vide") {
              track.info = {
                type: "video",
                width: -1,
                height: -1,
                codec: null,
                codecDescription: null,
                colorSpace: null,
                avcType: null,
                avcCodecInfo: null,
                hevcCodecInfo: null,
                vp9CodecInfo: null,
                av1CodecInfo: null
              };
            } else if (handlerType === "soun") {
              track.info = {
                type: "audio",
                numberOfChannels: -1,
                sampleRate: -1,
                codec: null,
                codecDescription: null,
                aacCodecInfo: null
              };
            }
          }
          ;
          break;
        case "stbl":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            track.sampleTableByteOffset = startPos;
            this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
          }
          ;
          break;
        case "stsd":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            if (track.info === null || track.sampleTable) {
              break;
            }
            const stsdVersion = readU8(slice);
            slice.skip(3);
            const entries = readU32Be(slice);
            for (let i = 0; i < entries; i++) {
              const sampleBoxStartPos = slice.filePos;
              const sampleBoxInfo = readBoxHeader(slice);
              if (!sampleBoxInfo) {
                break;
              }
              track.internalCodecId = sampleBoxInfo.name;
              const lowercaseBoxName = sampleBoxInfo.name.toLowerCase();
              if (track.info.type === "video") {
                if (lowercaseBoxName === "avc1" || lowercaseBoxName === "avc3") {
                  track.info.codec = "avc";
                  track.info.avcType = lowercaseBoxName === "avc1" ? 1 : 3;
                } else if (lowercaseBoxName === "hvc1" || lowercaseBoxName === "hev1") {
                  track.info.codec = "hevc";
                } else if (lowercaseBoxName === "vp08") {
                  track.info.codec = "vp8";
                } else if (lowercaseBoxName === "vp09") {
                  track.info.codec = "vp9";
                } else if (lowercaseBoxName === "av01") {
                  track.info.codec = "av1";
                } else {
                  console.warn(`Unsupported video codec (sample entry type '${sampleBoxInfo.name}').`);
                }
                slice.skip(6 * 1 + 2 + 2 + 2 + 3 * 4);
                track.info.width = readU16Be(slice);
                track.info.height = readU16Be(slice);
                slice.skip(4 + 4 + 4 + 2 + 32 + 2 + 2);
                this.readContiguousBoxes(
                  slice.slice(
                    slice.filePos,
                    sampleBoxStartPos + sampleBoxInfo.totalSize - slice.filePos
                  )
                );
              } else {
                if (lowercaseBoxName === "mp4a") {
                } else if (lowercaseBoxName === "opus") {
                  track.info.codec = "opus";
                } else if (lowercaseBoxName === "flac") {
                  track.info.codec = "flac";
                } else if (lowercaseBoxName === "twos" || lowercaseBoxName === "sowt" || lowercaseBoxName === "raw " || lowercaseBoxName === "in24" || lowercaseBoxName === "in32" || lowercaseBoxName === "fl32" || lowercaseBoxName === "fl64" || lowercaseBoxName === "lpcm" || lowercaseBoxName === "ipcm" || lowercaseBoxName === "fpcm") {
                } else if (lowercaseBoxName === "ulaw") {
                  track.info.codec = "ulaw";
                } else if (lowercaseBoxName === "alaw") {
                  track.info.codec = "alaw";
                } else if (lowercaseBoxName === "ac-3") {
                  track.info.codec = "ac3";
                } else if (lowercaseBoxName === "ec-3") {
                  track.info.codec = "eac3";
                } else {
                  console.warn(`Unsupported audio codec (sample entry type '${sampleBoxInfo.name}').`);
                }
                slice.skip(6 * 1 + 2);
                const version = readU16Be(slice);
                slice.skip(3 * 2);
                let channelCount = readU16Be(slice);
                let sampleSize = readU16Be(slice);
                slice.skip(2 * 2);
                let sampleRate = readU32Be(slice) / 65536;
                if (stsdVersion === 0 && version > 0) {
                  if (version === 1) {
                    slice.skip(4);
                    sampleSize = 8 * readU32Be(slice);
                    slice.skip(2 * 4);
                  } else if (version === 2) {
                    slice.skip(4);
                    sampleRate = readF64Be(slice);
                    channelCount = readU32Be(slice);
                    slice.skip(4);
                    sampleSize = readU32Be(slice);
                    const flags = readU32Be(slice);
                    slice.skip(2 * 4);
                    if (lowercaseBoxName === "lpcm") {
                      const bytesPerSample = sampleSize + 7 >> 3;
                      const isFloat = Boolean(flags & 1);
                      const isBigEndian = Boolean(flags & 2);
                      const sFlags = flags & 4 ? -1 : 0;
                      if (sampleSize > 0 && sampleSize <= 64) {
                        if (isFloat) {
                          if (sampleSize === 32) {
                            track.info.codec = isBigEndian ? "pcm-f32be" : "pcm-f32";
                          }
                        } else {
                          if (sFlags & 1 << bytesPerSample - 1) {
                            if (bytesPerSample === 1) {
                              track.info.codec = "pcm-s8";
                            } else if (bytesPerSample === 2) {
                              track.info.codec = isBigEndian ? "pcm-s16be" : "pcm-s16";
                            } else if (bytesPerSample === 3) {
                              track.info.codec = isBigEndian ? "pcm-s24be" : "pcm-s24";
                            } else if (bytesPerSample === 4) {
                              track.info.codec = isBigEndian ? "pcm-s32be" : "pcm-s32";
                            }
                          } else {
                            if (bytesPerSample === 1) {
                              track.info.codec = "pcm-u8";
                            }
                          }
                        }
                      }
                      if (track.info.codec === null) {
                        console.warn("Unsupported PCM format.");
                      }
                    }
                  }
                }
                if (track.info.codec === "opus") {
                  sampleRate = OPUS_SAMPLE_RATE;
                }
                track.info.numberOfChannels = channelCount;
                track.info.sampleRate = sampleRate;
                if (lowercaseBoxName === "twos") {
                  if (sampleSize === 8) {
                    track.info.codec = "pcm-s8";
                  } else if (sampleSize === 16) {
                    track.info.codec = "pcm-s16be";
                  } else {
                    console.warn(`Unsupported sample size ${sampleSize} for codec 'twos'.`);
                    track.info.codec = null;
                  }
                } else if (lowercaseBoxName === "sowt") {
                  if (sampleSize === 8) {
                    track.info.codec = "pcm-s8";
                  } else if (sampleSize === 16) {
                    track.info.codec = "pcm-s16";
                  } else {
                    console.warn(`Unsupported sample size ${sampleSize} for codec 'sowt'.`);
                    track.info.codec = null;
                  }
                } else if (lowercaseBoxName === "raw ") {
                  track.info.codec = "pcm-u8";
                } else if (lowercaseBoxName === "in24") {
                  track.info.codec = "pcm-s24be";
                } else if (lowercaseBoxName === "in32") {
                  track.info.codec = "pcm-s32be";
                } else if (lowercaseBoxName === "fl32") {
                  track.info.codec = "pcm-f32be";
                } else if (lowercaseBoxName === "fl64") {
                  track.info.codec = "pcm-f64be";
                } else if (lowercaseBoxName === "ipcm") {
                  track.info.codec = "pcm-s16be";
                } else if (lowercaseBoxName === "fpcm") {
                  track.info.codec = "pcm-f32be";
                }
                this.readContiguousBoxes(
                  slice.slice(
                    slice.filePos,
                    sampleBoxStartPos + sampleBoxInfo.totalSize - slice.filePos
                  )
                );
              }
            }
          }
          ;
          break;
        case "avcC":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            assert(track.info);
            track.info.codecDescription = readBytes(slice, boxInfo.contentSize);
          }
          ;
          break;
        case "hvcC":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            assert(track.info);
            track.info.codecDescription = readBytes(slice, boxInfo.contentSize);
          }
          ;
          break;
        case "vpcC":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            assert(track.info?.type === "video");
            slice.skip(4);
            const profile = readU8(slice);
            const level = readU8(slice);
            const thirdByte = readU8(slice);
            const bitDepth = thirdByte >> 4;
            const chromaSubsampling = thirdByte >> 1 & 7;
            const videoFullRangeFlag = thirdByte & 1;
            const colourPrimaries = readU8(slice);
            const transferCharacteristics = readU8(slice);
            const matrixCoefficients = readU8(slice);
            track.info.vp9CodecInfo = {
              profile,
              level,
              bitDepth,
              chromaSubsampling,
              videoFullRangeFlag,
              colourPrimaries,
              transferCharacteristics,
              matrixCoefficients
            };
          }
          ;
          break;
        case "av1C":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            assert(track.info?.type === "video");
            slice.skip(1);
            const secondByte = readU8(slice);
            const profile = secondByte >> 5;
            const level = secondByte & 31;
            const thirdByte = readU8(slice);
            const tier = thirdByte >> 7;
            const highBitDepth = thirdByte >> 6 & 1;
            const twelveBit = thirdByte >> 5 & 1;
            const monochrome = thirdByte >> 4 & 1;
            const chromaSubsamplingX = thirdByte >> 3 & 1;
            const chromaSubsamplingY = thirdByte >> 2 & 1;
            const chromaSamplePosition = thirdByte & 3;
            const bitDepth = profile === 2 && highBitDepth ? twelveBit ? 12 : 10 : highBitDepth ? 10 : 8;
            track.info.av1CodecInfo = {
              profile,
              level,
              tier,
              bitDepth,
              monochrome,
              chromaSubsamplingX,
              chromaSubsamplingY,
              chromaSamplePosition
            };
          }
          ;
          break;
        case "colr":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            assert(track.info?.type === "video");
            const colourType = readAscii(slice, 4);
            if (colourType !== "nclx") {
              break;
            }
            const colourPrimaries = readU16Be(slice);
            const transferCharacteristics = readU16Be(slice);
            const matrixCoefficients = readU16Be(slice);
            const fullRangeFlag = Boolean(readU8(slice) & 128);
            track.info.colorSpace = {
              primaries: COLOR_PRIMARIES_MAP_INVERSE[colourPrimaries],
              transfer: TRANSFER_CHARACTERISTICS_MAP_INVERSE[transferCharacteristics],
              matrix: MATRIX_COEFFICIENTS_MAP_INVERSE[matrixCoefficients],
              fullRange: fullRangeFlag
            };
          }
          ;
          break;
        case "wave":
          {
            this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
          }
          ;
          break;
        case "esds":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            assert(track.info?.type === "audio");
            slice.skip(4);
            const tag = readU8(slice);
            assert(tag === 3);
            readIsomVariableInteger(slice);
            slice.skip(2);
            const mixed = readU8(slice);
            const streamDependenceFlag = (mixed & 128) !== 0;
            const urlFlag = (mixed & 64) !== 0;
            const ocrStreamFlag = (mixed & 32) !== 0;
            if (streamDependenceFlag) {
              slice.skip(2);
            }
            if (urlFlag) {
              const urlLength = readU8(slice);
              slice.skip(urlLength);
            }
            if (ocrStreamFlag) {
              slice.skip(2);
            }
            const decoderConfigTag = readU8(slice);
            assert(decoderConfigTag === 4);
            const decoderConfigDescriptorLength = readIsomVariableInteger(slice);
            const payloadStart = slice.filePos;
            const objectTypeIndication = readU8(slice);
            if (objectTypeIndication === 64 || objectTypeIndication === 103) {
              track.info.codec = "aac";
              track.info.aacCodecInfo = {
                isMpeg2: objectTypeIndication === 103,
                objectType: null
              };
            } else if (objectTypeIndication === 105 || objectTypeIndication === 107) {
              track.info.codec = "mp3";
            } else if (objectTypeIndication === 221) {
              track.info.codec = "vorbis";
            } else {
              console.warn(
                `Unsupported audio codec (objectTypeIndication ${objectTypeIndication}) - discarding track.`
              );
            }
            slice.skip(1 + 3 + 4 + 4);
            if (decoderConfigDescriptorLength > slice.filePos - payloadStart) {
              const decoderSpecificInfoTag = readU8(slice);
              assert(decoderSpecificInfoTag === 5);
              const decoderSpecificInfoLength = readIsomVariableInteger(slice);
              track.info.codecDescription = readBytes(slice, decoderSpecificInfoLength);
              if (track.info.codec === "aac") {
                const audioSpecificConfig = parseAacAudioSpecificConfig(track.info.codecDescription);
                if (audioSpecificConfig.numberOfChannels !== null) {
                  track.info.numberOfChannels = audioSpecificConfig.numberOfChannels;
                }
                if (audioSpecificConfig.sampleRate !== null) {
                  track.info.sampleRate = audioSpecificConfig.sampleRate;
                }
              }
            }
          }
          ;
          break;
        case "enda":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            assert(track.info?.type === "audio");
            const littleEndian = readU16Be(slice) & 255;
            if (littleEndian) {
              if (track.info.codec === "pcm-s16be") {
                track.info.codec = "pcm-s16";
              } else if (track.info.codec === "pcm-s24be") {
                track.info.codec = "pcm-s24";
              } else if (track.info.codec === "pcm-s32be") {
                track.info.codec = "pcm-s32";
              } else if (track.info.codec === "pcm-f32be") {
                track.info.codec = "pcm-f32";
              } else if (track.info.codec === "pcm-f64be") {
                track.info.codec = "pcm-f64";
              }
            }
          }
          ;
          break;
        case "pcmC":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            assert(track.info?.type === "audio");
            slice.skip(1 + 3);
            const formatFlags = readU8(slice);
            const isLittleEndian = Boolean(formatFlags & 1);
            const pcmSampleSize = readU8(slice);
            if (track.info.codec === "pcm-s16be") {
              if (isLittleEndian) {
                if (pcmSampleSize === 16) {
                  track.info.codec = "pcm-s16";
                } else if (pcmSampleSize === 24) {
                  track.info.codec = "pcm-s24";
                } else if (pcmSampleSize === 32) {
                  track.info.codec = "pcm-s32";
                } else {
                  console.warn(`Invalid ipcm sample size ${pcmSampleSize}.`);
                  track.info.codec = null;
                }
              } else {
                if (pcmSampleSize === 16) {
                  track.info.codec = "pcm-s16be";
                } else if (pcmSampleSize === 24) {
                  track.info.codec = "pcm-s24be";
                } else if (pcmSampleSize === 32) {
                  track.info.codec = "pcm-s32be";
                } else {
                  console.warn(`Invalid ipcm sample size ${pcmSampleSize}.`);
                  track.info.codec = null;
                }
              }
            } else if (track.info.codec === "pcm-f32be") {
              if (isLittleEndian) {
                if (pcmSampleSize === 32) {
                  track.info.codec = "pcm-f32";
                } else if (pcmSampleSize === 64) {
                  track.info.codec = "pcm-f64";
                } else {
                  console.warn(`Invalid fpcm sample size ${pcmSampleSize}.`);
                  track.info.codec = null;
                }
              } else {
                if (pcmSampleSize === 32) {
                  track.info.codec = "pcm-f32be";
                } else if (pcmSampleSize === 64) {
                  track.info.codec = "pcm-f64be";
                } else {
                  console.warn(`Invalid fpcm sample size ${pcmSampleSize}.`);
                  track.info.codec = null;
                }
              }
            }
            break;
          }
          ;
        case "dOps":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            assert(track.info?.type === "audio");
            slice.skip(1);
            const outputChannelCount = readU8(slice);
            const preSkip = readU16Be(slice);
            const inputSampleRate = readU32Be(slice);
            const outputGain = readI16Be(slice);
            const channelMappingFamily = readU8(slice);
            let channelMappingTable;
            if (channelMappingFamily !== 0) {
              channelMappingTable = readBytes(slice, 2 + outputChannelCount);
            } else {
              channelMappingTable = new Uint8Array(0);
            }
            const description = new Uint8Array(8 + 1 + 1 + 2 + 4 + 2 + 1 + channelMappingTable.byteLength);
            const view2 = new DataView(description.buffer);
            view2.setUint32(0, 1332770163, false);
            view2.setUint32(4, 1214603620, false);
            view2.setUint8(8, 1);
            view2.setUint8(9, outputChannelCount);
            view2.setUint16(10, preSkip, true);
            view2.setUint32(12, inputSampleRate, true);
            view2.setInt16(16, outputGain, true);
            view2.setUint8(18, channelMappingFamily);
            description.set(channelMappingTable, 19);
            track.info.codecDescription = description;
            track.info.numberOfChannels = outputChannelCount;
          }
          ;
          break;
        case "dfLa":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            assert(track.info?.type === "audio");
            slice.skip(4);
            const BLOCK_TYPE_MASK = 127;
            const LAST_METADATA_BLOCK_FLAG_MASK = 128;
            const startPos2 = slice.filePos;
            while (slice.filePos < boxEndPos) {
              const flagAndType = readU8(slice);
              const metadataBlockLength = readU24Be(slice);
              const type = flagAndType & BLOCK_TYPE_MASK;
              if (type === 0 /* STREAMINFO */) {
                slice.skip(10);
                const word = readU32Be(slice);
                const sampleRate = word >>> 12;
                const numberOfChannels = (word >> 9 & 7) + 1;
                track.info.sampleRate = sampleRate;
                track.info.numberOfChannels = numberOfChannels;
                slice.skip(20);
              } else {
                slice.skip(metadataBlockLength);
              }
              if (flagAndType & LAST_METADATA_BLOCK_FLAG_MASK) {
                break;
              }
            }
            const endPos = slice.filePos;
            slice.filePos = startPos2;
            const bytes2 = readBytes(slice, endPos - startPos2);
            const description = new Uint8Array(4 + bytes2.byteLength);
            const view2 = new DataView(description.buffer);
            view2.setUint32(0, 1716281667, false);
            description.set(bytes2, 4);
            track.info.codecDescription = description;
          }
          ;
          break;
        case "dac3":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            assert(track.info?.type === "audio");
            const bytes2 = readBytes(slice, 3);
            const bitstream = new Bitstream(bytes2);
            const fscod = bitstream.readBits(2);
            bitstream.skipBits(5 + 3);
            const acmod = bitstream.readBits(3);
            const lfeon = bitstream.readBits(1);
            if (fscod < 3) {
              track.info.sampleRate = AC3_SAMPLE_RATES[fscod];
            }
            track.info.numberOfChannels = AC3_ACMOD_CHANNEL_COUNTS[acmod] + lfeon;
          }
          ;
          break;
        case "dec3":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            assert(track.info?.type === "audio");
            const bytes2 = readBytes(slice, boxInfo.contentSize);
            const config = parseEac3Config(bytes2);
            if (!config) {
              console.warn("Invalid dec3 box contents, ignoring.");
              break;
            }
            const sampleRate = getEac3SampleRate(config);
            if (sampleRate !== null) {
              track.info.sampleRate = sampleRate;
            }
            track.info.numberOfChannels = getEac3ChannelCount(config);
          }
          ;
          break;
        case "stts":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            if (!track.sampleTable) {
              break;
            }
            slice.skip(4);
            const entryCount = readU32Be(slice);
            let currentIndex = 0;
            let currentTimestamp = 0;
            for (let i = 0; i < entryCount; i++) {
              const sampleCount = readU32Be(slice);
              const sampleDelta = readU32Be(slice);
              track.sampleTable.sampleTimingEntries.push({
                startIndex: currentIndex,
                startDecodeTimestamp: currentTimestamp,
                count: sampleCount,
                delta: sampleDelta
              });
              currentIndex += sampleCount;
              currentTimestamp += sampleCount * sampleDelta;
            }
          }
          ;
          break;
        case "ctts":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            if (!track.sampleTable) {
              break;
            }
            slice.skip(1 + 3);
            const entryCount = readU32Be(slice);
            let sampleIndex = 0;
            for (let i = 0; i < entryCount; i++) {
              const sampleCount = readU32Be(slice);
              const sampleOffset = readI32Be(slice);
              track.sampleTable.sampleCompositionTimeOffsets.push({
                startIndex: sampleIndex,
                count: sampleCount,
                offset: sampleOffset
              });
              sampleIndex += sampleCount;
            }
          }
          ;
          break;
        case "stsz":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            if (!track.sampleTable) {
              break;
            }
            slice.skip(4);
            const sampleSize = readU32Be(slice);
            const sampleCount = readU32Be(slice);
            if (sampleSize === 0) {
              for (let i = 0; i < sampleCount; i++) {
                const sampleSize2 = readU32Be(slice);
                track.sampleTable.sampleSizes.push(sampleSize2);
              }
            } else {
              track.sampleTable.sampleSizes.push(sampleSize);
            }
          }
          ;
          break;
        case "stz2":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            if (!track.sampleTable) {
              break;
            }
            slice.skip(4);
            slice.skip(3);
            const fieldSize = readU8(slice);
            const sampleCount = readU32Be(slice);
            const bytes2 = readBytes(slice, Math.ceil(sampleCount * fieldSize / 8));
            const bitstream = new Bitstream(bytes2);
            for (let i = 0; i < sampleCount; i++) {
              const sampleSize = bitstream.readBits(fieldSize);
              track.sampleTable.sampleSizes.push(sampleSize);
            }
          }
          ;
          break;
        case "stss":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            if (!track.sampleTable) {
              break;
            }
            slice.skip(4);
            track.sampleTable.keySampleIndices = [];
            const entryCount = readU32Be(slice);
            for (let i = 0; i < entryCount; i++) {
              const sampleIndex = readU32Be(slice) - 1;
              track.sampleTable.keySampleIndices.push(sampleIndex);
            }
            if (track.sampleTable.keySampleIndices[0] !== 0) {
              track.sampleTable.keySampleIndices.unshift(0);
            }
          }
          ;
          break;
        case "stsc":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            if (!track.sampleTable) {
              break;
            }
            slice.skip(4);
            const entryCount = readU32Be(slice);
            for (let i = 0; i < entryCount; i++) {
              const startChunkIndex = readU32Be(slice) - 1;
              const samplesPerChunk = readU32Be(slice);
              const sampleDescriptionIndex = readU32Be(slice);
              track.sampleTable.sampleToChunk.push({
                startSampleIndex: -1,
                startChunkIndex,
                samplesPerChunk,
                sampleDescriptionIndex
              });
            }
            let startSampleIndex = 0;
            for (let i = 0; i < track.sampleTable.sampleToChunk.length; i++) {
              track.sampleTable.sampleToChunk[i].startSampleIndex = startSampleIndex;
              if (i < track.sampleTable.sampleToChunk.length - 1) {
                const nextChunk = track.sampleTable.sampleToChunk[i + 1];
                const chunkCount = nextChunk.startChunkIndex - track.sampleTable.sampleToChunk[i].startChunkIndex;
                startSampleIndex += chunkCount * track.sampleTable.sampleToChunk[i].samplesPerChunk;
              }
            }
          }
          ;
          break;
        case "stco":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            if (!track.sampleTable) {
              break;
            }
            slice.skip(4);
            const entryCount = readU32Be(slice);
            for (let i = 0; i < entryCount; i++) {
              const chunkOffset = readU32Be(slice);
              track.sampleTable.chunkOffsets.push(chunkOffset);
            }
          }
          ;
          break;
        case "co64":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            if (!track.sampleTable) {
              break;
            }
            slice.skip(4);
            const entryCount = readU32Be(slice);
            for (let i = 0; i < entryCount; i++) {
              const chunkOffset = readU64Be(slice);
              track.sampleTable.chunkOffsets.push(chunkOffset);
            }
          }
          ;
          break;
        case "mvex":
          {
            this.isFragmented = true;
            this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
          }
          ;
          break;
        case "mehd":
          {
            const version = readU8(slice);
            slice.skip(3);
            const fragmentDuration = version === 1 ? readU64Be(slice) : readU32Be(slice);
            this.movieDurationInTimescale = fragmentDuration;
          }
          ;
          break;
        case "trex":
          {
            slice.skip(4);
            const trackId = readU32Be(slice);
            const defaultSampleDescriptionIndex = readU32Be(slice);
            const defaultSampleDuration = readU32Be(slice);
            const defaultSampleSize = readU32Be(slice);
            const defaultSampleFlags = readU32Be(slice);
            this.fragmentTrackDefaults.push({
              trackId,
              defaultSampleDescriptionIndex,
              defaultSampleDuration,
              defaultSampleSize,
              defaultSampleFlags
            });
          }
          ;
          break;
        case "tfra":
          {
            const version = readU8(slice);
            slice.skip(3);
            const trackId = readU32Be(slice);
            const track = this.tracks.find((x) => x.id === trackId);
            if (!track) {
              break;
            }
            const word = readU32Be(slice);
            const lengthSizeOfTrafNum = (word & 48) >> 4;
            const lengthSizeOfTrunNum = (word & 12) >> 2;
            const lengthSizeOfSampleNum = word & 3;
            const functions = [readU8, readU16Be, readU24Be, readU32Be];
            const readTrafNum = functions[lengthSizeOfTrafNum];
            const readTrunNum = functions[lengthSizeOfTrunNum];
            const readSampleNum = functions[lengthSizeOfSampleNum];
            const numberOfEntries = readU32Be(slice);
            for (let i = 0; i < numberOfEntries; i++) {
              const time = version === 1 ? readU64Be(slice) : readU32Be(slice);
              const moofOffset = version === 1 ? readU64Be(slice) : readU32Be(slice);
              readTrafNum(slice);
              readTrunNum(slice);
              readSampleNum(slice);
              track.fragmentLookupTable.push({
                timestamp: time,
                moofOffset
              });
            }
            track.fragmentLookupTable.sort((a, b) => a.timestamp - b.timestamp);
            for (let i = 0; i < track.fragmentLookupTable.length - 1; i++) {
              const entry1 = track.fragmentLookupTable[i];
              const entry2 = track.fragmentLookupTable[i + 1];
              if (entry1.timestamp === entry2.timestamp) {
                track.fragmentLookupTable.splice(i + 1, 1);
                i--;
              }
            }
          }
          ;
          break;
        case "moof":
          {
            this.currentFragment = {
              moofOffset: startPos,
              moofSize: boxInfo.totalSize,
              implicitBaseDataOffset: startPos,
              trackData: /* @__PURE__ */ new Map()
            };
            this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
            this.lastReadFragment = this.currentFragment;
            this.currentFragment = null;
          }
          ;
          break;
        case "traf":
          {
            assert(this.currentFragment);
            this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
            if (this.currentTrack) {
              const trackData = this.currentFragment.trackData.get(this.currentTrack.id);
              if (trackData) {
                const { currentFragmentState } = this.currentTrack;
                assert(currentFragmentState);
                if (currentFragmentState.startTimestamp !== null) {
                  offsetFragmentTrackDataByTimestamp(trackData, currentFragmentState.startTimestamp);
                  trackData.startTimestampIsFinal = true;
                }
              }
              this.currentTrack.currentFragmentState = null;
              this.currentTrack = null;
            }
          }
          ;
          break;
        case "tfhd":
          {
            assert(this.currentFragment);
            slice.skip(1);
            const flags = readU24Be(slice);
            const baseDataOffsetPresent = Boolean(flags & 1);
            const sampleDescriptionIndexPresent = Boolean(flags & 2);
            const defaultSampleDurationPresent = Boolean(flags & 8);
            const defaultSampleSizePresent = Boolean(flags & 16);
            const defaultSampleFlagsPresent = Boolean(flags & 32);
            const durationIsEmpty = Boolean(flags & 65536);
            const defaultBaseIsMoof = Boolean(flags & 131072);
            const trackId = readU32Be(slice);
            const track = this.tracks.find((x) => x.id === trackId);
            if (!track) {
              break;
            }
            const defaults = this.fragmentTrackDefaults.find((x) => x.trackId === trackId);
            this.currentTrack = track;
            track.currentFragmentState = {
              baseDataOffset: this.currentFragment.implicitBaseDataOffset,
              sampleDescriptionIndex: defaults?.defaultSampleDescriptionIndex ?? null,
              defaultSampleDuration: defaults?.defaultSampleDuration ?? null,
              defaultSampleSize: defaults?.defaultSampleSize ?? null,
              defaultSampleFlags: defaults?.defaultSampleFlags ?? null,
              startTimestamp: null
            };
            if (baseDataOffsetPresent) {
              track.currentFragmentState.baseDataOffset = readU64Be(slice);
            } else if (defaultBaseIsMoof) {
              track.currentFragmentState.baseDataOffset = this.currentFragment.moofOffset;
            }
            if (sampleDescriptionIndexPresent) {
              track.currentFragmentState.sampleDescriptionIndex = readU32Be(slice);
            }
            if (defaultSampleDurationPresent) {
              track.currentFragmentState.defaultSampleDuration = readU32Be(slice);
            }
            if (defaultSampleSizePresent) {
              track.currentFragmentState.defaultSampleSize = readU32Be(slice);
            }
            if (defaultSampleFlagsPresent) {
              track.currentFragmentState.defaultSampleFlags = readU32Be(slice);
            }
            if (durationIsEmpty) {
              track.currentFragmentState.defaultSampleDuration = 0;
            }
          }
          ;
          break;
        case "tfdt":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            assert(track.currentFragmentState);
            const version = readU8(slice);
            slice.skip(3);
            const baseMediaDecodeTime = version === 0 ? readU32Be(slice) : readU64Be(slice);
            track.currentFragmentState.startTimestamp = baseMediaDecodeTime;
          }
          ;
          break;
        case "trun":
          {
            const track = this.currentTrack;
            if (!track) {
              break;
            }
            assert(this.currentFragment);
            assert(track.currentFragmentState);
            if (this.currentFragment.trackData.has(track.id)) {
              console.warn("Can't have two trun boxes for the same track in one fragment. Ignoring...");
              break;
            }
            const version = readU8(slice);
            const flags = readU24Be(slice);
            const dataOffsetPresent = Boolean(flags & 1);
            const firstSampleFlagsPresent = Boolean(flags & 4);
            const sampleDurationPresent = Boolean(flags & 256);
            const sampleSizePresent = Boolean(flags & 512);
            const sampleFlagsPresent = Boolean(flags & 1024);
            const sampleCompositionTimeOffsetsPresent = Boolean(flags & 2048);
            const sampleCount = readU32Be(slice);
            let dataOffset = track.currentFragmentState.baseDataOffset;
            if (dataOffsetPresent) {
              dataOffset += readI32Be(slice);
            }
            let firstSampleFlags = null;
            if (firstSampleFlagsPresent) {
              firstSampleFlags = readU32Be(slice);
            }
            let currentOffset = dataOffset;
            if (sampleCount === 0) {
              this.currentFragment.implicitBaseDataOffset = currentOffset;
              break;
            }
            let currentTimestamp = 0;
            const trackData = {
              track,
              startTimestamp: 0,
              endTimestamp: 0,
              firstKeyFrameTimestamp: null,
              samples: [],
              presentationTimestamps: [],
              startTimestampIsFinal: false
            };
            this.currentFragment.trackData.set(track.id, trackData);
            for (let i = 0; i < sampleCount; i++) {
              let sampleDuration;
              if (sampleDurationPresent) {
                sampleDuration = readU32Be(slice);
              } else {
                assert(track.currentFragmentState.defaultSampleDuration !== null);
                sampleDuration = track.currentFragmentState.defaultSampleDuration;
              }
              let sampleSize;
              if (sampleSizePresent) {
                sampleSize = readU32Be(slice);
              } else {
                assert(track.currentFragmentState.defaultSampleSize !== null);
                sampleSize = track.currentFragmentState.defaultSampleSize;
              }
              let sampleFlags;
              if (sampleFlagsPresent) {
                sampleFlags = readU32Be(slice);
              } else {
                assert(track.currentFragmentState.defaultSampleFlags !== null);
                sampleFlags = track.currentFragmentState.defaultSampleFlags;
              }
              if (i === 0 && firstSampleFlags !== null) {
                sampleFlags = firstSampleFlags;
              }
              let sampleCompositionTimeOffset = 0;
              if (sampleCompositionTimeOffsetsPresent) {
                if (version === 0) {
                  sampleCompositionTimeOffset = readU32Be(slice);
                } else {
                  sampleCompositionTimeOffset = readI32Be(slice);
                }
              }
              const isKeyFrame = !(sampleFlags & 65536);
              trackData.samples.push({
                presentationTimestamp: currentTimestamp + sampleCompositionTimeOffset,
                duration: sampleDuration,
                byteOffset: currentOffset,
                byteSize: sampleSize,
                isKeyFrame
              });
              currentOffset += sampleSize;
              currentTimestamp += sampleDuration;
            }
            trackData.presentationTimestamps = trackData.samples.map((x, i) => ({ presentationTimestamp: x.presentationTimestamp, sampleIndex: i })).sort((a, b) => a.presentationTimestamp - b.presentationTimestamp);
            for (let i = 0; i < trackData.presentationTimestamps.length; i++) {
              const currentEntry = trackData.presentationTimestamps[i];
              const currentSample = trackData.samples[currentEntry.sampleIndex];
              if (trackData.firstKeyFrameTimestamp === null && currentSample.isKeyFrame) {
                trackData.firstKeyFrameTimestamp = currentSample.presentationTimestamp;
              }
              if (i < trackData.presentationTimestamps.length - 1) {
                const nextEntry = trackData.presentationTimestamps[i + 1];
                currentSample.duration = nextEntry.presentationTimestamp - currentEntry.presentationTimestamp;
              }
            }
            const firstSample = trackData.samples[trackData.presentationTimestamps[0].sampleIndex];
            const lastSample = trackData.samples[last(trackData.presentationTimestamps).sampleIndex];
            trackData.startTimestamp = firstSample.presentationTimestamp;
            trackData.endTimestamp = lastSample.presentationTimestamp + lastSample.duration;
            this.currentFragment.implicitBaseDataOffset = currentOffset;
          }
          ;
          break;
        // Metadata section
        // https://exiftool.org/TagNames/QuickTime.html
        // https://mp4workshop.com/about
        case "udta":
          {
            const iterator = this.iterateContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
            for (const { boxInfo: boxInfo2, slice: slice2 } of iterator) {
              if (boxInfo2.name !== "meta" && !this.currentTrack) {
                const startPos2 = slice2.filePos;
                this.metadataTags.raw ??= {};
                if (boxInfo2.name[0] === "\xA9") {
                  this.metadataTags.raw[boxInfo2.name] ??= readMetadataStringShort(slice2);
                } else {
                  this.metadataTags.raw[boxInfo2.name] ??= readBytes(slice2, boxInfo2.contentSize);
                }
                slice2.filePos = startPos2;
              }
              switch (boxInfo2.name) {
                case "meta":
                  {
                    slice2.skip(-boxInfo2.headerSize);
                    this.traverseBox(slice2);
                  }
                  ;
                  break;
                case "\xA9nam":
                case "name":
                  {
                    if (this.currentTrack) {
                      this.currentTrack.name = textDecoder.decode(readBytes(slice2, boxInfo2.contentSize));
                    } else {
                      this.metadataTags.title ??= readMetadataStringShort(slice2);
                    }
                  }
                  ;
                  break;
                case "\xA9des":
                  {
                    if (!this.currentTrack) {
                      this.metadataTags.description ??= readMetadataStringShort(slice2);
                    }
                  }
                  ;
                  break;
                case "\xA9ART":
                  {
                    if (!this.currentTrack) {
                      this.metadataTags.artist ??= readMetadataStringShort(slice2);
                    }
                  }
                  ;
                  break;
                case "\xA9alb":
                  {
                    if (!this.currentTrack) {
                      this.metadataTags.album ??= readMetadataStringShort(slice2);
                    }
                  }
                  ;
                  break;
                case "albr":
                  {
                    if (!this.currentTrack) {
                      this.metadataTags.albumArtist ??= readMetadataStringShort(slice2);
                    }
                  }
                  ;
                  break;
                case "\xA9gen":
                  {
                    if (!this.currentTrack) {
                      this.metadataTags.genre ??= readMetadataStringShort(slice2);
                    }
                  }
                  ;
                  break;
                case "\xA9day":
                  {
                    if (!this.currentTrack) {
                      const date = new Date(readMetadataStringShort(slice2));
                      if (!Number.isNaN(date.getTime())) {
                        this.metadataTags.date ??= date;
                      }
                    }
                  }
                  ;
                  break;
                case "\xA9cmt":
                  {
                    if (!this.currentTrack) {
                      this.metadataTags.comment ??= readMetadataStringShort(slice2);
                    }
                  }
                  ;
                  break;
                case "\xA9lyr":
                  {
                    if (!this.currentTrack) {
                      this.metadataTags.lyrics ??= readMetadataStringShort(slice2);
                    }
                  }
                  ;
                  break;
              }
            }
          }
          ;
          break;
        case "meta":
          {
            if (this.currentTrack) {
              break;
            }
            const word = readU32Be(slice);
            const isQuickTime = word !== 0;
            this.currentMetadataKeys = /* @__PURE__ */ new Map();
            if (isQuickTime) {
              this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
            } else {
              this.readContiguousBoxes(slice.slice(contentStartPos + 4, boxInfo.contentSize - 4));
            }
            this.currentMetadataKeys = null;
          }
          ;
          break;
        case "keys":
          {
            if (!this.currentMetadataKeys) {
              break;
            }
            slice.skip(4);
            const entryCount = readU32Be(slice);
            for (let i = 0; i < entryCount; i++) {
              const keySize = readU32Be(slice);
              slice.skip(4);
              const keyName = textDecoder.decode(readBytes(slice, keySize - 8));
              this.currentMetadataKeys.set(i + 1, keyName);
            }
          }
          ;
          break;
        case "ilst":
          {
            if (!this.currentMetadataKeys) {
              break;
            }
            const iterator = this.iterateContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
            for (const { boxInfo: boxInfo2, slice: slice2 } of iterator) {
              let metadataKey = boxInfo2.name;
              const nameAsNumber = (metadataKey.charCodeAt(0) << 24) + (metadataKey.charCodeAt(1) << 16) + (metadataKey.charCodeAt(2) << 8) + metadataKey.charCodeAt(3);
              if (this.currentMetadataKeys.has(nameAsNumber)) {
                metadataKey = this.currentMetadataKeys.get(nameAsNumber);
              }
              const data = readDataBox(slice2);
              this.metadataTags.raw ??= {};
              this.metadataTags.raw[metadataKey] ??= data;
              switch (metadataKey) {
                case "\xA9nam":
                case "titl":
                case "com.apple.quicktime.title":
                case "title":
                  {
                    if (typeof data === "string") {
                      this.metadataTags.title ??= data;
                    }
                  }
                  ;
                  break;
                case "\xA9des":
                case "desc":
                case "dscp":
                case "com.apple.quicktime.description":
                case "description":
                  {
                    if (typeof data === "string") {
                      this.metadataTags.description ??= data;
                    }
                  }
                  ;
                  break;
                case "\xA9ART":
                case "com.apple.quicktime.artist":
                case "artist":
                  {
                    if (typeof data === "string") {
                      this.metadataTags.artist ??= data;
                    }
                  }
                  ;
                  break;
                case "\xA9alb":
                case "albm":
                case "com.apple.quicktime.album":
                case "album":
                  {
                    if (typeof data === "string") {
                      this.metadataTags.album ??= data;
                    }
                  }
                  ;
                  break;
                case "aART":
                case "album_artist":
                  {
                    if (typeof data === "string") {
                      this.metadataTags.albumArtist ??= data;
                    }
                  }
                  ;
                  break;
                case "\xA9cmt":
                case "com.apple.quicktime.comment":
                case "comment":
                  {
                    if (typeof data === "string") {
                      this.metadataTags.comment ??= data;
                    }
                  }
                  ;
                  break;
                case "\xA9gen":
                case "gnre":
                case "com.apple.quicktime.genre":
                case "genre":
                  {
                    if (typeof data === "string") {
                      this.metadataTags.genre ??= data;
                    }
                  }
                  ;
                  break;
                case "\xA9lyr":
                case "lyrics":
                  {
                    if (typeof data === "string") {
                      this.metadataTags.lyrics ??= data;
                    }
                  }
                  ;
                  break;
                case "\xA9day":
                case "rldt":
                case "com.apple.quicktime.creationdate":
                case "date":
                  {
                    if (typeof data === "string") {
                      const date = new Date(data);
                      if (!Number.isNaN(date.getTime())) {
                        this.metadataTags.date ??= date;
                      }
                    }
                  }
                  ;
                  break;
                case "covr":
                case "com.apple.quicktime.artwork":
                  {
                    if (data instanceof RichImageData) {
                      this.metadataTags.images ??= [];
                      this.metadataTags.images.push({
                        data: data.data,
                        kind: "coverFront",
                        mimeType: data.mimeType
                      });
                    } else if (data instanceof Uint8Array) {
                      this.metadataTags.images ??= [];
                      this.metadataTags.images.push({
                        data,
                        kind: "coverFront",
                        mimeType: "image/*"
                      });
                    }
                  }
                  ;
                  break;
                case "track":
                  {
                    if (typeof data === "string") {
                      const parts = data.split("/");
                      const trackNum = Number.parseInt(parts[0], 10);
                      const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);
                      if (Number.isInteger(trackNum) && trackNum > 0) {
                        this.metadataTags.trackNumber ??= trackNum;
                      }
                      if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {
                        this.metadataTags.tracksTotal ??= tracksTotal;
                      }
                    }
                  }
                  ;
                  break;
                case "trkn":
                  {
                    if (data instanceof Uint8Array && data.length >= 6) {
                      const view2 = toDataView(data);
                      const trackNumber = view2.getUint16(2, false);
                      const tracksTotal = view2.getUint16(4, false);
                      if (trackNumber > 0) {
                        this.metadataTags.trackNumber ??= trackNumber;
                      }
                      if (tracksTotal > 0) {
                        this.metadataTags.tracksTotal ??= tracksTotal;
                      }
                    }
                  }
                  ;
                  break;
                case "disc":
                case "disk":
                  {
                    if (data instanceof Uint8Array && data.length >= 6) {
                      const view2 = toDataView(data);
                      const discNumber = view2.getUint16(2, false);
                      const discNumberMax = view2.getUint16(4, false);
                      if (discNumber > 0) {
                        this.metadataTags.discNumber ??= discNumber;
                      }
                      if (discNumberMax > 0) {
                        this.metadataTags.discsTotal ??= discNumberMax;
                      }
                    }
                  }
                  ;
                  break;
              }
            }
          }
          ;
          break;
      }
      slice.filePos = boxEndPos;
      return true;
    }
  };
  var IsobmffTrackBacking = class {
    constructor(internalTrack) {
      this.internalTrack = internalTrack;
      this.packetToSampleIndex = /* @__PURE__ */ new WeakMap();
      this.packetToFragmentLocation = /* @__PURE__ */ new WeakMap();
    }
    getId() {
      return this.internalTrack.id;
    }
    getNumber() {
      const demuxer = this.internalTrack.demuxer;
      const inputTrack = this.internalTrack.inputTrack;
      const trackType = inputTrack.type;
      let number = 0;
      for (const track of demuxer.tracks) {
        if (track.inputTrack.type === trackType) {
          number++;
        }
        if (track === this.internalTrack) {
          break;
        }
      }
      return number;
    }
    getCodec() {
      throw new Error("Not implemented on base class.");
    }
    getInternalCodecId() {
      return this.internalTrack.internalCodecId;
    }
    getName() {
      return this.internalTrack.name;
    }
    getLanguageCode() {
      return this.internalTrack.languageCode;
    }
    getTimeResolution() {
      return this.internalTrack.timescale;
    }
    getDisposition() {
      return this.internalTrack.disposition;
    }
    async computeDuration() {
      const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
      return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    async getFirstTimestamp() {
      const firstPacket = await this.getFirstPacket({ metadataOnly: true });
      return firstPacket?.timestamp ?? 0;
    }
    async getFirstPacket(options) {
      const regularPacket = await this.fetchPacketForSampleIndex(0, options);
      if (regularPacket || !this.internalTrack.demuxer.isFragmented) {
        return regularPacket;
      }
      return this.performFragmentedLookup(
        null,
        (fragment) => {
          const trackData = fragment.trackData.get(this.internalTrack.id);
          if (trackData) {
            return {
              sampleIndex: 0,
              correctSampleFound: true
            };
          }
          return {
            sampleIndex: -1,
            correctSampleFound: false
          };
        },
        -Infinity,
        // Use -Infinity as a search timestamp to avoid using the lookup entries
        Infinity,
        options
      );
    }
    mapTimestampIntoTimescale(timestamp) {
      return roundIfAlmostInteger(timestamp * this.internalTrack.timescale) + this.internalTrack.editListOffset;
    }
    async getPacket(timestamp, options) {
      const timestampInTimescale = this.mapTimestampIntoTimescale(timestamp);
      const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);
      const sampleIndex = getSampleIndexForTimestamp(sampleTable, timestampInTimescale);
      const regularPacket = await this.fetchPacketForSampleIndex(sampleIndex, options);
      if (!sampleTableIsEmpty(sampleTable) || !this.internalTrack.demuxer.isFragmented) {
        return regularPacket;
      }
      return this.performFragmentedLookup(
        null,
        (fragment) => {
          const trackData = fragment.trackData.get(this.internalTrack.id);
          if (!trackData) {
            return { sampleIndex: -1, correctSampleFound: false };
          }
          const index = binarySearchLessOrEqual(
            trackData.presentationTimestamps,
            timestampInTimescale,
            (x) => x.presentationTimestamp
          );
          const sampleIndex2 = index !== -1 ? trackData.presentationTimestamps[index].sampleIndex : -1;
          const correctSampleFound = index !== -1 && timestampInTimescale < trackData.endTimestamp;
          return { sampleIndex: sampleIndex2, correctSampleFound };
        },
        timestampInTimescale,
        timestampInTimescale,
        options
      );
    }
    async getNextPacket(packet, options) {
      const regularSampleIndex = this.packetToSampleIndex.get(packet);
      if (regularSampleIndex !== void 0) {
        return this.fetchPacketForSampleIndex(regularSampleIndex + 1, options);
      }
      const locationInFragment = this.packetToFragmentLocation.get(packet);
      if (locationInFragment === void 0) {
        throw new Error("Packet was not created from this track.");
      }
      return this.performFragmentedLookup(
        locationInFragment.fragment,
        (fragment) => {
          if (fragment === locationInFragment.fragment) {
            const trackData = fragment.trackData.get(this.internalTrack.id);
            if (locationInFragment.sampleIndex + 1 < trackData.samples.length) {
              return {
                sampleIndex: locationInFragment.sampleIndex + 1,
                correctSampleFound: true
              };
            }
          } else {
            const trackData = fragment.trackData.get(this.internalTrack.id);
            if (trackData) {
              return {
                sampleIndex: 0,
                correctSampleFound: true
              };
            }
          }
          return {
            sampleIndex: -1,
            correctSampleFound: false
          };
        },
        -Infinity,
        // Use -Infinity as a search timestamp to avoid using the lookup entries
        Infinity,
        options
      );
    }
    async getKeyPacket(timestamp, options) {
      const timestampInTimescale = this.mapTimestampIntoTimescale(timestamp);
      const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);
      const sampleIndex = getKeyframeSampleIndexForTimestamp(sampleTable, timestampInTimescale);
      const regularPacket = await this.fetchPacketForSampleIndex(sampleIndex, options);
      if (!sampleTableIsEmpty(sampleTable) || !this.internalTrack.demuxer.isFragmented) {
        return regularPacket;
      }
      return this.performFragmentedLookup(
        null,
        (fragment) => {
          const trackData = fragment.trackData.get(this.internalTrack.id);
          if (!trackData) {
            return { sampleIndex: -1, correctSampleFound: false };
          }
          const index = findLastIndex(trackData.presentationTimestamps, (x) => {
            const sample = trackData.samples[x.sampleIndex];
            return sample.isKeyFrame && x.presentationTimestamp <= timestampInTimescale;
          });
          const sampleIndex2 = index !== -1 ? trackData.presentationTimestamps[index].sampleIndex : -1;
          const correctSampleFound = index !== -1 && timestampInTimescale < trackData.endTimestamp;
          return { sampleIndex: sampleIndex2, correctSampleFound };
        },
        timestampInTimescale,
        timestampInTimescale,
        options
      );
    }
    async getNextKeyPacket(packet, options) {
      const regularSampleIndex = this.packetToSampleIndex.get(packet);
      if (regularSampleIndex !== void 0) {
        const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);
        const nextKeyFrameSampleIndex = getNextKeyframeIndexForSample(sampleTable, regularSampleIndex);
        return this.fetchPacketForSampleIndex(nextKeyFrameSampleIndex, options);
      }
      const locationInFragment = this.packetToFragmentLocation.get(packet);
      if (locationInFragment === void 0) {
        throw new Error("Packet was not created from this track.");
      }
      return this.performFragmentedLookup(
        locationInFragment.fragment,
        (fragment) => {
          if (fragment === locationInFragment.fragment) {
            const trackData = fragment.trackData.get(this.internalTrack.id);
            const nextKeyFrameIndex = trackData.samples.findIndex(
              (x, i) => x.isKeyFrame && i > locationInFragment.sampleIndex
            );
            if (nextKeyFrameIndex !== -1) {
              return {
                sampleIndex: nextKeyFrameIndex,
                correctSampleFound: true
              };
            }
          } else {
            const trackData = fragment.trackData.get(this.internalTrack.id);
            if (trackData && trackData.firstKeyFrameTimestamp !== null) {
              const keyFrameIndex = trackData.samples.findIndex((x) => x.isKeyFrame);
              assert(keyFrameIndex !== -1);
              return {
                sampleIndex: keyFrameIndex,
                correctSampleFound: true
              };
            }
          }
          return {
            sampleIndex: -1,
            correctSampleFound: false
          };
        },
        -Infinity,
        // Use -Infinity as a search timestamp to avoid using the lookup entries
        Infinity,
        options
      );
    }
    async fetchPacketForSampleIndex(sampleIndex, options) {
      if (sampleIndex === -1) {
        return null;
      }
      const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);
      const sampleInfo = getSampleInfo(sampleTable, sampleIndex);
      if (!sampleInfo) {
        return null;
      }
      let data;
      if (options.metadataOnly) {
        data = PLACEHOLDER_DATA;
      } else {
        let slice = this.internalTrack.demuxer.reader.requestSlice(
          sampleInfo.sampleOffset,
          sampleInfo.sampleSize
        );
        if (slice instanceof Promise) slice = await slice;
        assert(slice);
        data = readBytes(slice, sampleInfo.sampleSize);
      }
      const timestamp = (sampleInfo.presentationTimestamp - this.internalTrack.editListOffset) / this.internalTrack.timescale;
      const duration = sampleInfo.duration / this.internalTrack.timescale;
      const packet = new EncodedPacket(
        data,
        sampleInfo.isKeyFrame ? "key" : "delta",
        timestamp,
        duration,
        sampleIndex,
        sampleInfo.sampleSize
      );
      this.packetToSampleIndex.set(packet, sampleIndex);
      return packet;
    }
    async fetchPacketInFragment(fragment, sampleIndex, options) {
      if (sampleIndex === -1) {
        return null;
      }
      const trackData = fragment.trackData.get(this.internalTrack.id);
      const fragmentSample = trackData.samples[sampleIndex];
      assert(fragmentSample);
      let data;
      if (options.metadataOnly) {
        data = PLACEHOLDER_DATA;
      } else {
        let slice = this.internalTrack.demuxer.reader.requestSlice(
          fragmentSample.byteOffset,
          fragmentSample.byteSize
        );
        if (slice instanceof Promise) slice = await slice;
        assert(slice);
        data = readBytes(slice, fragmentSample.byteSize);
      }
      const timestamp = (fragmentSample.presentationTimestamp - this.internalTrack.editListOffset) / this.internalTrack.timescale;
      const duration = fragmentSample.duration / this.internalTrack.timescale;
      const packet = new EncodedPacket(
        data,
        fragmentSample.isKeyFrame ? "key" : "delta",
        timestamp,
        duration,
        fragment.moofOffset + sampleIndex,
        fragmentSample.byteSize
      );
      this.packetToFragmentLocation.set(packet, { fragment, sampleIndex });
      return packet;
    }
    /** Looks for a packet in the fragments while trying to load as few fragments as possible to retrieve it. */
    async performFragmentedLookup(startFragment, getMatchInFragment, searchTimestamp, latestTimestamp, options) {
      const demuxer = this.internalTrack.demuxer;
      let currentFragment = null;
      let bestFragment = null;
      let bestSampleIndex = -1;
      if (startFragment) {
        const { sampleIndex, correctSampleFound } = getMatchInFragment(startFragment);
        if (correctSampleFound) {
          return this.fetchPacketInFragment(startFragment, sampleIndex, options);
        }
        if (sampleIndex !== -1) {
          bestFragment = startFragment;
          bestSampleIndex = sampleIndex;
        }
      }
      const lookupEntryIndex = binarySearchLessOrEqual(
        this.internalTrack.fragmentLookupTable,
        searchTimestamp,
        (x) => x.timestamp
      );
      const lookupEntry = lookupEntryIndex !== -1 ? this.internalTrack.fragmentLookupTable[lookupEntryIndex] : null;
      const positionCacheIndex = binarySearchLessOrEqual(
        this.internalTrack.fragmentPositionCache,
        searchTimestamp,
        (x) => x.startTimestamp
      );
      const positionCacheEntry = positionCacheIndex !== -1 ? this.internalTrack.fragmentPositionCache[positionCacheIndex] : null;
      const lookupEntryPosition = Math.max(
        lookupEntry?.moofOffset ?? 0,
        positionCacheEntry?.moofOffset ?? 0
      ) || null;
      let currentPos;
      if (!startFragment) {
        currentPos = lookupEntryPosition ?? 0;
      } else {
        if (lookupEntryPosition === null || startFragment.moofOffset >= lookupEntryPosition) {
          currentPos = startFragment.moofOffset + startFragment.moofSize;
          currentFragment = startFragment;
        } else {
          currentPos = lookupEntryPosition;
        }
      }
      while (true) {
        if (currentFragment) {
          const trackData = currentFragment.trackData.get(this.internalTrack.id);
          if (trackData && trackData.startTimestamp > latestTimestamp) {
            break;
          }
        }
        let slice = demuxer.reader.requestSliceRange(currentPos, MIN_BOX_HEADER_SIZE, MAX_BOX_HEADER_SIZE);
        if (slice instanceof Promise) slice = await slice;
        if (!slice) break;
        const boxStartPos = currentPos;
        const boxInfo = readBoxHeader(slice);
        if (!boxInfo) {
          break;
        }
        if (boxInfo.name === "moof") {
          currentFragment = await demuxer.readFragment(boxStartPos);
          const { sampleIndex, correctSampleFound } = getMatchInFragment(currentFragment);
          if (correctSampleFound) {
            return this.fetchPacketInFragment(currentFragment, sampleIndex, options);
          }
          if (sampleIndex !== -1) {
            bestFragment = currentFragment;
            bestSampleIndex = sampleIndex;
          }
        }
        currentPos = boxStartPos + boxInfo.totalSize;
      }
      if (lookupEntry && (!bestFragment || bestFragment.moofOffset < lookupEntry.moofOffset)) {
        const previousLookupEntry = this.internalTrack.fragmentLookupTable[lookupEntryIndex - 1];
        assert(!previousLookupEntry || previousLookupEntry.timestamp < lookupEntry.timestamp);
        const newSearchTimestamp = previousLookupEntry?.timestamp ?? -Infinity;
        return this.performFragmentedLookup(
          null,
          getMatchInFragment,
          newSearchTimestamp,
          latestTimestamp,
          options
        );
      }
      if (bestFragment) {
        return this.fetchPacketInFragment(bestFragment, bestSampleIndex, options);
      }
      return null;
    }
  };
  var IsobmffVideoTrackBacking = class extends IsobmffTrackBacking {
    constructor(internalTrack) {
      super(internalTrack);
      this.decoderConfigPromise = null;
      this.internalTrack = internalTrack;
    }
    getCodec() {
      return this.internalTrack.info.codec;
    }
    getCodedWidth() {
      return this.internalTrack.info.width;
    }
    getCodedHeight() {
      return this.internalTrack.info.height;
    }
    getRotation() {
      return this.internalTrack.rotation;
    }
    async getColorSpace() {
      return {
        primaries: this.internalTrack.info.colorSpace?.primaries,
        transfer: this.internalTrack.info.colorSpace?.transfer,
        matrix: this.internalTrack.info.colorSpace?.matrix,
        fullRange: this.internalTrack.info.colorSpace?.fullRange
      };
    }
    async canBeTransparent() {
      return false;
    }
    async getDecoderConfig() {
      if (!this.internalTrack.info.codec) {
        return null;
      }
      return this.decoderConfigPromise ??= (async () => {
        if (this.internalTrack.info.codec === "vp9" && !this.internalTrack.info.vp9CodecInfo) {
          const firstPacket = await this.getFirstPacket({});
          this.internalTrack.info.vp9CodecInfo = firstPacket && extractVp9CodecInfoFromPacket(firstPacket.data);
        } else if (this.internalTrack.info.codec === "av1" && !this.internalTrack.info.av1CodecInfo) {
          const firstPacket = await this.getFirstPacket({});
          this.internalTrack.info.av1CodecInfo = firstPacket && extractAv1CodecInfoFromPacket(firstPacket.data);
        }
        return {
          codec: extractVideoCodecString(this.internalTrack.info),
          codedWidth: this.internalTrack.info.width,
          codedHeight: this.internalTrack.info.height,
          description: this.internalTrack.info.codecDescription ?? void 0,
          colorSpace: this.internalTrack.info.colorSpace ?? void 0
        };
      })();
    }
  };
  var IsobmffAudioTrackBacking = class extends IsobmffTrackBacking {
    constructor(internalTrack) {
      super(internalTrack);
      this.decoderConfig = null;
      this.internalTrack = internalTrack;
    }
    getCodec() {
      return this.internalTrack.info.codec;
    }
    getNumberOfChannels() {
      return this.internalTrack.info.numberOfChannels;
    }
    getSampleRate() {
      return this.internalTrack.info.sampleRate;
    }
    async getDecoderConfig() {
      if (!this.internalTrack.info.codec) {
        return null;
      }
      return this.decoderConfig ??= {
        codec: extractAudioCodecString(this.internalTrack.info),
        numberOfChannels: this.internalTrack.info.numberOfChannels,
        sampleRate: this.internalTrack.info.sampleRate,
        description: this.internalTrack.info.codecDescription ?? void 0
      };
    }
  };
  var getSampleIndexForTimestamp = (sampleTable, timescaleUnits) => {
    if (sampleTable.presentationTimestamps) {
      const index = binarySearchLessOrEqual(
        sampleTable.presentationTimestamps,
        timescaleUnits,
        (x) => x.presentationTimestamp
      );
      if (index === -1) {
        return -1;
      }
      return sampleTable.presentationTimestamps[index].sampleIndex;
    } else {
      const index = binarySearchLessOrEqual(
        sampleTable.sampleTimingEntries,
        timescaleUnits,
        (x) => x.startDecodeTimestamp
      );
      if (index === -1) {
        return -1;
      }
      const entry = sampleTable.sampleTimingEntries[index];
      return entry.startIndex + Math.min(
        Math.floor((timescaleUnits - entry.startDecodeTimestamp) / entry.delta),
        entry.count - 1
      );
    }
  };
  var getKeyframeSampleIndexForTimestamp = (sampleTable, timescaleUnits) => {
    if (!sampleTable.keySampleIndices) {
      return getSampleIndexForTimestamp(sampleTable, timescaleUnits);
    }
    if (sampleTable.presentationTimestamps) {
      const index = binarySearchLessOrEqual(
        sampleTable.presentationTimestamps,
        timescaleUnits,
        (x) => x.presentationTimestamp
      );
      if (index === -1) {
        return -1;
      }
      for (let i = index; i >= 0; i--) {
        const sampleIndex = sampleTable.presentationTimestamps[i].sampleIndex;
        const isKeyFrame = binarySearchExact(sampleTable.keySampleIndices, sampleIndex, (x) => x) !== -1;
        if (isKeyFrame) {
          return sampleIndex;
        }
      }
      return -1;
    } else {
      const sampleIndex = getSampleIndexForTimestamp(sampleTable, timescaleUnits);
      const index = binarySearchLessOrEqual(sampleTable.keySampleIndices, sampleIndex, (x) => x);
      return sampleTable.keySampleIndices[index] ?? -1;
    }
  };
  var getSampleInfo = (sampleTable, sampleIndex) => {
    const timingEntryIndex = binarySearchLessOrEqual(sampleTable.sampleTimingEntries, sampleIndex, (x) => x.startIndex);
    const timingEntry = sampleTable.sampleTimingEntries[timingEntryIndex];
    if (!timingEntry || timingEntry.startIndex + timingEntry.count <= sampleIndex) {
      return null;
    }
    const decodeTimestamp = timingEntry.startDecodeTimestamp + (sampleIndex - timingEntry.startIndex) * timingEntry.delta;
    let presentationTimestamp = decodeTimestamp;
    const offsetEntryIndex = binarySearchLessOrEqual(
      sampleTable.sampleCompositionTimeOffsets,
      sampleIndex,
      (x) => x.startIndex
    );
    const offsetEntry = sampleTable.sampleCompositionTimeOffsets[offsetEntryIndex];
    if (offsetEntry && sampleIndex - offsetEntry.startIndex < offsetEntry.count) {
      presentationTimestamp += offsetEntry.offset;
    }
    const sampleSize = sampleTable.sampleSizes[Math.min(sampleIndex, sampleTable.sampleSizes.length - 1)];
    const chunkEntryIndex = binarySearchLessOrEqual(sampleTable.sampleToChunk, sampleIndex, (x) => x.startSampleIndex);
    const chunkEntry = sampleTable.sampleToChunk[chunkEntryIndex];
    assert(chunkEntry);
    const chunkIndex = chunkEntry.startChunkIndex + Math.floor((sampleIndex - chunkEntry.startSampleIndex) / chunkEntry.samplesPerChunk);
    const chunkOffset = sampleTable.chunkOffsets[chunkIndex];
    const startSampleIndexOfChunk = chunkEntry.startSampleIndex + (chunkIndex - chunkEntry.startChunkIndex) * chunkEntry.samplesPerChunk;
    let chunkSize = 0;
    let sampleOffset = chunkOffset;
    if (sampleTable.sampleSizes.length === 1) {
      sampleOffset += sampleSize * (sampleIndex - startSampleIndexOfChunk);
      chunkSize += sampleSize * chunkEntry.samplesPerChunk;
    } else {
      for (let i = startSampleIndexOfChunk; i < startSampleIndexOfChunk + chunkEntry.samplesPerChunk; i++) {
        const sampleSize2 = sampleTable.sampleSizes[i];
        if (i < sampleIndex) {
          sampleOffset += sampleSize2;
        }
        chunkSize += sampleSize2;
      }
    }
    let duration = timingEntry.delta;
    if (sampleTable.presentationTimestamps) {
      const presentationIndex = sampleTable.presentationTimestampIndexMap[sampleIndex];
      assert(presentationIndex !== void 0);
      if (presentationIndex < sampleTable.presentationTimestamps.length - 1) {
        const nextEntry = sampleTable.presentationTimestamps[presentationIndex + 1];
        const nextPresentationTimestamp = nextEntry.presentationTimestamp;
        duration = nextPresentationTimestamp - presentationTimestamp;
      }
    }
    return {
      presentationTimestamp,
      duration,
      sampleOffset,
      sampleSize,
      chunkOffset,
      chunkSize,
      isKeyFrame: sampleTable.keySampleIndices ? binarySearchExact(sampleTable.keySampleIndices, sampleIndex, (x) => x) !== -1 : true
    };
  };
  var getNextKeyframeIndexForSample = (sampleTable, sampleIndex) => {
    if (!sampleTable.keySampleIndices) {
      return sampleIndex + 1;
    }
    const index = binarySearchLessOrEqual(sampleTable.keySampleIndices, sampleIndex, (x) => x);
    return sampleTable.keySampleIndices[index + 1] ?? -1;
  };
  var offsetFragmentTrackDataByTimestamp = (trackData, timestamp) => {
    trackData.startTimestamp += timestamp;
    trackData.endTimestamp += timestamp;
    for (const sample of trackData.samples) {
      sample.presentationTimestamp += timestamp;
    }
    for (const entry of trackData.presentationTimestamps) {
      entry.presentationTimestamp += timestamp;
    }
  };
  var extractRotationFromMatrix = (matrix) => {
    const [m11, , , m21] = matrix;
    const scaleX = Math.hypot(m11, m21);
    const cosTheta = m11 / scaleX;
    const sinTheta = m21 / scaleX;
    const result = -Math.atan2(sinTheta, cosTheta) * (180 / Math.PI);
    if (!Number.isFinite(result)) {
      return 0;
    }
    return result;
  };
  var sampleTableIsEmpty = (sampleTable) => {
    return sampleTable.sampleSizes.length === 0;
  };

  // src/matroska/ebml.ts
  var EBMLFloat32 = class {
    constructor(value) {
      this.value = value;
    }
  };
  var EBMLFloat64 = class {
    constructor(value) {
      this.value = value;
    }
  };
  var EBMLSignedInt = class {
    constructor(value) {
      this.value = value;
    }
  };
  var EBMLUnicodeString = class {
    constructor(value) {
      this.value = value;
    }
  };
  var LEVEL_0_EBML_IDS = [
    440786851 /* EBML */,
    408125543 /* Segment */
  ];
  var LEVEL_1_EBML_IDS = [
    290298740 /* SeekHead */,
    357149030 /* Info */,
    524531317 /* Cluster */,
    374648427 /* Tracks */,
    475249515 /* Cues */,
    423732329 /* Attachments */,
    272869232 /* Chapters */,
    307544935 /* Tags */
  ];
  var LEVEL_0_AND_1_EBML_IDS = [
    ...LEVEL_0_EBML_IDS,
    ...LEVEL_1_EBML_IDS
  ];
  var measureUnsignedInt = (value) => {
    if (value < 1 << 8) {
      return 1;
    } else if (value < 1 << 16) {
      return 2;
    } else if (value < 1 << 24) {
      return 3;
    } else if (value < 2 ** 32) {
      return 4;
    } else if (value < 2 ** 40) {
      return 5;
    } else {
      return 6;
    }
  };
  var measureUnsignedBigInt = (value) => {
    if (value < 1n << 8n) {
      return 1;
    } else if (value < 1n << 16n) {
      return 2;
    } else if (value < 1n << 24n) {
      return 3;
    } else if (value < 1n << 32n) {
      return 4;
    } else if (value < 1n << 40n) {
      return 5;
    } else if (value < 1n << 48n) {
      return 6;
    } else if (value < 1n << 56n) {
      return 7;
    } else {
      return 8;
    }
  };
  var measureSignedInt = (value) => {
    if (value >= -(1 << 6) && value < 1 << 6) {
      return 1;
    } else if (value >= -(1 << 13) && value < 1 << 13) {
      return 2;
    } else if (value >= -(1 << 20) && value < 1 << 20) {
      return 3;
    } else if (value >= -(1 << 27) && value < 1 << 27) {
      return 4;
    } else if (value >= -(2 ** 34) && value < 2 ** 34) {
      return 5;
    } else {
      return 6;
    }
  };
  var measureVarInt = (value) => {
    if (value < (1 << 7) - 1) {
      return 1;
    } else if (value < (1 << 14) - 1) {
      return 2;
    } else if (value < (1 << 21) - 1) {
      return 3;
    } else if (value < (1 << 28) - 1) {
      return 4;
    } else if (value < 2 ** 35 - 1) {
      return 5;
    } else if (value < 2 ** 42 - 1) {
      return 6;
    } else {
      throw new Error("EBML varint size not supported " + value);
    }
  };
  var EBMLWriter = class {
    constructor(writer) {
      this.writer = writer;
      this.helper = new Uint8Array(8);
      this.helperView = new DataView(this.helper.buffer);
      /**
       * Stores the position from the start of the file to where EBML elements have been written. This is used to
       * rewrite/edit elements that were already added before, and to measure sizes of things.
       */
      this.offsets = /* @__PURE__ */ new WeakMap();
      /** Same as offsets, but stores position where the element's data starts (after ID and size fields). */
      this.dataOffsets = /* @__PURE__ */ new WeakMap();
    }
    writeByte(value) {
      this.helperView.setUint8(0, value);
      this.writer.write(this.helper.subarray(0, 1));
    }
    writeFloat32(value) {
      this.helperView.setFloat32(0, value, false);
      this.writer.write(this.helper.subarray(0, 4));
    }
    writeFloat64(value) {
      this.helperView.setFloat64(0, value, false);
      this.writer.write(this.helper);
    }
    writeUnsignedInt(value, width = measureUnsignedInt(value)) {
      let pos = 0;
      switch (width) {
        case 6:
          this.helperView.setUint8(pos++, value / 2 ** 40 | 0);
        // eslint-disable-next-line no-fallthrough
        case 5:
          this.helperView.setUint8(pos++, value / 2 ** 32 | 0);
        // eslint-disable-next-line no-fallthrough
        case 4:
          this.helperView.setUint8(pos++, value >> 24);
        // eslint-disable-next-line no-fallthrough
        case 3:
          this.helperView.setUint8(pos++, value >> 16);
        // eslint-disable-next-line no-fallthrough
        case 2:
          this.helperView.setUint8(pos++, value >> 8);
        // eslint-disable-next-line no-fallthrough
        case 1:
          this.helperView.setUint8(pos++, value);
          break;
        default:
          throw new Error("Bad unsigned int size " + width);
      }
      this.writer.write(this.helper.subarray(0, pos));
    }
    writeUnsignedBigInt(value, width = measureUnsignedBigInt(value)) {
      let pos = 0;
      for (let i = width - 1; i >= 0; i--) {
        this.helperView.setUint8(pos++, Number(value >> BigInt(i * 8) & 0xffn));
      }
      this.writer.write(this.helper.subarray(0, pos));
    }
    writeSignedInt(value, width = measureSignedInt(value)) {
      if (value < 0) {
        value += 2 ** (width * 8);
      }
      this.writeUnsignedInt(value, width);
    }
    writeVarInt(value, width = measureVarInt(value)) {
      let pos = 0;
      switch (width) {
        case 1:
          this.helperView.setUint8(pos++, 1 << 7 | value);
          break;
        case 2:
          this.helperView.setUint8(pos++, 1 << 6 | value >> 8);
          this.helperView.setUint8(pos++, value);
          break;
        case 3:
          this.helperView.setUint8(pos++, 1 << 5 | value >> 16);
          this.helperView.setUint8(pos++, value >> 8);
          this.helperView.setUint8(pos++, value);
          break;
        case 4:
          this.helperView.setUint8(pos++, 1 << 4 | value >> 24);
          this.helperView.setUint8(pos++, value >> 16);
          this.helperView.setUint8(pos++, value >> 8);
          this.helperView.setUint8(pos++, value);
          break;
        case 5:
          this.helperView.setUint8(pos++, 1 << 3 | value / 2 ** 32 & 7);
          this.helperView.setUint8(pos++, value >> 24);
          this.helperView.setUint8(pos++, value >> 16);
          this.helperView.setUint8(pos++, value >> 8);
          this.helperView.setUint8(pos++, value);
          break;
        case 6:
          this.helperView.setUint8(pos++, 1 << 2 | value / 2 ** 40 & 3);
          this.helperView.setUint8(pos++, value / 2 ** 32 | 0);
          this.helperView.setUint8(pos++, value >> 24);
          this.helperView.setUint8(pos++, value >> 16);
          this.helperView.setUint8(pos++, value >> 8);
          this.helperView.setUint8(pos++, value);
          break;
        default:
          throw new Error("Bad EBML varint size " + width);
      }
      this.writer.write(this.helper.subarray(0, pos));
    }
    writeAsciiString(str) {
      this.writer.write(new Uint8Array(str.split("").map((x) => x.charCodeAt(0))));
    }
    writeEBML(data) {
      if (data === null) return;
      if (data instanceof Uint8Array) {
        this.writer.write(data);
      } else if (Array.isArray(data)) {
        for (const elem of data) {
          this.writeEBML(elem);
        }
      } else {
        this.offsets.set(data, this.writer.getPos());
        this.writeUnsignedInt(data.id);
        if (Array.isArray(data.data)) {
          const sizePos = this.writer.getPos();
          const sizeSize = data.size === -1 ? 1 : data.size ?? 4;
          if (data.size === -1) {
            this.writeByte(255);
          } else {
            this.writer.seek(this.writer.getPos() + sizeSize);
          }
          const startPos = this.writer.getPos();
          this.dataOffsets.set(data, startPos);
          this.writeEBML(data.data);
          if (data.size !== -1) {
            const size = this.writer.getPos() - startPos;
            const endPos = this.writer.getPos();
            this.writer.seek(sizePos);
            this.writeVarInt(size, sizeSize);
            this.writer.seek(endPos);
          }
        } else if (typeof data.data === "number") {
          const size = data.size ?? measureUnsignedInt(data.data);
          this.writeVarInt(size);
          this.writeUnsignedInt(data.data, size);
        } else if (typeof data.data === "bigint") {
          const size = data.size ?? measureUnsignedBigInt(data.data);
          this.writeVarInt(size);
          this.writeUnsignedBigInt(data.data, size);
        } else if (typeof data.data === "string") {
          this.writeVarInt(data.data.length);
          this.writeAsciiString(data.data);
        } else if (data.data instanceof Uint8Array) {
          this.writeVarInt(data.data.byteLength, data.size);
          this.writer.write(data.data);
        } else if (data.data instanceof EBMLFloat32) {
          this.writeVarInt(4);
          this.writeFloat32(data.data.value);
        } else if (data.data instanceof EBMLFloat64) {
          this.writeVarInt(8);
          this.writeFloat64(data.data.value);
        } else if (data.data instanceof EBMLSignedInt) {
          const size = data.size ?? measureSignedInt(data.data.value);
          this.writeVarInt(size);
          this.writeSignedInt(data.data.value, size);
        } else if (data.data instanceof EBMLUnicodeString) {
          const bytes2 = textEncoder.encode(data.data.value);
          this.writeVarInt(bytes2.length);
          this.writer.write(bytes2);
        } else {
          assertNever(data.data);
        }
      }
    }
  };
  var MAX_VAR_INT_SIZE = 8;
  var MIN_HEADER_SIZE = 2;
  var MAX_HEADER_SIZE = 2 * MAX_VAR_INT_SIZE;
  var readVarIntSize = (slice) => {
    if (slice.remainingLength < 1) {
      return null;
    }
    const firstByte = readU8(slice);
    slice.skip(-1);
    if (firstByte === 0) {
      return null;
    }
    let width = 1;
    let mask = 128;
    while ((firstByte & mask) === 0) {
      width++;
      mask >>= 1;
    }
    if (slice.remainingLength < width) {
      return null;
    }
    return width;
  };
  var readVarInt = (slice) => {
    if (slice.remainingLength < 1) {
      return null;
    }
    const firstByte = readU8(slice);
    if (firstByte === 0) {
      return null;
    }
    let width = 1;
    let mask = 1 << 7;
    while ((firstByte & mask) === 0) {
      width++;
      mask >>= 1;
    }
    if (slice.remainingLength < width - 1) {
      return null;
    }
    let value = firstByte & mask - 1;
    for (let i = 1; i < width; i++) {
      value *= 1 << 8;
      value += readU8(slice);
    }
    return value;
  };
  var readUnsignedInt = (slice, width) => {
    if (width < 1 || width > 8) {
      throw new Error("Bad unsigned int size " + width);
    }
    let value = 0;
    for (let i = 0; i < width; i++) {
      value *= 1 << 8;
      value += readU8(slice);
    }
    return value;
  };
  var readUnsignedBigInt = (slice, width) => {
    if (width < 1) {
      throw new Error("Bad unsigned int size " + width);
    }
    let value = 0n;
    for (let i = 0; i < width; i++) {
      value <<= 8n;
      value += BigInt(readU8(slice));
    }
    return value;
  };
  var readElementId = (slice) => {
    const size = readVarIntSize(slice);
    if (size === null) {
      return null;
    }
    if (slice.remainingLength < size) {
      return null;
    }
    const id = readUnsignedInt(slice, size);
    return id;
  };
  var readElementSize = (slice) => {
    if (slice.remainingLength < 1) {
      return null;
    }
    const firstByte = readU8(slice);
    if (firstByte === 255) {
      return void 0;
    }
    slice.skip(-1);
    const size = readVarInt(slice);
    if (size === null) {
      return null;
    }
    if (size === 72057594037927940) {
      return void 0;
    }
    return size;
  };
  var readElementHeader = (slice) => {
    assert(slice.remainingLength >= MIN_HEADER_SIZE);
    const id = readElementId(slice);
    if (id === null) {
      return null;
    }
    const size = readElementSize(slice);
    if (size === null) {
      return null;
    }
    return { id, size };
  };
  var readAsciiString = (slice, length) => {
    const bytes2 = readBytes(slice, length);
    let strLength = 0;
    while (strLength < length && bytes2[strLength] !== 0) {
      strLength += 1;
    }
    return String.fromCharCode(...bytes2.subarray(0, strLength));
  };
  var readUnicodeString = (slice, length) => {
    const bytes2 = readBytes(slice, length);
    let strLength = 0;
    while (strLength < length && bytes2[strLength] !== 0) {
      strLength += 1;
    }
    return textDecoder.decode(bytes2.subarray(0, strLength));
  };
  var readFloat = (slice, width) => {
    if (width === 0) {
      return 0;
    }
    if (width !== 4 && width !== 8) {
      throw new Error("Bad float size " + width);
    }
    return width === 4 ? readF32Be(slice) : readF64Be(slice);
  };
  var searchForNextElementId = async (reader, startPos, ids, until) => {
    const idsSet = new Set(ids);
    let currentPos = startPos;
    while (until === null || currentPos < until) {
      let slice = reader.requestSliceRange(currentPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
      if (slice instanceof Promise) slice = await slice;
      if (!slice) break;
      const elementHeader = readElementHeader(slice);
      if (!elementHeader) {
        break;
      }
      if (idsSet.has(elementHeader.id)) {
        return { pos: currentPos, found: true };
      }
      assertDefinedSize(elementHeader.size);
      currentPos = slice.filePos + elementHeader.size;
    }
    return { pos: until !== null && until > currentPos ? until : currentPos, found: false };
  };
  var resync = async (reader, startPos, ids, until) => {
    const CHUNK_SIZE = 2 ** 16;
    const idsSet = new Set(ids);
    let currentPos = startPos;
    while (currentPos < until) {
      let slice = reader.requestSliceRange(currentPos, 0, Math.min(CHUNK_SIZE, until - currentPos));
      if (slice instanceof Promise) slice = await slice;
      if (!slice) break;
      if (slice.length < MAX_VAR_INT_SIZE) break;
      for (let i = 0; i < slice.length - MAX_VAR_INT_SIZE; i++) {
        slice.filePos = currentPos;
        const elementId = readElementId(slice);
        if (elementId !== null && idsSet.has(elementId)) {
          return currentPos;
        }
        currentPos++;
      }
    }
    return null;
  };
  var CODEC_STRING_MAP = {
    "avc": "V_MPEG4/ISO/AVC",
    "hevc": "V_MPEGH/ISO/HEVC",
    "vp8": "V_VP8",
    "vp9": "V_VP9",
    "av1": "V_AV1",
    "aac": "A_AAC",
    "mp3": "A_MPEG/L3",
    "opus": "A_OPUS",
    "vorbis": "A_VORBIS",
    "flac": "A_FLAC",
    "ac3": "A_AC3",
    "eac3": "A_EAC3",
    "pcm-u8": "A_PCM/INT/LIT",
    "pcm-s16": "A_PCM/INT/LIT",
    "pcm-s16be": "A_PCM/INT/BIG",
    "pcm-s24": "A_PCM/INT/LIT",
    "pcm-s24be": "A_PCM/INT/BIG",
    "pcm-s32": "A_PCM/INT/LIT",
    "pcm-s32be": "A_PCM/INT/BIG",
    "pcm-f32": "A_PCM/FLOAT/IEEE",
    "pcm-f64": "A_PCM/FLOAT/IEEE",
    "webvtt": "S_TEXT/WEBVTT"
  };
  function assertDefinedSize(size) {
    if (size === void 0) {
      throw new Error("Undefined element size is used in a place where it is not supported.");
    }
  }

  // src/matroska/matroska-misc.ts
  var buildMatroskaMimeType = (info) => {
    const base = info.hasVideo ? "video/" : info.hasAudio ? "audio/" : "application/";
    let string = base + (info.isWebM ? "webm" : "x-matroska");
    if (info.codecStrings.length > 0) {
      const uniqueCodecMimeTypes = [...new Set(info.codecStrings.filter(Boolean))];
      string += `; codecs="${uniqueCodecMimeTypes.join(", ")}"`;
    }
    return string;
  };

  // src/matroska/matroska-demuxer.ts
  var METADATA_ELEMENTS = [
    { id: 290298740 /* SeekHead */, flag: "seekHeadSeen" },
    { id: 357149030 /* Info */, flag: "infoSeen" },
    { id: 374648427 /* Tracks */, flag: "tracksSeen" },
    { id: 475249515 /* Cues */, flag: "cuesSeen" }
  ];
  var MAX_RESYNC_LENGTH = 10 * 2 ** 20;
  var MatroskaDemuxer = class extends Demuxer {
    constructor(input) {
      super(input);
      this.readMetadataPromise = null;
      this.segments = [];
      this.currentSegment = null;
      this.currentTrack = null;
      this.currentCluster = null;
      this.currentBlock = null;
      this.currentBlockAdditional = null;
      this.currentCueTime = null;
      this.currentDecodingInstruction = null;
      this.currentTagTargetIsMovie = true;
      this.currentSimpleTagName = null;
      this.currentAttachedFile = null;
      this.isWebM = false;
      this.reader = input._reader;
    }
    async computeDuration() {
      const tracks = await this.getTracks();
      const trackDurations = await Promise.all(tracks.map((x) => x.computeDuration()));
      return Math.max(0, ...trackDurations);
    }
    async getTracks() {
      await this.readMetadata();
      return this.segments.flatMap((segment) => segment.tracks.map((track) => track.inputTrack));
    }
    async getMimeType() {
      await this.readMetadata();
      const tracks = await this.getTracks();
      const codecStrings = await Promise.all(tracks.map((x) => x.getCodecParameterString()));
      return buildMatroskaMimeType({
        isWebM: this.isWebM,
        hasVideo: this.segments.some((segment) => segment.tracks.some((x) => x.info?.type === "video")),
        hasAudio: this.segments.some((segment) => segment.tracks.some((x) => x.info?.type === "audio")),
        codecStrings: codecStrings.filter(Boolean)
      });
    }
    async getMetadataTags() {
      await this.readMetadata();
      for (const segment of this.segments) {
        if (!segment.metadataTagsCollected) {
          if (this.reader.fileSize !== null) {
            await this.loadSegmentMetadata(segment);
          } else {
          }
          segment.metadataTagsCollected = true;
        }
      }
      let metadataTags = {};
      for (const segment of this.segments) {
        metadataTags = { ...metadataTags, ...segment.metadataTags };
      }
      return metadataTags;
    }
    readMetadata() {
      return this.readMetadataPromise ??= (async () => {
        let currentPos = 0;
        while (true) {
          let slice = this.reader.requestSliceRange(currentPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
          if (slice instanceof Promise) slice = await slice;
          if (!slice) break;
          const header = readElementHeader(slice);
          if (!header) {
            break;
          }
          const id = header.id;
          let size = header.size;
          const dataStartPos = slice.filePos;
          if (id === 440786851 /* EBML */) {
            assertDefinedSize(size);
            let slice2 = this.reader.requestSlice(dataStartPos, size);
            if (slice2 instanceof Promise) slice2 = await slice2;
            if (!slice2) break;
            this.readContiguousElements(slice2);
          } else if (id === 408125543 /* Segment */) {
            await this.readSegment(dataStartPos, size);
            if (size === void 0) {
              break;
            }
            if (this.reader.fileSize === null) {
              break;
            }
          } else if (id === 524531317 /* Cluster */) {
            if (this.reader.fileSize === null) {
              break;
            }
            if (size === void 0) {
              const nextElementPos = await searchForNextElementId(
                this.reader,
                dataStartPos,
                LEVEL_0_AND_1_EBML_IDS,
                this.reader.fileSize
              );
              size = nextElementPos.pos - dataStartPos;
            }
            const lastSegment = last(this.segments);
            if (lastSegment) {
              lastSegment.elementEndPos = dataStartPos + size;
            }
          }
          assertDefinedSize(size);
          currentPos = dataStartPos + size;
        }
      })();
    }
    async readSegment(segmentDataStart, dataSize) {
      this.currentSegment = {
        seekHeadSeen: false,
        infoSeen: false,
        tracksSeen: false,
        cuesSeen: false,
        tagsSeen: false,
        attachmentsSeen: false,
        timestampScale: -1,
        timestampFactor: -1,
        duration: -1,
        seekEntries: [],
        tracks: [],
        cuePoints: [],
        dataStartPos: segmentDataStart,
        elementEndPos: dataSize === void 0 ? null : segmentDataStart + dataSize,
        clusterSeekStartPos: segmentDataStart,
        lastReadCluster: null,
        metadataTags: {},
        metadataTagsCollected: false
      };
      this.segments.push(this.currentSegment);
      let currentPos = segmentDataStart;
      while (this.currentSegment.elementEndPos === null || currentPos < this.currentSegment.elementEndPos) {
        let slice = this.reader.requestSliceRange(currentPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
        if (slice instanceof Promise) slice = await slice;
        if (!slice) break;
        const elementStartPos = currentPos;
        const header = readElementHeader(slice);
        if (!header || !LEVEL_1_EBML_IDS.includes(header.id) && header.id !== 236 /* Void */) {
          const nextPos = await resync(
            this.reader,
            elementStartPos,
            LEVEL_1_EBML_IDS,
            Math.min(this.currentSegment.elementEndPos ?? Infinity, elementStartPos + MAX_RESYNC_LENGTH)
          );
          if (nextPos) {
            currentPos = nextPos;
            continue;
          } else {
            break;
          }
        }
        const { id, size } = header;
        const dataStartPos = slice.filePos;
        const metadataElementIndex = METADATA_ELEMENTS.findIndex((x) => x.id === id);
        if (metadataElementIndex !== -1) {
          const field = METADATA_ELEMENTS[metadataElementIndex].flag;
          this.currentSegment[field] = true;
          assertDefinedSize(size);
          let slice2 = this.reader.requestSlice(dataStartPos, size);
          if (slice2 instanceof Promise) slice2 = await slice2;
          if (slice2) {
            this.readContiguousElements(slice2);
          }
        } else if (id === 307544935 /* Tags */ || id === 423732329 /* Attachments */) {
          if (id === 307544935 /* Tags */) {
            this.currentSegment.tagsSeen = true;
          } else {
            this.currentSegment.attachmentsSeen = true;
          }
          assertDefinedSize(size);
          let slice2 = this.reader.requestSlice(dataStartPos, size);
          if (slice2 instanceof Promise) slice2 = await slice2;
          if (slice2) {
            this.readContiguousElements(slice2);
          }
        } else if (id === 524531317 /* Cluster */) {
          this.currentSegment.clusterSeekStartPos = elementStartPos;
          break;
        }
        if (size === void 0) {
          break;
        } else {
          currentPos = dataStartPos + size;
        }
      }
      this.currentSegment.seekEntries.sort((a, b) => a.segmentPosition - b.segmentPosition);
      if (this.reader.fileSize !== null) {
        for (const seekEntry of this.currentSegment.seekEntries) {
          const target = METADATA_ELEMENTS.find((x) => x.id === seekEntry.id);
          if (!target) {
            continue;
          }
          if (this.currentSegment[target.flag]) continue;
          let slice = this.reader.requestSliceRange(
            segmentDataStart + seekEntry.segmentPosition,
            MIN_HEADER_SIZE,
            MAX_HEADER_SIZE
          );
          if (slice instanceof Promise) slice = await slice;
          if (!slice) continue;
          const header = readElementHeader(slice);
          if (!header) continue;
          const { id, size } = header;
          if (id !== target.id) continue;
          assertDefinedSize(size);
          this.currentSegment[target.flag] = true;
          let dataSlice = this.reader.requestSlice(slice.filePos, size);
          if (dataSlice instanceof Promise) dataSlice = await dataSlice;
          if (!dataSlice) continue;
          this.readContiguousElements(dataSlice);
        }
      }
      if (this.currentSegment.timestampScale === -1) {
        this.currentSegment.timestampScale = 1e6;
        this.currentSegment.timestampFactor = 1e9 / 1e6;
      }
      for (const track of this.currentSegment.tracks) {
        if (track.defaultDurationNs !== null) {
          track.defaultDuration = this.currentSegment.timestampFactor * track.defaultDurationNs / 1e9;
        }
      }
      this.currentSegment.tracks.sort((a, b) => Number(b.disposition.default) - Number(a.disposition.default));
      const idToTrack = new Map(this.currentSegment.tracks.map((x) => [x.id, x]));
      for (const cuePoint of this.currentSegment.cuePoints) {
        const track = idToTrack.get(cuePoint.trackId);
        if (track) {
          track.cuePoints.push(cuePoint);
        }
      }
      for (const track of this.currentSegment.tracks) {
        track.cuePoints.sort((a, b) => a.time - b.time);
        for (let i = 0; i < track.cuePoints.length - 1; i++) {
          const cuePoint1 = track.cuePoints[i];
          const cuePoint2 = track.cuePoints[i + 1];
          if (cuePoint1.time === cuePoint2.time) {
            track.cuePoints.splice(i + 1, 1);
            i--;
          }
        }
      }
      let trackWithMostCuePoints = null;
      let maxCuePointCount = -Infinity;
      for (const track of this.currentSegment.tracks) {
        if (track.cuePoints.length > maxCuePointCount) {
          maxCuePointCount = track.cuePoints.length;
          trackWithMostCuePoints = track;
        }
      }
      for (const track of this.currentSegment.tracks) {
        if (track.cuePoints.length === 0) {
          track.cuePoints = trackWithMostCuePoints.cuePoints;
        }
      }
      this.currentSegment = null;
    }
    async readCluster(startPos, segment) {
      if (segment.lastReadCluster?.elementStartPos === startPos) {
        return segment.lastReadCluster;
      }
      let headerSlice = this.reader.requestSliceRange(startPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
      if (headerSlice instanceof Promise) headerSlice = await headerSlice;
      assert(headerSlice);
      const elementStartPos = startPos;
      const elementHeader = readElementHeader(headerSlice);
      assert(elementHeader);
      const id = elementHeader.id;
      assert(id === 524531317 /* Cluster */);
      let size = elementHeader.size;
      const dataStartPos = headerSlice.filePos;
      if (size === void 0) {
        const nextElementPos = await searchForNextElementId(
          this.reader,
          dataStartPos,
          LEVEL_0_AND_1_EBML_IDS,
          segment.elementEndPos
        );
        size = nextElementPos.pos - dataStartPos;
      }
      let dataSlice = this.reader.requestSlice(dataStartPos, size);
      if (dataSlice instanceof Promise) dataSlice = await dataSlice;
      const cluster = {
        segment,
        elementStartPos,
        elementEndPos: dataStartPos + size,
        dataStartPos,
        timestamp: -1,
        trackData: /* @__PURE__ */ new Map()
      };
      this.currentCluster = cluster;
      if (dataSlice) {
        const endPos = this.readContiguousElements(dataSlice, LEVEL_0_AND_1_EBML_IDS);
        cluster.elementEndPos = endPos;
      }
      for (const [, trackData] of cluster.trackData) {
        const track = trackData.track;
        assert(trackData.blocks.length > 0);
        let hasLacedBlocks = false;
        for (let i = 0; i < trackData.blocks.length; i++) {
          const block = trackData.blocks[i];
          block.timestamp += cluster.timestamp;
          hasLacedBlocks ||= block.lacing !== 0 /* None */;
        }
        trackData.presentationTimestamps = trackData.blocks.map((block, i) => ({ timestamp: block.timestamp, blockIndex: i })).sort((a, b) => a.timestamp - b.timestamp);
        for (let i = 0; i < trackData.presentationTimestamps.length; i++) {
          const currentEntry = trackData.presentationTimestamps[i];
          const currentBlock = trackData.blocks[currentEntry.blockIndex];
          if (trackData.firstKeyFrameTimestamp === null && currentBlock.isKeyFrame) {
            trackData.firstKeyFrameTimestamp = currentBlock.timestamp;
          }
          if (i < trackData.presentationTimestamps.length - 1) {
            const nextEntry = trackData.presentationTimestamps[i + 1];
            currentBlock.duration = nextEntry.timestamp - currentBlock.timestamp;
          } else if (currentBlock.duration === 0) {
            if (track.defaultDuration != null) {
              if (currentBlock.lacing === 0 /* None */) {
                currentBlock.duration = track.defaultDuration;
              } else {
              }
            }
          }
        }
        if (hasLacedBlocks) {
          this.expandLacedBlocks(trackData.blocks, track);
          trackData.presentationTimestamps = trackData.blocks.map((block, i) => ({ timestamp: block.timestamp, blockIndex: i })).sort((a, b) => a.timestamp - b.timestamp);
        }
        const firstBlock = trackData.blocks[trackData.presentationTimestamps[0].blockIndex];
        const lastBlock = trackData.blocks[last(trackData.presentationTimestamps).blockIndex];
        trackData.startTimestamp = firstBlock.timestamp;
        trackData.endTimestamp = lastBlock.timestamp + lastBlock.duration;
        const insertionIndex = binarySearchLessOrEqual(
          track.clusterPositionCache,
          trackData.startTimestamp,
          (x) => x.startTimestamp
        );
        if (insertionIndex === -1 || track.clusterPositionCache[insertionIndex].elementStartPos !== elementStartPos) {
          track.clusterPositionCache.splice(insertionIndex + 1, 0, {
            elementStartPos: cluster.elementStartPos,
            startTimestamp: trackData.startTimestamp
          });
        }
      }
      segment.lastReadCluster = cluster;
      return cluster;
    }
    getTrackDataInCluster(cluster, trackNumber) {
      let trackData = cluster.trackData.get(trackNumber);
      if (!trackData) {
        const track = cluster.segment.tracks.find((x) => x.id === trackNumber);
        if (!track) {
          return null;
        }
        trackData = {
          track,
          startTimestamp: 0,
          endTimestamp: 0,
          firstKeyFrameTimestamp: null,
          blocks: [],
          presentationTimestamps: []
        };
        cluster.trackData.set(trackNumber, trackData);
      }
      return trackData;
    }
    expandLacedBlocks(blocks, track) {
      for (let blockIndex = 0; blockIndex < blocks.length; blockIndex++) {
        const originalBlock = blocks[blockIndex];
        if (originalBlock.lacing === 0 /* None */) {
          continue;
        }
        if (!originalBlock.decoded) {
          originalBlock.data = this.decodeBlockData(track, originalBlock.data);
          originalBlock.decoded = true;
        }
        const slice = FileSlice4.tempFromBytes(originalBlock.data);
        const frameSizes = [];
        const frameCount = readU8(slice) + 1;
        switch (originalBlock.lacing) {
          case 1 /* Xiph */:
            {
              let totalUsedSize = 0;
              for (let i = 0; i < frameCount - 1; i++) {
                let frameSize = 0;
                while (slice.bufferPos < slice.length) {
                  const value = readU8(slice);
                  frameSize += value;
                  if (value < 255) {
                    frameSizes.push(frameSize);
                    totalUsedSize += frameSize;
                    break;
                  }
                }
              }
              frameSizes.push(slice.length - (slice.bufferPos + totalUsedSize));
            }
            ;
            break;
          case 2 /* FixedSize */:
            {
              const totalDataSize = slice.length - 1;
              const frameSize = Math.floor(totalDataSize / frameCount);
              for (let i = 0; i < frameCount; i++) {
                frameSizes.push(frameSize);
              }
            }
            ;
            break;
          case 3 /* Ebml */:
            {
              const firstResult = readVarInt(slice);
              assert(firstResult !== null);
              let currentSize = firstResult;
              frameSizes.push(currentSize);
              let totalUsedSize = currentSize;
              for (let i = 1; i < frameCount - 1; i++) {
                const startPos = slice.bufferPos;
                const diffResult = readVarInt(slice);
                assert(diffResult !== null);
                const unsignedDiff = diffResult;
                const width = slice.bufferPos - startPos;
                const bias = (1 << width * 7 - 1) - 1;
                const diff = unsignedDiff - bias;
                currentSize += diff;
                frameSizes.push(currentSize);
                totalUsedSize += currentSize;
              }
              frameSizes.push(slice.length - (slice.bufferPos + totalUsedSize));
            }
            ;
            break;
          default:
            assert(false);
        }
        assert(frameSizes.length === frameCount);
        blocks.splice(blockIndex, 1);
        const blockDuration = originalBlock.duration || frameCount * (track.defaultDuration ?? 0);
        for (let i = 0; i < frameCount; i++) {
          const frameSize = frameSizes[i];
          const frameData = readBytes(slice, frameSize);
          const frameTimestamp = originalBlock.timestamp + blockDuration * i / frameCount;
          const frameDuration = blockDuration / frameCount;
          blocks.splice(blockIndex + i, 0, {
            timestamp: frameTimestamp,
            duration: frameDuration,
            isKeyFrame: originalBlock.isKeyFrame,
            data: frameData,
            lacing: 0 /* None */,
            decoded: true,
            mainAdditional: originalBlock.mainAdditional
          });
        }
        blockIndex += frameCount;
        blockIndex--;
      }
    }
    async loadSegmentMetadata(segment) {
      for (const seekEntry of segment.seekEntries) {
        if (seekEntry.id === 307544935 /* Tags */ && !segment.tagsSeen) {
        } else if (seekEntry.id === 423732329 /* Attachments */ && !segment.attachmentsSeen) {
        } else {
          continue;
        }
        let slice = this.reader.requestSliceRange(
          segment.dataStartPos + seekEntry.segmentPosition,
          MIN_HEADER_SIZE,
          MAX_HEADER_SIZE
        );
        if (slice instanceof Promise) slice = await slice;
        if (!slice) continue;
        const header = readElementHeader(slice);
        if (!header || header.id !== seekEntry.id) continue;
        const { size } = header;
        assertDefinedSize(size);
        assert(!this.currentSegment);
        this.currentSegment = segment;
        let dataSlice = this.reader.requestSlice(slice.filePos, size);
        if (dataSlice instanceof Promise) dataSlice = await dataSlice;
        if (dataSlice) {
          this.readContiguousElements(dataSlice);
        }
        this.currentSegment = null;
        if (seekEntry.id === 307544935 /* Tags */) {
          segment.tagsSeen = true;
        } else if (seekEntry.id === 423732329 /* Attachments */) {
          segment.attachmentsSeen = true;
        }
      }
    }
    readContiguousElements(slice, stopIds) {
      while (slice.remainingLength >= MIN_HEADER_SIZE) {
        const startPos = slice.filePos;
        const foundElement = this.traverseElement(slice, stopIds);
        if (!foundElement) {
          return startPos;
        }
      }
      return slice.filePos;
    }
    traverseElement(slice, stopIds) {
      const header = readElementHeader(slice);
      if (!header) {
        return false;
      }
      if (stopIds && stopIds.includes(header.id)) {
        return false;
      }
      const { id, size } = header;
      const dataStartPos = slice.filePos;
      assertDefinedSize(size);
      switch (id) {
        case 17026 /* DocType */:
          {
            this.isWebM = readAsciiString(slice, size) === "webm";
          }
          ;
          break;
        case 19899 /* Seek */:
          {
            if (!this.currentSegment) break;
            const seekEntry = { id: -1, segmentPosition: -1 };
            this.currentSegment.seekEntries.push(seekEntry);
            this.readContiguousElements(slice.slice(dataStartPos, size));
            if (seekEntry.id === -1 || seekEntry.segmentPosition === -1) {
              this.currentSegment.seekEntries.pop();
            }
          }
          ;
          break;
        case 21419 /* SeekID */:
          {
            const lastSeekEntry = this.currentSegment?.seekEntries[this.currentSegment.seekEntries.length - 1];
            if (!lastSeekEntry) break;
            lastSeekEntry.id = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 21420 /* SeekPosition */:
          {
            const lastSeekEntry = this.currentSegment?.seekEntries[this.currentSegment.seekEntries.length - 1];
            if (!lastSeekEntry) break;
            lastSeekEntry.segmentPosition = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 2807729 /* TimestampScale */:
          {
            if (!this.currentSegment) break;
            this.currentSegment.timestampScale = readUnsignedInt(slice, size);
            this.currentSegment.timestampFactor = 1e9 / this.currentSegment.timestampScale;
          }
          ;
          break;
        case 17545 /* Duration */:
          {
            if (!this.currentSegment) break;
            this.currentSegment.duration = readFloat(slice, size);
          }
          ;
          break;
        case 174 /* TrackEntry */:
          {
            if (!this.currentSegment) break;
            this.currentTrack = {
              id: -1,
              segment: this.currentSegment,
              demuxer: this,
              clusterPositionCache: [],
              cuePoints: [],
              disposition: {
                ...DEFAULT_TRACK_DISPOSITION
              },
              inputTrack: null,
              codecId: null,
              codecPrivate: null,
              defaultDuration: null,
              defaultDurationNs: null,
              name: null,
              languageCode: UNDETERMINED_LANGUAGE,
              decodingInstructions: [],
              info: null
            };
            this.readContiguousElements(slice.slice(dataStartPos, size));
            if (!this.currentTrack) {
              break;
            }
            if (this.currentTrack.decodingInstructions.some((instruction) => {
              return instruction.data?.type !== "decompress" || instruction.scope !== 1 /* Block */ || instruction.data.algorithm !== 3 /* HeaderStripping */;
            })) {
              console.warn(`Track #${this.currentTrack.id} has an unsupported content encoding; dropping.`);
              this.currentTrack = null;
            }
            if (this.currentTrack && this.currentTrack.id !== -1 && this.currentTrack.codecId && this.currentTrack.info) {
              const slashIndex = this.currentTrack.codecId.indexOf("/");
              const codecIdWithoutSuffix = slashIndex === -1 ? this.currentTrack.codecId : this.currentTrack.codecId.slice(0, slashIndex);
              if (this.currentTrack.info.type === "video" && this.currentTrack.info.width !== -1 && this.currentTrack.info.height !== -1) {
                if (this.currentTrack.codecId === CODEC_STRING_MAP.avc) {
                  this.currentTrack.info.codec = "avc";
                  this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                } else if (this.currentTrack.codecId === CODEC_STRING_MAP.hevc) {
                  this.currentTrack.info.codec = "hevc";
                  this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                } else if (codecIdWithoutSuffix === CODEC_STRING_MAP.vp8) {
                  this.currentTrack.info.codec = "vp8";
                } else if (codecIdWithoutSuffix === CODEC_STRING_MAP.vp9) {
                  this.currentTrack.info.codec = "vp9";
                } else if (codecIdWithoutSuffix === CODEC_STRING_MAP.av1) {
                  this.currentTrack.info.codec = "av1";
                }
                const videoTrack = this.currentTrack;
                const inputTrack = new InputVideoTrack(this.input, new MatroskaVideoTrackBacking(videoTrack));
                this.currentTrack.inputTrack = inputTrack;
                this.currentSegment.tracks.push(this.currentTrack);
              } else if (this.currentTrack.info.type === "audio" && this.currentTrack.info.numberOfChannels !== -1 && this.currentTrack.info.sampleRate !== -1) {
                if (codecIdWithoutSuffix === CODEC_STRING_MAP.aac) {
                  this.currentTrack.info.codec = "aac";
                  this.currentTrack.info.aacCodecInfo = {
                    isMpeg2: this.currentTrack.codecId.includes("MPEG2"),
                    objectType: null
                  };
                  this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                } else if (this.currentTrack.codecId === CODEC_STRING_MAP.mp3) {
                  this.currentTrack.info.codec = "mp3";
                } else if (codecIdWithoutSuffix === CODEC_STRING_MAP.opus) {
                  this.currentTrack.info.codec = "opus";
                  this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                  this.currentTrack.info.sampleRate = OPUS_SAMPLE_RATE;
                } else if (codecIdWithoutSuffix === CODEC_STRING_MAP.vorbis) {
                  this.currentTrack.info.codec = "vorbis";
                  this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                } else if (codecIdWithoutSuffix === CODEC_STRING_MAP.flac) {
                  this.currentTrack.info.codec = "flac";
                  this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                } else if (codecIdWithoutSuffix === CODEC_STRING_MAP.ac3) {
                  this.currentTrack.info.codec = "ac3";
                  this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                } else if (codecIdWithoutSuffix === CODEC_STRING_MAP.eac3) {
                  this.currentTrack.info.codec = "eac3";
                  this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                } else if (this.currentTrack.codecId === "A_PCM/INT/LIT") {
                  if (this.currentTrack.info.bitDepth === 8) {
                    this.currentTrack.info.codec = "pcm-u8";
                  } else if (this.currentTrack.info.bitDepth === 16) {
                    this.currentTrack.info.codec = "pcm-s16";
                  } else if (this.currentTrack.info.bitDepth === 24) {
                    this.currentTrack.info.codec = "pcm-s24";
                  } else if (this.currentTrack.info.bitDepth === 32) {
                    this.currentTrack.info.codec = "pcm-s32";
                  }
                } else if (this.currentTrack.codecId === "A_PCM/INT/BIG") {
                  if (this.currentTrack.info.bitDepth === 8) {
                    this.currentTrack.info.codec = "pcm-u8";
                  } else if (this.currentTrack.info.bitDepth === 16) {
                    this.currentTrack.info.codec = "pcm-s16be";
                  } else if (this.currentTrack.info.bitDepth === 24) {
                    this.currentTrack.info.codec = "pcm-s24be";
                  } else if (this.currentTrack.info.bitDepth === 32) {
                    this.currentTrack.info.codec = "pcm-s32be";
                  }
                } else if (this.currentTrack.codecId === "A_PCM/FLOAT/IEEE") {
                  if (this.currentTrack.info.bitDepth === 32) {
                    this.currentTrack.info.codec = "pcm-f32";
                  } else if (this.currentTrack.info.bitDepth === 64) {
                    this.currentTrack.info.codec = "pcm-f64";
                  }
                }
                const audioTrack = this.currentTrack;
                const inputTrack = new InputAudioTrack(this.input, new MatroskaAudioTrackBacking(audioTrack));
                this.currentTrack.inputTrack = inputTrack;
                this.currentSegment.tracks.push(this.currentTrack);
              }
            }
            this.currentTrack = null;
          }
          ;
          break;
        case 215 /* TrackNumber */:
          {
            if (!this.currentTrack) break;
            this.currentTrack.id = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 131 /* TrackType */:
          {
            if (!this.currentTrack) break;
            const type = readUnsignedInt(slice, size);
            if (type === 1) {
              this.currentTrack.info = {
                type: "video",
                width: -1,
                height: -1,
                rotation: 0,
                codec: null,
                codecDescription: null,
                colorSpace: null,
                alphaMode: false
              };
            } else if (type === 2) {
              this.currentTrack.info = {
                type: "audio",
                numberOfChannels: -1,
                sampleRate: -1,
                bitDepth: -1,
                codec: null,
                codecDescription: null,
                aacCodecInfo: null
              };
            }
          }
          ;
          break;
        case 185 /* FlagEnabled */:
          {
            if (!this.currentTrack) break;
            const enabled = readUnsignedInt(slice, size);
            if (!enabled) {
              this.currentTrack = null;
            }
          }
          ;
          break;
        case 136 /* FlagDefault */:
          {
            if (!this.currentTrack) break;
            this.currentTrack.disposition.default = !!readUnsignedInt(slice, size);
          }
          ;
          break;
        case 21930 /* FlagForced */:
          {
            if (!this.currentTrack) break;
            this.currentTrack.disposition.forced = !!readUnsignedInt(slice, size);
          }
          ;
          break;
        case 21934 /* FlagOriginal */:
          {
            if (!this.currentTrack) break;
            this.currentTrack.disposition.original = !!readUnsignedInt(slice, size);
          }
          ;
          break;
        case 21931 /* FlagHearingImpaired */:
          {
            if (!this.currentTrack) break;
            this.currentTrack.disposition.hearingImpaired = !!readUnsignedInt(slice, size);
          }
          ;
          break;
        case 21932 /* FlagVisualImpaired */:
          {
            if (!this.currentTrack) break;
            this.currentTrack.disposition.visuallyImpaired = !!readUnsignedInt(slice, size);
          }
          ;
          break;
        case 21935 /* FlagCommentary */:
          {
            if (!this.currentTrack) break;
            this.currentTrack.disposition.commentary = !!readUnsignedInt(slice, size);
          }
          ;
          break;
        case 134 /* CodecID */:
          {
            if (!this.currentTrack) break;
            this.currentTrack.codecId = readAsciiString(slice, size);
          }
          ;
          break;
        case 25506 /* CodecPrivate */:
          {
            if (!this.currentTrack) break;
            this.currentTrack.codecPrivate = readBytes(slice, size);
          }
          ;
          break;
        case 2352003 /* DefaultDuration */:
          {
            if (!this.currentTrack) break;
            this.currentTrack.defaultDurationNs = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 21358 /* Name */:
          {
            if (!this.currentTrack) break;
            this.currentTrack.name = readUnicodeString(slice, size);
          }
          ;
          break;
        case 2274716 /* Language */:
          {
            if (!this.currentTrack) break;
            if (this.currentTrack.languageCode !== UNDETERMINED_LANGUAGE) {
              break;
            }
            this.currentTrack.languageCode = readAsciiString(slice, size);
            if (!isIso639Dash2LanguageCode(this.currentTrack.languageCode)) {
              this.currentTrack.languageCode = UNDETERMINED_LANGUAGE;
            }
          }
          ;
          break;
        case 2274717 /* LanguageBCP47 */:
          {
            if (!this.currentTrack) break;
            const bcp47 = readAsciiString(slice, size);
            const languageSubtag = bcp47.split("-")[0];
            if (languageSubtag) {
              this.currentTrack.languageCode = languageSubtag;
            } else {
              this.currentTrack.languageCode = UNDETERMINED_LANGUAGE;
            }
          }
          ;
          break;
        case 224 /* Video */:
          {
            if (this.currentTrack?.info?.type !== "video") break;
            this.readContiguousElements(slice.slice(dataStartPos, size));
          }
          ;
          break;
        case 176 /* PixelWidth */:
          {
            if (this.currentTrack?.info?.type !== "video") break;
            this.currentTrack.info.width = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 186 /* PixelHeight */:
          {
            if (this.currentTrack?.info?.type !== "video") break;
            this.currentTrack.info.height = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 21440 /* AlphaMode */:
          {
            if (this.currentTrack?.info?.type !== "video") break;
            this.currentTrack.info.alphaMode = readUnsignedInt(slice, size) === 1;
          }
          ;
          break;
        case 21936 /* Colour */:
          {
            if (this.currentTrack?.info?.type !== "video") break;
            this.currentTrack.info.colorSpace = {};
            this.readContiguousElements(slice.slice(dataStartPos, size));
          }
          ;
          break;
        case 21937 /* MatrixCoefficients */:
          {
            if (this.currentTrack?.info?.type !== "video" || !this.currentTrack.info.colorSpace) break;
            const matrixCoefficients = readUnsignedInt(slice, size);
            const mapped = MATRIX_COEFFICIENTS_MAP_INVERSE[matrixCoefficients] ?? null;
            this.currentTrack.info.colorSpace.matrix = mapped;
          }
          ;
          break;
        case 21945 /* Range */:
          {
            if (this.currentTrack?.info?.type !== "video" || !this.currentTrack.info.colorSpace) break;
            this.currentTrack.info.colorSpace.fullRange = readUnsignedInt(slice, size) === 2;
          }
          ;
          break;
        case 21946 /* TransferCharacteristics */:
          {
            if (this.currentTrack?.info?.type !== "video" || !this.currentTrack.info.colorSpace) break;
            const transferCharacteristics = readUnsignedInt(slice, size);
            const mapped = TRANSFER_CHARACTERISTICS_MAP_INVERSE[transferCharacteristics] ?? null;
            this.currentTrack.info.colorSpace.transfer = mapped;
          }
          ;
          break;
        case 21947 /* Primaries */:
          {
            if (this.currentTrack?.info?.type !== "video" || !this.currentTrack.info.colorSpace) break;
            const primaries = readUnsignedInt(slice, size);
            const mapped = COLOR_PRIMARIES_MAP_INVERSE[primaries] ?? null;
            this.currentTrack.info.colorSpace.primaries = mapped;
          }
          ;
          break;
        case 30320 /* Projection */:
          {
            if (this.currentTrack?.info?.type !== "video") break;
            this.readContiguousElements(slice.slice(dataStartPos, size));
          }
          ;
          break;
        case 30325 /* ProjectionPoseRoll */:
          {
            if (this.currentTrack?.info?.type !== "video") break;
            const rotation = readFloat(slice, size);
            const flippedRotation = -rotation;
            try {
              this.currentTrack.info.rotation = normalizeRotation(flippedRotation);
            } catch {
            }
          }
          ;
          break;
        case 225 /* Audio */:
          {
            if (this.currentTrack?.info?.type !== "audio") break;
            this.readContiguousElements(slice.slice(dataStartPos, size));
          }
          ;
          break;
        case 181 /* SamplingFrequency */:
          {
            if (this.currentTrack?.info?.type !== "audio") break;
            this.currentTrack.info.sampleRate = readFloat(slice, size);
          }
          ;
          break;
        case 159 /* Channels */:
          {
            if (this.currentTrack?.info?.type !== "audio") break;
            this.currentTrack.info.numberOfChannels = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 25188 /* BitDepth */:
          {
            if (this.currentTrack?.info?.type !== "audio") break;
            this.currentTrack.info.bitDepth = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 187 /* CuePoint */:
          {
            if (!this.currentSegment) break;
            this.readContiguousElements(slice.slice(dataStartPos, size));
            this.currentCueTime = null;
          }
          ;
          break;
        case 179 /* CueTime */:
          {
            this.currentCueTime = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 183 /* CueTrackPositions */:
          {
            if (this.currentCueTime === null) break;
            assert(this.currentSegment);
            const cuePoint = { time: this.currentCueTime, trackId: -1, clusterPosition: -1 };
            this.currentSegment.cuePoints.push(cuePoint);
            this.readContiguousElements(slice.slice(dataStartPos, size));
            if (cuePoint.trackId === -1 || cuePoint.clusterPosition === -1) {
              this.currentSegment.cuePoints.pop();
            }
          }
          ;
          break;
        case 247 /* CueTrack */:
          {
            const lastCuePoint = this.currentSegment?.cuePoints[this.currentSegment.cuePoints.length - 1];
            if (!lastCuePoint) break;
            lastCuePoint.trackId = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 241 /* CueClusterPosition */:
          {
            const lastCuePoint = this.currentSegment?.cuePoints[this.currentSegment.cuePoints.length - 1];
            if (!lastCuePoint) break;
            assert(this.currentSegment);
            lastCuePoint.clusterPosition = this.currentSegment.dataStartPos + readUnsignedInt(slice, size);
          }
          ;
          break;
        case 231 /* Timestamp */:
          {
            if (!this.currentCluster) break;
            this.currentCluster.timestamp = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 163 /* SimpleBlock */:
          {
            if (!this.currentCluster) break;
            const trackNumber = readVarInt(slice);
            if (trackNumber === null) break;
            const trackData = this.getTrackDataInCluster(this.currentCluster, trackNumber);
            if (!trackData) break;
            const relativeTimestamp = readI16Be(slice);
            const flags = readU8(slice);
            const lacing = flags >> 1 & 3;
            let isKeyFrame = !!(flags & 128);
            if (trackData.track.info?.type === "audio" && trackData.track.info.codec) {
              isKeyFrame = true;
            }
            const blockData = readBytes(slice, size - (slice.filePos - dataStartPos));
            const hasDecodingInstructions = trackData.track.decodingInstructions.length > 0;
            trackData.blocks.push({
              timestamp: relativeTimestamp,
              // We'll add the cluster's timestamp to this later
              duration: 0,
              // Will set later
              isKeyFrame,
              data: blockData,
              lacing,
              decoded: !hasDecodingInstructions,
              mainAdditional: null
            });
          }
          ;
          break;
        case 160 /* BlockGroup */:
          {
            if (!this.currentCluster) break;
            this.readContiguousElements(slice.slice(dataStartPos, size));
            this.currentBlock = null;
          }
          ;
          break;
        case 161 /* Block */:
          {
            if (!this.currentCluster) break;
            const trackNumber = readVarInt(slice);
            if (trackNumber === null) break;
            const trackData = this.getTrackDataInCluster(this.currentCluster, trackNumber);
            if (!trackData) break;
            const relativeTimestamp = readI16Be(slice);
            const flags = readU8(slice);
            const lacing = flags >> 1 & 3;
            const blockData = readBytes(slice, size - (slice.filePos - dataStartPos));
            const hasDecodingInstructions = trackData.track.decodingInstructions.length > 0;
            this.currentBlock = {
              timestamp: relativeTimestamp,
              // We'll add the cluster's timestamp to this later
              duration: 0,
              // Will set later
              isKeyFrame: true,
              data: blockData,
              lacing,
              decoded: !hasDecodingInstructions,
              mainAdditional: null
            };
            trackData.blocks.push(this.currentBlock);
          }
          ;
          break;
        case 30113 /* BlockAdditions */:
          {
            this.readContiguousElements(slice.slice(dataStartPos, size));
          }
          ;
          break;
        case 166 /* BlockMore */:
          {
            if (!this.currentBlock) break;
            this.currentBlockAdditional = {
              addId: 1,
              data: null
            };
            this.readContiguousElements(slice.slice(dataStartPos, size));
            if (this.currentBlockAdditional.data && this.currentBlockAdditional.addId === 1) {
              this.currentBlock.mainAdditional = this.currentBlockAdditional.data;
            }
            this.currentBlockAdditional = null;
          }
          ;
          break;
        case 165 /* BlockAdditional */:
          {
            if (!this.currentBlockAdditional) break;
            this.currentBlockAdditional.data = readBytes(slice, size);
          }
          ;
          break;
        case 238 /* BlockAddID */:
          {
            if (!this.currentBlockAdditional) break;
            this.currentBlockAdditional.addId = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 155 /* BlockDuration */:
          {
            if (!this.currentBlock) break;
            this.currentBlock.duration = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 251 /* ReferenceBlock */:
          {
            if (!this.currentBlock) break;
            this.currentBlock.isKeyFrame = false;
          }
          ;
          break;
        case 29555 /* Tag */:
          {
            this.currentTagTargetIsMovie = true;
            this.readContiguousElements(slice.slice(dataStartPos, size));
          }
          ;
          break;
        case 25536 /* Targets */:
          {
            this.readContiguousElements(slice.slice(dataStartPos, size));
          }
          ;
          break;
        case 26826 /* TargetTypeValue */:
          {
            const targetTypeValue = readUnsignedInt(slice, size);
            if (targetTypeValue !== 50) {
              this.currentTagTargetIsMovie = false;
            }
          }
          ;
          break;
        case 25541 /* TagTrackUID */:
        case 25545 /* TagEditionUID */:
        case 25540 /* TagChapterUID */:
        case 25542 /* TagAttachmentUID */:
          {
            this.currentTagTargetIsMovie = false;
          }
          ;
          break;
        case 26568 /* SimpleTag */:
          {
            if (!this.currentTagTargetIsMovie) break;
            this.currentSimpleTagName = null;
            this.readContiguousElements(slice.slice(dataStartPos, size));
          }
          ;
          break;
        case 17827 /* TagName */:
          {
            this.currentSimpleTagName = readUnicodeString(slice, size);
          }
          ;
          break;
        case 17543 /* TagString */:
          {
            if (!this.currentSimpleTagName) break;
            const value = readUnicodeString(slice, size);
            this.processTagValue(this.currentSimpleTagName, value);
          }
          ;
          break;
        case 17541 /* TagBinary */:
          {
            if (!this.currentSimpleTagName) break;
            const value = readBytes(slice, size);
            this.processTagValue(this.currentSimpleTagName, value);
          }
          ;
          break;
        case 24999 /* AttachedFile */:
          {
            if (!this.currentSegment) break;
            this.currentAttachedFile = {
              fileUid: null,
              fileName: null,
              fileMediaType: null,
              fileData: null,
              fileDescription: null
            };
            this.readContiguousElements(slice.slice(dataStartPos, size));
            const tags = this.currentSegment.metadataTags;
            if (this.currentAttachedFile.fileUid && this.currentAttachedFile.fileData) {
              tags.raw ??= {};
              tags.raw[this.currentAttachedFile.fileUid.toString()] = new AttachedFile(
                this.currentAttachedFile.fileData,
                this.currentAttachedFile.fileMediaType ?? void 0,
                this.currentAttachedFile.fileName ?? void 0,
                this.currentAttachedFile.fileDescription ?? void 0
              );
            }
            if (this.currentAttachedFile.fileMediaType?.startsWith("image/") && this.currentAttachedFile.fileData) {
              const fileName = this.currentAttachedFile.fileName;
              let kind = "unknown";
              if (fileName) {
                const lowerName = fileName.toLowerCase();
                if (lowerName.startsWith("cover.")) {
                  kind = "coverFront";
                } else if (lowerName.startsWith("back.")) {
                  kind = "coverBack";
                }
              }
              tags.images ??= [];
              tags.images.push({
                data: this.currentAttachedFile.fileData,
                mimeType: this.currentAttachedFile.fileMediaType,
                kind,
                name: this.currentAttachedFile.fileName ?? void 0,
                description: this.currentAttachedFile.fileDescription ?? void 0
              });
            }
            this.currentAttachedFile = null;
          }
          ;
          break;
        case 18094 /* FileUID */:
          {
            if (!this.currentAttachedFile) break;
            this.currentAttachedFile.fileUid = readUnsignedBigInt(slice, size);
          }
          ;
          break;
        case 18030 /* FileName */:
          {
            if (!this.currentAttachedFile) break;
            this.currentAttachedFile.fileName = readUnicodeString(slice, size);
          }
          ;
          break;
        case 18016 /* FileMediaType */:
          {
            if (!this.currentAttachedFile) break;
            this.currentAttachedFile.fileMediaType = readAsciiString(slice, size);
          }
          ;
          break;
        case 18012 /* FileData */:
          {
            if (!this.currentAttachedFile) break;
            this.currentAttachedFile.fileData = readBytes(slice, size);
          }
          ;
          break;
        case 18046 /* FileDescription */:
          {
            if (!this.currentAttachedFile) break;
            this.currentAttachedFile.fileDescription = readUnicodeString(slice, size);
          }
          ;
          break;
        case 28032 /* ContentEncodings */:
          {
            if (!this.currentTrack) break;
            this.readContiguousElements(slice.slice(dataStartPos, size));
            this.currentTrack.decodingInstructions.sort((a, b) => b.order - a.order);
          }
          ;
          break;
        case 25152 /* ContentEncoding */:
          {
            this.currentDecodingInstruction = {
              order: 0,
              scope: 1 /* Block */,
              data: null
            };
            this.readContiguousElements(slice.slice(dataStartPos, size));
            if (this.currentDecodingInstruction.data) {
              this.currentTrack.decodingInstructions.push(this.currentDecodingInstruction);
            }
            this.currentDecodingInstruction = null;
          }
          ;
          break;
        case 20529 /* ContentEncodingOrder */:
          {
            if (!this.currentDecodingInstruction) break;
            this.currentDecodingInstruction.order = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 20530 /* ContentEncodingScope */:
          {
            if (!this.currentDecodingInstruction) break;
            this.currentDecodingInstruction.scope = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 20532 /* ContentCompression */:
          {
            if (!this.currentDecodingInstruction) break;
            this.currentDecodingInstruction.data = {
              type: "decompress",
              algorithm: 0 /* Zlib */,
              settings: null
            };
            this.readContiguousElements(slice.slice(dataStartPos, size));
          }
          ;
          break;
        case 16980 /* ContentCompAlgo */:
          {
            if (this.currentDecodingInstruction?.data?.type !== "decompress") break;
            this.currentDecodingInstruction.data.algorithm = readUnsignedInt(slice, size);
          }
          ;
          break;
        case 16981 /* ContentCompSettings */:
          {
            if (this.currentDecodingInstruction?.data?.type !== "decompress") break;
            this.currentDecodingInstruction.data.settings = readBytes(slice, size);
          }
          ;
          break;
        case 20533 /* ContentEncryption */:
          {
            if (!this.currentDecodingInstruction) break;
            this.currentDecodingInstruction.data = {
              type: "decrypt"
            };
          }
          ;
          break;
      }
      slice.filePos = dataStartPos + size;
      return true;
    }
    decodeBlockData(track, rawData) {
      assert(track.decodingInstructions.length > 0);
      let currentData = rawData;
      for (const instruction of track.decodingInstructions) {
        assert(instruction.data);
        switch (instruction.data.type) {
          case "decompress":
            {
              switch (instruction.data.algorithm) {
                case 3 /* HeaderStripping */:
                  {
                    if (instruction.data.settings && instruction.data.settings.length > 0) {
                      const prefix = instruction.data.settings;
                      const newData = new Uint8Array(prefix.length + currentData.length);
                      newData.set(prefix, 0);
                      newData.set(currentData, prefix.length);
                      currentData = newData;
                    }
                  }
                  ;
                  break;
                default:
                  {
                  }
                  ;
              }
            }
            ;
            break;
          default:
            {
            }
            ;
        }
      }
      return currentData;
    }
    processTagValue(name, value) {
      if (!this.currentSegment?.metadataTags) return;
      const metadataTags = this.currentSegment.metadataTags;
      metadataTags.raw ??= {};
      metadataTags.raw[name] ??= value;
      if (typeof value === "string") {
        switch (name.toLowerCase()) {
          case "title":
            {
              metadataTags.title ??= value;
            }
            ;
            break;
          case "description":
            {
              metadataTags.description ??= value;
            }
            ;
            break;
          case "artist":
            {
              metadataTags.artist ??= value;
            }
            ;
            break;
          case "album":
            {
              metadataTags.album ??= value;
            }
            ;
            break;
          case "album_artist":
            {
              metadataTags.albumArtist ??= value;
            }
            ;
            break;
          case "genre":
            {
              metadataTags.genre ??= value;
            }
            ;
            break;
          case "comment":
            {
              metadataTags.comment ??= value;
            }
            ;
            break;
          case "lyrics":
            {
              metadataTags.lyrics ??= value;
            }
            ;
            break;
          case "date":
            {
              const date = new Date(value);
              if (!Number.isNaN(date.getTime())) {
                metadataTags.date ??= date;
              }
            }
            ;
            break;
          case "track_number":
          case "part_number":
            {
              const parts = value.split("/");
              const trackNum = Number.parseInt(parts[0], 10);
              const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);
              if (Number.isInteger(trackNum) && trackNum > 0) {
                metadataTags.trackNumber ??= trackNum;
              }
              if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {
                metadataTags.tracksTotal ??= tracksTotal;
              }
            }
            ;
            break;
          case "disc_number":
          case "disc":
            {
              const discParts = value.split("/");
              const discNum = Number.parseInt(discParts[0], 10);
              const discsTotal = discParts[1] && Number.parseInt(discParts[1], 10);
              if (Number.isInteger(discNum) && discNum > 0) {
                metadataTags.discNumber ??= discNum;
              }
              if (discsTotal && Number.isInteger(discsTotal) && discsTotal > 0) {
                metadataTags.discsTotal ??= discsTotal;
              }
            }
            ;
            break;
        }
      }
    }
  };
  var MatroskaTrackBacking = class {
    constructor(internalTrack) {
      this.internalTrack = internalTrack;
      this.packetToClusterLocation = /* @__PURE__ */ new WeakMap();
    }
    getId() {
      return this.internalTrack.id;
    }
    getNumber() {
      const demuxer = this.internalTrack.demuxer;
      const inputTrack = this.internalTrack.inputTrack;
      const trackType = inputTrack.type;
      let number = 0;
      for (const segment of demuxer.segments) {
        for (const track of segment.tracks) {
          if (track.inputTrack.type === trackType) {
            number++;
          }
          if (track === this.internalTrack) {
            break;
          }
        }
      }
      return number;
    }
    getCodec() {
      throw new Error("Not implemented on base class.");
    }
    getInternalCodecId() {
      return this.internalTrack.codecId;
    }
    async computeDuration() {
      const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
      return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    getName() {
      return this.internalTrack.name;
    }
    getLanguageCode() {
      return this.internalTrack.languageCode;
    }
    async getFirstTimestamp() {
      const firstPacket = await this.getFirstPacket({ metadataOnly: true });
      return firstPacket?.timestamp ?? 0;
    }
    getTimeResolution() {
      return this.internalTrack.segment.timestampFactor;
    }
    getDisposition() {
      return this.internalTrack.disposition;
    }
    async getFirstPacket(options) {
      return this.performClusterLookup(
        null,
        (cluster) => {
          const trackData = cluster.trackData.get(this.internalTrack.id);
          if (trackData) {
            return {
              blockIndex: 0,
              correctBlockFound: true
            };
          }
          return {
            blockIndex: -1,
            correctBlockFound: false
          };
        },
        -Infinity,
        // Use -Infinity as a search timestamp to avoid using the cues
        Infinity,
        options
      );
    }
    intoTimescale(timestamp) {
      return roundIfAlmostInteger(timestamp * this.internalTrack.segment.timestampFactor);
    }
    async getPacket(timestamp, options) {
      const timestampInTimescale = this.intoTimescale(timestamp);
      return this.performClusterLookup(
        null,
        (cluster) => {
          const trackData = cluster.trackData.get(this.internalTrack.id);
          if (!trackData) {
            return { blockIndex: -1, correctBlockFound: false };
          }
          const index = binarySearchLessOrEqual(
            trackData.presentationTimestamps,
            timestampInTimescale,
            (x) => x.timestamp
          );
          const blockIndex = index !== -1 ? trackData.presentationTimestamps[index].blockIndex : -1;
          const correctBlockFound = index !== -1 && timestampInTimescale < trackData.endTimestamp;
          return { blockIndex, correctBlockFound };
        },
        timestampInTimescale,
        timestampInTimescale,
        options
      );
    }
    async getNextPacket(packet, options) {
      const locationInCluster = this.packetToClusterLocation.get(packet);
      if (locationInCluster === void 0) {
        throw new Error("Packet was not created from this track.");
      }
      return this.performClusterLookup(
        locationInCluster.cluster,
        (cluster) => {
          if (cluster === locationInCluster.cluster) {
            const trackData = cluster.trackData.get(this.internalTrack.id);
            if (locationInCluster.blockIndex + 1 < trackData.blocks.length) {
              return {
                blockIndex: locationInCluster.blockIndex + 1,
                correctBlockFound: true
              };
            }
          } else {
            const trackData = cluster.trackData.get(this.internalTrack.id);
            if (trackData) {
              return {
                blockIndex: 0,
                correctBlockFound: true
              };
            }
          }
          return {
            blockIndex: -1,
            correctBlockFound: false
          };
        },
        -Infinity,
        // Use -Infinity as a search timestamp to avoid using the cues
        Infinity,
        options
      );
    }
    async getKeyPacket(timestamp, options) {
      const timestampInTimescale = this.intoTimescale(timestamp);
      return this.performClusterLookup(
        null,
        (cluster) => {
          const trackData = cluster.trackData.get(this.internalTrack.id);
          if (!trackData) {
            return { blockIndex: -1, correctBlockFound: false };
          }
          const index = findLastIndex(trackData.presentationTimestamps, (x) => {
            const block = trackData.blocks[x.blockIndex];
            return block.isKeyFrame && x.timestamp <= timestampInTimescale;
          });
          const blockIndex = index !== -1 ? trackData.presentationTimestamps[index].blockIndex : -1;
          const correctBlockFound = index !== -1 && timestampInTimescale < trackData.endTimestamp;
          return { blockIndex, correctBlockFound };
        },
        timestampInTimescale,
        timestampInTimescale,
        options
      );
    }
    async getNextKeyPacket(packet, options) {
      const locationInCluster = this.packetToClusterLocation.get(packet);
      if (locationInCluster === void 0) {
        throw new Error("Packet was not created from this track.");
      }
      return this.performClusterLookup(
        locationInCluster.cluster,
        (cluster) => {
          if (cluster === locationInCluster.cluster) {
            const trackData = cluster.trackData.get(this.internalTrack.id);
            const nextKeyFrameIndex = trackData.blocks.findIndex(
              (x, i) => x.isKeyFrame && i > locationInCluster.blockIndex
            );
            if (nextKeyFrameIndex !== -1) {
              return {
                blockIndex: nextKeyFrameIndex,
                correctBlockFound: true
              };
            }
          } else {
            const trackData = cluster.trackData.get(this.internalTrack.id);
            if (trackData && trackData.firstKeyFrameTimestamp !== null) {
              const keyFrameIndex = trackData.blocks.findIndex((x) => x.isKeyFrame);
              assert(keyFrameIndex !== -1);
              return {
                blockIndex: keyFrameIndex,
                correctBlockFound: true
              };
            }
          }
          return {
            blockIndex: -1,
            correctBlockFound: false
          };
        },
        -Infinity,
        // Use -Infinity as a search timestamp to avoid using the cues
        Infinity,
        options
      );
    }
    async fetchPacketInCluster(cluster, blockIndex, options) {
      if (blockIndex === -1) {
        return null;
      }
      const trackData = cluster.trackData.get(this.internalTrack.id);
      const block = trackData.blocks[blockIndex];
      assert(block);
      if (!block.decoded) {
        block.data = this.internalTrack.demuxer.decodeBlockData(this.internalTrack, block.data);
        block.decoded = true;
      }
      const data = options.metadataOnly ? PLACEHOLDER_DATA : block.data;
      const timestamp = block.timestamp / this.internalTrack.segment.timestampFactor;
      const duration = block.duration / this.internalTrack.segment.timestampFactor;
      const sideData = {};
      if (block.mainAdditional && this.internalTrack.info?.type === "video" && this.internalTrack.info.alphaMode) {
        sideData.alpha = options.metadataOnly ? PLACEHOLDER_DATA : block.mainAdditional;
        sideData.alphaByteLength = block.mainAdditional.byteLength;
      }
      const packet = new EncodedPacket(
        data,
        block.isKeyFrame ? "key" : "delta",
        timestamp,
        duration,
        cluster.dataStartPos + blockIndex,
        block.data.byteLength,
        sideData
      );
      this.packetToClusterLocation.set(packet, { cluster, blockIndex });
      return packet;
    }
    /** Looks for a packet in the clusters while trying to load as few clusters as possible to retrieve it. */
    async performClusterLookup(startCluster, getMatchInCluster, searchTimestamp, latestTimestamp, options) {
      const { demuxer, segment } = this.internalTrack;
      let currentCluster = null;
      let bestCluster = null;
      let bestBlockIndex = -1;
      if (startCluster) {
        const { blockIndex, correctBlockFound } = getMatchInCluster(startCluster);
        if (correctBlockFound) {
          return this.fetchPacketInCluster(startCluster, blockIndex, options);
        }
        if (blockIndex !== -1) {
          bestCluster = startCluster;
          bestBlockIndex = blockIndex;
        }
      }
      const cuePointIndex = binarySearchLessOrEqual(
        this.internalTrack.cuePoints,
        searchTimestamp,
        (x) => x.time
      );
      const cuePoint = cuePointIndex !== -1 ? this.internalTrack.cuePoints[cuePointIndex] : null;
      const positionCacheIndex = binarySearchLessOrEqual(
        this.internalTrack.clusterPositionCache,
        searchTimestamp,
        (x) => x.startTimestamp
      );
      const positionCacheEntry = positionCacheIndex !== -1 ? this.internalTrack.clusterPositionCache[positionCacheIndex] : null;
      const lookupEntryPosition = Math.max(
        cuePoint?.clusterPosition ?? 0,
        positionCacheEntry?.elementStartPos ?? 0
      ) || null;
      let currentPos;
      if (!startCluster) {
        currentPos = lookupEntryPosition ?? segment.clusterSeekStartPos;
      } else {
        if (lookupEntryPosition === null || startCluster.elementStartPos >= lookupEntryPosition) {
          currentPos = startCluster.elementEndPos;
          currentCluster = startCluster;
        } else {
          currentPos = lookupEntryPosition;
        }
      }
      while (segment.elementEndPos === null || currentPos <= segment.elementEndPos - MIN_HEADER_SIZE) {
        if (currentCluster) {
          const trackData = currentCluster.trackData.get(this.internalTrack.id);
          if (trackData && trackData.startTimestamp > latestTimestamp) {
            break;
          }
        }
        let slice = demuxer.reader.requestSliceRange(currentPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
        if (slice instanceof Promise) slice = await slice;
        if (!slice) break;
        const elementStartPos = currentPos;
        const elementHeader = readElementHeader(slice);
        if (!elementHeader || !LEVEL_1_EBML_IDS.includes(elementHeader.id) && elementHeader.id !== 236 /* Void */) {
          const nextPos = await resync(
            demuxer.reader,
            elementStartPos,
            LEVEL_1_EBML_IDS,
            Math.min(segment.elementEndPos ?? Infinity, elementStartPos + MAX_RESYNC_LENGTH)
          );
          if (nextPos) {
            currentPos = nextPos;
            continue;
          } else {
            break;
          }
        }
        const id = elementHeader.id;
        let size = elementHeader.size;
        const dataStartPos = slice.filePos;
        if (id === 524531317 /* Cluster */) {
          currentCluster = await demuxer.readCluster(elementStartPos, segment);
          size = currentCluster.elementEndPos - dataStartPos;
          const { blockIndex, correctBlockFound } = getMatchInCluster(currentCluster);
          if (correctBlockFound) {
            return this.fetchPacketInCluster(currentCluster, blockIndex, options);
          }
          if (blockIndex !== -1) {
            bestCluster = currentCluster;
            bestBlockIndex = blockIndex;
          }
        }
        if (size === void 0) {
          assert(id !== 524531317 /* Cluster */);
          const nextElementPos = await searchForNextElementId(
            demuxer.reader,
            dataStartPos,
            LEVEL_0_AND_1_EBML_IDS,
            segment.elementEndPos
          );
          size = nextElementPos.pos - dataStartPos;
        }
        const endPos = dataStartPos + size;
        if (segment.elementEndPos === null) {
          let slice2 = demuxer.reader.requestSliceRange(endPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
          if (slice2 instanceof Promise) slice2 = await slice2;
          if (!slice2) break;
          const elementId = readElementId(slice2);
          if (elementId === 408125543 /* Segment */) {
            segment.elementEndPos = endPos;
            break;
          }
        }
        currentPos = endPos;
      }
      if (cuePoint && (!bestCluster || bestCluster.elementStartPos < cuePoint.clusterPosition)) {
        const previousCuePoint = this.internalTrack.cuePoints[cuePointIndex - 1];
        assert(!previousCuePoint || previousCuePoint.time < cuePoint.time);
        const newSearchTimestamp = previousCuePoint?.time ?? -Infinity;
        return this.performClusterLookup(null, getMatchInCluster, newSearchTimestamp, latestTimestamp, options);
      }
      if (bestCluster) {
        return this.fetchPacketInCluster(bestCluster, bestBlockIndex, options);
      }
      return null;
    }
  };
  var MatroskaVideoTrackBacking = class extends MatroskaTrackBacking {
    constructor(internalTrack) {
      super(internalTrack);
      this.decoderConfigPromise = null;
      this.internalTrack = internalTrack;
    }
    getCodec() {
      return this.internalTrack.info.codec;
    }
    getCodedWidth() {
      return this.internalTrack.info.width;
    }
    getCodedHeight() {
      return this.internalTrack.info.height;
    }
    getRotation() {
      return this.internalTrack.info.rotation;
    }
    async getColorSpace() {
      return {
        primaries: this.internalTrack.info.colorSpace?.primaries,
        transfer: this.internalTrack.info.colorSpace?.transfer,
        matrix: this.internalTrack.info.colorSpace?.matrix,
        fullRange: this.internalTrack.info.colorSpace?.fullRange
      };
    }
    async canBeTransparent() {
      return this.internalTrack.info.alphaMode;
    }
    async getDecoderConfig() {
      if (!this.internalTrack.info.codec) {
        return null;
      }
      return this.decoderConfigPromise ??= (async () => {
        let firstPacket = null;
        const needsPacketForAdditionalInfo = this.internalTrack.info.codec === "vp9" || this.internalTrack.info.codec === "av1" || this.internalTrack.info.codec === "avc" && !this.internalTrack.info.codecDescription || this.internalTrack.info.codec === "hevc" && !this.internalTrack.info.codecDescription;
        if (needsPacketForAdditionalInfo) {
          firstPacket = await this.getFirstPacket({});
        }
        return {
          codec: extractVideoCodecString({
            width: this.internalTrack.info.width,
            height: this.internalTrack.info.height,
            codec: this.internalTrack.info.codec,
            codecDescription: this.internalTrack.info.codecDescription,
            colorSpace: this.internalTrack.info.colorSpace,
            avcType: 1,
            // We don't know better (or do we?) so just assume 'avc1'
            avcCodecInfo: this.internalTrack.info.codec === "avc" && firstPacket ? extractAvcDecoderConfigurationRecord(firstPacket.data) : null,
            hevcCodecInfo: this.internalTrack.info.codec === "hevc" && firstPacket ? extractHevcDecoderConfigurationRecord(firstPacket.data) : null,
            vp9CodecInfo: this.internalTrack.info.codec === "vp9" && firstPacket ? extractVp9CodecInfoFromPacket(firstPacket.data) : null,
            av1CodecInfo: this.internalTrack.info.codec === "av1" && firstPacket ? extractAv1CodecInfoFromPacket(firstPacket.data) : null
          }),
          codedWidth: this.internalTrack.info.width,
          codedHeight: this.internalTrack.info.height,
          description: this.internalTrack.info.codecDescription ?? void 0,
          colorSpace: this.internalTrack.info.colorSpace ?? void 0
        };
      })();
    }
  };
  var MatroskaAudioTrackBacking = class extends MatroskaTrackBacking {
    constructor(internalTrack) {
      super(internalTrack);
      this.decoderConfig = null;
      this.internalTrack = internalTrack;
    }
    getCodec() {
      return this.internalTrack.info.codec;
    }
    getNumberOfChannels() {
      return this.internalTrack.info.numberOfChannels;
    }
    getSampleRate() {
      return this.internalTrack.info.sampleRate;
    }
    async getDecoderConfig() {
      if (!this.internalTrack.info.codec) {
        return null;
      }
      return this.decoderConfig ??= {
        codec: extractAudioCodecString({
          codec: this.internalTrack.info.codec,
          codecDescription: this.internalTrack.info.codecDescription,
          aacCodecInfo: this.internalTrack.info.aacCodecInfo
        }),
        numberOfChannels: this.internalTrack.info.numberOfChannels,
        sampleRate: this.internalTrack.info.sampleRate,
        description: this.internalTrack.info.codecDescription ?? void 0
      };
    }
  };

  // src/mp3/mp3-reader.ts
  var readNextMp3FrameHeader = async (reader, startPos, until) => {
    let currentPos = startPos;
    while (until === null || currentPos < until) {
      let slice = reader.requestSlice(currentPos, FRAME_HEADER_SIZE);
      if (slice instanceof Promise) slice = await slice;
      if (!slice) break;
      const word = readU32Be(slice);
      const result = readMp3FrameHeader(word, reader.fileSize !== null ? reader.fileSize - currentPos : null);
      if (result.header) {
        return { header: result.header, startPos: currentPos };
      }
      currentPos += result.bytesAdvanced;
    }
    return null;
  };

  // src/mp3/mp3-demuxer.ts
  var Mp3Demuxer = class extends Demuxer {
    constructor(input) {
      super(input);
      this.metadataPromise = null;
      this.firstFrameHeader = null;
      this.loadedSamples = [];
      // All samples from the start of the file to lastLoadedPos
      this.metadataTags = null;
      this.tracks = [];
      this.readingMutex = new AsyncMutex();
      this.lastSampleLoaded = false;
      this.lastLoadedPos = 0;
      this.nextTimestampInSamples = 0;
      this.reader = input._reader;
    }
    async readMetadata() {
      return this.metadataPromise ??= (async () => {
        while (!this.firstFrameHeader && !this.lastSampleLoaded) {
          await this.advanceReader();
        }
        if (!this.firstFrameHeader) {
          throw new Error("No valid MP3 frame found.");
        }
        this.tracks = [new InputAudioTrack(this.input, new Mp3AudioTrackBacking(this))];
      })();
    }
    async advanceReader() {
      if (this.lastLoadedPos === 0) {
        while (true) {
          let slice2 = this.reader.requestSlice(this.lastLoadedPos, ID3_V2_HEADER_SIZE);
          if (slice2 instanceof Promise) slice2 = await slice2;
          if (!slice2) {
            this.lastSampleLoaded = true;
            return;
          }
          const id3V2Header = readId3V2Header(slice2);
          if (!id3V2Header) {
            break;
          }
          this.lastLoadedPos = slice2.filePos + id3V2Header.size;
        }
      }
      const result = await readNextMp3FrameHeader(this.reader, this.lastLoadedPos, this.reader.fileSize);
      if (!result) {
        this.lastSampleLoaded = true;
        return;
      }
      const header = result.header;
      this.lastLoadedPos = result.startPos + header.totalSize - 1;
      const xingOffset = getXingOffset(header.mpegVersionId, header.channel);
      let slice = this.reader.requestSlice(result.startPos + xingOffset, 4);
      if (slice instanceof Promise) slice = await slice;
      if (slice) {
        const word = readU32Be(slice);
        const isXing = word === XING || word === INFO;
        if (isXing) {
          return;
        }
      }
      if (!this.firstFrameHeader) {
        this.firstFrameHeader = header;
      }
      if (header.sampleRate !== this.firstFrameHeader.sampleRate) {
        console.warn(
          `MP3 changed sample rate mid-file: ${this.firstFrameHeader.sampleRate} Hz to ${header.sampleRate} Hz. Might be a bug, so please report this file.`
        );
      }
      const sampleDuration = header.audioSamplesInFrame / this.firstFrameHeader.sampleRate;
      const sample = {
        timestamp: this.nextTimestampInSamples / this.firstFrameHeader.sampleRate,
        duration: sampleDuration,
        dataStart: result.startPos,
        dataSize: header.totalSize
      };
      this.loadedSamples.push(sample);
      this.nextTimestampInSamples += header.audioSamplesInFrame;
      return;
    }
    async getMimeType() {
      return "audio/mpeg";
    }
    async getTracks() {
      await this.readMetadata();
      return this.tracks;
    }
    async computeDuration() {
      await this.readMetadata();
      const track = this.tracks[0];
      assert(track);
      return track.computeDuration();
    }
    async getMetadataTags() {
      const release = await this.readingMutex.acquire();
      try {
        await this.readMetadata();
        if (this.metadataTags) {
          return this.metadataTags;
        }
        this.metadataTags = {};
        let currentPos = 0;
        let id3V2HeaderFound = false;
        while (true) {
          let headerSlice = this.reader.requestSlice(currentPos, ID3_V2_HEADER_SIZE);
          if (headerSlice instanceof Promise) headerSlice = await headerSlice;
          if (!headerSlice) break;
          const id3V2Header = readId3V2Header(headerSlice);
          if (!id3V2Header) {
            break;
          }
          id3V2HeaderFound = true;
          let contentSlice = this.reader.requestSlice(headerSlice.filePos, id3V2Header.size);
          if (contentSlice instanceof Promise) contentSlice = await contentSlice;
          if (!contentSlice) break;
          parseId3V2Tag(contentSlice, id3V2Header, this.metadataTags);
          currentPos = headerSlice.filePos + id3V2Header.size;
        }
        if (!id3V2HeaderFound && this.reader.fileSize !== null && this.reader.fileSize >= ID3_V1_TAG_SIZE) {
          let slice = this.reader.requestSlice(this.reader.fileSize - ID3_V1_TAG_SIZE, ID3_V1_TAG_SIZE);
          if (slice instanceof Promise) slice = await slice;
          assert(slice);
          const tag = readAscii(slice, 3);
          if (tag === "TAG") {
            parseId3V1Tag(slice, this.metadataTags);
          }
        }
        return this.metadataTags;
      } finally {
        release();
      }
    }
  };
  var Mp3AudioTrackBacking = class {
    constructor(demuxer) {
      this.demuxer = demuxer;
    }
    getId() {
      return 1;
    }
    getNumber() {
      return 1;
    }
    async getFirstTimestamp() {
      return 0;
    }
    getTimeResolution() {
      assert(this.demuxer.firstFrameHeader);
      return this.demuxer.firstFrameHeader.sampleRate / this.demuxer.firstFrameHeader.audioSamplesInFrame;
    }
    async computeDuration() {
      const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
      return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    getName() {
      return null;
    }
    getLanguageCode() {
      return UNDETERMINED_LANGUAGE;
    }
    getCodec() {
      return "mp3";
    }
    getInternalCodecId() {
      return null;
    }
    getNumberOfChannels() {
      assert(this.demuxer.firstFrameHeader);
      return this.demuxer.firstFrameHeader.channel === 3 ? 1 : 2;
    }
    getSampleRate() {
      assert(this.demuxer.firstFrameHeader);
      return this.demuxer.firstFrameHeader.sampleRate;
    }
    getDisposition() {
      return {
        ...DEFAULT_TRACK_DISPOSITION
      };
    }
    async getDecoderConfig() {
      assert(this.demuxer.firstFrameHeader);
      return {
        codec: "mp3",
        numberOfChannels: this.demuxer.firstFrameHeader.channel === 3 ? 1 : 2,
        sampleRate: this.demuxer.firstFrameHeader.sampleRate
      };
    }
    async getPacketAtIndex(sampleIndex, options) {
      if (sampleIndex === -1) {
        return null;
      }
      const rawSample = this.demuxer.loadedSamples[sampleIndex];
      if (!rawSample) {
        return null;
      }
      let data;
      if (options.metadataOnly) {
        data = PLACEHOLDER_DATA;
      } else {
        let slice = this.demuxer.reader.requestSlice(rawSample.dataStart, rawSample.dataSize);
        if (slice instanceof Promise) slice = await slice;
        if (!slice) {
          return null;
        }
        data = readBytes(slice, rawSample.dataSize);
      }
      return new EncodedPacket(
        data,
        "key",
        rawSample.timestamp,
        rawSample.duration,
        sampleIndex,
        rawSample.dataSize
      );
    }
    getFirstPacket(options) {
      return this.getPacketAtIndex(0, options);
    }
    async getNextPacket(packet, options) {
      const release = await this.demuxer.readingMutex.acquire();
      try {
        const sampleIndex = binarySearchExact(
          this.demuxer.loadedSamples,
          packet.timestamp,
          (x) => x.timestamp
        );
        if (sampleIndex === -1) {
          throw new Error("Packet was not created from this track.");
        }
        const nextIndex = sampleIndex + 1;
        while (nextIndex >= this.demuxer.loadedSamples.length && !this.demuxer.lastSampleLoaded) {
          await this.demuxer.advanceReader();
        }
        return this.getPacketAtIndex(nextIndex, options);
      } finally {
        release();
      }
    }
    async getPacket(timestamp, options) {
      const release = await this.demuxer.readingMutex.acquire();
      try {
        while (true) {
          const index = binarySearchLessOrEqual(
            this.demuxer.loadedSamples,
            timestamp,
            (x) => x.timestamp
          );
          if (index === -1 && this.demuxer.loadedSamples.length > 0) {
            return null;
          }
          if (this.demuxer.lastSampleLoaded) {
            return this.getPacketAtIndex(index, options);
          }
          if (index >= 0 && index + 1 < this.demuxer.loadedSamples.length) {
            return this.getPacketAtIndex(index, options);
          }
          await this.demuxer.advanceReader();
        }
      } finally {
        release();
      }
    }
    getKeyPacket(timestamp, options) {
      return this.getPacket(timestamp, options);
    }
    getNextKeyPacket(packet, options) {
      return this.getNextPacket(packet, options);
    }
  };

  // src/ogg/ogg-misc.ts
  var OGGS = 1399285583;
  var OGG_CRC_POLYNOMIAL = 79764919;
  var OGG_CRC_TABLE = new Uint32Array(256);
  for (let n = 0; n < 256; n++) {
    let crc = n << 24;
    for (let k = 0; k < 8; k++) {
      crc = crc & 2147483648 ? crc << 1 ^ OGG_CRC_POLYNOMIAL : crc << 1;
    }
    OGG_CRC_TABLE[n] = crc >>> 0 & 4294967295;
  }
  var computeOggPageCrc = (bytes2) => {
    const view2 = toDataView(bytes2);
    const originalChecksum = view2.getUint32(22, true);
    view2.setUint32(22, 0, true);
    let crc = 0;
    for (let i = 0; i < bytes2.length; i++) {
      const byte = bytes2[i];
      crc = (crc << 8 ^ OGG_CRC_TABLE[crc >>> 24 ^ byte]) >>> 0;
    }
    view2.setUint32(22, originalChecksum, true);
    return crc;
  };
  var extractSampleMetadata = (data, codecInfo, vorbisLastBlocksize) => {
    let durationInSamples = 0;
    let currentBlocksize = null;
    if (data.length > 0) {
      if (codecInfo.codec === "vorbis") {
        assert(codecInfo.vorbisInfo);
        const vorbisModeCount = codecInfo.vorbisInfo.modeBlockflags.length;
        const bitCount = ilog(vorbisModeCount - 1);
        const modeMask = (1 << bitCount) - 1 << 1;
        const modeNumber = (data[0] & modeMask) >> 1;
        if (modeNumber >= codecInfo.vorbisInfo.modeBlockflags.length) {
          throw new Error("Invalid mode number.");
        }
        let prevBlocksize = vorbisLastBlocksize;
        const blockflag = codecInfo.vorbisInfo.modeBlockflags[modeNumber];
        currentBlocksize = codecInfo.vorbisInfo.blocksizes[blockflag];
        if (blockflag === 1) {
          const prevMask = (modeMask | 1) + 1;
          const flag = data[0] & prevMask ? 1 : 0;
          prevBlocksize = codecInfo.vorbisInfo.blocksizes[flag];
        }
        durationInSamples = prevBlocksize !== null ? prevBlocksize + currentBlocksize >> 2 : 0;
      } else if (codecInfo.codec === "opus") {
        const toc = parseOpusTocByte(data);
        durationInSamples = toc.durationInSamples;
      }
    }
    return {
      durationInSamples,
      vorbisBlockSize: currentBlocksize
    };
  };
  var buildOggMimeType = (info) => {
    let string = "audio/ogg";
    if (info.codecStrings) {
      const uniqueCodecMimeTypes = [...new Set(info.codecStrings)];
      string += `; codecs="${uniqueCodecMimeTypes.join(", ")}"`;
    }
    return string;
  };

  // src/ogg/ogg-reader.ts
  var MIN_PAGE_HEADER_SIZE = 27;
  var MAX_PAGE_HEADER_SIZE = 27 + 255;
  var MAX_PAGE_SIZE = MAX_PAGE_HEADER_SIZE + 255 * 255;
  var readPageHeader = (slice) => {
    const startPos = slice.filePos;
    const capturePattern = readU32Le(slice);
    if (capturePattern !== OGGS) {
      return null;
    }
    slice.skip(1);
    const headerType = readU8(slice);
    const granulePosition = readI64Le(slice);
    const serialNumber = readU32Le(slice);
    const sequenceNumber = readU32Le(slice);
    const checksum = readU32Le(slice);
    const numberPageSegments = readU8(slice);
    const lacingValues = new Uint8Array(numberPageSegments);
    for (let i = 0; i < numberPageSegments; i++) {
      lacingValues[i] = readU8(slice);
    }
    const headerSize = 27 + numberPageSegments;
    const dataSize = lacingValues.reduce((a, b) => a + b, 0);
    const totalSize = headerSize + dataSize;
    return {
      headerStartPos: startPos,
      totalSize,
      dataStartPos: startPos + headerSize,
      dataSize,
      headerType,
      granulePosition,
      serialNumber,
      sequenceNumber,
      checksum,
      lacingValues
    };
  };
  var findNextPageHeader = (slice, until) => {
    while (slice.filePos < until - (4 - 1)) {
      const word = readU32Le(slice);
      const firstByte = word & 255;
      const secondByte = word >>> 8 & 255;
      const thirdByte = word >>> 16 & 255;
      const fourthByte = word >>> 24 & 255;
      const O = 79;
      if (firstByte !== O && secondByte !== O && thirdByte !== O && fourthByte !== O) {
        continue;
      }
      slice.skip(-4);
      if (word === OGGS) {
        return true;
      }
      slice.skip(1);
    }
    return false;
  };

  // src/ogg/ogg-demuxer.ts
  var OggDemuxer = class extends Demuxer {
    constructor(input) {
      super(input);
      this.metadataPromise = null;
      this.bitstreams = [];
      this.tracks = [];
      this.metadataTags = {};
      this.reader = input._reader;
    }
    async readMetadata() {
      return this.metadataPromise ??= (async () => {
        let currentPos = 0;
        while (true) {
          let slice = this.reader.requestSliceRange(currentPos, MIN_PAGE_HEADER_SIZE, MAX_PAGE_HEADER_SIZE);
          if (slice instanceof Promise) slice = await slice;
          if (!slice) break;
          const page = readPageHeader(slice);
          if (!page) {
            break;
          }
          const isBos = !!(page.headerType & 2);
          if (!isBos) {
            break;
          }
          this.bitstreams.push({
            serialNumber: page.serialNumber,
            bosPage: page,
            description: null,
            numberOfChannels: -1,
            sampleRate: -1,
            codecInfo: {
              codec: null,
              vorbisInfo: null,
              opusInfo: null
            },
            lastMetadataPacket: null
          });
          currentPos = page.headerStartPos + page.totalSize;
        }
        for (const bitstream of this.bitstreams) {
          const firstPacket = await this.readPacket(bitstream.bosPage, 0);
          if (!firstPacket) {
            continue;
          }
          if (
            // Check for Vorbis
            firstPacket.data.byteLength >= 7 && firstPacket.data[0] === 1 && firstPacket.data[1] === 118 && firstPacket.data[2] === 111 && firstPacket.data[3] === 114 && firstPacket.data[4] === 98 && firstPacket.data[5] === 105 && firstPacket.data[6] === 115
          ) {
            await this.readVorbisMetadata(firstPacket, bitstream);
          } else if (
            // Check for Opus
            firstPacket.data.byteLength >= 8 && firstPacket.data[0] === 79 && firstPacket.data[1] === 112 && firstPacket.data[2] === 117 && firstPacket.data[3] === 115 && firstPacket.data[4] === 72 && firstPacket.data[5] === 101 && firstPacket.data[6] === 97 && firstPacket.data[7] === 100
          ) {
            await this.readOpusMetadata(firstPacket, bitstream);
          }
          if (bitstream.codecInfo.codec !== null) {
            this.tracks.push(new InputAudioTrack(this.input, new OggAudioTrackBacking(bitstream, this)));
          }
        }
      })();
    }
    async readVorbisMetadata(firstPacket, bitstream) {
      let nextPacketPosition = await this.findNextPacketStart(firstPacket);
      if (!nextPacketPosition) {
        return;
      }
      const secondPacket = await this.readPacket(nextPacketPosition.startPage, nextPacketPosition.startSegmentIndex);
      if (!secondPacket) {
        return;
      }
      nextPacketPosition = await this.findNextPacketStart(secondPacket);
      if (!nextPacketPosition) {
        return;
      }
      const thirdPacket = await this.readPacket(nextPacketPosition.startPage, nextPacketPosition.startSegmentIndex);
      if (!thirdPacket) {
        return;
      }
      if (secondPacket.data[0] !== 3 || thirdPacket.data[0] !== 5) {
        return;
      }
      const lacingValues = [];
      const addBytesToSegmentTable = (bytes2) => {
        while (true) {
          lacingValues.push(Math.min(255, bytes2));
          if (bytes2 < 255) {
            break;
          }
          bytes2 -= 255;
        }
      };
      addBytesToSegmentTable(firstPacket.data.length);
      addBytesToSegmentTable(secondPacket.data.length);
      const description = new Uint8Array(
        1 + lacingValues.length + firstPacket.data.length + secondPacket.data.length + thirdPacket.data.length
      );
      description[0] = 2;
      description.set(
        lacingValues,
        1
      );
      description.set(
        firstPacket.data,
        1 + lacingValues.length
      );
      description.set(
        secondPacket.data,
        1 + lacingValues.length + firstPacket.data.length
      );
      description.set(
        thirdPacket.data,
        1 + lacingValues.length + firstPacket.data.length + secondPacket.data.length
      );
      bitstream.codecInfo.codec = "vorbis";
      bitstream.description = description;
      bitstream.lastMetadataPacket = thirdPacket;
      const view2 = toDataView(firstPacket.data);
      bitstream.numberOfChannels = view2.getUint8(11);
      bitstream.sampleRate = view2.getUint32(12, true);
      const blockSizeByte = view2.getUint8(28);
      bitstream.codecInfo.vorbisInfo = {
        blocksizes: [
          1 << (blockSizeByte & 15),
          1 << (blockSizeByte >> 4)
        ],
        modeBlockflags: parseModesFromVorbisSetupPacket(thirdPacket.data).modeBlockflags
      };
      readVorbisComments(secondPacket.data.subarray(7), this.metadataTags);
    }
    async readOpusMetadata(firstPacket, bitstream) {
      const nextPacketPosition = await this.findNextPacketStart(firstPacket);
      if (!nextPacketPosition) {
        return;
      }
      const secondPacket = await this.readPacket(
        nextPacketPosition.startPage,
        nextPacketPosition.startSegmentIndex
      );
      if (!secondPacket) {
        return;
      }
      bitstream.codecInfo.codec = "opus";
      bitstream.description = firstPacket.data;
      bitstream.lastMetadataPacket = secondPacket;
      const header = parseOpusIdentificationHeader(firstPacket.data);
      bitstream.numberOfChannels = header.outputChannelCount;
      bitstream.sampleRate = OPUS_SAMPLE_RATE;
      bitstream.codecInfo.opusInfo = {
        preSkip: header.preSkip
      };
      readVorbisComments(secondPacket.data.subarray(8), this.metadataTags);
    }
    async readPacket(startPage, startSegmentIndex) {
      assert(startSegmentIndex < startPage.lacingValues.length);
      let startDataOffset = 0;
      for (let i = 0; i < startSegmentIndex; i++) {
        startDataOffset += startPage.lacingValues[i];
      }
      let currentPage = startPage;
      let currentDataOffset = startDataOffset;
      let currentSegmentIndex = startSegmentIndex;
      const chunks = [];
      outer:
        while (true) {
          let pageSlice = this.reader.requestSlice(currentPage.dataStartPos, currentPage.dataSize);
          if (pageSlice instanceof Promise) pageSlice = await pageSlice;
          assert(pageSlice);
          const pageData = readBytes(pageSlice, currentPage.dataSize);
          while (true) {
            if (currentSegmentIndex === currentPage.lacingValues.length) {
              chunks.push(pageData.subarray(startDataOffset, currentDataOffset));
              break;
            }
            const lacingValue = currentPage.lacingValues[currentSegmentIndex];
            currentDataOffset += lacingValue;
            if (lacingValue < 255) {
              chunks.push(pageData.subarray(startDataOffset, currentDataOffset));
              break outer;
            }
            currentSegmentIndex++;
          }
          let currentPos = currentPage.headerStartPos + currentPage.totalSize;
          while (true) {
            let headerSlice = this.reader.requestSliceRange(currentPos, MIN_PAGE_HEADER_SIZE, MAX_PAGE_HEADER_SIZE);
            if (headerSlice instanceof Promise) headerSlice = await headerSlice;
            if (!headerSlice) {
              return null;
            }
            const nextPage = readPageHeader(headerSlice);
            if (!nextPage) {
              return null;
            }
            currentPage = nextPage;
            if (currentPage.serialNumber === startPage.serialNumber) {
              break;
            }
            currentPos = currentPage.headerStartPos + currentPage.totalSize;
          }
          startDataOffset = 0;
          currentDataOffset = 0;
          currentSegmentIndex = 0;
        }
      const totalPacketSize = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
      if (totalPacketSize === 0) {
        return null;
      }
      const packetData = new Uint8Array(totalPacketSize);
      let offset = 0;
      for (let i = 0; i < chunks.length; i++) {
        const chunk = chunks[i];
        packetData.set(chunk, offset);
        offset += chunk.length;
      }
      return {
        data: packetData,
        endPage: currentPage,
        endSegmentIndex: currentSegmentIndex
      };
    }
    async findNextPacketStart(lastPacket) {
      if (lastPacket.endSegmentIndex < lastPacket.endPage.lacingValues.length - 1) {
        return { startPage: lastPacket.endPage, startSegmentIndex: lastPacket.endSegmentIndex + 1 };
      }
      const isEos = !!(lastPacket.endPage.headerType & 4);
      if (isEos) {
        return null;
      }
      let currentPos = lastPacket.endPage.headerStartPos + lastPacket.endPage.totalSize;
      while (true) {
        let slice = this.reader.requestSliceRange(currentPos, MIN_PAGE_HEADER_SIZE, MAX_PAGE_HEADER_SIZE);
        if (slice instanceof Promise) slice = await slice;
        if (!slice) {
          return null;
        }
        const nextPage = readPageHeader(slice);
        if (!nextPage) {
          return null;
        }
        if (nextPage.serialNumber === lastPacket.endPage.serialNumber) {
          return { startPage: nextPage, startSegmentIndex: 0 };
        }
        currentPos = nextPage.headerStartPos + nextPage.totalSize;
      }
    }
    async getMimeType() {
      await this.readMetadata();
      const codecStrings = await Promise.all(this.tracks.map((x) => x.getCodecParameterString()));
      return buildOggMimeType({
        codecStrings: codecStrings.filter(Boolean)
      });
    }
    async getTracks() {
      await this.readMetadata();
      return this.tracks;
    }
    async computeDuration() {
      const tracks = await this.getTracks();
      const trackDurations = await Promise.all(tracks.map((x) => x.computeDuration()));
      return Math.max(0, ...trackDurations);
    }
    async getMetadataTags() {
      await this.readMetadata();
      return this.metadataTags;
    }
  };
  var OggAudioTrackBacking = class {
    constructor(bitstream, demuxer) {
      this.bitstream = bitstream;
      this.demuxer = demuxer;
      this.encodedPacketToMetadata = /* @__PURE__ */ new WeakMap();
      this.sequentialScanCache = [];
      this.sequentialScanMutex = new AsyncMutex();
      this.internalSampleRate = bitstream.codecInfo.codec === "opus" ? OPUS_SAMPLE_RATE : bitstream.sampleRate;
    }
    getId() {
      return this.bitstream.serialNumber;
    }
    getNumber() {
      const index = this.demuxer.tracks.findIndex(
        (t) => t._backing.bitstream === this.bitstream
      );
      assert(index !== -1);
      return index + 1;
    }
    getNumberOfChannels() {
      return this.bitstream.numberOfChannels;
    }
    getSampleRate() {
      return this.bitstream.sampleRate;
    }
    getTimeResolution() {
      return this.bitstream.sampleRate;
    }
    getCodec() {
      return this.bitstream.codecInfo.codec;
    }
    getInternalCodecId() {
      return null;
    }
    async getDecoderConfig() {
      assert(this.bitstream.codecInfo.codec);
      return {
        codec: this.bitstream.codecInfo.codec,
        numberOfChannels: this.bitstream.numberOfChannels,
        sampleRate: this.bitstream.sampleRate,
        description: this.bitstream.description ?? void 0
      };
    }
    getName() {
      return null;
    }
    getLanguageCode() {
      return UNDETERMINED_LANGUAGE;
    }
    getDisposition() {
      return {
        ...DEFAULT_TRACK_DISPOSITION
      };
    }
    async getFirstTimestamp() {
      return 0;
    }
    async computeDuration() {
      const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
      return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    granulePositionToTimestampInSamples(granulePosition) {
      if (this.bitstream.codecInfo.codec === "opus") {
        assert(this.bitstream.codecInfo.opusInfo);
        return granulePosition - this.bitstream.codecInfo.opusInfo.preSkip;
      }
      return granulePosition;
    }
    createEncodedPacketFromOggPacket(packet, additional, options) {
      if (!packet) {
        return null;
      }
      const { durationInSamples, vorbisBlockSize } = extractSampleMetadata(
        packet.data,
        this.bitstream.codecInfo,
        additional.vorbisLastBlocksize
      );
      const encodedPacket = new EncodedPacket(
        options.metadataOnly ? PLACEHOLDER_DATA : packet.data,
        "key",
        Math.max(0, additional.timestampInSamples) / this.internalSampleRate,
        durationInSamples / this.internalSampleRate,
        packet.endPage.headerStartPos + packet.endSegmentIndex,
        packet.data.byteLength
      );
      this.encodedPacketToMetadata.set(encodedPacket, {
        packet,
        timestampInSamples: additional.timestampInSamples,
        durationInSamples,
        vorbisLastBlockSize: additional.vorbisLastBlocksize,
        vorbisBlockSize
      });
      return encodedPacket;
    }
    async getFirstPacket(options) {
      assert(this.bitstream.lastMetadataPacket);
      const packetPosition = await this.demuxer.findNextPacketStart(this.bitstream.lastMetadataPacket);
      if (!packetPosition) {
        return null;
      }
      let timestampInSamples = 0;
      if (this.bitstream.codecInfo.codec === "opus") {
        assert(this.bitstream.codecInfo.opusInfo);
        timestampInSamples -= this.bitstream.codecInfo.opusInfo.preSkip;
      }
      const packet = await this.demuxer.readPacket(packetPosition.startPage, packetPosition.startSegmentIndex);
      return this.createEncodedPacketFromOggPacket(
        packet,
        {
          timestampInSamples,
          vorbisLastBlocksize: null
        },
        options
      );
    }
    async getNextPacket(prevPacket, options) {
      const prevMetadata = this.encodedPacketToMetadata.get(prevPacket);
      if (!prevMetadata) {
        throw new Error("Packet was not created from this track.");
      }
      const packetPosition = await this.demuxer.findNextPacketStart(prevMetadata.packet);
      if (!packetPosition) {
        return null;
      }
      const timestampInSamples = prevMetadata.timestampInSamples + prevMetadata.durationInSamples;
      const packet = await this.demuxer.readPacket(
        packetPosition.startPage,
        packetPosition.startSegmentIndex
      );
      return this.createEncodedPacketFromOggPacket(
        packet,
        {
          timestampInSamples,
          vorbisLastBlocksize: prevMetadata.vorbisBlockSize
        },
        options
      );
    }
    async getPacket(timestamp, options) {
      if (this.demuxer.reader.fileSize === null) {
        return this.getPacketSequential(timestamp, options);
      }
      const timestampInSamples = roundIfAlmostInteger(timestamp * this.internalSampleRate);
      if (timestampInSamples === 0) {
        return this.getFirstPacket(options);
      }
      if (timestampInSamples < 0) {
        return null;
      }
      assert(this.bitstream.lastMetadataPacket);
      const startPosition = await this.demuxer.findNextPacketStart(this.bitstream.lastMetadataPacket);
      if (!startPosition) {
        return null;
      }
      let lowPage = startPosition.startPage;
      let high = this.demuxer.reader.fileSize;
      const lowPages = [lowPage];
      outer:
        while (lowPage.headerStartPos + lowPage.totalSize < high) {
          const low = lowPage.headerStartPos;
          const mid = Math.floor((low + high) / 2);
          let searchStartPos = mid;
          while (true) {
            const until = Math.min(
              searchStartPos + MAX_PAGE_SIZE,
              high - MIN_PAGE_HEADER_SIZE
            );
            let searchSlice = this.demuxer.reader.requestSlice(searchStartPos, until - searchStartPos);
            if (searchSlice instanceof Promise) searchSlice = await searchSlice;
            assert(searchSlice);
            const found = findNextPageHeader(searchSlice, until);
            if (!found) {
              high = mid + MIN_PAGE_HEADER_SIZE;
              continue outer;
            }
            let headerSlice = this.demuxer.reader.requestSliceRange(
              searchSlice.filePos,
              MIN_PAGE_HEADER_SIZE,
              MAX_PAGE_HEADER_SIZE
            );
            if (headerSlice instanceof Promise) headerSlice = await headerSlice;
            assert(headerSlice);
            const page = readPageHeader(headerSlice);
            assert(page);
            let pageValid = false;
            if (page.serialNumber === this.bitstream.serialNumber) {
              pageValid = true;
            } else {
              let pageSlice = this.demuxer.reader.requestSlice(page.headerStartPos, page.totalSize);
              if (pageSlice instanceof Promise) pageSlice = await pageSlice;
              assert(pageSlice);
              const bytes2 = readBytes(pageSlice, page.totalSize);
              const crc = computeOggPageCrc(bytes2);
              pageValid = crc === page.checksum;
            }
            if (!pageValid) {
              searchStartPos = page.headerStartPos + 4;
              continue;
            }
            if (pageValid && page.serialNumber !== this.bitstream.serialNumber) {
              searchStartPos = page.headerStartPos + page.totalSize;
              continue;
            }
            const isContinuationPage = page.granulePosition === -1;
            if (isContinuationPage) {
              searchStartPos = page.headerStartPos + page.totalSize;
              continue;
            }
            if (this.granulePositionToTimestampInSamples(page.granulePosition) > timestampInSamples) {
              high = page.headerStartPos;
            } else {
              lowPage = page;
              lowPages.push(page);
            }
            continue outer;
          }
        }
      let lowerPage = startPosition.startPage;
      for (const otherLowPage of lowPages) {
        if (otherLowPage.granulePosition === lowPage.granulePosition) {
          break;
        }
        if (!lowerPage || otherLowPage.headerStartPos > lowerPage.headerStartPos) {
          lowerPage = otherLowPage;
        }
      }
      let currentPage = lowerPage;
      const previousPages = [currentPage];
      while (true) {
        if (currentPage.serialNumber === this.bitstream.serialNumber && currentPage.granulePosition === lowPage.granulePosition) {
          break;
        }
        const nextPos = currentPage.headerStartPos + currentPage.totalSize;
        let slice = this.demuxer.reader.requestSliceRange(nextPos, MIN_PAGE_HEADER_SIZE, MAX_PAGE_HEADER_SIZE);
        if (slice instanceof Promise) slice = await slice;
        assert(slice);
        const nextPage = readPageHeader(slice);
        assert(nextPage);
        currentPage = nextPage;
        if (currentPage.serialNumber === this.bitstream.serialNumber) {
          previousPages.push(currentPage);
        }
      }
      assert(currentPage.granulePosition !== -1);
      let currentSegmentIndex = null;
      let currentTimestampInSamples;
      let currentTimestampIsCorrect;
      let endPage = currentPage;
      let endSegmentIndex = 0;
      if (currentPage.headerStartPos === startPosition.startPage.headerStartPos) {
        currentTimestampInSamples = this.granulePositionToTimestampInSamples(0);
        currentTimestampIsCorrect = true;
        currentSegmentIndex = 0;
      } else {
        currentTimestampInSamples = 0;
        currentTimestampIsCorrect = false;
        for (let i = currentPage.lacingValues.length - 1; i >= 0; i--) {
          const value = currentPage.lacingValues[i];
          if (value < 255) {
            currentSegmentIndex = i + 1;
            break;
          }
        }
        if (currentSegmentIndex === null) {
          throw new Error("Invalid page with granule position: no packets end on this page.");
        }
        endSegmentIndex = currentSegmentIndex - 1;
        const pseudopacket = {
          data: PLACEHOLDER_DATA,
          endPage,
          endSegmentIndex
        };
        const nextPosition = await this.demuxer.findNextPacketStart(pseudopacket);
        if (nextPosition) {
          const endPosition = findPreviousPacketEndPosition(previousPages, currentPage, currentSegmentIndex);
          assert(endPosition);
          const startPosition2 = findPacketStartPosition(
            previousPages,
            endPosition.page,
            endPosition.segmentIndex
          );
          if (startPosition2) {
            currentPage = startPosition2.page;
            currentSegmentIndex = startPosition2.segmentIndex;
          }
        } else {
          while (true) {
            const endPosition = findPreviousPacketEndPosition(
              previousPages,
              currentPage,
              currentSegmentIndex
            );
            if (!endPosition) {
              break;
            }
            const startPosition2 = findPacketStartPosition(
              previousPages,
              endPosition.page,
              endPosition.segmentIndex
            );
            if (!startPosition2) {
              break;
            }
            currentPage = startPosition2.page;
            currentSegmentIndex = startPosition2.segmentIndex;
            if (endPosition.page.headerStartPos !== endPage.headerStartPos) {
              endPage = endPosition.page;
              endSegmentIndex = endPosition.segmentIndex;
              break;
            }
          }
        }
      }
      let lastEncodedPacket = null;
      let lastEncodedPacketMetadata = null;
      while (currentPage !== null) {
        assert(currentSegmentIndex !== null);
        const packet = await this.demuxer.readPacket(currentPage, currentSegmentIndex);
        if (!packet) {
          break;
        }
        const skipPacket = currentPage.headerStartPos === startPosition.startPage.headerStartPos && currentSegmentIndex < startPosition.startSegmentIndex;
        if (!skipPacket) {
          let encodedPacket = this.createEncodedPacketFromOggPacket(
            packet,
            {
              timestampInSamples: currentTimestampInSamples,
              vorbisLastBlocksize: lastEncodedPacketMetadata?.vorbisBlockSize ?? null
            },
            options
          );
          assert(encodedPacket);
          let encodedPacketMetadata = this.encodedPacketToMetadata.get(encodedPacket);
          assert(encodedPacketMetadata);
          if (!currentTimestampIsCorrect && packet.endPage.headerStartPos === endPage.headerStartPos && packet.endSegmentIndex === endSegmentIndex) {
            currentTimestampInSamples = this.granulePositionToTimestampInSamples(
              currentPage.granulePosition
            );
            currentTimestampIsCorrect = true;
            encodedPacket = this.createEncodedPacketFromOggPacket(
              packet,
              {
                timestampInSamples: currentTimestampInSamples - encodedPacketMetadata.durationInSamples,
                vorbisLastBlocksize: lastEncodedPacketMetadata?.vorbisBlockSize ?? null
              },
              options
            );
            assert(encodedPacket);
            encodedPacketMetadata = this.encodedPacketToMetadata.get(encodedPacket);
            assert(encodedPacketMetadata);
          } else {
            currentTimestampInSamples += encodedPacketMetadata.durationInSamples;
          }
          lastEncodedPacket = encodedPacket;
          lastEncodedPacketMetadata = encodedPacketMetadata;
          if (currentTimestampIsCorrect && // Next timestamp will be too late
          (Math.max(currentTimestampInSamples, 0) > timestampInSamples || Math.max(encodedPacketMetadata.timestampInSamples, 0) === timestampInSamples)) {
            break;
          }
        }
        const nextPosition = await this.demuxer.findNextPacketStart(packet);
        if (!nextPosition) {
          break;
        }
        currentPage = nextPosition.startPage;
        currentSegmentIndex = nextPosition.startSegmentIndex;
      }
      return lastEncodedPacket;
    }
    // A slower but simpler and sequential algorithm for finding a packet in a file
    async getPacketSequential(timestamp, options) {
      const release = await this.sequentialScanMutex.acquire();
      try {
        const timestampInSamples = roundIfAlmostInteger(timestamp * this.internalSampleRate);
        timestamp = timestampInSamples / this.internalSampleRate;
        const index = binarySearchLessOrEqual(
          this.sequentialScanCache,
          timestampInSamples,
          (x) => x.timestampInSamples
        );
        let currentPacket;
        if (index !== -1) {
          const cacheEntry = this.sequentialScanCache[index];
          currentPacket = this.createEncodedPacketFromOggPacket(
            cacheEntry.packet,
            {
              timestampInSamples: cacheEntry.timestampInSamples,
              vorbisLastBlocksize: cacheEntry.vorbisLastBlockSize
            },
            options
          );
        } else {
          currentPacket = await this.getFirstPacket(options);
        }
        let i = 0;
        while (currentPacket && currentPacket.timestamp < timestamp) {
          const nextPacket = await this.getNextPacket(currentPacket, options);
          if (!nextPacket || nextPacket.timestamp > timestamp) {
            break;
          }
          currentPacket = nextPacket;
          i++;
          if (i === 100) {
            i = 0;
            const metadata = this.encodedPacketToMetadata.get(currentPacket);
            assert(metadata);
            if (this.sequentialScanCache.length > 0) {
              assert(last(this.sequentialScanCache).timestampInSamples <= metadata.timestampInSamples);
            }
            this.sequentialScanCache.push(metadata);
          }
        }
        return currentPacket;
      } finally {
        release();
      }
    }
    getKeyPacket(timestamp, options) {
      return this.getPacket(timestamp, options);
    }
    getNextKeyPacket(packet, options) {
      return this.getNextPacket(packet, options);
    }
  };
  var findPacketStartPosition = (pageList, endPage, endSegmentIndex) => {
    let page = endPage;
    let segmentIndex = endSegmentIndex;
    outer:
      while (true) {
        segmentIndex--;
        for (segmentIndex; segmentIndex >= 0; segmentIndex--) {
          const lacingValue = page.lacingValues[segmentIndex];
          if (lacingValue < 255) {
            segmentIndex++;
            break outer;
          }
        }
        assert(segmentIndex === -1);
        const pageStartsWithFreshPacket = !(page.headerType & 1);
        if (pageStartsWithFreshPacket) {
          segmentIndex = 0;
          break;
        }
        const previousPage = findLast(
          pageList,
          (x) => x.headerStartPos < page.headerStartPos
        );
        if (!previousPage) {
          return null;
        }
        page = previousPage;
        segmentIndex = page.lacingValues.length;
      }
    assert(segmentIndex !== -1);
    if (segmentIndex === page.lacingValues.length) {
      const nextPage = pageList[pageList.indexOf(page) + 1];
      assert(nextPage);
      page = nextPage;
      segmentIndex = 0;
    }
    return { page, segmentIndex };
  };
  var findPreviousPacketEndPosition = (pageList, startPage, startSegmentIndex) => {
    if (startSegmentIndex > 0) {
      return { page: startPage, segmentIndex: startSegmentIndex - 1 };
    }
    const previousPage = findLast(
      pageList,
      (x) => x.headerStartPos < startPage.headerStartPos
    );
    if (!previousPage) {
      return null;
    }
    return { page: previousPage, segmentIndex: previousPage.lacingValues.length - 1 };
  };

  // src/wave/wave-demuxer.ts
  var WaveDemuxer = class extends Demuxer {
    constructor(input) {
      super(input);
      this.metadataPromise = null;
      this.dataStart = -1;
      this.dataSize = -1;
      this.audioInfo = null;
      this.tracks = [];
      this.lastKnownPacketIndex = 0;
      this.metadataTags = {};
      this.reader = input._reader;
    }
    async readMetadata() {
      return this.metadataPromise ??= (async () => {
        let slice = this.reader.requestSlice(0, 12);
        if (slice instanceof Promise) slice = await slice;
        assert(slice);
        const riffType = readAscii(slice, 4);
        const littleEndian = riffType !== "RIFX";
        const isRf64 = riffType === "RF64";
        const outerChunkSize = readU32(slice, littleEndian);
        let totalFileSize = isRf64 ? this.reader.fileSize : Math.min(outerChunkSize + 8, this.reader.fileSize ?? Infinity);
        const format = readAscii(slice, 4);
        if (format !== "WAVE") {
          throw new Error("Invalid WAVE file - wrong format");
        }
        let chunksRead = 0;
        let dataChunkSize = null;
        let currentPos = slice.filePos;
        while (totalFileSize === null || currentPos < totalFileSize) {
          let slice2 = this.reader.requestSlice(currentPos, 8);
          if (slice2 instanceof Promise) slice2 = await slice2;
          if (!slice2) break;
          const chunkId = readAscii(slice2, 4);
          const chunkSize = readU32(slice2, littleEndian);
          const startPos = slice2.filePos;
          if (isRf64 && chunksRead === 0 && chunkId !== "ds64") {
            throw new Error('Invalid RF64 file: First chunk must be "ds64".');
          }
          if (chunkId === "fmt ") {
            await this.parseFmtChunk(startPos, chunkSize, littleEndian);
          } else if (chunkId === "data") {
            dataChunkSize ??= chunkSize;
            this.dataStart = slice2.filePos;
            this.dataSize = Math.min(dataChunkSize, (totalFileSize ?? Infinity) - this.dataStart);
            if (this.reader.fileSize === null) {
              break;
            }
          } else if (chunkId === "ds64") {
            let ds64Slice = this.reader.requestSlice(startPos, chunkSize);
            if (ds64Slice instanceof Promise) ds64Slice = await ds64Slice;
            if (!ds64Slice) break;
            const riffChunkSize = readU64(ds64Slice, littleEndian);
            dataChunkSize = readU64(ds64Slice, littleEndian);
            totalFileSize = Math.min(riffChunkSize + 8, this.reader.fileSize ?? Infinity);
          } else if (chunkId === "LIST") {
            await this.parseListChunk(startPos, chunkSize, littleEndian);
          } else if (chunkId === "ID3 " || chunkId === "id3 ") {
            await this.parseId3Chunk(startPos, chunkSize);
          }
          currentPos = startPos + chunkSize + (chunkSize & 1);
          chunksRead++;
        }
        if (!this.audioInfo) {
          throw new Error('Invalid WAVE file - missing "fmt " chunk');
        }
        if (this.dataStart === -1) {
          throw new Error('Invalid WAVE file - missing "data" chunk');
        }
        const blockSize = this.audioInfo.blockSizeInBytes;
        this.dataSize = Math.floor(this.dataSize / blockSize) * blockSize;
        this.tracks.push(new InputAudioTrack(this.input, new WaveAudioTrackBacking(this)));
      })();
    }
    async parseFmtChunk(startPos, size, littleEndian) {
      let slice = this.reader.requestSlice(startPos, size);
      if (slice instanceof Promise) slice = await slice;
      if (!slice) return;
      let formatTag = readU16(slice, littleEndian);
      const numChannels = readU16(slice, littleEndian);
      const sampleRate = readU32(slice, littleEndian);
      slice.skip(4);
      const blockAlign = readU16(slice, littleEndian);
      let bitsPerSample;
      if (size === 14) {
        bitsPerSample = 8;
      } else {
        bitsPerSample = readU16(slice, littleEndian);
      }
      if (size >= 18 && formatTag !== 357) {
        const cbSize = readU16(slice, littleEndian);
        const remainingSize = size - 18;
        const extensionSize = Math.min(remainingSize, cbSize);
        if (extensionSize >= 22 && formatTag === 65534 /* EXTENSIBLE */) {
          slice.skip(2 + 4);
          const subFormat = readBytes(slice, 16);
          formatTag = subFormat[0] | subFormat[1] << 8;
        }
      }
      if (formatTag === 7 /* MULAW */ || formatTag === 6 /* ALAW */) {
        bitsPerSample = 8;
      }
      this.audioInfo = {
        format: formatTag,
        numberOfChannels: numChannels,
        sampleRate,
        sampleSizeInBytes: Math.ceil(bitsPerSample / 8),
        blockSizeInBytes: blockAlign
      };
    }
    async parseListChunk(startPos, size, littleEndian) {
      let slice = this.reader.requestSlice(startPos, size);
      if (slice instanceof Promise) slice = await slice;
      if (!slice) return;
      const infoType = readAscii(slice, 4);
      if (infoType !== "INFO" && infoType !== "INF0") {
        return;
      }
      let currentPos = slice.filePos;
      while (currentPos <= startPos + size - 8) {
        slice.filePos = currentPos;
        const chunkName = readAscii(slice, 4);
        const chunkSize = readU32(slice, littleEndian);
        const bytes2 = readBytes(slice, chunkSize);
        let stringLength = 0;
        for (let i = 0; i < bytes2.length; i++) {
          if (bytes2[i] === 0) {
            break;
          }
          stringLength++;
        }
        const value = String.fromCharCode(...bytes2.subarray(0, stringLength));
        this.metadataTags.raw ??= {};
        this.metadataTags.raw[chunkName] = value;
        switch (chunkName) {
          case "INAM":
          case "TITL":
            {
              this.metadataTags.title ??= value;
            }
            ;
            break;
          case "TIT3":
            {
              this.metadataTags.description ??= value;
            }
            ;
            break;
          case "IART":
            {
              this.metadataTags.artist ??= value;
            }
            ;
            break;
          case "IPRD":
            {
              this.metadataTags.album ??= value;
            }
            ;
            break;
          case "IPRT":
          case "ITRK":
          case "TRCK":
            {
              const parts = value.split("/");
              const trackNum = Number.parseInt(parts[0], 10);
              const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);
              if (Number.isInteger(trackNum) && trackNum > 0) {
                this.metadataTags.trackNumber ??= trackNum;
              }
              if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {
                this.metadataTags.tracksTotal ??= tracksTotal;
              }
            }
            ;
            break;
          case "ICRD":
          case "IDIT":
            {
              const date = new Date(value);
              if (!Number.isNaN(date.getTime())) {
                this.metadataTags.date ??= date;
              }
            }
            ;
            break;
          case "YEAR":
            {
              const year = Number.parseInt(value, 10);
              if (Number.isInteger(year) && year > 0) {
                this.metadataTags.date ??= new Date(year, 0, 1);
              }
            }
            ;
            break;
          case "IGNR":
          case "GENR":
            {
              this.metadataTags.genre ??= value;
            }
            ;
            break;
          case "ICMT":
          case "CMNT":
          case "COMM":
            {
              this.metadataTags.comment ??= value;
            }
            ;
            break;
        }
        currentPos += 8 + chunkSize + (chunkSize & 1);
      }
    }
    async parseId3Chunk(startPos, size) {
      let slice = this.reader.requestSlice(startPos, size);
      if (slice instanceof Promise) slice = await slice;
      if (!slice) return;
      const id3V2Header = readId3V2Header(slice);
      if (id3V2Header) {
        const availableSize = size - ID3_V2_HEADER_SIZE;
        id3V2Header.size = Math.min(id3V2Header.size, availableSize);
        if (id3V2Header.size > 0) {
          const contentSlice = slice.slice(startPos + ID3_V2_HEADER_SIZE, id3V2Header.size);
          parseId3V2Tag(contentSlice, id3V2Header, this.metadataTags);
        }
      }
    }
    getCodec() {
      assert(this.audioInfo);
      if (this.audioInfo.format === 7 /* MULAW */) {
        return "ulaw";
      }
      if (this.audioInfo.format === 6 /* ALAW */) {
        return "alaw";
      }
      if (this.audioInfo.format === 1 /* PCM */) {
        if (this.audioInfo.sampleSizeInBytes === 1) {
          return "pcm-u8";
        } else if (this.audioInfo.sampleSizeInBytes === 2) {
          return "pcm-s16";
        } else if (this.audioInfo.sampleSizeInBytes === 3) {
          return "pcm-s24";
        } else if (this.audioInfo.sampleSizeInBytes === 4) {
          return "pcm-s32";
        }
      }
      if (this.audioInfo.format === 3 /* IEEE_FLOAT */) {
        if (this.audioInfo.sampleSizeInBytes === 4) {
          return "pcm-f32";
        }
      }
      return null;
    }
    async getMimeType() {
      return "audio/wav";
    }
    async computeDuration() {
      await this.readMetadata();
      const track = this.tracks[0];
      assert(track);
      return track.computeDuration();
    }
    async getTracks() {
      await this.readMetadata();
      return this.tracks;
    }
    async getMetadataTags() {
      await this.readMetadata();
      return this.metadataTags;
    }
  };
  var PACKET_SIZE_IN_FRAMES = 2048;
  var WaveAudioTrackBacking = class {
    constructor(demuxer) {
      this.demuxer = demuxer;
    }
    getId() {
      return 1;
    }
    getNumber() {
      return 1;
    }
    getCodec() {
      return this.demuxer.getCodec();
    }
    getInternalCodecId() {
      assert(this.demuxer.audioInfo);
      return this.demuxer.audioInfo.format;
    }
    async getDecoderConfig() {
      const codec = this.demuxer.getCodec();
      if (!codec) {
        return null;
      }
      assert(this.demuxer.audioInfo);
      return {
        codec,
        numberOfChannels: this.demuxer.audioInfo.numberOfChannels,
        sampleRate: this.demuxer.audioInfo.sampleRate
      };
    }
    async computeDuration() {
      const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
      return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    getNumberOfChannels() {
      assert(this.demuxer.audioInfo);
      return this.demuxer.audioInfo.numberOfChannels;
    }
    getSampleRate() {
      assert(this.demuxer.audioInfo);
      return this.demuxer.audioInfo.sampleRate;
    }
    getTimeResolution() {
      assert(this.demuxer.audioInfo);
      return this.demuxer.audioInfo.sampleRate;
    }
    getName() {
      return null;
    }
    getLanguageCode() {
      return UNDETERMINED_LANGUAGE;
    }
    getDisposition() {
      return {
        ...DEFAULT_TRACK_DISPOSITION
      };
    }
    async getFirstTimestamp() {
      return 0;
    }
    async getPacketAtIndex(packetIndex, options) {
      assert(packetIndex >= 0);
      assert(this.demuxer.audioInfo);
      const startOffset = packetIndex * PACKET_SIZE_IN_FRAMES * this.demuxer.audioInfo.blockSizeInBytes;
      if (startOffset >= this.demuxer.dataSize) {
        return null;
      }
      const sizeInBytes = Math.min(
        PACKET_SIZE_IN_FRAMES * this.demuxer.audioInfo.blockSizeInBytes,
        this.demuxer.dataSize - startOffset
      );
      if (this.demuxer.reader.fileSize === null) {
        let slice = this.demuxer.reader.requestSlice(this.demuxer.dataStart + startOffset, sizeInBytes);
        if (slice instanceof Promise) slice = await slice;
        if (!slice) {
          return null;
        }
      }
      let data;
      if (options.metadataOnly) {
        data = PLACEHOLDER_DATA;
      } else {
        let slice = this.demuxer.reader.requestSlice(this.demuxer.dataStart + startOffset, sizeInBytes);
        if (slice instanceof Promise) slice = await slice;
        assert(slice);
        data = readBytes(slice, sizeInBytes);
      }
      const timestamp = packetIndex * PACKET_SIZE_IN_FRAMES / this.demuxer.audioInfo.sampleRate;
      const duration = sizeInBytes / this.demuxer.audioInfo.blockSizeInBytes / this.demuxer.audioInfo.sampleRate;
      this.demuxer.lastKnownPacketIndex = Math.max(
        packetIndex,
        this.demuxer.lastKnownPacketIndex
      );
      return new EncodedPacket(
        data,
        "key",
        timestamp,
        duration,
        packetIndex,
        sizeInBytes
      );
    }
    getFirstPacket(options) {
      return this.getPacketAtIndex(0, options);
    }
    async getPacket(timestamp, options) {
      assert(this.demuxer.audioInfo);
      const packetIndex = Math.floor(Math.min(
        timestamp * this.demuxer.audioInfo.sampleRate / PACKET_SIZE_IN_FRAMES,
        (this.demuxer.dataSize - 1) / (PACKET_SIZE_IN_FRAMES * this.demuxer.audioInfo.blockSizeInBytes)
      ));
      if (packetIndex < 0) {
        return null;
      }
      const packet = await this.getPacketAtIndex(packetIndex, options);
      if (packet) {
        return packet;
      }
      if (packetIndex === 0) {
        return null;
      }
      assert(this.demuxer.reader.fileSize === null);
      let currentPacket = await this.getPacketAtIndex(this.demuxer.lastKnownPacketIndex, options);
      while (currentPacket) {
        const nextPacket = await this.getNextPacket(currentPacket, options);
        if (!nextPacket) {
          break;
        }
        currentPacket = nextPacket;
      }
      return currentPacket;
    }
    getNextPacket(packet, options) {
      assert(this.demuxer.audioInfo);
      const packetIndex = Math.round(packet.timestamp * this.demuxer.audioInfo.sampleRate / PACKET_SIZE_IN_FRAMES);
      return this.getPacketAtIndex(packetIndex + 1, options);
    }
    getKeyPacket(timestamp, options) {
      return this.getPacket(timestamp, options);
    }
    getNextKeyPacket(packet, options) {
      return this.getNextPacket(packet, options);
    }
  };

  // src/adts/adts-reader.ts
  var MIN_ADTS_FRAME_HEADER_SIZE = 7;
  var MAX_ADTS_FRAME_HEADER_SIZE = 9;
  var readAdtsFrameHeader = (slice) => {
    const startPos = slice.filePos;
    const bytes2 = readBytes(slice, 9);
    const bitstream = new Bitstream(bytes2);
    const syncword = bitstream.readBits(12);
    if (syncword !== 4095) {
      return null;
    }
    bitstream.skipBits(1);
    const layer = bitstream.readBits(2);
    if (layer !== 0) {
      return null;
    }
    const protectionAbsence = bitstream.readBits(1);
    const objectType = bitstream.readBits(2) + 1;
    const samplingFrequencyIndex = bitstream.readBits(4);
    if (samplingFrequencyIndex === 15) {
      return null;
    }
    bitstream.skipBits(1);
    const channelConfiguration = bitstream.readBits(3);
    if (channelConfiguration === 0) {
      throw new Error("ADTS frames with channel configuration 0 are not supported.");
    }
    bitstream.skipBits(1);
    bitstream.skipBits(1);
    bitstream.skipBits(1);
    bitstream.skipBits(1);
    const frameLength = bitstream.readBits(13);
    bitstream.skipBits(11);
    const numberOfAacFrames = bitstream.readBits(2) + 1;
    if (numberOfAacFrames !== 1) {
      throw new Error("ADTS frames with more than one AAC frame are not supported.");
    }
    let crcCheck = null;
    if (protectionAbsence === 1) {
      slice.filePos -= 2;
    } else {
      crcCheck = bitstream.readBits(16);
    }
    return {
      objectType,
      samplingFrequencyIndex,
      channelConfiguration,
      frameLength,
      numberOfAacFrames,
      crcCheck,
      startPos
    };
  };

  // src/adts/adts-demuxer.ts
  var SAMPLES_PER_AAC_FRAME = 1024;
  var AdtsDemuxer = class extends Demuxer {
    constructor(input) {
      super(input);
      this.metadataPromise = null;
      this.firstFrameHeader = null;
      this.loadedSamples = [];
      this.metadataTags = null;
      this.tracks = [];
      this.readingMutex = new AsyncMutex();
      this.lastSampleLoaded = false;
      this.lastLoadedPos = 0;
      this.nextTimestampInSamples = 0;
      this.reader = input._reader;
    }
    async readMetadata() {
      return this.metadataPromise ??= (async () => {
        while (!this.firstFrameHeader && !this.lastSampleLoaded) {
          await this.advanceReader();
        }
        assert(this.firstFrameHeader);
        this.tracks = [new InputAudioTrack(this.input, new AdtsAudioTrackBacking(this))];
      })();
    }
    async advanceReader() {
      if (this.lastLoadedPos === 0) {
        while (true) {
          let slice2 = this.reader.requestSlice(this.lastLoadedPos, ID3_V2_HEADER_SIZE);
          if (slice2 instanceof Promise) slice2 = await slice2;
          if (!slice2) {
            this.lastSampleLoaded = true;
            return;
          }
          const id3V2Header = readId3V2Header(slice2);
          if (!id3V2Header) {
            break;
          }
          this.lastLoadedPos = slice2.filePos + id3V2Header.size;
        }
      }
      let slice = this.reader.requestSliceRange(
        this.lastLoadedPos,
        MIN_ADTS_FRAME_HEADER_SIZE,
        MAX_ADTS_FRAME_HEADER_SIZE
      );
      if (slice instanceof Promise) slice = await slice;
      if (!slice) {
        this.lastSampleLoaded = true;
        return;
      }
      const header = readAdtsFrameHeader(slice);
      if (!header) {
        this.lastSampleLoaded = true;
        return;
      }
      if (this.reader.fileSize !== null && header.startPos + header.frameLength > this.reader.fileSize) {
        this.lastSampleLoaded = true;
        return;
      }
      if (!this.firstFrameHeader) {
        this.firstFrameHeader = header;
      }
      const sampleRate = aacFrequencyTable[header.samplingFrequencyIndex];
      assert(sampleRate !== void 0);
      const sampleDuration = SAMPLES_PER_AAC_FRAME / sampleRate;
      const sample = {
        timestamp: this.nextTimestampInSamples / sampleRate,
        duration: sampleDuration,
        dataStart: header.startPos,
        dataSize: header.frameLength
      };
      this.loadedSamples.push(sample);
      this.nextTimestampInSamples += SAMPLES_PER_AAC_FRAME;
      this.lastLoadedPos = header.startPos + header.frameLength;
    }
    async getMimeType() {
      return "audio/aac";
    }
    async getTracks() {
      await this.readMetadata();
      return this.tracks;
    }
    async computeDuration() {
      await this.readMetadata();
      const track = this.tracks[0];
      assert(track);
      return track.computeDuration();
    }
    async getMetadataTags() {
      const release = await this.readingMutex.acquire();
      try {
        await this.readMetadata();
        if (this.metadataTags) {
          return this.metadataTags;
        }
        this.metadataTags = {};
        let currentPos = 0;
        while (true) {
          let headerSlice = this.reader.requestSlice(currentPos, ID3_V2_HEADER_SIZE);
          if (headerSlice instanceof Promise) headerSlice = await headerSlice;
          if (!headerSlice) break;
          const id3V2Header = readId3V2Header(headerSlice);
          if (!id3V2Header) {
            break;
          }
          let contentSlice = this.reader.requestSlice(headerSlice.filePos, id3V2Header.size);
          if (contentSlice instanceof Promise) contentSlice = await contentSlice;
          if (!contentSlice) break;
          parseId3V2Tag(contentSlice, id3V2Header, this.metadataTags);
          currentPos = headerSlice.filePos + id3V2Header.size;
        }
        return this.metadataTags;
      } finally {
        release();
      }
    }
  };
  var AdtsAudioTrackBacking = class {
    constructor(demuxer) {
      this.demuxer = demuxer;
    }
    getId() {
      return 1;
    }
    getNumber() {
      return 1;
    }
    async getFirstTimestamp() {
      return 0;
    }
    getTimeResolution() {
      const sampleRate = this.getSampleRate();
      return sampleRate / SAMPLES_PER_AAC_FRAME;
    }
    async computeDuration() {
      const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
      return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    getName() {
      return null;
    }
    getLanguageCode() {
      return UNDETERMINED_LANGUAGE;
    }
    getCodec() {
      return "aac";
    }
    getInternalCodecId() {
      assert(this.demuxer.firstFrameHeader);
      return this.demuxer.firstFrameHeader.objectType;
    }
    getNumberOfChannels() {
      assert(this.demuxer.firstFrameHeader);
      const numberOfChannels = aacChannelMap[this.demuxer.firstFrameHeader.channelConfiguration];
      assert(numberOfChannels !== void 0);
      return numberOfChannels;
    }
    getSampleRate() {
      assert(this.demuxer.firstFrameHeader);
      const sampleRate = aacFrequencyTable[this.demuxer.firstFrameHeader.samplingFrequencyIndex];
      assert(sampleRate !== void 0);
      return sampleRate;
    }
    getDisposition() {
      return {
        ...DEFAULT_TRACK_DISPOSITION
      };
    }
    async getDecoderConfig() {
      assert(this.demuxer.firstFrameHeader);
      return {
        codec: `mp4a.40.${this.demuxer.firstFrameHeader.objectType}`,
        numberOfChannels: this.getNumberOfChannels(),
        sampleRate: this.getSampleRate()
      };
    }
    async getPacketAtIndex(sampleIndex, options) {
      if (sampleIndex === -1) {
        return null;
      }
      const rawSample = this.demuxer.loadedSamples[sampleIndex];
      if (!rawSample) {
        return null;
      }
      let data;
      if (options.metadataOnly) {
        data = PLACEHOLDER_DATA;
      } else {
        let slice = this.demuxer.reader.requestSlice(rawSample.dataStart, rawSample.dataSize);
        if (slice instanceof Promise) slice = await slice;
        if (!slice) {
          return null;
        }
        data = readBytes(slice, rawSample.dataSize);
      }
      return new EncodedPacket(
        data,
        "key",
        rawSample.timestamp,
        rawSample.duration,
        sampleIndex,
        rawSample.dataSize
      );
    }
    getFirstPacket(options) {
      return this.getPacketAtIndex(0, options);
    }
    async getNextPacket(packet, options) {
      const release = await this.demuxer.readingMutex.acquire();
      try {
        const sampleIndex = binarySearchExact(
          this.demuxer.loadedSamples,
          packet.timestamp,
          (x) => x.timestamp
        );
        if (sampleIndex === -1) {
          throw new Error("Packet was not created from this track.");
        }
        const nextIndex = sampleIndex + 1;
        while (nextIndex >= this.demuxer.loadedSamples.length && !this.demuxer.lastSampleLoaded) {
          await this.demuxer.advanceReader();
        }
        return this.getPacketAtIndex(nextIndex, options);
      } finally {
        release();
      }
    }
    async getPacket(timestamp, options) {
      const release = await this.demuxer.readingMutex.acquire();
      try {
        while (true) {
          const index = binarySearchLessOrEqual(
            this.demuxer.loadedSamples,
            timestamp,
            (x) => x.timestamp
          );
          if (index === -1 && this.demuxer.loadedSamples.length > 0) {
            return null;
          }
          if (this.demuxer.lastSampleLoaded) {
            return this.getPacketAtIndex(index, options);
          }
          if (index >= 0 && index + 1 < this.demuxer.loadedSamples.length) {
            return this.getPacketAtIndex(index, options);
          }
          await this.demuxer.advanceReader();
        }
      } finally {
        release();
      }
    }
    getKeyPacket(timestamp, options) {
      return this.getPacket(timestamp, options);
    }
    getNextKeyPacket(packet, options) {
      return this.getNextPacket(packet, options);
    }
  };

  // src/flac/flac-misc.ts
  var getBlockSizeOrUncommon = (bits) => {
    if (bits === 0) {
      return null;
    } else if (bits === 1) {
      return 192;
    } else if (bits >= 2 && bits <= 5) {
      return 144 * 2 ** bits;
    } else if (bits === 6) {
      return "uncommon-u8";
    } else if (bits === 7) {
      return "uncommon-u16";
    } else if (bits >= 8 && bits <= 15) {
      return 2 ** bits;
    } else {
      return null;
    }
  };
  var getSampleRateOrUncommon = (sampleRateBits, streamInfoSampleRate) => {
    switch (sampleRateBits) {
      case 0:
        return streamInfoSampleRate;
      case 1:
        return 88200;
      case 2:
        return 176400;
      case 3:
        return 192e3;
      case 4:
        return 8e3;
      case 5:
        return 16e3;
      case 6:
        return 22050;
      case 7:
        return 24e3;
      case 8:
        return 32e3;
      case 9:
        return 44100;
      case 10:
        return 48e3;
      case 11:
        return 96e3;
      case 12:
        return "uncommon-u8";
      case 13:
        return "uncommon-u16";
      case 14:
        return "uncommon-u16-10";
      default:
        return null;
    }
  };
  var readCodedNumber = (fileSlice) => {
    let ones = 0;
    const bitstream1 = new Bitstream(readBytes(fileSlice, 1));
    while (bitstream1.readBits(1) === 1) {
      ones++;
    }
    if (ones === 0) {
      return bitstream1.readBits(7);
    }
    const bitArray = [];
    const extraBytes = ones - 1;
    const bitstream2 = new Bitstream(readBytes(fileSlice, extraBytes));
    const firstByteBits = 8 - ones - 1;
    for (let i = 0; i < firstByteBits; i++) {
      bitArray.unshift(bitstream1.readBits(1));
    }
    for (let i = 0; i < extraBytes; i++) {
      for (let j = 0; j < 8; j++) {
        const val = bitstream2.readBits(1);
        if (j < 2) {
          continue;
        }
        bitArray.unshift(val);
      }
    }
    const encoded = bitArray.reduce((acc, bit, index) => {
      return acc | bit << index;
    }, 0);
    return encoded;
  };
  var readBlockSize = (slice, blockSizeBits) => {
    if (blockSizeBits === "uncommon-u16") {
      return readU16Be(slice) + 1;
    } else if (blockSizeBits === "uncommon-u8") {
      return readU8(slice) + 1;
    } else if (typeof blockSizeBits === "number") {
      return blockSizeBits;
    } else {
      assertNever(blockSizeBits);
      assert(false);
    }
  };
  var readSampleRate = (slice, sampleRateOrUncommon) => {
    if (sampleRateOrUncommon === "uncommon-u16") {
      return readU16Be(slice);
    }
    if (sampleRateOrUncommon === "uncommon-u16-10") {
      return readU16Be(slice) * 10;
    }
    if (sampleRateOrUncommon === "uncommon-u8") {
      return readU8(slice);
    }
    if (typeof sampleRateOrUncommon === "number") {
      return sampleRateOrUncommon;
    }
    return null;
  };
  var calculateCrc8 = (data) => {
    const polynomial = 7;
    let crc = 0;
    for (const byte of data) {
      crc ^= byte;
      for (let i = 0; i < 8; i++) {
        if ((crc & 128) !== 0) {
          crc = crc << 1 ^ polynomial;
        } else {
          crc <<= 1;
        }
        crc &= 255;
      }
    }
    return crc;
  };

  // src/flac/flac-demuxer.ts
  var FlacDemuxer = class extends Demuxer {
    constructor(input) {
      super(input);
      this.loadedSamples = [];
      // All samples from the start of the file to lastLoadedPos
      this.metadataPromise = null;
      this.track = null;
      this.metadataTags = {};
      this.audioInfo = null;
      this.lastLoadedPos = null;
      this.blockingBit = null;
      this.readingMutex = new AsyncMutex();
      this.lastSampleLoaded = false;
      this.reader = input._reader;
    }
    async computeDuration() {
      await this.readMetadata();
      assert(this.track);
      return this.track.computeDuration();
    }
    async getMetadataTags() {
      await this.readMetadata();
      return this.metadataTags;
    }
    async getTracks() {
      await this.readMetadata();
      assert(this.track);
      return [this.track];
    }
    async getMimeType() {
      return "audio/flac";
    }
    async readMetadata() {
      let currentPos = 4;
      return this.metadataPromise ??= (async () => {
        while (this.reader.fileSize === null || currentPos < this.reader.fileSize) {
          let sizeSlice = this.reader.requestSlice(currentPos, 4);
          if (sizeSlice instanceof Promise) sizeSlice = await sizeSlice;
          currentPos += 4;
          if (sizeSlice === null) {
            throw new Error(
              `Metadata block at position ${currentPos} is too small! Corrupted file.`
            );
          }
          assert(sizeSlice);
          const byte = readU8(sizeSlice);
          const size = readU24Be(sizeSlice);
          const isLastMetadata = (byte & 128) !== 0;
          const metaBlockType = byte & 127;
          switch (metaBlockType) {
            case 0 /* STREAMINFO */: {
              let streamInfoBlock = this.reader.requestSlice(
                currentPos,
                size
              );
              if (streamInfoBlock instanceof Promise) streamInfoBlock = await streamInfoBlock;
              assert(streamInfoBlock);
              if (streamInfoBlock === null) {
                throw new Error(
                  `StreamInfo block at position ${currentPos} is too small! Corrupted file.`
                );
              }
              const streamInfoBytes = readBytes(streamInfoBlock, 34);
              const bitstream = new Bitstream(streamInfoBytes);
              const minimumBlockSize = bitstream.readBits(16);
              const maximumBlockSize = bitstream.readBits(16);
              const minimumFrameSize = bitstream.readBits(24);
              const maximumFrameSize = bitstream.readBits(24);
              const sampleRate = bitstream.readBits(20);
              const numberOfChannels = bitstream.readBits(3) + 1;
              bitstream.readBits(5);
              const totalSamples = bitstream.readBits(36);
              bitstream.skipBits(16 * 8);
              const description = new Uint8Array(42);
              description.set(new Uint8Array([102, 76, 97, 67]), 0);
              description.set(new Uint8Array([128, 0, 0, 34]), 4);
              description.set(streamInfoBytes, 8);
              this.audioInfo = {
                numberOfChannels,
                sampleRate,
                totalSamples,
                minimumBlockSize,
                maximumBlockSize,
                minimumFrameSize,
                maximumFrameSize,
                description
              };
              this.track = new InputAudioTrack(this.input, new FlacAudioTrackBacking(this));
              break;
            }
            case 4 /* VORBIS_COMMENT */: {
              let vorbisCommentBlock = this.reader.requestSlice(
                currentPos,
                size
              );
              if (vorbisCommentBlock instanceof Promise) vorbisCommentBlock = await vorbisCommentBlock;
              assert(vorbisCommentBlock);
              readVorbisComments(
                readBytes(vorbisCommentBlock, size),
                this.metadataTags
              );
              break;
            }
            case 6 /* PICTURE */: {
              let pictureBlock = this.reader.requestSlice(
                currentPos,
                size
              );
              if (pictureBlock instanceof Promise) pictureBlock = await pictureBlock;
              assert(pictureBlock);
              const pictureType = readU32Be(pictureBlock);
              const mediaTypeLength = readU32Be(pictureBlock);
              const mediaType = textDecoder.decode(
                readBytes(pictureBlock, mediaTypeLength)
              );
              const descriptionLength = readU32Be(pictureBlock);
              const description = textDecoder.decode(
                readBytes(pictureBlock, descriptionLength)
              );
              pictureBlock.skip(4 + 4 + 4 + 4);
              const dataLength = readU32Be(pictureBlock);
              const data = readBytes(pictureBlock, dataLength);
              this.metadataTags.images ??= [];
              this.metadataTags.images.push({
                data,
                mimeType: mediaType,
                // https://www.rfc-editor.org/rfc/rfc9639.html#table13
                kind: pictureType === 3 ? "coverFront" : pictureType === 4 ? "coverBack" : "unknown",
                description
              });
              break;
            }
            default:
              break;
          }
          currentPos += size;
          if (isLastMetadata) {
            this.lastLoadedPos = currentPos;
            break;
          }
        }
      })();
    }
    async readNextFlacFrame({
      startPos,
      isFirstPacket
    }) {
      assert(this.audioInfo);
      const minimumHeaderLength = 6;
      const maximumHeaderSize = 16;
      const maximumSliceLength = this.audioInfo.maximumFrameSize + maximumHeaderSize;
      const slice = await this.reader.requestSliceRange(
        startPos,
        this.audioInfo.minimumFrameSize,
        maximumSliceLength
      );
      if (!slice) {
        return null;
      }
      const frameHeader = this.readFlacFrameHeader({
        slice,
        isFirstPacket
      });
      if (!frameHeader) {
        return null;
      }
      slice.filePos = startPos + this.audioInfo.minimumFrameSize;
      while (true) {
        if (slice.filePos > slice.end - minimumHeaderLength) {
          return {
            num: frameHeader.num,
            blockSize: frameHeader.blockSize,
            sampleRate: frameHeader.sampleRate,
            size: slice.end - startPos,
            isLastFrame: true
          };
        }
        const nextByte = readU8(slice);
        if (nextByte === 255) {
          const positionBeforeReading = slice.filePos;
          const byteAfterNextByte = readU8(slice);
          const expected = this.blockingBit === 1 ? 249 : 248;
          if (byteAfterNextByte !== expected) {
            slice.filePos = positionBeforeReading;
            continue;
          }
          slice.skip(-2);
          const lengthIfNextFlacFrameHeaderIsLegit = slice.filePos - startPos;
          const nextFrameHeader = this.readFlacFrameHeader({
            slice,
            isFirstPacket: false
          });
          if (!nextFrameHeader) {
            slice.filePos = positionBeforeReading;
            continue;
          }
          if (this.blockingBit === 0) {
            if (nextFrameHeader.num - frameHeader.num !== 1) {
              slice.filePos = positionBeforeReading;
              continue;
            }
          } else {
            if (nextFrameHeader.num - frameHeader.num !== frameHeader.blockSize) {
              slice.filePos = positionBeforeReading;
              continue;
            }
          }
          return {
            num: frameHeader.num,
            blockSize: frameHeader.blockSize,
            sampleRate: frameHeader.sampleRate,
            size: lengthIfNextFlacFrameHeaderIsLegit,
            isLastFrame: false
          };
        }
      }
    }
    readFlacFrameHeader({
      slice,
      isFirstPacket
    }) {
      const startOffset = slice.filePos;
      const bytes2 = readBytes(slice, 4);
      const bitstream = new Bitstream(bytes2);
      const bits = bitstream.readBits(15);
      if (bits !== 32764) {
        return null;
      }
      if (this.blockingBit === null) {
        assert(isFirstPacket);
        const newBlockingBit = bitstream.readBits(1);
        this.blockingBit = newBlockingBit;
      } else if (this.blockingBit === 1) {
        assert(!isFirstPacket);
        const newBlockingBit = bitstream.readBits(1);
        if (newBlockingBit !== 1) {
          return null;
        }
      } else if (this.blockingBit === 0) {
        assert(!isFirstPacket);
        const newBlockingBit = bitstream.readBits(1);
        if (newBlockingBit !== 0) {
          return null;
        }
      } else {
        throw new Error("Invalid blocking bit");
      }
      const blockSizeOrUncommon = getBlockSizeOrUncommon(bitstream.readBits(4));
      if (!blockSizeOrUncommon) {
        return null;
      }
      assert(this.audioInfo);
      const sampleRateOrUncommon = getSampleRateOrUncommon(
        bitstream.readBits(4),
        this.audioInfo.sampleRate
      );
      if (!sampleRateOrUncommon) {
        return null;
      }
      bitstream.readBits(4);
      bitstream.readBits(3);
      const reservedZero = bitstream.readBits(1);
      if (reservedZero !== 0) {
        return null;
      }
      const num = readCodedNumber(slice);
      const blockSize = readBlockSize(slice, blockSizeOrUncommon);
      const sampleRate = readSampleRate(slice, sampleRateOrUncommon);
      if (sampleRate === null) {
        return null;
      }
      if (sampleRate !== this.audioInfo.sampleRate) {
        return null;
      }
      const size = slice.filePos - startOffset;
      const crc = readU8(slice);
      slice.skip(-size);
      slice.skip(-1);
      const crcCalculated = calculateCrc8(readBytes(slice, size));
      if (crc !== crcCalculated) {
        return null;
      }
      return { num, blockSize, sampleRate };
    }
    async advanceReader() {
      await this.readMetadata();
      assert(this.lastLoadedPos !== null);
      assert(this.audioInfo);
      const startPos = this.lastLoadedPos;
      const frame = await this.readNextFlacFrame({
        startPos,
        isFirstPacket: this.loadedSamples.length === 0
      });
      if (!frame) {
        this.lastSampleLoaded = true;
        return;
      }
      const lastSample = this.loadedSamples[this.loadedSamples.length - 1];
      const blockOffset = lastSample ? lastSample.blockOffset + lastSample.blockSize : 0;
      const sample = {
        blockOffset,
        blockSize: frame.blockSize,
        byteOffset: startPos,
        byteSize: frame.size
      };
      this.lastLoadedPos = this.lastLoadedPos + frame.size;
      this.loadedSamples.push(sample);
      if (frame.isLastFrame) {
        this.lastSampleLoaded = true;
        return;
      }
    }
  };
  var FlacAudioTrackBacking = class {
    constructor(demuxer) {
      this.demuxer = demuxer;
    }
    getId() {
      return 1;
    }
    getNumber() {
      return 1;
    }
    getCodec() {
      return "flac";
    }
    getInternalCodecId() {
      return null;
    }
    getNumberOfChannels() {
      assert(this.demuxer.audioInfo);
      return this.demuxer.audioInfo.numberOfChannels;
    }
    async computeDuration() {
      const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
      return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    getSampleRate() {
      assert(this.demuxer.audioInfo);
      return this.demuxer.audioInfo.sampleRate;
    }
    getName() {
      return null;
    }
    getLanguageCode() {
      return UNDETERMINED_LANGUAGE;
    }
    getTimeResolution() {
      assert(this.demuxer.audioInfo);
      return this.demuxer.audioInfo.sampleRate;
    }
    getDisposition() {
      return {
        ...DEFAULT_TRACK_DISPOSITION
      };
    }
    async getFirstTimestamp() {
      return 0;
    }
    async getDecoderConfig() {
      assert(this.demuxer.audioInfo);
      return {
        codec: "flac",
        numberOfChannels: this.demuxer.audioInfo.numberOfChannels,
        sampleRate: this.demuxer.audioInfo.sampleRate,
        description: this.demuxer.audioInfo.description
      };
    }
    async getPacket(timestamp, options) {
      assert(this.demuxer.audioInfo);
      if (timestamp < 0) {
        throw new Error("Timestamp cannot be negative");
      }
      const release = await this.demuxer.readingMutex.acquire();
      try {
        while (true) {
          const packetIndex = binarySearchLessOrEqual(
            this.demuxer.loadedSamples,
            timestamp,
            (x) => x.blockOffset / this.demuxer.audioInfo.sampleRate
          );
          if (packetIndex === -1) {
            await this.demuxer.advanceReader();
            continue;
          }
          const packet = this.demuxer.loadedSamples[packetIndex];
          const sampleTimestamp = packet.blockOffset / this.demuxer.audioInfo.sampleRate;
          const sampleDuration = packet.blockSize / this.demuxer.audioInfo.sampleRate;
          if (sampleTimestamp + sampleDuration <= timestamp) {
            if (this.demuxer.lastSampleLoaded) {
              return this.getPacketAtIndex(
                this.demuxer.loadedSamples.length - 1,
                options
              );
            }
            await this.demuxer.advanceReader();
            continue;
          }
          return this.getPacketAtIndex(packetIndex, options);
        }
      } finally {
        release();
      }
    }
    async getNextPacket(packet, options) {
      const release = await this.demuxer.readingMutex.acquire();
      try {
        const nextIndex = packet.sequenceNumber + 1;
        if (this.demuxer.lastSampleLoaded && nextIndex >= this.demuxer.loadedSamples.length) {
          return null;
        }
        while (nextIndex >= this.demuxer.loadedSamples.length && !this.demuxer.lastSampleLoaded) {
          await this.demuxer.advanceReader();
        }
        return this.getPacketAtIndex(nextIndex, options);
      } finally {
        release();
      }
    }
    getKeyPacket(timestamp, options) {
      return this.getPacket(timestamp, options);
    }
    getNextKeyPacket(packet, options) {
      return this.getNextPacket(packet, options);
    }
    async getPacketAtIndex(sampleIndex, options) {
      const rawSample = this.demuxer.loadedSamples[sampleIndex];
      if (!rawSample) {
        return null;
      }
      let data;
      if (options.metadataOnly) {
        data = PLACEHOLDER_DATA;
      } else {
        let slice = this.demuxer.reader.requestSlice(
          rawSample.byteOffset,
          rawSample.byteSize
        );
        if (slice instanceof Promise) slice = await slice;
        if (!slice) {
          return null;
        }
        data = readBytes(slice, rawSample.byteSize);
      }
      assert(this.demuxer.audioInfo);
      const timestamp = rawSample.blockOffset / this.demuxer.audioInfo.sampleRate;
      const duration = rawSample.blockSize / this.demuxer.audioInfo.sampleRate;
      return new EncodedPacket(
        data,
        "key",
        timestamp,
        duration,
        sampleIndex,
        rawSample.byteSize
      );
    }
    async getFirstPacket(options) {
      while (this.demuxer.loadedSamples.length === 0 && !this.demuxer.lastSampleLoaded) {
        await this.demuxer.advanceReader();
      }
      return this.getPacketAtIndex(0, options);
    }
  };

  // src/mpeg-ts/mpeg-ts-misc.ts
  var TIMESCALE = 9e4;
  var TS_PACKET_SIZE = 188;
  var buildMpegTsMimeType = (codecStrings) => {
    let string = "video/MP2T";
    const uniqueCodecStrings = [...new Set(codecStrings.filter(Boolean))];
    if (uniqueCodecStrings.length > 0) {
      string += `; codecs="${uniqueCodecStrings.join(", ")}"`;
    }
    return string;
  };

  // src/mpeg-ts/mpeg-ts-demuxer.ts
  var MpegTsDemuxer = class extends Demuxer {
    constructor(input) {
      super(input);
      this.metadataPromise = null;
      this.elementaryStreams = [];
      this.tracks = [];
      this.packetOffset = 0;
      this.packetStride = -1;
      this.sectionEndPositions = [];
      this.seekChunkSize = 5 * 1024 * 1024;
      // 5 MiB, picked because most HLS segments are below this size
      this.minReferencePointByteDistance = -1;
      this.reader = input._reader;
    }
    async readMetadata() {
      return this.metadataPromise ??= (async () => {
        const lengthToCheck = TS_PACKET_SIZE + 16 + 1;
        let startingSlice = this.reader.requestSlice(0, lengthToCheck);
        if (startingSlice instanceof Promise) startingSlice = await startingSlice;
        assert(startingSlice);
        const startingBytes = readBytes(startingSlice, lengthToCheck);
        if (startingBytes[0] === 71 && startingBytes[TS_PACKET_SIZE] === 71) {
          this.packetOffset = 0;
          this.packetStride = TS_PACKET_SIZE;
        } else if (startingBytes[0] === 71 && startingBytes[TS_PACKET_SIZE + 16] === 71) {
          this.packetOffset = 0;
          this.packetStride = TS_PACKET_SIZE + 16;
        } else if (startingBytes[4] === 71 && startingBytes[4 + TS_PACKET_SIZE] === 71) {
          this.packetOffset = 4;
          this.packetStride = TS_PACKET_SIZE;
        } else {
          throw new Error("Unreachable.");
        }
        const MIN_REFERENCE_POINT_PACKET_DISTANCE = 256;
        this.minReferencePointByteDistance = MIN_REFERENCE_POINT_PACKET_DISTANCE * this.packetStride;
        let currentPos = this.packetOffset;
        let programMapPid = null;
        let hasProgramAssociationTable = false;
        let hasProgramMap = false;
        while (true) {
          const packetHeader = await this.readPacketHeader(currentPos);
          if (!packetHeader) {
            break;
          }
          if (packetHeader.payloadUnitStartIndicator === 0) {
            currentPos += this.packetStride;
            continue;
          }
          const section = await this.readSection(
            currentPos,
            true,
            !hasProgramMap
            // Expect contiguous sections as long as we don't have the PMT
          );
          if (!section) {
            break;
          }
          const BYTES_BEFORE_SECTION_LENGTH = 3;
          const BITS_IN_CRC_32 = 32;
          let isProbablyProgramMap = false;
          if (!hasProgramMap && section.pid !== 0) {
            const isPesPacket = section.payload[0] === 0 && section.payload[1] === 0 && section.payload[2] === 1;
            if (!isPesPacket) {
              const bitstream = new Bitstream(section.payload);
              const pointerField = bitstream.readAlignedByte();
              bitstream.skipBits(8 * pointerField);
              const tableId = bitstream.readBits(8);
              isProbablyProgramMap = tableId === 2;
            }
          }
          if (section.pid === 0 && !hasProgramAssociationTable) {
            const bitstream = new Bitstream(section.payload);
            const pointerField = bitstream.readAlignedByte();
            bitstream.skipBits(8 * pointerField);
            bitstream.skipBits(14);
            const sectionLength = bitstream.readBits(10);
            bitstream.skipBits(40);
            while (8 * (sectionLength + BYTES_BEFORE_SECTION_LENGTH) - bitstream.pos > BITS_IN_CRC_32) {
              const programNumber = bitstream.readBits(16);
              bitstream.skipBits(3);
              if (programNumber !== 0) {
                if (programMapPid !== null) {
                  throw new Error("Only files with a single program are supported.");
                } else {
                  programMapPid = bitstream.readBits(13);
                }
              }
            }
            if (programMapPid === null) {
              throw new Error("Program Association Table must link to a Program Map Table.");
            }
            hasProgramAssociationTable = true;
          } else if ((section.pid === programMapPid || isProbablyProgramMap) && !hasProgramMap) {
            const bitstream = new Bitstream(section.payload);
            const pointerField = bitstream.readAlignedByte();
            bitstream.skipBits(8 * pointerField);
            bitstream.skipBits(12);
            const sectionLength = bitstream.readBits(12);
            bitstream.skipBits(43);
            const pcrPid = bitstream.readBits(13);
            bitstream.skipBits(6);
            const programInfoLength = bitstream.readBits(10);
            bitstream.skipBits(8 * programInfoLength);
            while (8 * (sectionLength + BYTES_BEFORE_SECTION_LENGTH) - bitstream.pos > BITS_IN_CRC_32) {
              const streamType = bitstream.readBits(8);
              bitstream.skipBits(3);
              const elementaryPid = bitstream.readBits(13);
              bitstream.skipBits(6);
              const esInfoLength = bitstream.readBits(10);
              const esInfoEndPos = bitstream.pos + 8 * esInfoLength;
              let hasAc3Descriptor = false;
              let hasEac3Descriptor = false;
              while (bitstream.pos < esInfoEndPos) {
                const descriptorTag = bitstream.readBits(8);
                const descriptorLength = bitstream.readBits(8);
                if (descriptorTag === 106) {
                  hasAc3Descriptor = true;
                } else if (descriptorTag === 122 || descriptorTag === 204) {
                  hasEac3Descriptor = true;
                }
                bitstream.skipBits(8 * descriptorLength);
              }
              let info = null;
              switch (streamType) {
                case 3 /* MP3_MPEG1 */:
                case 4 /* MP3_MPEG2 */:
                case 15 /* AAC */:
                  {
                    const codec = streamType === 15 /* AAC */ ? "aac" : "mp3";
                    info = {
                      type: "audio",
                      codec,
                      aacCodecInfo: null,
                      numberOfChannels: -1,
                      sampleRate: -1
                    };
                  }
                  ;
                  break;
                case 27 /* AVC */:
                case 36 /* HEVC */:
                  {
                    const codec = streamType === 27 /* AVC */ ? "avc" : "hevc";
                    info = {
                      type: "video",
                      codec,
                      avcCodecInfo: null,
                      hevcCodecInfo: null,
                      colorSpace: {
                        primaries: null,
                        transfer: null,
                        matrix: null,
                        fullRange: null
                      },
                      width: -1,
                      height: -1,
                      reorderSize: -1
                    };
                  }
                  ;
                  break;
                case 129 /* AC3_SYSTEM_A */:
                  {
                    info = {
                      type: "audio",
                      codec: "ac3",
                      aacCodecInfo: null,
                      numberOfChannels: -1,
                      sampleRate: -1
                    };
                  }
                  ;
                  break;
                case 135 /* EAC3_SYSTEM_A */:
                  {
                    info = {
                      type: "audio",
                      codec: "eac3",
                      aacCodecInfo: null,
                      numberOfChannels: -1,
                      sampleRate: -1
                    };
                  }
                  ;
                  break;
                case 6 /* PRIVATE_DATA */:
                  {
                    if (hasEac3Descriptor) {
                      info = {
                        type: "audio",
                        codec: "eac3",
                        aacCodecInfo: null,
                        numberOfChannels: -1,
                        sampleRate: -1
                      };
                    } else if (hasAc3Descriptor) {
                      info = {
                        type: "audio",
                        codec: "ac3",
                        aacCodecInfo: null,
                        numberOfChannels: -1,
                        sampleRate: -1
                      };
                    }
                  }
                  ;
                  break;
                default: {
                  console.warn(`Unsupported stream_type 0x${streamType.toString(16)}; ignoring stream.`);
                }
              }
              if (info) {
                this.elementaryStreams.push({
                  demuxer: this,
                  pid: elementaryPid,
                  streamType,
                  initialized: false,
                  firstSection: null,
                  info,
                  referencePesPackets: []
                });
              }
            }
            hasProgramMap = true;
          } else {
            const elementaryStream = this.elementaryStreams.find((x) => x.pid === section.pid);
            if (elementaryStream && !elementaryStream.initialized) {
              const pesPacket = readPesPacket(section);
              if (!pesPacket) {
                throw new Error(
                  `Couldn't read first PES packet for Elementary Stream with PID ${elementaryStream.pid}`
                );
              }
              elementaryStream.firstSection = section;
              if (elementaryStream.info.type === "video") {
                if (elementaryStream.info.codec === "avc") {
                  elementaryStream.info.avcCodecInfo = extractAvcDecoderConfigurationRecord(pesPacket.data);
                  if (!elementaryStream.info.avcCodecInfo) {
                    throw new Error(
                      "Invalid AVC video stream; could not extract AVCDecoderConfigurationRecord from first packet."
                    );
                  }
                  const spsUnit = elementaryStream.info.avcCodecInfo.sequenceParameterSets[0];
                  assert(spsUnit);
                  const spsInfo = parseAvcSps(spsUnit);
                  elementaryStream.info.width = spsInfo.displayWidth;
                  elementaryStream.info.height = spsInfo.displayHeight;
                  elementaryStream.info.colorSpace = {
                    primaries: COLOR_PRIMARIES_MAP_INVERSE[spsInfo.colourPrimaries],
                    transfer: TRANSFER_CHARACTERISTICS_MAP_INVERSE[spsInfo.transferCharacteristics],
                    matrix: MATRIX_COEFFICIENTS_MAP_INVERSE[spsInfo.matrixCoefficients],
                    fullRange: !!spsInfo.fullRangeFlag
                  };
                  elementaryStream.info.reorderSize = spsInfo.maxDecFrameBuffering;
                  elementaryStream.initialized = true;
                } else if (elementaryStream.info.codec === "hevc") {
                  elementaryStream.info.hevcCodecInfo = extractHevcDecoderConfigurationRecord(pesPacket.data);
                  if (!elementaryStream.info.hevcCodecInfo) {
                    throw new Error(
                      "Invalid HEVC video stream; could not extract HVCDecoderConfigurationRecord from first packet."
                    );
                  }
                  const spsArray = elementaryStream.info.hevcCodecInfo.arrays.find(
                    (a) => a.nalUnitType === 33 /* SPS_NUT */
                  );
                  const spsUnit = spsArray.nalUnits[0];
                  assert(spsUnit);
                  const spsInfo = parseHevcSps(spsUnit);
                  elementaryStream.info.width = spsInfo.displayWidth;
                  elementaryStream.info.height = spsInfo.displayHeight;
                  elementaryStream.info.colorSpace = {
                    primaries: COLOR_PRIMARIES_MAP_INVERSE[spsInfo.colourPrimaries],
                    transfer: TRANSFER_CHARACTERISTICS_MAP_INVERSE[spsInfo.transferCharacteristics],
                    matrix: MATRIX_COEFFICIENTS_MAP_INVERSE[spsInfo.matrixCoefficients],
                    fullRange: !!spsInfo.fullRangeFlag
                  };
                  elementaryStream.info.reorderSize = spsInfo.maxDecFrameBuffering;
                  elementaryStream.initialized = true;
                } else {
                  throw new Error("Unhandled.");
                }
              } else {
                if (elementaryStream.info.codec === "aac") {
                  const slice = FileSlice4.tempFromBytes(pesPacket.data);
                  const header = readAdtsFrameHeader(slice);
                  if (!header) {
                    throw new Error(
                      "Invalid AAC audio stream; could not read ADTS frame header from first packet."
                    );
                  }
                  elementaryStream.info.aacCodecInfo = {
                    isMpeg2: false,
                    objectType: header.objectType
                  };
                  elementaryStream.info.numberOfChannels = aacChannelMap[header.channelConfiguration];
                  elementaryStream.info.sampleRate = aacFrequencyTable[header.samplingFrequencyIndex];
                  elementaryStream.initialized = true;
                } else if (elementaryStream.info.codec === "mp3") {
                  const word = readU32Be(FileSlice4.tempFromBytes(pesPacket.data));
                  const result = readMp3FrameHeader(word, pesPacket.data.byteLength);
                  if (!result.header) {
                    throw new Error(
                      "Invalid MP3 audio stream; could not read frame header from first packet."
                    );
                  }
                  elementaryStream.info.numberOfChannels = result.header.channel === 3 ? 1 : 2;
                  elementaryStream.info.sampleRate = result.header.sampleRate;
                  elementaryStream.initialized = true;
                } else if (elementaryStream.info.codec === "ac3") {
                  const frameInfo = parseAc3SyncFrame(pesPacket.data);
                  if (!frameInfo) {
                    throw new Error(
                      "Invalid AC-3 audio stream; could not read sync frame from first packet."
                    );
                  }
                  if (frameInfo.fscod === 3) {
                    throw new Error(
                      "Invalid AC-3 audio stream; reserved sample rate code found in first packet."
                    );
                  }
                  elementaryStream.info.numberOfChannels = AC3_ACMOD_CHANNEL_COUNTS[frameInfo.acmod] + frameInfo.lfeon;
                  elementaryStream.info.sampleRate = AC3_SAMPLE_RATES[frameInfo.fscod];
                  elementaryStream.initialized = true;
                } else if (elementaryStream.info.codec === "eac3") {
                  const frameInfo = parseEac3SyncFrame(pesPacket.data);
                  if (!frameInfo) {
                    throw new Error(
                      "Invalid E-AC-3 audio stream; could not read sync frame from first packet."
                    );
                  }
                  const sampleRate = getEac3SampleRate(frameInfo);
                  if (sampleRate === null) {
                    throw new Error(
                      "Invalid E-AC-3 audio stream; reserved sample rate code found in first packet."
                    );
                  }
                  elementaryStream.info.numberOfChannels = getEac3ChannelCount(frameInfo);
                  elementaryStream.info.sampleRate = sampleRate;
                  elementaryStream.initialized = true;
                } else {
                  throw new Error("Unhandled.");
                }
              }
            }
          }
          const isDone = hasProgramMap && this.elementaryStreams.every((x) => x.initialized);
          if (isDone) {
            break;
          }
          currentPos += this.packetStride;
        }
        if (!hasProgramMap) {
          if (!hasProgramAssociationTable) {
            throw new Error("No Program Association Table found in the file.");
          }
          throw new Error("No Program Map Table found in the file.");
        }
        for (const stream of this.elementaryStreams) {
          if (stream.info.type === "video") {
            this.tracks.push(
              new InputVideoTrack(
                this.input,
                new MpegTsVideoTrackBacking(stream)
              )
            );
          } else {
            this.tracks.push(
              new InputAudioTrack(
                this.input,
                new MpegTsAudioTrackBacking(stream)
              )
            );
          }
        }
      })();
    }
    async getTracks() {
      await this.readMetadata();
      return this.tracks;
    }
    async getMetadataTags() {
      return {};
    }
    async computeDuration() {
      const tracks = await this.getTracks();
      const trackDurations = await Promise.all(tracks.map((x) => x.computeDuration()));
      return Math.max(0, ...trackDurations);
    }
    async getMimeType() {
      await this.readMetadata();
      const tracks = await this.getTracks();
      const codecStrings = await Promise.all(tracks.map((x) => x.getCodecParameterString()));
      return buildMpegTsMimeType(codecStrings);
    }
    async readSection(startPos, full, contiguous = false) {
      let endPos = startPos;
      let currentPos = startPos;
      const chunks = [];
      let chunksByteLength = 0;
      let firstPacket = null;
      let mustAddSectionEnd = true;
      let randomAccessIndicator = 0;
      while (true) {
        const packet = await this.readPacket(currentPos);
        currentPos += this.packetStride;
        if (!packet) {
          break;
        }
        if (!firstPacket) {
          if (packet.payloadUnitStartIndicator === 0) {
            break;
          }
          firstPacket = packet;
        } else {
          if (packet.pid !== firstPacket.pid) {
            if (contiguous) {
              break;
            } else {
              continue;
            }
          }
          if (packet.payloadUnitStartIndicator === 1) {
            break;
          }
        }
        const hasAdaptationField = !!(packet.adaptationFieldControl & 2);
        const hasPayload = !!(packet.adaptationFieldControl & 1);
        let adaptationFieldLength = 0;
        if (hasAdaptationField) {
          adaptationFieldLength = 1 + packet.body[0];
          if (packet === firstPacket && adaptationFieldLength > 1) {
            randomAccessIndicator = packet.body[1] >> 6 & 1;
          }
        }
        if (hasPayload) {
          if (adaptationFieldLength === 0) {
            chunks.push(packet.body);
            chunksByteLength += packet.body.byteLength;
          } else {
            chunks.push(packet.body.subarray(adaptationFieldLength));
            chunksByteLength += packet.body.byteLength - adaptationFieldLength;
          }
        }
        endPos = currentPos;
        if (!full && chunksByteLength >= 64) {
          mustAddSectionEnd = false;
          break;
        }
        const isKnownSectionEnd = binarySearchExact(this.sectionEndPositions, endPos, (x) => x) !== -1;
        if (isKnownSectionEnd) {
          mustAddSectionEnd = false;
          break;
        }
      }
      if (mustAddSectionEnd) {
        const index = binarySearchLessOrEqual(this.sectionEndPositions, endPos, (x) => x);
        this.sectionEndPositions.splice(index + 1, 0, endPos);
      }
      if (!firstPacket) {
        return null;
      }
      let merged;
      if (chunks.length === 1) {
        merged = chunks[0];
      } else {
        const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
        merged = new Uint8Array(totalLength);
        let offset = 0;
        for (const chunk of chunks) {
          merged.set(chunk, offset);
          offset += chunk.length;
        }
      }
      return {
        startPos,
        endPos: full ? endPos : null,
        pid: firstPacket.pid,
        payload: merged,
        randomAccessIndicator
      };
    }
    async readPacketHeader(pos) {
      let slice = this.reader.requestSlice(pos, 4);
      if (slice instanceof Promise) slice = await slice;
      if (!slice) {
        return null;
      }
      const syncByte = readU8(slice);
      if (syncByte !== 71) {
        throw new Error("Invalid TS packet sync byte. Likely an internal bug, please report this file.");
      }
      const nextTwoBytes = readU16Be(slice);
      const transportErrorIndicator = nextTwoBytes >> 15;
      const payloadUnitStartIndicator = nextTwoBytes >> 14 & 1;
      const transportPriority = nextTwoBytes >> 13 & 1;
      const pid = nextTwoBytes & 8191;
      const nextByte = readU8(slice);
      const transportScramblingControl = nextByte >> 6;
      const adaptationFieldControl = nextByte >> 4 & 3;
      const continuityCounter = nextByte & 15;
      return {
        payloadUnitStartIndicator,
        pid,
        adaptationFieldControl
      };
    }
    async readPacket(pos) {
      let slice = this.reader.requestSlice(pos, TS_PACKET_SIZE);
      if (slice instanceof Promise) slice = await slice;
      if (!slice) {
        return null;
      }
      const bytes2 = readBytes(slice, TS_PACKET_SIZE);
      const syncByte = bytes2[0];
      if (syncByte !== 71) {
        throw new Error("Invalid TS packet sync byte. Likely an internal bug, please report this file.");
      }
      const nextTwoBytes = (bytes2[1] << 8) + bytes2[2];
      const transportErrorIndicator = nextTwoBytes >> 15;
      const payloadUnitStartIndicator = nextTwoBytes >> 14 & 1;
      const transportPriority = nextTwoBytes >> 13 & 1;
      const pid = nextTwoBytes & 8191;
      const nextByte = bytes2[3];
      const transportScramblingControl = nextByte >> 6;
      const adaptationFieldControl = nextByte >> 4 & 3;
      const continuityCounter = nextByte & 15;
      return {
        payloadUnitStartIndicator,
        pid,
        adaptationFieldControl,
        body: bytes2.subarray(4)
      };
    }
  };
  var readPesPacketHeader = (section) => {
    if (section.payload.byteLength < 3) {
      return null;
    }
    const bitstream = new Bitstream(section.payload);
    const startCodePrefix = bitstream.readBits(24);
    if (startCodePrefix !== 1) {
      return null;
    }
    const streamId = bitstream.readBits(8);
    bitstream.skipBits(16);
    if (streamId === 188 || streamId === 190 || streamId === 191 || streamId === 240 || streamId === 241 || streamId === 255 || streamId === 242 || streamId === 248) {
      return null;
    }
    bitstream.skipBits(8);
    const ptsDtsFlags = bitstream.readBits(2);
    bitstream.skipBits(14);
    let pts = 0;
    if (ptsDtsFlags === 2 || ptsDtsFlags === 3) {
      bitstream.skipBits(4);
      pts += bitstream.readBits(3) * (1 << 30);
      bitstream.skipBits(1);
      pts += bitstream.readBits(15) * (1 << 15);
      bitstream.skipBits(1);
      pts += bitstream.readBits(15);
    } else {
      throw new Error(
        "PES packets without PTS are not currently supported. If you think this file should be supported, please report it."
      );
    }
    return {
      sectionStartPos: section.startPos,
      sectionEndPos: section.endPos,
      pts,
      randomAccessIndicator: section.randomAccessIndicator
    };
  };
  var readPesPacket = (section) => {
    assert(section.endPos !== null);
    const header = readPesPacketHeader(section);
    if (!header) {
      return null;
    }
    const bitstream = new Bitstream(section.payload);
    bitstream.skipBits(32);
    const pesPacketLength = bitstream.readBits(16);
    const BYTES_UNTIL_END_OF_PES_PACKET_LENGTH = 6;
    bitstream.skipBits(16);
    const pesHeaderDataLength = bitstream.readBits(8);
    const pesHeaderEndPos = bitstream.pos + 8 * pesHeaderDataLength;
    bitstream.pos = pesHeaderEndPos;
    const bytePos = pesHeaderEndPos / 8;
    assert(Number.isInteger(bytePos));
    const data = section.payload.subarray(
      bytePos,
      // "A value of 0 indicates that the PES packet length is neither specified nor bounded and is allowed only in
      // PES packets whose payload consists of bytes from a video elementary stream contained in
      // transport stream packets."
      pesPacketLength > 0 ? BYTES_UNTIL_END_OF_PES_PACKET_LENGTH + pesPacketLength : section.payload.byteLength
    );
    return {
      ...header,
      data
    };
  };
  var MpegTsTrackBacking = class _MpegTsTrackBacking {
    constructor(elementaryStream) {
      this.elementaryStream = elementaryStream;
      this.packetBuffers = /* @__PURE__ */ new WeakMap();
      /** Used for recreating PacketBuffers if necessary. */
      this.packetSectionStarts = /* @__PURE__ */ new WeakMap();
    }
    getId() {
      return this.elementaryStream.pid;
    }
    getNumber() {
      const demuxer = this.elementaryStream.demuxer;
      const trackType = this.elementaryStream.info.type;
      let number = 0;
      for (const track of demuxer.tracks) {
        if (track.type === trackType) {
          number++;
        }
        assert(track._backing instanceof _MpegTsTrackBacking);
        if (track._backing.elementaryStream === this.elementaryStream) {
          break;
        }
      }
      return number;
    }
    getCodec() {
      throw new Error("Not implemented on base class.");
    }
    getInternalCodecId() {
      return this.elementaryStream.streamType;
    }
    getName() {
      return null;
    }
    getLanguageCode() {
      return UNDETERMINED_LANGUAGE;
    }
    getDisposition() {
      return DEFAULT_TRACK_DISPOSITION;
    }
    getTimeResolution() {
      return TIMESCALE;
    }
    async computeDuration() {
      const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
      return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    async getFirstTimestamp() {
      const firstPacket = await this.getFirstPacket({ metadataOnly: true });
      return firstPacket?.timestamp ?? 0;
    }
    createEncodedPacket(suppliedPacket, duration, options) {
      let packetType;
      if (this.allPacketsAreKeyPackets()) {
        packetType = "key";
      } else {
        packetType = suppliedPacket.randomAccessIndicator === 1 ? "key" : "delta";
      }
      return new EncodedPacket(
        options.metadataOnly ? PLACEHOLDER_DATA : suppliedPacket.data,
        packetType,
        suppliedPacket.pts / TIMESCALE,
        Math.max(duration / TIMESCALE, 0),
        suppliedPacket.sequenceNumber,
        suppliedPacket.data.byteLength
      );
    }
    async getFirstPacket(options) {
      const section = this.elementaryStream.firstSection;
      assert(section);
      const pesPacket = readPesPacket(section);
      assert(pesPacket);
      const context = new PacketReadingContext(this.elementaryStream, pesPacket);
      const buffer = new PacketBuffer(this, context);
      const result = await buffer.readNext();
      if (!result) {
        return null;
      }
      const packet = this.createEncodedPacket(result.packet, result.duration, options);
      this.packetBuffers.set(packet, buffer);
      this.packetSectionStarts.set(packet, result.packet.sectionStartPos);
      return packet;
    }
    async getNextPacket(packet, options) {
      let buffer = this.packetBuffers.get(packet);
      if (buffer) {
        const result = await buffer.readNext();
        if (!result) {
          return null;
        }
        this.packetBuffers.delete(packet);
        const newPacket = this.createEncodedPacket(result.packet, result.duration, options);
        this.packetBuffers.set(newPacket, buffer);
        this.packetSectionStarts.set(newPacket, result.packet.sectionStartPos);
        return newPacket;
      }
      const sectionStartPos = this.packetSectionStarts.get(packet);
      if (sectionStartPos === void 0) {
        throw new Error("Packet was not created from this track.");
      }
      const demuxer = this.elementaryStream.demuxer;
      const section = await demuxer.readSection(sectionStartPos, true);
      assert(section);
      const pesPacket = readPesPacket(section);
      assert(pesPacket);
      const context = new PacketReadingContext(this.elementaryStream, pesPacket);
      buffer = new PacketBuffer(this, context);
      const targetSequenceNumber = packet.sequenceNumber;
      while (true) {
        const result = await buffer.readNext();
        if (!result) {
          return null;
        }
        if (result.packet.sequenceNumber > targetSequenceNumber) {
          const newPacket = this.createEncodedPacket(result.packet, result.duration, options);
          this.packetBuffers.set(newPacket, buffer);
          this.packetSectionStarts.set(newPacket, result.packet.sectionStartPos);
          return newPacket;
        }
      }
    }
    async getNextKeyPacket(packet, options) {
      let currentPacket = packet;
      while (true) {
        currentPacket = await this.getNextPacket(currentPacket, options);
        if (!currentPacket) {
          return null;
        }
        if (currentPacket.type === "key") {
          return currentPacket;
        }
      }
    }
    getPacket(timestamp, options) {
      return this.doPacketLookup(timestamp, false, options);
    }
    getKeyPacket(timestamp, options) {
      return this.doPacketLookup(timestamp, true, options);
    }
    /**
     * Searches for the packet with the largest timestamp not larger than `timestamp` in the file, using a combination
     * of chunk-based binary search and linear refinement. The reason the coarse search is done in large chunks is to
     * make it more performant for small files and over high-latency readers such as the network.
     */
    async doPacketLookup(timestamp, keyframesOnly, options) {
      const searchPts = roundIfAlmostInteger(timestamp * TIMESCALE);
      const demuxer = this.elementaryStream.demuxer;
      const { reader, seekChunkSize } = demuxer;
      const pid = this.elementaryStream.pid;
      const findFirstPesPacketHeaderInChunk = async (startPos, endPos) => {
        let currentPos = startPos;
        while (currentPos < endPos) {
          const packetHeader = await demuxer.readPacketHeader(currentPos);
          if (!packetHeader) {
            return null;
          }
          if (packetHeader.pid === pid && packetHeader.payloadUnitStartIndicator === 1) {
            const section = await demuxer.readSection(currentPos, false);
            if (!section) {
              return null;
            }
            const pesPacketHeader = readPesPacketHeader(section);
            if (pesPacketHeader) {
              return pesPacketHeader;
            }
          }
          currentPos += demuxer.packetStride;
        }
        return null;
      };
      const firstSection = this.elementaryStream.firstSection;
      assert(firstSection);
      const firstPesPacketHeader = readPesPacketHeader(firstSection);
      assert(firstPesPacketHeader);
      if (searchPts < firstPesPacketHeader.pts) {
        return null;
      }
      let scanStartPos;
      const referencePesPackets = this.elementaryStream.referencePesPackets;
      const referencePointIndex = binarySearchLessOrEqual(referencePesPackets, searchPts, (x) => x.pts);
      const referencePoint = referencePointIndex !== -1 ? referencePesPackets[referencePointIndex] : null;
      if (referencePoint && searchPts - referencePoint.pts < TIMESCALE / 2) {
        scanStartPos = referencePoint.sectionStartPos;
      } else {
        let startChunkIndex = 0;
        if (reader.fileSize !== null) {
          const numChunks = Math.ceil(reader.fileSize / seekChunkSize);
          if (numChunks > 1) {
            let low = 0;
            let high = numChunks - 1;
            startChunkIndex = low;
            while (low <= high) {
              const mid = Math.floor((low + high) / 2);
              const chunkStartPos = floorToMultiple(mid * seekChunkSize, demuxer.packetStride) + firstPesPacketHeader.sectionStartPos;
              const chunkEndPos = chunkStartPos + seekChunkSize;
              const pesHeader = await findFirstPesPacketHeaderInChunk(chunkStartPos, chunkEndPos);
              if (!pesHeader) {
                high = mid - 1;
                continue;
              }
              if (pesHeader.pts <= searchPts) {
                startChunkIndex = mid;
                low = mid + 1;
              } else {
                high = mid - 1;
              }
            }
          }
        }
        scanStartPos = floorToMultiple(
          startChunkIndex * seekChunkSize,
          demuxer.packetStride
        ) + firstPesPacketHeader.sectionStartPos;
      }
      let currentPesHeader = await findFirstPesPacketHeaderInChunk(
        scanStartPos,
        reader.fileSize ?? Infinity
      );
      if (!currentPesHeader) {
        currentPesHeader = firstPesPacketHeader;
      }
      const reorderSize = this.getReorderSize();
      const retrieveEncodedPacket = async (sectionStartPos, predicate) => {
        const section = await demuxer.readSection(sectionStartPos, true);
        assert(section);
        const pesPacket = readPesPacket(section);
        assert(pesPacket);
        const context = new PacketReadingContext(this.elementaryStream, pesPacket);
        const buffer = new PacketBuffer(this, context);
        while (true) {
          const topPts = last(buffer.presentationOrderPackets)?.pts ?? -Infinity;
          if (topPts >= searchPts) {
            break;
          }
          const didRead = await buffer.readNextPacket();
          if (!didRead) {
            break;
          }
        }
        const targetIndex = findLastIndex(buffer.presentationOrderPackets, predicate);
        if (targetIndex === -1) {
          return null;
        }
        const targetPacket = buffer.presentationOrderPackets[targetIndex];
        const lastDuration = targetIndex === 0 ? 0 : targetPacket.pts - buffer.presentationOrderPackets[targetIndex - 1].pts;
        while (buffer.decodeOrderPackets[0] !== targetPacket) {
          buffer.decodeOrderPackets.shift();
        }
        buffer.lastDuration = lastDuration;
        const result = await buffer.readNext();
        assert(result);
        const packet = this.createEncodedPacket(result.packet, result.duration, options);
        this.packetBuffers.set(packet, buffer);
        this.packetSectionStarts.set(packet, result.packet.sectionStartPos);
        return packet;
      };
      if (!keyframesOnly || this.allPacketsAreKeyPackets()) {
        outer:
          while (true) {
            let currentPos = currentPesHeader.sectionStartPos + demuxer.packetStride;
            while (true) {
              const packetHeader = await demuxer.readPacketHeader(currentPos);
              if (!packetHeader) {
                break outer;
              }
              if (packetHeader.pid === pid && packetHeader.payloadUnitStartIndicator === 1) {
                const section = await demuxer.readSection(currentPos, false);
                if (section) {
                  const nextPesHeader = readPesPacketHeader(section);
                  if (nextPesHeader) {
                    if (nextPesHeader.pts > searchPts) {
                      break outer;
                    }
                    currentPesHeader = nextPesHeader;
                    maybeInsertReferencePacket(this.elementaryStream, nextPesHeader);
                    break;
                  }
                }
              }
              currentPos += demuxer.packetStride;
            }
          }
        outer:
          for (let i = 0; i < reorderSize; i++) {
            let pos = currentPesHeader.sectionStartPos - demuxer.packetStride;
            while (pos >= demuxer.packetOffset) {
              const packetHeader = await demuxer.readPacketHeader(pos);
              if (!packetHeader) {
                break outer;
              }
              if (packetHeader.pid === pid && packetHeader.payloadUnitStartIndicator === 1) {
                const section = await demuxer.readSection(pos, false);
                if (section) {
                  const header = readPesPacketHeader(section);
                  if (header) {
                    currentPesHeader = header;
                    break;
                  }
                }
              }
              pos -= demuxer.packetStride;
            }
          }
        return retrieveEncodedPacket(currentPesHeader.sectionStartPos, (p) => p.pts <= searchPts);
      } else {
        let currentChunkStartPos = scanStartPos;
        let nextChunkStartPos = null;
        while (true) {
          let bestKeyPesHeader = null;
          const isFirstChunk = currentChunkStartPos <= firstPesPacketHeader.sectionStartPos;
          let pesHeader;
          if (isFirstChunk) {
            pesHeader = firstPesPacketHeader;
            bestKeyPesHeader = firstPesPacketHeader;
          } else {
            pesHeader = await findFirstPesPacketHeaderInChunk(
              currentChunkStartPos,
              reader.fileSize ?? Infinity
            );
          }
          let passedSearchPts = false;
          let lookaheadCount = 0;
          outer:
            while (pesHeader) {
              if (nextChunkStartPos !== null && pesHeader.sectionStartPos >= nextChunkStartPos) {
                break;
              }
              const isKeyCandidate = pesHeader.randomAccessIndicator === 1;
              if (isKeyCandidate && pesHeader.pts <= searchPts) {
                bestKeyPesHeader = pesHeader;
              }
              if (pesHeader.pts > searchPts) {
                passedSearchPts = true;
              }
              if (passedSearchPts) {
                lookaheadCount++;
                if (lookaheadCount >= reorderSize) {
                  break;
                }
              }
              let currentPos = pesHeader.sectionStartPos + demuxer.packetStride;
              while (true) {
                const packetHeader = await demuxer.readPacketHeader(currentPos);
                if (!packetHeader) {
                  break outer;
                }
                if (packetHeader.pid === pid && packetHeader.payloadUnitStartIndicator === 1) {
                  const section = await demuxer.readSection(currentPos, false);
                  if (section) {
                    pesHeader = readPesPacketHeader(section);
                    if (pesHeader) {
                      maybeInsertReferencePacket(this.elementaryStream, pesHeader);
                      break;
                    }
                  }
                }
                currentPos += demuxer.packetStride;
              }
            }
          if (bestKeyPesHeader) {
            let startPesHeader = bestKeyPesHeader;
            if (lookaheadCount === 0) {
              outer:
                for (let i = 0; i < reorderSize - 1; i++) {
                  let pos = startPesHeader.sectionStartPos - demuxer.packetStride;
                  while (pos >= demuxer.packetOffset) {
                    const packetHeader = await demuxer.readPacketHeader(pos);
                    if (!packetHeader) {
                      break outer;
                    }
                    if (packetHeader.pid === pid && packetHeader.payloadUnitStartIndicator === 1) {
                      const section = await demuxer.readSection(pos, false);
                      if (section) {
                        const header = readPesPacketHeader(section);
                        if (header) {
                          startPesHeader = header;
                          break;
                        }
                      }
                    }
                    pos -= demuxer.packetStride;
                  }
                }
            }
            const encodedPacket = await retrieveEncodedPacket(
              startPesHeader.sectionStartPos,
              (p) => p.pts <= searchPts && p.randomAccessIndicator === 1
            );
            assert(encodedPacket);
            return encodedPacket;
          }
          assert(!isFirstChunk);
          nextChunkStartPos = currentChunkStartPos;
          currentChunkStartPos = Math.max(
            floorToMultiple(
              currentChunkStartPos - firstPesPacketHeader.sectionStartPos - seekChunkSize,
              demuxer.packetStride
            ) + firstPesPacketHeader.sectionStartPos,
            firstPesPacketHeader.sectionStartPos
          );
        }
      }
    }
  };
  var MpegTsVideoTrackBacking = class extends MpegTsTrackBacking {
    constructor(elementaryStream) {
      super(elementaryStream);
      this.elementaryStream = elementaryStream;
      this.decoderConfig = {
        codec: extractVideoCodecString({
          width: this.elementaryStream.info.width,
          height: this.elementaryStream.info.height,
          codec: this.elementaryStream.info.codec,
          codecDescription: null,
          colorSpace: this.elementaryStream.info.colorSpace,
          avcType: 1,
          avcCodecInfo: this.elementaryStream.info.avcCodecInfo,
          hevcCodecInfo: this.elementaryStream.info.hevcCodecInfo,
          vp9CodecInfo: null,
          av1CodecInfo: null
        }),
        codedWidth: this.elementaryStream.info.width,
        codedHeight: this.elementaryStream.info.height,
        colorSpace: this.elementaryStream.info.colorSpace
      };
    }
    getCodec() {
      return this.elementaryStream.info.codec;
    }
    getCodedWidth() {
      return this.elementaryStream.info.width;
    }
    getCodedHeight() {
      return this.elementaryStream.info.height;
    }
    getRotation() {
      return 0;
    }
    async getColorSpace() {
      return this.elementaryStream.info.colorSpace;
    }
    async canBeTransparent() {
      return false;
    }
    async getDecoderConfig() {
      return this.decoderConfig;
    }
    allPacketsAreKeyPackets() {
      return false;
    }
    getReorderSize() {
      return this.elementaryStream.info.reorderSize;
    }
  };
  var MpegTsAudioTrackBacking = class extends MpegTsTrackBacking {
    constructor(elementaryStream) {
      super(elementaryStream);
      this.elementaryStream = elementaryStream;
    }
    getCodec() {
      return this.elementaryStream.info.codec;
    }
    getNumberOfChannels() {
      return this.elementaryStream.info.numberOfChannels;
    }
    getSampleRate() {
      return this.elementaryStream.info.sampleRate;
    }
    async getDecoderConfig() {
      return {
        codec: extractAudioCodecString({
          codec: this.elementaryStream.info.codec,
          codecDescription: null,
          aacCodecInfo: this.elementaryStream.info.aacCodecInfo
        }),
        numberOfChannels: this.elementaryStream.info.numberOfChannels,
        sampleRate: this.elementaryStream.info.sampleRate
      };
    }
    allPacketsAreKeyPackets() {
      return true;
    }
    getReorderSize() {
      return 1;
    }
  };
  var maybeInsertReferencePacket = (elementaryStream, pesPacketHeader) => {
    const referencePesPackets = elementaryStream.referencePesPackets;
    const index = binarySearchLessOrEqual(
      referencePesPackets,
      pesPacketHeader.sectionStartPos,
      (x) => x.sectionStartPos
    );
    if (index >= 0) {
      const entry = referencePesPackets[index];
      if (pesPacketHeader.pts <= entry.pts) {
        return false;
      }
      const minByteDistance = elementaryStream.demuxer.minReferencePointByteDistance;
      if (pesPacketHeader.sectionStartPos - entry.sectionStartPos < minByteDistance) {
        return false;
      }
      if (index < referencePesPackets.length - 1) {
        const nextEntry = referencePesPackets[index + 1];
        if (nextEntry.pts < pesPacketHeader.pts) {
          return false;
        }
        if (nextEntry.sectionStartPos - pesPacketHeader.sectionStartPos < minByteDistance) {
          return false;
        }
      }
    }
    referencePesPackets.splice(index + 1, 0, pesPacketHeader);
    return true;
  };
  var markNextPacket = async (context) => {
    assert(!context.suppliedPacket);
    const elementaryStream = context.elementaryStream;
    if (elementaryStream.info.type === "video") {
      const codec = elementaryStream.info.codec;
      const CHUNK_SIZE = 1024;
      if (codec !== "avc" && codec !== "hevc") {
        throw new Error("Unhandled.");
      }
      let packetStartPos = null;
      while (true) {
        let remaining = context.ensureBuffered(CHUNK_SIZE);
        if (remaining instanceof Promise) remaining = await remaining;
        if (remaining === 0) {
          break;
        }
        const chunkStartPos = context.currentPos;
        const chunk = context.readBytes(remaining);
        const length = chunk.byteLength;
        let i = 0;
        while (i < length) {
          const zeroIndex = chunk.indexOf(0, i);
          if (zeroIndex === -1 || zeroIndex >= length) {
            break;
          }
          i = zeroIndex;
          const posBeforeZero = chunkStartPos + i;
          if (i + 4 >= length) {
            context.seekTo(posBeforeZero);
            break;
          }
          const b1 = chunk[i + 1];
          const b2 = chunk[i + 2];
          const b3 = chunk[i + 3];
          let startCodeLength = 0;
          let nalUnitTypeByte = null;
          if (b1 === 0 && b2 === 0 && b3 === 1) {
            startCodeLength = 4;
            nalUnitTypeByte = chunk[i + 4];
          } else if (b1 === 0 && b2 === 1) {
            startCodeLength = 3;
            nalUnitTypeByte = b3;
          }
          if (startCodeLength === 0) {
            i++;
            continue;
          }
          const startCodePos = posBeforeZero;
          if (packetStartPos === null) {
            packetStartPos = startCodePos;
            i += startCodeLength;
            continue;
          }
          if (nalUnitTypeByte !== null) {
            const nalUnitType = codec === "avc" ? extractNalUnitTypeForAvc(nalUnitTypeByte) : extractNalUnitTypeForHevc(nalUnitTypeByte);
            const isAud = codec === "avc" ? nalUnitType === 9 /* AUD */ : nalUnitType === 35 /* AUD_NUT */;
            if (isAud) {
              const packetLength = startCodePos - packetStartPos;
              context.seekTo(packetStartPos);
              return context.supplyPacket(packetLength, 0);
            }
          }
          i += startCodeLength;
        }
        if (remaining < CHUNK_SIZE) {
          break;
        }
      }
      if (packetStartPos !== null) {
        const packetLength = context.endPos - packetStartPos;
        context.seekTo(packetStartPos);
        return context.supplyPacket(packetLength, 0);
      }
    } else {
      const codec = elementaryStream.info.codec;
      const CHUNK_SIZE = 128;
      while (true) {
        let remaining = context.ensureBuffered(CHUNK_SIZE);
        if (remaining instanceof Promise) remaining = await remaining;
        const startPos = context.currentPos;
        while (context.currentPos - startPos < remaining) {
          const byte = context.readU8();
          if (codec === "aac") {
            if (byte !== 255) {
              continue;
            }
            context.skip(-1);
            const possibleHeaderStartPos = context.currentPos;
            let remaining2 = context.ensureBuffered(MAX_ADTS_FRAME_HEADER_SIZE);
            if (remaining2 instanceof Promise) remaining2 = await remaining2;
            if (remaining2 < MAX_ADTS_FRAME_HEADER_SIZE) {
              return;
            }
            const headerBytes = context.readBytes(MAX_ADTS_FRAME_HEADER_SIZE);
            const header = readAdtsFrameHeader(FileSlice4.tempFromBytes(headerBytes));
            if (header) {
              context.seekTo(possibleHeaderStartPos);
              let remaining3 = context.ensureBuffered(header.frameLength);
              if (remaining3 instanceof Promise) remaining3 = await remaining3;
              return context.supplyPacket(
                remaining3,
                Math.round(SAMPLES_PER_AAC_FRAME * TIMESCALE / elementaryStream.info.sampleRate)
              );
            } else {
              context.seekTo(possibleHeaderStartPos + 1);
            }
          } else if (codec === "mp3") {
            if (byte !== 255) {
              continue;
            }
            context.skip(-1);
            const possibleHeaderStartPos = context.currentPos;
            let remaining2 = context.ensureBuffered(FRAME_HEADER_SIZE);
            if (remaining2 instanceof Promise) remaining2 = await remaining2;
            if (remaining2 < FRAME_HEADER_SIZE) {
              return;
            }
            const headerBytes = context.readBytes(FRAME_HEADER_SIZE);
            const word = toDataView(headerBytes).getUint32(0);
            const result = readMp3FrameHeader(word, null);
            if (result.header) {
              context.seekTo(possibleHeaderStartPos);
              let remaining3 = context.ensureBuffered(result.header.totalSize);
              if (remaining3 instanceof Promise) remaining3 = await remaining3;
              const duration = result.header.audioSamplesInFrame * TIMESCALE / elementaryStream.info.sampleRate;
              return context.supplyPacket(remaining3, Math.round(duration));
            } else {
              context.seekTo(possibleHeaderStartPos + 1);
            }
          } else if (codec === "ac3") {
            if (byte !== 11) {
              continue;
            }
            context.skip(-1);
            const possibleSyncPos = context.currentPos;
            let remaining2 = context.ensureBuffered(5);
            if (remaining2 instanceof Promise) remaining2 = await remaining2;
            if (remaining2 < 5) {
              return;
            }
            const headerBytes = context.readBytes(5);
            if (headerBytes[0] !== 11 || headerBytes[1] !== 119) {
              context.seekTo(possibleSyncPos + 1);
              continue;
            }
            const fscod = headerBytes[4] >> 6;
            const frmsizecod = headerBytes[4] & 63;
            if (fscod === 3 || frmsizecod > 37) {
              context.seekTo(possibleSyncPos + 1);
              continue;
            }
            const frameSize = AC3_FRAME_SIZES[3 * frmsizecod + fscod];
            assert(frameSize !== void 0);
            context.seekTo(possibleSyncPos);
            remaining2 = context.ensureBuffered(frameSize);
            if (remaining2 instanceof Promise) remaining2 = await remaining2;
            const duration = Math.round(
              AC3_SAMPLES_PER_FRAME * TIMESCALE / elementaryStream.info.sampleRate
            );
            return context.supplyPacket(remaining2, duration);
          } else if (codec === "eac3") {
            if (byte !== 11) {
              continue;
            }
            context.skip(-1);
            const possibleSyncPos = context.currentPos;
            let remaining2 = context.ensureBuffered(5);
            if (remaining2 instanceof Promise) remaining2 = await remaining2;
            if (remaining2 < 5) {
              return;
            }
            const headerBytes = context.readBytes(5);
            if (headerBytes[0] !== 11 || headerBytes[1] !== 119) {
              context.seekTo(possibleSyncPos + 1);
              continue;
            }
            const frmsiz = (headerBytes[2] & 7) << 8 | headerBytes[3];
            const frameSize = (frmsiz + 1) * 2;
            const fscod = headerBytes[4] >> 6;
            const numblkscod = fscod === 3 ? 3 : headerBytes[4] >> 4 & 3;
            const numblks = EAC3_NUMBLKS_TABLE[numblkscod];
            context.seekTo(possibleSyncPos);
            remaining2 = context.ensureBuffered(frameSize);
            if (remaining2 instanceof Promise) remaining2 = await remaining2;
            const samplesPerFrame = numblks * 256;
            const duration = Math.round(
              samplesPerFrame * TIMESCALE / elementaryStream.info.sampleRate
            );
            return context.supplyPacket(remaining2, duration);
          } else {
            throw new Error("Unhandled.");
          }
        }
        if (remaining < CHUNK_SIZE) {
          break;
        }
      }
    }
  };
  var PacketReadingContext = class _PacketReadingContext {
    constructor(elementaryStream, startingPesPacket) {
      this.currentPos = 0;
      // Relative to the data in startingPesPacket
      this.pesPackets = [];
      this.currentPesPacketIndex = 0;
      this.currentPesPacketPos = 0;
      this.endPos = 0;
      this.nextPts = 0;
      this.suppliedPacket = null;
      this.elementaryStream = elementaryStream;
      this.pid = elementaryStream.pid;
      this.demuxer = elementaryStream.demuxer;
      this.startingPesPacket = startingPesPacket;
    }
    clone() {
      const clone = new _PacketReadingContext(this.elementaryStream, this.startingPesPacket);
      clone.currentPos = this.currentPos;
      clone.pesPackets = [...this.pesPackets];
      clone.currentPesPacketIndex = this.currentPesPacketIndex;
      clone.currentPesPacketPos = this.currentPesPacketPos;
      clone.endPos = this.endPos;
      clone.nextPts = this.nextPts;
      return clone;
    }
    ensureBuffered(length) {
      const remaining = this.endPos - this.currentPos;
      if (remaining >= length) {
        return length;
      }
      return this.bufferData(length - remaining).then(() => Math.min(this.endPos - this.currentPos, length));
    }
    getCurrentPesPacket() {
      const packet = this.pesPackets[this.currentPesPacketIndex];
      assert(packet);
      return packet;
    }
    async bufferData(length) {
      const targetEndPos = this.endPos + length;
      while (this.endPos < targetEndPos) {
        let pesPacket;
        if (this.pesPackets.length === 0) {
          pesPacket = this.startingPesPacket;
        } else {
          let currentPos = last(this.pesPackets).sectionEndPos;
          assert(currentPos !== null);
          while (true) {
            const packetHeader = await this.demuxer.readPacketHeader(currentPos);
            if (!packetHeader) {
              return;
            }
            if (packetHeader.pid === this.pid) {
              const nextSection = await this.demuxer.readSection(currentPos, true);
              if (!nextSection) {
                return;
              }
              const nextPesPacket = readPesPacket(nextSection);
              if (nextPesPacket) {
                pesPacket = nextPesPacket;
                break;
              }
            }
            currentPos += this.demuxer.packetStride;
          }
        }
        this.pesPackets.push(pesPacket);
        this.endPos += pesPacket.data.byteLength;
        if (this.pesPackets.length === 1) {
          this.nextPts = pesPacket.pts;
        }
      }
    }
    readBytes(length) {
      const currentPesPacket = this.getCurrentPesPacket();
      const relativeStartOffset = this.currentPos - this.currentPesPacketPos;
      const relativeEndOffset = relativeStartOffset + length;
      this.currentPos += length;
      if (relativeEndOffset <= currentPesPacket.data.byteLength) {
        return currentPesPacket.data.subarray(relativeStartOffset, relativeEndOffset);
      }
      const result = new Uint8Array(length);
      result.set(currentPesPacket.data.subarray(relativeStartOffset));
      let offset = currentPesPacket.data.byteLength - relativeStartOffset;
      while (true) {
        this.advanceCurrentPacket();
        const currentPesPacket2 = this.getCurrentPesPacket();
        const relativeEndOffset2 = length - offset;
        if (relativeEndOffset2 <= currentPesPacket2.data.byteLength) {
          result.set(currentPesPacket2.data.subarray(0, relativeEndOffset2), offset);
          break;
        }
        result.set(currentPesPacket2.data, offset);
        offset += currentPesPacket2.data.byteLength;
      }
      return result;
    }
    readU8() {
      let currentPesPacket = this.getCurrentPesPacket();
      const relativeOffset = this.currentPos - this.currentPesPacketPos;
      this.currentPos++;
      if (relativeOffset < currentPesPacket.data.byteLength) {
        return currentPesPacket.data[relativeOffset];
      }
      this.advanceCurrentPacket();
      currentPesPacket = this.getCurrentPesPacket();
      return currentPesPacket.data[0];
    }
    seekTo(pos) {
      if (pos === this.currentPos) {
        return;
      }
      if (pos < this.currentPos) {
        while (pos < this.currentPesPacketPos) {
          this.currentPesPacketIndex--;
          const currentPacket = this.getCurrentPesPacket();
          this.currentPesPacketPos -= currentPacket.data.byteLength;
          this.nextPts = currentPacket.pts;
        }
      } else {
        while (true) {
          const currentPesPacket = this.getCurrentPesPacket();
          const currentEndPos = this.currentPesPacketPos + currentPesPacket.data.byteLength;
          if (pos < currentEndPos) {
            break;
          }
          this.currentPesPacketPos += currentPesPacket.data.byteLength;
          this.currentPesPacketIndex++;
          this.nextPts = this.getCurrentPesPacket().pts;
        }
      }
      this.currentPos = pos;
    }
    skip(n) {
      this.seekTo(this.currentPos + n);
    }
    advanceCurrentPacket() {
      this.currentPesPacketPos += this.getCurrentPesPacket().data.byteLength;
      this.currentPesPacketIndex++;
      this.nextPts = this.getCurrentPesPacket().pts;
    }
    /** Supplies the context with a new encoded packet, beginning at the current position. */
    supplyPacket(packetLength, intrinsicDuration) {
      const currentPesPacket = this.getCurrentPesPacket();
      maybeInsertReferencePacket(this.elementaryStream, currentPesPacket);
      const pts = this.nextPts;
      this.nextPts += intrinsicDuration;
      const sectionStartPos = currentPesPacket.sectionStartPos;
      const sequenceNumber = sectionStartPos + (this.currentPos - this.currentPesPacketPos);
      const data = this.readBytes(packetLength);
      let randomAccessIndicator = currentPesPacket.randomAccessIndicator;
      assert(this.elementaryStream.firstSection);
      if (currentPesPacket.sectionStartPos === this.elementaryStream.firstSection.startPos) {
        randomAccessIndicator = 1;
      }
      this.suppliedPacket = {
        pts,
        data,
        sequenceNumber,
        sectionStartPos,
        randomAccessIndicator
      };
      this.pesPackets.splice(0, this.currentPesPacketIndex);
      this.currentPesPacketIndex = 0;
    }
  };
  var PacketBuffer = class {
    constructor(backing, context) {
      this.decodeOrderPackets = [];
      this.reorderBuffer = [];
      this.presentationOrderPackets = [];
      this.reachedEnd = false;
      this.lastDuration = 0;
      this.backing = backing;
      this.context = context;
      this.reorderSize = backing.getReorderSize();
      assert(this.reorderSize >= 0);
    }
    async readNext() {
      if (this.decodeOrderPackets.length === 0) {
        const didRead = await this.readNextPacket();
        if (!didRead) {
          return null;
        }
      }
      await this.ensureCurrentPacketHasNext();
      const packet = this.decodeOrderPackets[0];
      const presentationIndex = this.presentationOrderPackets.indexOf(packet);
      assert(presentationIndex !== -1);
      let duration;
      if (presentationIndex === this.presentationOrderPackets.length - 1) {
        duration = this.lastDuration;
      } else {
        const nextPacket = this.presentationOrderPackets[presentationIndex + 1];
        duration = nextPacket.pts - packet.pts;
        this.lastDuration = duration;
      }
      this.decodeOrderPackets.shift();
      while (this.presentationOrderPackets.length > 0) {
        const first = this.presentationOrderPackets[0];
        if (this.decodeOrderPackets.includes(first)) {
          break;
        }
        this.presentationOrderPackets.shift();
      }
      return { packet, duration };
    }
    async readNextPacket() {
      if (this.reachedEnd) {
        return false;
      }
      let suppliedPacket;
      if (this.context.suppliedPacket) {
        suppliedPacket = this.context.suppliedPacket;
      } else {
        await markNextPacket(this.context);
        suppliedPacket = this.context.suppliedPacket;
      }
      this.context.suppliedPacket = null;
      if (!suppliedPacket) {
        this.reachedEnd = true;
        this.flushReorderBuffer();
        return false;
      }
      this.decodeOrderPackets.push(suppliedPacket);
      this.processPacketThroughReorderBuffer(suppliedPacket);
      return true;
    }
    async ensureCurrentPacketHasNext() {
      const current = this.decodeOrderPackets[0];
      assert(current);
      while (true) {
        const presentationIndex = this.presentationOrderPackets.indexOf(current);
        if (presentationIndex !== -1 && presentationIndex <= this.presentationOrderPackets.length - 2) {
          break;
        }
        const didRead = await this.readNextPacket();
        if (!didRead) {
          break;
        }
      }
    }
    processPacketThroughReorderBuffer(packet) {
      this.reorderBuffer.push(packet);
      if (this.reorderBuffer.length >= this.reorderSize) {
        let minIndex = 0;
        for (let i = 1; i < this.reorderBuffer.length; i++) {
          if (this.reorderBuffer[i].pts < this.reorderBuffer[minIndex].pts) {
            minIndex = i;
          }
        }
        const packet2 = this.reorderBuffer.splice(minIndex, 1)[0];
        this.presentationOrderPackets.push(packet2);
      }
    }
    flushReorderBuffer() {
      this.reorderBuffer.sort((a, b) => a.pts - b.pts);
      this.presentationOrderPackets.push(...this.reorderBuffer);
      this.reorderBuffer.length = 0;
    }
  };

  // src/input-format.ts
  var InputFormat = class {
  };
  var IsobmffInputFormat = class extends InputFormat {
    /** @internal */
    async _getMajorBrand(input) {
      let slice = input._reader.requestSlice(0, 12);
      if (slice instanceof Promise) slice = await slice;
      if (!slice) return null;
      slice.skip(4);
      const fourCc = readAscii(slice, 4);
      if (fourCc !== "ftyp") {
        return null;
      }
      return readAscii(slice, 4);
    }
    /** @internal */
    _createDemuxer(input) {
      return new IsobmffDemuxer(input);
    }
  };
  var Mp4InputFormat = class extends IsobmffInputFormat {
    /** @internal */
    async _canReadInput(input) {
      const majorBrand = await this._getMajorBrand(input);
      return !!majorBrand && majorBrand !== "qt  ";
    }
    get name() {
      return "MP4";
    }
    get mimeType() {
      return "video/mp4";
    }
  };
  var QuickTimeInputFormat = class extends IsobmffInputFormat {
    /** @internal */
    async _canReadInput(input) {
      const majorBrand = await this._getMajorBrand(input);
      return majorBrand === "qt  ";
    }
    get name() {
      return "QuickTime File Format";
    }
    get mimeType() {
      return "video/quicktime";
    }
  };
  var MatroskaInputFormat = class extends InputFormat {
    /** @internal */
    async isSupportedEBMLOfDocType(input, desiredDocType) {
      let headerSlice = input._reader.requestSlice(0, MAX_HEADER_SIZE);
      if (headerSlice instanceof Promise) headerSlice = await headerSlice;
      if (!headerSlice) return false;
      const varIntSize = readVarIntSize(headerSlice);
      if (varIntSize === null) {
        return false;
      }
      if (varIntSize < 1 || varIntSize > 8) {
        return false;
      }
      const id = readUnsignedInt(headerSlice, varIntSize);
      if (id !== 440786851 /* EBML */) {
        return false;
      }
      const dataSize = readElementSize(headerSlice);
      if (typeof dataSize !== "number") {
        return false;
      }
      let dataSlice = input._reader.requestSlice(headerSlice.filePos, dataSize);
      if (dataSlice instanceof Promise) dataSlice = await dataSlice;
      if (!dataSlice) return false;
      const startPos = headerSlice.filePos;
      while (dataSlice.filePos <= startPos + dataSize - MIN_HEADER_SIZE) {
        const header = readElementHeader(dataSlice);
        if (!header) break;
        const { id: id2, size } = header;
        const dataStartPos = dataSlice.filePos;
        if (size === void 0) return false;
        switch (id2) {
          case 17030 /* EBMLVersion */:
            {
              const ebmlVersion = readUnsignedInt(dataSlice, size);
              if (ebmlVersion !== 1) {
                return false;
              }
            }
            ;
            break;
          case 17143 /* EBMLReadVersion */:
            {
              const ebmlReadVersion = readUnsignedInt(dataSlice, size);
              if (ebmlReadVersion !== 1) {
                return false;
              }
            }
            ;
            break;
          case 17026 /* DocType */:
            {
              const docType = readAsciiString(dataSlice, size);
              if (docType !== desiredDocType) {
                return false;
              }
            }
            ;
            break;
          case 17031 /* DocTypeVersion */:
            {
              const docTypeVersion = readUnsignedInt(dataSlice, size);
              if (docTypeVersion > 4) {
                return false;
              }
            }
            ;
            break;
        }
        dataSlice.filePos = dataStartPos + size;
      }
      return true;
    }
    /** @internal */
    _canReadInput(input) {
      return this.isSupportedEBMLOfDocType(input, "matroska");
    }
    /** @internal */
    _createDemuxer(input) {
      return new MatroskaDemuxer(input);
    }
    get name() {
      return "Matroska";
    }
    get mimeType() {
      return "video/x-matroska";
    }
  };
  var WebMInputFormat = class extends MatroskaInputFormat {
    /** @internal */
    _canReadInput(input) {
      return this.isSupportedEBMLOfDocType(input, "webm");
    }
    get name() {
      return "WebM";
    }
    get mimeType() {
      return "video/webm";
    }
  };
  var Mp3InputFormat = class extends InputFormat {
    /** @internal */
    async _canReadInput(input) {
      let currentPos = 0;
      while (true) {
        let slice2 = input._reader.requestSlice(currentPos, ID3_V2_HEADER_SIZE);
        if (slice2 instanceof Promise) slice2 = await slice2;
        if (!slice2) break;
        const id3V2Header = readId3V2Header(slice2);
        if (!id3V2Header) {
          break;
        }
        currentPos = slice2.filePos + id3V2Header.size;
      }
      const firstResult = await readNextMp3FrameHeader(input._reader, currentPos, currentPos + 4096);
      if (!firstResult) {
        return false;
      }
      const firstHeader = firstResult.header;
      const xingOffset = getXingOffset(firstHeader.mpegVersionId, firstHeader.channel);
      let slice = input._reader.requestSlice(firstResult.startPos + xingOffset, 4);
      if (slice instanceof Promise) slice = await slice;
      if (!slice) return false;
      const word = readU32Be(slice);
      const isXing = word === XING || word === INFO;
      if (isXing) {
        return true;
      }
      currentPos = firstResult.startPos + firstResult.header.totalSize;
      const secondResult = await readNextMp3FrameHeader(input._reader, currentPos, currentPos + FRAME_HEADER_SIZE);
      if (!secondResult) {
        return false;
      }
      const secondHeader = secondResult.header;
      if (firstHeader.channel !== secondHeader.channel || firstHeader.sampleRate !== secondHeader.sampleRate) {
        return false;
      }
      return true;
    }
    /** @internal */
    _createDemuxer(input) {
      return new Mp3Demuxer(input);
    }
    get name() {
      return "MP3";
    }
    get mimeType() {
      return "audio/mpeg";
    }
  };
  var WaveInputFormat = class extends InputFormat {
    /** @internal */
    async _canReadInput(input) {
      let slice = input._reader.requestSlice(0, 12);
      if (slice instanceof Promise) slice = await slice;
      if (!slice) return false;
      const riffType = readAscii(slice, 4);
      if (riffType !== "RIFF" && riffType !== "RIFX" && riffType !== "RF64") {
        return false;
      }
      slice.skip(4);
      const format = readAscii(slice, 4);
      return format === "WAVE";
    }
    /** @internal */
    _createDemuxer(input) {
      return new WaveDemuxer(input);
    }
    get name() {
      return "WAVE";
    }
    get mimeType() {
      return "audio/wav";
    }
  };
  var OggInputFormat = class extends InputFormat {
    /** @internal */
    async _canReadInput(input) {
      let slice = input._reader.requestSlice(0, 4);
      if (slice instanceof Promise) slice = await slice;
      if (!slice) return false;
      return readAscii(slice, 4) === "OggS";
    }
    /** @internal */
    _createDemuxer(input) {
      return new OggDemuxer(input);
    }
    get name() {
      return "Ogg";
    }
    get mimeType() {
      return "application/ogg";
    }
  };
  var FlacInputFormat = class extends InputFormat {
    /** @internal */
    async _canReadInput(input) {
      let slice = input._reader.requestSlice(0, 4);
      if (slice instanceof Promise) slice = await slice;
      if (!slice) return false;
      return readAscii(slice, 4) === "fLaC";
    }
    get name() {
      return "FLAC";
    }
    get mimeType() {
      return "audio/flac";
    }
    /** @internal */
    _createDemuxer(input) {
      return new FlacDemuxer(input);
    }
  };
  var AdtsInputFormat = class extends InputFormat {
    /** @internal */
    async _canReadInput(input) {
      let currentPos = 0;
      while (true) {
        let slice2 = input._reader.requestSlice(currentPos, ID3_V2_HEADER_SIZE);
        if (slice2 instanceof Promise) slice2 = await slice2;
        if (!slice2) break;
        const id3V2Header = readId3V2Header(slice2);
        if (!id3V2Header) {
          break;
        }
        currentPos = slice2.filePos + id3V2Header.size;
      }
      let slice = input._reader.requestSliceRange(
        currentPos,
        MIN_ADTS_FRAME_HEADER_SIZE,
        MAX_ADTS_FRAME_HEADER_SIZE
      );
      if (slice instanceof Promise) slice = await slice;
      if (!slice) return false;
      const firstHeader = readAdtsFrameHeader(slice);
      if (!firstHeader) {
        return false;
      }
      currentPos += firstHeader.frameLength;
      slice = input._reader.requestSliceRange(
        currentPos,
        MIN_ADTS_FRAME_HEADER_SIZE,
        MAX_ADTS_FRAME_HEADER_SIZE
      );
      if (slice instanceof Promise) slice = await slice;
      if (!slice) return false;
      const secondHeader = readAdtsFrameHeader(slice);
      if (!secondHeader) {
        return false;
      }
      return firstHeader.objectType === secondHeader.objectType && firstHeader.samplingFrequencyIndex === secondHeader.samplingFrequencyIndex && firstHeader.channelConfiguration === secondHeader.channelConfiguration;
    }
    /** @internal */
    _createDemuxer(input) {
      return new AdtsDemuxer(input);
    }
    get name() {
      return "ADTS";
    }
    get mimeType() {
      return "audio/aac";
    }
  };
  var MpegTsInputFormat = class extends InputFormat {
    /** @internal */
    async _canReadInput(input) {
      const lengthToCheck = TS_PACKET_SIZE + 16 + 1;
      let slice = input._reader.requestSlice(0, lengthToCheck);
      if (slice instanceof Promise) slice = await slice;
      if (!slice) return false;
      const bytes2 = readBytes(slice, lengthToCheck);
      if (bytes2[0] === 71 && bytes2[TS_PACKET_SIZE] === 71) {
        return true;
      } else if (bytes2[0] === 71 && bytes2[TS_PACKET_SIZE + 16] === 71) {
        return true;
      } else if (bytes2[4] === 71 && bytes2[4 + TS_PACKET_SIZE] === 71) {
        return true;
      }
      return false;
    }
    /** @internal */
    _createDemuxer(input) {
      return new MpegTsDemuxer(input);
    }
    get name() {
      return "MPEG Transport Stream";
    }
    get mimeType() {
      return "video/MP2T";
    }
  };
  var MP4 = /* @__PURE__ */ new Mp4InputFormat();
  var QTFF = /* @__PURE__ */ new QuickTimeInputFormat();
  var MATROSKA = /* @__PURE__ */ new MatroskaInputFormat();
  var WEBM = /* @__PURE__ */ new WebMInputFormat();
  var MP3 = /* @__PURE__ */ new Mp3InputFormat();
  var WAVE = /* @__PURE__ */ new WaveInputFormat();
  var OGG = /* @__PURE__ */ new OggInputFormat();
  var ADTS = /* @__PURE__ */ new AdtsInputFormat();
  var FLAC = /* @__PURE__ */ new FlacInputFormat();
  var MPEG_TS = /* @__PURE__ */ new MpegTsInputFormat();
  var ALL_FORMATS = [MP4, QTFF, MATROSKA, WEBM, WAVE, OGG, FLAC, MP3, ADTS, MPEG_TS];

  // src/source.ts
  var nodeAlias = __toESM(require_node(), 1);
  var node = typeof nodeAlias !== "undefined" ? nodeAlias : void 0;
  var Source = class {
    constructor() {
      /** @internal */
      this._disposed = false;
      /** @internal */
      this._sizePromise = null;
      /** Called each time data is retrieved from the source. Will be called with the retrieved range (end exclusive). */
      this.onread = null;
    }
    /**
     * Resolves with the total size of the file in bytes. This function is memoized, meaning only the first call
     * will retrieve the size.
     *
     * Returns null if the source is unsized.
     */
    async getSizeOrNull() {
      if (this._disposed) {
        throw new InputDisposedError();
      }
      return this._sizePromise ??= Promise.resolve(this._retrieveSize());
    }
    /**
     * Resolves with the total size of the file in bytes. This function is memoized, meaning only the first call
     * will retrieve the size.
     *
     * Throws an error if the source is unsized.
     */
    async getSize() {
      if (this._disposed) {
        throw new InputDisposedError();
      }
      const result = await this.getSizeOrNull();
      if (result === null) {
        throw new Error("Cannot determine the size of an unsized source.");
      }
      return result;
    }
  };
  var BufferSource = class extends Source {
    /**
     * Creates a new {@link BufferSource} backed by the specified `ArrayBuffer`, `SharedArrayBuffer`,
     * or `ArrayBufferView`.
     */
    constructor(buffer) {
      if (!(buffer instanceof ArrayBuffer) && !(typeof SharedArrayBuffer !== "undefined" && buffer instanceof SharedArrayBuffer) && !ArrayBuffer.isView(buffer)) {
        throw new TypeError("buffer must be an ArrayBuffer, SharedArrayBuffer, or ArrayBufferView.");
      }
      super();
      /** @internal */
      this._onreadCalled = false;
      this._bytes = toUint8Array(buffer);
      this._view = toDataView(buffer);
    }
    /** @internal */
    _retrieveSize() {
      return this._bytes.byteLength;
    }
    /** @internal */
    _read() {
      if (!this._onreadCalled) {
        this.onread?.(0, this._bytes.byteLength);
        this._onreadCalled = true;
      }
      return {
        bytes: this._bytes,
        view: this._view,
        offset: 0
      };
    }
    /** @internal */
    _dispose() {
    }
  };
  var BlobSource = class extends Source {
    /**
     * Creates a new {@link BlobSource} backed by the specified
     * [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).
     */
    constructor(blob, options = {}) {
      if (!(blob instanceof Blob)) {
        throw new TypeError("blob must be a Blob.");
      }
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (options.maxCacheSize !== void 0 && (!isNumber(options.maxCacheSize) || options.maxCacheSize < 0)) {
        throw new TypeError("options.maxCacheSize, when provided, must be a non-negative number.");
      }
      super();
      /** @internal */
      this._readers = /* @__PURE__ */ new WeakMap();
      this._blob = blob;
      this._orchestrator = new ReadOrchestrator({
        maxCacheSize: options.maxCacheSize ?? 8 * 2 ** 20,
        maxWorkerCount: 4,
        runWorker: this._runWorker.bind(this),
        prefetchProfile: PREFETCH_PROFILES.fileSystem
      });
    }
    /** @internal */
    _retrieveSize() {
      const size = this._blob.size;
      this._orchestrator.fileSize = size;
      return size;
    }
    /** @internal */
    _read(start, end) {
      return this._orchestrator.read(start, end);
    }
    /** @internal */
    async _runWorker(worker) {
      let reader = this._readers.get(worker);
      if (reader === void 0) {
        if ("stream" in this._blob && !isWebKit()) {
          const slice = this._blob.slice(worker.currentPos);
          reader = slice.stream().getReader();
        } else {
          reader = null;
        }
        this._readers.set(worker, reader);
      }
      while (worker.currentPos < worker.targetPos && !worker.aborted) {
        if (reader) {
          const { done, value } = await reader.read();
          if (done) {
            this._orchestrator.forgetWorker(worker);
            throw new Error("Blob reader stopped unexpectedly before all requested data was read.");
          }
          if (worker.aborted) {
            break;
          }
          this.onread?.(worker.currentPos, worker.currentPos + value.length);
          this._orchestrator.supplyWorkerData(worker, value);
        } else {
          const data = await this._blob.slice(worker.currentPos, worker.targetPos).arrayBuffer();
          if (worker.aborted) {
            break;
          }
          this.onread?.(worker.currentPos, worker.currentPos + data.byteLength);
          this._orchestrator.supplyWorkerData(worker, new Uint8Array(data));
        }
      }
      worker.running = false;
      if (worker.aborted) {
        await reader?.cancel();
      }
    }
    /** @internal */
    _dispose() {
      this._orchestrator.dispose();
    }
  };
  var URL_SOURCE_MIN_LOAD_AMOUNT = 0.5 * 2 ** 20;
  var DEFAULT_RETRY_DELAY = (previousAttempts, error, src) => {
    const couldBeCorsError = error instanceof Error && (error.message.includes("Failed to fetch") || error.message.includes("Load failed") || error.message.includes("NetworkError when attempting to fetch resource"));
    if (couldBeCorsError) {
      let originOfSrc = null;
      try {
        if (typeof window !== "undefined" && typeof window.location !== "undefined") {
          originOfSrc = new URL(src instanceof Request ? src.url : src, window.location.href).origin;
        }
      } catch {
      }
      const isOnline = typeof navigator !== "undefined" && typeof navigator.onLine === "boolean" ? navigator.onLine : true;
      if (isOnline && originOfSrc !== null && originOfSrc !== window.location.origin) {
        console.warn(
          `Request will not be retried because a CORS error was suspected due to different origins. You can modify this behavior by providing your own function for the 'getRetryDelay' option.`
        );
        return null;
      }
    }
    return Math.min(2 ** (previousAttempts - 2), 16);
  };
  var UrlSource = class extends Source {
    /**
     * Creates a new {@link UrlSource} backed by the resource at the specified URL.
     *
     * When passing a `Request` instance, note that the `signal` and `headers.Range` options will be overridden by
     * Mediabunny. If you want to cancel ongoing requests, use {@link Input.dispose}.
     */
    constructor(url2, options = {}) {
      if (typeof url2 !== "string" && !(url2 instanceof URL) && !(typeof Request !== "undefined" && url2 instanceof Request)) {
        throw new TypeError("url must be a string, URL or Request.");
      }
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (options.requestInit !== void 0 && (!options.requestInit || typeof options.requestInit !== "object")) {
        throw new TypeError("options.requestInit, when provided, must be an object.");
      }
      if (options.getRetryDelay !== void 0 && typeof options.getRetryDelay !== "function") {
        throw new TypeError("options.getRetryDelay, when provided, must be a function.");
      }
      if (options.maxCacheSize !== void 0 && (!isNumber(options.maxCacheSize) || options.maxCacheSize < 0)) {
        throw new TypeError("options.maxCacheSize, when provided, must be a non-negative number.");
      }
      if (options.parallelism !== void 0 && (!Number.isInteger(options.parallelism) || options.parallelism < 1)) {
        throw new TypeError("options.parallelism, when provided, must be a positive number.");
      }
      if (options.fetchFn !== void 0 && typeof options.fetchFn !== "function") {
        throw new TypeError("options.fetchFn, when provided, must be a function.");
      }
      super();
      /** @internal */
      this._existingResponses = /* @__PURE__ */ new WeakMap();
      this._url = url2;
      this._options = options;
      this._getRetryDelay = options.getRetryDelay ?? DEFAULT_RETRY_DELAY;
      const DEFAULT_PARALLELISM = 2;
      this._orchestrator = new ReadOrchestrator({
        maxCacheSize: options.maxCacheSize ?? 64 * 2 ** 20,
        maxWorkerCount: options.parallelism ?? DEFAULT_PARALLELISM,
        runWorker: this._runWorker.bind(this),
        prefetchProfile: PREFETCH_PROFILES.network
      });
    }
    /** @internal */
    async _retrieveSize() {
      const abortController = new AbortController();
      const response = await retriedFetch(
        this._options.fetchFn ?? fetch,
        this._url,
        mergeRequestInit(this._options.requestInit ?? {}, {
          headers: {
            // We could also send a non-range request to request the same bytes (all of them), but doing it like
            // this is an easy way to check if the server supports range requests in the first place
            Range: "bytes=0-"
          },
          signal: abortController.signal
        }),
        this._getRetryDelay,
        () => this._disposed
      );
      if (!response.ok) {
        throw new Error(`Error fetching ${String(this._url)}: ${response.status} ${response.statusText}`);
      }
      let worker;
      let fileSize;
      if (response.status === 206) {
        fileSize = this._getTotalLengthFromRangeResponse(response);
        worker = this._orchestrator.createWorker(0, Math.min(fileSize, URL_SOURCE_MIN_LOAD_AMOUNT));
      } else {
        const contentLength = response.headers.get("Content-Length");
        if (contentLength) {
          fileSize = Number(contentLength);
          worker = this._orchestrator.createWorker(0, fileSize);
          this._orchestrator.options.maxCacheSize = Infinity;
          console.warn(
            "HTTP server did not respond with 206 Partial Content, meaning the entire remote resource now has to be downloaded. For efficient media file streaming across a network, please make sure your server supports range requests."
          );
        } else {
          throw new Error(`HTTP response (status ${response.status}) must surface Content-Length header.`);
        }
      }
      this._orchestrator.fileSize = fileSize;
      this._existingResponses.set(worker, { response, abortController });
      this._orchestrator.runWorker(worker);
      return fileSize;
    }
    /** @internal */
    _read(start, end) {
      return this._orchestrator.read(start, end);
    }
    /** @internal */
    async _runWorker(worker) {
      while (true) {
        const existing = this._existingResponses.get(worker);
        this._existingResponses.delete(worker);
        let abortController = existing?.abortController;
        let response = existing?.response;
        if (!abortController) {
          abortController = new AbortController();
          response = await retriedFetch(
            this._options.fetchFn ?? fetch,
            this._url,
            mergeRequestInit(this._options.requestInit ?? {}, {
              headers: {
                Range: `bytes=${worker.currentPos}-`
              },
              signal: abortController.signal
            }),
            this._getRetryDelay,
            () => this._disposed
          );
        }
        assert(response);
        if (!response.ok) {
          throw new Error(`Error fetching ${String(this._url)}: ${response.status} ${response.statusText}`);
        }
        if (worker.currentPos > 0 && response.status !== 206) {
          throw new Error(
            "HTTP server did not respond with 206 Partial Content to a range request. To enable efficient media file streaming across a network, please make sure your server supports range requests."
          );
        }
        if (!response.body) {
          throw new Error(
            "Missing HTTP response body stream. The used fetch function must provide the response body as a ReadableStream."
          );
        }
        const reader = response.body.getReader();
        while (true) {
          if (worker.currentPos >= worker.targetPos || worker.aborted) {
            abortController.abort();
            worker.running = false;
            return;
          }
          let readResult;
          try {
            readResult = await reader.read();
          } catch (error) {
            if (this._disposed) {
              throw error;
            }
            const retryDelayInSeconds = this._getRetryDelay(1, error, this._url);
            if (retryDelayInSeconds !== null) {
              console.error("Error while reading response stream. Attempting to resume.", error);
              await new Promise((resolve) => setTimeout(resolve, 1e3 * retryDelayInSeconds));
              break;
            } else {
              throw error;
            }
          }
          if (worker.aborted) {
            continue;
          }
          const { done, value } = readResult;
          if (done) {
            if (worker.currentPos >= worker.targetPos) {
              this._orchestrator.forgetWorker(worker);
              worker.running = false;
              return;
            }
            break;
          }
          this.onread?.(worker.currentPos, worker.currentPos + value.length);
          this._orchestrator.supplyWorkerData(worker, value);
        }
      }
    }
    /** @internal */
    _getTotalLengthFromRangeResponse(response) {
      const contentRange = response.headers.get("Content-Range");
      if (contentRange) {
        const match = /\/(\d+)/.exec(contentRange);
        if (match) {
          return Number(match[1]);
        }
      }
      const contentLength = response.headers.get("Content-Length");
      if (contentLength) {
        return Number(contentLength);
      } else {
        throw new Error(
          "Partial HTTP response (status 206) must surface either Content-Range or Content-Length header."
        );
      }
    }
    /** @internal */
    _dispose() {
      this._orchestrator.dispose();
    }
  };
  var FilePathSource = class extends Source {
    /** Creates a new {@link FilePathSource} backed by the file at the specified file path. */
    constructor(filePath, options = {}) {
      if (typeof filePath !== "string") {
        throw new TypeError("filePath must be a string.");
      }
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (options.maxCacheSize !== void 0 && (!isNumber(options.maxCacheSize) || options.maxCacheSize < 0)) {
        throw new TypeError("options.maxCacheSize, when provided, must be a non-negative number.");
      }
      super();
      /** @internal */
      this._fileHandle = null;
      this._streamSource = new StreamSource({
        getSize: async () => {
          this._fileHandle = await node.fs.open(filePath, "r");
          const stats = await this._fileHandle.stat();
          return stats.size;
        },
        read: async (start, end) => {
          assert(this._fileHandle);
          const buffer = new Uint8Array(end - start);
          await this._fileHandle.read(buffer, 0, end - start, start);
          return buffer;
        },
        maxCacheSize: options.maxCacheSize,
        prefetchProfile: "fileSystem"
      });
    }
    /** @internal */
    _read(start, end) {
      return this._streamSource._read(start, end);
    }
    /** @internal */
    _retrieveSize() {
      return this._streamSource._retrieveSize();
    }
    /** @internal */
    _dispose() {
      this._streamSource._dispose();
      void this._fileHandle?.close();
      this._fileHandle = null;
    }
  };
  var StreamSource = class extends Source {
    /** Creates a new {@link StreamSource} whose behavior is specified by `options`.  */
    constructor(options) {
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (typeof options.getSize !== "function") {
        throw new TypeError("options.getSize must be a function.");
      }
      if (typeof options.read !== "function") {
        throw new TypeError("options.read must be a function.");
      }
      if (options.dispose !== void 0 && typeof options.dispose !== "function") {
        throw new TypeError("options.dispose, when provided, must be a function.");
      }
      if (options.maxCacheSize !== void 0 && (!isNumber(options.maxCacheSize) || options.maxCacheSize < 0)) {
        throw new TypeError("options.maxCacheSize, when provided, must be a non-negative number.");
      }
      if (options.prefetchProfile && !["none", "fileSystem", "network"].includes(options.prefetchProfile)) {
        throw new TypeError(
          "options.prefetchProfile, when provided, must be one of 'none', 'fileSystem' or 'network'."
        );
      }
      super();
      this._options = options;
      this._orchestrator = new ReadOrchestrator({
        maxCacheSize: options.maxCacheSize ?? 8 * 2 ** 20,
        maxWorkerCount: 2,
        // Fixed for now, *should* be fine
        prefetchProfile: PREFETCH_PROFILES[options.prefetchProfile ?? "none"],
        runWorker: this._runWorker.bind(this)
      });
    }
    /** @internal */
    _retrieveSize() {
      const result = this._options.getSize();
      if (result instanceof Promise) {
        return result.then((size) => {
          if (!Number.isInteger(size) || size < 0) {
            throw new TypeError("options.getSize must return or resolve to a non-negative integer.");
          }
          this._orchestrator.fileSize = size;
          return size;
        });
      } else {
        if (!Number.isInteger(result) || result < 0) {
          throw new TypeError("options.getSize must return or resolve to a non-negative integer.");
        }
        this._orchestrator.fileSize = result;
        return result;
      }
    }
    /** @internal */
    _read(start, end) {
      return this._orchestrator.read(start, end);
    }
    /** @internal */
    async _runWorker(worker) {
      while (worker.currentPos < worker.targetPos && !worker.aborted) {
        const originalCurrentPos = worker.currentPos;
        const originalTargetPos = worker.targetPos;
        let data = this._options.read(worker.currentPos, originalTargetPos);
        if (data instanceof Promise) data = await data;
        if (worker.aborted) {
          break;
        }
        if (data instanceof Uint8Array) {
          data = toUint8Array(data);
          if (data.length !== originalTargetPos - worker.currentPos) {
            throw new Error(
              `options.read returned a Uint8Array with unexpected length: Requested ${originalTargetPos - worker.currentPos} bytes, but got ${data.length}.`
            );
          }
          this.onread?.(worker.currentPos, worker.currentPos + data.length);
          this._orchestrator.supplyWorkerData(worker, data);
        } else if (data instanceof ReadableStream) {
          const reader = data.getReader();
          while (worker.currentPos < originalTargetPos && !worker.aborted) {
            const { done, value } = await reader.read();
            if (done) {
              if (worker.currentPos < originalTargetPos) {
                throw new Error(
                  `ReadableStream returned by options.read ended before supplying enough data. Requested ${originalTargetPos - originalCurrentPos} bytes, but got ${worker.currentPos - originalCurrentPos}`
                );
              }
              break;
            }
            if (!(value instanceof Uint8Array)) {
              throw new TypeError("ReadableStream returned by options.read must yield Uint8Array chunks.");
            }
            if (worker.aborted) {
              break;
            }
            const data2 = toUint8Array(value);
            this.onread?.(worker.currentPos, worker.currentPos + data2.length);
            this._orchestrator.supplyWorkerData(worker, data2);
          }
        } else {
          throw new TypeError("options.read must return or resolve to a Uint8Array or a ReadableStream.");
        }
      }
      worker.running = false;
    }
    /** @internal */
    _dispose() {
      this._orchestrator.dispose();
      this._options.dispose?.();
    }
  };
  var ReadableStreamSource = class extends Source {
    /** Creates a new {@link ReadableStreamSource} backed by the specified `ReadableStream<Uint8Array>`. */
    constructor(stream, options = {}) {
      if (!(stream instanceof ReadableStream)) {
        throw new TypeError("stream must be a ReadableStream.");
      }
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (options.maxCacheSize !== void 0 && (!isNumber(options.maxCacheSize) || options.maxCacheSize < 0)) {
        throw new TypeError("options.maxCacheSize, when provided, must be a non-negative number.");
      }
      super();
      /** @internal */
      this._reader = null;
      /** @internal */
      this._cache = [];
      /** @internal */
      this._pendingSlices = [];
      /** @internal */
      this._currentIndex = 0;
      /** @internal */
      this._targetIndex = 0;
      /** @internal */
      this._maxRequestedIndex = 0;
      /** @internal */
      this._endIndex = null;
      /** @internal */
      this._pulling = false;
      this._stream = stream;
      this._maxCacheSize = options.maxCacheSize ?? 16 * 2 ** 20;
    }
    /** @internal */
    _retrieveSize() {
      return this._endIndex;
    }
    /** @internal */
    _read(start, end) {
      if (this._endIndex !== null && end > this._endIndex) {
        return null;
      }
      this._maxRequestedIndex = Math.max(this._maxRequestedIndex, end);
      const cacheStartIndex = binarySearchLessOrEqual(this._cache, start, (x) => x.start);
      const cacheStartEntry = cacheStartIndex !== -1 ? this._cache[cacheStartIndex] : null;
      if (cacheStartEntry && cacheStartEntry.start <= start && end <= cacheStartEntry.end) {
        return {
          bytes: cacheStartEntry.bytes,
          view: cacheStartEntry.view,
          offset: cacheStartEntry.start
        };
      }
      let lastEnd = start;
      const bytes2 = new Uint8Array(end - start);
      if (cacheStartIndex !== -1) {
        for (let i = cacheStartIndex; i < this._cache.length; i++) {
          const cacheEntry = this._cache[i];
          if (cacheEntry.start >= end) {
            break;
          }
          const cappedStart = Math.max(start, cacheEntry.start);
          if (cappedStart > lastEnd) {
            this._throwDueToCacheMiss();
          }
          const cappedEnd = Math.min(end, cacheEntry.end);
          if (cappedStart < cappedEnd) {
            bytes2.set(
              cacheEntry.bytes.subarray(cappedStart - cacheEntry.start, cappedEnd - cacheEntry.start),
              cappedStart - start
            );
            lastEnd = cappedEnd;
          }
        }
      }
      if (lastEnd === end) {
        return {
          bytes: bytes2,
          view: toDataView(bytes2),
          offset: start
        };
      }
      if (this._currentIndex > lastEnd) {
        this._throwDueToCacheMiss();
      }
      const { promise, resolve, reject } = promiseWithResolvers();
      this._pendingSlices.push({
        start,
        end,
        bytes: bytes2,
        resolve,
        reject
      });
      this._targetIndex = Math.max(this._targetIndex, end);
      if (!this._pulling) {
        this._pulling = true;
        void this._pull().catch((error) => {
          this._pulling = false;
          if (this._pendingSlices.length > 0) {
            this._pendingSlices.forEach((x) => x.reject(error));
            this._pendingSlices.length = 0;
          } else {
            throw error;
          }
        });
      }
      return promise;
    }
    /** @internal */
    _throwDueToCacheMiss() {
      throw new Error(
        "Read is before the cached region. With ReadableStreamSource, you must access the data more sequentially or increase the size of its cache."
      );
    }
    /** @internal */
    async _pull() {
      this._reader ??= this._stream.getReader();
      while (this._currentIndex < this._targetIndex && !this._disposed) {
        const { done, value } = await this._reader.read();
        if (done) {
          for (const pendingSlice of this._pendingSlices) {
            pendingSlice.resolve(null);
          }
          this._pendingSlices.length = 0;
          this._endIndex = this._currentIndex;
          break;
        }
        const startIndex = this._currentIndex;
        const endIndex = this._currentIndex + value.byteLength;
        for (let i = 0; i < this._pendingSlices.length; i++) {
          const pendingSlice = this._pendingSlices[i];
          const cappedStart = Math.max(startIndex, pendingSlice.start);
          const cappedEnd = Math.min(endIndex, pendingSlice.end);
          if (cappedStart < cappedEnd) {
            pendingSlice.bytes.set(
              value.subarray(cappedStart - startIndex, cappedEnd - startIndex),
              cappedStart - pendingSlice.start
            );
            if (cappedEnd === pendingSlice.end) {
              pendingSlice.resolve({
                bytes: pendingSlice.bytes,
                view: toDataView(pendingSlice.bytes),
                offset: pendingSlice.start
              });
              this._pendingSlices.splice(i, 1);
              i--;
            }
          }
        }
        this._cache.push({
          start: startIndex,
          end: endIndex,
          bytes: value,
          view: toDataView(value),
          age: 0
          // Unused
        });
        while (this._cache.length > 0) {
          const firstEntry = this._cache[0];
          const distance = this._maxRequestedIndex - firstEntry.end;
          if (distance <= this._maxCacheSize) {
            break;
          }
          this._cache.shift();
        }
        this._currentIndex += value.byteLength;
      }
      this._pulling = false;
    }
    /** @internal */
    _dispose() {
      this._pendingSlices.length = 0;
      this._cache.length = 0;
    }
  };
  var PREFETCH_PROFILES = {
    none: (start, end) => ({ start, end }),
    fileSystem: (start, end) => {
      const padding = 2 ** 16;
      start = Math.floor((start - padding) / padding) * padding;
      end = Math.ceil((end + padding) / padding) * padding;
      return { start, end };
    },
    network: (start, end, workers) => {
      const paddingStart = 2 ** 16;
      start = Math.max(0, Math.floor((start - paddingStart) / paddingStart) * paddingStart);
      for (const worker of workers) {
        const maxExtensionAmount = 8 * 2 ** 20;
        const thresholdPoint = Math.max(
          (worker.startPos + worker.targetPos) / 2,
          worker.targetPos - maxExtensionAmount
        );
        if (closedIntervalsOverlap(
          start,
          end,
          thresholdPoint,
          worker.targetPos
        )) {
          const size = worker.targetPos - worker.startPos;
          const a = Math.ceil((size + 1) / maxExtensionAmount) * maxExtensionAmount;
          const b = 2 ** Math.ceil(Math.log2(size + 1));
          const extent = Math.min(b, a);
          end = Math.max(end, worker.startPos + extent);
        }
      }
      end = Math.max(end, start + URL_SOURCE_MIN_LOAD_AMOUNT);
      return {
        start,
        end
      };
    }
  };
  var ReadOrchestrator = class {
    constructor(options) {
      this.options = options;
      this.fileSize = null;
      this.nextAge = 0;
      // Used for LRU eviction of both cache entries and workers
      this.workers = [];
      this.cache = [];
      this.currentCacheSize = 0;
      this.disposed = false;
    }
    read(innerStart, innerEnd) {
      assert(this.fileSize !== null);
      const prefetchRange = this.options.prefetchProfile(innerStart, innerEnd, this.workers);
      const outerStart = Math.max(prefetchRange.start, 0);
      const outerEnd = Math.min(prefetchRange.end, this.fileSize);
      assert(outerStart <= innerStart && innerEnd <= outerEnd);
      let result = null;
      const innerCacheStartIndex = binarySearchLessOrEqual(this.cache, innerStart, (x) => x.start);
      const innerStartEntry = innerCacheStartIndex !== -1 ? this.cache[innerCacheStartIndex] : null;
      if (innerStartEntry && innerStartEntry.start <= innerStart && innerEnd <= innerStartEntry.end) {
        innerStartEntry.age = this.nextAge++;
        result = {
          bytes: innerStartEntry.bytes,
          view: innerStartEntry.view,
          offset: innerStartEntry.start
        };
      }
      const outerCacheStartIndex = binarySearchLessOrEqual(this.cache, outerStart, (x) => x.start);
      const bytes2 = result ? null : new Uint8Array(innerEnd - innerStart);
      let contiguousBytesWriteEnd = 0;
      let lastEnd = outerStart;
      const outerHoles = [];
      if (outerCacheStartIndex !== -1) {
        for (let i = outerCacheStartIndex; i < this.cache.length; i++) {
          const entry = this.cache[i];
          if (entry.start >= outerEnd) {
            break;
          }
          if (entry.end <= outerStart) {
            continue;
          }
          const cappedOuterStart = Math.max(outerStart, entry.start);
          const cappedOuterEnd = Math.min(outerEnd, entry.end);
          assert(cappedOuterStart <= cappedOuterEnd);
          if (lastEnd < cappedOuterStart) {
            outerHoles.push({ start: lastEnd, end: cappedOuterStart });
          }
          lastEnd = cappedOuterEnd;
          if (bytes2) {
            const cappedInnerStart = Math.max(innerStart, entry.start);
            const cappedInnerEnd = Math.min(innerEnd, entry.end);
            if (cappedInnerStart < cappedInnerEnd) {
              const relativeOffset = cappedInnerStart - innerStart;
              bytes2.set(
                entry.bytes.subarray(cappedInnerStart - entry.start, cappedInnerEnd - entry.start),
                relativeOffset
              );
              if (relativeOffset === contiguousBytesWriteEnd) {
                contiguousBytesWriteEnd = cappedInnerEnd - innerStart;
              }
            }
          }
          entry.age = this.nextAge++;
        }
        if (lastEnd < outerEnd) {
          outerHoles.push({ start: lastEnd, end: outerEnd });
        }
      } else {
        outerHoles.push({ start: outerStart, end: outerEnd });
      }
      if (bytes2 && contiguousBytesWriteEnd >= bytes2.length) {
        result = {
          bytes: bytes2,
          view: toDataView(bytes2),
          offset: innerStart
        };
      }
      if (outerHoles.length === 0) {
        assert(result);
        return result;
      }
      const { promise, resolve, reject } = promiseWithResolvers();
      const innerHoles = [];
      for (const outerHole of outerHoles) {
        const cappedStart = Math.max(innerStart, outerHole.start);
        const cappedEnd = Math.min(innerEnd, outerHole.end);
        if (cappedStart === outerHole.start && cappedEnd === outerHole.end) {
          innerHoles.push(outerHole);
        } else if (cappedStart < cappedEnd) {
          innerHoles.push({ start: cappedStart, end: cappedEnd });
        }
      }
      for (const outerHole of outerHoles) {
        const pendingSlice = bytes2 && {
          start: innerStart,
          bytes: bytes2,
          holes: innerHoles,
          resolve,
          reject
        };
        let workerFound = false;
        for (const worker of this.workers) {
          const gapTolerance = 2 ** 17;
          if (closedIntervalsOverlap(
            outerHole.start - gapTolerance,
            outerHole.start,
            worker.currentPos,
            worker.targetPos
          )) {
            worker.targetPos = Math.max(worker.targetPos, outerHole.end);
            workerFound = true;
            if (pendingSlice && !worker.pendingSlices.includes(pendingSlice)) {
              worker.pendingSlices.push(pendingSlice);
            }
            if (!worker.running) {
              this.runWorker(worker);
            }
            break;
          }
        }
        if (!workerFound) {
          const newWorker = this.createWorker(outerHole.start, outerHole.end);
          if (pendingSlice) {
            newWorker.pendingSlices = [pendingSlice];
          }
          this.runWorker(newWorker);
        }
      }
      if (!result) {
        assert(bytes2);
        result = promise.then((bytes3) => ({
          bytes: bytes3,
          view: toDataView(bytes3),
          offset: innerStart
        }));
      } else {
      }
      return result;
    }
    createWorker(startPos, targetPos) {
      const worker = {
        startPos,
        currentPos: startPos,
        targetPos,
        running: false,
        // Due to async shenanigans, it can happen that workers are started after disposal. In this case, instead of
        // simply not creating the worker, we allow it to run but immediately label it as aborted, so it can then
        // shut itself down.
        aborted: this.disposed,
        pendingSlices: [],
        age: this.nextAge++
      };
      this.workers.push(worker);
      while (this.workers.length > this.options.maxWorkerCount) {
        let oldestIndex = 0;
        let oldestWorker = this.workers[0];
        for (let i = 1; i < this.workers.length; i++) {
          const worker2 = this.workers[i];
          if (worker2.age < oldestWorker.age) {
            oldestIndex = i;
            oldestWorker = worker2;
          }
        }
        if (oldestWorker.running && oldestWorker.pendingSlices.length > 0) {
          break;
        }
        oldestWorker.aborted = true;
        this.workers.splice(oldestIndex, 1);
      }
      return worker;
    }
    runWorker(worker) {
      assert(!worker.running);
      assert(worker.currentPos < worker.targetPos);
      worker.running = true;
      worker.age = this.nextAge++;
      void this.options.runWorker(worker).catch((error) => {
        worker.running = false;
        if (worker.pendingSlices.length > 0) {
          worker.pendingSlices.forEach((x) => x.reject(error));
          worker.pendingSlices.length = 0;
        } else {
          throw error;
        }
      });
    }
    /** Called by a worker when it has read some data. */
    supplyWorkerData(worker, bytes2) {
      assert(!worker.aborted);
      const start = worker.currentPos;
      const end = start + bytes2.length;
      this.insertIntoCache({
        start,
        end,
        bytes: bytes2,
        view: toDataView(bytes2),
        age: this.nextAge++
      });
      worker.currentPos += bytes2.length;
      worker.targetPos = Math.max(worker.targetPos, worker.currentPos);
      for (let i = 0; i < worker.pendingSlices.length; i++) {
        const pendingSlice = worker.pendingSlices[i];
        const clampedStart = Math.max(start, pendingSlice.start);
        const clampedEnd = Math.min(end, pendingSlice.start + pendingSlice.bytes.length);
        if (clampedStart < clampedEnd) {
          pendingSlice.bytes.set(
            bytes2.subarray(clampedStart - start, clampedEnd - start),
            clampedStart - pendingSlice.start
          );
        }
        for (let j = 0; j < pendingSlice.holes.length; j++) {
          const hole = pendingSlice.holes[j];
          if (start <= hole.start && end > hole.start) {
            hole.start = end;
          }
          if (hole.end <= hole.start) {
            pendingSlice.holes.splice(j, 1);
            j--;
          }
        }
        if (pendingSlice.holes.length === 0) {
          pendingSlice.resolve(pendingSlice.bytes);
          worker.pendingSlices.splice(i, 1);
          i--;
        }
      }
      for (let i = 0; i < this.workers.length; i++) {
        const otherWorker = this.workers[i];
        if (worker === otherWorker || otherWorker.running) {
          continue;
        }
        if (closedIntervalsOverlap(
          start,
          end,
          otherWorker.currentPos,
          otherWorker.targetPos
          // These should typically be equal when the worker's idle
        )) {
          this.workers.splice(i, 1);
          i--;
        }
      }
    }
    forgetWorker(worker) {
      const index = this.workers.indexOf(worker);
      assert(index !== -1);
      this.workers.splice(index, 1);
    }
    insertIntoCache(entry) {
      if (this.options.maxCacheSize === 0) {
        return;
      }
      let insertionIndex = binarySearchLessOrEqual(this.cache, entry.start, (x) => x.start) + 1;
      if (insertionIndex > 0) {
        const previous = this.cache[insertionIndex - 1];
        if (previous.end >= entry.end) {
          return;
        }
        if (previous.end > entry.start) {
          const joined = new Uint8Array(entry.end - previous.start);
          joined.set(previous.bytes, 0);
          joined.set(entry.bytes, entry.start - previous.start);
          this.currentCacheSize += entry.end - previous.end;
          previous.bytes = joined;
          previous.view = toDataView(joined);
          previous.end = entry.end;
          insertionIndex--;
          entry = previous;
        } else {
          this.cache.splice(insertionIndex, 0, entry);
          this.currentCacheSize += entry.bytes.length;
        }
      } else {
        this.cache.splice(insertionIndex, 0, entry);
        this.currentCacheSize += entry.bytes.length;
      }
      for (let i = insertionIndex + 1; i < this.cache.length; i++) {
        const next = this.cache[i];
        if (entry.end <= next.start) {
          break;
        }
        if (entry.end >= next.end) {
          this.cache.splice(i, 1);
          this.currentCacheSize -= next.bytes.length;
          i--;
          continue;
        }
        const joined = new Uint8Array(next.end - entry.start);
        joined.set(entry.bytes, 0);
        joined.set(next.bytes, next.start - entry.start);
        this.currentCacheSize -= entry.end - next.start;
        entry.bytes = joined;
        entry.view = toDataView(joined);
        entry.end = next.end;
        this.cache.splice(i, 1);
        break;
      }
      while (this.currentCacheSize > this.options.maxCacheSize) {
        let oldestIndex = 0;
        let oldestEntry = this.cache[0];
        for (let i = 1; i < this.cache.length; i++) {
          const entry2 = this.cache[i];
          if (entry2.age < oldestEntry.age) {
            oldestIndex = i;
            oldestEntry = entry2;
          }
        }
        if (this.currentCacheSize - oldestEntry.bytes.length <= this.options.maxCacheSize) {
          break;
        }
        this.cache.splice(oldestIndex, 1);
        this.currentCacheSize -= oldestEntry.bytes.length;
      }
    }
    dispose() {
      for (const worker of this.workers) {
        worker.aborted = true;
      }
      this.workers.length = 0;
      this.cache.length = 0;
      this.disposed = true;
    }
  };

  // src/input.ts
  polyfillSymbolDispose();
  var Input = class {
    /**
     * Creates a new input file from the specified options. No reading operations will be performed until methods are
     * called on this instance.
     */
    constructor(options) {
      /** @internal */
      this._demuxerPromise = null;
      /** @internal */
      this._format = null;
      /** @internal */
      this._disposed = false;
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (!Array.isArray(options.formats) || options.formats.some((x) => !(x instanceof InputFormat))) {
        throw new TypeError("options.formats must be an array of InputFormat.");
      }
      if (!(options.source instanceof Source)) {
        throw new TypeError("options.source must be a Source.");
      }
      if (options.source._disposed) {
        throw new Error("options.source must not be disposed.");
      }
      this._formats = options.formats;
      this._source = options.source;
      this._reader = new Reader11(options.source);
    }
    /** True if the input has been disposed. */
    get disposed() {
      return this._disposed;
    }
    /** @internal */
    _getDemuxer() {
      return this._demuxerPromise ??= (async () => {
        this._reader.fileSize = await this._source.getSizeOrNull();
        for (const format of this._formats) {
          const canRead = await format._canReadInput(this);
          if (canRead) {
            this._format = format;
            return format._createDemuxer(this);
          }
        }
        throw new Error("Input has an unsupported or unrecognizable format.");
      })();
    }
    /**
     * Returns the source from which this input file reads its data. This is the same source that was passed to the
     * constructor.
     */
    get source() {
      return this._source;
    }
    /**
     * Returns the format of the input file. You can compare this result directly to the {@link InputFormat} singletons
     * or use `instanceof` checks for subset-aware logic (for example, `format instanceof MatroskaInputFormat` is true
     * for both MKV and WebM).
     */
    async getFormat() {
      await this._getDemuxer();
      assert(this._format);
      return this._format;
    }
    /**
     * Computes the duration of the input file, in seconds. More precisely, returns the largest end timestamp among
     * all tracks.
     */
    async computeDuration() {
      const demuxer = await this._getDemuxer();
      return demuxer.computeDuration();
    }
    /**
     * Returns the timestamp at which the input file starts. More precisely, returns the smallest starting timestamp
     * among all tracks.
     */
    async getFirstTimestamp() {
      const tracks = await this.getTracks();
      if (tracks.length === 0) {
        return 0;
      }
      const firstTimestamps = await Promise.all(tracks.map((x) => x.getFirstTimestamp()));
      return Math.min(...firstTimestamps);
    }
    /** Returns the list of all tracks of this input file. */
    async getTracks() {
      const demuxer = await this._getDemuxer();
      return demuxer.getTracks();
    }
    /** Returns the list of all video tracks of this input file. */
    async getVideoTracks() {
      const tracks = await this.getTracks();
      return tracks.filter((x) => x.isVideoTrack());
    }
    /** Returns the list of all audio tracks of this input file. */
    async getAudioTracks() {
      const tracks = await this.getTracks();
      return tracks.filter((x) => x.isAudioTrack());
    }
    /** Returns the primary video track of this input file, or null if there are no video tracks. */
    async getPrimaryVideoTrack() {
      const tracks = await this.getTracks();
      return tracks.find((x) => x.isVideoTrack()) ?? null;
    }
    /** Returns the primary audio track of this input file, or null if there are no audio tracks. */
    async getPrimaryAudioTrack() {
      const tracks = await this.getTracks();
      return tracks.find((x) => x.isAudioTrack()) ?? null;
    }
    /** Returns the full MIME type of this input file, including track codecs. */
    async getMimeType() {
      const demuxer = await this._getDemuxer();
      return demuxer.getMimeType();
    }
    /**
     * Returns descriptive metadata tags about the media file, such as title, author, date, cover art, or other
     * attached files.
     */
    async getMetadataTags() {
      const demuxer = await this._getDemuxer();
      return demuxer.getMetadataTags();
    }
    /**
     * Disposes this input and frees connected resources. When an input is disposed, ongoing read operations will be
     * canceled, all future read operations will fail, any open decoders will be closed, and all ongoing media sink
     * operations will be canceled. Disallowed and canceled operations will throw an {@link InputDisposedError}.
     *
     * You are expected not to use an input after disposing it. While some operations may still work, it is not
     * specified and may change in any future update.
     */
    dispose() {
      if (this._disposed) {
        return;
      }
      this._disposed = true;
      this._source._disposed = true;
      this._source._dispose();
    }
    /**
     * Calls `.dispose()` on the input, implementing the `Disposable` interface for use with
     * JavaScript Explicit Resource Management features.
     */
    [Symbol.dispose]() {
      this.dispose();
    }
  };
  var InputDisposedError = class extends Error {
    /** Creates a new {@link InputDisposedError}. */
    constructor(message = "Input has been disposed.") {
      super(message);
      this.name = "InputDisposedError";
    }
  };

  // src/reader.ts
  var Reader11 = class {
    constructor(source) {
      this.source = source;
    }
    requestSlice(start, length) {
      if (this.source._disposed) {
        throw new InputDisposedError();
      }
      if (start < 0) {
        return null;
      }
      if (this.fileSize !== null && start + length > this.fileSize) {
        return null;
      }
      const end = start + length;
      const result = this.source._read(start, end);
      if (result instanceof Promise) {
        return result.then((x) => {
          if (!x) {
            return null;
          }
          return new FileSlice4(x.bytes, x.view, x.offset, start, end);
        });
      } else {
        if (!result) {
          return null;
        }
        return new FileSlice4(result.bytes, result.view, result.offset, start, end);
      }
    }
    requestSliceRange(start, minLength, maxLength) {
      if (this.source._disposed) {
        throw new InputDisposedError();
      }
      if (start < 0) {
        return null;
      }
      if (this.fileSize !== null) {
        return this.requestSlice(
          start,
          clamp(this.fileSize - start, minLength, maxLength)
        );
      } else {
        const promisedAttempt = this.requestSlice(start, maxLength);
        const handleAttempt = (attempt) => {
          if (attempt) {
            return attempt;
          }
          const handleFileSize = (fileSize) => {
            assert(fileSize !== null);
            return this.requestSlice(
              start,
              clamp(fileSize - start, minLength, maxLength)
            );
          };
          const promisedFileSize = this.source._retrieveSize();
          if (promisedFileSize instanceof Promise) {
            return promisedFileSize.then(handleFileSize);
          } else {
            return handleFileSize(promisedFileSize);
          }
        };
        if (promisedAttempt instanceof Promise) {
          return promisedAttempt.then(handleAttempt);
        } else {
          return handleAttempt(promisedAttempt);
        }
      }
    }
  };
  var FileSlice4 = class _FileSlice {
    constructor(bytes2, view2, offset, start, end) {
      this.bytes = bytes2;
      this.view = view2;
      this.offset = offset;
      this.start = start;
      this.end = end;
      this.bufferPos = start - offset;
    }
    static tempFromBytes(bytes2) {
      return new _FileSlice(
        bytes2,
        toDataView(bytes2),
        0,
        0,
        bytes2.length
      );
    }
    get length() {
      return this.end - this.start;
    }
    get filePos() {
      return this.offset + this.bufferPos;
    }
    set filePos(value) {
      this.bufferPos = value - this.offset;
    }
    /** The number of bytes left from the current pos to the end of the slice. */
    get remainingLength() {
      return Math.max(this.end - this.filePos, 0);
    }
    skip(byteCount) {
      this.bufferPos += byteCount;
    }
    /** Creates a new subslice of this slice whose byte range must be contained within this slice. */
    slice(filePos, length = this.end - filePos) {
      if (filePos < this.start || filePos + length > this.end) {
        throw new RangeError("Slicing outside of original slice.");
      }
      return new _FileSlice(
        this.bytes,
        this.view,
        this.offset,
        filePos,
        filePos + length
      );
    }
  };
  var checkIsInRange = (slice, bytesToRead) => {
    if (slice.filePos < slice.start || slice.filePos + bytesToRead > slice.end) {
      throw new RangeError(
        `Tried reading [${slice.filePos}, ${slice.filePos + bytesToRead}), but slice is [${slice.start}, ${slice.end}). This is likely an internal error, please report it alongside the file that caused it.`
      );
    }
  };
  var readBytes = (slice, length) => {
    checkIsInRange(slice, length);
    const bytes2 = slice.bytes.subarray(slice.bufferPos, slice.bufferPos + length);
    slice.bufferPos += length;
    return bytes2;
  };
  var readU8 = (slice) => {
    checkIsInRange(slice, 1);
    return slice.view.getUint8(slice.bufferPos++);
  };
  var readU16 = (slice, littleEndian) => {
    checkIsInRange(slice, 2);
    const value = slice.view.getUint16(slice.bufferPos, littleEndian);
    slice.bufferPos += 2;
    return value;
  };
  var readU16Be = (slice) => {
    checkIsInRange(slice, 2);
    const value = slice.view.getUint16(slice.bufferPos, false);
    slice.bufferPos += 2;
    return value;
  };
  var readU24Be = (slice) => {
    checkIsInRange(slice, 3);
    const value = getUint24(slice.view, slice.bufferPos, false);
    slice.bufferPos += 3;
    return value;
  };
  var readI16Be = (slice) => {
    checkIsInRange(slice, 2);
    const value = slice.view.getInt16(slice.bufferPos, false);
    slice.bufferPos += 2;
    return value;
  };
  var readU32 = (slice, littleEndian) => {
    checkIsInRange(slice, 4);
    const value = slice.view.getUint32(slice.bufferPos, littleEndian);
    slice.bufferPos += 4;
    return value;
  };
  var readU32Be = (slice) => {
    checkIsInRange(slice, 4);
    const value = slice.view.getUint32(slice.bufferPos, false);
    slice.bufferPos += 4;
    return value;
  };
  var readU32Le = (slice) => {
    checkIsInRange(slice, 4);
    const value = slice.view.getUint32(slice.bufferPos, true);
    slice.bufferPos += 4;
    return value;
  };
  var readI32Be = (slice) => {
    checkIsInRange(slice, 4);
    const value = slice.view.getInt32(slice.bufferPos, false);
    slice.bufferPos += 4;
    return value;
  };
  var readI32Le = (slice) => {
    checkIsInRange(slice, 4);
    const value = slice.view.getInt32(slice.bufferPos, true);
    slice.bufferPos += 4;
    return value;
  };
  var readU64 = (slice, littleEndian) => {
    let low;
    let high;
    if (littleEndian) {
      low = readU32(slice, true);
      high = readU32(slice, true);
    } else {
      high = readU32(slice, false);
      low = readU32(slice, false);
    }
    return high * 4294967296 + low;
  };
  var readU64Be = (slice) => {
    const high = readU32Be(slice);
    const low = readU32Be(slice);
    return high * 4294967296 + low;
  };
  var readI64Be = (slice) => {
    const high = readI32Be(slice);
    const low = readU32Be(slice);
    return high * 4294967296 + low;
  };
  var readI64Le = (slice) => {
    const low = readU32Le(slice);
    const high = readI32Le(slice);
    return high * 4294967296 + low;
  };
  var readF32Be = (slice) => {
    checkIsInRange(slice, 4);
    const value = slice.view.getFloat32(slice.bufferPos, false);
    slice.bufferPos += 4;
    return value;
  };
  var readF64Be = (slice) => {
    checkIsInRange(slice, 8);
    const value = slice.view.getFloat64(slice.bufferPos, false);
    slice.bufferPos += 8;
    return value;
  };
  var readAscii = (slice, length) => {
    checkIsInRange(slice, length);
    let str = "";
    for (let i = 0; i < length; i++) {
      str += String.fromCharCode(slice.bytes[slice.bufferPos++]);
    }
    return str;
  };

  // src/id3.ts
  var ID3_V1_TAG_SIZE = 128;
  var ID3_V2_HEADER_SIZE = 10;
  var ID3_V1_GENRES = [
    "Blues",
    "Classic rock",
    "Country",
    "Dance",
    "Disco",
    "Funk",
    "Grunge",
    "Hip-hop",
    "Jazz",
    "Metal",
    "New age",
    "Oldies",
    "Other",
    "Pop",
    "Rhythm and blues",
    "Rap",
    "Reggae",
    "Rock",
    "Techno",
    "Industrial",
    "Alternative",
    "Ska",
    "Death metal",
    "Pranks",
    "Soundtrack",
    "Euro-techno",
    "Ambient",
    "Trip-hop",
    "Vocal",
    "Jazz & funk",
    "Fusion",
    "Trance",
    "Classical",
    "Instrumental",
    "Acid",
    "House",
    "Game",
    "Sound clip",
    "Gospel",
    "Noise",
    "Alternative rock",
    "Bass",
    "Soul",
    "Punk",
    "Space",
    "Meditative",
    "Instrumental pop",
    "Instrumental rock",
    "Ethnic",
    "Gothic",
    "Darkwave",
    "Techno-industrial",
    "Electronic",
    "Pop-folk",
    "Eurodance",
    "Dream",
    "Southern rock",
    "Comedy",
    "Cult",
    "Gangsta",
    "Top 40",
    "Christian rap",
    "Pop/funk",
    "Jungle music",
    "Native US",
    "Cabaret",
    "New wave",
    "Psychedelic",
    "Rave",
    "Showtunes",
    "Trailer",
    "Lo-fi",
    "Tribal",
    "Acid punk",
    "Acid jazz",
    "Polka",
    "Retro",
    "Musical",
    "Rock 'n' roll",
    "Hard rock",
    "Folk",
    "Folk rock",
    "National folk",
    "Swing",
    "Fast fusion",
    "Bebop",
    "Latin",
    "Revival",
    "Celtic",
    "Bluegrass",
    "Avantgarde",
    "Gothic rock",
    "Progressive rock",
    "Psychedelic rock",
    "Symphonic rock",
    "Slow rock",
    "Big band",
    "Chorus",
    "Easy listening",
    "Acoustic",
    "Humour",
    "Speech",
    "Chanson",
    "Opera",
    "Chamber music",
    "Sonata",
    "Symphony",
    "Booty bass",
    "Primus",
    "Porn groove",
    "Satire",
    "Slow jam",
    "Club",
    "Tango",
    "Samba",
    "Folklore",
    "Ballad",
    "Power ballad",
    "Rhythmic Soul",
    "Freestyle",
    "Duet",
    "Punk rock",
    "Drum solo",
    "A cappella",
    "Euro-house",
    "Dance hall",
    "Goa music",
    "Drum & bass",
    "Club-house",
    "Hardcore techno",
    "Terror",
    "Indie",
    "Britpop",
    "Negerpunk",
    "Polsk punk",
    "Beat",
    "Christian gangsta rap",
    "Heavy metal",
    "Black metal",
    "Crossover",
    "Contemporary Christian",
    "Christian rock",
    "Merengue",
    "Salsa",
    "Thrash metal",
    "Anime",
    "Jpop",
    "Synthpop",
    "Christmas",
    "Art rock",
    "Baroque",
    "Bhangra",
    "Big beat",
    "Breakbeat",
    "Chillout",
    "Downtempo",
    "Dub",
    "EBM",
    "Eclectic",
    "Electro",
    "Electroclash",
    "Emo",
    "Experimental",
    "Garage",
    "Global",
    "IDM",
    "Illbient",
    "Industro-Goth",
    "Jam Band",
    "Krautrock",
    "Leftfield",
    "Lounge",
    "Math rock",
    "New romantic",
    "Nu-breakz",
    "Post-punk",
    "Post-rock",
    "Psytrance",
    "Shoegaze",
    "Space rock",
    "Trop rock",
    "World music",
    "Neoclassical",
    "Audiobook",
    "Audio theatre",
    "Neue Deutsche Welle",
    "Podcast",
    "Indie rock",
    "G-Funk",
    "Dubstep",
    "Garage rock",
    "Psybient"
  ];
  var parseId3V1Tag = (slice, tags) => {
    const startPos = slice.filePos;
    tags.raw ??= {};
    tags.raw["TAG"] ??= readBytes(slice, ID3_V1_TAG_SIZE - 3);
    slice.filePos = startPos;
    const title = readId3V1String(slice, 30);
    if (title) tags.title ??= title;
    const artist = readId3V1String(slice, 30);
    if (artist) tags.artist ??= artist;
    const album = readId3V1String(slice, 30);
    if (album) tags.album ??= album;
    const yearText = readId3V1String(slice, 4);
    const year = Number.parseInt(yearText, 10);
    if (Number.isInteger(year) && year > 0) {
      tags.date ??= new Date(year, 0, 1);
    }
    const commentBytes = readBytes(slice, 30);
    let comment;
    if (commentBytes[28] === 0 && commentBytes[29] !== 0) {
      const trackNum = commentBytes[29];
      if (trackNum > 0) {
        tags.trackNumber ??= trackNum;
      }
      slice.skip(-30);
      comment = readId3V1String(slice, 28);
      slice.skip(2);
    } else {
      slice.skip(-30);
      comment = readId3V1String(slice, 30);
    }
    if (comment) tags.comment ??= comment;
    const genreIndex = readU8(slice);
    if (genreIndex < ID3_V1_GENRES.length) {
      tags.genre ??= ID3_V1_GENRES[genreIndex];
    }
  };
  var readId3V1String = (slice, length) => {
    const bytes2 = readBytes(slice, length);
    const endIndex = coalesceIndex(bytes2.indexOf(0), bytes2.length);
    const relevantBytes = bytes2.subarray(0, endIndex);
    let str = "";
    for (let i = 0; i < relevantBytes.length; i++) {
      str += String.fromCharCode(relevantBytes[i]);
    }
    return str.trimEnd();
  };
  var readId3V2Header = (slice) => {
    const startPos = slice.filePos;
    const tag = readAscii(slice, 3);
    const majorVersion = readU8(slice);
    const revision = readU8(slice);
    const flags = readU8(slice);
    const sizeRaw = readU32Be(slice);
    if (tag !== "ID3" || majorVersion === 255 || revision === 255 || (sizeRaw & 2155905152) !== 0) {
      slice.filePos = startPos;
      return null;
    }
    const size = decodeSynchsafe(sizeRaw);
    return { majorVersion, revision, flags, size };
  };
  var parseId3V2Tag = (slice, header, tags) => {
    if (![2, 3, 4].includes(header.majorVersion)) {
      console.warn(`Unsupported ID3v2 major version: ${header.majorVersion}`);
      return;
    }
    const bytes2 = readBytes(slice, header.size);
    const reader = new Id3V2Reader(header, bytes2);
    if (header.flags & 16 /* Footer */) {
      reader.removeFooter();
    }
    if (header.flags & 128 /* Unsynchronisation */ && header.majorVersion === 3) {
      reader.ununsynchronizeAll();
    }
    if (header.flags & 64 /* ExtendedHeader */) {
      const extendedHeaderSize = reader.readU32();
      if (header.majorVersion === 3) {
        reader.pos += extendedHeaderSize;
      } else {
        reader.pos += extendedHeaderSize - 4;
      }
    }
    while (reader.pos <= reader.bytes.length - reader.frameHeaderSize()) {
      const frame = reader.readId3V2Frame();
      if (!frame) {
        break;
      }
      const frameStartPos = reader.pos;
      const frameEndPos = reader.pos + frame.size;
      let frameEncrypted = false;
      let frameCompressed = false;
      let frameUnsynchronized = false;
      if (header.majorVersion === 3) {
        frameEncrypted = !!(frame.flags & 1 << 6);
        frameCompressed = !!(frame.flags & 1 << 7);
      } else if (header.majorVersion === 4) {
        frameEncrypted = !!(frame.flags & 1 << 2);
        frameCompressed = !!(frame.flags & 1 << 3);
        frameUnsynchronized = !!(frame.flags & 1 << 1) || !!(header.flags & 128 /* Unsynchronisation */);
      }
      if (frameEncrypted) {
        console.warn(`Skipping encrypted ID3v2 frame ${frame.id}`);
        reader.pos = frameEndPos;
        continue;
      }
      if (frameCompressed) {
        console.warn(`Skipping compressed ID3v2 frame ${frame.id}`);
        reader.pos = frameEndPos;
        continue;
      }
      if (frameUnsynchronized) {
        reader.ununsynchronizeRegion(reader.pos, frameEndPos);
      }
      tags.raw ??= {};
      if (frame.id[0] === "T") {
        tags.raw[frame.id] ??= reader.readId3V2EncodingAndText(frameEndPos);
      } else {
        tags.raw[frame.id] ??= reader.readBytes(frame.size);
      }
      reader.pos = frameStartPos;
      switch (frame.id) {
        case "TIT2":
        case "TT2":
          {
            tags.title ??= reader.readId3V2EncodingAndText(frameEndPos);
          }
          ;
          break;
        case "TIT3":
        case "TT3":
          {
            tags.description ??= reader.readId3V2EncodingAndText(frameEndPos);
          }
          ;
          break;
        case "TPE1":
        case "TP1":
          {
            tags.artist ??= reader.readId3V2EncodingAndText(frameEndPos);
          }
          ;
          break;
        case "TALB":
        case "TAL":
          {
            tags.album ??= reader.readId3V2EncodingAndText(frameEndPos);
          }
          ;
          break;
        case "TPE2":
        case "TP2":
          {
            tags.albumArtist ??= reader.readId3V2EncodingAndText(frameEndPos);
          }
          ;
          break;
        case "TRCK":
        case "TRK":
          {
            const trackText = reader.readId3V2EncodingAndText(frameEndPos);
            const parts = trackText.split("/");
            const trackNum = Number.parseInt(parts[0], 10);
            const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);
            if (Number.isInteger(trackNum) && trackNum > 0) {
              tags.trackNumber ??= trackNum;
            }
            if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {
              tags.tracksTotal ??= tracksTotal;
            }
          }
          ;
          break;
        case "TPOS":
        case "TPA":
          {
            const discText = reader.readId3V2EncodingAndText(frameEndPos);
            const parts = discText.split("/");
            const discNum = Number.parseInt(parts[0], 10);
            const discsTotal = parts[1] && Number.parseInt(parts[1], 10);
            if (Number.isInteger(discNum) && discNum > 0) {
              tags.discNumber ??= discNum;
            }
            if (discsTotal && Number.isInteger(discsTotal) && discsTotal > 0) {
              tags.discsTotal ??= discsTotal;
            }
          }
          ;
          break;
        case "TCON":
        case "TCO":
          {
            const genreText = reader.readId3V2EncodingAndText(frameEndPos);
            let match = /^\((\d+)\)/.exec(genreText);
            if (match) {
              const genreNumber = Number.parseInt(match[1]);
              if (ID3_V1_GENRES[genreNumber] !== void 0) {
                tags.genre ??= ID3_V1_GENRES[genreNumber];
                break;
              }
            }
            match = /^\d+$/.exec(genreText);
            if (match) {
              const genreNumber = Number.parseInt(match[0]);
              if (ID3_V1_GENRES[genreNumber] !== void 0) {
                tags.genre ??= ID3_V1_GENRES[genreNumber];
                break;
              }
            }
            tags.genre ??= genreText;
          }
          ;
          break;
        case "TDRC":
        case "TDAT":
          {
            const dateText = reader.readId3V2EncodingAndText(frameEndPos);
            const date = new Date(dateText);
            if (!Number.isNaN(date.getTime())) {
              tags.date ??= date;
            }
          }
          ;
          break;
        case "TYER":
        case "TYE":
          {
            const yearText = reader.readId3V2EncodingAndText(frameEndPos);
            const year = Number.parseInt(yearText, 10);
            if (Number.isInteger(year)) {
              tags.date ??= new Date(year, 0, 1);
            }
          }
          ;
          break;
        case "USLT":
        case "ULT":
          {
            const encoding = reader.readU8();
            reader.pos += 3;
            reader.readId3V2Text(encoding, frameEndPos);
            tags.lyrics ??= reader.readId3V2Text(encoding, frameEndPos);
          }
          ;
          break;
        case "COMM":
        case "COM":
          {
            const encoding = reader.readU8();
            reader.pos += 3;
            reader.readId3V2Text(encoding, frameEndPos);
            tags.comment ??= reader.readId3V2Text(encoding, frameEndPos);
          }
          ;
          break;
        case "APIC":
        case "PIC":
          {
            const encoding = reader.readId3V2TextEncoding();
            let mimeType;
            if (header.majorVersion === 2) {
              const imageFormat = reader.readAscii(3);
              mimeType = imageFormat === "PNG" ? "image/png" : imageFormat === "JPG" ? "image/jpeg" : "image/*";
            } else {
              mimeType = reader.readId3V2Text(encoding, frameEndPos);
            }
            const pictureType = reader.readU8();
            const description = reader.readId3V2Text(encoding, frameEndPos).trimEnd();
            const imageDataSize = frameEndPos - reader.pos;
            if (imageDataSize >= 0) {
              const imageData = reader.readBytes(imageDataSize);
              if (!tags.images) tags.images = [];
              tags.images.push({
                data: imageData,
                mimeType,
                kind: pictureType === 3 ? "coverFront" : pictureType === 4 ? "coverBack" : "unknown",
                description
              });
            }
          }
          ;
          break;
        default:
          {
            reader.pos += frame.size;
          }
          ;
          break;
      }
      reader.pos = frameEndPos;
    }
  };
  var Id3V2Reader = class {
    constructor(header, bytes2) {
      this.header = header;
      this.bytes = bytes2;
      this.pos = 0;
      this.view = new DataView(bytes2.buffer, bytes2.byteOffset, bytes2.byteLength);
    }
    frameHeaderSize() {
      return this.header.majorVersion === 2 ? 6 : 10;
    }
    ununsynchronizeAll() {
      const newBytes = [];
      for (let i = 0; i < this.bytes.length; i++) {
        const value1 = this.bytes[i];
        newBytes.push(value1);
        if (value1 === 255 && i !== this.bytes.length - 1) {
          const value2 = this.bytes[i];
          if (value2 === 0) {
            i++;
          }
        }
      }
      this.bytes = new Uint8Array(newBytes);
      this.view = new DataView(this.bytes.buffer);
    }
    ununsynchronizeRegion(start, end) {
      const newBytes = [];
      for (let i = start; i < end; i++) {
        const value1 = this.bytes[i];
        newBytes.push(value1);
        if (value1 === 255 && i !== end - 1) {
          const value2 = this.bytes[i + 1];
          if (value2 === 0) {
            i++;
          }
        }
      }
      const before = this.bytes.subarray(0, start);
      const after = this.bytes.subarray(end);
      this.bytes = new Uint8Array(before.length + newBytes.length + after.length);
      this.bytes.set(before, 0);
      this.bytes.set(newBytes, before.length);
      this.bytes.set(after, before.length + newBytes.length);
      this.view = new DataView(this.bytes.buffer);
    }
    removeFooter() {
      this.bytes = this.bytes.subarray(0, this.bytes.length - ID3_V2_HEADER_SIZE);
      this.view = new DataView(this.bytes.buffer);
    }
    readBytes(length) {
      const slice = this.bytes.subarray(this.pos, this.pos + length);
      this.pos += length;
      return slice;
    }
    readU8() {
      const value = this.view.getUint8(this.pos);
      this.pos += 1;
      return value;
    }
    readU16() {
      const value = this.view.getUint16(this.pos, false);
      this.pos += 2;
      return value;
    }
    readU24() {
      const high = this.view.getUint16(this.pos, false);
      const low = this.view.getUint8(this.pos + 1);
      this.pos += 3;
      return high * 256 + low;
    }
    readU32() {
      const value = this.view.getUint32(this.pos, false);
      this.pos += 4;
      return value;
    }
    readAscii(length) {
      let str = "";
      for (let i = 0; i < length; i++) {
        str += String.fromCharCode(this.view.getUint8(this.pos + i));
      }
      this.pos += length;
      return str;
    }
    readId3V2Frame() {
      if (this.header.majorVersion === 2) {
        const id = this.readAscii(3);
        if (id === "\0\0\0") {
          return null;
        }
        const size = this.readU24();
        return { id, size, flags: 0 };
      } else {
        const id = this.readAscii(4);
        if (id === "\0\0\0\0") {
          return null;
        }
        const sizeRaw = this.readU32();
        let size = this.header.majorVersion === 4 ? decodeSynchsafe(sizeRaw) : sizeRaw;
        const flags = this.readU16();
        const headerEndPos = this.pos;
        const isSizeValid = (size2) => {
          const nextPos = this.pos + size2;
          if (nextPos > this.bytes.length) {
            return false;
          }
          if (nextPos <= this.bytes.length - this.frameHeaderSize()) {
            this.pos += size2;
            const nextId = this.readAscii(4);
            if (nextId !== "\0\0\0\0" && !/[0-9A-Z]{4}/.test(nextId)) {
              return false;
            }
          }
          return true;
        };
        if (!isSizeValid(size)) {
          const otherSize = this.header.majorVersion === 4 ? sizeRaw : decodeSynchsafe(sizeRaw);
          if (isSizeValid(otherSize)) {
            size = otherSize;
          }
        }
        this.pos = headerEndPos;
        return { id, size, flags };
      }
    }
    readId3V2TextEncoding() {
      const number = this.readU8();
      if (number > 3) {
        throw new Error(`Unsupported text encoding: ${number}`);
      }
      return number;
    }
    readId3V2Text(encoding, until) {
      const startPos = this.pos;
      const data = this.readBytes(until - this.pos);
      switch (encoding) {
        case 0 /* ISO_8859_1 */: {
          let str = "";
          for (let i = 0; i < data.length; i++) {
            const value = data[i];
            if (value === 0) {
              this.pos = startPos + i + 1;
              break;
            }
            str += String.fromCharCode(value);
          }
          return str;
        }
        case 1 /* UTF_16_WITH_BOM */: {
          if (data[0] === 255 && data[1] === 254) {
            const decoder = new TextDecoder("utf-16le");
            const endIndex = coalesceIndex(
              data.findIndex((x, i) => x === 0 && data[i + 1] === 0 && i % 2 === 0),
              data.length
            );
            this.pos = startPos + Math.min(endIndex + 2, data.length);
            return decoder.decode(data.subarray(2, endIndex));
          } else if (data[0] === 254 && data[1] === 255) {
            const decoder = new TextDecoder("utf-16be");
            const endIndex = coalesceIndex(
              data.findIndex((x, i) => x === 0 && data[i + 1] === 0 && i % 2 === 0),
              data.length
            );
            this.pos = startPos + Math.min(endIndex + 2, data.length);
            return decoder.decode(data.subarray(2, endIndex));
          } else {
            const endIndex = coalesceIndex(data.findIndex((x) => x === 0), data.length);
            this.pos = startPos + Math.min(endIndex + 1, data.length);
            return textDecoder.decode(data.subarray(0, endIndex));
          }
        }
        case 2 /* UTF_16_BE_NO_BOM */: {
          const decoder = new TextDecoder("utf-16be");
          const endIndex = coalesceIndex(
            data.findIndex((x, i) => x === 0 && data[i + 1] === 0 && i % 2 === 0),
            data.length
          );
          this.pos = startPos + Math.min(endIndex + 2, data.length);
          return decoder.decode(data.subarray(0, endIndex));
        }
        case 3 /* UTF_8 */: {
          const endIndex = coalesceIndex(data.findIndex((x) => x === 0), data.length);
          this.pos = startPos + Math.min(endIndex + 1, data.length);
          return textDecoder.decode(data.subarray(0, endIndex));
        }
      }
    }
    readId3V2EncodingAndText(until) {
      if (this.pos >= until) {
        return "";
      }
      const encoding = this.readId3V2TextEncoding();
      return this.readId3V2Text(encoding, until);
    }
  };
  var Id3V2Writer = class {
    constructor(writer) {
      this.helper = new Uint8Array(8);
      this.helperView = toDataView(this.helper);
      this.writer = writer;
    }
    writeId3V2Tag(metadata) {
      const tagStartPos = this.writer.getPos();
      this.writeAscii("ID3");
      this.writeU8(4);
      this.writeU8(0);
      this.writeU8(0);
      this.writeSynchsafeU32(0);
      const framesStartPos = this.writer.getPos();
      const writtenTags = /* @__PURE__ */ new Set();
      for (const { key, value } of keyValueIterator(metadata)) {
        switch (key) {
          case "title":
            {
              this.writeId3V2TextFrame("TIT2", value);
              writtenTags.add("TIT2");
            }
            ;
            break;
          case "description":
            {
              this.writeId3V2TextFrame("TIT3", value);
              writtenTags.add("TIT3");
            }
            ;
            break;
          case "artist":
            {
              this.writeId3V2TextFrame("TPE1", value);
              writtenTags.add("TPE1");
            }
            ;
            break;
          case "album":
            {
              this.writeId3V2TextFrame("TALB", value);
              writtenTags.add("TALB");
            }
            ;
            break;
          case "albumArtist":
            {
              this.writeId3V2TextFrame("TPE2", value);
              writtenTags.add("TPE2");
            }
            ;
            break;
          case "trackNumber":
            {
              const string = metadata.tracksTotal !== void 0 ? `${value}/${metadata.tracksTotal}` : value.toString();
              this.writeId3V2TextFrame("TRCK", string);
              writtenTags.add("TRCK");
            }
            ;
            break;
          case "discNumber":
            {
              const string = metadata.discsTotal !== void 0 ? `${value}/${metadata.discsTotal}` : value.toString();
              this.writeId3V2TextFrame("TPOS", string);
              writtenTags.add("TPOS");
            }
            ;
            break;
          case "genre":
            {
              this.writeId3V2TextFrame("TCON", value);
              writtenTags.add("TCON");
            }
            ;
            break;
          case "date":
            {
              this.writeId3V2TextFrame("TDRC", value.toISOString().slice(0, 10));
              writtenTags.add("TDRC");
            }
            ;
            break;
          case "lyrics":
            {
              this.writeId3V2LyricsFrame(value);
              writtenTags.add("USLT");
            }
            ;
            break;
          case "comment":
            {
              this.writeId3V2CommentFrame(value);
              writtenTags.add("COMM");
            }
            ;
            break;
          case "images":
            {
              const pictureTypeMap = { coverFront: 3, coverBack: 4, unknown: 0 };
              for (const image of value) {
                const pictureType = pictureTypeMap[image.kind] ?? 0;
                const description = image.description ?? "";
                this.writeId3V2ApicFrame(image.mimeType, pictureType, description, image.data);
              }
            }
            ;
            break;
          case "tracksTotal":
          case "discsTotal":
            {
            }
            ;
            break;
          case "raw":
            {
            }
            ;
            break;
          default: {
            assertNever(key);
          }
        }
      }
      if (metadata.raw) {
        for (const key in metadata.raw) {
          const value = metadata.raw[key];
          if (value == null || key.length !== 4 || writtenTags.has(key)) {
            continue;
          }
          let bytes2;
          if (typeof value === "string") {
            const encoded = textEncoder.encode(value);
            bytes2 = new Uint8Array(encoded.byteLength + 2);
            bytes2[0] = 3 /* UTF_8 */;
            bytes2.set(encoded, 1);
          } else if (value instanceof Uint8Array) {
            bytes2 = value;
          } else {
            continue;
          }
          this.writeAscii(key);
          this.writeSynchsafeU32(bytes2.byteLength);
          this.writeU16(0);
          this.writer.write(bytes2);
        }
      }
      const framesEndPos = this.writer.getPos();
      const framesSize = framesEndPos - framesStartPos;
      this.writer.seek(tagStartPos + 6);
      this.writeSynchsafeU32(framesSize);
      this.writer.seek(framesEndPos);
      return framesSize + 10;
    }
    writeU8(value) {
      this.helper[0] = value;
      this.writer.write(this.helper.subarray(0, 1));
    }
    writeU16(value) {
      this.helperView.setUint16(0, value, false);
      this.writer.write(this.helper.subarray(0, 2));
    }
    writeU32(value) {
      this.helperView.setUint32(0, value, false);
      this.writer.write(this.helper.subarray(0, 4));
    }
    writeAscii(text) {
      for (let i = 0; i < text.length; i++) {
        this.helper[i] = text.charCodeAt(i);
      }
      this.writer.write(this.helper.subarray(0, text.length));
    }
    writeSynchsafeU32(value) {
      this.writeU32(encodeSynchsafe(value));
    }
    writeIsoString(text) {
      const bytes2 = new Uint8Array(text.length + 1);
      for (let i = 0; i < text.length; i++) {
        bytes2[i] = text.charCodeAt(i);
      }
      bytes2[text.length] = 0;
      this.writer.write(bytes2);
    }
    writeUtf8String(text) {
      const utf8Data = textEncoder.encode(text);
      this.writer.write(utf8Data);
      this.writeU8(0);
    }
    writeId3V2TextFrame(frameId, text) {
      const useIso88591 = isIso88591Compatible(text);
      const textDataLength = useIso88591 ? text.length : textEncoder.encode(text).byteLength;
      const frameSize = 1 + textDataLength + 1;
      this.writeAscii(frameId);
      this.writeSynchsafeU32(frameSize);
      this.writeU16(0);
      this.writeU8(useIso88591 ? 0 /* ISO_8859_1 */ : 3 /* UTF_8 */);
      if (useIso88591) {
        this.writeIsoString(text);
      } else {
        this.writeUtf8String(text);
      }
    }
    writeId3V2LyricsFrame(lyrics) {
      const useIso88591 = isIso88591Compatible(lyrics);
      const shortDescription = "";
      const frameSize = 1 + 3 + shortDescription.length + 1 + lyrics.length + 1;
      this.writeAscii("USLT");
      this.writeSynchsafeU32(frameSize);
      this.writeU16(0);
      this.writeU8(useIso88591 ? 0 /* ISO_8859_1 */ : 3 /* UTF_8 */);
      this.writeAscii("und");
      if (useIso88591) {
        this.writeIsoString(shortDescription);
        this.writeIsoString(lyrics);
      } else {
        this.writeUtf8String(shortDescription);
        this.writeUtf8String(lyrics);
      }
    }
    writeId3V2CommentFrame(comment) {
      const useIso88591 = isIso88591Compatible(comment);
      const textDataLength = useIso88591 ? comment.length : textEncoder.encode(comment).byteLength;
      const shortDescription = "";
      const frameSize = 1 + 3 + shortDescription.length + 1 + textDataLength + 1;
      this.writeAscii("COMM");
      this.writeSynchsafeU32(frameSize);
      this.writeU16(0);
      this.writeU8(useIso88591 ? 0 /* ISO_8859_1 */ : 3 /* UTF_8 */);
      this.writeU8(117);
      this.writeU8(110);
      this.writeU8(100);
      if (useIso88591) {
        this.writeIsoString(shortDescription);
        this.writeIsoString(comment);
      } else {
        this.writeUtf8String(shortDescription);
        this.writeUtf8String(comment);
      }
    }
    writeId3V2ApicFrame(mimeType, pictureType, description, imageData) {
      const useIso88591 = isIso88591Compatible(mimeType) && isIso88591Compatible(description);
      const descriptionDataLength = useIso88591 ? description.length : textEncoder.encode(description).byteLength;
      const frameSize = 1 + mimeType.length + 1 + 1 + descriptionDataLength + 1 + imageData.byteLength;
      this.writeAscii("APIC");
      this.writeSynchsafeU32(frameSize);
      this.writeU16(0);
      this.writeU8(useIso88591 ? 0 /* ISO_8859_1 */ : 3 /* UTF_8 */);
      if (useIso88591) {
        this.writeIsoString(mimeType);
      } else {
        this.writeUtf8String(mimeType);
      }
      this.writeU8(pictureType);
      if (useIso88591) {
        this.writeIsoString(description);
      } else {
        this.writeUtf8String(description);
      }
      this.writer.write(imageData);
    }
  };

  // src/muxer.ts
  var Muxer = class {
    constructor(output) {
      this.mutex = new AsyncMutex();
      /**
       * This field is used to synchronize multiple MediaStreamTracks. They use the same time coordinate system across
       * tracks, and to ensure correct audio-video sync, we must use the same offset for all of them. The reason an offset
       * is needed at all is because the timestamps typically don't start at zero.
       */
      this.firstMediaStreamTimestamp = null;
      this.trackTimestampInfo = /* @__PURE__ */ new WeakMap();
      this.output = output;
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    onTrackClose(track) {
    }
    validateAndNormalizeTimestamp(track, timestampInSeconds, isKeyPacket) {
      timestampInSeconds += track.source._timestampOffset;
      let timestampInfo = this.trackTimestampInfo.get(track);
      if (!timestampInfo) {
        if (!isKeyPacket) {
          throw new Error("First packet must be a key packet.");
        }
        timestampInfo = {
          maxTimestamp: timestampInSeconds,
          maxTimestampBeforeLastKeyPacket: timestampInSeconds
        };
        this.trackTimestampInfo.set(track, timestampInfo);
      }
      if (timestampInSeconds < 0) {
        throw new Error(`Timestamps must be non-negative (got ${timestampInSeconds}s).`);
      }
      if (isKeyPacket) {
        timestampInfo.maxTimestampBeforeLastKeyPacket = timestampInfo.maxTimestamp;
      }
      if (timestampInSeconds < timestampInfo.maxTimestampBeforeLastKeyPacket) {
        throw new Error(
          `Timestamps cannot be smaller than the largest timestamp of the previous GOP (a GOP begins with a key packet and ends right before the next key packet). Got ${timestampInSeconds}s, but largest timestamp is ${timestampInfo.maxTimestampBeforeLastKeyPacket}s.`
        );
      }
      timestampInfo.maxTimestamp = Math.max(timestampInfo.maxTimestamp, timestampInSeconds);
      return timestampInSeconds;
    }
  };

  // src/adts/adts-misc.ts
  var buildAdtsHeaderTemplate = (config) => {
    const header = new Uint8Array(7);
    const bitstream = new Bitstream(header);
    const { objectType, frequencyIndex, channelConfiguration } = config;
    const profile = objectType - 1;
    bitstream.writeBits(12, 4095);
    bitstream.writeBits(1, 0);
    bitstream.writeBits(2, 0);
    bitstream.writeBits(1, 1);
    bitstream.writeBits(2, profile);
    bitstream.writeBits(4, frequencyIndex);
    bitstream.writeBits(1, 0);
    bitstream.writeBits(3, channelConfiguration);
    bitstream.writeBits(1, 0);
    bitstream.writeBits(1, 0);
    bitstream.writeBits(1, 0);
    bitstream.writeBits(1, 0);
    bitstream.skipBits(13);
    bitstream.writeBits(11, 2047);
    bitstream.writeBits(2, 0);
    return { header, bitstream };
  };
  var writeAdtsFrameLength = (bitstream, frameLength) => {
    bitstream.pos = 30;
    bitstream.writeBits(13, frameLength);
  };

  // src/adts/adts-muxer.ts
  var AdtsMuxer = class extends Muxer {
    constructor(output, format) {
      super(output);
      this.header = null;
      this.headerBitstream = null;
      this.inputIsAdts = null;
      this.format = format;
      this.writer = output._writer;
    }
    async start() {
      if (!metadataTagsAreEmpty(this.output._metadataTags)) {
        const id3Writer = new Id3V2Writer(this.writer);
        id3Writer.writeId3V2Tag(this.output._metadataTags);
      }
    }
    async getMimeType() {
      return "audio/aac";
    }
    async addEncodedVideoPacket() {
      throw new Error("ADTS does not support video.");
    }
    async addEncodedAudioPacket(track, packet, meta) {
      const release = await this.mutex.acquire();
      try {
        this.validateAndNormalizeTimestamp(track, packet.timestamp, packet.type === "key");
        if (this.inputIsAdts === null) {
          validateAudioChunkMetadata(meta);
          const description = meta?.decoderConfig?.description;
          this.inputIsAdts = !description;
          if (!this.inputIsAdts) {
            const config = parseAacAudioSpecificConfig(toUint8Array(description));
            const template = buildAdtsHeaderTemplate(config);
            this.header = template.header;
            this.headerBitstream = template.bitstream;
          }
        }
        if (this.inputIsAdts) {
          const startPos = this.writer.getPos();
          this.writer.write(packet.data);
          if (this.format._options.onFrame) {
            this.format._options.onFrame(packet.data, startPos);
          }
        } else {
          assert(this.header);
          const frameLength = packet.data.byteLength + this.header.byteLength;
          writeAdtsFrameLength(this.headerBitstream, frameLength);
          const startPos = this.writer.getPos();
          this.writer.write(this.header);
          this.writer.write(packet.data);
          if (this.format._options.onFrame) {
            const frameBytes = new Uint8Array(frameLength);
            frameBytes.set(this.header, 0);
            frameBytes.set(packet.data, this.header.byteLength);
            this.format._options.onFrame(frameBytes, startPos);
          }
        }
        await this.writer.flush();
      } finally {
        release();
      }
    }
    async addSubtitleCue() {
      throw new Error("ADTS does not support subtitles.");
    }
    async finalize() {
      const release = await this.mutex.acquire();
      release();
    }
  };

  // src/flac/flac-muxer.ts
  var FLAC_HEADER = /* @__PURE__ */ new Uint8Array([102, 76, 97, 67]);
  var STREAMINFO_SIZE = 38;
  var STREAMINFO_BLOCK_SIZE = 34;
  var FlacMuxer = class extends Muxer {
    constructor(output, format) {
      super(output);
      this.metadataWritten = false;
      this.blockSizes = [];
      this.frameSizes = [];
      this.sampleRate = null;
      this.channels = null;
      this.bitsPerSample = null;
      this.writer = output._writer;
      this.format = format;
    }
    async start() {
      this.writer.write(FLAC_HEADER);
    }
    writeHeader({
      bitsPerSample,
      minimumBlockSize,
      maximumBlockSize,
      minimumFrameSize,
      maximumFrameSize,
      sampleRate,
      channels,
      totalSamples
    }) {
      assert(this.writer.getPos() === 4);
      const hasMetadata = !metadataTagsAreEmpty(this.output._metadataTags);
      const headerBitstream = new Bitstream(new Uint8Array(4));
      headerBitstream.writeBits(1, Number(!hasMetadata));
      headerBitstream.writeBits(7, 0 /* STREAMINFO */);
      headerBitstream.writeBits(24, STREAMINFO_BLOCK_SIZE);
      this.writer.write(headerBitstream.bytes);
      const contentBitstream = new Bitstream(new Uint8Array(18));
      contentBitstream.writeBits(16, minimumBlockSize);
      contentBitstream.writeBits(16, maximumBlockSize);
      contentBitstream.writeBits(24, minimumFrameSize);
      contentBitstream.writeBits(24, maximumFrameSize);
      contentBitstream.writeBits(20, sampleRate);
      contentBitstream.writeBits(3, channels - 1);
      contentBitstream.writeBits(5, bitsPerSample - 1);
      if (totalSamples >= 2 ** 32) {
        throw new Error("This muxer only supports writing up to 2 ** 32 samples");
      }
      contentBitstream.writeBits(4, 0);
      contentBitstream.writeBits(32, totalSamples);
      this.writer.write(contentBitstream.bytes);
      this.writer.write(new Uint8Array(16));
    }
    writePictureBlock(picture) {
      const headerSize = 32 + picture.mimeType.length + (picture.description?.length ?? 0) + picture.data.length;
      const header = new Uint8Array(headerSize);
      let offset = 0;
      const dataView = toDataView(header);
      dataView.setUint32(
        offset,
        picture.kind === "coverFront" ? 3 : picture.kind === "coverBack" ? 4 : 0
      );
      offset += 4;
      dataView.setUint32(offset, picture.mimeType.length);
      offset += 4;
      header.set(textEncoder.encode(picture.mimeType), 8);
      offset += picture.mimeType.length;
      dataView.setUint32(offset, picture.description?.length ?? 0);
      offset += 4;
      header.set(textEncoder.encode(picture.description ?? ""), offset);
      offset += picture.description?.length ?? 0;
      offset += 4 + 4 + 4 + 4;
      dataView.setUint32(offset, picture.data.length);
      offset += 4;
      header.set(picture.data, offset);
      offset += picture.data.length;
      assert(offset === headerSize);
      const headerBitstream = new Bitstream(new Uint8Array(4));
      headerBitstream.writeBits(1, 0);
      headerBitstream.writeBits(7, 6 /* PICTURE */);
      headerBitstream.writeBits(24, headerSize);
      this.writer.write(headerBitstream.bytes);
      this.writer.write(header);
    }
    writeVorbisCommentAndPictureBlock() {
      this.writer.seek(STREAMINFO_SIZE + FLAC_HEADER.byteLength);
      if (metadataTagsAreEmpty(this.output._metadataTags)) {
        this.metadataWritten = true;
        return;
      }
      const pictures = this.output._metadataTags.images ?? [];
      for (const picture of pictures) {
        this.writePictureBlock(picture);
      }
      const vorbisComment = createVorbisComments(
        new Uint8Array(0),
        this.output._metadataTags,
        false
      );
      const headerBitstream = new Bitstream(new Uint8Array(4));
      headerBitstream.writeBits(1, 1);
      headerBitstream.writeBits(7, 4 /* VORBIS_COMMENT */);
      headerBitstream.writeBits(24, vorbisComment.length);
      this.writer.write(headerBitstream.bytes);
      this.writer.write(vorbisComment);
      this.metadataWritten = true;
    }
    async getMimeType() {
      return "audio/flac";
    }
    async addEncodedVideoPacket() {
      throw new Error("FLAC does not support video.");
    }
    async addEncodedAudioPacket(track, packet, meta) {
      const release = await this.mutex.acquire();
      validateAudioChunkMetadata(meta);
      assert(meta);
      assert(meta.decoderConfig);
      assert(meta.decoderConfig.description);
      try {
        this.validateAndNormalizeTimestamp(
          track,
          packet.timestamp,
          packet.type === "key"
        );
        if (this.sampleRate === null) {
          this.sampleRate = meta.decoderConfig.sampleRate;
        }
        if (this.channels === null) {
          this.channels = meta.decoderConfig.numberOfChannels;
        }
        if (this.bitsPerSample === null) {
          const descriptionBitstream = new Bitstream(
            toUint8Array(meta.decoderConfig.description)
          );
          descriptionBitstream.skipBits(103 + 64);
          const bitsPerSample = descriptionBitstream.readBits(5) + 1;
          this.bitsPerSample = bitsPerSample;
        }
        if (!this.metadataWritten) {
          this.writeVorbisCommentAndPictureBlock();
        }
        const slice = FileSlice4.tempFromBytes(packet.data);
        readBytes(slice, 2);
        const bytes2 = readBytes(slice, 2);
        const bitstream = new Bitstream(bytes2);
        const blockSizeOrUncommon = getBlockSizeOrUncommon(bitstream.readBits(4));
        if (blockSizeOrUncommon === null) {
          throw new Error("Invalid FLAC frame: Invalid block size.");
        }
        readCodedNumber(slice);
        const blockSize = readBlockSize(slice, blockSizeOrUncommon);
        this.blockSizes.push(blockSize);
        this.frameSizes.push(packet.data.length);
        const startPos = this.writer.getPos();
        this.writer.write(packet.data);
        if (this.format._options.onFrame) {
          this.format._options.onFrame(packet.data, startPos);
        }
        await this.writer.flush();
      } finally {
        release();
      }
    }
    addSubtitleCue() {
      throw new Error("FLAC does not support subtitles.");
    }
    async finalize() {
      const release = await this.mutex.acquire();
      let minimumBlockSize = Infinity;
      let maximumBlockSize = 0;
      let minimumFrameSize = Infinity;
      let maximumFrameSize = 0;
      let totalSamples = 0;
      for (let i = 0; i < this.blockSizes.length; i++) {
        minimumFrameSize = Math.min(minimumFrameSize, this.frameSizes[i]);
        maximumFrameSize = Math.max(maximumFrameSize, this.frameSizes[i]);
        maximumBlockSize = Math.max(maximumBlockSize, this.blockSizes[i]);
        totalSamples += this.blockSizes[i];
        const isLastFrame = i === this.blockSizes.length - 1;
        if (isLastFrame) {
          continue;
        }
        minimumBlockSize = Math.min(minimumBlockSize, this.blockSizes[i]);
      }
      assert(this.sampleRate !== null);
      assert(this.channels !== null);
      assert(this.bitsPerSample !== null);
      this.writer.seek(4);
      this.writeHeader({
        minimumBlockSize,
        maximumBlockSize,
        minimumFrameSize,
        maximumFrameSize,
        sampleRate: this.sampleRate,
        channels: this.channels,
        bitsPerSample: this.bitsPerSample,
        totalSamples
      });
      release();
    }
  };

  // src/subtitles.ts
  var cueBlockHeaderRegex = /(?:(.+?)\n)?((?:\d{2}:)?\d{2}:\d{2}.\d{3})\s+-->\s+((?:\d{2}:)?\d{2}:\d{2}.\d{3})/g;
  var preambleStartRegex = /^WEBVTT(.|\n)*?\n{2}/;
  var inlineTimestampRegex = /<(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})>/g;
  var SubtitleParser = class {
    constructor(options) {
      this.preambleText = null;
      this.preambleEmitted = false;
      this.options = options;
    }
    parse(text) {
      text = text.replaceAll("\r\n", "\n").replaceAll("\r", "\n");
      cueBlockHeaderRegex.lastIndex = 0;
      let match;
      if (!this.preambleText) {
        if (!preambleStartRegex.test(text)) {
          throw new Error("WebVTT preamble incorrect.");
        }
        match = cueBlockHeaderRegex.exec(text);
        const preamble = text.slice(0, match?.index ?? text.length).trimEnd();
        if (!preamble) {
          throw new Error("No WebVTT preamble provided.");
        }
        this.preambleText = preamble;
        if (match) {
          text = text.slice(match.index);
          cueBlockHeaderRegex.lastIndex = 0;
        }
      }
      while (match = cueBlockHeaderRegex.exec(text)) {
        const notes = text.slice(0, match.index);
        const cueIdentifier = match[1];
        const matchEnd = match.index + match[0].length;
        const bodyStart = text.indexOf("\n", matchEnd) + 1;
        const cueSettings = text.slice(matchEnd, bodyStart).trim();
        let bodyEnd = text.indexOf("\n\n", matchEnd);
        if (bodyEnd === -1) bodyEnd = text.length;
        const startTime = parseSubtitleTimestamp(match[2]);
        const endTime = parseSubtitleTimestamp(match[3]);
        const duration = endTime - startTime;
        const body = text.slice(bodyStart, bodyEnd).trim();
        text = text.slice(bodyEnd).trimStart();
        cueBlockHeaderRegex.lastIndex = 0;
        const cue = {
          timestamp: startTime / 1e3,
          duration: duration / 1e3,
          text: body,
          identifier: cueIdentifier,
          settings: cueSettings,
          notes
        };
        const meta = {};
        if (!this.preambleEmitted) {
          meta.config = {
            description: this.preambleText
          };
          this.preambleEmitted = true;
        }
        this.options.output(cue, meta);
      }
    }
  };
  var timestampRegex = /(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})/;
  var parseSubtitleTimestamp = (string) => {
    const match = timestampRegex.exec(string);
    if (!match) throw new Error("Expected match.");
    return 60 * 60 * 1e3 * Number(match[1] || "0") + 60 * 1e3 * Number(match[2]) + 1e3 * Number(match[3]) + Number(match[4]);
  };
  var formatSubtitleTimestamp = (timestamp) => {
    const hours = Math.floor(timestamp / (60 * 60 * 1e3));
    const minutes = Math.floor(timestamp % (60 * 60 * 1e3) / (60 * 1e3));
    const seconds = Math.floor(timestamp % (60 * 1e3) / 1e3);
    const milliseconds = timestamp % 1e3;
    return hours.toString().padStart(2, "0") + ":" + minutes.toString().padStart(2, "0") + ":" + seconds.toString().padStart(2, "0") + "." + milliseconds.toString().padStart(3, "0");
  };

  // src/isobmff/isobmff-boxes.ts
  var IsobmffBoxWriter = class {
    constructor(writer) {
      this.writer = writer;
      this.helper = new Uint8Array(8);
      this.helperView = new DataView(this.helper.buffer);
      /**
       * Stores the position from the start of the file to where boxes elements have been written. This is used to
       * rewrite/edit elements that were already added before, and to measure sizes of things.
       */
      this.offsets = /* @__PURE__ */ new WeakMap();
    }
    writeU32(value) {
      this.helperView.setUint32(0, value, false);
      this.writer.write(this.helper.subarray(0, 4));
    }
    writeU64(value) {
      this.helperView.setUint32(0, Math.floor(value / 2 ** 32), false);
      this.helperView.setUint32(4, value, false);
      this.writer.write(this.helper.subarray(0, 8));
    }
    writeAscii(text) {
      for (let i = 0; i < text.length; i++) {
        this.helperView.setUint8(i % 8, text.charCodeAt(i));
        if (i % 8 === 7) this.writer.write(this.helper);
      }
      if (text.length % 8 !== 0) {
        this.writer.write(this.helper.subarray(0, text.length % 8));
      }
    }
    writeBox(box2) {
      this.offsets.set(box2, this.writer.getPos());
      if (box2.contents && !box2.children) {
        this.writeBoxHeader(box2, box2.size ?? box2.contents.byteLength + 8);
        this.writer.write(box2.contents);
      } else {
        const startPos = this.writer.getPos();
        this.writeBoxHeader(box2, 0);
        if (box2.contents) this.writer.write(box2.contents);
        if (box2.children) {
          for (const child of box2.children) if (child) this.writeBox(child);
        }
        const endPos = this.writer.getPos();
        const size = box2.size ?? endPos - startPos;
        this.writer.seek(startPos);
        this.writeBoxHeader(box2, size);
        this.writer.seek(endPos);
      }
    }
    writeBoxHeader(box2, size) {
      this.writeU32(box2.largeSize ? 1 : size);
      this.writeAscii(box2.type);
      if (box2.largeSize) this.writeU64(size);
    }
    measureBoxHeader(box2) {
      return 8 + (box2.largeSize ? 8 : 0);
    }
    patchBox(box2) {
      const boxOffset = this.offsets.get(box2);
      assert(boxOffset !== void 0);
      const endPos = this.writer.getPos();
      this.writer.seek(boxOffset);
      this.writeBox(box2);
      this.writer.seek(endPos);
    }
    measureBox(box2) {
      if (box2.contents && !box2.children) {
        const headerSize = this.measureBoxHeader(box2);
        return headerSize + box2.contents.byteLength;
      } else {
        let result = this.measureBoxHeader(box2);
        if (box2.contents) result += box2.contents.byteLength;
        if (box2.children) {
          for (const child of box2.children) if (child) result += this.measureBox(child);
        }
        return result;
      }
    }
  };
  var bytes = /* @__PURE__ */ new Uint8Array(8);
  var view = /* @__PURE__ */ new DataView(bytes.buffer);
  var u8 = (value) => {
    return [(value % 256 + 256) % 256];
  };
  var u16 = (value) => {
    view.setUint16(0, value, false);
    return [bytes[0], bytes[1]];
  };
  var i16 = (value) => {
    view.setInt16(0, value, false);
    return [bytes[0], bytes[1]];
  };
  var u24 = (value) => {
    view.setUint32(0, value, false);
    return [bytes[1], bytes[2], bytes[3]];
  };
  var u32 = (value) => {
    view.setUint32(0, value, false);
    return [bytes[0], bytes[1], bytes[2], bytes[3]];
  };
  var i32 = (value) => {
    view.setInt32(0, value, false);
    return [bytes[0], bytes[1], bytes[2], bytes[3]];
  };
  var u64 = (value) => {
    view.setUint32(0, Math.floor(value / 2 ** 32), false);
    view.setUint32(4, value, false);
    return [bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]];
  };
  var fixed_8_8 = (value) => {
    view.setInt16(0, 2 ** 8 * value, false);
    return [bytes[0], bytes[1]];
  };
  var fixed_16_16 = (value) => {
    view.setInt32(0, 2 ** 16 * value, false);
    return [bytes[0], bytes[1], bytes[2], bytes[3]];
  };
  var fixed_2_30 = (value) => {
    view.setInt32(0, 2 ** 30 * value, false);
    return [bytes[0], bytes[1], bytes[2], bytes[3]];
  };
  var variableUnsignedInt = (value, byteLength) => {
    const bytes2 = [];
    let remaining = value;
    do {
      let byte = remaining & 127;
      remaining >>= 7;
      if (bytes2.length > 0) {
        byte |= 128;
      }
      bytes2.push(byte);
      if (byteLength !== void 0) {
        byteLength--;
      }
    } while (remaining > 0 || byteLength);
    return bytes2.reverse();
  };
  var ascii = (text, nullTerminated = false) => {
    const bytes2 = Array(text.length).fill(null).map((_, i) => text.charCodeAt(i));
    if (nullTerminated) bytes2.push(0);
    return bytes2;
  };
  var lastPresentedSample = (samples) => {
    let result = null;
    for (const sample of samples) {
      if (!result || sample.timestamp > result.timestamp) {
        result = sample;
      }
    }
    return result;
  };
  var rotationMatrix = (rotationInDegrees) => {
    const theta = rotationInDegrees * (Math.PI / 180);
    const cosTheta = Math.round(Math.cos(theta));
    const sinTheta = Math.round(Math.sin(theta));
    return [
      cosTheta,
      sinTheta,
      0,
      -sinTheta,
      cosTheta,
      0,
      0,
      0,
      1
    ];
  };
  var IDENTITY_MATRIX = /* @__PURE__ */ rotationMatrix(0);
  var matrixToBytes = (matrix) => {
    return [
      fixed_16_16(matrix[0]),
      fixed_16_16(matrix[1]),
      fixed_2_30(matrix[2]),
      fixed_16_16(matrix[3]),
      fixed_16_16(matrix[4]),
      fixed_2_30(matrix[5]),
      fixed_16_16(matrix[6]),
      fixed_16_16(matrix[7]),
      fixed_2_30(matrix[8])
    ];
  };
  var box = (type, contents, children) => ({
    type,
    contents: contents && new Uint8Array(contents.flat(10)),
    children
  });
  var fullBox = (type, version, flags, contents, children) => box(
    type,
    [u8(version), u24(flags), contents ?? []],
    children
  );
  var ftyp = (details) => {
    const minorVersion = 512;
    if (details.isQuickTime) {
      return box("ftyp", [
        ascii("qt  "),
        // Major brand
        u32(minorVersion),
        // Minor version
        // Compatible brands
        ascii("qt  ")
      ]);
    }
    if (details.fragmented) {
      return box("ftyp", [
        ascii("iso5"),
        // Major brand
        u32(minorVersion),
        // Minor version
        // Compatible brands
        ascii("iso5"),
        ascii("iso6"),
        ascii("mp41")
      ]);
    }
    return box("ftyp", [
      ascii("isom"),
      // Major brand
      u32(minorVersion),
      // Minor version
      // Compatible brands
      ascii("isom"),
      details.holdsAvc ? ascii("avc1") : [],
      ascii("mp41")
    ]);
  };
  var mdat = (reserveLargeSize) => ({ type: "mdat", largeSize: reserveLargeSize });
  var free = (size) => ({ type: "free", size });
  var moov = (muxer) => box("moov", void 0, [
    mvhd(muxer.creationTime, muxer.trackDatas),
    ...muxer.trackDatas.map((x) => trak(x, muxer.creationTime)),
    muxer.isFragmented ? mvex(muxer.trackDatas) : null,
    udta(muxer)
  ]);
  var mvhd = (creationTime, trackDatas) => {
    const duration = intoTimescale(Math.max(
      0,
      ...trackDatas.filter((x) => x.samples.length > 0).map((x) => {
        const lastSample = lastPresentedSample(x.samples);
        return lastSample.timestamp + lastSample.duration;
      })
    ), GLOBAL_TIMESCALE);
    const nextTrackId = Math.max(0, ...trackDatas.map((x) => x.track.id)) + 1;
    const needsU64 = !isU32(creationTime) || !isU32(duration);
    const u32OrU64 = needsU64 ? u64 : u32;
    return fullBox("mvhd", +needsU64, 0, [
      u32OrU64(creationTime),
      // Creation time
      u32OrU64(creationTime),
      // Modification time
      u32(GLOBAL_TIMESCALE),
      // Timescale
      u32OrU64(duration),
      // Duration
      fixed_16_16(1),
      // Preferred rate
      fixed_8_8(1),
      // Preferred volume
      Array(10).fill(0),
      // Reserved
      matrixToBytes(IDENTITY_MATRIX),
      // Matrix
      Array(24).fill(0),
      // Pre-defined
      u32(nextTrackId)
      // Next track ID
    ]);
  };
  var trak = (trackData, creationTime) => {
    const trackMetadata = getTrackMetadata(trackData);
    return box("trak", void 0, [
      tkhd(trackData, creationTime),
      mdia(trackData, creationTime),
      trackMetadata.name !== void 0 ? box("udta", void 0, [
        box("name", [
          // VLC (and Mediabunny) also recognize ©nam
          ...textEncoder.encode(trackMetadata.name)
        ])
      ]) : null
    ]);
  };
  var tkhd = (trackData, creationTime) => {
    const lastSample = lastPresentedSample(trackData.samples);
    const durationInGlobalTimescale = intoTimescale(
      lastSample ? lastSample.timestamp + lastSample.duration : 0,
      GLOBAL_TIMESCALE
    );
    const needsU64 = !isU32(creationTime) || !isU32(durationInGlobalTimescale);
    const u32OrU64 = needsU64 ? u64 : u32;
    let matrix;
    if (trackData.type === "video") {
      const rotation = trackData.track.metadata.rotation;
      matrix = rotationMatrix(rotation ?? 0);
    } else {
      matrix = IDENTITY_MATRIX;
    }
    let flags = 2;
    if (trackData.track.metadata.disposition?.default !== false) {
      flags |= 1;
    }
    return fullBox("tkhd", +needsU64, flags, [
      u32OrU64(creationTime),
      // Creation time
      u32OrU64(creationTime),
      // Modification time
      u32(trackData.track.id),
      // Track ID
      u32(0),
      // Reserved
      u32OrU64(durationInGlobalTimescale),
      // Duration
      Array(8).fill(0),
      // Reserved
      u16(0),
      // Layer
      u16(trackData.track.id),
      // Alternate group
      fixed_8_8(trackData.type === "audio" ? 1 : 0),
      // Volume
      u16(0),
      // Reserved
      matrixToBytes(matrix),
      // Matrix
      fixed_16_16(trackData.type === "video" ? trackData.info.width : 0),
      // Track width
      fixed_16_16(trackData.type === "video" ? trackData.info.height : 0)
      // Track height
    ]);
  };
  var mdia = (trackData, creationTime) => box("mdia", void 0, [
    mdhd(trackData, creationTime),
    hdlr(true, TRACK_TYPE_TO_COMPONENT_SUBTYPE[trackData.type], TRACK_TYPE_TO_HANDLER_NAME[trackData.type]),
    minf(trackData)
  ]);
  var mdhd = (trackData, creationTime) => {
    const lastSample = lastPresentedSample(trackData.samples);
    const localDuration = intoTimescale(
      lastSample ? lastSample.timestamp + lastSample.duration : 0,
      trackData.timescale
    );
    const needsU64 = !isU32(creationTime) || !isU32(localDuration);
    const u32OrU64 = needsU64 ? u64 : u32;
    return fullBox("mdhd", +needsU64, 0, [
      u32OrU64(creationTime),
      // Creation time
      u32OrU64(creationTime),
      // Modification time
      u32(trackData.timescale),
      // Timescale
      u32OrU64(localDuration),
      // Duration
      u16(getLanguageCodeInt(trackData.track.metadata.languageCode ?? UNDETERMINED_LANGUAGE)),
      // Language
      u16(0)
      // Quality
    ]);
  };
  var TRACK_TYPE_TO_COMPONENT_SUBTYPE = {
    video: "vide",
    audio: "soun",
    subtitle: "text"
  };
  var TRACK_TYPE_TO_HANDLER_NAME = {
    video: "MediabunnyVideoHandler",
    audio: "MediabunnySoundHandler",
    subtitle: "MediabunnyTextHandler"
  };
  var hdlr = (hasComponentType, handlerType, name, manufacturer = "\0\0\0\0") => fullBox("hdlr", 0, 0, [
    hasComponentType ? ascii("mhlr") : u32(0),
    // Component type
    ascii(handlerType),
    // Component subtype
    ascii(manufacturer),
    // Component manufacturer
    u32(0),
    // Component flags
    u32(0),
    // Component flags mask
    ascii(name, true)
    // Component name
  ]);
  var minf = (trackData) => box("minf", void 0, [
    TRACK_TYPE_TO_HEADER_BOX[trackData.type](),
    dinf(),
    stbl(trackData)
  ]);
  var vmhd = () => fullBox("vmhd", 0, 1, [
    u16(0),
    // Graphics mode
    u16(0),
    // Opcolor R
    u16(0),
    // Opcolor G
    u16(0)
    // Opcolor B
  ]);
  var smhd = () => fullBox("smhd", 0, 0, [
    u16(0),
    // Balance
    u16(0)
    // Reserved
  ]);
  var nmhd = () => fullBox("nmhd", 0, 0);
  var TRACK_TYPE_TO_HEADER_BOX = {
    video: vmhd,
    audio: smhd,
    subtitle: nmhd
  };
  var dinf = () => box("dinf", void 0, [
    dref()
  ]);
  var dref = () => fullBox("dref", 0, 0, [
    u32(1)
    // Entry count
  ], [
    url()
  ]);
  var url = () => fullBox("url ", 0, 1);
  var stbl = (trackData) => {
    const needsCtts = trackData.compositionTimeOffsetTable.length > 1 || trackData.compositionTimeOffsetTable.some((x) => x.sampleCompositionTimeOffset !== 0);
    return box("stbl", void 0, [
      stsd(trackData),
      stts(trackData),
      needsCtts ? ctts(trackData) : null,
      needsCtts ? cslg(trackData) : null,
      stsc(trackData),
      stsz(trackData),
      stco(trackData),
      stss(trackData)
    ]);
  };
  var stsd = (trackData) => {
    let sampleDescription;
    if (trackData.type === "video") {
      sampleDescription = videoSampleDescription(
        videoCodecToBoxName(trackData.track.source._codec, trackData.info.decoderConfig.codec),
        trackData
      );
    } else if (trackData.type === "audio") {
      const boxName = audioCodecToBoxName(trackData.track.source._codec, trackData.muxer.isQuickTime);
      assert(boxName);
      sampleDescription = soundSampleDescription(
        boxName,
        trackData
      );
    } else if (trackData.type === "subtitle") {
      sampleDescription = subtitleSampleDescription(
        SUBTITLE_CODEC_TO_BOX_NAME[trackData.track.source._codec],
        trackData
      );
    }
    assert(sampleDescription);
    return fullBox("stsd", 0, 0, [
      u32(1)
      // Entry count
    ], [
      sampleDescription
    ]);
  };
  var videoSampleDescription = (compressionType, trackData) => box(compressionType, [
    Array(6).fill(0),
    // Reserved
    u16(1),
    // Data reference index
    u16(0),
    // Pre-defined
    u16(0),
    // Reserved
    Array(12).fill(0),
    // Pre-defined
    u16(trackData.info.width),
    // Width
    u16(trackData.info.height),
    // Height
    u32(4718592),
    // Horizontal resolution
    u32(4718592),
    // Vertical resolution
    u32(0),
    // Reserved
    u16(1),
    // Frame count
    Array(32).fill(0),
    // Compressor name
    u16(24),
    // Depth
    i16(65535)
    // Pre-defined
  ], [
    VIDEO_CODEC_TO_CONFIGURATION_BOX[trackData.track.source._codec](trackData),
    colorSpaceIsComplete(trackData.info.decoderConfig.colorSpace) ? colr(trackData) : null
  ]);
  var colr = (trackData) => box("colr", [
    ascii("nclx"),
    // Colour type
    u16(COLOR_PRIMARIES_MAP[trackData.info.decoderConfig.colorSpace.primaries]),
    // Colour primaries
    u16(TRANSFER_CHARACTERISTICS_MAP[trackData.info.decoderConfig.colorSpace.transfer]),
    // Transfer characteristics
    u16(MATRIX_COEFFICIENTS_MAP[trackData.info.decoderConfig.colorSpace.matrix]),
    // Matrix coefficients
    u8((trackData.info.decoderConfig.colorSpace.fullRange ? 1 : 0) << 7)
    // Full range flag
  ]);
  var avcC = (trackData) => trackData.info.decoderConfig && box("avcC", [
    // For AVC, description is an AVCDecoderConfigurationRecord, so nothing else to do here
    ...toUint8Array(trackData.info.decoderConfig.description)
  ]);
  var hvcC = (trackData) => trackData.info.decoderConfig && box("hvcC", [
    // For HEVC, description is an HEVCDecoderConfigurationRecord, so nothing else to do here
    ...toUint8Array(trackData.info.decoderConfig.description)
  ]);
  var vpcC = (trackData) => {
    if (!trackData.info.decoderConfig) {
      return null;
    }
    const decoderConfig = trackData.info.decoderConfig;
    const parts = decoderConfig.codec.split(".");
    const profile = Number(parts[1]);
    const level = Number(parts[2]);
    const bitDepth = Number(parts[3]);
    const chromaSubsampling = parts[4] ? Number(parts[4]) : 1;
    const videoFullRangeFlag = parts[8] ? Number(parts[8]) : Number(decoderConfig.colorSpace?.fullRange ?? 0);
    const thirdByte = (bitDepth << 4) + (chromaSubsampling << 1) + videoFullRangeFlag;
    const colourPrimaries = parts[5] ? Number(parts[5]) : decoderConfig.colorSpace?.primaries ? COLOR_PRIMARIES_MAP[decoderConfig.colorSpace.primaries] : 2;
    const transferCharacteristics = parts[6] ? Number(parts[6]) : decoderConfig.colorSpace?.transfer ? TRANSFER_CHARACTERISTICS_MAP[decoderConfig.colorSpace.transfer] : 2;
    const matrixCoefficients = parts[7] ? Number(parts[7]) : decoderConfig.colorSpace?.matrix ? MATRIX_COEFFICIENTS_MAP[decoderConfig.colorSpace.matrix] : 2;
    return fullBox("vpcC", 1, 0, [
      u8(profile),
      // Profile
      u8(level),
      // Level
      u8(thirdByte),
      // Bit depth, chroma subsampling, full range
      u8(colourPrimaries),
      // Colour primaries
      u8(transferCharacteristics),
      // Transfer characteristics
      u8(matrixCoefficients),
      // Matrix coefficients
      u16(0)
      // Codec initialization data size
    ]);
  };
  var av1C = (trackData) => {
    return box("av1C", generateAv1CodecConfigurationFromCodecString(trackData.info.decoderConfig.codec));
  };
  var soundSampleDescription = (compressionType, trackData) => {
    let version = 0;
    let contents;
    let sampleSizeInBits = 16;
    if (PCM_AUDIO_CODECS.includes(trackData.track.source._codec)) {
      const codec = trackData.track.source._codec;
      const { sampleSize } = parsePcmCodec(codec);
      sampleSizeInBits = 8 * sampleSize;
      if (sampleSizeInBits > 16) {
        version = 1;
      }
    }
    if (version === 0) {
      contents = [
        Array(6).fill(0),
        // Reserved
        u16(1),
        // Data reference index
        u16(version),
        // Version
        u16(0),
        // Revision level
        u32(0),
        // Vendor
        u16(trackData.info.numberOfChannels),
        // Number of channels
        u16(sampleSizeInBits),
        // Sample size (bits)
        u16(0),
        // Compression ID
        u16(0),
        // Packet size
        u16(trackData.info.sampleRate < 2 ** 16 ? trackData.info.sampleRate : 0),
        // Sample rate (upper)
        u16(0)
        // Sample rate (lower)
      ];
    } else {
      contents = [
        Array(6).fill(0),
        // Reserved
        u16(1),
        // Data reference index
        u16(version),
        // Version
        u16(0),
        // Revision level
        u32(0),
        // Vendor
        u16(trackData.info.numberOfChannels),
        // Number of channels
        u16(Math.min(sampleSizeInBits, 16)),
        // Sample size (bits)
        u16(0),
        // Compression ID
        u16(0),
        // Packet size
        u16(trackData.info.sampleRate < 2 ** 16 ? trackData.info.sampleRate : 0),
        // Sample rate (upper)
        u16(0),
        // Sample rate (lower)
        u32(1),
        // Samples per packet (must be 1 for uncompressed formats)
        u32(sampleSizeInBits / 8),
        // Bytes per packet
        u32(trackData.info.numberOfChannels * sampleSizeInBits / 8),
        // Bytes per frame
        u32(2)
        // Bytes per sample (constant in FFmpeg)
      ];
    }
    return box(compressionType, contents, [
      audioCodecToConfigurationBox(trackData.track.source._codec, trackData.muxer.isQuickTime)?.(trackData) ?? null
    ]);
  };
  var esds = (trackData) => {
    let objectTypeIndication;
    switch (trackData.track.source._codec) {
      case "aac":
        {
          objectTypeIndication = 64;
        }
        ;
        break;
      case "mp3":
        {
          objectTypeIndication = 107;
        }
        ;
        break;
      case "vorbis":
        {
          objectTypeIndication = 221;
        }
        ;
        break;
      default:
        throw new Error(`Unhandled audio codec: ${trackData.track.source._codec}`);
    }
    let bytes2 = [
      ...u8(objectTypeIndication),
      // Object type indication
      ...u8(21),
      // stream type(6bits)=5 audio, flags(2bits)=1
      ...u24(0),
      // 24bit buffer size
      ...u32(0),
      // max bitrate
      ...u32(0)
      // avg bitrate
    ];
    if (trackData.info.decoderConfig.description) {
      const description = toUint8Array(trackData.info.decoderConfig.description);
      bytes2 = [
        ...bytes2,
        ...u8(5),
        // TAG(5) = DecoderSpecificInfo
        ...variableUnsignedInt(description.byteLength),
        ...description
      ];
    }
    bytes2 = [
      ...u16(1),
      // ES_ID = 1
      ...u8(0),
      // flags etc = 0
      ...u8(4),
      // TAG(4) = ES Descriptor
      ...variableUnsignedInt(bytes2.length),
      ...bytes2,
      ...u8(6),
      // TAG(6)
      ...u8(1),
      // length
      ...u8(2)
      // data
    ];
    bytes2 = [
      ...u8(3),
      // TAG(3) = Object Descriptor
      ...variableUnsignedInt(bytes2.length),
      ...bytes2
    ];
    return fullBox("esds", 0, 0, bytes2);
  };
  var wave = (trackData) => {
    return box("wave", void 0, [
      frma(trackData),
      enda(trackData),
      box("\0\0\0\0")
      // NULL tag at the end
    ]);
  };
  var frma = (trackData) => {
    return box("frma", [
      ascii(audioCodecToBoxName(trackData.track.source._codec, trackData.muxer.isQuickTime))
    ]);
  };
  var enda = (trackData) => {
    const { littleEndian } = parsePcmCodec(trackData.track.source._codec);
    return box("enda", [
      u16(+littleEndian)
    ]);
  };
  var dOps = (trackData) => {
    let outputChannelCount = trackData.info.numberOfChannels;
    let preSkip = 3840;
    let inputSampleRate = trackData.info.sampleRate;
    let outputGain = 0;
    let channelMappingFamily = 0;
    let channelMappingTable = new Uint8Array(0);
    const description = trackData.info.decoderConfig?.description;
    if (description) {
      assert(description.byteLength >= 18);
      const bytes2 = toUint8Array(description);
      const header = parseOpusIdentificationHeader(bytes2);
      outputChannelCount = header.outputChannelCount;
      preSkip = header.preSkip;
      inputSampleRate = header.inputSampleRate;
      outputGain = header.outputGain;
      channelMappingFamily = header.channelMappingFamily;
      if (header.channelMappingTable) {
        channelMappingTable = header.channelMappingTable;
      }
    }
    return box("dOps", [
      u8(0),
      // Version
      u8(outputChannelCount),
      // OutputChannelCount
      u16(preSkip),
      // PreSkip
      u32(inputSampleRate),
      // InputSampleRate
      i16(outputGain),
      // OutputGain
      u8(channelMappingFamily),
      // ChannelMappingFamily
      ...channelMappingTable
    ]);
  };
  var dfLa = (trackData) => {
    const description = trackData.info.decoderConfig?.description;
    assert(description);
    const bytes2 = toUint8Array(description);
    return fullBox("dfLa", 0, 0, [
      ...bytes2.subarray(4)
    ]);
  };
  var pcmC = (trackData) => {
    const { littleEndian, sampleSize } = parsePcmCodec(trackData.track.source._codec);
    const formatFlags = +littleEndian;
    return fullBox("pcmC", 0, 0, [
      u8(formatFlags),
      u8(8 * sampleSize)
    ]);
  };
  var dac3 = (trackData) => {
    const frameInfo = parseAc3SyncFrame(trackData.info.firstPacket.data);
    if (!frameInfo) {
      throw new Error(
        "Couldn't extract AC-3 frame info from the audio packet. Ensure the packets contain valid AC-3 sync frames (as specified in ETSI TS 102 366)."
      );
    }
    const bytes2 = new Uint8Array(3);
    const bitstream = new Bitstream(bytes2);
    bitstream.writeBits(2, frameInfo.fscod);
    bitstream.writeBits(5, frameInfo.bsid);
    bitstream.writeBits(3, frameInfo.bsmod);
    bitstream.writeBits(3, frameInfo.acmod);
    bitstream.writeBits(1, frameInfo.lfeon);
    bitstream.writeBits(5, frameInfo.bitRateCode);
    bitstream.writeBits(5, 0);
    return box("dac3", [...bytes2]);
  };
  var dec3 = (trackData) => {
    const frameInfo = parseEac3SyncFrame(trackData.info.firstPacket.data);
    if (!frameInfo) {
      throw new Error(
        "Couldn't extract E-AC-3 frame info from the audio packet. Ensure the packets contain valid E-AC-3 sync frames (as specified in ETSI TS 102 366)."
      );
    }
    let totalBits = 16;
    for (const sub of frameInfo.substreams) {
      totalBits += 23;
      if (sub.numDepSub > 0) {
        totalBits += 9;
      } else {
        totalBits += 1;
      }
    }
    const size = Math.ceil(totalBits / 8);
    const bytes2 = new Uint8Array(size);
    const bitstream = new Bitstream(bytes2);
    bitstream.writeBits(13, frameInfo.dataRate);
    bitstream.writeBits(3, frameInfo.substreams.length - 1);
    for (const sub of frameInfo.substreams) {
      bitstream.writeBits(2, sub.fscod);
      bitstream.writeBits(5, sub.bsid);
      bitstream.writeBits(1, 0);
      bitstream.writeBits(1, 0);
      bitstream.writeBits(3, sub.bsmod);
      bitstream.writeBits(3, sub.acmod);
      bitstream.writeBits(1, sub.lfeon);
      bitstream.writeBits(3, 0);
      bitstream.writeBits(4, sub.numDepSub);
      if (sub.numDepSub > 0) {
        bitstream.writeBits(9, sub.chanLoc);
      } else {
        bitstream.writeBits(1, 0);
      }
    }
    return box("dec3", [...bytes2]);
  };
  var subtitleSampleDescription = (compressionType, trackData) => box(compressionType, [
    Array(6).fill(0),
    // Reserved
    u16(1)
    // Data reference index
  ], [
    SUBTITLE_CODEC_TO_CONFIGURATION_BOX[trackData.track.source._codec](trackData)
  ]);
  var vttC = (trackData) => box("vttC", [
    ...textEncoder.encode(trackData.info.config.description)
  ]);
  var stts = (trackData) => {
    return fullBox("stts", 0, 0, [
      u32(trackData.timeToSampleTable.length),
      // Number of entries
      trackData.timeToSampleTable.map((x) => [
        // Time-to-sample table
        u32(x.sampleCount),
        // Sample count
        u32(x.sampleDelta)
        // Sample duration
      ])
    ]);
  };
  var stss = (trackData) => {
    if (trackData.samples.every((x) => x.type === "key")) return null;
    const keySamples = [...trackData.samples.entries()].filter(([, sample]) => sample.type === "key");
    return fullBox("stss", 0, 0, [
      u32(keySamples.length),
      // Number of entries
      keySamples.map(([index]) => u32(index + 1))
      // Sync sample table
    ]);
  };
  var stsc = (trackData) => {
    return fullBox("stsc", 0, 0, [
      u32(trackData.compactlyCodedChunkTable.length),
      // Number of entries
      trackData.compactlyCodedChunkTable.map((x) => [
        // Sample-to-chunk table
        u32(x.firstChunk),
        // First chunk
        u32(x.samplesPerChunk),
        // Samples per chunk
        u32(1)
        // Sample description index
      ])
    ]);
  };
  var stsz = (trackData) => {
    if (trackData.type === "audio" && trackData.info.requiresPcmTransformation) {
      const { sampleSize } = parsePcmCodec(trackData.track.source._codec);
      return fullBox("stsz", 0, 0, [
        u32(sampleSize * trackData.info.numberOfChannels),
        // Sample size
        u32(trackData.samples.reduce((acc, x) => acc + intoTimescale(x.duration, trackData.timescale), 0))
      ]);
    }
    return fullBox("stsz", 0, 0, [
      u32(0),
      // Sample size (0 means non-constant size)
      u32(trackData.samples.length),
      // Number of entries
      trackData.samples.map((x) => u32(x.size))
      // Sample size table
    ]);
  };
  var stco = (trackData) => {
    if (trackData.finalizedChunks.length > 0 && last(trackData.finalizedChunks).offset >= 2 ** 32) {
      return fullBox("co64", 0, 0, [
        u32(trackData.finalizedChunks.length),
        // Number of entries
        trackData.finalizedChunks.map((x) => u64(x.offset))
        // Chunk offset table
      ]);
    }
    return fullBox("stco", 0, 0, [
      u32(trackData.finalizedChunks.length),
      // Number of entries
      trackData.finalizedChunks.map((x) => u32(x.offset))
      // Chunk offset table
    ]);
  };
  var ctts = (trackData) => {
    return fullBox("ctts", 1, 0, [
      u32(trackData.compositionTimeOffsetTable.length),
      // Number of entries
      trackData.compositionTimeOffsetTable.map((x) => [
        // Time-to-sample table
        u32(x.sampleCount),
        // Sample count
        i32(x.sampleCompositionTimeOffset)
        // Sample offset
      ])
    ]);
  };
  var cslg = (trackData) => {
    let leastDecodeToDisplayDelta = Infinity;
    let greatestDecodeToDisplayDelta = -Infinity;
    let compositionStartTime = Infinity;
    let compositionEndTime = -Infinity;
    assert(trackData.compositionTimeOffsetTable.length > 0);
    assert(trackData.samples.length > 0);
    for (let i = 0; i < trackData.compositionTimeOffsetTable.length; i++) {
      const entry = trackData.compositionTimeOffsetTable[i];
      leastDecodeToDisplayDelta = Math.min(leastDecodeToDisplayDelta, entry.sampleCompositionTimeOffset);
      greatestDecodeToDisplayDelta = Math.max(greatestDecodeToDisplayDelta, entry.sampleCompositionTimeOffset);
    }
    for (let i = 0; i < trackData.samples.length; i++) {
      const sample = trackData.samples[i];
      compositionStartTime = Math.min(
        compositionStartTime,
        intoTimescale(sample.timestamp, trackData.timescale)
      );
      compositionEndTime = Math.max(
        compositionEndTime,
        intoTimescale(sample.timestamp + sample.duration, trackData.timescale)
      );
    }
    const compositionToDtsShift = Math.max(-leastDecodeToDisplayDelta, 0);
    if (compositionEndTime >= 2 ** 31) {
      return null;
    }
    return fullBox("cslg", 0, 0, [
      i32(compositionToDtsShift),
      // Composition to DTS shift
      i32(leastDecodeToDisplayDelta),
      // Least decode to display delta
      i32(greatestDecodeToDisplayDelta),
      // Greatest decode to display delta
      i32(compositionStartTime),
      // Composition start time
      i32(compositionEndTime)
      // Composition end time
    ]);
  };
  var mvex = (trackDatas) => {
    return box("mvex", void 0, trackDatas.map(trex));
  };
  var trex = (trackData) => {
    return fullBox("trex", 0, 0, [
      u32(trackData.track.id),
      // Track ID
      u32(1),
      // Default sample description index
      u32(0),
      // Default sample duration
      u32(0),
      // Default sample size
      u32(0)
      // Default sample flags
    ]);
  };
  var moof = (sequenceNumber, trackDatas) => {
    return box("moof", void 0, [
      mfhd(sequenceNumber),
      ...trackDatas.map(traf)
    ]);
  };
  var mfhd = (sequenceNumber) => {
    return fullBox("mfhd", 0, 0, [
      u32(sequenceNumber)
      // Sequence number
    ]);
  };
  var fragmentSampleFlags = (sample) => {
    let byte1 = 0;
    let byte2 = 0;
    const byte3 = 0;
    const byte4 = 0;
    const sampleIsDifferenceSample = sample.type === "delta";
    byte2 |= +sampleIsDifferenceSample;
    if (sampleIsDifferenceSample) {
      byte1 |= 1;
    } else {
      byte1 |= 2;
    }
    return byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;
  };
  var traf = (trackData) => {
    return box("traf", void 0, [
      tfhd(trackData),
      tfdt(trackData),
      trun(trackData)
    ]);
  };
  var tfhd = (trackData) => {
    assert(trackData.currentChunk);
    let tfFlags = 0;
    tfFlags |= 8;
    tfFlags |= 16;
    tfFlags |= 32;
    tfFlags |= 131072;
    const referenceSample = trackData.currentChunk.samples[1] ?? trackData.currentChunk.samples[0];
    const referenceSampleInfo = {
      duration: referenceSample.timescaleUnitsToNextSample,
      size: referenceSample.size,
      flags: fragmentSampleFlags(referenceSample)
    };
    return fullBox("tfhd", 0, tfFlags, [
      u32(trackData.track.id),
      // Track ID
      u32(referenceSampleInfo.duration),
      // Default sample duration
      u32(referenceSampleInfo.size),
      // Default sample size
      u32(referenceSampleInfo.flags)
      // Default sample flags
    ]);
  };
  var tfdt = (trackData) => {
    assert(trackData.currentChunk);
    return fullBox("tfdt", 1, 0, [
      u64(intoTimescale(trackData.currentChunk.startTimestamp, trackData.timescale))
      // Base Media Decode Time
    ]);
  };
  var trun = (trackData) => {
    assert(trackData.currentChunk);
    const allSampleDurations = trackData.currentChunk.samples.map((x) => x.timescaleUnitsToNextSample);
    const allSampleSizes = trackData.currentChunk.samples.map((x) => x.size);
    const allSampleFlags = trackData.currentChunk.samples.map(fragmentSampleFlags);
    const allSampleCompositionTimeOffsets = trackData.currentChunk.samples.map((x) => intoTimescale(x.timestamp - x.decodeTimestamp, trackData.timescale));
    const uniqueSampleDurations = new Set(allSampleDurations);
    const uniqueSampleSizes = new Set(allSampleSizes);
    const uniqueSampleFlags = new Set(allSampleFlags);
    const uniqueSampleCompositionTimeOffsets = new Set(allSampleCompositionTimeOffsets);
    const firstSampleFlagsPresent = uniqueSampleFlags.size === 2 && allSampleFlags[0] !== allSampleFlags[1];
    const sampleDurationPresent = uniqueSampleDurations.size > 1;
    const sampleSizePresent = uniqueSampleSizes.size > 1;
    const sampleFlagsPresent = !firstSampleFlagsPresent && uniqueSampleFlags.size > 1;
    const sampleCompositionTimeOffsetsPresent = uniqueSampleCompositionTimeOffsets.size > 1 || [...uniqueSampleCompositionTimeOffsets].some((x) => x !== 0);
    let flags = 0;
    flags |= 1;
    flags |= 4 * +firstSampleFlagsPresent;
    flags |= 256 * +sampleDurationPresent;
    flags |= 512 * +sampleSizePresent;
    flags |= 1024 * +sampleFlagsPresent;
    flags |= 2048 * +sampleCompositionTimeOffsetsPresent;
    return fullBox("trun", 1, flags, [
      u32(trackData.currentChunk.samples.length),
      // Sample count
      u32(trackData.currentChunk.offset - trackData.currentChunk.moofOffset || 0),
      // Data offset
      firstSampleFlagsPresent ? u32(allSampleFlags[0]) : [],
      trackData.currentChunk.samples.map((_, i) => [
        sampleDurationPresent ? u32(allSampleDurations[i]) : [],
        // Sample duration
        sampleSizePresent ? u32(allSampleSizes[i]) : [],
        // Sample size
        sampleFlagsPresent ? u32(allSampleFlags[i]) : [],
        // Sample flags
        // Sample composition time offsets
        sampleCompositionTimeOffsetsPresent ? i32(allSampleCompositionTimeOffsets[i]) : []
      ])
    ]);
  };
  var mfra = (trackDatas) => {
    return box("mfra", void 0, [
      ...trackDatas.map(tfra),
      mfro()
    ]);
  };
  var tfra = (trackData, trackIndex) => {
    const version = 1;
    return fullBox("tfra", version, 0, [
      u32(trackData.track.id),
      // Track ID
      u32(63),
      // This specifies that traf number, trun number and sample number are 32-bit ints
      u32(trackData.finalizedChunks.length),
      // Number of entries
      trackData.finalizedChunks.map((chunk) => [
        u64(intoTimescale(chunk.samples[0].timestamp, trackData.timescale)),
        // Time (in presentation time)
        u64(chunk.moofOffset),
        // moof offset
        u32(trackIndex + 1),
        // traf number
        u32(1),
        // trun number
        u32(1)
        // Sample number
      ])
    ]);
  };
  var mfro = () => {
    return fullBox("mfro", 0, 0, [
      // This value needs to be overwritten manually from the outside, where the actual size of the enclosing mfra box
      // is known
      u32(0)
      // Size
    ]);
  };
  var vtte = () => box("vtte");
  var vttc = (payload, timestamp, identifier, settings, sourceId) => box("vttc", void 0, [
    sourceId !== null ? box("vsid", [i32(sourceId)]) : null,
    identifier !== null ? box("iden", [...textEncoder.encode(identifier)]) : null,
    timestamp !== null ? box("ctim", [...textEncoder.encode(formatSubtitleTimestamp(timestamp))]) : null,
    settings !== null ? box("sttg", [...textEncoder.encode(settings)]) : null,
    box("payl", [...textEncoder.encode(payload)])
  ]);
  var vtta = (notes) => box("vtta", [...textEncoder.encode(notes)]);
  var udta = (muxer) => {
    const boxes = [];
    const metadataFormat = muxer.format._options.metadataFormat ?? "auto";
    const metadataTags = muxer.output._metadataTags;
    if (metadataFormat === "mdir" || metadataFormat === "auto" && !muxer.isQuickTime) {
      const metaBox = metaMdir(metadataTags);
      if (metaBox) boxes.push(metaBox);
    } else if (metadataFormat === "mdta") {
      const metaBox = metaMdta(metadataTags);
      if (metaBox) boxes.push(metaBox);
    } else if (metadataFormat === "udta" || metadataFormat === "auto" && muxer.isQuickTime) {
      addQuickTimeMetadataTagBoxes(boxes, muxer.output._metadataTags);
    }
    if (boxes.length === 0) {
      return null;
    }
    return box("udta", void 0, boxes);
  };
  var addQuickTimeMetadataTagBoxes = (boxes, tags) => {
    for (const { key, value } of keyValueIterator(tags)) {
      switch (key) {
        case "title":
          {
            boxes.push(metadataTagStringBoxShort("\xA9nam", value));
          }
          ;
          break;
        case "description":
          {
            boxes.push(metadataTagStringBoxShort("\xA9des", value));
          }
          ;
          break;
        case "artist":
          {
            boxes.push(metadataTagStringBoxShort("\xA9ART", value));
          }
          ;
          break;
        case "album":
          {
            boxes.push(metadataTagStringBoxShort("\xA9alb", value));
          }
          ;
          break;
        case "albumArtist":
          {
            boxes.push(metadataTagStringBoxShort("albr", value));
          }
          ;
          break;
        case "genre":
          {
            boxes.push(metadataTagStringBoxShort("\xA9gen", value));
          }
          ;
          break;
        case "date":
          {
            boxes.push(metadataTagStringBoxShort("\xA9day", value.toISOString().slice(0, 10)));
          }
          ;
          break;
        case "comment":
          {
            boxes.push(metadataTagStringBoxShort("\xA9cmt", value));
          }
          ;
          break;
        case "lyrics":
          {
            boxes.push(metadataTagStringBoxShort("\xA9lyr", value));
          }
          ;
          break;
        case "raw":
          {
          }
          ;
          break;
        case "discNumber":
        case "discsTotal":
        case "trackNumber":
        case "tracksTotal":
        case "images":
          {
          }
          ;
          break;
        default:
          assertNever(key);
      }
    }
    if (tags.raw) {
      for (const key in tags.raw) {
        const value = tags.raw[key];
        if (value == null || key.length !== 4 || boxes.some((x) => x.type === key)) {
          continue;
        }
        if (typeof value === "string") {
          boxes.push(metadataTagStringBoxShort(key, value));
        } else if (value instanceof Uint8Array) {
          boxes.push(box(key, Array.from(value)));
        }
      }
    }
  };
  var metadataTagStringBoxShort = (name, value) => {
    const encoded = textEncoder.encode(value);
    return box(name, [
      u16(encoded.length),
      u16(getLanguageCodeInt("und")),
      Array.from(encoded)
    ]);
  };
  var DATA_BOX_MIME_TYPE_MAP = {
    "image/jpeg": 13,
    "image/png": 14,
    "image/bmp": 27
  };
  var generateMetadataPairs = (tags, isMdta) => {
    const pairs = [];
    for (const { key, value } of keyValueIterator(tags)) {
      switch (key) {
        case "title":
          {
            pairs.push({ key: isMdta ? "title" : "\xA9nam", value: dataStringBoxLong(value) });
          }
          ;
          break;
        case "description":
          {
            pairs.push({ key: isMdta ? "description" : "\xA9des", value: dataStringBoxLong(value) });
          }
          ;
          break;
        case "artist":
          {
            pairs.push({ key: isMdta ? "artist" : "\xA9ART", value: dataStringBoxLong(value) });
          }
          ;
          break;
        case "album":
          {
            pairs.push({ key: isMdta ? "album" : "\xA9alb", value: dataStringBoxLong(value) });
          }
          ;
          break;
        case "albumArtist":
          {
            pairs.push({ key: isMdta ? "album_artist" : "aART", value: dataStringBoxLong(value) });
          }
          ;
          break;
        case "comment":
          {
            pairs.push({ key: isMdta ? "comment" : "\xA9cmt", value: dataStringBoxLong(value) });
          }
          ;
          break;
        case "genre":
          {
            pairs.push({ key: isMdta ? "genre" : "\xA9gen", value: dataStringBoxLong(value) });
          }
          ;
          break;
        case "lyrics":
          {
            pairs.push({ key: isMdta ? "lyrics" : "\xA9lyr", value: dataStringBoxLong(value) });
          }
          ;
          break;
        case "date":
          {
            pairs.push({
              key: isMdta ? "date" : "\xA9day",
              value: dataStringBoxLong(value.toISOString().slice(0, 10))
            });
          }
          ;
          break;
        case "images":
          {
            for (const image of value) {
              if (image.kind !== "coverFront") {
                continue;
              }
              pairs.push({ key: "covr", value: box("data", [
                u32(DATA_BOX_MIME_TYPE_MAP[image.mimeType] ?? 0),
                // Type indicator
                u32(0),
                // Locale indicator
                Array.from(image.data)
                // Kinda slow, hopefully temp
              ]) });
            }
          }
          ;
          break;
        case "trackNumber":
          {
            if (isMdta) {
              const string = tags.tracksTotal !== void 0 ? `${value}/${tags.tracksTotal}` : value.toString();
              pairs.push({ key: "track", value: dataStringBoxLong(string) });
            } else {
              pairs.push({ key: "trkn", value: box("data", [
                u32(0),
                // 8 bytes empty
                u32(0),
                u16(0),
                // Empty
                u16(value),
                u16(tags.tracksTotal ?? 0),
                u16(0)
                // Empty
              ]) });
            }
          }
          ;
          break;
        case "discNumber":
          {
            if (!isMdta) {
              pairs.push({ key: "disc", value: box("data", [
                u32(0),
                // 8 bytes empty
                u32(0),
                u16(0),
                // Empty
                u16(value),
                u16(tags.discsTotal ?? 0),
                u16(0)
                // Empty
              ]) });
            }
          }
          ;
          break;
        case "tracksTotal":
        case "discsTotal":
          {
          }
          ;
          break;
        case "raw":
          {
          }
          ;
          break;
        default:
          assertNever(key);
      }
    }
    if (tags.raw) {
      for (const key in tags.raw) {
        const value = tags.raw[key];
        if (value == null || !isMdta && key.length !== 4 || pairs.some((x) => x.key === key)) {
          continue;
        }
        if (typeof value === "string") {
          pairs.push({ key, value: dataStringBoxLong(value) });
        } else if (value instanceof Uint8Array) {
          pairs.push({ key, value: box("data", [
            u32(0),
            // Type indicator
            u32(0),
            // Locale indicator
            Array.from(value)
          ]) });
        } else if (value instanceof RichImageData) {
          pairs.push({ key, value: box("data", [
            u32(DATA_BOX_MIME_TYPE_MAP[value.mimeType] ?? 0),
            // Type indicator
            u32(0),
            // Locale indicator
            Array.from(value.data)
            // Kinda slow, hopefully temp
          ]) });
        }
      }
    }
    return pairs;
  };
  var metaMdir = (tags) => {
    const pairs = generateMetadataPairs(tags, false);
    if (pairs.length === 0) {
      return null;
    }
    return fullBox("meta", 0, 0, void 0, [
      hdlr(false, "mdir", "", "appl"),
      // mdir handler
      box("ilst", void 0, pairs.map((pair) => box(pair.key, void 0, [pair.value])))
      // Item list without keys box
    ]);
  };
  var metaMdta = (tags) => {
    const pairs = generateMetadataPairs(tags, true);
    if (pairs.length === 0) {
      return null;
    }
    return box("meta", void 0, [
      hdlr(false, "mdta", ""),
      // mdta handler
      fullBox("keys", 0, 0, [
        u32(pairs.length)
      ], pairs.map((pair) => box("mdta", [
        // Hacky since these aren't boxes technically, but if not box why box-shaped?
        ...textEncoder.encode(pair.key)
      ]))),
      box("ilst", void 0, pairs.map((pair, i) => {
        const boxName = String.fromCharCode(...u32(i + 1));
        return box(boxName, void 0, [pair.value]);
      }))
    ]);
  };
  var dataStringBoxLong = (value) => {
    return box("data", [
      u32(1),
      // Type indicator (UTF-8)
      u32(0),
      // Locale indicator
      ...textEncoder.encode(value)
    ]);
  };
  var videoCodecToBoxName = (codec, fullCodecString) => {
    switch (codec) {
      case "avc":
        return fullCodecString.startsWith("avc3") ? "avc3" : "avc1";
      case "hevc":
        return "hvc1";
      case "vp8":
        return "vp08";
      case "vp9":
        return "vp09";
      case "av1":
        return "av01";
    }
  };
  var VIDEO_CODEC_TO_CONFIGURATION_BOX = {
    avc: avcC,
    hevc: hvcC,
    vp8: vpcC,
    vp9: vpcC,
    av1: av1C
  };
  var audioCodecToBoxName = (codec, isQuickTime) => {
    switch (codec) {
      case "aac":
        return "mp4a";
      case "mp3":
        return "mp4a";
      case "opus":
        return "Opus";
      case "vorbis":
        return "mp4a";
      case "flac":
        return "fLaC";
      case "ulaw":
        return "ulaw";
      case "alaw":
        return "alaw";
      case "pcm-u8":
        return "raw ";
      case "pcm-s8":
        return "sowt";
      case "ac3":
        return "ac-3";
      case "eac3":
        return "ec-3";
    }
    if (isQuickTime) {
      switch (codec) {
        case "pcm-s16":
          return "sowt";
        case "pcm-s16be":
          return "twos";
        case "pcm-s24":
          return "in24";
        case "pcm-s24be":
          return "in24";
        case "pcm-s32":
          return "in32";
        case "pcm-s32be":
          return "in32";
        case "pcm-f32":
          return "fl32";
        case "pcm-f32be":
          return "fl32";
        case "pcm-f64":
          return "fl64";
        case "pcm-f64be":
          return "fl64";
      }
    } else {
      switch (codec) {
        case "pcm-s16":
          return "ipcm";
        case "pcm-s16be":
          return "ipcm";
        case "pcm-s24":
          return "ipcm";
        case "pcm-s24be":
          return "ipcm";
        case "pcm-s32":
          return "ipcm";
        case "pcm-s32be":
          return "ipcm";
        case "pcm-f32":
          return "fpcm";
        case "pcm-f32be":
          return "fpcm";
        case "pcm-f64":
          return "fpcm";
        case "pcm-f64be":
          return "fpcm";
      }
    }
  };
  var audioCodecToConfigurationBox = (codec, isQuickTime) => {
    switch (codec) {
      case "aac":
        return esds;
      case "mp3":
        return esds;
      case "opus":
        return dOps;
      case "vorbis":
        return esds;
      case "flac":
        return dfLa;
      case "ac3":
        return dac3;
      case "eac3":
        return dec3;
    }
    if (isQuickTime) {
      switch (codec) {
        case "pcm-s24":
          return wave;
        case "pcm-s24be":
          return wave;
        case "pcm-s32":
          return wave;
        case "pcm-s32be":
          return wave;
        case "pcm-f32":
          return wave;
        case "pcm-f32be":
          return wave;
        case "pcm-f64":
          return wave;
        case "pcm-f64be":
          return wave;
      }
    } else {
      switch (codec) {
        case "pcm-s16":
          return pcmC;
        case "pcm-s16be":
          return pcmC;
        case "pcm-s24":
          return pcmC;
        case "pcm-s24be":
          return pcmC;
        case "pcm-s32":
          return pcmC;
        case "pcm-s32be":
          return pcmC;
        case "pcm-f32":
          return pcmC;
        case "pcm-f32be":
          return pcmC;
        case "pcm-f64":
          return pcmC;
        case "pcm-f64be":
          return pcmC;
      }
    }
    return null;
  };
  var SUBTITLE_CODEC_TO_BOX_NAME = {
    webvtt: "wvtt"
  };
  var SUBTITLE_CODEC_TO_CONFIGURATION_BOX = {
    webvtt: vttC
  };
  var getLanguageCodeInt = (code) => {
    assert(code.length === 3);
    ;
    let language = 0;
    for (let i = 0; i < 3; i++) {
      language <<= 5;
      language += code.charCodeAt(i) - 96;
    }
    return language;
  };

  // src/writer.ts
  var Writer = class {
    constructor() {
      /** Setting this to true will cause the writer to ensure data is written in a strictly monotonic, streamable way. */
      this.ensureMonotonicity = false;
      this.trackedWrites = null;
      this.trackedStart = -1;
      this.trackedEnd = -1;
    }
    start() {
    }
    maybeTrackWrites(data) {
      if (!this.trackedWrites) {
        return;
      }
      let pos = this.getPos();
      if (pos < this.trackedStart) {
        if (pos + data.byteLength <= this.trackedStart) {
          return;
        }
        data = data.subarray(this.trackedStart - pos);
        pos = 0;
      }
      const neededSize = pos + data.byteLength - this.trackedStart;
      let newLength = this.trackedWrites.byteLength;
      while (newLength < neededSize) {
        newLength *= 2;
      }
      if (newLength !== this.trackedWrites.byteLength) {
        const copy = new Uint8Array(newLength);
        copy.set(this.trackedWrites, 0);
        this.trackedWrites = copy;
      }
      this.trackedWrites.set(data, pos - this.trackedStart);
      this.trackedEnd = Math.max(this.trackedEnd, pos + data.byteLength);
    }
    startTrackingWrites() {
      this.trackedWrites = new Uint8Array(2 ** 10);
      this.trackedStart = this.getPos();
      this.trackedEnd = this.trackedStart;
    }
    stopTrackingWrites() {
      if (!this.trackedWrites) {
        throw new Error("Internal error: Can't get tracked writes since nothing was tracked.");
      }
      const slice = this.trackedWrites.subarray(0, this.trackedEnd - this.trackedStart);
      const result = {
        data: slice,
        start: this.trackedStart,
        end: this.trackedEnd
      };
      this.trackedWrites = null;
      return result;
    }
  };
  var ARRAY_BUFFER_INITIAL_SIZE = 2 ** 16;
  var ARRAY_BUFFER_MAX_SIZE = 2 ** 32;
  var BufferTargetWriter = class extends Writer {
    constructor(target) {
      super();
      this.pos = 0;
      this.maxPos = 0;
      this.target = target;
      this.supportsResize = "resize" in new ArrayBuffer(0);
      if (this.supportsResize) {
        try {
          this.buffer = new ArrayBuffer(ARRAY_BUFFER_INITIAL_SIZE, { maxByteLength: ARRAY_BUFFER_MAX_SIZE });
        } catch {
          this.buffer = new ArrayBuffer(ARRAY_BUFFER_INITIAL_SIZE);
          this.supportsResize = false;
        }
      } else {
        this.buffer = new ArrayBuffer(ARRAY_BUFFER_INITIAL_SIZE);
      }
      this.bytes = new Uint8Array(this.buffer);
    }
    ensureSize(size) {
      let newLength = this.buffer.byteLength;
      while (newLength < size) newLength *= 2;
      if (newLength === this.buffer.byteLength) return;
      if (newLength > ARRAY_BUFFER_MAX_SIZE) {
        throw new Error(
          `ArrayBuffer exceeded maximum size of ${ARRAY_BUFFER_MAX_SIZE} bytes. Please consider using another target.`
        );
      }
      if (this.supportsResize) {
        this.buffer.resize(newLength);
      } else {
        const newBuffer = new ArrayBuffer(newLength);
        const newBytes = new Uint8Array(newBuffer);
        newBytes.set(this.bytes, 0);
        this.buffer = newBuffer;
        this.bytes = newBytes;
      }
    }
    write(data) {
      this.maybeTrackWrites(data);
      this.ensureSize(this.pos + data.byteLength);
      this.bytes.set(data, this.pos);
      this.target.onwrite?.(this.pos, this.pos + data.byteLength);
      this.pos += data.byteLength;
      this.maxPos = Math.max(this.maxPos, this.pos);
    }
    seek(newPos) {
      this.pos = newPos;
    }
    getPos() {
      return this.pos;
    }
    async flush() {
    }
    async finalize() {
      this.ensureSize(this.pos);
      this.target.buffer = this.buffer.slice(0, Math.max(this.maxPos, this.pos));
    }
    async close() {
    }
    getSlice(start, end) {
      return this.bytes.slice(start, end);
    }
  };
  var DEFAULT_CHUNK_SIZE = 2 ** 24;
  var MAX_CHUNKS_AT_ONCE = 2;
  var StreamTargetWriter = class extends Writer {
    constructor(target) {
      super();
      this.pos = 0;
      this.sections = [];
      this.lastWriteEnd = 0;
      this.lastFlushEnd = 0;
      this.writer = null;
      this.writeError = null;
      /**
       * The data is divided up into fixed-size chunks, whose contents are first filled in RAM and then flushed out.
       * A chunk is flushed if all of its contents have been written.
       */
      this.chunks = [];
      this.target = target;
      this.chunked = target._options.chunked ?? false;
      this.chunkSize = target._options.chunkSize ?? DEFAULT_CHUNK_SIZE;
    }
    start() {
      this.writer = this.target._writable.getWriter();
    }
    write(data) {
      if (this.pos > this.lastWriteEnd) {
        const paddingBytesNeeded = this.pos - this.lastWriteEnd;
        this.pos = this.lastWriteEnd;
        this.write(new Uint8Array(paddingBytesNeeded));
      }
      this.maybeTrackWrites(data);
      this.sections.push({
        data: data.slice(),
        start: this.pos
      });
      this.target.onwrite?.(this.pos, this.pos + data.byteLength);
      this.pos += data.byteLength;
      this.lastWriteEnd = Math.max(this.lastWriteEnd, this.pos);
    }
    seek(newPos) {
      this.pos = newPos;
    }
    getPos() {
      return this.pos;
    }
    async flush() {
      if (this.writeError !== null) {
        throw this.writeError;
      }
      if (this.pos > this.lastWriteEnd) {
        const paddingBytesNeeded = this.pos - this.lastWriteEnd;
        this.pos = this.lastWriteEnd;
        this.write(new Uint8Array(paddingBytesNeeded));
      }
      assert(this.writer);
      if (this.sections.length === 0) return;
      const chunks = [];
      const sorted = [...this.sections].sort((a, b) => a.start - b.start);
      chunks.push({
        start: sorted[0].start,
        size: sorted[0].data.byteLength
      });
      for (let i = 1; i < sorted.length; i++) {
        const lastChunk = chunks[chunks.length - 1];
        const section = sorted[i];
        if (section.start <= lastChunk.start + lastChunk.size) {
          lastChunk.size = Math.max(lastChunk.size, section.start + section.data.byteLength - lastChunk.start);
        } else {
          chunks.push({
            start: section.start,
            size: section.data.byteLength
          });
        }
      }
      for (const chunk of chunks) {
        chunk.data = new Uint8Array(chunk.size);
        for (const section of this.sections) {
          if (chunk.start <= section.start && section.start < chunk.start + chunk.size) {
            chunk.data.set(section.data, section.start - chunk.start);
          }
        }
        if (this.writer.desiredSize !== null && this.writer.desiredSize <= 0) {
          await this.writer.ready;
        }
        if (this.chunked) {
          this.writeDataIntoChunks(chunk.data, chunk.start);
          this.tryToFlushChunks();
        } else {
          if (this.ensureMonotonicity && chunk.start !== this.lastFlushEnd) {
            throw new Error("Internal error: Monotonicity violation.");
          }
          void this.writer.write({
            type: "write",
            data: chunk.data,
            position: chunk.start
          }).catch((error) => {
            this.writeError ??= error;
          });
          this.lastFlushEnd = chunk.start + chunk.data.byteLength;
        }
      }
      this.sections.length = 0;
    }
    writeDataIntoChunks(data, position) {
      let chunkIndex = this.chunks.findIndex((x) => x.start <= position && position < x.start + this.chunkSize);
      if (chunkIndex === -1) chunkIndex = this.createChunk(position);
      const chunk = this.chunks[chunkIndex];
      const relativePosition = position - chunk.start;
      const toWrite = data.subarray(0, Math.min(this.chunkSize - relativePosition, data.byteLength));
      chunk.data.set(toWrite, relativePosition);
      const section = {
        start: relativePosition,
        end: relativePosition + toWrite.byteLength
      };
      this.insertSectionIntoChunk(chunk, section);
      if (chunk.written[0].start === 0 && chunk.written[0].end === this.chunkSize) {
        chunk.shouldFlush = true;
      }
      if (this.chunks.length > MAX_CHUNKS_AT_ONCE) {
        for (let i = 0; i < this.chunks.length - 1; i++) {
          this.chunks[i].shouldFlush = true;
        }
        this.tryToFlushChunks();
      }
      if (toWrite.byteLength < data.byteLength) {
        this.writeDataIntoChunks(data.subarray(toWrite.byteLength), position + toWrite.byteLength);
      }
    }
    insertSectionIntoChunk(chunk, section) {
      let low = 0;
      let high = chunk.written.length - 1;
      let index = -1;
      while (low <= high) {
        const mid = Math.floor(low + (high - low + 1) / 2);
        if (chunk.written[mid].start <= section.start) {
          low = mid + 1;
          index = mid;
        } else {
          high = mid - 1;
        }
      }
      chunk.written.splice(index + 1, 0, section);
      if (index === -1 || chunk.written[index].end < section.start) index++;
      while (index < chunk.written.length - 1 && chunk.written[index].end >= chunk.written[index + 1].start) {
        chunk.written[index].end = Math.max(chunk.written[index].end, chunk.written[index + 1].end);
        chunk.written.splice(index + 1, 1);
      }
    }
    createChunk(includesPosition) {
      const start = Math.floor(includesPosition / this.chunkSize) * this.chunkSize;
      const chunk = {
        start,
        data: new Uint8Array(this.chunkSize),
        written: [],
        shouldFlush: false
      };
      this.chunks.push(chunk);
      this.chunks.sort((a, b) => a.start - b.start);
      return this.chunks.indexOf(chunk);
    }
    tryToFlushChunks(force = false) {
      assert(this.writer);
      for (let i = 0; i < this.chunks.length; i++) {
        const chunk = this.chunks[i];
        if (!chunk.shouldFlush && !force) continue;
        for (const section of chunk.written) {
          const position = chunk.start + section.start;
          if (this.ensureMonotonicity && position !== this.lastFlushEnd) {
            throw new Error("Internal error: Monotonicity violation.");
          }
          void this.writer.write({
            type: "write",
            data: chunk.data.subarray(section.start, section.end),
            position
          }).catch((error) => {
            this.writeError ??= error;
          });
          this.lastFlushEnd = chunk.start + section.end;
        }
        this.chunks.splice(i--, 1);
      }
    }
    async finalize() {
      if (this.chunked) {
        this.tryToFlushChunks(true);
      }
      if (this.writeError !== null) {
        throw this.writeError;
      }
      assert(this.writer);
      await this.writer.ready;
      return this.writer.close();
    }
    async close() {
      return this.writer?.close();
    }
  };
  var NullTargetWriter = class extends Writer {
    constructor(target) {
      super();
      this.target = target;
      this.pos = 0;
    }
    write(data) {
      this.maybeTrackWrites(data);
      this.target.onwrite?.(this.pos, this.pos + data.byteLength);
      this.pos += data.byteLength;
    }
    getPos() {
      return this.pos;
    }
    seek(newPos) {
      this.pos = newPos;
    }
    async flush() {
    }
    async finalize() {
    }
    async close() {
    }
  };

  // src/target.ts
  var nodeAlias2 = __toESM(require_node(), 1);
  var node2 = typeof nodeAlias2 !== "undefined" ? nodeAlias2 : void 0;
  var Target = class {
    constructor() {
      /** @internal */
      this._output = null;
      /**
       * Called each time data is written to the target. Will be called with the byte range into which data was written.
       *
       * Use this callback to track the size of the output file as it grows. But be warned, this function is chatty and
       * gets called *extremely* often.
       */
      this.onwrite = null;
    }
  };
  var BufferTarget = class extends Target {
    constructor() {
      super(...arguments);
      /** Stores the final output buffer. Until the output is finalized, this will be `null`. */
      this.buffer = null;
    }
    /** @internal */
    _createWriter() {
      return new BufferTargetWriter(this);
    }
  };
  var StreamTarget = class extends Target {
    /** Creates a new {@link StreamTarget} which writes to the specified `writable`. */
    constructor(writable, options = {}) {
      super();
      if (!(writable instanceof WritableStream)) {
        throw new TypeError("StreamTarget requires a WritableStream instance.");
      }
      if (options != null && typeof options !== "object") {
        throw new TypeError("StreamTarget options, when provided, must be an object.");
      }
      if (options.chunked !== void 0 && typeof options.chunked !== "boolean") {
        throw new TypeError("options.chunked, when provided, must be a boolean.");
      }
      if (options.chunkSize !== void 0 && (!Number.isInteger(options.chunkSize) || options.chunkSize < 1024)) {
        throw new TypeError("options.chunkSize, when provided, must be an integer and not smaller than 1024.");
      }
      this._writable = writable;
      this._options = options;
    }
    /** @internal */
    _createWriter() {
      return new StreamTargetWriter(this);
    }
  };
  var FilePathTarget = class extends Target {
    /** Creates a new {@link FilePathTarget} that writes to the file at the specified file path. */
    constructor(filePath, options = {}) {
      if (typeof filePath !== "string") {
        throw new TypeError("filePath must be a string.");
      }
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      super();
      /** @internal */
      this._fileHandle = null;
      const writable = new WritableStream({
        start: async () => {
          this._fileHandle = await node2.fs.open(filePath, "w");
        },
        write: async (chunk) => {
          assert(this._fileHandle);
          await this._fileHandle.write(chunk.data, 0, chunk.data.byteLength, chunk.position);
        },
        close: async () => {
          if (this._fileHandle) {
            await this._fileHandle.close();
            this._fileHandle = null;
          }
        }
      });
      this._streamTarget = new StreamTarget(writable, {
        chunked: true,
        ...options
      });
      this._streamTarget._output = this._output;
    }
    /** @internal */
    _createWriter() {
      return this._streamTarget._createWriter();
    }
  };
  var NullTarget = class extends Target {
    /** @internal */
    _createWriter() {
      return new NullTargetWriter(this);
    }
  };

  // src/isobmff/isobmff-muxer.ts
  var GLOBAL_TIMESCALE = 1e3;
  var TIMESTAMP_OFFSET = 2082844800;
  var getTrackMetadata = (trackData) => {
    const metadata = {};
    const track = trackData.track;
    if (track.metadata.name !== void 0) {
      metadata.name = track.metadata.name;
    }
    return metadata;
  };
  var intoTimescale = (timeInSeconds, timescale, round = true) => {
    const value = timeInSeconds * timescale;
    return round ? Math.round(value) : value;
  };
  var IsobmffMuxer2 = class extends Muxer {
    constructor(output, format) {
      super(output);
      this.auxTarget = new BufferTarget();
      this.auxWriter = this.auxTarget._createWriter();
      this.auxBoxWriter = new IsobmffBoxWriter(this.auxWriter);
      this.mdat = null;
      this.ftypSize = null;
      this.trackDatas = [];
      this.allTracksKnown = promiseWithResolvers();
      this.creationTime = Math.floor(Date.now() / 1e3) + TIMESTAMP_OFFSET;
      this.finalizedChunks = [];
      this.nextFragmentNumber = 1;
      // Only relevant for fragmented files, to make sure new fragments start with the highest timestamp seen so far
      this.maxWrittenTimestamp = -Infinity;
      this.format = format;
      this.writer = output._writer;
      this.boxWriter = new IsobmffBoxWriter(this.writer);
      this.isQuickTime = format instanceof MovOutputFormat;
      const fastStartDefault = this.writer instanceof BufferTargetWriter ? "in-memory" : false;
      this.fastStart = format._options.fastStart ?? fastStartDefault;
      this.isFragmented = this.fastStart === "fragmented";
      if (this.fastStart === "in-memory" || this.isFragmented) {
        this.writer.ensureMonotonicity = true;
      }
      this.minimumFragmentDuration = format._options.minimumFragmentDuration ?? 1;
    }
    async start() {
      const release = await this.mutex.acquire();
      const holdsAvc = this.output._tracks.some((x) => x.type === "video" && x.source._codec === "avc");
      {
        if (this.format._options.onFtyp) {
          this.writer.startTrackingWrites();
        }
        this.boxWriter.writeBox(ftyp({
          isQuickTime: this.isQuickTime,
          holdsAvc,
          fragmented: this.isFragmented
        }));
        if (this.format._options.onFtyp) {
          const { data, start } = this.writer.stopTrackingWrites();
          this.format._options.onFtyp(data, start);
        }
      }
      this.ftypSize = this.writer.getPos();
      if (this.fastStart === "in-memory") {
      } else if (this.fastStart === "reserve") {
        for (const track of this.output._tracks) {
          if (track.metadata.maximumPacketCount === void 0) {
            throw new Error(
              "All tracks must specify maximumPacketCount in their metadata when using fastStart: 'reserve'."
            );
          }
        }
      } else if (this.isFragmented) {
      } else {
        if (this.format._options.onMdat) {
          this.writer.startTrackingWrites();
        }
        this.mdat = mdat(true);
        this.boxWriter.writeBox(this.mdat);
      }
      await this.writer.flush();
      release();
    }
    allTracksAreKnown() {
      for (const track of this.output._tracks) {
        if (!track.source._closed && !this.trackDatas.some((x) => x.track === track)) {
          return false;
        }
      }
      return true;
    }
    async getMimeType() {
      await this.allTracksKnown.promise;
      const codecStrings = this.trackDatas.map((trackData) => {
        if (trackData.type === "video") {
          return trackData.info.decoderConfig.codec;
        } else if (trackData.type === "audio") {
          return trackData.info.decoderConfig.codec;
        } else {
          const map = {
            webvtt: "wvtt"
          };
          return map[trackData.track.source._codec];
        }
      });
      return buildIsobmffMimeType({
        isQuickTime: this.isQuickTime,
        hasVideo: this.trackDatas.some((x) => x.type === "video"),
        hasAudio: this.trackDatas.some((x) => x.type === "audio"),
        codecStrings
      });
    }
    getVideoTrackData(track, packet, meta) {
      const existingTrackData = this.trackDatas.find((x) => x.track === track);
      if (existingTrackData) {
        return existingTrackData;
      }
      validateVideoChunkMetadata(meta);
      assert(meta);
      assert(meta.decoderConfig);
      const decoderConfig = { ...meta.decoderConfig };
      assert(decoderConfig.codedWidth !== void 0);
      assert(decoderConfig.codedHeight !== void 0);
      let requiresAnnexBTransformation = false;
      if (track.source._codec === "avc" && !decoderConfig.description) {
        const decoderConfigurationRecord = extractAvcDecoderConfigurationRecord(packet.data);
        if (!decoderConfigurationRecord) {
          throw new Error(
            "Couldn't extract an AVCDecoderConfigurationRecord from the AVC packet. Make sure the packets are in Annex B format (as specified in ITU-T-REC-H.264) when not providing a description, or provide a description (must be an AVCDecoderConfigurationRecord as specified in ISO 14496-15) and ensure the packets are in AVCC format."
          );
        }
        decoderConfig.description = serializeAvcDecoderConfigurationRecord(decoderConfigurationRecord);
        requiresAnnexBTransformation = true;
      } else if (track.source._codec === "hevc" && !decoderConfig.description) {
        const decoderConfigurationRecord = extractHevcDecoderConfigurationRecord(packet.data);
        if (!decoderConfigurationRecord) {
          throw new Error(
            "Couldn't extract an HEVCDecoderConfigurationRecord from the HEVC packet. Make sure the packets are in Annex B format (as specified in ITU-T-REC-H.265) when not providing a description, or provide a description (must be an HEVCDecoderConfigurationRecord as specified in ISO 14496-15) and ensure the packets are in HEVC format."
          );
        }
        decoderConfig.description = serializeHevcDecoderConfigurationRecord(decoderConfigurationRecord);
        requiresAnnexBTransformation = true;
      }
      const timescale = computeRationalApproximation(1 / (track.metadata.frameRate ?? 57600), 1e6).denominator;
      const newTrackData = {
        muxer: this,
        track,
        type: "video",
        info: {
          width: decoderConfig.codedWidth,
          height: decoderConfig.codedHeight,
          decoderConfig,
          requiresAnnexBTransformation
        },
        timescale,
        samples: [],
        sampleQueue: [],
        timestampProcessingQueue: [],
        timeToSampleTable: [],
        compositionTimeOffsetTable: [],
        lastTimescaleUnits: null,
        lastSample: null,
        finalizedChunks: [],
        currentChunk: null,
        compactlyCodedChunkTable: []
      };
      this.trackDatas.push(newTrackData);
      this.trackDatas.sort((a, b) => a.track.id - b.track.id);
      if (this.allTracksAreKnown()) {
        this.allTracksKnown.resolve();
      }
      return newTrackData;
    }
    getAudioTrackData(track, packet, meta) {
      const existingTrackData = this.trackDatas.find((x) => x.track === track);
      if (existingTrackData) {
        return existingTrackData;
      }
      validateAudioChunkMetadata(meta);
      assert(meta);
      assert(meta.decoderConfig);
      const decoderConfig = { ...meta.decoderConfig };
      let requiresAdtsStripping = false;
      if (track.source._codec === "aac" && !decoderConfig.description) {
        const adtsFrame = readAdtsFrameHeader(FileSlice4.tempFromBytes(packet.data));
        if (!adtsFrame) {
          throw new Error(
            "Couldn't parse ADTS header from the AAC packet. Make sure the packets are in ADTS format (as specified in ISO 13818-7) when not providing a description, or provide a description (must be an AudioSpecificConfig as specified in ISO 14496-3) and ensure the packets are raw AAC data."
          );
        }
        const sampleRate = aacFrequencyTable[adtsFrame.samplingFrequencyIndex];
        const numberOfChannels = aacChannelMap[adtsFrame.channelConfiguration];
        if (sampleRate === void 0 || numberOfChannels === void 0) {
          throw new Error("Invalid ADTS frame header.");
        }
        decoderConfig.description = buildAacAudioSpecificConfig({
          objectType: adtsFrame.objectType,
          sampleRate,
          numberOfChannels
        });
        requiresAdtsStripping = true;
      }
      const newTrackData = {
        muxer: this,
        track,
        type: "audio",
        info: {
          numberOfChannels: meta.decoderConfig.numberOfChannels,
          sampleRate: meta.decoderConfig.sampleRate,
          decoderConfig,
          requiresPcmTransformation: !this.isFragmented && PCM_AUDIO_CODECS.includes(track.source._codec),
          requiresAdtsStripping,
          firstPacket: packet
        },
        timescale: decoderConfig.sampleRate,
        samples: [],
        sampleQueue: [],
        timestampProcessingQueue: [],
        timeToSampleTable: [],
        compositionTimeOffsetTable: [],
        lastTimescaleUnits: null,
        lastSample: null,
        finalizedChunks: [],
        currentChunk: null,
        compactlyCodedChunkTable: []
      };
      this.trackDatas.push(newTrackData);
      this.trackDatas.sort((a, b) => a.track.id - b.track.id);
      if (this.allTracksAreKnown()) {
        this.allTracksKnown.resolve();
      }
      return newTrackData;
    }
    getSubtitleTrackData(track, meta) {
      const existingTrackData = this.trackDatas.find((x) => x.track === track);
      if (existingTrackData) {
        return existingTrackData;
      }
      validateSubtitleMetadata(meta);
      assert(meta);
      assert(meta.config);
      const newTrackData = {
        muxer: this,
        track,
        type: "subtitle",
        info: {
          config: meta.config
        },
        timescale: 1e3,
        // Reasonable
        samples: [],
        sampleQueue: [],
        timestampProcessingQueue: [],
        timeToSampleTable: [],
        compositionTimeOffsetTable: [],
        lastTimescaleUnits: null,
        lastSample: null,
        finalizedChunks: [],
        currentChunk: null,
        compactlyCodedChunkTable: [],
        lastCueEndTimestamp: 0,
        cueQueue: [],
        nextSourceId: 0,
        cueToSourceId: /* @__PURE__ */ new WeakMap()
      };
      this.trackDatas.push(newTrackData);
      this.trackDatas.sort((a, b) => a.track.id - b.track.id);
      if (this.allTracksAreKnown()) {
        this.allTracksKnown.resolve();
      }
      return newTrackData;
    }
    async addEncodedVideoPacket(track, packet, meta) {
      const release = await this.mutex.acquire();
      try {
        const trackData = this.getVideoTrackData(track, packet, meta);
        let packetData = packet.data;
        if (trackData.info.requiresAnnexBTransformation) {
          const nalUnits = [...iterateNalUnitsInAnnexB(packetData)].map((loc) => packetData.subarray(loc.offset, loc.offset + loc.length));
          if (nalUnits.length === 0) {
            throw new Error(
              "Failed to transform packet data. Make sure all packets are provided in Annex B format, as specified in ITU-T-REC-H.264 and ITU-T-REC-H.265."
            );
          }
          packetData = concatNalUnitsInLengthPrefixed(nalUnits, 4);
        }
        const timestamp = this.validateAndNormalizeTimestamp(
          trackData.track,
          packet.timestamp,
          packet.type === "key"
        );
        const internalSample = this.createSampleForTrack(
          trackData,
          packetData,
          timestamp,
          packet.duration,
          packet.type
        );
        await this.registerSample(trackData, internalSample);
      } finally {
        release();
      }
    }
    async addEncodedAudioPacket(track, packet, meta) {
      const release = await this.mutex.acquire();
      try {
        const trackData = this.getAudioTrackData(track, packet, meta);
        let packetData = packet.data;
        if (trackData.info.requiresAdtsStripping) {
          const adtsFrame = readAdtsFrameHeader(FileSlice4.tempFromBytes(packetData));
          if (!adtsFrame) {
            throw new Error("Expected ADTS frame, didn't get one.");
          }
          const headerLength = adtsFrame.crcCheck === null ? MIN_ADTS_FRAME_HEADER_SIZE : MAX_ADTS_FRAME_HEADER_SIZE;
          packetData = packetData.subarray(headerLength);
        }
        const timestamp = this.validateAndNormalizeTimestamp(
          trackData.track,
          packet.timestamp,
          packet.type === "key"
        );
        const internalSample = this.createSampleForTrack(
          trackData,
          packetData,
          timestamp,
          packet.duration,
          packet.type
        );
        if (trackData.info.requiresPcmTransformation) {
          await this.maybePadWithSilence(trackData, timestamp);
        }
        await this.registerSample(trackData, internalSample);
      } finally {
        release();
      }
    }
    async maybePadWithSilence(trackData, untilTimestamp) {
      const lastSample = last(trackData.samples);
      const lastEndTimestamp = lastSample ? lastSample.timestamp + lastSample.duration : 0;
      const delta = untilTimestamp - lastEndTimestamp;
      const deltaInTimescale = intoTimescale(delta, trackData.timescale);
      if (deltaInTimescale > 0) {
        const { sampleSize, silentValue } = parsePcmCodec(
          trackData.info.decoderConfig.codec
        );
        const samplesNeeded = deltaInTimescale * trackData.info.numberOfChannels;
        const data = new Uint8Array(sampleSize * samplesNeeded).fill(silentValue);
        const paddingSample = this.createSampleForTrack(
          trackData,
          new Uint8Array(data.buffer),
          lastEndTimestamp,
          delta,
          "key"
        );
        await this.registerSample(trackData, paddingSample);
      }
    }
    async addSubtitleCue(track, cue, meta) {
      const release = await this.mutex.acquire();
      try {
        const trackData = this.getSubtitleTrackData(track, meta);
        this.validateAndNormalizeTimestamp(trackData.track, cue.timestamp, true);
        if (track.source._codec === "webvtt") {
          trackData.cueQueue.push(cue);
          await this.processWebVTTCues(trackData, cue.timestamp);
        } else {
        }
      } finally {
        release();
      }
    }
    async processWebVTTCues(trackData, until) {
      while (trackData.cueQueue.length > 0) {
        const timestamps = /* @__PURE__ */ new Set([]);
        for (const cue of trackData.cueQueue) {
          assert(cue.timestamp <= until);
          assert(trackData.lastCueEndTimestamp <= cue.timestamp + cue.duration);
          timestamps.add(Math.max(cue.timestamp, trackData.lastCueEndTimestamp));
          timestamps.add(cue.timestamp + cue.duration);
        }
        const sortedTimestamps = [...timestamps].sort((a, b) => a - b);
        const sampleStart = sortedTimestamps[0];
        const sampleEnd = sortedTimestamps[1] ?? sampleStart;
        if (until < sampleEnd) {
          break;
        }
        if (trackData.lastCueEndTimestamp < sampleStart) {
          this.auxWriter.seek(0);
          const box2 = vtte();
          this.auxBoxWriter.writeBox(box2);
          const body2 = this.auxWriter.getSlice(0, this.auxWriter.getPos());
          const sample2 = this.createSampleForTrack(
            trackData,
            body2,
            trackData.lastCueEndTimestamp,
            sampleStart - trackData.lastCueEndTimestamp,
            "key"
          );
          await this.registerSample(trackData, sample2);
          trackData.lastCueEndTimestamp = sampleStart;
        }
        this.auxWriter.seek(0);
        for (let i = 0; i < trackData.cueQueue.length; i++) {
          const cue = trackData.cueQueue[i];
          if (cue.timestamp >= sampleEnd) {
            break;
          }
          inlineTimestampRegex.lastIndex = 0;
          const containsTimestamp = inlineTimestampRegex.test(cue.text);
          const endTimestamp = cue.timestamp + cue.duration;
          let sourceId = trackData.cueToSourceId.get(cue);
          if (sourceId === void 0 && sampleEnd < endTimestamp) {
            sourceId = trackData.nextSourceId++;
            trackData.cueToSourceId.set(cue, sourceId);
          }
          if (cue.notes) {
            const box3 = vtta(cue.notes);
            this.auxBoxWriter.writeBox(box3);
          }
          const box2 = vttc(
            cue.text,
            containsTimestamp ? sampleStart : null,
            cue.identifier ?? null,
            cue.settings ?? null,
            sourceId ?? null
          );
          this.auxBoxWriter.writeBox(box2);
          if (endTimestamp === sampleEnd) {
            trackData.cueQueue.splice(i--, 1);
          }
        }
        const body = this.auxWriter.getSlice(0, this.auxWriter.getPos());
        const sample = this.createSampleForTrack(trackData, body, sampleStart, sampleEnd - sampleStart, "key");
        await this.registerSample(trackData, sample);
        trackData.lastCueEndTimestamp = sampleEnd;
      }
    }
    createSampleForTrack(trackData, data, timestamp, duration, type) {
      const sample = {
        timestamp,
        decodeTimestamp: timestamp,
        // This may be refined later
        duration,
        data,
        size: data.byteLength,
        type,
        timescaleUnitsToNextSample: intoTimescale(duration, trackData.timescale)
        // Will be refined
      };
      return sample;
    }
    processTimestamps(trackData, nextSample) {
      if (trackData.timestampProcessingQueue.length === 0) {
        return;
      }
      if (trackData.type === "audio" && trackData.info.requiresPcmTransformation) {
        let totalDuration = 0;
        for (let i = 0; i < trackData.timestampProcessingQueue.length; i++) {
          const sample = trackData.timestampProcessingQueue[i];
          const duration = intoTimescale(sample.duration, trackData.timescale);
          totalDuration += duration;
        }
        if (trackData.timeToSampleTable.length === 0) {
          trackData.timeToSampleTable.push({
            sampleCount: totalDuration,
            sampleDelta: 1
          });
        } else {
          const lastEntry = last(trackData.timeToSampleTable);
          lastEntry.sampleCount += totalDuration;
        }
        trackData.timestampProcessingQueue.length = 0;
        return;
      }
      const sortedTimestamps = trackData.timestampProcessingQueue.map((x) => x.timestamp).sort((a, b) => a - b);
      for (let i = 0; i < trackData.timestampProcessingQueue.length; i++) {
        const sample = trackData.timestampProcessingQueue[i];
        sample.decodeTimestamp = sortedTimestamps[i];
        if (!this.isFragmented && trackData.lastTimescaleUnits === null) {
          sample.decodeTimestamp = 0;
        }
        const sampleCompositionTimeOffset = intoTimescale(sample.timestamp - sample.decodeTimestamp, trackData.timescale);
        const durationInTimescale = intoTimescale(sample.duration, trackData.timescale);
        if (trackData.lastTimescaleUnits !== null) {
          assert(trackData.lastSample);
          const timescaleUnits = intoTimescale(sample.decodeTimestamp, trackData.timescale, false);
          const delta = Math.round(timescaleUnits - trackData.lastTimescaleUnits);
          assert(delta >= 0);
          trackData.lastTimescaleUnits += delta;
          trackData.lastSample.timescaleUnitsToNextSample = delta;
          if (!this.isFragmented) {
            let lastTableEntry = last(trackData.timeToSampleTable);
            assert(lastTableEntry);
            if (lastTableEntry.sampleCount === 1) {
              lastTableEntry.sampleDelta = delta;
              const entryBefore = trackData.timeToSampleTable[trackData.timeToSampleTable.length - 2];
              if (entryBefore && entryBefore.sampleDelta === delta) {
                entryBefore.sampleCount++;
                trackData.timeToSampleTable.pop();
                lastTableEntry = entryBefore;
              }
            } else if (lastTableEntry.sampleDelta !== delta) {
              lastTableEntry.sampleCount--;
              trackData.timeToSampleTable.push(lastTableEntry = {
                sampleCount: 1,
                sampleDelta: delta
              });
            }
            if (lastTableEntry.sampleDelta === durationInTimescale) {
              lastTableEntry.sampleCount++;
            } else {
              trackData.timeToSampleTable.push({
                sampleCount: 1,
                sampleDelta: durationInTimescale
              });
            }
            const lastCompositionTimeOffsetTableEntry = last(trackData.compositionTimeOffsetTable);
            assert(lastCompositionTimeOffsetTableEntry);
            if (lastCompositionTimeOffsetTableEntry.sampleCompositionTimeOffset === sampleCompositionTimeOffset) {
              lastCompositionTimeOffsetTableEntry.sampleCount++;
            } else {
              trackData.compositionTimeOffsetTable.push({
                sampleCount: 1,
                sampleCompositionTimeOffset
              });
            }
          }
        } else {
          trackData.lastTimescaleUnits = intoTimescale(sample.decodeTimestamp, trackData.timescale, false);
          if (!this.isFragmented) {
            trackData.timeToSampleTable.push({
              sampleCount: 1,
              sampleDelta: durationInTimescale
            });
            trackData.compositionTimeOffsetTable.push({
              sampleCount: 1,
              sampleCompositionTimeOffset
            });
          }
        }
        trackData.lastSample = sample;
      }
      trackData.timestampProcessingQueue.length = 0;
      assert(trackData.lastSample);
      assert(trackData.lastTimescaleUnits !== null);
      if (nextSample !== void 0 && trackData.lastSample.timescaleUnitsToNextSample === 0) {
        assert(nextSample.type === "key");
        const timescaleUnits = intoTimescale(nextSample.timestamp, trackData.timescale, false);
        const delta = Math.round(timescaleUnits - trackData.lastTimescaleUnits);
        trackData.lastSample.timescaleUnitsToNextSample = delta;
      }
    }
    async registerSample(trackData, sample) {
      if (sample.type === "key") {
        this.processTimestamps(trackData, sample);
      }
      trackData.timestampProcessingQueue.push(sample);
      if (this.isFragmented) {
        trackData.sampleQueue.push(sample);
        await this.interleaveSamples();
      } else if (this.fastStart === "reserve") {
        await this.registerSampleFastStartReserve(trackData, sample);
      } else {
        await this.addSampleToTrack(trackData, sample);
      }
    }
    async addSampleToTrack(trackData, sample) {
      if (!this.isFragmented) {
        trackData.samples.push(sample);
        if (this.fastStart === "reserve") {
          const maximumPacketCount = trackData.track.metadata.maximumPacketCount;
          assert(maximumPacketCount !== void 0);
          if (trackData.samples.length > maximumPacketCount) {
            throw new Error(
              `Track #${trackData.track.id} has already reached the maximum packet count (${maximumPacketCount}). Either add less packets or increase the maximum packet count.`
            );
          }
        }
      }
      let beginNewChunk = false;
      if (!trackData.currentChunk) {
        beginNewChunk = true;
      } else {
        trackData.currentChunk.startTimestamp = Math.min(
          trackData.currentChunk.startTimestamp,
          sample.timestamp
        );
        const currentChunkDuration = sample.timestamp - trackData.currentChunk.startTimestamp;
        if (this.isFragmented) {
          const keyFrameQueuedEverywhere = this.trackDatas.every((otherTrackData) => {
            if (trackData === otherTrackData) {
              return sample.type === "key";
            }
            const firstQueuedSample = otherTrackData.sampleQueue[0];
            if (firstQueuedSample) {
              return firstQueuedSample.type === "key";
            }
            return otherTrackData.track.source._closed;
          });
          if (currentChunkDuration >= this.minimumFragmentDuration && keyFrameQueuedEverywhere && sample.timestamp > this.maxWrittenTimestamp) {
            beginNewChunk = true;
            await this.finalizeFragment();
          }
        } else {
          beginNewChunk = currentChunkDuration >= 0.5;
        }
      }
      if (beginNewChunk) {
        if (trackData.currentChunk) {
          await this.finalizeCurrentChunk(trackData);
        }
        trackData.currentChunk = {
          startTimestamp: sample.timestamp,
          samples: [],
          offset: null,
          moofOffset: null
        };
      }
      assert(trackData.currentChunk);
      trackData.currentChunk.samples.push(sample);
      if (this.isFragmented) {
        this.maxWrittenTimestamp = Math.max(this.maxWrittenTimestamp, sample.timestamp);
      }
    }
    async finalizeCurrentChunk(trackData) {
      assert(!this.isFragmented);
      if (!trackData.currentChunk) return;
      trackData.finalizedChunks.push(trackData.currentChunk);
      this.finalizedChunks.push(trackData.currentChunk);
      let sampleCount = trackData.currentChunk.samples.length;
      if (trackData.type === "audio" && trackData.info.requiresPcmTransformation) {
        sampleCount = trackData.currentChunk.samples.reduce((acc, sample) => acc + intoTimescale(sample.duration, trackData.timescale), 0);
      }
      if (trackData.compactlyCodedChunkTable.length === 0 || last(trackData.compactlyCodedChunkTable).samplesPerChunk !== sampleCount) {
        trackData.compactlyCodedChunkTable.push({
          firstChunk: trackData.finalizedChunks.length,
          // 1-indexed
          samplesPerChunk: sampleCount
        });
      }
      if (this.fastStart === "in-memory") {
        trackData.currentChunk.offset = 0;
        return;
      }
      trackData.currentChunk.offset = this.writer.getPos();
      for (const sample of trackData.currentChunk.samples) {
        assert(sample.data);
        this.writer.write(sample.data);
        sample.data = null;
      }
      await this.writer.flush();
    }
    async interleaveSamples(isFinalCall = false) {
      assert(this.isFragmented);
      if (!isFinalCall && !this.allTracksAreKnown()) {
        return;
      }
      outer:
        while (true) {
          let trackWithMinTimestamp = null;
          let minTimestamp = Infinity;
          for (const trackData of this.trackDatas) {
            if (!isFinalCall && trackData.sampleQueue.length === 0 && !trackData.track.source._closed) {
              break outer;
            }
            if (trackData.sampleQueue.length > 0 && trackData.sampleQueue[0].timestamp < minTimestamp) {
              trackWithMinTimestamp = trackData;
              minTimestamp = trackData.sampleQueue[0].timestamp;
            }
          }
          if (!trackWithMinTimestamp) {
            break;
          }
          const sample = trackWithMinTimestamp.sampleQueue.shift();
          await this.addSampleToTrack(trackWithMinTimestamp, sample);
        }
    }
    async finalizeFragment(flushWriter = true) {
      assert(this.isFragmented);
      const fragmentNumber = this.nextFragmentNumber++;
      if (fragmentNumber === 1) {
        if (this.format._options.onMoov) {
          this.writer.startTrackingWrites();
        }
        const movieBox = moov(this);
        this.boxWriter.writeBox(movieBox);
        if (this.format._options.onMoov) {
          const { data, start } = this.writer.stopTrackingWrites();
          this.format._options.onMoov(data, start);
        }
      }
      const tracksInFragment = this.trackDatas.filter((x) => x.currentChunk);
      const moofBox = moof(fragmentNumber, tracksInFragment);
      const moofOffset = this.writer.getPos();
      const mdatStartPos = moofOffset + this.boxWriter.measureBox(moofBox);
      let currentPos = mdatStartPos + MIN_BOX_HEADER_SIZE;
      let fragmentStartTimestamp = Infinity;
      for (const trackData of tracksInFragment) {
        trackData.currentChunk.offset = currentPos;
        trackData.currentChunk.moofOffset = moofOffset;
        for (const sample of trackData.currentChunk.samples) {
          currentPos += sample.size;
        }
        fragmentStartTimestamp = Math.min(fragmentStartTimestamp, trackData.currentChunk.startTimestamp);
      }
      const mdatSize = currentPos - mdatStartPos;
      const needsLargeMdatSize = mdatSize >= 2 ** 32;
      if (needsLargeMdatSize) {
        for (const trackData of tracksInFragment) {
          trackData.currentChunk.offset += MAX_BOX_HEADER_SIZE - MIN_BOX_HEADER_SIZE;
        }
      }
      if (this.format._options.onMoof) {
        this.writer.startTrackingWrites();
      }
      const newMoofBox = moof(fragmentNumber, tracksInFragment);
      this.boxWriter.writeBox(newMoofBox);
      if (this.format._options.onMoof) {
        const { data, start } = this.writer.stopTrackingWrites();
        this.format._options.onMoof(data, start, fragmentStartTimestamp);
      }
      assert(this.writer.getPos() === mdatStartPos);
      if (this.format._options.onMdat) {
        this.writer.startTrackingWrites();
      }
      const mdatBox = mdat(needsLargeMdatSize);
      mdatBox.size = mdatSize;
      this.boxWriter.writeBox(mdatBox);
      this.writer.seek(mdatStartPos + (needsLargeMdatSize ? MAX_BOX_HEADER_SIZE : MIN_BOX_HEADER_SIZE));
      for (const trackData of tracksInFragment) {
        for (const sample of trackData.currentChunk.samples) {
          this.writer.write(sample.data);
          sample.data = null;
        }
      }
      if (this.format._options.onMdat) {
        const { data, start } = this.writer.stopTrackingWrites();
        this.format._options.onMdat(data, start);
      }
      for (const trackData of tracksInFragment) {
        trackData.finalizedChunks.push(trackData.currentChunk);
        this.finalizedChunks.push(trackData.currentChunk);
        trackData.currentChunk = null;
      }
      if (flushWriter) {
        await this.writer.flush();
      }
    }
    async registerSampleFastStartReserve(trackData, sample) {
      if (this.allTracksAreKnown()) {
        if (!this.mdat) {
          const moovBox = moov(this);
          const moovSize = this.boxWriter.measureBox(moovBox);
          const reservedSize = moovSize + this.computeSampleTableSizeUpperBound() + 4096;
          assert(this.ftypSize !== null);
          this.writer.seek(this.ftypSize + reservedSize);
          if (this.format._options.onMdat) {
            this.writer.startTrackingWrites();
          }
          this.mdat = mdat(true);
          this.boxWriter.writeBox(this.mdat);
          for (const trackData2 of this.trackDatas) {
            for (const sample2 of trackData2.sampleQueue) {
              await this.addSampleToTrack(trackData2, sample2);
            }
            trackData2.sampleQueue.length = 0;
          }
        }
        await this.addSampleToTrack(trackData, sample);
      } else {
        trackData.sampleQueue.push(sample);
      }
    }
    computeSampleTableSizeUpperBound() {
      assert(this.fastStart === "reserve");
      let upperBound = 0;
      for (const trackData of this.trackDatas) {
        const n = trackData.track.metadata.maximumPacketCount;
        assert(n !== void 0);
        upperBound += (4 + 4) * Math.ceil(2 / 3 * n);
        upperBound += 4 * n;
        upperBound += (4 + 4) * Math.ceil(2 / 3 * n);
        upperBound += (4 + 4 + 4) * Math.ceil(2 / 3 * n);
        upperBound += 4 * n;
        upperBound += 8 * n;
      }
      return upperBound;
    }
    // eslint-disable-next-line @typescript-eslint/no-misused-promises
    async onTrackClose(track) {
      const release = await this.mutex.acquire();
      if (track.type === "subtitle" && track.source._codec === "webvtt") {
        const trackData = this.trackDatas.find((x) => x.track === track);
        if (trackData) {
          await this.processWebVTTCues(trackData, Infinity);
        }
      }
      if (this.allTracksAreKnown()) {
        this.allTracksKnown.resolve();
      }
      if (this.isFragmented) {
        await this.interleaveSamples();
      }
      release();
    }
    /** Finalizes the file, making it ready for use. Must be called after all video and audio chunks have been added. */
    async finalize() {
      const release = await this.mutex.acquire();
      this.allTracksKnown.resolve();
      for (const trackData of this.trackDatas) {
        if (trackData.type === "subtitle" && trackData.track.source._codec === "webvtt") {
          await this.processWebVTTCues(trackData, Infinity);
        }
      }
      if (this.isFragmented) {
        await this.interleaveSamples(true);
        for (const trackData of this.trackDatas) {
          this.processTimestamps(trackData);
        }
        await this.finalizeFragment(false);
      } else {
        for (const trackData of this.trackDatas) {
          this.processTimestamps(trackData);
          await this.finalizeCurrentChunk(trackData);
        }
      }
      if (this.fastStart === "in-memory") {
        this.mdat = mdat(false);
        let mdatSize;
        for (let i = 0; i < 2; i++) {
          const movieBox2 = moov(this);
          const movieBoxSize = this.boxWriter.measureBox(movieBox2);
          mdatSize = this.boxWriter.measureBox(this.mdat);
          let currentChunkPos = this.writer.getPos() + movieBoxSize + mdatSize;
          for (const chunk of this.finalizedChunks) {
            chunk.offset = currentChunkPos;
            for (const { data } of chunk.samples) {
              assert(data);
              currentChunkPos += data.byteLength;
              mdatSize += data.byteLength;
            }
          }
          if (currentChunkPos < 2 ** 32) break;
          if (mdatSize >= 2 ** 32) this.mdat.largeSize = true;
        }
        if (this.format._options.onMoov) {
          this.writer.startTrackingWrites();
        }
        const movieBox = moov(this);
        this.boxWriter.writeBox(movieBox);
        if (this.format._options.onMoov) {
          const { data, start } = this.writer.stopTrackingWrites();
          this.format._options.onMoov(data, start);
        }
        if (this.format._options.onMdat) {
          this.writer.startTrackingWrites();
        }
        this.mdat.size = mdatSize;
        this.boxWriter.writeBox(this.mdat);
        for (const chunk of this.finalizedChunks) {
          for (const sample of chunk.samples) {
            assert(sample.data);
            this.writer.write(sample.data);
            sample.data = null;
          }
        }
        if (this.format._options.onMdat) {
          const { data, start } = this.writer.stopTrackingWrites();
          this.format._options.onMdat(data, start);
        }
      } else if (this.isFragmented) {
        const startPos = this.writer.getPos();
        const mfraBox = mfra(this.trackDatas);
        this.boxWriter.writeBox(mfraBox);
        const mfraBoxSize = this.writer.getPos() - startPos;
        this.writer.seek(this.writer.getPos() - 4);
        this.boxWriter.writeU32(mfraBoxSize);
      } else {
        assert(this.mdat);
        const mdatPos = this.boxWriter.offsets.get(this.mdat);
        assert(mdatPos !== void 0);
        const mdatSize = this.writer.getPos() - mdatPos;
        this.mdat.size = mdatSize;
        this.mdat.largeSize = mdatSize >= 2 ** 32;
        this.boxWriter.patchBox(this.mdat);
        if (this.format._options.onMdat) {
          const { data, start } = this.writer.stopTrackingWrites();
          this.format._options.onMdat(data, start);
        }
        const movieBox = moov(this);
        if (this.fastStart === "reserve") {
          assert(this.ftypSize !== null);
          this.writer.seek(this.ftypSize);
          if (this.format._options.onMoov) {
            this.writer.startTrackingWrites();
          }
          this.boxWriter.writeBox(movieBox);
          const remainingSpace = this.boxWriter.offsets.get(this.mdat) - this.writer.getPos();
          this.boxWriter.writeBox(free(remainingSpace));
        } else {
          if (this.format._options.onMoov) {
            this.writer.startTrackingWrites();
          }
          this.boxWriter.writeBox(movieBox);
        }
        if (this.format._options.onMoov) {
          const { data, start } = this.writer.stopTrackingWrites();
          this.format._options.onMoov(data, start);
        }
      }
      release();
    }
  };

  // src/matroska/matroska-muxer.ts
  var MIN_CLUSTER_TIMESTAMP_MS = -(2 ** 15);
  var MAX_CLUSTER_TIMESTAMP_MS = 2 ** 15 - 1;
  var APP_NAME = "Mediabunny";
  var SEGMENT_SIZE_BYTES = 6;
  var CLUSTER_SIZE_BYTES = 5;
  var TRACK_TYPE_MAP = {
    video: 1,
    audio: 2,
    subtitle: 17
  };
  var MatroskaMuxer = class extends Muxer {
    constructor(output, format) {
      super(output);
      this.trackDatas = [];
      this.allTracksKnown = promiseWithResolvers();
      this.segment = null;
      this.segmentInfo = null;
      this.seekHead = null;
      this.tracksElement = null;
      this.tagsElement = null;
      this.attachmentsElement = null;
      this.segmentDuration = null;
      this.cues = null;
      this.currentCluster = null;
      this.currentClusterStartMsTimestamp = null;
      this.currentClusterMaxMsTimestamp = null;
      this.trackDatasInCurrentCluster = /* @__PURE__ */ new Map();
      this.duration = 0;
      this.writer = output._writer;
      this.format = format;
      this.ebmlWriter = new EBMLWriter(this.writer);
      if (this.format._options.appendOnly) {
        this.writer.ensureMonotonicity = true;
      }
    }
    async start() {
      const release = await this.mutex.acquire();
      this.writeEBMLHeader();
      this.createSegmentInfo();
      this.createCues();
      await this.writer.flush();
      release();
    }
    writeEBMLHeader() {
      if (this.format._options.onEbmlHeader) {
        this.writer.startTrackingWrites();
      }
      const ebmlHeader = { id: 440786851 /* EBML */, data: [
        { id: 17030 /* EBMLVersion */, data: 1 },
        { id: 17143 /* EBMLReadVersion */, data: 1 },
        { id: 17138 /* EBMLMaxIDLength */, data: 4 },
        { id: 17139 /* EBMLMaxSizeLength */, data: 8 },
        { id: 17026 /* DocType */, data: this.format instanceof WebMOutputFormat ? "webm" : "matroska" },
        { id: 17031 /* DocTypeVersion */, data: 2 },
        { id: 17029 /* DocTypeReadVersion */, data: 2 }
      ] };
      this.ebmlWriter.writeEBML(ebmlHeader);
      if (this.format._options.onEbmlHeader) {
        const { data, start } = this.writer.stopTrackingWrites();
        this.format._options.onEbmlHeader(data, start);
      }
    }
    /**
     * Creates a SeekHead element which is positioned near the start of the file and allows the media player to seek to
     * relevant sections more easily. Since we don't know the positions of those sections yet, we'll set them later.
     */
    maybeCreateSeekHead(writeOffsets) {
      if (this.format._options.appendOnly) {
        return;
      }
      const kaxCues = new Uint8Array([28, 83, 187, 107]);
      const kaxInfo = new Uint8Array([21, 73, 169, 102]);
      const kaxTracks = new Uint8Array([22, 84, 174, 107]);
      const kaxAttachments = new Uint8Array([25, 65, 164, 105]);
      const kaxTags = new Uint8Array([18, 84, 195, 103]);
      const seekHead = { id: 290298740 /* SeekHead */, data: [
        { id: 19899 /* Seek */, data: [
          { id: 21419 /* SeekID */, data: kaxCues },
          {
            id: 21420 /* SeekPosition */,
            size: 5,
            data: writeOffsets ? this.ebmlWriter.offsets.get(this.cues) - this.segmentDataOffset : 0
          }
        ] },
        { id: 19899 /* Seek */, data: [
          { id: 21419 /* SeekID */, data: kaxInfo },
          {
            id: 21420 /* SeekPosition */,
            size: 5,
            data: writeOffsets ? this.ebmlWriter.offsets.get(this.segmentInfo) - this.segmentDataOffset : 0
          }
        ] },
        { id: 19899 /* Seek */, data: [
          { id: 21419 /* SeekID */, data: kaxTracks },
          {
            id: 21420 /* SeekPosition */,
            size: 5,
            data: writeOffsets ? this.ebmlWriter.offsets.get(this.tracksElement) - this.segmentDataOffset : 0
          }
        ] },
        this.attachmentsElement ? { id: 19899 /* Seek */, data: [
          { id: 21419 /* SeekID */, data: kaxAttachments },
          {
            id: 21420 /* SeekPosition */,
            size: 5,
            data: writeOffsets ? this.ebmlWriter.offsets.get(this.attachmentsElement) - this.segmentDataOffset : 0
          }
        ] } : null,
        this.tagsElement ? { id: 19899 /* Seek */, data: [
          { id: 21419 /* SeekID */, data: kaxTags },
          {
            id: 21420 /* SeekPosition */,
            size: 5,
            data: writeOffsets ? this.ebmlWriter.offsets.get(this.tagsElement) - this.segmentDataOffset : 0
          }
        ] } : null
      ] };
      this.seekHead = seekHead;
    }
    createSegmentInfo() {
      const segmentDuration = { id: 17545 /* Duration */, data: new EBMLFloat64(0) };
      this.segmentDuration = segmentDuration;
      const segmentInfo = { id: 357149030 /* Info */, data: [
        { id: 2807729 /* TimestampScale */, data: 1e6 },
        { id: 19840 /* MuxingApp */, data: APP_NAME },
        { id: 22337 /* WritingApp */, data: APP_NAME },
        !this.format._options.appendOnly ? segmentDuration : null
      ] };
      this.segmentInfo = segmentInfo;
    }
    createTracks() {
      const tracksElement = { id: 374648427 /* Tracks */, data: [] };
      this.tracksElement = tracksElement;
      for (const trackData of this.trackDatas) {
        const codecId = CODEC_STRING_MAP[trackData.track.source._codec];
        assert(codecId);
        let seekPreRollNs = 0;
        if (trackData.type === "audio" && trackData.track.source._codec === "opus") {
          seekPreRollNs = 1e6 * 80;
          const description = trackData.info.decoderConfig.description;
          if (description) {
            const bytes2 = toUint8Array(description);
            const header = parseOpusIdentificationHeader(bytes2);
            seekPreRollNs = Math.round(1e9 * (header.preSkip / OPUS_SAMPLE_RATE));
          }
        }
        tracksElement.data.push({ id: 174 /* TrackEntry */, data: [
          { id: 215 /* TrackNumber */, data: trackData.track.id },
          { id: 29637 /* TrackUID */, data: trackData.track.id },
          { id: 131 /* TrackType */, data: TRACK_TYPE_MAP[trackData.type] },
          trackData.track.metadata.disposition?.default === false ? { id: 136 /* FlagDefault */, data: 0 } : null,
          trackData.track.metadata.disposition?.forced ? { id: 21930 /* FlagForced */, data: 1 } : null,
          trackData.track.metadata.disposition?.hearingImpaired ? { id: 21931 /* FlagHearingImpaired */, data: 1 } : null,
          trackData.track.metadata.disposition?.visuallyImpaired ? { id: 21932 /* FlagVisualImpaired */, data: 1 } : null,
          trackData.track.metadata.disposition?.original ? { id: 21934 /* FlagOriginal */, data: 1 } : null,
          trackData.track.metadata.disposition?.commentary ? { id: 21935 /* FlagCommentary */, data: 1 } : null,
          { id: 156 /* FlagLacing */, data: 0 },
          { id: 2274716 /* Language */, data: trackData.track.metadata.languageCode ?? UNDETERMINED_LANGUAGE },
          { id: 134 /* CodecID */, data: codecId },
          { id: 22186 /* CodecDelay */, data: 0 },
          { id: 22203 /* SeekPreRoll */, data: seekPreRollNs },
          trackData.track.metadata.name !== void 0 ? { id: 21358 /* Name */, data: new EBMLUnicodeString(trackData.track.metadata.name) } : null,
          trackData.type === "video" ? this.videoSpecificTrackInfo(trackData) : null,
          trackData.type === "audio" ? this.audioSpecificTrackInfo(trackData) : null,
          trackData.type === "subtitle" ? this.subtitleSpecificTrackInfo(trackData) : null
        ] });
      }
    }
    videoSpecificTrackInfo(trackData) {
      const { frameRate, rotation } = trackData.track.metadata;
      const elements = [
        trackData.info.decoderConfig.description ? {
          id: 25506 /* CodecPrivate */,
          data: toUint8Array(trackData.info.decoderConfig.description)
        } : null,
        frameRate ? {
          id: 2352003 /* DefaultDuration */,
          data: 1e9 / frameRate
        } : null
      ];
      const flippedRotation = rotation ? normalizeRotation(-rotation) : 0;
      const colorSpace = trackData.info.decoderConfig.colorSpace;
      const videoElement = { id: 224 /* Video */, data: [
        { id: 176 /* PixelWidth */, data: trackData.info.width },
        { id: 186 /* PixelHeight */, data: trackData.info.height },
        trackData.info.alphaMode ? { id: 21440 /* AlphaMode */, data: 1 } : null,
        colorSpaceIsComplete(colorSpace) ? {
          id: 21936 /* Colour */,
          data: [
            {
              id: 21937 /* MatrixCoefficients */,
              data: MATRIX_COEFFICIENTS_MAP[colorSpace.matrix]
            },
            {
              id: 21946 /* TransferCharacteristics */,
              data: TRANSFER_CHARACTERISTICS_MAP[colorSpace.transfer]
            },
            {
              id: 21947 /* Primaries */,
              data: COLOR_PRIMARIES_MAP[colorSpace.primaries]
            },
            {
              id: 21945 /* Range */,
              data: colorSpace.fullRange ? 2 : 1
            }
          ]
        } : null,
        flippedRotation ? {
          id: 30320 /* Projection */,
          data: [
            {
              id: 30321 /* ProjectionType */,
              data: 0
              // rectangular
            },
            {
              id: 30325 /* ProjectionPoseRoll */,
              data: new EBMLFloat32((flippedRotation + 180) % 360 - 180)
              // [0, 270] -> [-180, 90]
            }
          ]
        } : null
      ] };
      elements.push(videoElement);
      return elements;
    }
    audioSpecificTrackInfo(trackData) {
      const pcmInfo = PCM_AUDIO_CODECS.includes(trackData.track.source._codec) ? parsePcmCodec(trackData.track.source._codec) : null;
      return [
        trackData.info.decoderConfig.description ? {
          id: 25506 /* CodecPrivate */,
          data: toUint8Array(trackData.info.decoderConfig.description)
        } : null,
        { id: 225 /* Audio */, data: [
          { id: 181 /* SamplingFrequency */, data: new EBMLFloat32(trackData.info.sampleRate) },
          { id: 159 /* Channels */, data: trackData.info.numberOfChannels },
          pcmInfo ? { id: 25188 /* BitDepth */, data: 8 * pcmInfo.sampleSize } : null
        ] }
      ];
    }
    subtitleSpecificTrackInfo(trackData) {
      return [
        { id: 25506 /* CodecPrivate */, data: textEncoder.encode(trackData.info.config.description) }
      ];
    }
    maybeCreateTags() {
      const simpleTags = [];
      const addSimpleTag = (key, value) => {
        simpleTags.push({ id: 26568 /* SimpleTag */, data: [
          { id: 17827 /* TagName */, data: new EBMLUnicodeString(key) },
          typeof value === "string" ? { id: 17543 /* TagString */, data: new EBMLUnicodeString(value) } : { id: 17541 /* TagBinary */, data: value }
        ] });
      };
      const metadataTags = this.output._metadataTags;
      const writtenTags = /* @__PURE__ */ new Set();
      for (const { key, value } of keyValueIterator(metadataTags)) {
        switch (key) {
          case "title":
            {
              addSimpleTag("TITLE", value);
              writtenTags.add("TITLE");
            }
            ;
            break;
          case "description":
            {
              addSimpleTag("DESCRIPTION", value);
              writtenTags.add("DESCRIPTION");
            }
            ;
            break;
          case "artist":
            {
              addSimpleTag("ARTIST", value);
              writtenTags.add("ARTIST");
            }
            ;
            break;
          case "album":
            {
              addSimpleTag("ALBUM", value);
              writtenTags.add("ALBUM");
            }
            ;
            break;
          case "albumArtist":
            {
              addSimpleTag("ALBUM_ARTIST", value);
              writtenTags.add("ALBUM_ARTIST");
            }
            ;
            break;
          case "genre":
            {
              addSimpleTag("GENRE", value);
              writtenTags.add("GENRE");
            }
            ;
            break;
          case "comment":
            {
              addSimpleTag("COMMENT", value);
              writtenTags.add("COMMENT");
            }
            ;
            break;
          case "lyrics":
            {
              addSimpleTag("LYRICS", value);
              writtenTags.add("LYRICS");
            }
            ;
            break;
          case "date":
            {
              addSimpleTag("DATE", value.toISOString().slice(0, 10));
              writtenTags.add("DATE");
            }
            ;
            break;
          case "trackNumber":
            {
              const string = metadataTags.tracksTotal !== void 0 ? `${value}/${metadataTags.tracksTotal}` : value.toString();
              addSimpleTag("PART_NUMBER", string);
              writtenTags.add("PART_NUMBER");
            }
            ;
            break;
          case "discNumber":
            {
              const string = metadataTags.discsTotal !== void 0 ? `${value}/${metadataTags.discsTotal}` : value.toString();
              addSimpleTag("DISC", string);
              writtenTags.add("DISC");
            }
            ;
            break;
          case "tracksTotal":
          case "discsTotal":
            {
            }
            ;
            break;
          case "images":
          case "raw":
            {
            }
            ;
            break;
          default:
            assertNever(key);
        }
      }
      if (metadataTags.raw) {
        for (const key in metadataTags.raw) {
          const value = metadataTags.raw[key];
          if (value == null || writtenTags.has(key)) {
            continue;
          }
          if (typeof value === "string" || value instanceof Uint8Array) {
            addSimpleTag(key, value);
          }
        }
      }
      if (simpleTags.length === 0) {
        return;
      }
      this.tagsElement = {
        id: 307544935 /* Tags */,
        data: [{ id: 29555 /* Tag */, data: [
          { id: 25536 /* Targets */, data: [
            { id: 26826 /* TargetTypeValue */, data: 50 },
            { id: 25546 /* TargetType */, data: "MOVIE" }
          ] },
          ...simpleTags
        ] }]
      };
    }
    maybeCreateAttachments() {
      const metadataTags = this.output._metadataTags;
      const elements = [];
      const existingFileUids = /* @__PURE__ */ new Set();
      const images = metadataTags.images ?? [];
      for (const image of images) {
        let imageName = image.name;
        if (imageName === void 0) {
          const baseName = image.kind === "coverFront" ? "cover" : image.kind === "coverBack" ? "back" : "image";
          imageName = baseName + (imageMimeTypeToExtension(image.mimeType) ?? "");
        }
        let fileUid;
        while (true) {
          fileUid = 0n;
          for (let i = 0; i < 8; i++) {
            fileUid <<= 8n;
            fileUid |= BigInt(Math.floor(Math.random() * 256));
          }
          if (fileUid !== 0n && !existingFileUids.has(fileUid)) {
            break;
          }
        }
        existingFileUids.add(fileUid);
        elements.push({
          id: 24999 /* AttachedFile */,
          data: [
            image.description !== void 0 ? { id: 18046 /* FileDescription */, data: new EBMLUnicodeString(image.description) } : null,
            { id: 18030 /* FileName */, data: new EBMLUnicodeString(imageName) },
            { id: 18016 /* FileMediaType */, data: image.mimeType },
            { id: 18012 /* FileData */, data: image.data },
            { id: 18094 /* FileUID */, data: fileUid }
          ]
        });
      }
      for (const [key, value] of Object.entries(metadataTags.raw ?? {})) {
        if (!(value instanceof AttachedFile)) {
          continue;
        }
        const keyIsNumeric = /^\d+$/.test(key);
        if (!keyIsNumeric) {
          continue;
        }
        if (images.find((x) => x.mimeType === value.mimeType && uint8ArraysAreEqual(x.data, value.data))) {
          continue;
        }
        elements.push({
          id: 24999 /* AttachedFile */,
          data: [
            value.description !== void 0 ? { id: 18046 /* FileDescription */, data: new EBMLUnicodeString(value.description) } : null,
            { id: 18030 /* FileName */, data: new EBMLUnicodeString(value.name ?? "") },
            { id: 18016 /* FileMediaType */, data: value.mimeType ?? "" },
            { id: 18012 /* FileData */, data: value.data },
            { id: 18094 /* FileUID */, data: BigInt(key) }
          ]
        });
      }
      if (elements.length === 0) {
        return;
      }
      this.attachmentsElement = { id: 423732329 /* Attachments */, data: elements };
    }
    createSegment() {
      this.createTracks();
      this.maybeCreateTags();
      this.maybeCreateAttachments();
      this.maybeCreateSeekHead(false);
      const segment = {
        id: 408125543 /* Segment */,
        size: this.format._options.appendOnly ? -1 : SEGMENT_SIZE_BYTES,
        data: [
          this.seekHead,
          // null if append-only
          this.segmentInfo,
          this.tracksElement,
          // Matroska spec says put this at the end of the file, but I think placing it before the first cluster
          // makes more sense, and FFmpeg agrees (argumentum ad ffmpegum fallacy)
          this.attachmentsElement,
          this.tagsElement
        ]
      };
      this.segment = segment;
      if (this.format._options.onSegmentHeader) {
        this.writer.startTrackingWrites();
      }
      this.ebmlWriter.writeEBML(segment);
      if (this.format._options.onSegmentHeader) {
        const { data, start } = this.writer.stopTrackingWrites();
        this.format._options.onSegmentHeader(data, start);
      }
    }
    createCues() {
      this.cues = { id: 475249515 /* Cues */, data: [] };
    }
    get segmentDataOffset() {
      assert(this.segment);
      return this.ebmlWriter.dataOffsets.get(this.segment);
    }
    allTracksAreKnown() {
      for (const track of this.output._tracks) {
        if (!track.source._closed && !this.trackDatas.some((x) => x.track === track)) {
          return false;
        }
      }
      return true;
    }
    async getMimeType() {
      await this.allTracksKnown.promise;
      const codecStrings = this.trackDatas.map((trackData) => {
        if (trackData.type === "video") {
          return trackData.info.decoderConfig.codec;
        } else if (trackData.type === "audio") {
          return trackData.info.decoderConfig.codec;
        } else {
          const map = {
            webvtt: "wvtt"
          };
          return map[trackData.track.source._codec];
        }
      });
      return buildMatroskaMimeType({
        isWebM: this.format instanceof WebMOutputFormat,
        hasVideo: this.trackDatas.some((x) => x.type === "video"),
        hasAudio: this.trackDatas.some((x) => x.type === "audio"),
        codecStrings
      });
    }
    getVideoTrackData(track, packet, meta) {
      const existingTrackData = this.trackDatas.find((x) => x.track === track);
      if (existingTrackData) {
        return existingTrackData;
      }
      validateVideoChunkMetadata(meta);
      assert(meta);
      assert(meta.decoderConfig);
      assert(meta.decoderConfig.codedWidth !== void 0);
      assert(meta.decoderConfig.codedHeight !== void 0);
      const newTrackData = {
        track,
        type: "video",
        info: {
          width: meta.decoderConfig.codedWidth,
          height: meta.decoderConfig.codedHeight,
          decoderConfig: meta.decoderConfig,
          alphaMode: !!packet.sideData.alpha
          // The first packet determines if this track has alpha or not
        },
        chunkQueue: [],
        lastWrittenMsTimestamp: null
      };
      if (track.source._codec === "vp9") {
        newTrackData.info.decoderConfig = {
          ...newTrackData.info.decoderConfig,
          description: new Uint8Array(
            generateVp9CodecConfigurationFromCodecString(newTrackData.info.decoderConfig.codec)
          )
        };
      } else if (track.source._codec === "av1") {
        newTrackData.info.decoderConfig = {
          ...newTrackData.info.decoderConfig,
          description: new Uint8Array(
            generateAv1CodecConfigurationFromCodecString(newTrackData.info.decoderConfig.codec)
          )
        };
      }
      this.trackDatas.push(newTrackData);
      this.trackDatas.sort((a, b) => a.track.id - b.track.id);
      if (this.allTracksAreKnown()) {
        this.allTracksKnown.resolve();
      }
      return newTrackData;
    }
    getAudioTrackData(track, packet, meta) {
      const existingTrackData = this.trackDatas.find((x) => x.track === track);
      if (existingTrackData) {
        return existingTrackData;
      }
      validateAudioChunkMetadata(meta);
      assert(meta);
      assert(meta.decoderConfig);
      const decoderConfig = { ...meta.decoderConfig };
      let requiresAdtsStripping = false;
      if (track.source._codec === "aac" && !decoderConfig.description) {
        const adtsFrame = readAdtsFrameHeader(FileSlice4.tempFromBytes(packet.data));
        if (!adtsFrame) {
          throw new Error(
            "Couldn't parse ADTS header from the AAC packet. Make sure the packets are in ADTS format (as specified in ISO 13818-7) when not providing a description, or provide a description (must be an AudioSpecificConfig as specified in ISO 14496-3) and ensure the packets are raw AAC data."
          );
        }
        const sampleRate = aacFrequencyTable[adtsFrame.samplingFrequencyIndex];
        const numberOfChannels = aacChannelMap[adtsFrame.channelConfiguration];
        if (sampleRate === void 0 || numberOfChannels === void 0) {
          throw new Error("Invalid ADTS frame header.");
        }
        decoderConfig.description = buildAacAudioSpecificConfig({
          objectType: adtsFrame.objectType,
          sampleRate,
          numberOfChannels
        });
        requiresAdtsStripping = true;
      }
      const newTrackData = {
        track,
        type: "audio",
        info: {
          numberOfChannels: meta.decoderConfig.numberOfChannels,
          sampleRate: meta.decoderConfig.sampleRate,
          decoderConfig,
          requiresAdtsStripping
        },
        chunkQueue: [],
        lastWrittenMsTimestamp: null
      };
      this.trackDatas.push(newTrackData);
      this.trackDatas.sort((a, b) => a.track.id - b.track.id);
      if (this.allTracksAreKnown()) {
        this.allTracksKnown.resolve();
      }
      return newTrackData;
    }
    getSubtitleTrackData(track, meta) {
      const existingTrackData = this.trackDatas.find((x) => x.track === track);
      if (existingTrackData) {
        return existingTrackData;
      }
      validateSubtitleMetadata(meta);
      assert(meta);
      assert(meta.config);
      const newTrackData = {
        track,
        type: "subtitle",
        info: {
          config: meta.config
        },
        chunkQueue: [],
        lastWrittenMsTimestamp: null
      };
      this.trackDatas.push(newTrackData);
      this.trackDatas.sort((a, b) => a.track.id - b.track.id);
      if (this.allTracksAreKnown()) {
        this.allTracksKnown.resolve();
      }
      return newTrackData;
    }
    async addEncodedVideoPacket(track, packet, meta) {
      const release = await this.mutex.acquire();
      try {
        const trackData = this.getVideoTrackData(track, packet, meta);
        const isKeyFrame = packet.type === "key";
        let timestamp = this.validateAndNormalizeTimestamp(trackData.track, packet.timestamp, isKeyFrame);
        let duration = packet.duration;
        if (track.metadata.frameRate !== void 0) {
          timestamp = roundToMultiple(timestamp, 1 / track.metadata.frameRate);
          duration = roundToMultiple(duration, 1 / track.metadata.frameRate);
        }
        const additions = trackData.info.alphaMode ? packet.sideData.alpha ?? null : null;
        const videoChunk = this.createInternalChunk(packet.data, timestamp, duration, packet.type, additions);
        if (track.source._codec === "vp9") this.fixVP9ColorSpace(trackData, videoChunk);
        trackData.chunkQueue.push(videoChunk);
        await this.interleaveChunks();
      } finally {
        release();
      }
    }
    async addEncodedAudioPacket(track, packet, meta) {
      const release = await this.mutex.acquire();
      try {
        const trackData = this.getAudioTrackData(track, packet, meta);
        let packetData = packet.data;
        if (trackData.info.requiresAdtsStripping) {
          const adtsFrame = readAdtsFrameHeader(FileSlice4.tempFromBytes(packetData));
          if (!adtsFrame) {
            throw new Error("Expected ADTS frame, didn't get one.");
          }
          const headerLength = adtsFrame.crcCheck === null ? MIN_ADTS_FRAME_HEADER_SIZE : MAX_ADTS_FRAME_HEADER_SIZE;
          packetData = packetData.subarray(headerLength);
        }
        const isKeyFrame = packet.type === "key";
        const timestamp = this.validateAndNormalizeTimestamp(trackData.track, packet.timestamp, isKeyFrame);
        const audioChunk = this.createInternalChunk(packetData, timestamp, packet.duration, packet.type);
        trackData.chunkQueue.push(audioChunk);
        await this.interleaveChunks();
      } finally {
        release();
      }
    }
    async addSubtitleCue(track, cue, meta) {
      const release = await this.mutex.acquire();
      try {
        const trackData = this.getSubtitleTrackData(track, meta);
        const timestamp = this.validateAndNormalizeTimestamp(trackData.track, cue.timestamp, true);
        let bodyText = cue.text;
        const timestampMs = Math.round(timestamp * 1e3);
        inlineTimestampRegex.lastIndex = 0;
        bodyText = bodyText.replace(inlineTimestampRegex, (match) => {
          const time = parseSubtitleTimestamp(match.slice(1, -1));
          const offsetTime = time - timestampMs;
          return `<${formatSubtitleTimestamp(offsetTime)}>`;
        });
        const body = textEncoder.encode(bodyText);
        const additions = `${cue.settings ?? ""}
${cue.identifier ?? ""}
${cue.notes ?? ""}`;
        const subtitleChunk = this.createInternalChunk(
          body,
          timestamp,
          cue.duration,
          "key",
          additions.trim() ? textEncoder.encode(additions) : null
        );
        trackData.chunkQueue.push(subtitleChunk);
        await this.interleaveChunks();
      } finally {
        release();
      }
    }
    async interleaveChunks(isFinalCall = false) {
      if (!isFinalCall && !this.allTracksAreKnown()) {
        return;
      }
      outer:
        while (true) {
          let trackWithMinTimestamp = null;
          let minTimestamp = Infinity;
          for (const trackData of this.trackDatas) {
            if (!isFinalCall && trackData.chunkQueue.length === 0 && !trackData.track.source._closed) {
              break outer;
            }
            if (trackData.chunkQueue.length > 0 && trackData.chunkQueue[0].timestamp < minTimestamp) {
              trackWithMinTimestamp = trackData;
              minTimestamp = trackData.chunkQueue[0].timestamp;
            }
          }
          if (!trackWithMinTimestamp) {
            break;
          }
          const chunk = trackWithMinTimestamp.chunkQueue.shift();
          this.writeBlock(trackWithMinTimestamp, chunk);
        }
      if (!isFinalCall) {
        await this.writer.flush();
      }
    }
    /**
     * Due to [a bug in Chromium](https://bugs.chromium.org/p/chromium/issues/detail?id=1377842), VP9 streams often
    	 * lack color space information. This method patches in that information.
     */
    fixVP9ColorSpace(trackData, chunk) {
      if (chunk.type !== "key") return;
      if (!trackData.info.decoderConfig.colorSpace || !trackData.info.decoderConfig.colorSpace.matrix) return;
      const bitstream = new Bitstream(chunk.data);
      bitstream.skipBits(2);
      const profileLowBit = bitstream.readBits(1);
      const profileHighBit = bitstream.readBits(1);
      const profile = (profileHighBit << 1) + profileLowBit;
      if (profile === 3) bitstream.skipBits(1);
      const showExistingFrame = bitstream.readBits(1);
      if (showExistingFrame) return;
      const frameType = bitstream.readBits(1);
      if (frameType !== 0) return;
      bitstream.skipBits(2);
      const syncCode = bitstream.readBits(24);
      if (syncCode !== 4817730) return;
      if (profile >= 2) bitstream.skipBits(1);
      const colorSpaceID = {
        rgb: 7,
        bt709: 2,
        bt470bg: 1,
        smpte170m: 3
      }[trackData.info.decoderConfig.colorSpace.matrix];
      writeBits(chunk.data, bitstream.pos, bitstream.pos + 3, colorSpaceID);
    }
    /** Converts a read-only external chunk into an internal one for easier use. */
    createInternalChunk(data, timestamp, duration, type, additions = null) {
      const internalChunk = {
        data,
        type,
        timestamp,
        duration,
        additions
      };
      return internalChunk;
    }
    /** Writes a block containing media data to the file. */
    writeBlock(trackData, chunk) {
      if (!this.segment) {
        this.createSegment();
      }
      const msTimestamp = Math.round(1e3 * chunk.timestamp);
      const keyFrameQueuedEverywhere = this.trackDatas.every((otherTrackData) => {
        if (trackData === otherTrackData) {
          return chunk.type === "key";
        }
        const firstQueuedSample = otherTrackData.chunkQueue[0];
        if (firstQueuedSample) {
          return firstQueuedSample.type === "key";
        }
        return otherTrackData.track.source._closed;
      });
      let shouldCreateNewCluster = false;
      if (!this.currentCluster) {
        shouldCreateNewCluster = true;
      } else {
        assert(this.currentClusterStartMsTimestamp !== null);
        assert(this.currentClusterMaxMsTimestamp !== null);
        const relativeTimestamp2 = msTimestamp - this.currentClusterStartMsTimestamp;
        shouldCreateNewCluster = keyFrameQueuedEverywhere && msTimestamp > this.currentClusterMaxMsTimestamp && relativeTimestamp2 >= 1e3 * (this.format._options.minimumClusterDuration ?? 1) || relativeTimestamp2 > MAX_CLUSTER_TIMESTAMP_MS;
      }
      if (shouldCreateNewCluster) {
        this.createNewCluster(msTimestamp);
      }
      const relativeTimestamp = msTimestamp - this.currentClusterStartMsTimestamp;
      if (relativeTimestamp < MIN_CLUSTER_TIMESTAMP_MS) {
        return;
      }
      const prelude = new Uint8Array(4);
      const view2 = new DataView(prelude.buffer);
      view2.setUint8(0, 128 | trackData.track.id);
      view2.setInt16(1, relativeTimestamp, false);
      const msDuration = Math.round(1e3 * chunk.duration);
      if (!chunk.additions) {
        view2.setUint8(3, Number(chunk.type === "key") << 7);
        const simpleBlock = { id: 163 /* SimpleBlock */, data: [
          prelude,
          chunk.data
        ] };
        this.ebmlWriter.writeEBML(simpleBlock);
      } else {
        const blockGroup = { id: 160 /* BlockGroup */, data: [
          { id: 161 /* Block */, data: [
            prelude,
            chunk.data
          ] },
          chunk.type === "delta" ? {
            id: 251 /* ReferenceBlock */,
            data: new EBMLSignedInt(trackData.lastWrittenMsTimestamp - msTimestamp)
          } : null,
          chunk.additions ? { id: 30113 /* BlockAdditions */, data: [
            { id: 166 /* BlockMore */, data: [
              { id: 238 /* BlockAddID */, data: 1 },
              // Some players expect BlockAddID to come first
              { id: 165 /* BlockAdditional */, data: chunk.additions }
            ] }
          ] } : null,
          msDuration > 0 ? { id: 155 /* BlockDuration */, data: msDuration } : null
        ] };
        this.ebmlWriter.writeEBML(blockGroup);
      }
      this.duration = Math.max(this.duration, msTimestamp + msDuration);
      trackData.lastWrittenMsTimestamp = msTimestamp;
      if (!this.trackDatasInCurrentCluster.has(trackData)) {
        this.trackDatasInCurrentCluster.set(trackData, {
          firstMsTimestamp: msTimestamp
        });
      }
      this.currentClusterMaxMsTimestamp = Math.max(this.currentClusterMaxMsTimestamp, msTimestamp);
    }
    /** Creates a new Cluster element to contain media chunks. */
    createNewCluster(msTimestamp) {
      if (this.currentCluster) {
        this.finalizeCurrentCluster();
      }
      if (this.format._options.onCluster) {
        this.writer.startTrackingWrites();
      }
      this.currentCluster = {
        id: 524531317 /* Cluster */,
        size: this.format._options.appendOnly ? -1 : CLUSTER_SIZE_BYTES,
        data: [
          { id: 231 /* Timestamp */, data: msTimestamp }
        ]
      };
      this.ebmlWriter.writeEBML(this.currentCluster);
      this.currentClusterStartMsTimestamp = msTimestamp;
      this.currentClusterMaxMsTimestamp = msTimestamp;
      this.trackDatasInCurrentCluster.clear();
    }
    finalizeCurrentCluster() {
      assert(this.currentCluster);
      if (!this.format._options.appendOnly) {
        const clusterSize = this.writer.getPos() - this.ebmlWriter.dataOffsets.get(this.currentCluster);
        const endPos = this.writer.getPos();
        this.writer.seek(this.ebmlWriter.offsets.get(this.currentCluster) + 4);
        this.ebmlWriter.writeVarInt(clusterSize, CLUSTER_SIZE_BYTES);
        this.writer.seek(endPos);
      }
      if (this.format._options.onCluster) {
        assert(this.currentClusterStartMsTimestamp !== null);
        const { data, start } = this.writer.stopTrackingWrites();
        this.format._options.onCluster(data, start, this.currentClusterStartMsTimestamp / 1e3);
      }
      const clusterOffsetFromSegment = this.ebmlWriter.offsets.get(this.currentCluster) - this.segmentDataOffset;
      const groupedByTimestamp = /* @__PURE__ */ new Map();
      for (const [trackData, { firstMsTimestamp }] of this.trackDatasInCurrentCluster) {
        if (!groupedByTimestamp.has(firstMsTimestamp)) {
          groupedByTimestamp.set(firstMsTimestamp, []);
        }
        groupedByTimestamp.get(firstMsTimestamp).push(trackData);
      }
      const groupedAndSortedByTimestamp = [...groupedByTimestamp.entries()].sort((a, b) => a[0] - b[0]);
      for (const [msTimestamp, trackDatas] of groupedAndSortedByTimestamp) {
        assert(this.cues);
        this.cues.data.push({ id: 187 /* CuePoint */, data: [
          { id: 179 /* CueTime */, data: msTimestamp },
          // Create CueTrackPositions for each track that starts at this timestamp
          ...trackDatas.map((trackData) => {
            return { id: 183 /* CueTrackPositions */, data: [
              { id: 247 /* CueTrack */, data: trackData.track.id },
              { id: 241 /* CueClusterPosition */, data: clusterOffsetFromSegment }
            ] };
          })
        ] });
      }
    }
    // eslint-disable-next-line @typescript-eslint/no-misused-promises
    async onTrackClose() {
      const release = await this.mutex.acquire();
      if (this.allTracksAreKnown()) {
        this.allTracksKnown.resolve();
      }
      await this.interleaveChunks();
      release();
    }
    /** Finalizes the file, making it ready for use. Must be called after all media chunks have been added. */
    async finalize() {
      const release = await this.mutex.acquire();
      this.allTracksKnown.resolve();
      if (!this.segment) {
        this.createSegment();
      }
      await this.interleaveChunks(true);
      if (this.currentCluster) {
        this.finalizeCurrentCluster();
      }
      assert(this.cues);
      this.ebmlWriter.writeEBML(this.cues);
      if (!this.format._options.appendOnly) {
        const endPos = this.writer.getPos();
        const segmentSize = this.writer.getPos() - this.segmentDataOffset;
        this.writer.seek(this.ebmlWriter.offsets.get(this.segment) + 4);
        this.ebmlWriter.writeVarInt(segmentSize, SEGMENT_SIZE_BYTES);
        this.segmentDuration.data = new EBMLFloat64(this.duration);
        this.writer.seek(this.ebmlWriter.offsets.get(this.segmentDuration));
        this.ebmlWriter.writeEBML(this.segmentDuration);
        assert(this.seekHead);
        this.writer.seek(this.ebmlWriter.offsets.get(this.seekHead));
        this.maybeCreateSeekHead(true);
        this.ebmlWriter.writeEBML(this.seekHead);
        this.writer.seek(endPos);
      }
      release();
    }
  };

  // src/mp3/mp3-writer.ts
  var Mp3Writer = class {
    constructor(writer) {
      this.writer = writer;
      this.helper = new Uint8Array(8);
      this.helperView = new DataView(this.helper.buffer);
    }
    writeU32(value) {
      this.helperView.setUint32(0, value, false);
      this.writer.write(this.helper.subarray(0, 4));
    }
    writeXingFrame(data) {
      const startPos = this.writer.getPos();
      const firstByte = 255;
      const secondByte = 224 | data.mpegVersionId << 3 | data.layer << 1;
      let lowSamplingFrequency;
      if (data.mpegVersionId & 2) {
        lowSamplingFrequency = data.mpegVersionId & 1 ? 0 : 1;
      } else {
        lowSamplingFrequency = 1;
      }
      const padding = 0;
      const neededBytes = 155;
      let bitrateIndex = -1;
      const bitrateOffset = lowSamplingFrequency * 16 * 4 + data.layer * 16;
      for (let i = 0; i < 16; i++) {
        const kbr = KILOBIT_RATES[bitrateOffset + i];
        const size = computeMp3FrameSize(lowSamplingFrequency, data.layer, 1e3 * kbr, data.sampleRate, padding);
        if (size >= neededBytes) {
          bitrateIndex = i;
          break;
        }
      }
      if (bitrateIndex === -1) {
        throw new Error("No suitable bitrate found.");
      }
      const thirdByte = bitrateIndex << 4 | data.frequencyIndex << 2 | padding << 1;
      const fourthByte = data.channel << 6 | data.modeExtension << 4 | data.copyright << 3 | data.original << 2 | data.emphasis;
      this.helper[0] = firstByte;
      this.helper[1] = secondByte;
      this.helper[2] = thirdByte;
      this.helper[3] = fourthByte;
      this.writer.write(this.helper.subarray(0, 4));
      const xingOffset = getXingOffset(data.mpegVersionId, data.channel);
      this.writer.seek(startPos + xingOffset);
      this.writeU32(XING);
      let flags = 0;
      if (data.frameCount !== null) {
        flags |= 1;
      }
      if (data.fileSize !== null) {
        flags |= 2;
      }
      if (data.toc !== null) {
        flags |= 4;
      }
      this.writeU32(flags);
      this.writeU32(data.frameCount ?? 0);
      this.writeU32(data.fileSize ?? 0);
      this.writer.write(data.toc ?? new Uint8Array(100));
      const kilobitRate = KILOBIT_RATES[bitrateOffset + bitrateIndex];
      const frameSize = computeMp3FrameSize(
        lowSamplingFrequency,
        data.layer,
        1e3 * kilobitRate,
        data.sampleRate,
        padding
      );
      this.writer.seek(startPos + frameSize);
    }
  };

  // src/mp3/mp3-muxer.ts
  var Mp3Muxer = class extends Muxer {
    constructor(output, format) {
      super(output);
      this.xingFrameData = null;
      this.frameCount = 0;
      this.framePositions = [];
      this.xingFramePos = null;
      this.format = format;
      this.writer = output._writer;
      this.mp3Writer = new Mp3Writer(output._writer);
    }
    async start() {
      if (!metadataTagsAreEmpty(this.output._metadataTags)) {
        const id3Writer = new Id3V2Writer(this.writer);
        id3Writer.writeId3V2Tag(this.output._metadataTags);
      }
    }
    async getMimeType() {
      return "audio/mpeg";
    }
    async addEncodedVideoPacket() {
      throw new Error("MP3 does not support video.");
    }
    async addEncodedAudioPacket(track, packet) {
      const release = await this.mutex.acquire();
      try {
        const writeXingHeader = this.format._options.xingHeader !== false;
        if (!this.xingFrameData && writeXingHeader) {
          const view2 = toDataView(packet.data);
          if (view2.byteLength < 4) {
            throw new Error("Invalid MP3 header in sample.");
          }
          const word = view2.getUint32(0, false);
          const header = readMp3FrameHeader(word, null).header;
          if (!header) {
            throw new Error("Invalid MP3 header in sample.");
          }
          const xingOffset = getXingOffset(header.mpegVersionId, header.channel);
          if (view2.byteLength >= xingOffset + 4) {
            const word2 = view2.getUint32(xingOffset, false);
            const isXing = word2 === XING || word2 === INFO;
            if (isXing) {
              return;
            }
          }
          this.xingFrameData = {
            mpegVersionId: header.mpegVersionId,
            layer: header.layer,
            frequencyIndex: header.frequencyIndex,
            sampleRate: header.sampleRate,
            channel: header.channel,
            modeExtension: header.modeExtension,
            copyright: header.copyright,
            original: header.original,
            emphasis: header.emphasis,
            frameCount: null,
            fileSize: null,
            toc: null
          };
          this.xingFramePos = this.writer.getPos();
          this.mp3Writer.writeXingFrame(this.xingFrameData);
          this.frameCount++;
        }
        this.validateAndNormalizeTimestamp(track, packet.timestamp, packet.type === "key");
        this.writer.write(packet.data);
        this.frameCount++;
        await this.writer.flush();
        if (writeXingHeader) {
          this.framePositions.push(this.writer.getPos());
        }
      } finally {
        release();
      }
    }
    async addSubtitleCue() {
      throw new Error("MP3 does not support subtitles.");
    }
    async finalize() {
      if (!this.xingFrameData || this.xingFramePos === null) {
        return;
      }
      const release = await this.mutex.acquire();
      const endPos = this.writer.getPos();
      this.writer.seek(this.xingFramePos);
      const toc = new Uint8Array(100);
      for (let i = 0; i < 100; i++) {
        const index = Math.floor(this.framePositions.length * (i / 100));
        assert(index !== -1 && index < this.framePositions.length);
        const byteOffset = this.framePositions[index];
        toc[i] = 256 * (byteOffset / endPos);
      }
      this.xingFrameData.frameCount = this.frameCount;
      this.xingFrameData.fileSize = endPos;
      this.xingFrameData.toc = toc;
      if (this.format._options.onXingFrame) {
        this.writer.startTrackingWrites();
      }
      this.mp3Writer.writeXingFrame(this.xingFrameData);
      if (this.format._options.onXingFrame) {
        const { data, start } = this.writer.stopTrackingWrites();
        this.format._options.onXingFrame(data, start);
      }
      this.writer.seek(endPos);
      release();
    }
  };

  // src/ogg/ogg-muxer.ts
  var PAGE_SIZE_TARGET = 8192;
  var OggMuxer = class extends Muxer {
    constructor(output, format) {
      super(output);
      this.trackDatas = [];
      this.bosPagesWritten = false;
      this.allTracksKnown = promiseWithResolvers();
      this.pageBytes = new Uint8Array(MAX_PAGE_SIZE);
      this.pageView = new DataView(this.pageBytes.buffer);
      this.format = format;
      this.writer = output._writer;
      this.writer.ensureMonotonicity = true;
    }
    async start() {
    }
    async getMimeType() {
      await this.allTracksKnown.promise;
      return buildOggMimeType({
        codecStrings: this.trackDatas.map((x) => x.codecInfo.codec)
      });
    }
    addEncodedVideoPacket() {
      throw new Error("Video tracks are not supported.");
    }
    getTrackData(track, meta) {
      const existingTrackData = this.trackDatas.find((td) => td.track === track);
      if (existingTrackData) {
        return existingTrackData;
      }
      let serialNumber;
      do {
        serialNumber = Math.floor(2 ** 32 * Math.random());
      } while (this.trackDatas.some((td) => td.serialNumber === serialNumber));
      assert(track.source._codec === "vorbis" || track.source._codec === "opus");
      validateAudioChunkMetadata(meta);
      assert(meta);
      assert(meta.decoderConfig);
      const newTrackData = {
        track,
        serialNumber,
        internalSampleRate: track.source._codec === "opus" ? OPUS_SAMPLE_RATE : meta.decoderConfig.sampleRate,
        codecInfo: {
          codec: track.source._codec,
          vorbisInfo: null,
          opusInfo: null
        },
        vorbisLastBlocksize: null,
        packetQueue: [],
        currentTimestampInSamples: 0,
        pagesWritten: 0,
        currentGranulePosition: 0,
        currentLacingValues: [],
        currentPageData: [],
        currentPageSize: 27,
        currentPageStartsWithFreshPacket: true,
        currentPageStartTimestampInSamples: 0
      };
      this.queueHeaderPackets(newTrackData, meta);
      this.trackDatas.push(newTrackData);
      if (this.allTracksAreKnown()) {
        this.allTracksKnown.resolve();
      }
      return newTrackData;
    }
    queueHeaderPackets(trackData, meta) {
      assert(meta.decoderConfig);
      if (trackData.track.source._codec === "vorbis") {
        assert(meta.decoderConfig.description);
        const bytes2 = toUint8Array(meta.decoderConfig.description);
        if (bytes2[0] !== 2) {
          throw new TypeError("First byte of Vorbis decoder description must be 2.");
        }
        let pos = 1;
        const readPacketLength = () => {
          let length = 0;
          while (true) {
            const value = bytes2[pos++];
            if (value === void 0) {
              throw new TypeError("Vorbis decoder description is too short.");
            }
            length += value;
            if (value < 255) {
              return length;
            }
          }
        };
        const identificationHeaderLength = readPacketLength();
        const commentHeaderLength = readPacketLength();
        const setupHeaderLength = bytes2.length - pos;
        if (setupHeaderLength <= 0) {
          throw new TypeError("Vorbis decoder description is too short.");
        }
        const identificationHeader = bytes2.subarray(pos, pos += identificationHeaderLength);
        pos += commentHeaderLength;
        const setupHeader = bytes2.subarray(pos);
        const commentHeaderHeader = new Uint8Array(7);
        commentHeaderHeader[0] = 3;
        commentHeaderHeader[1] = 118;
        commentHeaderHeader[2] = 111;
        commentHeaderHeader[3] = 114;
        commentHeaderHeader[4] = 98;
        commentHeaderHeader[5] = 105;
        commentHeaderHeader[6] = 115;
        const commentHeader = createVorbisComments(commentHeaderHeader, this.output._metadataTags, true);
        trackData.packetQueue.push({
          data: identificationHeader,
          timestampInSamples: 0,
          durationInSamples: 0,
          forcePageFlush: true
        }, {
          data: commentHeader,
          timestampInSamples: 0,
          durationInSamples: 0,
          forcePageFlush: false
        }, {
          data: setupHeader,
          timestampInSamples: 0,
          durationInSamples: 0,
          forcePageFlush: true
          // The last header packet must flush the page
        });
        const view2 = toDataView(identificationHeader);
        const blockSizeByte = view2.getUint8(28);
        trackData.codecInfo.vorbisInfo = {
          blocksizes: [
            1 << (blockSizeByte & 15),
            1 << (blockSizeByte >> 4)
          ],
          modeBlockflags: parseModesFromVorbisSetupPacket(setupHeader).modeBlockflags
        };
      } else if (trackData.track.source._codec === "opus") {
        if (!meta.decoderConfig.description) {
          throw new TypeError("For Ogg, Opus decoder description is required.");
        }
        const identificationHeader = toUint8Array(meta.decoderConfig.description);
        const commentHeaderHeader = new Uint8Array(8);
        const commentHeaderHeaderView = toDataView(commentHeaderHeader);
        commentHeaderHeaderView.setUint32(0, 1332770163, false);
        commentHeaderHeaderView.setUint32(4, 1415669619, false);
        const commentHeader = createVorbisComments(commentHeaderHeader, this.output._metadataTags, true);
        trackData.packetQueue.push({
          data: identificationHeader,
          timestampInSamples: 0,
          durationInSamples: 0,
          forcePageFlush: true
        }, {
          data: commentHeader,
          timestampInSamples: 0,
          durationInSamples: 0,
          forcePageFlush: true
          // The last header packet must flush the page
        });
        trackData.codecInfo.opusInfo = {
          preSkip: parseOpusIdentificationHeader(identificationHeader).preSkip
        };
      }
    }
    async addEncodedAudioPacket(track, packet, meta) {
      const release = await this.mutex.acquire();
      try {
        const trackData = this.getTrackData(track, meta);
        this.validateAndNormalizeTimestamp(trackData.track, packet.timestamp, packet.type === "key");
        const currentTimestampInSamples = trackData.currentTimestampInSamples;
        const { durationInSamples, vorbisBlockSize } = extractSampleMetadata(
          packet.data,
          trackData.codecInfo,
          trackData.vorbisLastBlocksize
        );
        trackData.currentTimestampInSamples += durationInSamples;
        trackData.vorbisLastBlocksize = vorbisBlockSize;
        trackData.packetQueue.push({
          data: packet.data,
          timestampInSamples: currentTimestampInSamples,
          durationInSamples,
          forcePageFlush: false
        });
        await this.interleavePages();
      } finally {
        release();
      }
    }
    addSubtitleCue() {
      throw new Error("Subtitle tracks are not supported.");
    }
    allTracksAreKnown() {
      for (const track of this.output._tracks) {
        if (!track.source._closed && !this.trackDatas.some((x) => x.track === track)) {
          return false;
        }
      }
      return true;
    }
    async interleavePages(isFinalCall = false) {
      if (!this.bosPagesWritten) {
        if (!this.allTracksAreKnown() && !isFinalCall) {
          return;
        }
        for (const trackData of this.trackDatas) {
          while (trackData.packetQueue.length > 0) {
            const packet = trackData.packetQueue.shift();
            this.writePacket(trackData, packet, false);
            if (packet.forcePageFlush) {
              break;
            }
          }
        }
        this.bosPagesWritten = true;
      }
      outer:
        while (true) {
          let trackWithMinTimestamp = null;
          let minTimestamp = Infinity;
          for (const trackData of this.trackDatas) {
            if (!isFinalCall && trackData.packetQueue.length <= 1 && !trackData.track.source._closed) {
              break outer;
            }
            if (trackData.packetQueue.length > 0 && trackData.packetQueue[0].timestampInSamples < minTimestamp) {
              trackWithMinTimestamp = trackData;
              minTimestamp = trackData.packetQueue[0].timestampInSamples;
            }
          }
          if (!trackWithMinTimestamp) {
            break;
          }
          const packet = trackWithMinTimestamp.packetQueue.shift();
          const isFinalPacket = trackWithMinTimestamp.packetQueue.length === 0;
          this.writePacket(trackWithMinTimestamp, packet, isFinalPacket);
        }
      if (!isFinalCall) {
        await this.writer.flush();
      }
    }
    writePacket(trackData, packet, isFinalPacket) {
      const packetEndTimestampInSamples = packet.timestampInSamples + packet.durationInSamples;
      if (this.format._options.maximumPageDuration !== void 0) {
        const maxDurationInSamples = this.format._options.maximumPageDuration * trackData.internalSampleRate;
        if (trackData.currentLacingValues.length > 0 && packetEndTimestampInSamples - trackData.currentPageStartTimestampInSamples > maxDurationInSamples) {
          this.writePage(trackData, false);
        }
      }
      let remainingLength = packet.data.length;
      let dataStartOffset = 0;
      let dataOffset = 0;
      while (true) {
        if (trackData.currentLacingValues.length === 0 && dataStartOffset > 0) {
          trackData.currentPageStartsWithFreshPacket = false;
        }
        const segmentSize = Math.min(255, remainingLength);
        trackData.currentLacingValues.push(segmentSize);
        trackData.currentPageSize++;
        dataOffset += segmentSize;
        const segmentIsLastOfPacket = remainingLength < 255;
        if (trackData.currentLacingValues.length === 255) {
          const slice2 = packet.data.subarray(dataStartOffset, dataOffset);
          dataStartOffset = dataOffset;
          trackData.currentPageData.push(slice2);
          trackData.currentPageSize += slice2.length;
          this.writePage(trackData, isFinalPacket && segmentIsLastOfPacket);
          if (segmentIsLastOfPacket) {
            return;
          }
        }
        if (segmentIsLastOfPacket) {
          break;
        }
        remainingLength -= 255;
      }
      const slice = packet.data.subarray(dataStartOffset);
      trackData.currentPageData.push(slice);
      trackData.currentPageSize += slice.length;
      trackData.currentGranulePosition = packetEndTimestampInSamples;
      if (trackData.currentPageSize >= PAGE_SIZE_TARGET || packet.forcePageFlush) {
        this.writePage(trackData, isFinalPacket);
      }
    }
    writePage(trackData, isEos) {
      this.pageView.setUint32(0, OGGS, true);
      this.pageView.setUint8(4, 0);
      let headerType = 0;
      if (!trackData.currentPageStartsWithFreshPacket) {
        headerType |= 1;
      }
      if (trackData.pagesWritten === 0) {
        headerType |= 2;
      }
      if (isEos) {
        headerType |= 4;
      }
      this.pageView.setUint8(5, headerType);
      const granulePosition = trackData.currentLacingValues.every((x) => x === 255) ? -1 : trackData.currentGranulePosition;
      setInt64(this.pageView, 6, granulePosition, true);
      this.pageView.setUint32(14, trackData.serialNumber, true);
      this.pageView.setUint32(18, trackData.pagesWritten, true);
      this.pageView.setUint32(22, 0, true);
      this.pageView.setUint8(26, trackData.currentLacingValues.length);
      this.pageBytes.set(trackData.currentLacingValues, 27);
      let pos = 27 + trackData.currentLacingValues.length;
      for (const data of trackData.currentPageData) {
        this.pageBytes.set(data, pos);
        pos += data.length;
      }
      const slice = this.pageBytes.subarray(0, pos);
      const crc = computeOggPageCrc(slice);
      this.pageView.setUint32(22, crc, true);
      trackData.pagesWritten++;
      trackData.currentLacingValues.length = 0;
      trackData.currentPageData.length = 0;
      trackData.currentPageSize = 27;
      trackData.currentPageStartsWithFreshPacket = true;
      trackData.currentPageStartTimestampInSamples = trackData.currentGranulePosition;
      if (this.format._options.onPage) {
        this.writer.startTrackingWrites();
      }
      this.writer.write(slice);
      if (this.format._options.onPage) {
        const { data, start } = this.writer.stopTrackingWrites();
        this.format._options.onPage(data, start, trackData.track.source);
      }
    }
    // eslint-disable-next-line @typescript-eslint/no-misused-promises
    async onTrackClose() {
      const release = await this.mutex.acquire();
      if (this.allTracksAreKnown()) {
        this.allTracksKnown.resolve();
      }
      await this.interleavePages();
      release();
    }
    async finalize() {
      const release = await this.mutex.acquire();
      this.allTracksKnown.resolve();
      await this.interleavePages(true);
      for (const trackData of this.trackDatas) {
        if (trackData.currentLacingValues.length > 0) {
          this.writePage(trackData, true);
        }
      }
      release();
    }
  };

  // src/mpeg-ts/mpeg-ts-muxer.ts
  var PAT_PID = 0;
  var PMT_PID = 4096;
  var FIRST_TRACK_PID = 256;
  var VIDEO_STREAM_ID_BASE = 224;
  var AUDIO_STREAM_ID_BASE = 192;
  var AVC_AUD_NAL = new Uint8Array([9, 240]);
  var HEVC_AUD_NAL = new Uint8Array([70, 1]);
  var MpegTsMuxer = class extends Muxer {
    constructor(output, format) {
      super(output);
      this.trackDatas = [];
      this.tablesWritten = false;
      this.continuityCounters = /* @__PURE__ */ new Map();
      this.packetBuffer = new Uint8Array(TS_PACKET_SIZE);
      this.packetView = toDataView(this.packetBuffer);
      this.allTracksKnown = promiseWithResolvers();
      this.videoTrackIndex = 0;
      this.audioTrackIndex = 0;
      this.adaptationFieldBuffer = new Uint8Array(184);
      this.payloadBuffer = new Uint8Array(184);
      this.format = format;
      this.writer = output._writer;
      this.writer.ensureMonotonicity = true;
    }
    async start() {
    }
    async getMimeType() {
      await this.allTracksKnown.promise;
      return buildMpegTsMimeType(this.trackDatas.map((x) => x.codecString));
    }
    getVideoTrackData(track, meta) {
      const existingTrackData = this.trackDatas.find((x) => x.track === track);
      if (existingTrackData) {
        return existingTrackData;
      }
      validateVideoChunkMetadata(meta);
      assert(meta?.decoderConfig);
      const codec = track.source._codec;
      assert(codec === "avc" || codec === "hevc");
      const streamType = codec === "avc" ? 27 /* AVC */ : 36 /* HEVC */;
      const pid = FIRST_TRACK_PID + this.trackDatas.length;
      const streamId = VIDEO_STREAM_ID_BASE + this.videoTrackIndex++;
      const newTrackData = {
        track,
        pid,
        streamType,
        streamId,
        codecString: meta.decoderConfig.codec,
        timestampProcessingQueue: [],
        packetQueue: [],
        inputIsAnnexB: null,
        inputIsAdts: null,
        avcDecoderConfig: null,
        hevcDecoderConfig: null,
        adtsHeader: null,
        adtsHeaderBitstream: null,
        firstPacketWritten: false
      };
      this.trackDatas.push(newTrackData);
      if (this.allTracksAreKnown()) {
        this.allTracksKnown.resolve();
      }
      return newTrackData;
    }
    getAudioTrackData(track, meta) {
      const existingTrackData = this.trackDatas.find((x) => x.track === track);
      if (existingTrackData) {
        return existingTrackData;
      }
      validateAudioChunkMetadata(meta);
      assert(meta?.decoderConfig);
      const codec = track.source._codec;
      assert(codec === "aac" || codec === "mp3" || codec === "ac3" || codec === "eac3");
      let streamType;
      let streamId;
      switch (codec) {
        case "aac":
          {
            streamType = 15 /* AAC */;
            streamId = AUDIO_STREAM_ID_BASE + this.audioTrackIndex++;
          }
          ;
          break;
        case "mp3":
          {
            streamType = 3 /* MP3_MPEG1 */;
            streamId = AUDIO_STREAM_ID_BASE + this.audioTrackIndex++;
          }
          ;
          break;
        case "ac3":
          {
            streamType = 129 /* AC3_SYSTEM_A */;
            streamId = 189;
          }
          ;
          break;
        case "eac3":
          {
            streamType = 135 /* EAC3_SYSTEM_A */;
            streamId = 189;
          }
          ;
          break;
      }
      const pid = FIRST_TRACK_PID + this.trackDatas.length;
      const newTrackData = {
        track,
        pid,
        streamType,
        streamId,
        codecString: meta.decoderConfig.codec,
        timestampProcessingQueue: [],
        packetQueue: [],
        inputIsAnnexB: null,
        inputIsAdts: null,
        avcDecoderConfig: null,
        hevcDecoderConfig: null,
        adtsHeader: null,
        adtsHeaderBitstream: null,
        firstPacketWritten: false
      };
      this.trackDatas.push(newTrackData);
      if (this.allTracksAreKnown()) {
        this.allTracksKnown.resolve();
      }
      return newTrackData;
    }
    async addEncodedVideoPacket(track, packet, meta) {
      const release = await this.mutex.acquire();
      try {
        const trackData = this.getVideoTrackData(track, meta);
        const timestamp = this.validateAndNormalizeTimestamp(
          trackData.track,
          packet.timestamp,
          packet.type === "key"
        );
        const preparedData = this.prepareVideoPacket(trackData, packet, meta);
        if (packet.type === "key") {
          await this.flushTimestampQueue(trackData);
        }
        trackData.timestampProcessingQueue.push({
          data: preparedData,
          presentationTimestamp: timestamp,
          decodeTimestamp: null,
          isKeyframe: packet.type === "key"
        });
      } finally {
        release();
      }
    }
    async addEncodedAudioPacket(track, packet, meta) {
      const release = await this.mutex.acquire();
      try {
        const trackData = this.getAudioTrackData(track, meta);
        const timestamp = this.validateAndNormalizeTimestamp(
          trackData.track,
          packet.timestamp,
          packet.type === "key"
        );
        const preparedData = this.prepareAudioPacket(trackData, packet, meta);
        if (packet.type === "key") {
          await this.flushTimestampQueue(trackData);
        }
        trackData.timestampProcessingQueue.push({
          data: preparedData,
          presentationTimestamp: timestamp,
          decodeTimestamp: null,
          isKeyframe: packet.type === "key"
        });
      } finally {
        release();
      }
    }
    async addSubtitleCue() {
      throw new Error("MPEG-TS does not support subtitles.");
    }
    prepareVideoPacket(trackData, packet, meta) {
      const codec = trackData.track.source._codec;
      if (trackData.inputIsAnnexB === null) {
        const description = meta?.decoderConfig?.description;
        trackData.inputIsAnnexB = !description;
        if (!trackData.inputIsAnnexB) {
          const bytes2 = toUint8Array(description);
          if (codec === "avc") {
            trackData.avcDecoderConfig = deserializeAvcDecoderConfigurationRecord(bytes2);
          } else {
            trackData.hevcDecoderConfig = deserializeHevcDecoderConfigurationRecord(bytes2);
          }
        }
      }
      if (trackData.inputIsAnnexB) {
        return this.prepareAnnexBVideoPacket(packet.data, codec);
      } else {
        return this.prepareLengthPrefixedVideoPacket(trackData, packet, codec);
      }
    }
    prepareAnnexBVideoPacket(data, codec) {
      const nalUnits = [];
      for (const loc of iterateNalUnitsInAnnexB(data)) {
        const nalUnit = data.subarray(loc.offset, loc.offset + loc.length);
        const isAud = codec === "avc" ? extractNalUnitTypeForAvc(nalUnit[0]) === 9 /* AUD */ : extractNalUnitTypeForHevc(nalUnit[0]) === 35 /* AUD_NUT */;
        if (!isAud) {
          nalUnits.push(nalUnit);
        }
      }
      const aud = codec === "avc" ? AVC_AUD_NAL : HEVC_AUD_NAL;
      nalUnits.unshift(aud);
      return concatNalUnitsInAnnexB(nalUnits);
    }
    prepareLengthPrefixedVideoPacket(trackData, packet, codec) {
      const data = packet.data;
      const lengthSize = codec === "avc" ? trackData.avcDecoderConfig.lengthSizeMinusOne + 1 : trackData.hevcDecoderConfig.lengthSizeMinusOne + 1;
      const nalUnits = [];
      for (const loc of iterateNalUnitsInLengthPrefixed(data, lengthSize)) {
        const nalUnit = data.subarray(loc.offset, loc.offset + loc.length);
        const isAud = codec === "avc" ? extractNalUnitTypeForAvc(nalUnit[0]) === 9 /* AUD */ : extractNalUnitTypeForHevc(nalUnit[0]) === 35 /* AUD_NUT */;
        if (!isAud) {
          nalUnits.push(nalUnit);
        }
      }
      if (packet.type === "key") {
        if (codec === "avc") {
          const config = trackData.avcDecoderConfig;
          for (const pps of config.pictureParameterSets) {
            nalUnits.unshift(pps);
          }
          for (const sps of config.sequenceParameterSets) {
            nalUnits.unshift(sps);
          }
        } else {
          const config = trackData.hevcDecoderConfig;
          for (const arr of config.arrays) {
            if (arr.nalUnitType === 34 /* PPS_NUT */) {
              for (const nal of arr.nalUnits) {
                nalUnits.unshift(nal);
              }
            }
          }
          for (const arr of config.arrays) {
            if (arr.nalUnitType === 33 /* SPS_NUT */) {
              for (const nal of arr.nalUnits) {
                nalUnits.unshift(nal);
              }
            }
          }
          for (const arr of config.arrays) {
            if (arr.nalUnitType === 32 /* VPS_NUT */) {
              for (const nal of arr.nalUnits) {
                nalUnits.unshift(nal);
              }
            }
          }
        }
      }
      const aud = codec === "avc" ? AVC_AUD_NAL : HEVC_AUD_NAL;
      nalUnits.unshift(aud);
      return concatNalUnitsInAnnexB(nalUnits);
    }
    prepareAudioPacket(trackData, packet, meta) {
      const codec = trackData.track.source._codec;
      if (codec === "mp3" || codec === "ac3" || codec === "eac3") {
        return packet.data;
      }
      if (trackData.inputIsAdts === null) {
        const description = meta?.decoderConfig?.description;
        trackData.inputIsAdts = !description;
        if (!trackData.inputIsAdts) {
          const config = parseAacAudioSpecificConfig(toUint8Array(description));
          const template = buildAdtsHeaderTemplate(config);
          trackData.adtsHeader = template.header;
          trackData.adtsHeaderBitstream = template.bitstream;
        }
      }
      if (trackData.inputIsAdts) {
        return packet.data;
      }
      assert(trackData.adtsHeader);
      assert(trackData.adtsHeaderBitstream);
      const header = trackData.adtsHeader;
      const frameLength = packet.data.byteLength + header.byteLength;
      writeAdtsFrameLength(trackData.adtsHeaderBitstream, frameLength);
      const result = new Uint8Array(frameLength);
      result.set(header, 0);
      result.set(packet.data, header.byteLength);
      return result;
    }
    allTracksAreKnown() {
      for (const track of this.output._tracks) {
        if (!track.source._closed && !this.trackDatas.some((x) => x.track === track)) {
          return false;
        }
      }
      return true;
    }
    async flushTimestampQueue(trackData, alsoInterleave = true) {
      if (trackData.timestampProcessingQueue.length === 0) {
        return;
      }
      const sortedTimestamps = trackData.timestampProcessingQueue.map((packet) => packet.presentationTimestamp).sort((a, b) => a - b);
      for (let i = 0; i < trackData.timestampProcessingQueue.length; i++) {
        const queuedPacket = trackData.timestampProcessingQueue[i];
        queuedPacket.decodeTimestamp = sortedTimestamps[i];
        trackData.packetQueue.push(queuedPacket);
      }
      trackData.timestampProcessingQueue.length = 0;
      if (alsoInterleave) {
        await this.interleavePackets();
      }
    }
    async interleavePackets(isFinalCall = false) {
      if (!this.tablesWritten) {
        if (!this.allTracksAreKnown() && !isFinalCall) {
          return;
        }
        this.writeTables();
      }
      outer:
        while (true) {
          let trackWithMinTimestamp = null;
          let minTimestamp = Infinity;
          for (const trackData of this.trackDatas) {
            if (!isFinalCall && trackData.packetQueue.length === 0 && !trackData.track.source._closed) {
              break outer;
            }
            if (trackData.packetQueue.length > 0 && trackData.packetQueue[0].presentationTimestamp < minTimestamp) {
              trackWithMinTimestamp = trackData;
              minTimestamp = trackData.packetQueue[0].presentationTimestamp;
            }
          }
          if (!trackWithMinTimestamp) {
            break;
          }
          const queuedPacket = trackWithMinTimestamp.packetQueue.shift();
          this.writePesPacket(trackWithMinTimestamp, queuedPacket);
        }
      if (!isFinalCall) {
        await this.writer.flush();
      }
    }
    writeTables() {
      assert(!this.tablesWritten);
      this.writePsiSection(PAT_PID, PAT_SECTION);
      this.writePsiSection(PMT_PID, buildPmt(this.trackDatas));
      this.tablesWritten = true;
    }
    writePsiSection(pid, section) {
      let offset = 0;
      let isFirst = true;
      while (offset < section.length) {
        const pointerFieldSize = isFirst ? 1 : 0;
        const availablePayload = 184 - pointerFieldSize;
        const remainingData = section.length - offset;
        const chunkSize = Math.min(availablePayload, remainingData);
        let payload;
        if (isFirst) {
          payload = this.payloadBuffer.subarray(0, 1 + chunkSize);
          payload[0] = 0;
          payload.set(section.subarray(offset, offset + chunkSize), 1);
        } else {
          payload = section.subarray(offset, offset + chunkSize);
        }
        this.writeTsPacket(pid, isFirst, null, payload);
        offset += chunkSize;
        isFirst = false;
      }
    }
    writePesPacket(trackData, queuedPacket) {
      const includeDts = trackData.track.type === "video";
      const headerDataLength = includeDts ? 10 : 5;
      const pesHeaderBuffer = new Uint8Array(9 + headerDataLength);
      const pesView = toDataView(pesHeaderBuffer);
      const ptsDtsBitstream = new Bitstream(pesHeaderBuffer.subarray(9));
      setUint24(pesView, 0, 1, false);
      pesHeaderBuffer[3] = trackData.streamId;
      const pesPacketLength = trackData.track.type === "video" ? 0 : Math.min(8 + queuedPacket.data.length, 65535);
      pesView.setUint16(4, pesPacketLength, false);
      pesView.setUint8(6, 132);
      pesView.setUint8(7, includeDts ? 192 : 128);
      pesView.setUint8(8, headerDataLength);
      const pts = Math.round(queuedPacket.presentationTimestamp * TIMESCALE);
      ptsDtsBitstream.pos = 0;
      ptsDtsBitstream.writeBits(4, includeDts ? 3 : 2);
      ptsDtsBitstream.writeBits(3, pts >>> 30 & 7);
      ptsDtsBitstream.writeBits(1, 1);
      ptsDtsBitstream.writeBits(15, pts >>> 15 & 32767);
      ptsDtsBitstream.writeBits(1, 1);
      ptsDtsBitstream.writeBits(15, pts & 32767);
      ptsDtsBitstream.writeBits(1, 1);
      if (includeDts) {
        assert(queuedPacket.decodeTimestamp !== null);
        const dts = Math.round(queuedPacket.decodeTimestamp * TIMESCALE);
        ptsDtsBitstream.writeBits(4, 1);
        ptsDtsBitstream.writeBits(3, dts >>> 30 & 7);
        ptsDtsBitstream.writeBits(1, 1);
        ptsDtsBitstream.writeBits(15, dts >>> 15 & 32767);
        ptsDtsBitstream.writeBits(1, 1);
        ptsDtsBitstream.writeBits(15, dts & 32767);
        ptsDtsBitstream.writeBits(1, 1);
      }
      const totalLength = pesHeaderBuffer.length + queuedPacket.data.length;
      let offset = 0;
      let isFirstTsPacket = true;
      while (offset < totalLength) {
        const pusi = isFirstTsPacket;
        const remainingData = totalLength - offset;
        const randomAccessIndicator = isFirstTsPacket && queuedPacket.isKeyframe;
        const discontinuityIndicator = isFirstTsPacket && !trackData.firstPacketWritten;
        const basePaddingNeeded = Math.max(0, 184 - remainingData);
        let adaptationFieldSize;
        if (randomAccessIndicator || discontinuityIndicator) {
          adaptationFieldSize = Math.max(2, basePaddingNeeded);
        } else {
          adaptationFieldSize = basePaddingNeeded;
        }
        let adaptationField = null;
        if (adaptationFieldSize > 0) {
          const buf = this.adaptationFieldBuffer;
          if (adaptationFieldSize === 1) {
            buf[0] = 0;
          } else {
            buf[0] = adaptationFieldSize - 1;
            buf[1] = Number(discontinuityIndicator) << 7 | Number(randomAccessIndicator) << 6;
            buf.fill(255, 2, adaptationFieldSize);
          }
          adaptationField = buf.subarray(0, adaptationFieldSize);
        }
        const payloadSize = Math.min(184 - adaptationFieldSize, remainingData);
        const payload = this.payloadBuffer.subarray(0, payloadSize);
        let payloadOffset = 0;
        if (offset < pesHeaderBuffer.length) {
          const headerBytes = Math.min(pesHeaderBuffer.length - offset, payloadSize);
          payload.set(pesHeaderBuffer.subarray(offset, offset + headerBytes), 0);
          payloadOffset = headerBytes;
        }
        const dataStart = Math.max(0, offset - pesHeaderBuffer.length);
        const dataEnd = dataStart + (payloadSize - payloadOffset);
        if (payloadOffset < payloadSize) {
          payload.set(queuedPacket.data.subarray(dataStart, dataEnd), payloadOffset);
        }
        this.writeTsPacket(trackData.pid, pusi, adaptationField, payload);
        offset += payloadSize;
        isFirstTsPacket = false;
      }
      trackData.firstPacketWritten = true;
    }
    writeTsPacket(pid, pusi, adaptationField, payload) {
      const cc = this.continuityCounters.get(pid) ?? 0;
      const hasPayload = payload.length > 0;
      const adaptCtrl = adaptationField ? hasPayload ? 3 : 2 : hasPayload ? 1 : 0;
      this.packetBuffer[0] = 71;
      this.packetView.setUint16(1, (pusi ? 16384 : 0) | pid & 8191, false);
      this.packetBuffer[3] = adaptCtrl << 4 | cc & 15;
      if (hasPayload) {
        this.continuityCounters.set(pid, cc + 1 & 15);
      }
      let offset = 4;
      if (adaptationField) {
        this.packetBuffer.set(adaptationField, offset);
        offset += adaptationField.length;
      }
      this.packetBuffer.set(payload, offset);
      offset += payload.length;
      if (offset < TS_PACKET_SIZE) {
        this.packetBuffer.fill(255, offset);
      }
      const startPos = this.writer.getPos();
      this.writer.write(this.packetBuffer);
      if (this.format._options.onPacket) {
        this.format._options.onPacket(this.packetBuffer.slice(), startPos);
      }
    }
    // eslint-disable-next-line @typescript-eslint/no-misused-promises
    async onTrackClose(track) {
      const release = await this.mutex.acquire();
      if (this.allTracksAreKnown()) {
        this.allTracksKnown.resolve();
      }
      const trackData = this.trackDatas.find((x) => x.track === track);
      if (trackData) {
        await this.flushTimestampQueue(trackData, false);
      }
      await this.interleavePackets();
      release();
    }
    async finalize() {
      const release = await this.mutex.acquire();
      this.allTracksKnown.resolve();
      for (const trackData of this.trackDatas) {
        await this.flushTimestampQueue(trackData, false);
      }
      await this.interleavePackets(true);
      release();
    }
  };
  var MPEG_TS_CRC_POLYNOMIAL = 79764919;
  var MPEG_TS_CRC_TABLE = new Uint32Array(256);
  for (let n = 0; n < 256; n++) {
    let crc = n << 24;
    for (let k = 0; k < 8; k++) {
      crc = crc & 2147483648 ? crc << 1 ^ MPEG_TS_CRC_POLYNOMIAL : crc << 1;
    }
    MPEG_TS_CRC_TABLE[n] = crc >>> 0 & 4294967295;
  }
  var computeMpegTsCrc32 = (data) => {
    let crc = 4294967295;
    for (let i = 0; i < data.length; i++) {
      const byte = data[i];
      crc = (crc << 8 ^ MPEG_TS_CRC_TABLE[crc >>> 24 ^ byte]) >>> 0;
    }
    return crc;
  };
  var PAT_SECTION = new Uint8Array(16);
  {
    const view2 = toDataView(PAT_SECTION);
    PAT_SECTION[0] = 0;
    view2.setUint16(1, 45069, false);
    view2.setUint16(3, 1, false);
    PAT_SECTION[5] = 193;
    PAT_SECTION[6] = 0;
    PAT_SECTION[7] = 0;
    view2.setUint16(8, 1, false);
    view2.setUint16(10, 57344 | PMT_PID & 8191, false);
    view2.setUint32(12, computeMpegTsCrc32(PAT_SECTION.subarray(0, 12)), false);
  }
  var buildPmt = (trackDatas) => {
    let totalEsBytes = 0;
    for (const trackData of trackDatas) {
      totalEsBytes += 5;
      if (trackData.streamType === 129 /* AC3_SYSTEM_A */) {
        totalEsBytes += AC3_REGISTRATION_DESCRIPTOR.length;
      } else if (trackData.streamType === 135 /* EAC3_SYSTEM_A */) {
        totalEsBytes += EAC3_REGISTRATION_DESCRIPTOR.length;
      }
    }
    const sectionLength = 9 + totalEsBytes + 4;
    const section = new Uint8Array(3 + sectionLength - 4);
    const view2 = toDataView(section);
    section[0] = 2;
    view2.setUint16(1, 45056 | sectionLength & 4095, false);
    view2.setUint16(3, 1, false);
    section[5] = 193;
    section[6] = 0;
    section[7] = 0;
    view2.setUint16(8, 57344 | 8191, false);
    view2.setUint16(10, 61440, false);
    let offset = 12;
    for (const trackData of trackDatas) {
      section[offset++] = trackData.streamType;
      view2.setUint16(offset, 57344 | trackData.pid & 8191, false);
      offset += 2;
      if (trackData.streamType === 129 /* AC3_SYSTEM_A */) {
        view2.setUint16(offset, 61440 | AC3_REGISTRATION_DESCRIPTOR.length, false);
        offset += 2;
        section.set(AC3_REGISTRATION_DESCRIPTOR, offset);
        offset += AC3_REGISTRATION_DESCRIPTOR.length;
      } else if (trackData.streamType === 135 /* EAC3_SYSTEM_A */) {
        view2.setUint16(offset, 61440 | EAC3_REGISTRATION_DESCRIPTOR.length, false);
        offset += 2;
        section.set(EAC3_REGISTRATION_DESCRIPTOR, offset);
        offset += EAC3_REGISTRATION_DESCRIPTOR.length;
      } else {
        view2.setUint16(offset, 61440, false);
        offset += 2;
      }
    }
    const crc = computeMpegTsCrc32(section);
    const result = new Uint8Array(section.length + 4);
    result.set(section, 0);
    toDataView(result).setUint32(section.length, crc, false);
    return result;
  };

  // src/wave/riff-writer.ts
  var RiffWriter = class {
    constructor(writer) {
      this.writer = writer;
      this.helper = new Uint8Array(8);
      this.helperView = new DataView(this.helper.buffer);
    }
    writeU16(value) {
      this.helperView.setUint16(0, value, true);
      this.writer.write(this.helper.subarray(0, 2));
    }
    writeU32(value) {
      this.helperView.setUint32(0, value, true);
      this.writer.write(this.helper.subarray(0, 4));
    }
    writeU64(value) {
      this.helperView.setUint32(0, value, true);
      this.helperView.setUint32(4, Math.floor(value / 2 ** 32), true);
      this.writer.write(this.helper);
    }
    writeAscii(text) {
      this.writer.write(new TextEncoder().encode(text));
    }
  };

  // src/wave/wave-muxer.ts
  var WaveMuxer = class extends Muxer {
    constructor(output, format) {
      super(output);
      this.headerWritten = false;
      this.dataSize = 0;
      this.sampleRate = null;
      this.sampleCount = 0;
      this.riffSizePos = null;
      this.dataSizePos = null;
      this.ds64RiffSizePos = null;
      this.ds64DataSizePos = null;
      this.ds64SampleCountPos = null;
      this.format = format;
      this.writer = output._writer;
      this.riffWriter = new RiffWriter(output._writer);
      this.isRf64 = !!format._options.large;
    }
    async start() {
    }
    async getMimeType() {
      return "audio/wav";
    }
    async addEncodedVideoPacket() {
      throw new Error("WAVE does not support video.");
    }
    async addEncodedAudioPacket(track, packet, meta) {
      const release = await this.mutex.acquire();
      try {
        if (!this.headerWritten) {
          validateAudioChunkMetadata(meta);
          assert(meta);
          assert(meta.decoderConfig);
          this.writeHeader(track, meta.decoderConfig);
          this.sampleRate = meta.decoderConfig.sampleRate;
          this.headerWritten = true;
        }
        this.validateAndNormalizeTimestamp(track, packet.timestamp, packet.type === "key");
        if (!this.isRf64 && this.writer.getPos() + packet.data.byteLength >= 2 ** 32) {
          throw new Error(
            "Adding more audio data would exceed the maximum RIFF size of 4 GiB. To write larger files, use RF64 by setting `large: true` in the WavOutputFormatOptions."
          );
        }
        this.writer.write(packet.data);
        this.dataSize += packet.data.byteLength;
        this.sampleCount += Math.round(packet.duration * this.sampleRate);
        await this.writer.flush();
      } finally {
        release();
      }
    }
    async addSubtitleCue() {
      throw new Error("WAVE does not support subtitles.");
    }
    writeHeader(track, config) {
      if (this.format._options.onHeader) {
        this.writer.startTrackingWrites();
      }
      let format;
      const codec = track.source._codec;
      const pcmInfo = parsePcmCodec(codec);
      if (pcmInfo.dataType === "ulaw") {
        format = 7 /* MULAW */;
      } else if (pcmInfo.dataType === "alaw") {
        format = 6 /* ALAW */;
      } else if (pcmInfo.dataType === "float") {
        format = 3 /* IEEE_FLOAT */;
      } else {
        format = 1 /* PCM */;
      }
      const channels = config.numberOfChannels;
      const sampleRate = config.sampleRate;
      const blockSize = pcmInfo.sampleSize * channels;
      this.riffWriter.writeAscii(this.isRf64 ? "RF64" : "RIFF");
      if (this.isRf64) {
        this.riffWriter.writeU32(4294967295);
      } else {
        this.riffSizePos = this.writer.getPos();
        this.riffWriter.writeU32(0);
      }
      this.riffWriter.writeAscii("WAVE");
      if (this.isRf64) {
        this.riffWriter.writeAscii("ds64");
        this.riffWriter.writeU32(28);
        this.ds64RiffSizePos = this.writer.getPos();
        this.riffWriter.writeU64(0);
        this.ds64DataSizePos = this.writer.getPos();
        this.riffWriter.writeU64(0);
        this.ds64SampleCountPos = this.writer.getPos();
        this.riffWriter.writeU64(0);
        this.riffWriter.writeU32(0);
      }
      this.riffWriter.writeAscii("fmt ");
      this.riffWriter.writeU32(16);
      this.riffWriter.writeU16(format);
      this.riffWriter.writeU16(channels);
      this.riffWriter.writeU32(sampleRate);
      this.riffWriter.writeU32(sampleRate * blockSize);
      this.riffWriter.writeU16(blockSize);
      this.riffWriter.writeU16(8 * pcmInfo.sampleSize);
      if (!metadataTagsAreEmpty(this.output._metadataTags)) {
        const metadataFormat = this.format._options.metadataFormat ?? "info";
        if (metadataFormat === "info") {
          this.writeInfoChunk(this.output._metadataTags);
        } else if (metadataFormat === "id3") {
          this.writeId3Chunk(this.output._metadataTags);
        } else {
          assertNever(metadataFormat);
        }
      }
      this.riffWriter.writeAscii("data");
      if (this.isRf64) {
        this.riffWriter.writeU32(4294967295);
      } else {
        this.dataSizePos = this.writer.getPos();
        this.riffWriter.writeU32(0);
      }
      if (this.format._options.onHeader) {
        const { data, start } = this.writer.stopTrackingWrites();
        this.format._options.onHeader(data, start);
      }
    }
    writeInfoChunk(metadata) {
      const startPos = this.writer.getPos();
      this.riffWriter.writeAscii("LIST");
      this.riffWriter.writeU32(0);
      this.riffWriter.writeAscii("INFO");
      const writtenTags = /* @__PURE__ */ new Set();
      const writeInfoTag = (tag, value) => {
        if (!isIso88591Compatible(value)) {
          console.warn(`Didn't write tag '${tag}' because '${value}' is not ISO 8859-1-compatible.`);
          return;
        }
        const size = value.length + 1;
        const bytes2 = new Uint8Array(size);
        for (let i = 0; i < value.length; i++) {
          bytes2[i] = value.charCodeAt(i);
        }
        this.riffWriter.writeAscii(tag);
        this.riffWriter.writeU32(size);
        this.writer.write(bytes2);
        if (size & 1) {
          this.writer.write(new Uint8Array(1));
        }
        writtenTags.add(tag);
      };
      for (const { key, value } of keyValueIterator(metadata)) {
        switch (key) {
          case "title":
            {
              writeInfoTag("INAM", value);
              writtenTags.add("INAM");
            }
            ;
            break;
          case "artist":
            {
              writeInfoTag("IART", value);
              writtenTags.add("IART");
            }
            ;
            break;
          case "album":
            {
              writeInfoTag("IPRD", value);
              writtenTags.add("IPRD");
            }
            ;
            break;
          case "trackNumber":
            {
              const string = metadata.tracksTotal !== void 0 ? `${value}/${metadata.tracksTotal}` : value.toString();
              writeInfoTag("ITRK", string);
              writtenTags.add("ITRK");
            }
            ;
            break;
          case "genre":
            {
              writeInfoTag("IGNR", value);
              writtenTags.add("IGNR");
            }
            ;
            break;
          case "date":
            {
              writeInfoTag("ICRD", value.toISOString().slice(0, 10));
              writtenTags.add("ICRD");
            }
            ;
            break;
          case "comment":
            {
              writeInfoTag("ICMT", value);
              writtenTags.add("ICMT");
            }
            ;
            break;
          case "albumArtist":
          case "discNumber":
          case "tracksTotal":
          case "discsTotal":
          case "description":
          case "lyrics":
          case "images":
            {
            }
            ;
            break;
          case "raw":
            {
            }
            ;
            break;
          default:
            assertNever(key);
        }
      }
      if (metadata.raw) {
        for (const key in metadata.raw) {
          const value = metadata.raw[key];
          if (value == null || key.length !== 4 || writtenTags.has(key)) {
            continue;
          }
          if (typeof value === "string") {
            writeInfoTag(key, value);
          }
        }
      }
      const endPos = this.writer.getPos();
      const chunkSize = endPos - startPos - 8;
      this.writer.seek(startPos + 4);
      this.riffWriter.writeU32(chunkSize);
      this.writer.seek(endPos);
      if (chunkSize & 1) {
        this.writer.write(new Uint8Array(1));
      }
    }
    writeId3Chunk(metadata) {
      const startPos = this.writer.getPos();
      this.riffWriter.writeAscii("ID3 ");
      this.riffWriter.writeU32(0);
      const id3Writer = new Id3V2Writer(this.writer);
      const id3TagSize = id3Writer.writeId3V2Tag(metadata);
      const endPos = this.writer.getPos();
      this.writer.seek(startPos + 4);
      this.riffWriter.writeU32(id3TagSize);
      this.writer.seek(endPos);
      if (id3TagSize & 1) {
        this.writer.write(new Uint8Array(1));
      }
    }
    async finalize() {
      const release = await this.mutex.acquire();
      const endPos = this.writer.getPos();
      if (this.isRf64) {
        assert(this.ds64RiffSizePos !== null);
        this.writer.seek(this.ds64RiffSizePos);
        this.riffWriter.writeU64(endPos - 8);
        assert(this.ds64DataSizePos !== null);
        this.writer.seek(this.ds64DataSizePos);
        this.riffWriter.writeU64(this.dataSize);
        assert(this.ds64SampleCountPos !== null);
        this.writer.seek(this.ds64SampleCountPos);
        this.riffWriter.writeU64(this.sampleCount);
      } else {
        assert(this.riffSizePos !== null);
        this.writer.seek(this.riffSizePos);
        this.riffWriter.writeU32(endPos - 8);
        assert(this.dataSizePos !== null);
        this.writer.seek(this.dataSizePos);
        this.riffWriter.writeU32(this.dataSize);
      }
      this.writer.seek(endPos);
      release();
    }
  };

  // src/output-format.ts
  var OutputFormat = class {
    /** Returns a list of video codecs that this output format can contain. */
    getSupportedVideoCodecs() {
      return this.getSupportedCodecs().filter((codec) => VIDEO_CODECS.includes(codec));
    }
    /** Returns a list of audio codecs that this output format can contain. */
    getSupportedAudioCodecs() {
      return this.getSupportedCodecs().filter((codec) => AUDIO_CODECS.includes(codec));
    }
    /** Returns a list of subtitle codecs that this output format can contain. */
    getSupportedSubtitleCodecs() {
      return this.getSupportedCodecs().filter((codec) => SUBTITLE_CODECS.includes(codec));
    }
    /** @internal */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    _codecUnsupportedHint(codec) {
      return "";
    }
  };
  var IsobmffOutputFormat2 = class extends OutputFormat {
    /** Internal constructor. */
    constructor(options = {}) {
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (options.fastStart !== void 0 && ![false, "in-memory", "reserve", "fragmented"].includes(options.fastStart)) {
        throw new TypeError(
          "options.fastStart, when provided, must be false, 'in-memory', 'reserve', or 'fragmented'."
        );
      }
      if (options.minimumFragmentDuration !== void 0 && (!Number.isFinite(options.minimumFragmentDuration) || options.minimumFragmentDuration < 0)) {
        throw new TypeError("options.minimumFragmentDuration, when provided, must be a non-negative number.");
      }
      if (options.onFtyp !== void 0 && typeof options.onFtyp !== "function") {
        throw new TypeError("options.onFtyp, when provided, must be a function.");
      }
      if (options.onMoov !== void 0 && typeof options.onMoov !== "function") {
        throw new TypeError("options.onMoov, when provided, must be a function.");
      }
      if (options.onMdat !== void 0 && typeof options.onMdat !== "function") {
        throw new TypeError("options.onMdat, when provided, must be a function.");
      }
      if (options.onMoof !== void 0 && typeof options.onMoof !== "function") {
        throw new TypeError("options.onMoof, when provided, must be a function.");
      }
      if (options.metadataFormat !== void 0 && !["mdir", "mdta", "udta", "auto"].includes(options.metadataFormat)) {
        throw new TypeError(
          "options.metadataFormat, when provided, must be either 'auto', 'mdir', 'mdta', or 'udta'."
        );
      }
      super();
      this._options = options;
    }
    getSupportedTrackCounts() {
      const max = 2 ** 32 - 1;
      return {
        video: { min: 0, max },
        audio: { min: 0, max },
        subtitle: { min: 0, max },
        total: { min: 1, max }
      };
    }
    get supportsVideoRotationMetadata() {
      return true;
    }
    get supportsTimestampedMediaData() {
      return true;
    }
    /** @internal */
    _createMuxer(output) {
      return new IsobmffMuxer2(output, this);
    }
  };
  var Mp4OutputFormat = class extends IsobmffOutputFormat2 {
    /** Creates a new {@link Mp4OutputFormat} configured with the specified `options`. */
    constructor(options) {
      super(options);
    }
    /** @internal */
    get _name() {
      return "MP4";
    }
    get fileExtension() {
      return ".mp4";
    }
    get mimeType() {
      return "video/mp4";
    }
    getSupportedCodecs() {
      return [
        ...VIDEO_CODECS,
        ...NON_PCM_AUDIO_CODECS,
        // These are supported via ISO/IEC 23003-5:
        "pcm-s16",
        "pcm-s16be",
        "pcm-s24",
        "pcm-s24be",
        "pcm-s32",
        "pcm-s32be",
        "pcm-f32",
        "pcm-f32be",
        "pcm-f64",
        "pcm-f64be",
        ...SUBTITLE_CODECS
      ];
    }
    /** @internal */
    _codecUnsupportedHint(codec) {
      if (new MovOutputFormat().getSupportedCodecs().includes(codec)) {
        return " Switching to MOV will grant support for this codec.";
      }
      return "";
    }
  };
  var MovOutputFormat = class extends IsobmffOutputFormat2 {
    /** Creates a new {@link MovOutputFormat} configured with the specified `options`. */
    constructor(options) {
      super(options);
    }
    /** @internal */
    get _name() {
      return "MOV";
    }
    get fileExtension() {
      return ".mov";
    }
    get mimeType() {
      return "video/quicktime";
    }
    getSupportedCodecs() {
      return [
        ...VIDEO_CODECS,
        ...AUDIO_CODECS
      ];
    }
    /** @internal */
    _codecUnsupportedHint(codec) {
      if (new Mp4OutputFormat().getSupportedCodecs().includes(codec)) {
        return " Switching to MP4 will grant support for this codec.";
      }
      return "";
    }
  };
  var MkvOutputFormat2 = class extends OutputFormat {
    /** Creates a new {@link MkvOutputFormat} configured with the specified `options`. */
    constructor(options = {}) {
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (options.appendOnly !== void 0 && typeof options.appendOnly !== "boolean") {
        throw new TypeError("options.appendOnly, when provided, must be a boolean.");
      }
      if (options.minimumClusterDuration !== void 0 && (!Number.isFinite(options.minimumClusterDuration) || options.minimumClusterDuration < 0)) {
        throw new TypeError("options.minimumClusterDuration, when provided, must be a non-negative number.");
      }
      if (options.onEbmlHeader !== void 0 && typeof options.onEbmlHeader !== "function") {
        throw new TypeError("options.onEbmlHeader, when provided, must be a function.");
      }
      if (options.onSegmentHeader !== void 0 && typeof options.onSegmentHeader !== "function") {
        throw new TypeError("options.onHeader, when provided, must be a function.");
      }
      if (options.onCluster !== void 0 && typeof options.onCluster !== "function") {
        throw new TypeError("options.onCluster, when provided, must be a function.");
      }
      super();
      this._options = options;
    }
    /** @internal */
    _createMuxer(output) {
      return new MatroskaMuxer(output, this);
    }
    /** @internal */
    get _name() {
      return "Matroska";
    }
    getSupportedTrackCounts() {
      const max = 127;
      return {
        video: { min: 0, max },
        audio: { min: 0, max },
        subtitle: { min: 0, max },
        total: { min: 1, max }
      };
    }
    get fileExtension() {
      return ".mkv";
    }
    get mimeType() {
      return "video/x-matroska";
    }
    getSupportedCodecs() {
      return [
        ...VIDEO_CODECS,
        ...NON_PCM_AUDIO_CODECS,
        ...PCM_AUDIO_CODECS.filter((codec) => !["pcm-s8", "pcm-f32be", "pcm-f64be", "ulaw", "alaw"].includes(codec)),
        ...SUBTITLE_CODECS
      ];
    }
    get supportsVideoRotationMetadata() {
      return false;
    }
    get supportsTimestampedMediaData() {
      return true;
    }
  };
  var WebMOutputFormat = class extends MkvOutputFormat2 {
    /** Creates a new {@link WebMOutputFormat} configured with the specified `options`. */
    constructor(options) {
      super(options);
    }
    getSupportedCodecs() {
      return [
        ...VIDEO_CODECS.filter((codec) => ["vp8", "vp9", "av1"].includes(codec)),
        ...AUDIO_CODECS.filter((codec) => ["opus", "vorbis"].includes(codec)),
        ...SUBTITLE_CODECS
      ];
    }
    /** @internal */
    get _name() {
      return "WebM";
    }
    get fileExtension() {
      return ".webm";
    }
    get mimeType() {
      return "video/webm";
    }
    /** @internal */
    _codecUnsupportedHint(codec) {
      if (new MkvOutputFormat2().getSupportedCodecs().includes(codec)) {
        return " Switching to MKV will grant support for this codec.";
      }
      return "";
    }
  };
  var Mp3OutputFormat = class extends OutputFormat {
    /** Creates a new {@link Mp3OutputFormat} configured with the specified `options`. */
    constructor(options = {}) {
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (options.xingHeader !== void 0 && typeof options.xingHeader !== "boolean") {
        throw new TypeError("options.xingHeader, when provided, must be a boolean.");
      }
      if (options.onXingFrame !== void 0 && typeof options.onXingFrame !== "function") {
        throw new TypeError("options.onXingFrame, when provided, must be a function.");
      }
      super();
      this._options = options;
    }
    /** @internal */
    _createMuxer(output) {
      return new Mp3Muxer(output, this);
    }
    /** @internal */
    get _name() {
      return "MP3";
    }
    getSupportedTrackCounts() {
      return {
        video: { min: 0, max: 0 },
        audio: { min: 1, max: 1 },
        subtitle: { min: 0, max: 0 },
        total: { min: 1, max: 1 }
      };
    }
    get fileExtension() {
      return ".mp3";
    }
    get mimeType() {
      return "audio/mpeg";
    }
    getSupportedCodecs() {
      return ["mp3"];
    }
    get supportsVideoRotationMetadata() {
      return false;
    }
    get supportsTimestampedMediaData() {
      return false;
    }
  };
  var WavOutputFormat = class extends OutputFormat {
    /** Creates a new {@link WavOutputFormat} configured with the specified `options`. */
    constructor(options = {}) {
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (options.large !== void 0 && typeof options.large !== "boolean") {
        throw new TypeError("options.large, when provided, must be a boolean.");
      }
      if (options.metadataFormat !== void 0 && !["info", "id3"].includes(options.metadataFormat)) {
        throw new TypeError("options.metadataFormat, when provided, must be either 'info' or 'id3'.");
      }
      if (options.onHeader !== void 0 && typeof options.onHeader !== "function") {
        throw new TypeError("options.onHeader, when provided, must be a function.");
      }
      super();
      this._options = options;
    }
    /** @internal */
    _createMuxer(output) {
      return new WaveMuxer(output, this);
    }
    /** @internal */
    get _name() {
      return "WAVE";
    }
    getSupportedTrackCounts() {
      return {
        video: { min: 0, max: 0 },
        audio: { min: 1, max: 1 },
        subtitle: { min: 0, max: 0 },
        total: { min: 1, max: 1 }
      };
    }
    get fileExtension() {
      return ".wav";
    }
    get mimeType() {
      return "audio/wav";
    }
    getSupportedCodecs() {
      return [
        ...PCM_AUDIO_CODECS.filter(
          (codec) => ["pcm-s16", "pcm-s24", "pcm-s32", "pcm-f32", "pcm-u8", "ulaw", "alaw"].includes(codec)
        )
      ];
    }
    get supportsVideoRotationMetadata() {
      return false;
    }
    get supportsTimestampedMediaData() {
      return false;
    }
  };
  var OggOutputFormat = class extends OutputFormat {
    /** Creates a new {@link OggOutputFormat} configured with the specified `options`. */
    constructor(options = {}) {
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (options.maximumPageDuration !== void 0 && (!Number.isFinite(options.maximumPageDuration) || options.maximumPageDuration <= 0)) {
        throw new TypeError("options.maximumPageDuration, when provided, must be a positive number.");
      }
      if (options.onPage !== void 0 && typeof options.onPage !== "function") {
        throw new TypeError("options.onPage, when provided, must be a function.");
      }
      super();
      this._options = options;
    }
    /** @internal */
    _createMuxer(output) {
      return new OggMuxer(output, this);
    }
    /** @internal */
    get _name() {
      return "Ogg";
    }
    getSupportedTrackCounts() {
      const max = 2 ** 32;
      return {
        video: { min: 0, max: 0 },
        audio: { min: 0, max },
        subtitle: { min: 0, max: 0 },
        total: { min: 1, max }
      };
    }
    get fileExtension() {
      return ".ogg";
    }
    get mimeType() {
      return "application/ogg";
    }
    getSupportedCodecs() {
      return [
        ...AUDIO_CODECS.filter((codec) => ["vorbis", "opus"].includes(codec))
      ];
    }
    get supportsVideoRotationMetadata() {
      return false;
    }
    get supportsTimestampedMediaData() {
      return false;
    }
  };
  var AdtsOutputFormat = class extends OutputFormat {
    /** Creates a new {@link AdtsOutputFormat} configured with the specified `options`. */
    constructor(options = {}) {
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (options.onFrame !== void 0 && typeof options.onFrame !== "function") {
        throw new TypeError("options.onFrame, when provided, must be a function.");
      }
      super();
      this._options = options;
    }
    /** @internal */
    _createMuxer(output) {
      return new AdtsMuxer(output, this);
    }
    /** @internal */
    get _name() {
      return "ADTS";
    }
    getSupportedTrackCounts() {
      return {
        video: { min: 0, max: 0 },
        audio: { min: 1, max: 1 },
        subtitle: { min: 0, max: 0 },
        total: { min: 1, max: 1 }
      };
    }
    get fileExtension() {
      return ".aac";
    }
    get mimeType() {
      return "audio/aac";
    }
    getSupportedCodecs() {
      return ["aac"];
    }
    get supportsVideoRotationMetadata() {
      return false;
    }
    get supportsTimestampedMediaData() {
      return false;
    }
  };
  var FlacOutputFormat = class extends OutputFormat {
    /** Creates a new {@link FlacOutputFormat} configured with the specified `options`. */
    constructor(options = {}) {
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      super();
      this._options = options;
    }
    /** @internal */
    _createMuxer(output) {
      return new FlacMuxer(output, this);
    }
    /** @internal */
    get _name() {
      return "FLAC";
    }
    getSupportedTrackCounts() {
      return {
        video: { min: 0, max: 0 },
        audio: { min: 1, max: 1 },
        subtitle: { min: 0, max: 0 },
        total: { min: 1, max: 1 }
      };
    }
    get fileExtension() {
      return ".flac";
    }
    get mimeType() {
      return "audio/flac";
    }
    getSupportedCodecs() {
      return ["flac"];
    }
    get supportsVideoRotationMetadata() {
      return false;
    }
    get supportsTimestampedMediaData() {
      return false;
    }
  };
  var MpegTsOutputFormat = class extends OutputFormat {
    /** Creates a new {@link MpegTsOutputFormat} configured with the specified `options`. */
    constructor(options = {}) {
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (options.onPacket !== void 0 && typeof options.onPacket !== "function") {
        throw new TypeError("options.onPacket, when provided, must be a function.");
      }
      super();
      this._options = options;
    }
    /** @internal */
    _createMuxer(output) {
      return new MpegTsMuxer(output, this);
    }
    /** @internal */
    get _name() {
      return "MPEG-TS";
    }
    getSupportedTrackCounts() {
      const maxVideo = 16;
      const maxAudio = 32;
      const maxTotal = maxVideo + maxAudio;
      return {
        video: { min: 0, max: maxVideo },
        audio: { min: 0, max: maxAudio },
        subtitle: { min: 0, max: 0 },
        total: { min: 1, max: maxTotal }
      };
    }
    get fileExtension() {
      return ".ts";
    }
    get mimeType() {
      return "video/MP2T";
    }
    getSupportedCodecs() {
      return [
        ...VIDEO_CODECS.filter((codec) => ["avc", "hevc"].includes(codec)),
        ...AUDIO_CODECS.filter((codec) => ["aac", "mp3", "ac3", "eac3"].includes(codec))
      ];
    }
    get supportsVideoRotationMetadata() {
      return false;
    }
    get supportsTimestampedMediaData() {
      return true;
    }
  };

  // src/encode.ts
  var validateVideoEncodingConfig = (config) => {
    if (!config || typeof config !== "object") {
      throw new TypeError("Encoding config must be an object.");
    }
    if (!VIDEO_CODECS.includes(config.codec)) {
      throw new TypeError(`Invalid video codec '${config.codec}'. Must be one of: ${VIDEO_CODECS.join(", ")}.`);
    }
    if (!(config.bitrate instanceof Quality) && (!Number.isInteger(config.bitrate) || config.bitrate <= 0)) {
      throw new TypeError("config.bitrate must be a positive integer or a quality.");
    }
    if (config.keyFrameInterval !== void 0 && (!Number.isFinite(config.keyFrameInterval) || config.keyFrameInterval < 0)) {
      throw new TypeError("config.keyFrameInterval, when provided, must be a non-negative number.");
    }
    if (config.sizeChangeBehavior !== void 0 && !["deny", "passThrough", "fill", "contain", "cover"].includes(config.sizeChangeBehavior)) {
      throw new TypeError(
        "config.sizeChangeBehavior, when provided, must be 'deny', 'passThrough', 'fill', 'contain' or 'cover'."
      );
    }
    if (config.onEncodedPacket !== void 0 && typeof config.onEncodedPacket !== "function") {
      throw new TypeError("config.onEncodedChunk, when provided, must be a function.");
    }
    if (config.onEncoderConfig !== void 0 && typeof config.onEncoderConfig !== "function") {
      throw new TypeError("config.onEncoderConfig, when provided, must be a function.");
    }
    validateVideoEncodingAdditionalOptions(config.codec, config);
  };
  var validateVideoEncodingAdditionalOptions = (codec, options) => {
    if (!options || typeof options !== "object") {
      throw new TypeError("Encoding options must be an object.");
    }
    if (options.alpha !== void 0 && !["discard", "keep"].includes(options.alpha)) {
      throw new TypeError("options.alpha, when provided, must be 'discard' or 'keep'.");
    }
    if (options.bitrateMode !== void 0 && !["constant", "variable"].includes(options.bitrateMode)) {
      throw new TypeError("bitrateMode, when provided, must be 'constant' or 'variable'.");
    }
    if (options.latencyMode !== void 0 && !["quality", "realtime"].includes(options.latencyMode)) {
      throw new TypeError("latencyMode, when provided, must be 'quality' or 'realtime'.");
    }
    if (options.fullCodecString !== void 0 && typeof options.fullCodecString !== "string") {
      throw new TypeError("fullCodecString, when provided, must be a string.");
    }
    if (options.fullCodecString !== void 0 && inferCodecFromCodecString(options.fullCodecString) !== codec) {
      throw new TypeError(
        `fullCodecString, when provided, must be a string that matches the specified codec (${codec}).`
      );
    }
    if (options.hardwareAcceleration !== void 0 && !["no-preference", "prefer-hardware", "prefer-software"].includes(options.hardwareAcceleration)) {
      throw new TypeError(
        "hardwareAcceleration, when provided, must be 'no-preference', 'prefer-hardware' or 'prefer-software'."
      );
    }
    if (options.scalabilityMode !== void 0 && typeof options.scalabilityMode !== "string") {
      throw new TypeError("scalabilityMode, when provided, must be a string.");
    }
    if (options.contentHint !== void 0 && typeof options.contentHint !== "string") {
      throw new TypeError("contentHint, when provided, must be a string.");
    }
  };
  var buildVideoEncoderConfig = (options) => {
    const resolvedBitrate = options.bitrate instanceof Quality ? options.bitrate._toVideoBitrate(options.codec, options.width, options.height) : options.bitrate;
    return {
      codec: options.fullCodecString ?? buildVideoCodecString(
        options.codec,
        options.width,
        options.height,
        resolvedBitrate
      ),
      width: options.width,
      height: options.height,
      bitrate: resolvedBitrate,
      bitrateMode: options.bitrateMode,
      alpha: options.alpha ?? "discard",
      framerate: options.framerate,
      latencyMode: options.latencyMode,
      hardwareAcceleration: options.hardwareAcceleration,
      scalabilityMode: options.scalabilityMode,
      contentHint: options.contentHint,
      ...getVideoEncoderConfigExtension(options.codec)
    };
  };
  var validateAudioEncodingConfig = (config) => {
    if (!config || typeof config !== "object") {
      throw new TypeError("Encoding config must be an object.");
    }
    if (!AUDIO_CODECS.includes(config.codec)) {
      throw new TypeError(`Invalid audio codec '${config.codec}'. Must be one of: ${AUDIO_CODECS.join(", ")}.`);
    }
    if (config.bitrate === void 0 && (!PCM_AUDIO_CODECS.includes(config.codec) || config.codec === "flac")) {
      throw new TypeError("config.bitrate must be provided for compressed audio codecs.");
    }
    if (config.bitrate !== void 0 && !(config.bitrate instanceof Quality) && (!Number.isInteger(config.bitrate) || config.bitrate <= 0)) {
      throw new TypeError("config.bitrate, when provided, must be a positive integer or a quality.");
    }
    if (config.onEncodedPacket !== void 0 && typeof config.onEncodedPacket !== "function") {
      throw new TypeError("config.onEncodedChunk, when provided, must be a function.");
    }
    if (config.onEncoderConfig !== void 0 && typeof config.onEncoderConfig !== "function") {
      throw new TypeError("config.onEncoderConfig, when provided, must be a function.");
    }
    validateAudioEncodingAdditionalOptions(config.codec, config);
  };
  var validateAudioEncodingAdditionalOptions = (codec, options) => {
    if (!options || typeof options !== "object") {
      throw new TypeError("Encoding options must be an object.");
    }
    if (options.bitrateMode !== void 0 && !["constant", "variable"].includes(options.bitrateMode)) {
      throw new TypeError("bitrateMode, when provided, must be 'constant' or 'variable'.");
    }
    if (options.fullCodecString !== void 0 && typeof options.fullCodecString !== "string") {
      throw new TypeError("fullCodecString, when provided, must be a string.");
    }
    if (options.fullCodecString !== void 0 && inferCodecFromCodecString(options.fullCodecString) !== codec) {
      throw new TypeError(
        `fullCodecString, when provided, must be a string that matches the specified codec (${codec}).`
      );
    }
  };
  var buildAudioEncoderConfig = (options) => {
    const resolvedBitrate = options.bitrate instanceof Quality ? options.bitrate._toAudioBitrate(options.codec) : options.bitrate;
    return {
      codec: options.fullCodecString ?? buildAudioCodecString(
        options.codec,
        options.numberOfChannels,
        options.sampleRate
      ),
      numberOfChannels: options.numberOfChannels,
      sampleRate: options.sampleRate,
      bitrate: resolvedBitrate,
      bitrateMode: options.bitrateMode,
      ...getAudioEncoderConfigExtension(options.codec)
    };
  };
  var Quality = class {
    /** @internal */
    constructor(factor) {
      this._factor = factor;
    }
    /** @internal */
    _toVideoBitrate(codec, width, height) {
      const pixels = width * height;
      const codecEfficiencyFactors = {
        avc: 1,
        // H.264/AVC (baseline)
        hevc: 0.6,
        // H.265/HEVC (~40% more efficient than AVC)
        vp9: 0.6,
        // Similar to HEVC
        av1: 0.4,
        // ~60% more efficient than AVC
        vp8: 1.2
        // Slightly less efficient than AVC
      };
      const referencePixels = 1920 * 1080;
      const referenceBitrate = 3e6;
      const scaleFactor = Math.pow(pixels / referencePixels, 0.95);
      const baseBitrate = referenceBitrate * scaleFactor;
      const codecAdjustedBitrate = baseBitrate * codecEfficiencyFactors[codec];
      const finalBitrate = codecAdjustedBitrate * this._factor;
      return Math.ceil(finalBitrate / 1e3) * 1e3;
    }
    /** @internal */
    _toAudioBitrate(codec) {
      if (PCM_AUDIO_CODECS.includes(codec) || codec === "flac") {
        return void 0;
      }
      const baseRates = {
        aac: 128e3,
        // 128kbps base for AAC
        opus: 64e3,
        // 64kbps base for Opus
        mp3: 16e4,
        // 160kbps base for MP3
        vorbis: 64e3,
        // 64kbps base for Vorbis
        ac3: 384e3,
        // 384kbps base for AC-3
        eac3: 192e3
        // 192kbps base for E-AC-3
      };
      const baseBitrate = baseRates[codec];
      if (!baseBitrate) {
        throw new Error(`Unhandled codec: ${codec}`);
      }
      let finalBitrate = baseBitrate * this._factor;
      if (codec === "aac") {
        const validRates = [96e3, 128e3, 16e4, 192e3];
        finalBitrate = validRates.reduce(
          (prev, curr) => Math.abs(curr - finalBitrate) < Math.abs(prev - finalBitrate) ? curr : prev
        );
      } else if (codec === "opus" || codec === "vorbis") {
        finalBitrate = Math.max(6e3, finalBitrate);
      } else if (codec === "mp3") {
        const validRates = [
          8e3,
          16e3,
          24e3,
          32e3,
          4e4,
          48e3,
          64e3,
          8e4,
          96e3,
          112e3,
          128e3,
          16e4,
          192e3,
          224e3,
          256e3,
          32e4
        ];
        finalBitrate = validRates.reduce(
          (prev, curr) => Math.abs(curr - finalBitrate) < Math.abs(prev - finalBitrate) ? curr : prev
        );
      }
      return Math.round(finalBitrate / 1e3) * 1e3;
    }
  };
  var QUALITY_VERY_LOW = /* @__PURE__ */ new Quality(0.3);
  var QUALITY_LOW = /* @__PURE__ */ new Quality(0.6);
  var QUALITY_MEDIUM = /* @__PURE__ */ new Quality(1);
  var QUALITY_HIGH = /* @__PURE__ */ new Quality(2);
  var QUALITY_VERY_HIGH = /* @__PURE__ */ new Quality(4);
  var canEncode = (codec) => {
    if (VIDEO_CODECS.includes(codec)) {
      return canEncodeVideo(codec);
    } else if (AUDIO_CODECS.includes(codec)) {
      return canEncodeAudio(codec);
    } else if (SUBTITLE_CODECS.includes(codec)) {
      return canEncodeSubtitles(codec);
    }
    throw new TypeError(`Unknown codec '${codec}'.`);
  };
  var canEncodeVideo = async (codec, options = {}) => {
    const {
      width = 1280,
      height = 720,
      bitrate = 1e6,
      ...restOptions
    } = options;
    if (!VIDEO_CODECS.includes(codec)) {
      return false;
    }
    if (!Number.isInteger(width) || width <= 0) {
      throw new TypeError("width must be a positive integer.");
    }
    if (!Number.isInteger(height) || height <= 0) {
      throw new TypeError("height must be a positive integer.");
    }
    if (!(bitrate instanceof Quality) && (!Number.isInteger(bitrate) || bitrate <= 0)) {
      throw new TypeError("bitrate must be a positive integer or a quality.");
    }
    validateVideoEncodingAdditionalOptions(codec, restOptions);
    let encoderConfig = null;
    if (customVideoEncoders.length > 0) {
      encoderConfig ??= buildVideoEncoderConfig({
        codec,
        width,
        height,
        bitrate,
        framerate: void 0,
        ...restOptions
      });
      if (customVideoEncoders.some((x) => x.supports(codec, encoderConfig))) {
        return true;
      }
    }
    if (typeof VideoEncoder === "undefined") {
      return false;
    }
    const hasOddDimension = width % 2 === 1 || height % 2 === 1;
    if (hasOddDimension && (codec === "avc" || codec === "hevc")) {
      return false;
    }
    encoderConfig ??= buildVideoEncoderConfig({
      codec,
      width,
      height,
      bitrate,
      framerate: void 0,
      ...restOptions,
      alpha: "discard"
      // Since we handle alpha ourselves
    });
    const support = await VideoEncoder.isConfigSupported(encoderConfig);
    if (!support.supported) {
      return false;
    }
    if (isFirefox()) {
      return new Promise(async (resolve) => {
        try {
          const encoder = new VideoEncoder({
            output: () => {
            },
            error: () => resolve(false)
          });
          encoder.configure(encoderConfig);
          const frameData = new Uint8Array(width * height * 4);
          const frame = new VideoFrame(frameData, {
            format: "RGBA",
            codedWidth: width,
            codedHeight: height,
            timestamp: 0
          });
          encoder.encode(frame);
          frame.close();
          await encoder.flush();
          resolve(true);
        } catch {
          resolve(false);
        }
      });
    } else {
      return true;
    }
  };
  var canEncodeAudio = async (codec, options = {}) => {
    const {
      numberOfChannels = 2,
      sampleRate = 48e3,
      bitrate = 128e3,
      ...restOptions
    } = options;
    if (!AUDIO_CODECS.includes(codec)) {
      return false;
    }
    if (!Number.isInteger(numberOfChannels) || numberOfChannels <= 0) {
      throw new TypeError("numberOfChannels must be a positive integer.");
    }
    if (!Number.isInteger(sampleRate) || sampleRate <= 0) {
      throw new TypeError("sampleRate must be a positive integer.");
    }
    if (!(bitrate instanceof Quality) && (!Number.isInteger(bitrate) || bitrate <= 0)) {
      throw new TypeError("bitrate must be a positive integer.");
    }
    validateAudioEncodingAdditionalOptions(codec, restOptions);
    let encoderConfig = null;
    if (customAudioEncoders.length > 0) {
      encoderConfig ??= buildAudioEncoderConfig({
        codec,
        numberOfChannels,
        sampleRate,
        bitrate,
        ...restOptions
      });
      if (customAudioEncoders.some((x) => x.supports(codec, encoderConfig))) {
        return true;
      }
    }
    if (PCM_AUDIO_CODECS.includes(codec)) {
      return true;
    }
    if (typeof AudioEncoder === "undefined") {
      return false;
    }
    encoderConfig ??= buildAudioEncoderConfig({
      codec,
      numberOfChannels,
      sampleRate,
      bitrate,
      ...restOptions
    });
    const support = await AudioEncoder.isConfigSupported(encoderConfig);
    return support.supported === true;
  };
  var canEncodeSubtitles = async (codec) => {
    if (!SUBTITLE_CODECS.includes(codec)) {
      return false;
    }
    return true;
  };
  var getEncodableCodecs = async () => {
    const [videoCodecs, audioCodecs, subtitleCodecs] = await Promise.all([
      getEncodableVideoCodecs(),
      getEncodableAudioCodecs(),
      getEncodableSubtitleCodecs()
    ]);
    return [...videoCodecs, ...audioCodecs, ...subtitleCodecs];
  };
  var getEncodableVideoCodecs = async (checkedCodecs = VIDEO_CODECS, options) => {
    const bools = await Promise.all(checkedCodecs.map((codec) => canEncodeVideo(codec, options)));
    return checkedCodecs.filter((_, i) => bools[i]);
  };
  var getEncodableAudioCodecs = async (checkedCodecs = AUDIO_CODECS, options) => {
    const bools = await Promise.all(checkedCodecs.map((codec) => canEncodeAudio(codec, options)));
    return checkedCodecs.filter((_, i) => bools[i]);
  };
  var getEncodableSubtitleCodecs = async (checkedCodecs = SUBTITLE_CODECS) => {
    const bools = await Promise.all(checkedCodecs.map(canEncodeSubtitles));
    return checkedCodecs.filter((_, i) => bools[i]);
  };
  var getFirstEncodableVideoCodec = async (checkedCodecs, options) => {
    for (const codec of checkedCodecs) {
      if (await canEncodeVideo(codec, options)) {
        return codec;
      }
    }
    return null;
  };
  var getFirstEncodableAudioCodec = async (checkedCodecs, options) => {
    for (const codec of checkedCodecs) {
      if (await canEncodeAudio(codec, options)) {
        return codec;
      }
    }
    return null;
  };
  var getFirstEncodableSubtitleCodec = async (checkedCodecs) => {
    for (const codec of checkedCodecs) {
      if (await canEncodeSubtitles(codec)) {
        return codec;
      }
    }
    return null;
  };

  // src/media-source.ts
  var MediaSource = class {
    constructor() {
      /** @internal */
      this._connectedTrack = null;
      /** @internal */
      this._closingPromise = null;
      /** @internal */
      this._closed = false;
      /**
       * @internal
       * A time offset in seconds that is added to all timestamps generated by this source.
       */
      this._timestampOffset = 0;
    }
    /** @internal */
    _ensureValidAdd() {
      if (!this._connectedTrack) {
        throw new Error("Source is not connected to an output track.");
      }
      if (this._connectedTrack.output.state === "canceled") {
        throw new Error("Output has been canceled.");
      }
      if (this._connectedTrack.output.state === "finalizing" || this._connectedTrack.output.state === "finalized") {
        throw new Error("Output has been finalized.");
      }
      if (this._connectedTrack.output.state === "pending") {
        throw new Error("Output has not started.");
      }
      if (this._closed) {
        throw new Error("Source is closed.");
      }
    }
    /** @internal */
    async _start() {
    }
    /** @internal */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    async _flushAndClose(forceClose) {
    }
    /**
     * Closes this source. This prevents future samples from being added and signals to the output file that no further
     * samples will come in for this track. Calling `.close()` is optional but recommended after adding the
     * last sample - for improved performance and reduced memory usage.
     */
    close() {
      if (this._closingPromise) {
        return;
      }
      const connectedTrack = this._connectedTrack;
      if (!connectedTrack) {
        throw new Error("Cannot call close without connecting the source to an output track.");
      }
      if (connectedTrack.output.state === "pending") {
        throw new Error("Cannot call close before output has been started.");
      }
      this._closingPromise = (async () => {
        await this._flushAndClose(false);
        this._closed = true;
        if (connectedTrack.output.state === "finalizing" || connectedTrack.output.state === "finalized") {
          return;
        }
        connectedTrack.output._muxer.onTrackClose(connectedTrack);
      })();
    }
    /** @internal */
    async _flushOrWaitForOngoingClose(forceClose) {
      return this._closingPromise ??= (async () => {
        await this._flushAndClose(forceClose);
        this._closed = true;
      })();
    }
  };
  var VideoSource = class extends MediaSource {
    /** Internal constructor. */
    constructor(codec) {
      super();
      /** @internal */
      this._connectedTrack = null;
      if (!VIDEO_CODECS.includes(codec)) {
        throw new TypeError(`Invalid video codec '${codec}'. Must be one of: ${VIDEO_CODECS.join(", ")}.`);
      }
      this._codec = codec;
    }
  };
  var EncodedVideoPacketSource = class extends VideoSource {
    /** Creates a new {@link EncodedVideoPacketSource} whose packets are encoded using `codec`. */
    constructor(codec) {
      super(codec);
    }
    /**
     * Adds an encoded packet to the output video track. Packets must be added in *decode order*, while a packet's
     * timestamp must be its *presentation timestamp*. B-frames are handled automatically.
     *
     * @param meta - Additional metadata from the encoder. You should pass this for the first call, including a valid
     * decoder config.
     *
     * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise
     * to respect writer and encoder backpressure.
     */
    add(packet, meta) {
      if (!(packet instanceof EncodedPacket)) {
        throw new TypeError("packet must be an EncodedPacket.");
      }
      if (packet.isMetadataOnly) {
        throw new TypeError("Metadata-only packets cannot be added.");
      }
      if (meta !== void 0 && (!meta || typeof meta !== "object")) {
        throw new TypeError("meta, when provided, must be an object.");
      }
      this._ensureValidAdd();
      return this._connectedTrack.output._muxer.addEncodedVideoPacket(this._connectedTrack, packet, meta);
    }
  };
  var VideoEncoderWrapper = class {
    constructor(source, encodingConfig) {
      this.source = source;
      this.encodingConfig = encodingConfig;
      this.ensureEncoderPromise = null;
      this.encoderInitialized = false;
      this.encoder = null;
      this.muxer = null;
      this.lastMultipleOfKeyFrameInterval = -1;
      this.codedWidth = null;
      this.codedHeight = null;
      this.resizeCanvas = null;
      this.customEncoder = null;
      this.customEncoderCallSerializer = new CallSerializer();
      this.customEncoderQueueSize = 0;
      // Alpha stuff
      this.alphaEncoder = null;
      this.splitter = null;
      this.splitterCreationFailed = false;
      this.alphaFrameQueue = [];
      /**
       * Encoders typically throw their errors "out of band", meaning asynchronously in some other execution context.
       * However, we want to surface these errors to the user within the normal control flow, so they don't go uncaught.
       * So, we keep track of the encoder error and throw it as soon as we get the chance.
       */
      this.error = null;
    }
    async add(videoSample, shouldClose, encodeOptions) {
      try {
        this.checkForEncoderError();
        this.source._ensureValidAdd();
        if (this.codedWidth !== null && this.codedHeight !== null) {
          if (videoSample.codedWidth !== this.codedWidth || videoSample.codedHeight !== this.codedHeight) {
            const sizeChangeBehavior = this.encodingConfig.sizeChangeBehavior ?? "deny";
            if (sizeChangeBehavior === "passThrough") {
            } else if (sizeChangeBehavior === "deny") {
              throw new Error(
                `Video sample size must remain constant. Expected ${this.codedWidth}x${this.codedHeight}, got ${videoSample.codedWidth}x${videoSample.codedHeight}. To allow the sample size to change over time, set \`sizeChangeBehavior\` to a value other than 'strict' in the encoding options.`
              );
            } else {
              let canvasIsNew = false;
              if (!this.resizeCanvas) {
                if (typeof document !== "undefined") {
                  this.resizeCanvas = document.createElement("canvas");
                  this.resizeCanvas.width = this.codedWidth;
                  this.resizeCanvas.height = this.codedHeight;
                } else {
                  this.resizeCanvas = new OffscreenCanvas(this.codedWidth, this.codedHeight);
                }
                canvasIsNew = true;
              }
              const context = this.resizeCanvas.getContext("2d", {
                alpha: isFirefox()
                // Firefox has VideoFrame glitches with opaque canvases
              });
              assert(context);
              if (!canvasIsNew) {
                if (isFirefox()) {
                  context.fillStyle = "black";
                  context.fillRect(0, 0, this.codedWidth, this.codedHeight);
                } else {
                  context.clearRect(0, 0, this.codedWidth, this.codedHeight);
                }
              }
              videoSample.drawWithFit(context, { fit: sizeChangeBehavior });
              if (shouldClose) {
                videoSample.close();
              }
              videoSample = new VideoSample(this.resizeCanvas, {
                timestamp: videoSample.timestamp,
                duration: videoSample.duration,
                rotation: videoSample.rotation
              });
              shouldClose = true;
            }
          }
        } else {
          this.codedWidth = videoSample.codedWidth;
          this.codedHeight = videoSample.codedHeight;
        }
        if (!this.encoderInitialized) {
          if (!this.ensureEncoderPromise) {
            this.ensureEncoder(videoSample);
          }
          if (!this.encoderInitialized) {
            await this.ensureEncoderPromise;
          }
        }
        assert(this.encoderInitialized);
        const keyFrameInterval = this.encodingConfig.keyFrameInterval ?? 5;
        const multipleOfKeyFrameInterval = Math.floor(videoSample.timestamp / keyFrameInterval);
        const finalEncodeOptions = {
          ...encodeOptions,
          keyFrame: encodeOptions?.keyFrame || keyFrameInterval === 0 || multipleOfKeyFrameInterval !== this.lastMultipleOfKeyFrameInterval
        };
        this.lastMultipleOfKeyFrameInterval = multipleOfKeyFrameInterval;
        if (this.customEncoder) {
          this.customEncoderQueueSize++;
          const clonedSample = videoSample.clone();
          const promise = this.customEncoderCallSerializer.call(() => this.customEncoder.encode(clonedSample, finalEncodeOptions)).then(() => this.customEncoderQueueSize--).catch((error) => this.error ??= error).finally(() => {
            clonedSample.close();
          });
          if (this.customEncoderQueueSize >= 4) {
            await promise;
          }
        } else {
          assert(this.encoder);
          const videoFrame = videoSample.toVideoFrame();
          if (!this.alphaEncoder) {
            this.encoder.encode(videoFrame, finalEncodeOptions);
            videoFrame.close();
          } else {
            const frameDefinitelyHasNoAlpha = !!videoFrame.format && !videoFrame.format.includes("A");
            if (frameDefinitelyHasNoAlpha || this.splitterCreationFailed) {
              this.alphaFrameQueue.push(null);
              this.encoder.encode(videoFrame, finalEncodeOptions);
              videoFrame.close();
            } else {
              const width = videoFrame.displayWidth;
              const height = videoFrame.displayHeight;
              if (!this.splitter) {
                try {
                  this.splitter = new ColorAlphaSplitter(width, height);
                } catch (error) {
                  console.error("Due to an error, only color data will be encoded.", error);
                  this.splitterCreationFailed = true;
                  this.alphaFrameQueue.push(null);
                  this.encoder.encode(videoFrame, finalEncodeOptions);
                  videoFrame.close();
                }
              }
              if (this.splitter) {
                const colorFrame = this.splitter.extractColor(videoFrame);
                const alphaFrame = this.splitter.extractAlpha(videoFrame);
                this.alphaFrameQueue.push(alphaFrame);
                this.encoder.encode(colorFrame, finalEncodeOptions);
                colorFrame.close();
                videoFrame.close();
              }
            }
          }
          if (shouldClose) {
            videoSample.close();
          }
          if (this.encoder.encodeQueueSize >= 4) {
            await new Promise((resolve) => this.encoder.addEventListener("dequeue", resolve, { once: true }));
          }
        }
        await this.muxer.mutex.currentPromise;
      } finally {
        if (shouldClose) {
          videoSample.close();
        }
      }
    }
    ensureEncoder(videoSample) {
      this.ensureEncoderPromise = (async () => {
        const encoderConfig = buildVideoEncoderConfig({
          width: videoSample.codedWidth,
          height: videoSample.codedHeight,
          ...this.encodingConfig,
          framerate: this.source._connectedTrack?.metadata.frameRate
        });
        this.encodingConfig.onEncoderConfig?.(encoderConfig);
        const MatchingCustomEncoder = customVideoEncoders.find((x) => x.supports(
          this.encodingConfig.codec,
          encoderConfig
        ));
        if (MatchingCustomEncoder) {
          this.customEncoder = new MatchingCustomEncoder();
          this.customEncoder.codec = this.encodingConfig.codec;
          this.customEncoder.config = encoderConfig;
          this.customEncoder.onPacket = (packet, meta) => {
            if (!(packet instanceof EncodedPacket)) {
              throw new TypeError("The first argument passed to onPacket must be an EncodedPacket.");
            }
            if (meta !== void 0 && (!meta || typeof meta !== "object")) {
              throw new TypeError("The second argument passed to onPacket must be an object or undefined.");
            }
            this.encodingConfig.onEncodedPacket?.(packet, meta);
            void this.muxer.addEncodedVideoPacket(this.source._connectedTrack, packet, meta).catch((error) => {
              this.error ??= error;
            });
          };
          await this.customEncoder.init();
        } else {
          if (typeof VideoEncoder === "undefined") {
            throw new Error("VideoEncoder is not supported by this browser.");
          }
          encoderConfig.alpha = "discard";
          if (this.encodingConfig.alpha === "keep") {
            encoderConfig.latencyMode = "quality";
          }
          const hasOddDimension = encoderConfig.width % 2 === 1 || encoderConfig.height % 2 === 1;
          if (hasOddDimension && (this.encodingConfig.codec === "avc" || this.encodingConfig.codec === "hevc")) {
            throw new Error(
              `The dimensions ${encoderConfig.width}x${encoderConfig.height} are not supported for codec '${this.encodingConfig.codec}'; both width and height must be even numbers. Make sure to round your dimensions to the nearest even number.`
            );
          }
          const support = await VideoEncoder.isConfigSupported(encoderConfig);
          if (!support.supported) {
            throw new Error(
              `This specific encoder configuration (${encoderConfig.codec}, ${encoderConfig.bitrate} bps, ${encoderConfig.width}x${encoderConfig.height}, hardware acceleration: ${encoderConfig.hardwareAcceleration ?? "no-preference"}) is not supported by this browser. Consider using another codec or changing your video parameters.`
            );
          }
          const colorChunkQueue = [];
          const nullAlphaChunkQueue = [];
          let encodedAlphaChunkCount = 0;
          let alphaEncoderQueue = 0;
          const addPacket = (colorChunk, alphaChunk, meta) => {
            const sideData = {};
            if (alphaChunk) {
              const alphaData = new Uint8Array(alphaChunk.byteLength);
              alphaChunk.copyTo(alphaData);
              sideData.alpha = alphaData;
            }
            const packet = EncodedPacket.fromEncodedChunk(colorChunk, sideData);
            this.encodingConfig.onEncodedPacket?.(packet, meta);
            void this.muxer.addEncodedVideoPacket(this.source._connectedTrack, packet, meta).catch((error) => {
              this.error ??= error;
            });
          };
          const stack = new Error("Encoding error").stack;
          this.encoder = new VideoEncoder({
            output: (chunk, meta) => {
              if (!this.alphaEncoder) {
                addPacket(chunk, null, meta);
                return;
              }
              const alphaFrame = this.alphaFrameQueue.shift();
              assert(alphaFrame !== void 0);
              if (alphaFrame) {
                this.alphaEncoder.encode(alphaFrame, {
                  // Crucial: The alpha frame is forced to be a key frame whenever the color frame
                  // also is. Without this, playback can glitch and even crash in some browsers.
                  // This is the reason why the two encoders are wired in series and not in parallel.
                  keyFrame: chunk.type === "key"
                });
                alphaEncoderQueue++;
                alphaFrame.close();
                colorChunkQueue.push({ chunk, meta });
              } else {
                if (alphaEncoderQueue === 0) {
                  addPacket(chunk, null, meta);
                } else {
                  nullAlphaChunkQueue.push(encodedAlphaChunkCount + alphaEncoderQueue);
                  colorChunkQueue.push({ chunk, meta });
                }
              }
            },
            error: (error) => {
              error.stack = stack;
              this.error ??= error;
            }
          });
          this.encoder.configure(encoderConfig);
          if (this.encodingConfig.alpha === "keep") {
            const stack2 = new Error("Encoding error").stack;
            this.alphaEncoder = new VideoEncoder({
              // We ignore the alpha chunk's metadata
              // eslint-disable-next-line @typescript-eslint/no-unused-vars
              output: (chunk, meta) => {
                alphaEncoderQueue--;
                const colorChunk = colorChunkQueue.shift();
                assert(colorChunk !== void 0);
                addPacket(colorChunk.chunk, chunk, colorChunk.meta);
                encodedAlphaChunkCount++;
                while (nullAlphaChunkQueue.length > 0 && nullAlphaChunkQueue[0] === encodedAlphaChunkCount) {
                  nullAlphaChunkQueue.shift();
                  const colorChunk2 = colorChunkQueue.shift();
                  assert(colorChunk2 !== void 0);
                  addPacket(colorChunk2.chunk, null, colorChunk2.meta);
                }
              },
              error: (error) => {
                error.stack = stack2;
                this.error ??= error;
              }
            });
            this.alphaEncoder.configure(encoderConfig);
          }
        }
        assert(this.source._connectedTrack);
        this.muxer = this.source._connectedTrack.output._muxer;
        this.encoderInitialized = true;
      })();
    }
    async flushAndClose(forceClose) {
      if (!forceClose) this.checkForEncoderError();
      if (this.customEncoder) {
        if (!forceClose) {
          void this.customEncoderCallSerializer.call(() => this.customEncoder.flush());
        }
        await this.customEncoderCallSerializer.call(() => this.customEncoder.close());
      } else if (this.encoder) {
        if (!forceClose) {
          await this.encoder.flush();
          await this.alphaEncoder?.flush();
        }
        if (this.encoder.state !== "closed") {
          this.encoder.close();
        }
        if (this.alphaEncoder && this.alphaEncoder.state !== "closed") {
          this.alphaEncoder.close();
        }
        this.alphaFrameQueue.forEach((x) => x?.close());
        this.splitter?.close();
      }
      if (!forceClose) this.checkForEncoderError();
    }
    getQueueSize() {
      if (this.customEncoder) {
        return this.customEncoderQueueSize;
      } else {
        return this.encoder?.encodeQueueSize ?? 0;
      }
    }
    checkForEncoderError() {
      if (this.error) {
        throw this.error;
      }
    }
  };
  var ColorAlphaSplitter = class {
    constructor(initialWidth, initialHeight) {
      this.lastFrame = null;
      if (typeof OffscreenCanvas !== "undefined") {
        this.canvas = new OffscreenCanvas(initialWidth, initialHeight);
      } else {
        this.canvas = document.createElement("canvas");
        this.canvas.width = initialWidth;
        this.canvas.height = initialHeight;
      }
      const gl = this.canvas.getContext("webgl2", {
        alpha: true
        // Needed due to the YUV thing we do for alpha
      });
      if (!gl) {
        throw new Error("Couldn't acquire WebGL 2 context.");
      }
      this.gl = gl;
      this.colorProgram = this.createColorProgram();
      this.alphaProgram = this.createAlphaProgram();
      this.vao = this.createVAO();
      this.sourceTexture = this.createTexture();
      this.alphaResolutionLocation = this.gl.getUniformLocation(this.alphaProgram, "u_resolution");
      this.gl.useProgram(this.colorProgram);
      this.gl.uniform1i(this.gl.getUniformLocation(this.colorProgram, "u_sourceTexture"), 0);
      this.gl.useProgram(this.alphaProgram);
      this.gl.uniform1i(this.gl.getUniformLocation(this.alphaProgram, "u_sourceTexture"), 0);
    }
    createVertexShader() {
      return this.createShader(this.gl.VERTEX_SHADER, `#version 300 es
			in vec2 a_position;
			in vec2 a_texCoord;
			out vec2 v_texCoord;
			
			void main() {
				gl_Position = vec4(a_position, 0.0, 1.0);
				v_texCoord = a_texCoord;
			}
		`);
    }
    createColorProgram() {
      const vertexShader = this.createVertexShader();
      const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, `#version 300 es
			precision highp float;
			
			uniform sampler2D u_sourceTexture;
			in vec2 v_texCoord;
			out vec4 fragColor;
			
			void main() {
				vec4 source = texture(u_sourceTexture, v_texCoord);
				fragColor = vec4(source.rgb, 1.0);
			}
		`);
      const program = this.gl.createProgram();
      this.gl.attachShader(program, vertexShader);
      this.gl.attachShader(program, fragmentShader);
      this.gl.linkProgram(program);
      return program;
    }
    createAlphaProgram() {
      const vertexShader = this.createVertexShader();
      const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, `#version 300 es
			precision highp float;
			
			uniform sampler2D u_sourceTexture;
			uniform vec2 u_resolution; // The width and height of the canvas
			in vec2 v_texCoord;
			out vec4 fragColor;

			// This function determines the value for a single byte in the YUV stream
			float getByteValue(float byteOffset) {
				float width = u_resolution.x;
				float height = u_resolution.y;

				float yPlaneSize = width * height;

				if (byteOffset < yPlaneSize) {
					// This byte is in the luma plane. Find the corresponding pixel coordinates to sample from
					float y = floor(byteOffset / width);
					float x = mod(byteOffset, width);
					
					// Add 0.5 to sample the center of the texel
					vec2 sampleCoord = (vec2(x, y) + 0.5) / u_resolution;
					
					// The luma value is the alpha from the source texture
					return texture(u_sourceTexture, sampleCoord).a;
				} else {
					// Write a fixed value for chroma and beyond
					return 128.0 / 255.0;
				}
			}
			
			void main() {
				// Each fragment writes 4 bytes (R, G, B, A)
				float pixelIndex = floor(gl_FragCoord.y) * u_resolution.x + floor(gl_FragCoord.x);
				float baseByteOffset = pixelIndex * 4.0;

				vec4 result;
				for (int i = 0; i < 4; i++) {
					float currentByteOffset = baseByteOffset + float(i);
					result[i] = getByteValue(currentByteOffset);
				}
				
				fragColor = result;
			}
		`);
      const program = this.gl.createProgram();
      this.gl.attachShader(program, vertexShader);
      this.gl.attachShader(program, fragmentShader);
      this.gl.linkProgram(program);
      return program;
    }
    createShader(type, source) {
      const shader = this.gl.createShader(type);
      this.gl.shaderSource(shader, source);
      this.gl.compileShader(shader);
      if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
        console.error("Shader compile error:", this.gl.getShaderInfoLog(shader));
      }
      return shader;
    }
    createVAO() {
      const vao = this.gl.createVertexArray();
      this.gl.bindVertexArray(vao);
      const vertices = new Float32Array([
        -1,
        -1,
        0,
        1,
        1,
        -1,
        1,
        1,
        -1,
        1,
        0,
        0,
        1,
        1,
        1,
        0
      ]);
      const buffer = this.gl.createBuffer();
      this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
      this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);
      const positionLocation = this.gl.getAttribLocation(this.colorProgram, "a_position");
      const texCoordLocation = this.gl.getAttribLocation(this.colorProgram, "a_texCoord");
      this.gl.enableVertexAttribArray(positionLocation);
      this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 16, 0);
      this.gl.enableVertexAttribArray(texCoordLocation);
      this.gl.vertexAttribPointer(texCoordLocation, 2, this.gl.FLOAT, false, 16, 8);
      return vao;
    }
    createTexture() {
      const texture = this.gl.createTexture();
      this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
      this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
      this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
      this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
      this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
      return texture;
    }
    updateTexture(sourceFrame) {
      if (this.lastFrame === sourceFrame) {
        return;
      }
      if (sourceFrame.displayWidth !== this.canvas.width || sourceFrame.displayHeight !== this.canvas.height) {
        this.canvas.width = sourceFrame.displayWidth;
        this.canvas.height = sourceFrame.displayHeight;
      }
      this.gl.activeTexture(this.gl.TEXTURE0);
      this.gl.bindTexture(this.gl.TEXTURE_2D, this.sourceTexture);
      this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, sourceFrame);
      this.lastFrame = sourceFrame;
    }
    extractColor(sourceFrame) {
      this.updateTexture(sourceFrame);
      this.gl.useProgram(this.colorProgram);
      this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
      this.gl.clear(this.gl.COLOR_BUFFER_BIT);
      this.gl.bindVertexArray(this.vao);
      this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
      return new VideoFrame(this.canvas, {
        timestamp: sourceFrame.timestamp,
        duration: sourceFrame.duration ?? void 0,
        alpha: "discard"
      });
    }
    extractAlpha(sourceFrame) {
      this.updateTexture(sourceFrame);
      this.gl.useProgram(this.alphaProgram);
      this.gl.uniform2f(this.alphaResolutionLocation, this.canvas.width, this.canvas.height);
      this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
      this.gl.clear(this.gl.COLOR_BUFFER_BIT);
      this.gl.bindVertexArray(this.vao);
      this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
      const { width, height } = this.canvas;
      const chromaSamples = Math.ceil(width / 2) * Math.ceil(height / 2);
      const yuvSize = width * height + chromaSamples * 2;
      const requiredHeight = Math.ceil(yuvSize / (width * 4));
      let yuv = new Uint8Array(4 * width * requiredHeight);
      this.gl.readPixels(0, 0, width, requiredHeight, this.gl.RGBA, this.gl.UNSIGNED_BYTE, yuv);
      yuv = yuv.subarray(0, yuvSize);
      assert(yuv[width * height] === 128);
      assert(yuv[yuv.length - 1] === 128);
      const init = {
        format: "I420",
        codedWidth: width,
        codedHeight: height,
        timestamp: sourceFrame.timestamp,
        duration: sourceFrame.duration ?? void 0,
        transfer: [yuv.buffer]
      };
      return new VideoFrame(yuv, init);
    }
    close() {
      this.gl.getExtension("WEBGL_lose_context")?.loseContext();
      this.gl = null;
    }
  };
  var VideoSampleSource = class extends VideoSource {
    /**
     * Creates a new {@link VideoSampleSource} whose samples are encoded according to the specified
     * {@link VideoEncodingConfig}.
     */
    constructor(encodingConfig) {
      validateVideoEncodingConfig(encodingConfig);
      super(encodingConfig.codec);
      this._encoder = new VideoEncoderWrapper(this, encodingConfig);
    }
    /**
     * Encodes a video sample (frame) and then adds it to the output.
     *
     * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise
     * to respect writer and encoder backpressure.
     */
    add(videoSample, encodeOptions) {
      if (!(videoSample instanceof VideoSample)) {
        throw new TypeError("videoSample must be a VideoSample.");
      }
      return this._encoder.add(videoSample, false, encodeOptions);
    }
    /** @internal */
    _flushAndClose(forceClose) {
      return this._encoder.flushAndClose(forceClose);
    }
  };
  var CanvasSource = class extends VideoSource {
    /**
     * Creates a new {@link CanvasSource} from a canvas element or `OffscreenCanvas` whose samples are encoded
     * according to the specified {@link VideoEncodingConfig}.
     */
    constructor(canvas, encodingConfig) {
      if (!(typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement) && !(typeof OffscreenCanvas !== "undefined" && canvas instanceof OffscreenCanvas)) {
        throw new TypeError("canvas must be an HTMLCanvasElement or OffscreenCanvas.");
      }
      validateVideoEncodingConfig(encodingConfig);
      super(encodingConfig.codec);
      this._encoder = new VideoEncoderWrapper(this, encodingConfig);
      this._canvas = canvas;
    }
    /**
     * Captures the current canvas state as a video sample (frame), encodes it and adds it to the output.
     *
     * @param timestamp - The timestamp of the sample, in seconds.
     * @param duration - The duration of the sample, in seconds.
     *
     * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise
     * to respect writer and encoder backpressure.
     */
    add(timestamp, duration = 0, encodeOptions) {
      if (!Number.isFinite(timestamp) || timestamp < 0) {
        throw new TypeError("timestamp must be a non-negative number.");
      }
      if (!Number.isFinite(duration) || duration < 0) {
        throw new TypeError("duration must be a non-negative number.");
      }
      const sample = new VideoSample(this._canvas, { timestamp, duration });
      return this._encoder.add(sample, true, encodeOptions);
    }
    /** @internal */
    _flushAndClose(forceClose) {
      return this._encoder.flushAndClose(forceClose);
    }
  };
  var MediaStreamVideoTrackSource = class extends VideoSource {
    /**
     * Creates a new {@link MediaStreamVideoTrackSource} from a
     * [`MediaStreamVideoTrack`](https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack), which will pull
     * video samples from the stream in real time and encode them according to {@link VideoEncodingConfig}.
     */
    constructor(track, encodingConfig) {
      if (!(track instanceof MediaStreamTrack) || track.kind !== "video") {
        throw new TypeError("track must be a video MediaStreamTrack.");
      }
      validateVideoEncodingConfig(encodingConfig);
      encodingConfig = {
        ...encodingConfig,
        latencyMode: "realtime"
      };
      super(encodingConfig.codec);
      /** @internal */
      this._abortController = null;
      /** @internal */
      this._workerTrackId = null;
      /** @internal */
      this._workerListener = null;
      /** @internal */
      this._promiseWithResolvers = promiseWithResolvers();
      /** @internal */
      this._errorPromiseAccessed = false;
      /** @internal */
      this._paused = false;
      /** @internal */
      this._lastSampleTimestamp = null;
      /** @internal */
      this._pauseOffset = 0;
      this._encoder = new VideoEncoderWrapper(this, encodingConfig);
      this._track = track;
    }
    /** A promise that rejects upon any error within this source. This promise never resolves. */
    get errorPromise() {
      this._errorPromiseAccessed = true;
      return this._promiseWithResolvers.promise;
    }
    /** Whether this source is currently paused as a result of calling `.pause()`. */
    get paused() {
      return this._paused;
    }
    /** @internal */
    async _start() {
      if (!this._errorPromiseAccessed) {
        console.warn(
          "Make sure not to ignore the `errorPromise` field on MediaStreamVideoTrackSource, so that any internal errors get bubbled up properly."
        );
      }
      this._abortController = new AbortController();
      let firstVideoFrameTimestamp = null;
      let errored = false;
      const onVideoFrame = (videoFrame) => {
        if (errored) {
          videoFrame.close();
          return;
        }
        const currentTimestamp = videoFrame.timestamp / 1e6;
        if (this._paused) {
          const frameSeen = firstVideoFrameTimestamp !== null;
          if (frameSeen) {
            if (this._lastSampleTimestamp !== null) {
              const timeDelta = currentTimestamp - this._lastSampleTimestamp;
              this._pauseOffset -= timeDelta;
            }
            this._lastSampleTimestamp = currentTimestamp;
          }
          videoFrame.close();
          return;
        }
        if (firstVideoFrameTimestamp === null) {
          firstVideoFrameTimestamp = currentTimestamp;
          const muxer = this._connectedTrack.output._muxer;
          if (muxer.firstMediaStreamTimestamp === null) {
            muxer.firstMediaStreamTimestamp = performance.now() / 1e3;
            this._timestampOffset = -firstVideoFrameTimestamp;
          } else {
            this._timestampOffset = performance.now() / 1e3 - muxer.firstMediaStreamTimestamp - firstVideoFrameTimestamp;
          }
        }
        this._lastSampleTimestamp = currentTimestamp;
        if (this._encoder.getQueueSize() >= 4) {
          videoFrame.close();
          return;
        }
        const sample = new VideoSample(videoFrame, {
          timestamp: currentTimestamp + this._pauseOffset
        });
        void this._encoder.add(sample, true).catch((error) => {
          errored = true;
          this._abortController?.abort();
          this._promiseWithResolvers.reject(error);
          if (this._workerTrackId !== null) {
            sendMessageToMediaStreamTrackProcessorWorker({
              type: "stopTrack",
              trackId: this._workerTrackId
            });
          }
        });
      };
      if (typeof MediaStreamTrackProcessor !== "undefined") {
        const processor = new MediaStreamTrackProcessor({ track: this._track });
        const consumer = new WritableStream({ write: onVideoFrame });
        processor.readable.pipeTo(consumer, {
          signal: this._abortController.signal
        }).catch((error) => {
          if (error instanceof DOMException && error.name === "AbortError") return;
          this._promiseWithResolvers.reject(error);
        });
      } else {
        const supportedInWorker = await mediaStreamTrackProcessorIsSupportedInWorker();
        if (supportedInWorker) {
          this._workerTrackId = nextMediaStreamTrackProcessorWorkerId++;
          sendMessageToMediaStreamTrackProcessorWorker({
            type: "videoTrack",
            trackId: this._workerTrackId,
            track: this._track
          });
          this._workerListener = (event) => {
            const message = event.data;
            if (message.type === "videoFrame" && message.trackId === this._workerTrackId) {
              onVideoFrame(message.videoFrame);
            } else if (message.type === "error" && message.trackId === this._workerTrackId) {
              this._promiseWithResolvers.reject(message.error);
            }
          };
          mediaStreamTrackProcessorWorker.addEventListener("message", this._workerListener);
        } else {
          throw new Error("MediaStreamTrackProcessor is required but not supported by this browser.");
        }
      }
    }
    /**
     * Pauses the capture of video frames - any video frames emitted by the underlying media stream will be ignored
     * while paused. This does *not* close the underlying `MediaStreamVideoTrack`, it just ignores its output.
     */
    pause() {
      this._paused = true;
    }
    /** Resumes the capture of video frames after being paused. */
    resume() {
      this._paused = false;
    }
    /** @internal */
    async _flushAndClose(forceClose) {
      if (this._abortController) {
        this._abortController.abort();
        this._abortController = null;
      }
      if (this._workerTrackId !== null) {
        assert(this._workerListener);
        sendMessageToMediaStreamTrackProcessorWorker({
          type: "stopTrack",
          trackId: this._workerTrackId
        });
        await new Promise((resolve) => {
          const listener = (event) => {
            const message = event.data;
            if (message.type === "trackStopped" && message.trackId === this._workerTrackId) {
              assert(this._workerListener);
              mediaStreamTrackProcessorWorker.removeEventListener("message", this._workerListener);
              mediaStreamTrackProcessorWorker.removeEventListener("message", listener);
              resolve();
            }
          };
          mediaStreamTrackProcessorWorker.addEventListener("message", listener);
        });
      }
      await this._encoder.flushAndClose(forceClose);
    }
  };
  var AudioSource = class extends MediaSource {
    /** Internal constructor. */
    constructor(codec) {
      super();
      /** @internal */
      this._connectedTrack = null;
      if (!AUDIO_CODECS.includes(codec)) {
        throw new TypeError(`Invalid audio codec '${codec}'. Must be one of: ${AUDIO_CODECS.join(", ")}.`);
      }
      this._codec = codec;
    }
  };
  var EncodedAudioPacketSource = class extends AudioSource {
    /** Creates a new {@link EncodedAudioPacketSource} whose packets are encoded using `codec`. */
    constructor(codec) {
      super(codec);
    }
    /**
     * Adds an encoded packet to the output audio track. Packets must be added in *decode order*.
     *
     * @param meta - Additional metadata from the encoder. You should pass this for the first call, including a valid
     * decoder config.
     *
     * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise
     * to respect writer and encoder backpressure.
     */
    add(packet, meta) {
      if (!(packet instanceof EncodedPacket)) {
        throw new TypeError("packet must be an EncodedPacket.");
      }
      if (packet.isMetadataOnly) {
        throw new TypeError("Metadata-only packets cannot be added.");
      }
      if (meta !== void 0 && (!meta || typeof meta !== "object")) {
        throw new TypeError("meta, when provided, must be an object.");
      }
      this._ensureValidAdd();
      return this._connectedTrack.output._muxer.addEncodedAudioPacket(this._connectedTrack, packet, meta);
    }
  };
  var AudioEncoderWrapper = class {
    constructor(source, encodingConfig) {
      this.source = source;
      this.encodingConfig = encodingConfig;
      this.ensureEncoderPromise = null;
      this.encoderInitialized = false;
      this.encoder = null;
      this.muxer = null;
      this.lastNumberOfChannels = null;
      this.lastSampleRate = null;
      this.isPcmEncoder = false;
      this.outputSampleSize = null;
      this.writeOutputValue = null;
      this.customEncoder = null;
      this.customEncoderCallSerializer = new CallSerializer();
      this.customEncoderQueueSize = 0;
      this.lastEndSampleIndex = null;
      /**
       * Encoders typically throw their errors "out of band", meaning asynchronously in some other execution context.
       * However, we want to surface these errors to the user within the normal control flow, so they don't go uncaught.
       * So, we keep track of the encoder error and throw it as soon as we get the chance.
       */
      this.error = null;
    }
    async add(audioSample, shouldClose) {
      try {
        this.checkForEncoderError();
        this.source._ensureValidAdd();
        if (this.lastNumberOfChannels !== null && this.lastSampleRate !== null) {
          if (audioSample.numberOfChannels !== this.lastNumberOfChannels || audioSample.sampleRate !== this.lastSampleRate) {
            throw new Error(
              `Audio parameters must remain constant. Expected ${this.lastNumberOfChannels} channels at ${this.lastSampleRate} Hz, got ${audioSample.numberOfChannels} channels at ${audioSample.sampleRate} Hz.`
            );
          }
        } else {
          this.lastNumberOfChannels = audioSample.numberOfChannels;
          this.lastSampleRate = audioSample.sampleRate;
        }
        if (!this.encoderInitialized) {
          if (!this.ensureEncoderPromise) {
            this.ensureEncoder(audioSample);
          }
          if (!this.encoderInitialized) {
            await this.ensureEncoderPromise;
          }
        }
        assert(this.encoderInitialized);
        {
          const startSampleIndex = Math.round(
            audioSample.timestamp * audioSample.sampleRate
          );
          const endSampleIndex = Math.round(
            (audioSample.timestamp + audioSample.duration) * audioSample.sampleRate
          );
          if (this.lastEndSampleIndex === null) {
            this.lastEndSampleIndex = endSampleIndex;
          } else {
            const sampleDiff = startSampleIndex - this.lastEndSampleIndex;
            if (sampleDiff >= 64) {
              const fillSample = new AudioSample({
                data: new Float32Array(sampleDiff * audioSample.numberOfChannels),
                format: "f32-planar",
                sampleRate: audioSample.sampleRate,
                numberOfChannels: audioSample.numberOfChannels,
                numberOfFrames: sampleDiff,
                timestamp: this.lastEndSampleIndex / audioSample.sampleRate
              });
              await this.add(fillSample, true);
            }
            this.lastEndSampleIndex += audioSample.numberOfFrames;
          }
        }
        if (this.customEncoder) {
          this.customEncoderQueueSize++;
          const clonedSample = audioSample.clone();
          const promise = this.customEncoderCallSerializer.call(() => this.customEncoder.encode(clonedSample)).then(() => this.customEncoderQueueSize--).catch((error) => this.error ??= error).finally(() => {
            clonedSample.close();
          });
          if (this.customEncoderQueueSize >= 4) {
            await promise;
          }
          await this.muxer.mutex.currentPromise;
        } else if (this.isPcmEncoder) {
          await this.doPcmEncoding(audioSample, shouldClose);
        } else {
          assert(this.encoder);
          const audioData = audioSample.toAudioData();
          this.encoder.encode(audioData);
          audioData.close();
          if (shouldClose) {
            audioSample.close();
          }
          if (this.encoder.encodeQueueSize >= 4) {
            await new Promise((resolve) => this.encoder.addEventListener("dequeue", resolve, { once: true }));
          }
          await this.muxer.mutex.currentPromise;
        }
      } finally {
        if (shouldClose) {
          audioSample.close();
        }
      }
    }
    async doPcmEncoding(audioSample, shouldClose) {
      assert(this.outputSampleSize);
      assert(this.writeOutputValue);
      const { numberOfChannels, numberOfFrames, sampleRate, timestamp } = audioSample;
      const CHUNK_SIZE = 2048;
      const outputs = [];
      for (let frame = 0; frame < numberOfFrames; frame += CHUNK_SIZE) {
        const frameCount = Math.min(CHUNK_SIZE, audioSample.numberOfFrames - frame);
        const outputSize = frameCount * numberOfChannels * this.outputSampleSize;
        const outputBuffer = new ArrayBuffer(outputSize);
        const outputView = new DataView(outputBuffer);
        outputs.push({ frameCount, view: outputView });
      }
      const allocationSize = audioSample.allocationSize({ planeIndex: 0, format: "f32-planar" });
      const floats = new Float32Array(allocationSize / Float32Array.BYTES_PER_ELEMENT);
      for (let i = 0; i < numberOfChannels; i++) {
        audioSample.copyTo(floats, { planeIndex: i, format: "f32-planar" });
        for (let j = 0; j < outputs.length; j++) {
          const { frameCount, view: view2 } = outputs[j];
          for (let k = 0; k < frameCount; k++) {
            this.writeOutputValue(
              view2,
              (k * numberOfChannels + i) * this.outputSampleSize,
              floats[j * CHUNK_SIZE + k]
            );
          }
        }
      }
      if (shouldClose) {
        audioSample.close();
      }
      const meta = {
        decoderConfig: {
          codec: this.encodingConfig.codec,
          numberOfChannels,
          sampleRate
        }
      };
      for (let i = 0; i < outputs.length; i++) {
        const { frameCount, view: view2 } = outputs[i];
        const outputBuffer = view2.buffer;
        const startFrame = i * CHUNK_SIZE;
        const packet = new EncodedPacket(
          new Uint8Array(outputBuffer),
          "key",
          timestamp + startFrame / sampleRate,
          frameCount / sampleRate
        );
        this.encodingConfig.onEncodedPacket?.(packet, meta);
        await this.muxer.addEncodedAudioPacket(this.source._connectedTrack, packet, meta);
      }
    }
    ensureEncoder(audioSample) {
      this.ensureEncoderPromise = (async () => {
        const { numberOfChannels, sampleRate } = audioSample;
        const encoderConfig = buildAudioEncoderConfig({
          numberOfChannels,
          sampleRate,
          ...this.encodingConfig
        });
        this.encodingConfig.onEncoderConfig?.(encoderConfig);
        const MatchingCustomEncoder = customAudioEncoders.find((x) => x.supports(
          this.encodingConfig.codec,
          encoderConfig
        ));
        if (MatchingCustomEncoder) {
          this.customEncoder = new MatchingCustomEncoder();
          this.customEncoder.codec = this.encodingConfig.codec;
          this.customEncoder.config = encoderConfig;
          this.customEncoder.onPacket = (packet, meta) => {
            if (!(packet instanceof EncodedPacket)) {
              throw new TypeError("The first argument passed to onPacket must be an EncodedPacket.");
            }
            if (meta !== void 0 && (!meta || typeof meta !== "object")) {
              throw new TypeError("The second argument passed to onPacket must be an object or undefined.");
            }
            this.encodingConfig.onEncodedPacket?.(packet, meta);
            void this.muxer.addEncodedAudioPacket(this.source._connectedTrack, packet, meta).catch((error) => {
              this.error ??= error;
            });
          };
          await this.customEncoder.init();
        } else if (PCM_AUDIO_CODECS.includes(this.encodingConfig.codec)) {
          this.initPcmEncoder();
        } else {
          if (typeof AudioEncoder === "undefined") {
            throw new Error("AudioEncoder is not supported by this browser.");
          }
          const support = await AudioEncoder.isConfigSupported(encoderConfig);
          if (!support.supported) {
            throw new Error(
              `This specific encoder configuration (${encoderConfig.codec}, ${encoderConfig.bitrate} bps, ${encoderConfig.numberOfChannels} channels, ${encoderConfig.sampleRate} Hz) is not supported by this browser. Consider using another codec or changing your audio parameters.`
            );
          }
          const stack = new Error("Encoding error").stack;
          this.encoder = new AudioEncoder({
            output: (chunk, meta) => {
              if (this.encodingConfig.codec === "aac" && meta?.decoderConfig) {
                let needsDescriptionOverwrite = false;
                if (!meta.decoderConfig.description || meta.decoderConfig.description.byteLength < 2) {
                  needsDescriptionOverwrite = true;
                } else {
                  const audioSpecificConfig = parseAacAudioSpecificConfig(
                    toUint8Array(meta.decoderConfig.description)
                  );
                  needsDescriptionOverwrite = audioSpecificConfig.objectType === 0;
                }
                if (needsDescriptionOverwrite) {
                  const objectType = Number(last(encoderConfig.codec.split(".")));
                  meta.decoderConfig.description = buildAacAudioSpecificConfig({
                    objectType,
                    numberOfChannels: meta.decoderConfig.numberOfChannels,
                    sampleRate: meta.decoderConfig.sampleRate
                  });
                }
              }
              const packet = EncodedPacket.fromEncodedChunk(chunk);
              this.encodingConfig.onEncodedPacket?.(packet, meta);
              void this.muxer.addEncodedAudioPacket(this.source._connectedTrack, packet, meta).catch((error) => {
                this.error ??= error;
              });
            },
            error: (error) => {
              error.stack = stack;
              this.error ??= error;
            }
          });
          this.encoder.configure(encoderConfig);
        }
        assert(this.source._connectedTrack);
        this.muxer = this.source._connectedTrack.output._muxer;
        this.encoderInitialized = true;
      })();
    }
    initPcmEncoder() {
      this.isPcmEncoder = true;
      const codec = this.encodingConfig.codec;
      const { dataType, sampleSize, littleEndian } = parsePcmCodec(codec);
      this.outputSampleSize = sampleSize;
      switch (sampleSize) {
        case 1:
          {
            if (dataType === "unsigned") {
              this.writeOutputValue = (view2, byteOffset, value) => view2.setUint8(byteOffset, clamp((value + 1) * 127.5, 0, 255));
            } else if (dataType === "signed") {
              this.writeOutputValue = (view2, byteOffset, value) => {
                view2.setInt8(byteOffset, clamp(Math.round(value * 128), -128, 127));
              };
            } else if (dataType === "ulaw") {
              this.writeOutputValue = (view2, byteOffset, value) => {
                const int16 = clamp(Math.floor(value * 32767), -32768, 32767);
                view2.setUint8(byteOffset, toUlaw(int16));
              };
            } else if (dataType === "alaw") {
              this.writeOutputValue = (view2, byteOffset, value) => {
                const int16 = clamp(Math.floor(value * 32767), -32768, 32767);
                view2.setUint8(byteOffset, toAlaw(int16));
              };
            } else {
              assert(false);
            }
          }
          ;
          break;
        case 2:
          {
            if (dataType === "unsigned") {
              this.writeOutputValue = (view2, byteOffset, value) => view2.setUint16(byteOffset, clamp((value + 1) * 32767.5, 0, 65535), littleEndian);
            } else if (dataType === "signed") {
              this.writeOutputValue = (view2, byteOffset, value) => view2.setInt16(byteOffset, clamp(Math.round(value * 32767), -32768, 32767), littleEndian);
            } else {
              assert(false);
            }
          }
          ;
          break;
        case 3:
          {
            if (dataType === "unsigned") {
              this.writeOutputValue = (view2, byteOffset, value) => setUint24(view2, byteOffset, clamp((value + 1) * 83886075e-1, 0, 16777215), littleEndian);
            } else if (dataType === "signed") {
              this.writeOutputValue = (view2, byteOffset, value) => setInt24(
                view2,
                byteOffset,
                clamp(Math.round(value * 8388607), -8388608, 8388607),
                littleEndian
              );
            } else {
              assert(false);
            }
          }
          ;
          break;
        case 4:
          {
            if (dataType === "unsigned") {
              this.writeOutputValue = (view2, byteOffset, value) => view2.setUint32(byteOffset, clamp((value + 1) * 21474836475e-1, 0, 4294967295), littleEndian);
            } else if (dataType === "signed") {
              this.writeOutputValue = (view2, byteOffset, value) => view2.setInt32(
                byteOffset,
                clamp(Math.round(value * 2147483647), -2147483648, 2147483647),
                littleEndian
              );
            } else if (dataType === "float") {
              this.writeOutputValue = (view2, byteOffset, value) => view2.setFloat32(byteOffset, value, littleEndian);
            } else {
              assert(false);
            }
          }
          ;
          break;
        case 8:
          {
            if (dataType === "float") {
              this.writeOutputValue = (view2, byteOffset, value) => view2.setFloat64(byteOffset, value, littleEndian);
            } else {
              assert(false);
            }
          }
          ;
          break;
        default:
          {
            assertNever(sampleSize);
            assert(false);
          }
          ;
      }
    }
    async flushAndClose(forceClose) {
      if (!forceClose) this.checkForEncoderError();
      if (this.customEncoder) {
        if (!forceClose) {
          void this.customEncoderCallSerializer.call(() => this.customEncoder.flush());
        }
        await this.customEncoderCallSerializer.call(() => this.customEncoder.close());
      } else if (this.encoder) {
        if (!forceClose) {
          await this.encoder.flush();
        }
        if (this.encoder.state !== "closed") {
          this.encoder.close();
        }
      }
      if (!forceClose) this.checkForEncoderError();
    }
    getQueueSize() {
      if (this.customEncoder) {
        return this.customEncoderQueueSize;
      } else if (this.isPcmEncoder) {
        return 0;
      } else {
        return this.encoder?.encodeQueueSize ?? 0;
      }
    }
    checkForEncoderError() {
      if (this.error) {
        throw this.error;
      }
    }
  };
  var AudioSampleSource = class extends AudioSource {
    /**
     * Creates a new {@link AudioSampleSource} whose samples are encoded according to the specified
     * {@link AudioEncodingConfig}.
     */
    constructor(encodingConfig) {
      validateAudioEncodingConfig(encodingConfig);
      super(encodingConfig.codec);
      this._encoder = new AudioEncoderWrapper(this, encodingConfig);
    }
    /**
     * Encodes an audio sample and then adds it to the output.
     *
     * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise
     * to respect writer and encoder backpressure.
     */
    add(audioSample) {
      if (!(audioSample instanceof AudioSample)) {
        throw new TypeError("audioSample must be an AudioSample.");
      }
      return this._encoder.add(audioSample, false);
    }
    /** @internal */
    _flushAndClose(forceClose) {
      return this._encoder.flushAndClose(forceClose);
    }
  };
  var AudioBufferSource = class extends AudioSource {
    /**
     * Creates a new {@link AudioBufferSource} whose `AudioBuffer` instances are encoded according to the specified
     * {@link AudioEncodingConfig}.
     */
    constructor(encodingConfig) {
      validateAudioEncodingConfig(encodingConfig);
      super(encodingConfig.codec);
      /** @internal */
      this._accumulatedTime = 0;
      this._encoder = new AudioEncoderWrapper(this, encodingConfig);
    }
    /**
     * Converts an AudioBuffer to audio samples, encodes them and adds them to the output. The first AudioBuffer will
     * be played at timestamp 0, and any subsequent AudioBuffer will have a timestamp equal to the total duration of
     * all previous AudioBuffers.
     *
     * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise
     * to respect writer and encoder backpressure.
     */
    async add(audioBuffer) {
      if (!(audioBuffer instanceof AudioBuffer)) {
        throw new TypeError("audioBuffer must be an AudioBuffer.");
      }
      const iterator = AudioSample._fromAudioBuffer(audioBuffer, this._accumulatedTime);
      this._accumulatedTime += audioBuffer.duration;
      for (const audioSample of iterator) {
        await this._encoder.add(audioSample, true);
      }
    }
    /** @internal */
    _flushAndClose(forceClose) {
      return this._encoder.flushAndClose(forceClose);
    }
  };
  var MediaStreamAudioTrackSource = class extends AudioSource {
    /**
     * Creates a new {@link MediaStreamAudioTrackSource} from a `MediaStreamAudioTrack`, which will pull audio samples
     * from the stream in real time and encode them according to {@link AudioEncodingConfig}.
     */
    constructor(track, encodingConfig) {
      if (!(track instanceof MediaStreamTrack) || track.kind !== "audio") {
        throw new TypeError("track must be an audio MediaStreamTrack.");
      }
      validateAudioEncodingConfig(encodingConfig);
      super(encodingConfig.codec);
      /** @internal */
      this._abortController = null;
      /** @internal */
      this._audioContext = null;
      /** @internal */
      this._scriptProcessorNode = null;
      // Deprecated but goated
      /** @internal */
      this._promiseWithResolvers = promiseWithResolvers();
      /** @internal */
      this._errorPromiseAccessed = false;
      /** @internal */
      this._paused = false;
      /** @internal */
      this._lastSampleTimestamp = null;
      /** @internal */
      this._pauseOffset = 0;
      this._encoder = new AudioEncoderWrapper(this, encodingConfig);
      this._track = track;
    }
    /** A promise that rejects upon any error within this source. This promise never resolves. */
    get errorPromise() {
      this._errorPromiseAccessed = true;
      return this._promiseWithResolvers.promise;
    }
    /** Whether this source is currently paused as a result of calling `.pause()`. */
    get paused() {
      return this._paused;
    }
    /** @internal */
    async _start() {
      if (!this._errorPromiseAccessed) {
        console.warn(
          "Make sure not to ignore the `errorPromise` field on MediaStreamVideoTrackSource, so that any internal errors get bubbled up properly."
        );
      }
      this._abortController = new AbortController();
      let firstAudioDataTimestamp = null;
      let errored = false;
      const onAudioSample = (audioSample) => {
        if (errored) {
          audioSample.close();
          return;
        }
        const currentTimestamp = audioSample.timestamp;
        if (this._paused) {
          const dataSeen = firstAudioDataTimestamp !== null;
          if (dataSeen) {
            if (this._lastSampleTimestamp !== null) {
              const timeDelta = currentTimestamp - this._lastSampleTimestamp;
              this._pauseOffset -= timeDelta;
            }
            this._lastSampleTimestamp = currentTimestamp;
          }
          audioSample.close();
          return;
        }
        if (firstAudioDataTimestamp === null) {
          firstAudioDataTimestamp = audioSample.timestamp;
          const muxer = this._connectedTrack.output._muxer;
          if (muxer.firstMediaStreamTimestamp === null) {
            muxer.firstMediaStreamTimestamp = performance.now() / 1e3;
            this._timestampOffset = -firstAudioDataTimestamp;
          } else {
            this._timestampOffset = performance.now() / 1e3 - muxer.firstMediaStreamTimestamp - firstAudioDataTimestamp;
          }
        }
        this._lastSampleTimestamp = currentTimestamp;
        if (this._encoder.getQueueSize() >= 4) {
          audioSample.close();
          return;
        }
        audioSample.setTimestamp(currentTimestamp + this._pauseOffset);
        void this._encoder.add(audioSample, true).catch((error) => {
          errored = true;
          this._abortController?.abort();
          this._promiseWithResolvers.reject(error);
          void this._audioContext?.suspend();
        });
      };
      if (typeof MediaStreamTrackProcessor !== "undefined") {
        const processor = new MediaStreamTrackProcessor({ track: this._track });
        const consumer = new WritableStream({
          write: (audioData) => onAudioSample(new AudioSample(audioData))
        });
        processor.readable.pipeTo(consumer, {
          signal: this._abortController.signal
        }).catch((error) => {
          if (error instanceof DOMException && error.name === "AbortError") return;
          this._promiseWithResolvers.reject(error);
        });
      } else {
        const AudioContext = window.AudioContext || window.webkitAudioContext;
        this._audioContext = new AudioContext({ sampleRate: this._track.getSettings().sampleRate });
        const sourceNode = this._audioContext.createMediaStreamSource(new MediaStream([this._track]));
        this._scriptProcessorNode = this._audioContext.createScriptProcessor(4096);
        if (this._audioContext.state === "suspended") {
          await this._audioContext.resume();
        }
        sourceNode.connect(this._scriptProcessorNode);
        this._scriptProcessorNode.connect(this._audioContext.destination);
        let totalDuration = 0;
        this._scriptProcessorNode.onaudioprocess = (event) => {
          const iterator = AudioSample._fromAudioBuffer(event.inputBuffer, totalDuration);
          totalDuration += event.inputBuffer.duration;
          for (const audioSample of iterator) {
            onAudioSample(audioSample);
          }
        };
      }
    }
    /**
     * Pauses the capture of audio data - any audio data emitted by the underlying media stream will be ignored
     * while paused. This does *not* close the underlying `MediaStreamAudioTrack`, it just ignores its output.
     */
    pause() {
      this._paused = true;
    }
    /** Resumes the capture of audio data after being paused. */
    resume() {
      this._paused = false;
    }
    /** @internal */
    async _flushAndClose(forceClose) {
      if (this._abortController) {
        this._abortController.abort();
        this._abortController = null;
      }
      if (this._audioContext) {
        assert(this._scriptProcessorNode);
        this._scriptProcessorNode.disconnect();
        await this._audioContext.suspend();
      }
      await this._encoder.flushAndClose(forceClose);
    }
  };
  var mediaStreamTrackProcessorWorkerCode = () => {
    const sendMessage = (message, transfer) => {
      if (transfer) {
        self.postMessage(message, { transfer });
      } else {
        self.postMessage(message);
      }
    };
    sendMessage({
      type: "support",
      supported: typeof MediaStreamTrackProcessor !== "undefined"
    });
    const abortControllers = /* @__PURE__ */ new Map();
    const activeTracks = /* @__PURE__ */ new Map();
    self.addEventListener("message", (event) => {
      const message = event.data;
      switch (message.type) {
        case "videoTrack":
          {
            activeTracks.set(message.trackId, message.track);
            const processor = new MediaStreamTrackProcessor({ track: message.track });
            const consumer = new WritableStream({
              write: (videoFrame) => {
                if (!activeTracks.has(message.trackId)) {
                  videoFrame.close();
                  return;
                }
                sendMessage({
                  type: "videoFrame",
                  trackId: message.trackId,
                  videoFrame
                }, [videoFrame]);
              }
            });
            const abortController = new AbortController();
            abortControllers.set(message.trackId, abortController);
            processor.readable.pipeTo(consumer, {
              signal: abortController.signal
            }).catch((error) => {
              if (error instanceof DOMException && error.name === "AbortError") return;
              sendMessage({
                type: "error",
                trackId: message.trackId,
                error
              });
            });
          }
          ;
          break;
        case "stopTrack":
          {
            const abortController = abortControllers.get(message.trackId);
            if (abortController) {
              abortController.abort();
              abortControllers.delete(message.trackId);
            }
            const track = activeTracks.get(message.trackId);
            track?.stop();
            activeTracks.delete(message.trackId);
            sendMessage({
              type: "trackStopped",
              trackId: message.trackId
            });
          }
          ;
          break;
        default:
          assertNever(message);
      }
    });
  };
  var nextMediaStreamTrackProcessorWorkerId = 0;
  var mediaStreamTrackProcessorWorker = null;
  var initMediaStreamTrackProcessorWorker = () => {
    const blob = new Blob(
      [`(${mediaStreamTrackProcessorWorkerCode.toString()})()`],
      { type: "application/javascript" }
    );
    const url2 = URL.createObjectURL(blob);
    mediaStreamTrackProcessorWorker = new Worker(url2);
  };
  var mediaStreamTrackProcessorIsSupportedInWorkerCache = null;
  var mediaStreamTrackProcessorIsSupportedInWorker = async () => {
    if (mediaStreamTrackProcessorIsSupportedInWorkerCache !== null) {
      return mediaStreamTrackProcessorIsSupportedInWorkerCache;
    }
    if (!mediaStreamTrackProcessorWorker) {
      initMediaStreamTrackProcessorWorker();
    }
    return new Promise((resolve) => {
      assert(mediaStreamTrackProcessorWorker);
      const listener = (event) => {
        const message = event.data;
        if (message.type === "support") {
          mediaStreamTrackProcessorIsSupportedInWorkerCache = message.supported;
          mediaStreamTrackProcessorWorker.removeEventListener("message", listener);
          resolve(message.supported);
        }
      };
      mediaStreamTrackProcessorWorker.addEventListener("message", listener);
    });
  };
  var sendMessageToMediaStreamTrackProcessorWorker = (message, transfer) => {
    assert(mediaStreamTrackProcessorWorker);
    if (transfer) {
      mediaStreamTrackProcessorWorker.postMessage(message, transfer);
    } else {
      mediaStreamTrackProcessorWorker.postMessage(message);
    }
  };
  var SubtitleSource = class extends MediaSource {
    /** Internal constructor. */
    constructor(codec) {
      super();
      /** @internal */
      this._connectedTrack = null;
      if (!SUBTITLE_CODECS.includes(codec)) {
        throw new TypeError(`Invalid subtitle codec '${codec}'. Must be one of: ${SUBTITLE_CODECS.join(", ")}.`);
      }
      this._codec = codec;
    }
  };
  var TextSubtitleSource = class extends SubtitleSource {
    /** Creates a new {@link TextSubtitleSource} where added text chunks are in the specified `codec`. */
    constructor(codec) {
      super(codec);
      /** @internal */
      this._error = null;
      this._parser = new SubtitleParser({
        codec,
        output: (cue, metadata) => {
          void this._connectedTrack?.output._muxer.addSubtitleCue(this._connectedTrack, cue, metadata).catch((error) => {
            this._error ??= error;
          });
        }
      });
    }
    /**
     * Parses the subtitle text according to the specified codec and adds it to the output track. You don't have to
     * add the entire subtitle file at once here; you can provide it in chunks.
     *
     * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise
     * to respect writer and encoder backpressure.
     */
    add(text) {
      if (typeof text !== "string") {
        throw new TypeError("text must be a string.");
      }
      this._checkForError();
      this._ensureValidAdd();
      this._parser.parse(text);
      return this._connectedTrack.output._muxer.mutex.currentPromise;
    }
    /** @internal */
    _checkForError() {
      if (this._error) {
        throw this._error;
      }
    }
    /** @internal */
    async _flushAndClose(forceClose) {
      if (!forceClose) {
        this._checkForError();
      }
    }
  };

  // src/output.ts
  var ALL_TRACK_TYPES = ["video", "audio", "subtitle"];
  var validateBaseTrackMetadata = (metadata) => {
    if (!metadata || typeof metadata !== "object") {
      throw new TypeError("metadata must be an object.");
    }
    if (metadata.languageCode !== void 0 && !isIso639Dash2LanguageCode(metadata.languageCode)) {
      throw new TypeError("metadata.languageCode, when provided, must be a three-letter, ISO 639-2/T language code.");
    }
    if (metadata.name !== void 0 && typeof metadata.name !== "string") {
      throw new TypeError("metadata.name, when provided, must be a string.");
    }
    if (metadata.disposition !== void 0) {
      validateTrackDisposition(metadata.disposition);
    }
    if (metadata.maximumPacketCount !== void 0 && (!Number.isInteger(metadata.maximumPacketCount) || metadata.maximumPacketCount < 0)) {
      throw new TypeError("metadata.maximumPacketCount, when provided, must be a non-negative integer.");
    }
  };
  var Output = class {
    /**
     * Creates a new instance of {@link Output} which can then be used to create a new media file according to the
     * specified {@link OutputOptions}.
     */
    constructor(options) {
      /** The current state of the output. */
      this.state = "pending";
      /** @internal */
      this._tracks = [];
      /** @internal */
      this._startPromise = null;
      /** @internal */
      this._cancelPromise = null;
      /** @internal */
      this._finalizePromise = null;
      /** @internal */
      this._mutex = new AsyncMutex();
      /** @internal */
      this._metadataTags = {};
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (!(options.format instanceof OutputFormat)) {
        throw new TypeError("options.format must be an OutputFormat.");
      }
      if (!(options.target instanceof Target)) {
        throw new TypeError("options.target must be a Target.");
      }
      if (options.target._output) {
        throw new Error("Target is already used for another output.");
      }
      options.target._output = this;
      this.format = options.format;
      this.target = options.target;
      this._writer = options.target._createWriter();
      this._muxer = options.format._createMuxer(this);
    }
    /** Adds a video track to the output with the given source. Can only be called before the output is started. */
    addVideoTrack(source, metadata = {}) {
      if (!(source instanceof VideoSource)) {
        throw new TypeError("source must be a VideoSource.");
      }
      validateBaseTrackMetadata(metadata);
      if (metadata.rotation !== void 0 && ![0, 90, 180, 270].includes(metadata.rotation)) {
        throw new TypeError(`Invalid video rotation: ${metadata.rotation}. Has to be 0, 90, 180 or 270.`);
      }
      if (!this.format.supportsVideoRotationMetadata && metadata.rotation) {
        throw new Error(`${this.format._name} does not support video rotation metadata.`);
      }
      if (metadata.frameRate !== void 0 && (!Number.isFinite(metadata.frameRate) || metadata.frameRate <= 0)) {
        throw new TypeError(
          `Invalid video frame rate: ${metadata.frameRate}. Must be a positive number.`
        );
      }
      this._addTrack("video", source, metadata);
    }
    /** Adds an audio track to the output with the given source. Can only be called before the output is started. */
    addAudioTrack(source, metadata = {}) {
      if (!(source instanceof AudioSource)) {
        throw new TypeError("source must be an AudioSource.");
      }
      validateBaseTrackMetadata(metadata);
      this._addTrack("audio", source, metadata);
    }
    /** Adds a subtitle track to the output with the given source. Can only be called before the output is started. */
    addSubtitleTrack(source, metadata = {}) {
      if (!(source instanceof SubtitleSource)) {
        throw new TypeError("source must be a SubtitleSource.");
      }
      validateBaseTrackMetadata(metadata);
      this._addTrack("subtitle", source, metadata);
    }
    /**
     * Sets descriptive metadata tags about the media file, such as title, author, date, or cover art. When called
     * multiple times, only the metadata from the last call will be used.
     *
     * Can only be called before the output is started.
     */
    setMetadataTags(tags) {
      validateMetadataTags(tags);
      if (this.state !== "pending") {
        throw new Error("Cannot set metadata tags after output has been started or canceled.");
      }
      this._metadataTags = tags;
    }
    /** @internal */
    _addTrack(type, source, metadata) {
      if (this.state !== "pending") {
        throw new Error("Cannot add track after output has been started or canceled.");
      }
      if (source._connectedTrack) {
        throw new Error("Source is already used for a track.");
      }
      const supportedTrackCounts = this.format.getSupportedTrackCounts();
      const presentTracksOfThisType = this._tracks.reduce(
        (count, track2) => count + (track2.type === type ? 1 : 0),
        0
      );
      const maxCount = supportedTrackCounts[type].max;
      if (presentTracksOfThisType === maxCount) {
        throw new Error(
          maxCount === 0 ? `${this.format._name} does not support ${type} tracks.` : `${this.format._name} does not support more than ${maxCount} ${type} track${maxCount === 1 ? "" : "s"}.`
        );
      }
      const maxTotalCount = supportedTrackCounts.total.max;
      if (this._tracks.length === maxTotalCount) {
        throw new Error(
          `${this.format._name} does not support more than ${maxTotalCount} tracks${maxTotalCount === 1 ? "" : "s"} in total.`
        );
      }
      const track = {
        id: this._tracks.length + 1,
        output: this,
        type,
        source,
        metadata
      };
      if (track.type === "video") {
        const supportedVideoCodecs = this.format.getSupportedVideoCodecs();
        if (supportedVideoCodecs.length === 0) {
          throw new Error(
            `${this.format._name} does not support video tracks.` + this.format._codecUnsupportedHint(track.source._codec)
          );
        } else if (!supportedVideoCodecs.includes(track.source._codec)) {
          throw new Error(
            `Codec '${track.source._codec}' cannot be contained within ${this.format._name}. Supported video codecs are: ${supportedVideoCodecs.map((codec) => `'${codec}'`).join(", ")}.` + this.format._codecUnsupportedHint(track.source._codec)
          );
        }
      } else if (track.type === "audio") {
        const supportedAudioCodecs = this.format.getSupportedAudioCodecs();
        if (supportedAudioCodecs.length === 0) {
          throw new Error(
            `${this.format._name} does not support audio tracks.` + this.format._codecUnsupportedHint(track.source._codec)
          );
        } else if (!supportedAudioCodecs.includes(track.source._codec)) {
          throw new Error(
            `Codec '${track.source._codec}' cannot be contained within ${this.format._name}. Supported audio codecs are: ${supportedAudioCodecs.map((codec) => `'${codec}'`).join(", ")}.` + this.format._codecUnsupportedHint(track.source._codec)
          );
        }
      } else if (track.type === "subtitle") {
        const supportedSubtitleCodecs = this.format.getSupportedSubtitleCodecs();
        if (supportedSubtitleCodecs.length === 0) {
          throw new Error(
            `${this.format._name} does not support subtitle tracks.` + this.format._codecUnsupportedHint(track.source._codec)
          );
        } else if (!supportedSubtitleCodecs.includes(track.source._codec)) {
          throw new Error(
            `Codec '${track.source._codec}' cannot be contained within ${this.format._name}. Supported subtitle codecs are: ${supportedSubtitleCodecs.map((codec) => `'${codec}'`).join(", ")}.` + this.format._codecUnsupportedHint(track.source._codec)
          );
        }
      }
      this._tracks.push(track);
      source._connectedTrack = track;
    }
    /**
     * Starts the creation of the output file. This method should be called after all tracks have been added. Only after
     * the output has started can media samples be added to the tracks.
     *
     * @returns A promise that resolves when the output has successfully started and is ready to receive media samples.
     */
    async start() {
      const supportedTrackCounts = this.format.getSupportedTrackCounts();
      for (const trackType of ALL_TRACK_TYPES) {
        const presentTracksOfThisType = this._tracks.reduce(
          (count, track) => count + (track.type === trackType ? 1 : 0),
          0
        );
        const minCount = supportedTrackCounts[trackType].min;
        if (presentTracksOfThisType < minCount) {
          throw new Error(
            minCount === supportedTrackCounts[trackType].max ? `${this.format._name} requires exactly ${minCount} ${trackType} track${minCount === 1 ? "" : "s"}.` : `${this.format._name} requires at least ${minCount} ${trackType} track${minCount === 1 ? "" : "s"}.`
          );
        }
      }
      const totalMinCount = supportedTrackCounts.total.min;
      if (this._tracks.length < totalMinCount) {
        throw new Error(
          totalMinCount === supportedTrackCounts.total.max ? `${this.format._name} requires exactly ${totalMinCount} track${totalMinCount === 1 ? "" : "s"}.` : `${this.format._name} requires at least ${totalMinCount} track${totalMinCount === 1 ? "" : "s"}.`
        );
      }
      if (this.state === "canceled") {
        throw new Error("Output has been canceled.");
      }
      if (this._startPromise) {
        console.warn("Output has already been started.");
        return this._startPromise;
      }
      return this._startPromise = (async () => {
        this.state = "started";
        this._writer.start();
        const release = await this._mutex.acquire();
        await this._muxer.start();
        const promises = this._tracks.map((track) => track.source._start());
        await Promise.all(promises);
        release();
      })();
    }
    /**
     * Resolves with the full MIME type of the output file, including track codecs.
     *
     * The returned promise will resolve only once the precise codec strings of all tracks are known.
     */
    getMimeType() {
      return this._muxer.getMimeType();
    }
    /**
     * Cancels the creation of the output file, releasing internal resources like encoders and preventing further
     * samples from being added.
     *
     * @returns A promise that resolves once all internal resources have been released.
     */
    async cancel() {
      if (this._cancelPromise) {
        console.warn("Output has already been canceled.");
        return this._cancelPromise;
      } else if (this.state === "finalizing" || this.state === "finalized") {
        console.warn("Output has already been finalized.");
        return;
      }
      return this._cancelPromise = (async () => {
        this.state = "canceled";
        const release = await this._mutex.acquire();
        const promises = this._tracks.map((x) => x.source._flushOrWaitForOngoingClose(true));
        await Promise.all(promises);
        await this._writer.close();
        release();
      })();
    }
    /**
     * Finalizes the output file. This method must be called after all media samples across all tracks have been added.
     * Once the Promise returned by this method completes, the output file is ready.
     */
    async finalize() {
      if (this.state === "pending") {
        throw new Error("Cannot finalize before starting.");
      }
      if (this.state === "canceled") {
        throw new Error("Cannot finalize after canceling.");
      }
      if (this._finalizePromise) {
        console.warn("Output has already been finalized.");
        return this._finalizePromise;
      }
      return this._finalizePromise = (async () => {
        this.state = "finalizing";
        const release = await this._mutex.acquire();
        const promises = this._tracks.map((x) => x.source._flushOrWaitForOngoingClose(false));
        await Promise.all(promises);
        await this._muxer.finalize();
        await this._writer.flush();
        await this._writer.finalize();
        this.state = "finalized";
        release();
      })();
    }
  };

  // src/conversion.ts
  var validateVideoOptions = (videoOptions) => {
    if (videoOptions !== void 0 && (!videoOptions || typeof videoOptions !== "object")) {
      throw new TypeError("options.video, when provided, must be an object.");
    }
    if (videoOptions?.discard !== void 0 && typeof videoOptions.discard !== "boolean") {
      throw new TypeError("options.video.discard, when provided, must be a boolean.");
    }
    if (videoOptions?.forceTranscode !== void 0 && typeof videoOptions.forceTranscode !== "boolean") {
      throw new TypeError("options.video.forceTranscode, when provided, must be a boolean.");
    }
    if (videoOptions?.codec !== void 0 && !VIDEO_CODECS.includes(videoOptions.codec)) {
      throw new TypeError(
        `options.video.codec, when provided, must be one of: ${VIDEO_CODECS.join(", ")}.`
      );
    }
    if (videoOptions?.bitrate !== void 0 && !(videoOptions.bitrate instanceof Quality) && (!Number.isInteger(videoOptions.bitrate) || videoOptions.bitrate <= 0)) {
      throw new TypeError("options.video.bitrate, when provided, must be a positive integer or a quality.");
    }
    if (videoOptions?.width !== void 0 && (!Number.isInteger(videoOptions.width) || videoOptions.width <= 0)) {
      throw new TypeError("options.video.width, when provided, must be a positive integer.");
    }
    if (videoOptions?.height !== void 0 && (!Number.isInteger(videoOptions.height) || videoOptions.height <= 0)) {
      throw new TypeError("options.video.height, when provided, must be a positive integer.");
    }
    if (videoOptions?.fit !== void 0 && !["fill", "contain", "cover"].includes(videoOptions.fit)) {
      throw new TypeError("options.video.fit, when provided, must be one of 'fill', 'contain', or 'cover'.");
    }
    if (videoOptions?.width !== void 0 && videoOptions.height !== void 0 && videoOptions.fit === void 0) {
      throw new TypeError(
        "When both options.video.width and options.video.height are provided, options.video.fit must also be provided."
      );
    }
    if (videoOptions?.rotate !== void 0 && ![0, 90, 180, 270].includes(videoOptions.rotate)) {
      throw new TypeError("options.video.rotate, when provided, must be 0, 90, 180 or 270.");
    }
    if (videoOptions?.allowRotationMetadata !== void 0 && typeof videoOptions.allowRotationMetadata !== "boolean") {
      throw new TypeError("options.video.allowRotationMetadata, when provided, must be a boolean.");
    }
    if (videoOptions?.crop !== void 0) {
      validateCropRectangle(videoOptions.crop, "options.video.");
    }
    if (videoOptions?.frameRate !== void 0 && (!Number.isFinite(videoOptions.frameRate) || videoOptions.frameRate <= 0)) {
      throw new TypeError("options.video.frameRate, when provided, must be a finite positive number.");
    }
    if (videoOptions?.alpha !== void 0 && !["discard", "keep"].includes(videoOptions.alpha)) {
      throw new TypeError("options.video.alpha, when provided, must be either 'discard' or 'keep'.");
    }
    if (videoOptions?.keyFrameInterval !== void 0 && (!Number.isFinite(videoOptions.keyFrameInterval) || videoOptions.keyFrameInterval < 0)) {
      throw new TypeError("options.video.keyFrameInterval, when provided, must be a non-negative number.");
    }
    if (videoOptions?.process !== void 0 && typeof videoOptions.process !== "function") {
      throw new TypeError("options.video.process, when provided, must be a function.");
    }
    if (videoOptions?.processedWidth !== void 0 && (!Number.isInteger(videoOptions.processedWidth) || videoOptions.processedWidth <= 0)) {
      throw new TypeError("options.video.processedWidth, when provided, must be a positive integer.");
    }
    if (videoOptions?.processedHeight !== void 0 && (!Number.isInteger(videoOptions.processedHeight) || videoOptions.processedHeight <= 0)) {
      throw new TypeError("options.video.processedHeight, when provided, must be a positive integer.");
    }
    if (videoOptions?.hardwareAcceleration !== void 0 && !["no-preference", "prefer-hardware", "prefer-software"].includes(videoOptions.hardwareAcceleration)) {
      throw new TypeError(
        "options.video.hardwareAcceleration, when provided, must be 'no-preference', 'prefer-hardware' or 'prefer-software'."
      );
    }
  };
  var validateAudioOptions = (audioOptions) => {
    if (audioOptions !== void 0 && (!audioOptions || typeof audioOptions !== "object")) {
      throw new TypeError("options.audio, when provided, must be an object.");
    }
    if (audioOptions?.discard !== void 0 && typeof audioOptions.discard !== "boolean") {
      throw new TypeError("options.audio.discard, when provided, must be a boolean.");
    }
    if (audioOptions?.forceTranscode !== void 0 && typeof audioOptions.forceTranscode !== "boolean") {
      throw new TypeError("options.audio.forceTranscode, when provided, must be a boolean.");
    }
    if (audioOptions?.codec !== void 0 && !AUDIO_CODECS.includes(audioOptions.codec)) {
      throw new TypeError(
        `options.audio.codec, when provided, must be one of: ${AUDIO_CODECS.join(", ")}.`
      );
    }
    if (audioOptions?.bitrate !== void 0 && !(audioOptions.bitrate instanceof Quality) && (!Number.isInteger(audioOptions.bitrate) || audioOptions.bitrate <= 0)) {
      throw new TypeError("options.audio.bitrate, when provided, must be a positive integer or a quality.");
    }
    if (audioOptions?.numberOfChannels !== void 0 && (!Number.isInteger(audioOptions.numberOfChannels) || audioOptions.numberOfChannels <= 0)) {
      throw new TypeError("options.audio.numberOfChannels, when provided, must be a positive integer.");
    }
    if (audioOptions?.sampleRate !== void 0 && (!Number.isInteger(audioOptions.sampleRate) || audioOptions.sampleRate <= 0)) {
      throw new TypeError("options.audio.sampleRate, when provided, must be a positive integer.");
    }
    if (audioOptions?.process !== void 0 && typeof audioOptions.process !== "function") {
      throw new TypeError("options.audio.process, when provided, must be a function.");
    }
    if (audioOptions?.processedNumberOfChannels !== void 0 && (!Number.isInteger(audioOptions.processedNumberOfChannels) || audioOptions.processedNumberOfChannels <= 0)) {
      throw new TypeError("options.audio.processedNumberOfChannels, when provided, must be a positive integer.");
    }
    if (audioOptions?.processedSampleRate !== void 0 && (!Number.isInteger(audioOptions.processedSampleRate) || audioOptions.processedSampleRate <= 0)) {
      throw new TypeError("options.audio.processedSampleRate, when provided, must be a positive integer.");
    }
  };
  var FALLBACK_NUMBER_OF_CHANNELS = 2;
  var FALLBACK_SAMPLE_RATE = 48e3;
  var Conversion = class _Conversion {
    /** Creates a new Conversion instance (duh). */
    constructor(options) {
      /** @internal */
      this._addedCounts = {
        video: 0,
        audio: 0,
        subtitle: 0
      };
      /** @internal */
      this._totalTrackCount = 0;
      /** @internal */
      this._trackPromises = [];
      /** @internal */
      this._executed = false;
      /** @internal */
      this._synchronizer = new TrackSynchronizer();
      /** @internal */
      this._totalDuration = null;
      /** @internal */
      this._maxTimestamps = /* @__PURE__ */ new Map();
      // Track ID -> timestamp
      /** @internal */
      this._canceled = false;
      /**
       * A callback that is fired whenever the conversion progresses. Returns a number between 0 and 1, indicating the
       * completion of the conversion. Note that a progress of 1 doesn't necessarily mean the conversion is complete;
       * the conversion is complete once `execute()` resolves.
       *
       * In order for progress to be computed, this property must be set before `execute` is called.
       */
      this.onProgress = void 0;
      /** @internal */
      this._computeProgress = false;
      /** @internal */
      this._lastProgress = 0;
      /**
       * Whether this conversion, as it has been configured, is valid and can be executed. If this field is `false`, check
       * the `discardedTracks` field for reasons.
       */
      this.isValid = false;
      /** The list of tracks that are included in the output file. */
      this.utilizedTracks = [];
      /** The list of tracks from the input file that have been discarded, alongside the discard reason. */
      this.discardedTracks = [];
      if (!options || typeof options !== "object") {
        throw new TypeError("options must be an object.");
      }
      if (!(options.input instanceof Input)) {
        throw new TypeError("options.input must be an Input.");
      }
      if (!(options.output instanceof Output)) {
        throw new TypeError("options.output must be an Output.");
      }
      if (options.output._tracks.length > 0 || Object.keys(options.output._metadataTags).length > 0 || options.output.state !== "pending") {
        throw new TypeError("options.output must be fresh: no tracks or metadata tags added and not started.");
      }
      if (typeof options.video !== "function") {
        validateVideoOptions(options.video);
      } else {
      }
      if (typeof options.audio !== "function") {
        validateAudioOptions(options.audio);
      } else {
      }
      if (options.trim !== void 0 && (!options.trim || typeof options.trim !== "object")) {
        throw new TypeError("options.trim, when provided, must be an object.");
      }
      if (options.trim?.start !== void 0 && !Number.isFinite(options.trim.start)) {
        throw new TypeError("options.trim.start, when provided, must be a finite number.");
      }
      if (options.trim?.end !== void 0 && !Number.isFinite(options.trim.end)) {
        throw new TypeError("options.trim.end, when provided, must be a finite number.");
      }
      if (options.trim?.start !== void 0 && options.trim.end !== void 0 && options.trim.start >= options.trim.end) {
        throw new TypeError("options.trim.start must be less than options.trim.end.");
      }
      if (options.tags !== void 0 && (typeof options.tags !== "object" || !options.tags) && typeof options.tags !== "function") {
        throw new TypeError("options.tags, when provided, must be an object or a function.");
      }
      if (typeof options.tags === "object") {
        validateMetadataTags(options.tags);
      }
      if (options.showWarnings !== void 0 && typeof options.showWarnings !== "boolean") {
        throw new TypeError("options.showWarnings, when provided, must be a boolean.");
      }
      this._options = options;
      this.input = options.input;
      this.output = options.output;
      const { promise: started, resolve: start } = promiseWithResolvers();
      this._started = started;
      this._start = start;
    }
    /** Initializes a new conversion process without starting the conversion. */
    static async init(options) {
      const conversion = new _Conversion(options);
      await conversion._init();
      return conversion;
    }
    /** @internal */
    async _init() {
      this._startTimestamp = this._options.trim?.start ?? Math.max(
        await this.input.getFirstTimestamp(),
        // Samples can also have negative timestamps, but the meaning typically is "don't present me", so let's cut
        // those out by default.
        0
      );
      this._endTimestamp = Math.max(this._options.trim?.end ?? Infinity, this._startTimestamp);
      const inputTracks = await this.input.getTracks();
      const outputTrackCounts = this.output.format.getSupportedTrackCounts();
      let nVideo = 1;
      let nAudio = 1;
      for (const track of inputTracks) {
        let trackOptions = void 0;
        if (track.isVideoTrack()) {
          if (this._options.video) {
            if (typeof this._options.video === "function") {
              trackOptions = await this._options.video(track, nVideo);
              validateVideoOptions(trackOptions);
              nVideo++;
            } else {
              trackOptions = this._options.video;
            }
          }
        } else if (track.isAudioTrack()) {
          if (this._options.audio) {
            if (typeof this._options.audio === "function") {
              trackOptions = await this._options.audio(track, nAudio);
              validateAudioOptions(trackOptions);
              nAudio++;
            } else {
              trackOptions = this._options.audio;
            }
          }
        } else {
          assert(false);
        }
        if (trackOptions?.discard) {
          this.discardedTracks.push({
            track,
            reason: "discarded_by_user"
          });
          continue;
        }
        if (this._totalTrackCount === outputTrackCounts.total.max) {
          this.discardedTracks.push({
            track,
            reason: "max_track_count_reached"
          });
          continue;
        }
        if (this._addedCounts[track.type] === outputTrackCounts[track.type].max) {
          this.discardedTracks.push({
            track,
            reason: "max_track_count_of_type_reached"
          });
          continue;
        }
        if (track.isVideoTrack()) {
          await this._processVideoTrack(track, trackOptions ?? {});
        } else if (track.isAudioTrack()) {
          await this._processAudioTrack(track, trackOptions ?? {});
        }
      }
      const inputTags = await this.input.getMetadataTags();
      let outputTags;
      if (this._options.tags) {
        const result = typeof this._options.tags === "function" ? await this._options.tags(inputTags) : this._options.tags;
        validateMetadataTags(result);
        outputTags = result;
      } else {
        outputTags = inputTags;
      }
      const inputAndOutputFormatMatch = (await this.input.getFormat()).mimeType === this.output.format.mimeType;
      const rawTagsAreUnchanged = inputTags.raw === outputTags.raw;
      if (inputTags.raw && rawTagsAreUnchanged && !inputAndOutputFormatMatch) {
        delete outputTags.raw;
      }
      this.output.setMetadataTags(outputTags);
      this.isValid = this._totalTrackCount >= outputTrackCounts.total.min && this._addedCounts.video >= outputTrackCounts.video.min && this._addedCounts.audio >= outputTrackCounts.audio.min && this._addedCounts.subtitle >= outputTrackCounts.subtitle.min;
      if (this._options.showWarnings ?? true) {
        const warnElements = [];
        const unintentionallyDiscardedTracks = this.discardedTracks.filter((x) => x.reason !== "discarded_by_user");
        if (unintentionallyDiscardedTracks.length > 0) {
          warnElements.push(
            "Some tracks had to be discarded from the conversion:",
            unintentionallyDiscardedTracks
          );
        }
        if (!this.isValid) {
          warnElements.push("\n\n" + this._getInvalidityExplanation().join(""));
        }
        if (warnElements.length > 0) {
          console.warn(...warnElements);
        }
      }
    }
    /** @internal */
    _getInvalidityExplanation() {
      const elements = [];
      if (this.discardedTracks.length === 0) {
        elements.push(
          "Due to missing tracks, this conversion cannot be executed."
        );
      } else {
        const encodabilityIsTheProblem = this.discardedTracks.every(
          (x) => x.reason === "discarded_by_user" || x.reason === "no_encodable_target_codec"
        );
        elements.push(
          "Due to discarded tracks, this conversion cannot be executed."
        );
        if (encodabilityIsTheProblem) {
          const codecs = this.discardedTracks.flatMap((x) => {
            if (x.reason === "discarded_by_user") return [];
            if (x.track.type === "video") {
              return this.output.format.getSupportedVideoCodecs();
            } else if (x.track.type === "audio") {
              return this.output.format.getSupportedAudioCodecs();
            } else {
              return this.output.format.getSupportedSubtitleCodecs();
            }
          });
          if (codecs.length === 1) {
            elements.push(
              `
Tracks were discarded because your environment is not able to encode '${codecs[0]}'.`
            );
          } else {
            elements.push(
              `
Tracks were discarded because your environment is not able to encode any of the following codecs: ${codecs.map((x) => `'${x}'`).join(", ")}.`
            );
          }
          if (codecs.includes("mp3")) {
            elements.push(
              `
The @mediabunny/mp3-encoder extension package provides support for encoding MP3.`
            );
          }
          if (codecs.includes("ac3") || codecs.includes("eac3")) {
            elements.push(
              "\nThe @mediabunny/ac3 extension package provides support for encoding and decoding AC-3/E-AC-3."
            );
          }
        } else {
          elements.push("\nCheck the discardedTracks field for more info.");
        }
      }
      return elements;
    }
    /**
     * Executes the conversion process. Resolves once conversion is complete.
     *
     * Will throw if `isValid` is `false`.
     */
    async execute() {
      if (!this.isValid) {
        throw new Error(
          "Cannot execute this conversion because its output configuration is invalid. Make sure to always check the isValid field before executing a conversion.\n" + this._getInvalidityExplanation().join("")
        );
      }
      if (this._executed) {
        throw new Error("Conversion cannot be executed twice.");
      }
      this._executed = true;
      if (this.onProgress) {
        const durationPromises = this.utilizedTracks.map((x) => x.computeDuration());
        const duration = Math.max(0, ...await Promise.all(durationPromises));
        this._computeProgress = true;
        this._totalDuration = Math.min(
          duration - this._startTimestamp,
          this._endTimestamp - this._startTimestamp
        );
        for (const track of this.utilizedTracks) {
          this._maxTimestamps.set(track.id, 0);
        }
        this.onProgress?.(0);
      }
      await this.output.start();
      this._start();
      try {
        await Promise.all(this._trackPromises);
      } catch (error) {
        if (!this._canceled) {
          void this.cancel();
        }
        throw error;
      }
      if (this._canceled) {
        throw new ConversionCanceledError();
      }
      await this.output.finalize();
      if (this._computeProgress) {
        this.onProgress?.(1);
      }
    }
    /**
     * Cancels the conversion process, causing any ongoing `execute` call to throw a `ConversionCanceledError`.
     * Does nothing if the conversion is already complete.
     */
    async cancel() {
      if (this.output.state === "finalizing" || this.output.state === "finalized") {
        return;
      }
      if (this._canceled) {
        console.warn("Conversion already canceled.");
        return;
      }
      this._canceled = true;
      await this.output.cancel();
    }
    /** @internal */
    async _processVideoTrack(track, trackOptions) {
      const sourceCodec = track.codec;
      if (!sourceCodec) {
        this.discardedTracks.push({
          track,
          reason: "unknown_source_codec"
        });
        return;
      }
      let videoSource;
      const totalRotation = normalizeRotation(track.rotation + (trackOptions.rotate ?? 0));
      const canUseRotationMetadata = this.output.format.supportsVideoRotationMetadata && (trackOptions.allowRotationMetadata ?? true);
      const [rotatedWidth, rotatedHeight] = totalRotation % 180 === 0 ? [track.codedWidth, track.codedHeight] : [track.codedHeight, track.codedWidth];
      const crop = trackOptions.crop;
      if (crop) {
        clampCropRectangle(crop, rotatedWidth, rotatedHeight);
      }
      const [originalWidth, originalHeight] = crop ? [crop.width, crop.height] : [rotatedWidth, rotatedHeight];
      let width = originalWidth;
      let height = originalHeight;
      const aspectRatio = width / height;
      const ceilToMultipleOfTwo = (value) => Math.ceil(value / 2) * 2;
      if (trackOptions.width !== void 0 && trackOptions.height === void 0) {
        width = ceilToMultipleOfTwo(trackOptions.width);
        height = ceilToMultipleOfTwo(Math.round(width / aspectRatio));
      } else if (trackOptions.width === void 0 && trackOptions.height !== void 0) {
        height = ceilToMultipleOfTwo(trackOptions.height);
        width = ceilToMultipleOfTwo(Math.round(height * aspectRatio));
      } else if (trackOptions.width !== void 0 && trackOptions.height !== void 0) {
        width = ceilToMultipleOfTwo(trackOptions.width);
        height = ceilToMultipleOfTwo(trackOptions.height);
      }
      const firstTimestamp = await track.getFirstTimestamp();
      const needsTranscode = !!trackOptions.forceTranscode || firstTimestamp < this._startTimestamp || !!trackOptions.frameRate || trackOptions.keyFrameInterval !== void 0 || trackOptions.process !== void 0;
      let needsRerender = width !== originalWidth || height !== originalHeight || totalRotation !== 0 && (!canUseRotationMetadata || trackOptions.process !== void 0) || !!crop;
      const alpha = trackOptions.alpha ?? "discard";
      let videoCodecs = this.output.format.getSupportedVideoCodecs();
      if (!needsTranscode && !trackOptions.bitrate && !needsRerender && videoCodecs.includes(sourceCodec) && (!trackOptions.codec || trackOptions.codec === sourceCodec)) {
        const source = new EncodedVideoPacketSource(sourceCodec);
        videoSource = source;
        this._trackPromises.push((async () => {
          await this._started;
          const sink = new EncodedPacketSink(track);
          const decoderConfig = await track.getDecoderConfig();
          const meta = { decoderConfig: decoderConfig ?? void 0 };
          const endPacket = Number.isFinite(this._endTimestamp) ? await sink.getPacket(this._endTimestamp, { metadataOnly: true }) ?? void 0 : void 0;
          for await (const packet of sink.packets(void 0, endPacket, { verifyKeyPackets: true })) {
            if (this._canceled) {
              return;
            }
            const modifiedPacket = packet.clone({
              timestamp: packet.timestamp - this._startTimestamp,
              sideData: alpha === "discard" ? {} : packet.sideData
            });
            assert(modifiedPacket.timestamp >= 0);
            this._reportProgress(track.id, modifiedPacket.timestamp);
            await source.add(modifiedPacket, meta);
            if (this._synchronizer.shouldWait(track.id, modifiedPacket.timestamp)) {
              await this._synchronizer.wait(modifiedPacket.timestamp);
            }
          }
          source.close();
          this._synchronizer.closeTrack(track.id);
        })());
      } else {
        const canDecode = await track.canDecode();
        if (!canDecode) {
          this.discardedTracks.push({
            track,
            reason: "undecodable_source_codec"
          });
          return;
        }
        if (trackOptions.codec) {
          videoCodecs = videoCodecs.filter((codec) => codec === trackOptions.codec);
        }
        const bitrate = trackOptions.bitrate ?? QUALITY_HIGH;
        const encodableCodec = await getFirstEncodableVideoCodec(videoCodecs, {
          width: trackOptions.process && trackOptions.processedWidth ? trackOptions.processedWidth : width,
          height: trackOptions.process && trackOptions.processedHeight ? trackOptions.processedHeight : height,
          bitrate
        });
        if (!encodableCodec) {
          this.discardedTracks.push({
            track,
            reason: "no_encodable_target_codec"
          });
          return;
        }
        const encodingConfig = {
          codec: encodableCodec,
          bitrate,
          keyFrameInterval: trackOptions.keyFrameInterval,
          sizeChangeBehavior: trackOptions.fit ?? "passThrough",
          alpha,
          hardwareAcceleration: trackOptions.hardwareAcceleration
        };
        const source = new VideoSampleSource(encodingConfig);
        videoSource = source;
        if (!needsRerender) {
          const tempOutput = new Output({
            format: new Mp4OutputFormat(),
            // Supports all video codecs
            target: new NullTarget()
          });
          const tempSource = new VideoSampleSource(encodingConfig);
          tempOutput.addVideoTrack(tempSource);
          await tempOutput.start();
          const sink = new VideoSampleSink(track);
          const firstSample = await sink.getSample(firstTimestamp);
          if (firstSample) {
            try {
              await tempSource.add(firstSample);
              firstSample.close();
              await tempOutput.finalize();
            } catch (error) {
              console.info("Error when probing encoder support. Falling back to rerender path.", error);
              needsRerender = true;
              void tempOutput.cancel();
            }
          } else {
            await tempOutput.cancel();
          }
        }
        if (needsRerender) {
          this._trackPromises.push((async () => {
            await this._started;
            const sink = new CanvasSink(track, {
              width,
              height,
              fit: trackOptions.fit ?? "fill",
              rotation: totalRotation,
              // Bake the rotation into the output
              crop: trackOptions.crop,
              poolSize: 1,
              alpha: alpha === "keep"
            });
            const iterator = sink.canvases(this._startTimestamp, this._endTimestamp);
            const frameRate = trackOptions.frameRate;
            let lastCanvas = null;
            let lastCanvasTimestamp = null;
            let lastCanvasEndTimestamp = null;
            const padFrames = async (until) => {
              assert(lastCanvas);
              assert(frameRate !== void 0);
              const frameDifference = Math.round((until - lastCanvasTimestamp) * frameRate);
              for (let i = 1; i < frameDifference; i++) {
                const sample = new VideoSample(lastCanvas, {
                  timestamp: lastCanvasTimestamp + i / frameRate,
                  duration: 1 / frameRate
                });
                await this._registerVideoSample(track, trackOptions, source, sample);
                sample.close();
              }
            };
            for await (const { canvas, timestamp, duration } of iterator) {
              if (this._canceled) {
                return;
              }
              let adjustedSampleTimestamp = Math.max(timestamp - this._startTimestamp, 0);
              lastCanvasEndTimestamp = adjustedSampleTimestamp + duration;
              if (frameRate !== void 0) {
                const alignedTimestamp = Math.floor(adjustedSampleTimestamp * frameRate) / frameRate;
                if (lastCanvas !== null) {
                  if (alignedTimestamp <= lastCanvasTimestamp) {
                    lastCanvas = canvas;
                    lastCanvasTimestamp = alignedTimestamp;
                    continue;
                  } else {
                    await padFrames(alignedTimestamp);
                  }
                }
                adjustedSampleTimestamp = alignedTimestamp;
              }
              const sample = new VideoSample(canvas, {
                timestamp: adjustedSampleTimestamp,
                duration: frameRate !== void 0 ? 1 / frameRate : duration
              });
              await this._registerVideoSample(track, trackOptions, source, sample);
              sample.close();
              if (frameRate !== void 0) {
                lastCanvas = canvas;
                lastCanvasTimestamp = adjustedSampleTimestamp;
              }
            }
            if (lastCanvas) {
              assert(lastCanvasEndTimestamp !== null);
              assert(frameRate !== void 0);
              await padFrames(Math.floor(lastCanvasEndTimestamp * frameRate) / frameRate);
            }
            source.close();
            this._synchronizer.closeTrack(track.id);
          })());
        } else {
          this._trackPromises.push((async () => {
            await this._started;
            const sink = new VideoSampleSink(track);
            const frameRate = trackOptions.frameRate;
            let lastSample = null;
            let lastSampleTimestamp = null;
            let lastSampleEndTimestamp = null;
            const padFrames = async (until) => {
              assert(lastSample);
              assert(frameRate !== void 0);
              const frameDifference = Math.round((until - lastSampleTimestamp) * frameRate);
              for (let i = 1; i < frameDifference; i++) {
                lastSample.setTimestamp(lastSampleTimestamp + i / frameRate);
                lastSample.setDuration(1 / frameRate);
                await this._registerVideoSample(track, trackOptions, source, lastSample);
              }
              lastSample.close();
            };
            for await (const sample of sink.samples(this._startTimestamp, this._endTimestamp)) {
              if (this._canceled) {
                sample.close();
                lastSample?.close();
                return;
              }
              let adjustedSampleTimestamp = Math.max(sample.timestamp - this._startTimestamp, 0);
              lastSampleEndTimestamp = adjustedSampleTimestamp + sample.duration;
              if (frameRate !== void 0) {
                const alignedTimestamp = Math.floor(adjustedSampleTimestamp * frameRate) / frameRate;
                if (lastSample !== null) {
                  if (alignedTimestamp <= lastSampleTimestamp) {
                    lastSample.close();
                    lastSample = sample;
                    lastSampleTimestamp = alignedTimestamp;
                    continue;
                  } else {
                    await padFrames(alignedTimestamp);
                  }
                }
                adjustedSampleTimestamp = alignedTimestamp;
                sample.setDuration(1 / frameRate);
              }
              sample.setTimestamp(adjustedSampleTimestamp);
              await this._registerVideoSample(track, trackOptions, source, sample);
              if (frameRate !== void 0) {
                lastSample = sample;
                lastSampleTimestamp = adjustedSampleTimestamp;
              } else {
                sample.close();
              }
            }
            if (lastSample) {
              assert(lastSampleEndTimestamp !== null);
              assert(frameRate !== void 0);
              await padFrames(Math.floor(lastSampleEndTimestamp * frameRate) / frameRate);
            }
            source.close();
            this._synchronizer.closeTrack(track.id);
          })());
        }
      }
      this.output.addVideoTrack(videoSource, {
        frameRate: trackOptions.frameRate,
        // TODO: This condition can be removed when all demuxers properly homogenize to BCP47 in v2
        languageCode: isIso639Dash2LanguageCode(track.languageCode) ? track.languageCode : void 0,
        name: track.name ?? void 0,
        disposition: track.disposition,
        rotation: needsRerender ? 0 : totalRotation
        // Rerendering will bake the rotation into the output
      });
      this._addedCounts.video++;
      this._totalTrackCount++;
      this.utilizedTracks.push(track);
    }
    /** @internal */
    async _registerVideoSample(track, trackOptions, source, sample) {
      if (this._canceled) {
        return;
      }
      this._reportProgress(track.id, sample.timestamp);
      let finalSamples;
      if (!trackOptions.process) {
        finalSamples = [sample];
      } else {
        let processed = trackOptions.process(sample);
        if (processed instanceof Promise) processed = await processed;
        if (!Array.isArray(processed)) {
          processed = processed === null ? [] : [processed];
        }
        finalSamples = processed.map((x) => {
          if (x instanceof VideoSample) {
            return x;
          }
          if (typeof VideoFrame !== "undefined" && x instanceof VideoFrame) {
            return new VideoSample(x);
          }
          return new VideoSample(x, {
            timestamp: sample.timestamp,
            duration: sample.duration
          });
        });
      }
      for (const finalSample of finalSamples) {
        if (this._canceled) {
          break;
        }
        await source.add(finalSample);
        if (this._synchronizer.shouldWait(track.id, finalSample.timestamp)) {
          await this._synchronizer.wait(finalSample.timestamp);
        }
      }
      for (const finalSample of finalSamples) {
        if (finalSample !== sample) {
          finalSample.close();
        }
      }
    }
    /** @internal */
    async _processAudioTrack(track, trackOptions) {
      const sourceCodec = track.codec;
      if (!sourceCodec) {
        this.discardedTracks.push({
          track,
          reason: "unknown_source_codec"
        });
        return;
      }
      let audioSource;
      const originalNumberOfChannels = track.numberOfChannels;
      const originalSampleRate = track.sampleRate;
      const firstTimestamp = await track.getFirstTimestamp();
      let numberOfChannels = trackOptions.numberOfChannels ?? originalNumberOfChannels;
      let sampleRate = trackOptions.sampleRate ?? originalSampleRate;
      let needsResample = numberOfChannels !== originalNumberOfChannels || sampleRate !== originalSampleRate || firstTimestamp < this._startTimestamp || firstTimestamp > this._startTimestamp && !this.output.format.supportsTimestampedMediaData;
      let audioCodecs = this.output.format.getSupportedAudioCodecs();
      if (!trackOptions.forceTranscode && !trackOptions.bitrate && !needsResample && audioCodecs.includes(sourceCodec) && (!trackOptions.codec || trackOptions.codec === sourceCodec) && !trackOptions.process) {
        const source = new EncodedAudioPacketSource(sourceCodec);
        audioSource = source;
        this._trackPromises.push((async () => {
          await this._started;
          const sink = new EncodedPacketSink(track);
          const decoderConfig = await track.getDecoderConfig();
          const meta = { decoderConfig: decoderConfig ?? void 0 };
          const endPacket = Number.isFinite(this._endTimestamp) ? await sink.getPacket(this._endTimestamp, { metadataOnly: true }) ?? void 0 : void 0;
          for await (const packet of sink.packets(void 0, endPacket)) {
            if (this._canceled) {
              return;
            }
            const modifiedPacket = packet.clone({
              timestamp: packet.timestamp - this._startTimestamp
            });
            assert(modifiedPacket.timestamp >= 0);
            this._reportProgress(track.id, modifiedPacket.timestamp);
            await source.add(modifiedPacket, meta);
            if (this._synchronizer.shouldWait(track.id, modifiedPacket.timestamp)) {
              await this._synchronizer.wait(modifiedPacket.timestamp);
            }
          }
          source.close();
          this._synchronizer.closeTrack(track.id);
        })());
      } else {
        const canDecode = await track.canDecode();
        if (!canDecode) {
          this.discardedTracks.push({
            track,
            reason: "undecodable_source_codec"
          });
          return;
        }
        let codecOfChoice = null;
        if (trackOptions.codec) {
          audioCodecs = audioCodecs.filter((codec) => codec === trackOptions.codec);
        }
        const bitrate = trackOptions.bitrate ?? QUALITY_HIGH;
        const encodableCodecs = await getEncodableAudioCodecs(audioCodecs, {
          numberOfChannels: trackOptions.process && trackOptions.processedNumberOfChannels ? trackOptions.processedNumberOfChannels : numberOfChannels,
          sampleRate: trackOptions.process && trackOptions.processedSampleRate ? trackOptions.processedSampleRate : sampleRate,
          bitrate
        });
        if (!encodableCodecs.some((codec) => NON_PCM_AUDIO_CODECS.includes(codec)) && audioCodecs.some((codec) => NON_PCM_AUDIO_CODECS.includes(codec)) && (numberOfChannels !== FALLBACK_NUMBER_OF_CHANNELS || sampleRate !== FALLBACK_SAMPLE_RATE)) {
          const encodableCodecsWithDefaultParams = await getEncodableAudioCodecs(audioCodecs, {
            numberOfChannels: FALLBACK_NUMBER_OF_CHANNELS,
            sampleRate: FALLBACK_SAMPLE_RATE,
            bitrate
          });
          const nonPcmCodec = encodableCodecsWithDefaultParams.find((codec) => NON_PCM_AUDIO_CODECS.includes(codec));
          if (nonPcmCodec) {
            needsResample = true;
            codecOfChoice = nonPcmCodec;
            numberOfChannels = FALLBACK_NUMBER_OF_CHANNELS;
            sampleRate = FALLBACK_SAMPLE_RATE;
          }
        } else {
          codecOfChoice = encodableCodecs[0] ?? null;
        }
        if (codecOfChoice === null) {
          this.discardedTracks.push({
            track,
            reason: "no_encodable_target_codec"
          });
          return;
        }
        if (needsResample) {
          audioSource = this._resampleAudio(
            track,
            trackOptions,
            codecOfChoice,
            numberOfChannels,
            sampleRate,
            bitrate
          );
        } else {
          const source = new AudioSampleSource({
            codec: codecOfChoice,
            bitrate
          });
          audioSource = source;
          this._trackPromises.push((async () => {
            await this._started;
            const sink = new AudioSampleSink(track);
            for await (const sample of sink.samples(void 0, this._endTimestamp)) {
              if (this._canceled) {
                sample.close();
                return;
              }
              sample.setTimestamp(sample.timestamp - this._startTimestamp);
              await this._registerAudioSample(track, trackOptions, source, sample);
              sample.close();
            }
            source.close();
            this._synchronizer.closeTrack(track.id);
          })());
        }
      }
      this.output.addAudioTrack(audioSource, {
        // TODO: This condition can be removed when all demuxers properly homogenize to BCP47 in v2
        languageCode: isIso639Dash2LanguageCode(track.languageCode) ? track.languageCode : void 0,
        name: track.name ?? void 0,
        disposition: track.disposition
      });
      this._addedCounts.audio++;
      this._totalTrackCount++;
      this.utilizedTracks.push(track);
    }
    /** @internal */
    async _registerAudioSample(track, trackOptions, source, sample) {
      if (this._canceled) {
        return;
      }
      this._reportProgress(track.id, sample.timestamp);
      let finalSamples;
      if (!trackOptions.process) {
        finalSamples = [sample];
      } else {
        let processed = trackOptions.process(sample);
        if (processed instanceof Promise) processed = await processed;
        if (!Array.isArray(processed)) {
          processed = processed === null ? [] : [processed];
        }
        if (!processed.every((x) => x instanceof AudioSample)) {
          throw new TypeError(
            "The audio process function must return an AudioSample, null, or an array of AudioSamples."
          );
        }
        finalSamples = processed;
      }
      for (const finalSample of finalSamples) {
        if (this._canceled) {
          break;
        }
        await source.add(finalSample);
        if (this._synchronizer.shouldWait(track.id, finalSample.timestamp)) {
          await this._synchronizer.wait(finalSample.timestamp);
        }
      }
      for (const finalSample of finalSamples) {
        if (finalSample !== sample) {
          finalSample.close();
        }
      }
    }
    /** @internal */
    _resampleAudio(track, trackOptions, codec, targetNumberOfChannels, targetSampleRate, bitrate) {
      const source = new AudioSampleSource({
        codec,
        bitrate
      });
      this._trackPromises.push((async () => {
        await this._started;
        const resampler = new AudioResampler({
          targetNumberOfChannels,
          targetSampleRate,
          startTime: this._startTimestamp,
          endTime: this._endTimestamp,
          onSample: async (sample) => {
            await this._registerAudioSample(track, trackOptions, source, sample);
            sample.close();
          }
        });
        const sink = new AudioSampleSink(track);
        const iterator = sink.samples(this._startTimestamp, this._endTimestamp);
        for await (const sample of iterator) {
          if (this._canceled) {
            sample.close();
            return;
          }
          await resampler.add(sample);
          sample.close();
        }
        await resampler.finalize();
        source.close();
        this._synchronizer.closeTrack(track.id);
      })());
      return source;
    }
    /** @internal */
    _reportProgress(trackId, endTimestamp) {
      if (!this._computeProgress) {
        return;
      }
      assert(this._totalDuration !== null);
      this._maxTimestamps.set(
        trackId,
        Math.max(endTimestamp, this._maxTimestamps.get(trackId))
      );
      const minTimestamp = Math.min(...this._maxTimestamps.values());
      const newProgress = clamp(minTimestamp / this._totalDuration, 0, 1);
      if (newProgress !== this._lastProgress) {
        this._lastProgress = newProgress;
        this.onProgress?.(newProgress);
      }
    }
  };
  var ConversionCanceledError = class extends Error {
    /** Creates a new {@link ConversionCanceledError}. */
    constructor(message = "Conversion has been canceled.") {
      super(message);
      this.name = "ConversionCanceledError";
    }
  };
  var MAX_TIMESTAMP_GAP = 5;
  var TrackSynchronizer = class {
    constructor() {
      this.maxTimestamps = /* @__PURE__ */ new Map();
      // Track ID -> timestamp
      this.resolvers = [];
    }
    computeMinAndMaybeResolve() {
      let newMin = Infinity;
      for (const [, timestamp] of this.maxTimestamps) {
        newMin = Math.min(newMin, timestamp);
      }
      for (let i = 0; i < this.resolvers.length; i++) {
        const entry = this.resolvers[i];
        if (entry.timestamp - newMin < MAX_TIMESTAMP_GAP) {
          entry.resolve();
          this.resolvers.splice(i, 1);
          i--;
        }
      }
      return newMin;
    }
    shouldWait(trackId, timestamp) {
      this.maxTimestamps.set(trackId, Math.max(timestamp, this.maxTimestamps.get(trackId) ?? -Infinity));
      const newMin = this.computeMinAndMaybeResolve();
      return timestamp - newMin >= MAX_TIMESTAMP_GAP;
    }
    wait(timestamp) {
      const { promise, resolve } = promiseWithResolvers();
      this.resolvers.push({
        timestamp,
        resolve
      });
      return promise;
    }
    closeTrack(trackId) {
      this.maxTimestamps.delete(trackId);
      this.computeMinAndMaybeResolve();
    }
  };
  var AudioResampler = class {
    constructor(options) {
      this.sourceSampleRate = null;
      this.sourceNumberOfChannels = null;
      this.targetSampleRate = options.targetSampleRate;
      this.targetNumberOfChannels = options.targetNumberOfChannels;
      this.startTime = options.startTime;
      this.endTime = options.endTime;
      this.onSample = options.onSample;
      this.bufferSizeInFrames = Math.floor(this.targetSampleRate * 5);
      this.bufferSizeInSamples = this.bufferSizeInFrames * this.targetNumberOfChannels;
      this.outputBuffer = new Float32Array(this.bufferSizeInSamples);
      this.bufferStartFrame = 0;
      this.maxWrittenFrame = -1;
    }
    /**
     * Sets up the channel mixer to handle up/downmixing in the case where input and output channel counts don't match.
     */
    doChannelMixerSetup() {
      assert(this.sourceNumberOfChannels !== null);
      const sourceNum = this.sourceNumberOfChannels;
      const targetNum = this.targetNumberOfChannels;
      if (sourceNum === 1 && targetNum === 2) {
        this.channelMixer = (sourceData, sourceFrameIndex) => {
          return sourceData[sourceFrameIndex * sourceNum];
        };
      } else if (sourceNum === 1 && targetNum === 4) {
        this.channelMixer = (sourceData, sourceFrameIndex, targetChannelIndex) => {
          return sourceData[sourceFrameIndex * sourceNum] * +(targetChannelIndex < 2);
        };
      } else if (sourceNum === 1 && targetNum === 6) {
        this.channelMixer = (sourceData, sourceFrameIndex, targetChannelIndex) => {
          return sourceData[sourceFrameIndex * sourceNum] * +(targetChannelIndex === 2);
        };
      } else if (sourceNum === 2 && targetNum === 1) {
        this.channelMixer = (sourceData, sourceFrameIndex) => {
          const baseIdx = sourceFrameIndex * sourceNum;
          return 0.5 * (sourceData[baseIdx] + sourceData[baseIdx + 1]);
        };
      } else if (sourceNum === 2 && targetNum === 4) {
        this.channelMixer = (sourceData, sourceFrameIndex, targetChannelIndex) => {
          return sourceData[sourceFrameIndex * sourceNum + targetChannelIndex] * +(targetChannelIndex < 2);
        };
      } else if (sourceNum === 2 && targetNum === 6) {
        this.channelMixer = (sourceData, sourceFrameIndex, targetChannelIndex) => {
          return sourceData[sourceFrameIndex * sourceNum + targetChannelIndex] * +(targetChannelIndex < 2);
        };
      } else if (sourceNum === 4 && targetNum === 1) {
        this.channelMixer = (sourceData, sourceFrameIndex) => {
          const baseIdx = sourceFrameIndex * sourceNum;
          return 0.25 * (sourceData[baseIdx] + sourceData[baseIdx + 1] + sourceData[baseIdx + 2] + sourceData[baseIdx + 3]);
        };
      } else if (sourceNum === 4 && targetNum === 2) {
        this.channelMixer = (sourceData, sourceFrameIndex, targetChannelIndex) => {
          const baseIdx = sourceFrameIndex * sourceNum;
          return 0.5 * (sourceData[baseIdx + targetChannelIndex] + sourceData[baseIdx + targetChannelIndex + 2]);
        };
      } else if (sourceNum === 4 && targetNum === 6) {
        this.channelMixer = (sourceData, sourceFrameIndex, targetChannelIndex) => {
          const baseIdx = sourceFrameIndex * sourceNum;
          if (targetChannelIndex < 2) return sourceData[baseIdx + targetChannelIndex];
          if (targetChannelIndex === 2 || targetChannelIndex === 3) return 0;
          return sourceData[baseIdx + targetChannelIndex - 2];
        };
      } else if (sourceNum === 6 && targetNum === 1) {
        this.channelMixer = (sourceData, sourceFrameIndex) => {
          const baseIdx = sourceFrameIndex * sourceNum;
          return Math.SQRT1_2 * (sourceData[baseIdx] + sourceData[baseIdx + 1]) + sourceData[baseIdx + 2] + 0.5 * (sourceData[baseIdx + 4] + sourceData[baseIdx + 5]);
        };
      } else if (sourceNum === 6 && targetNum === 2) {
        this.channelMixer = (sourceData, sourceFrameIndex, targetChannelIndex) => {
          const baseIdx = sourceFrameIndex * sourceNum;
          return sourceData[baseIdx + targetChannelIndex] + Math.SQRT1_2 * (sourceData[baseIdx + 2] + sourceData[baseIdx + targetChannelIndex + 4]);
        };
      } else if (sourceNum === 6 && targetNum === 4) {
        this.channelMixer = (sourceData, sourceFrameIndex, targetChannelIndex) => {
          const baseIdx = sourceFrameIndex * sourceNum;
          if (targetChannelIndex < 2) {
            return sourceData[baseIdx + targetChannelIndex] + Math.SQRT1_2 * sourceData[baseIdx + 2];
          }
          return sourceData[baseIdx + targetChannelIndex + 2];
        };
      } else {
        this.channelMixer = (sourceData, sourceFrameIndex, targetChannelIndex) => {
          return targetChannelIndex < sourceNum ? sourceData[sourceFrameIndex * sourceNum + targetChannelIndex] : 0;
        };
      }
    }
    ensureTempBufferSize(requiredSamples) {
      let length = this.tempSourceBuffer.length;
      while (length < requiredSamples) {
        length *= 2;
      }
      if (length !== this.tempSourceBuffer.length) {
        const newBuffer = new Float32Array(length);
        newBuffer.set(this.tempSourceBuffer);
        this.tempSourceBuffer = newBuffer;
      }
    }
    async add(audioSample) {
      if (this.sourceSampleRate === null) {
        this.sourceSampleRate = audioSample.sampleRate;
        this.sourceNumberOfChannels = audioSample.numberOfChannels;
        this.tempSourceBuffer = new Float32Array(this.sourceSampleRate * this.sourceNumberOfChannels);
        this.doChannelMixerSetup();
      }
      const requiredSamples = audioSample.numberOfFrames * audioSample.numberOfChannels;
      this.ensureTempBufferSize(requiredSamples);
      const sourceDataSize = audioSample.allocationSize({ planeIndex: 0, format: "f32" });
      const sourceView = new Float32Array(this.tempSourceBuffer.buffer, 0, sourceDataSize / 4);
      audioSample.copyTo(sourceView, { planeIndex: 0, format: "f32" });
      const inputStartTime = audioSample.timestamp - this.startTime;
      const inputDuration = audioSample.numberOfFrames / this.sourceSampleRate;
      const inputEndTime = Math.min(inputStartTime + inputDuration, this.endTime - this.startTime);
      const outputStartFrame = Math.floor(inputStartTime * this.targetSampleRate);
      const outputEndFrame = Math.ceil(inputEndTime * this.targetSampleRate);
      for (let outputFrame = outputStartFrame; outputFrame < outputEndFrame; outputFrame++) {
        if (outputFrame < this.bufferStartFrame) {
          continue;
        }
        while (outputFrame >= this.bufferStartFrame + this.bufferSizeInFrames) {
          await this.finalizeCurrentBuffer();
          this.bufferStartFrame += this.bufferSizeInFrames;
        }
        const bufferFrameIndex = outputFrame - this.bufferStartFrame;
        assert(bufferFrameIndex < this.bufferSizeInFrames);
        const outputTime = outputFrame / this.targetSampleRate;
        const inputTime = outputTime - inputStartTime;
        const sourcePosition = inputTime * this.sourceSampleRate;
        const sourceLowerFrame = Math.floor(sourcePosition);
        const sourceUpperFrame = Math.ceil(sourcePosition);
        const fraction = sourcePosition - sourceLowerFrame;
        for (let targetChannel = 0; targetChannel < this.targetNumberOfChannels; targetChannel++) {
          let lowerSample = 0;
          let upperSample = 0;
          if (sourceLowerFrame >= 0 && sourceLowerFrame < audioSample.numberOfFrames) {
            lowerSample = this.channelMixer(sourceView, sourceLowerFrame, targetChannel);
          }
          if (sourceUpperFrame >= 0 && sourceUpperFrame < audioSample.numberOfFrames) {
            upperSample = this.channelMixer(sourceView, sourceUpperFrame, targetChannel);
          }
          const outputSample = lowerSample + fraction * (upperSample - lowerSample);
          const outputIndex = bufferFrameIndex * this.targetNumberOfChannels + targetChannel;
          this.outputBuffer[outputIndex] += outputSample;
        }
        this.maxWrittenFrame = Math.max(this.maxWrittenFrame, bufferFrameIndex);
      }
    }
    async finalizeCurrentBuffer() {
      if (this.maxWrittenFrame < 0) {
        return;
      }
      const samplesWritten = (this.maxWrittenFrame + 1) * this.targetNumberOfChannels;
      const outputData = new Float32Array(samplesWritten);
      outputData.set(this.outputBuffer.subarray(0, samplesWritten));
      const timestampSeconds = this.bufferStartFrame / this.targetSampleRate;
      const audioSample = new AudioSample({
        format: "f32",
        sampleRate: this.targetSampleRate,
        numberOfChannels: this.targetNumberOfChannels,
        timestamp: timestampSeconds,
        data: outputData
      });
      await this.onSample(audioSample);
      this.outputBuffer.fill(0);
      this.maxWrittenFrame = -1;
    }
    finalize() {
      return this.finalizeCurrentBuffer();
    }
  };

  // src/index.ts
  var MEDIABUNNY_LOADED_SYMBOL = Symbol.for("mediabunny loaded");
  if (globalThis[MEDIABUNNY_LOADED_SYMBOL]) {
    console.error(
      "[WARNING]\nMediabunny was loaded twice. This will likely cause Mediabunny not to work correctly. Check if multiple dependencies are importing different versions of Mediabunny, or if something is being bundled incorrectly."
    );
  }
  globalThis[MEDIABUNNY_LOADED_SYMBOL] = true;
  return __toCommonJS(index_exports);
})();
if ( true && typeof module.exports === "object") Object.assign(module.exports, Mediabunny)


/***/ },

/***/ 4229
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Cb: () => (/* binding */ PlayerInternals)
/* harmony export */ });
/* unused harmony exports Thumbnail, Player */
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4848);
/* harmony import */ var remotion__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3947);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(6540);
/* harmony import */ var remotion_no_react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(9382);
"use client";
// src/icons.tsx

var ICON_SIZE = 25;
var fullscreenIconSize = 16;
var PlayIcon = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("svg", {
    width: ICON_SIZE,
    height: ICON_SIZE,
    viewBox: "0 0 25 25",
    fill: "none",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("path", {
      d: "M8 6.375C7.40904 8.17576 7.06921 10.2486 7.01438 12.3871C6.95955 14.5255 7.19163 16.6547 7.6875 18.5625C9.95364 18.2995 12.116 17.6164 14.009 16.5655C15.902 15.5147 17.4755 14.124 18.6088 12.5C17.5158 10.8949 15.9949 9.51103 14.1585 8.45082C12.3222 7.3906 10.2174 6.68116 8 6.375Z",
      fill: "white",
      stroke: "white",
      strokeWidth: "6.25",
      strokeLinejoin: "round"
    })
  });
};
var PauseIcon = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("svg", {
    viewBox: "0 0 100 100",
    width: ICON_SIZE,
    height: ICON_SIZE,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("rect", {
        x: "25",
        y: "20",
        width: "20",
        height: "60",
        fill: "#fff",
        ry: "5",
        rx: "5"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("rect", {
        x: "55",
        y: "20",
        width: "20",
        height: "60",
        fill: "#fff",
        ry: "5",
        rx: "5"
      })
    ]
  });
};
var FullscreenIcon = ({
  isFullscreen
}) => {
  const strokeWidth = 6;
  const viewSize = 32;
  const out = isFullscreen ? 0 : strokeWidth / 2;
  const middleInset = isFullscreen ? strokeWidth * 1.6 : strokeWidth / 2;
  const inset = isFullscreen ? strokeWidth * 1.6 : strokeWidth * 2;
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("svg", {
    viewBox: `0 0 ${viewSize} ${viewSize}`,
    height: fullscreenIconSize,
    width: fullscreenIconSize,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("path", {
        d: `
				M ${out} ${inset}
				L ${middleInset} ${middleInset}
				L ${inset} ${out}
				`,
        stroke: "#fff",
        strokeWidth,
        fill: "none"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("path", {
        d: `
				M ${viewSize - out} ${inset}
				L ${viewSize - middleInset} ${middleInset}
				L ${viewSize - inset} ${out}
				`,
        stroke: "#fff",
        strokeWidth,
        fill: "none"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("path", {
        d: `
				M ${out} ${viewSize - inset}
				L ${middleInset} ${viewSize - middleInset}
				L ${inset} ${viewSize - out}
				`,
        stroke: "#fff",
        strokeWidth,
        fill: "none"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("path", {
        d: `
				M ${viewSize - out} ${viewSize - inset}
				L ${viewSize - middleInset} ${viewSize - middleInset}
				L ${viewSize - inset} ${viewSize - out}
				`,
        stroke: "#fff",
        strokeWidth,
        fill: "none"
      })
    ]
  });
};
var VolumeOffIcon = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("svg", {
    width: ICON_SIZE,
    height: ICON_SIZE,
    viewBox: "0 0 24 24",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("path", {
      d: "M3.63 3.63a.996.996 0 000 1.41L7.29 8.7 7 9H4c-.55 0-1 .45-1 1v4c0 .55.45 1 1 1h3l3.29 3.29c.63.63 1.71.18 1.71-.71v-4.17l4.18 4.18c-.49.37-1.02.68-1.6.91-.36.15-.58.53-.58.92 0 .72.73 1.18 1.39.91.8-.33 1.55-.77 2.22-1.31l1.34 1.34a.996.996 0 101.41-1.41L5.05 3.63c-.39-.39-1.02-.39-1.42 0zM19 12c0 .82-.15 1.61-.41 2.34l1.53 1.53c.56-1.17.88-2.48.88-3.87 0-3.83-2.4-7.11-5.78-8.4-.59-.23-1.22.23-1.22.86v.19c0 .38.25.71.61.85C17.18 6.54 19 9.06 19 12zm-8.71-6.29l-.17.17L12 7.76V6.41c0-.89-1.08-1.33-1.71-.7zM16.5 12A4.5 4.5 0 0014 7.97v1.79l2.48 2.48c.01-.08.02-.16.02-.24z",
      fill: "#fff"
    })
  });
};
var VolumeOnIcon = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("svg", {
    width: ICON_SIZE,
    height: ICON_SIZE,
    viewBox: "0 0 24 24",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("path", {
      d: "M3 10v4c0 .55.45 1 1 1h3l3.29 3.29c.63.63 1.71.18 1.71-.71V6.41c0-.89-1.08-1.34-1.71-.71L7 9H4c-.55 0-1 .45-1 1zm13.5 2A4.5 4.5 0 0014 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 4.45v.2c0 .38.25.71.6.85C17.18 6.53 19 9.06 19 12s-1.82 5.47-4.4 6.5c-.36.14-.6.47-.6.85v.2c0 .63.63 1.07 1.21.85C18.6 19.11 21 15.84 21 12s-2.4-7.11-5.79-8.4c-.58-.23-1.21.22-1.21.85z",
      fill: "#fff"
    })
  });
};

// src/BufferingIndicator.tsx

var className = "__remotion_buffering_indicator";
var remotionBufferingAnimation = "__remotion_buffering_animation";
var playerStyle = {
  width: ICON_SIZE,
  height: ICON_SIZE,
  overflow: "hidden",
  lineHeight: "normal",
  fontSize: "inherit"
};
var studioStyle = {
  width: 14,
  height: 14,
  overflow: "hidden",
  lineHeight: "normal",
  fontSize: "inherit"
};
var BufferingIndicator = ({ type }) => {
  const style = type === "player" ? playerStyle : studioStyle;
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("style", {
        type: "text/css",
        children: `
				@keyframes ${remotionBufferingAnimation} {
          0% {
            rotate: 0deg;
          }
          100% {
            rotate: 360deg;
          }
        }
        
        .${className} {
            animation: ${remotionBufferingAnimation} 1s linear infinite;
        }        
			`
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
        style,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("svg", {
          viewBox: type === "player" ? "0 0 22 22" : "0 0 18 18",
          style,
          className,
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("path", {
            d: type === "player" ? "M 11 4 A 7 7 0 0 1 15.1145 16.66312" : "M 9 2 A 7 7 0 0 1 13.1145 14.66312",
            stroke: "white",
            strokeLinecap: "round",
            fill: "none",
            strokeWidth: 3
          })
        })
      })
    ]
  });
};

// src/calculate-scale.ts


// src/utils/calculate-player-size.ts
var calculatePlayerSize = ({
  currentSize,
  width,
  height,
  compositionWidth,
  compositionHeight
}) => {
  if (width !== undefined && height === undefined) {
    return {
      aspectRatio: [compositionWidth, compositionHeight].join("/")
    };
  }
  if (height !== undefined && width === undefined) {
    return {
      aspectRatio: [compositionWidth, compositionHeight].join("/")
    };
  }
  if (!currentSize) {
    return {
      width: compositionWidth,
      height: compositionHeight
    };
  }
  return {
    width: compositionWidth,
    height: compositionHeight
  };
};

// src/calculate-scale.ts
var calculateCanvasTransformation = ({
  previewSize,
  compositionWidth,
  compositionHeight,
  canvasSize
}) => {
  const scale = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.calculateScale({
    canvasSize,
    compositionHeight,
    compositionWidth,
    previewSize
  });
  const correction = 0 - (1 - scale) / 2;
  const xCorrection = correction * compositionWidth;
  const yCorrection = correction * compositionHeight;
  const width = compositionWidth * scale;
  const height = compositionHeight * scale;
  const centerX = canvasSize.width / 2 - width / 2;
  const centerY = canvasSize.height / 2 - height / 2;
  return {
    centerX,
    centerY,
    xCorrection,
    yCorrection,
    scale
  };
};
var calculateOuterStyle = ({
  config,
  style,
  canvasSize,
  overflowVisible,
  layout
}) => {
  if (!config) {
    return {};
  }
  return {
    position: "relative",
    overflow: overflowVisible ? "visible" : "hidden",
    ...calculatePlayerSize({
      compositionHeight: config.height,
      compositionWidth: config.width,
      currentSize: canvasSize,
      height: style?.height,
      width: style?.width
    }),
    opacity: layout ? 1 : 0,
    ...style
  };
};
var calculateContainerStyle = ({
  config,
  layout,
  scale,
  overflowVisible
}) => {
  if (!config) {
    return {};
  }
  if (!layout) {
    return {
      position: "absolute",
      width: config.width,
      height: config.height,
      display: "flex",
      transform: `scale(${scale})`,
      overflow: overflowVisible ? "visible" : "hidden"
    };
  }
  return {
    position: "absolute",
    width: config.width,
    height: config.height,
    display: "flex",
    transform: `scale(${scale})`,
    marginLeft: layout.xCorrection,
    marginTop: layout.yCorrection,
    overflow: overflowVisible ? "visible" : "hidden"
  };
};
var calculateOuter = ({
  layout,
  scale,
  config,
  overflowVisible
}) => {
  if (!config) {
    return {};
  }
  if (!layout) {
    return {
      width: config.width * scale,
      height: config.height * scale,
      display: "flex",
      flexDirection: "column",
      position: "absolute",
      overflow: overflowVisible ? "visible" : "hidden"
    };
  }
  const { centerX, centerY } = layout;
  return {
    width: config.width * scale,
    height: config.height * scale,
    display: "flex",
    flexDirection: "column",
    position: "absolute",
    left: centerX,
    top: centerY,
    overflow: overflowVisible ? "visible" : "hidden"
  };
};

// src/emitter-context.ts

var PlayerEventEmitterContext = react__WEBPACK_IMPORTED_MODULE_2__.createContext(undefined);
var ThumbnailEmitterContext = react__WEBPACK_IMPORTED_MODULE_2__.createContext(undefined);

// src/EmitterProvider.tsx



// src/event-emitter.ts
class PlayerEmitter {
  listeners = {
    ended: [],
    error: [],
    pause: [],
    play: [],
    ratechange: [],
    scalechange: [],
    seeked: [],
    timeupdate: [],
    frameupdate: [],
    fullscreenchange: [],
    volumechange: [],
    mutechange: [],
    waiting: [],
    resume: []
  };
  addEventListener(name, callback) {
    this.listeners[name].push(callback);
  }
  removeEventListener(name, callback) {
    this.listeners[name] = this.listeners[name].filter((l) => l !== callback);
  }
  dispatchEvent(dispatchName, context) {
    this.listeners[dispatchName].forEach((callback) => {
      callback({ detail: context });
    });
  }
  dispatchSeek = (frame) => {
    this.dispatchEvent("seeked", {
      frame
    });
  };
  dispatchVolumeChange = (volume) => {
    this.dispatchEvent("volumechange", {
      volume
    });
  };
  dispatchPause = () => {
    this.dispatchEvent("pause", undefined);
  };
  dispatchPlay = () => {
    this.dispatchEvent("play", undefined);
  };
  dispatchEnded = () => {
    this.dispatchEvent("ended", undefined);
  };
  dispatchRateChange = (playbackRate) => {
    this.dispatchEvent("ratechange", {
      playbackRate
    });
  };
  dispatchScaleChange = (scale) => {
    this.dispatchEvent("scalechange", {
      scale
    });
  };
  dispatchError = (error) => {
    this.dispatchEvent("error", {
      error
    });
  };
  dispatchTimeUpdate = (event) => {
    this.dispatchEvent("timeupdate", event);
  };
  dispatchFrameUpdate = (event) => {
    this.dispatchEvent("frameupdate", event);
  };
  dispatchFullscreenChange = (event) => {
    this.dispatchEvent("fullscreenchange", event);
  };
  dispatchMuteChange = (event) => {
    this.dispatchEvent("mutechange", event);
  };
  dispatchWaiting = (event) => {
    this.dispatchEvent("waiting", event);
  };
  dispatchResume = (event) => {
    this.dispatchEvent("resume", event);
  };
}

class ThumbnailEmitter {
  listeners = {
    error: [],
    waiting: [],
    resume: []
  };
  addEventListener(name, callback) {
    this.listeners[name].push(callback);
  }
  removeEventListener(name, callback) {
    this.listeners[name] = this.listeners[name].filter((l) => l !== callback);
  }
  dispatchEvent(dispatchName, context) {
    this.listeners[dispatchName].forEach((callback) => {
      callback({ detail: context });
    });
  }
  dispatchError = (error) => {
    this.dispatchEvent("error", {
      error
    });
  };
  dispatchWaiting = (event) => {
    this.dispatchEvent("waiting", event);
  };
  dispatchResume = (event) => {
    this.dispatchEvent("resume", event);
  };
}

// src/use-buffer-state-emitter.ts


var useBufferStateEmitter = (emitter) => {
  const bufferManager = (0,react__WEBPACK_IMPORTED_MODULE_2__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.BufferingContextReact);
  if (!bufferManager) {
    throw new Error("BufferingContextReact not found");
  }
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useLayoutEffect)(() => {
    const clear1 = bufferManager.listenForBuffering(() => {
      bufferManager.buffering.current = true;
      emitter.dispatchWaiting({});
    });
    const clear2 = bufferManager.listenForResume(() => {
      bufferManager.buffering.current = false;
      emitter.dispatchResume({});
    });
    return () => {
      clear1.remove();
      clear2.remove();
    };
  }, [bufferManager, emitter]);
};

// src/EmitterProvider.tsx

var PlayerEmitterProvider = ({ children, currentPlaybackRate }) => {
  const [emitter] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(() => new PlayerEmitter);
  const bufferManager = (0,react__WEBPACK_IMPORTED_MODULE_2__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.BufferingContextReact);
  if (!bufferManager) {
    throw new Error("BufferingContextReact not found");
  }
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (currentPlaybackRate) {
      emitter.dispatchRateChange(currentPlaybackRate);
    }
  }, [emitter, currentPlaybackRate]);
  useBufferStateEmitter(emitter);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(PlayerEventEmitterContext.Provider, {
    value: emitter,
    children
  });
};

// src/use-frame-imperative.ts


var useFrameImperative = () => {
  const frame = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.Timeline.useTimelinePosition();
  const frameRef = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(frame);
  frameRef.current = frame;
  const getCurrentFrame = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    return frameRef.current;
  }, []);
  return getCurrentFrame;
};

// src/use-hover-state.ts

var useHoverState = (ref, hideControlsWhenPointerDoesntMove) => {
  const [hovered, setHovered] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(false);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    const { current } = ref;
    if (!current) {
      return;
    }
    let hoverTimeout;
    const addHoverTimeout = () => {
      if (hideControlsWhenPointerDoesntMove) {
        clearTimeout(hoverTimeout);
        hoverTimeout = setTimeout(() => {
          setHovered(false);
        }, hideControlsWhenPointerDoesntMove === true ? 3000 : hideControlsWhenPointerDoesntMove);
      }
    };
    const onHover = () => {
      setHovered(true);
      addHoverTimeout();
    };
    const onLeave = () => {
      setHovered(false);
      clearTimeout(hoverTimeout);
    };
    const onMove = () => {
      setHovered(true);
      addHoverTimeout();
    };
    current.addEventListener("mouseenter", onHover);
    current.addEventListener("mouseleave", onLeave);
    current.addEventListener("mousemove", onMove);
    return () => {
      current.removeEventListener("mouseenter", onHover);
      current.removeEventListener("mouseleave", onLeave);
      current.removeEventListener("mousemove", onMove);
      clearTimeout(hoverTimeout);
    };
  }, [hideControlsWhenPointerDoesntMove, ref]);
  return hovered;
};

// src/use-playback.ts



// src/browser-mediasession.ts


// src/use-player.ts


var usePlayer = () => {
  const [playing, setPlaying, imperativePlaying] = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.Timeline.usePlayingState();
  const [hasPlayed, setHasPlayed] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(false);
  const frame = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.Timeline.useTimelinePosition();
  const playStart = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(frame);
  const setFrame = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.Timeline.useTimelineSetFrame();
  const setTimelinePosition = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.Timeline.useTimelineSetFrame();
  const audioContext = (0,react__WEBPACK_IMPORTED_MODULE_2__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.SharedAudioContext);
  const { audioAndVideoTags } = (0,react__WEBPACK_IMPORTED_MODULE_2__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.TimelineContext);
  const frameRef = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(frame);
  frameRef.current = frame;
  const video = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.useVideo();
  const config = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.useUnsafeVideoConfig();
  const emitter = (0,react__WEBPACK_IMPORTED_MODULE_2__.useContext)(PlayerEventEmitterContext);
  const lastFrame = (config?.durationInFrames ?? 1) - 1;
  const isLastFrame = frame === lastFrame;
  const isFirstFrame = frame === 0;
  if (!emitter) {
    throw new TypeError("Expected Player event emitter context");
  }
  const bufferingContext = (0,react__WEBPACK_IMPORTED_MODULE_2__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.BufferingContextReact);
  if (!bufferingContext) {
    throw new Error("Missing the buffering context. Most likely you have a Remotion version mismatch.");
  }
  const { buffering } = bufferingContext;
  const seek = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((newFrame) => {
    if (video?.id) {
      setTimelinePosition((c) => ({ ...c, [video.id]: newFrame }));
    }
    frameRef.current = newFrame;
    emitter.dispatchSeek(newFrame);
  }, [emitter, setTimelinePosition, video?.id]);
  const play = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((e) => {
    if (imperativePlaying.current) {
      return;
    }
    setHasPlayed(true);
    if (isLastFrame) {
      seek(0);
    }
    audioContext?.audioContext?.resume();
    if (audioContext && audioContext.numberOfAudioTags > 0 && e) {
      audioContext.playAllAudios();
    }
    audioAndVideoTags.current.forEach((a) => a.play("player play() was called and playing audio from a click"));
    imperativePlaying.current = true;
    setPlaying(true);
    playStart.current = frameRef.current;
    emitter.dispatchPlay();
  }, [
    imperativePlaying,
    isLastFrame,
    audioContext,
    setPlaying,
    emitter,
    seek,
    audioAndVideoTags
  ]);
  const pause = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    if (imperativePlaying.current) {
      imperativePlaying.current = false;
      setPlaying(false);
      emitter.dispatchPause();
      audioContext?.audioContext?.suspend();
    }
  }, [emitter, imperativePlaying, setPlaying, audioContext]);
  const pauseAndReturnToPlayStart = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    if (imperativePlaying.current) {
      imperativePlaying.current = false;
      frameRef.current = playStart.current;
      if (config) {
        setTimelinePosition((c) => ({
          ...c,
          [config.id]: playStart.current
        }));
        setPlaying(false);
        emitter.dispatchPause();
      }
    }
  }, [config, emitter, imperativePlaying, setPlaying, setTimelinePosition]);
  const videoId = video?.id;
  const frameBack = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((frames) => {
    if (!videoId) {
      return null;
    }
    if (imperativePlaying.current) {
      return;
    }
    setFrame((c) => {
      const prevFrame = c[videoId] ?? window.remotion_initialFrame ?? 0;
      const newFrame = Math.max(0, prevFrame - frames);
      if (prevFrame === newFrame) {
        return c;
      }
      return {
        ...c,
        [videoId]: newFrame
      };
    });
  }, [imperativePlaying, setFrame, videoId]);
  const frameForward = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((frames) => {
    if (!videoId) {
      return null;
    }
    if (imperativePlaying.current) {
      return;
    }
    setFrame((c) => {
      const prevFrame = c[videoId] ?? window.remotion_initialFrame ?? 0;
      const newFrame = Math.min(lastFrame, prevFrame + frames);
      if (prevFrame === newFrame) {
        return c;
      }
      return {
        ...c,
        [videoId]: newFrame
      };
    });
  }, [videoId, imperativePlaying, lastFrame, setFrame]);
  const toggle = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((e) => {
    if (imperativePlaying.current) {
      pause();
    } else {
      play(e);
    }
  }, [imperativePlaying, pause, play]);
  const isPlaying = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    return imperativePlaying.current;
  }, [imperativePlaying]);
  const getCurrentFrame = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    return frameRef.current;
  }, [frameRef]);
  const isBuffering = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    return buffering.current;
  }, [buffering]);
  const returnValue = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      frameBack,
      frameForward,
      isLastFrame,
      emitter,
      playing,
      play,
      pause,
      seek,
      isFirstFrame,
      getCurrentFrame,
      isPlaying,
      isBuffering,
      pauseAndReturnToPlayStart,
      hasPlayed,
      toggle
    };
  }, [
    emitter,
    frameBack,
    frameForward,
    hasPlayed,
    isFirstFrame,
    isLastFrame,
    getCurrentFrame,
    pause,
    pauseAndReturnToPlayStart,
    play,
    playing,
    seek,
    toggle,
    isPlaying,
    isBuffering
  ]);
  return returnValue;
};

// src/browser-mediasession.ts
var useBrowserMediaSession = ({
  browserMediaControlsBehavior,
  videoConfig,
  playbackRate
}) => {
  const { playing, pause, play, emitter, getCurrentFrame, seek } = usePlayer();
  const hasEverPlayed = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(false);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (playing) {
      hasEverPlayed.current = true;
    }
  }, [playing]);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (!navigator.mediaSession) {
      return;
    }
    if (browserMediaControlsBehavior.mode === "do-nothing") {
      return;
    }
    if (playing) {
      navigator.mediaSession.playbackState = "playing";
    } else if (hasEverPlayed.current) {
      navigator.mediaSession.playbackState = "paused";
    }
  }, [browserMediaControlsBehavior.mode, playing]);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (!navigator.mediaSession) {
      return;
    }
    if (browserMediaControlsBehavior.mode === "do-nothing") {
      return;
    }
    const onTimeUpdate = () => {
      if (!videoConfig) {
        return;
      }
      if (navigator.mediaSession) {
        navigator.mediaSession.setPositionState({
          duration: videoConfig.durationInFrames / videoConfig.fps,
          playbackRate,
          position: getCurrentFrame() / videoConfig.fps
        });
      }
    };
    emitter.addEventListener("timeupdate", onTimeUpdate);
    return () => {
      emitter.removeEventListener("timeupdate", onTimeUpdate);
    };
  }, [
    browserMediaControlsBehavior.mode,
    emitter,
    getCurrentFrame,
    playbackRate,
    videoConfig
  ]);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (!navigator.mediaSession) {
      return;
    }
    if (browserMediaControlsBehavior.mode === "do-nothing") {
      return;
    }
    navigator.mediaSession.setActionHandler("play", () => {
      if (browserMediaControlsBehavior.mode === "register-media-session") {
        play();
      }
    });
    navigator.mediaSession.setActionHandler("pause", () => {
      if (browserMediaControlsBehavior.mode === "register-media-session") {
        pause();
      }
    });
    navigator.mediaSession.setActionHandler("seekto", (event) => {
      if (browserMediaControlsBehavior.mode === "register-media-session" && event.seekTime !== undefined && videoConfig) {
        seek(Math.round(event.seekTime * videoConfig.fps));
      }
    });
    navigator.mediaSession.setActionHandler("seekbackward", () => {
      if (browserMediaControlsBehavior.mode === "register-media-session" && videoConfig) {
        seek(Math.max(0, Math.round((getCurrentFrame() - 10) * videoConfig.fps)));
      }
    });
    navigator.mediaSession.setActionHandler("seekforward", () => {
      if (browserMediaControlsBehavior.mode === "register-media-session" && videoConfig) {
        seek(Math.max(videoConfig.durationInFrames - 1, Math.round((getCurrentFrame() + 10) * videoConfig.fps)));
      }
    });
    navigator.mediaSession.setActionHandler("previoustrack", () => {
      if (browserMediaControlsBehavior.mode === "register-media-session") {
        seek(0);
      }
    });
    return () => {
      navigator.mediaSession.metadata = null;
      navigator.mediaSession.setActionHandler("play", null);
      navigator.mediaSession.setActionHandler("pause", null);
      navigator.mediaSession.setActionHandler("seekto", null);
      navigator.mediaSession.setActionHandler("seekbackward", null);
      navigator.mediaSession.setActionHandler("seekforward", null);
      navigator.mediaSession.setActionHandler("previoustrack", null);
    };
  }, [
    browserMediaControlsBehavior.mode,
    getCurrentFrame,
    pause,
    play,
    seek,
    videoConfig
  ]);
};

// src/calculate-next-frame.ts
var calculateNextFrame = ({
  time,
  currentFrame: startFrame,
  playbackSpeed,
  fps,
  actualLastFrame,
  actualFirstFrame,
  framesAdvanced,
  shouldLoop
}) => {
  const op = playbackSpeed < 0 ? Math.ceil : Math.floor;
  const framesToAdvance = op(time * playbackSpeed / (1000 / fps)) - framesAdvanced;
  const nextFrame = framesToAdvance + startFrame;
  const isCurrentFrameOutside = startFrame > actualLastFrame || startFrame < actualFirstFrame;
  const isNextFrameOutside = nextFrame > actualLastFrame || nextFrame < actualFirstFrame;
  const hasEnded = !shouldLoop && isNextFrameOutside && !isCurrentFrameOutside;
  if (playbackSpeed > 0) {
    if (isNextFrameOutside) {
      return {
        nextFrame: actualFirstFrame,
        framesToAdvance,
        hasEnded
      };
    }
    return { nextFrame, framesToAdvance, hasEnded };
  }
  if (isNextFrameOutside) {
    return { nextFrame: actualLastFrame, framesToAdvance, hasEnded };
  }
  return { nextFrame, framesToAdvance, hasEnded };
};

// src/is-backgrounded.ts

var getIsBackgrounded = () => {
  if (typeof document === "undefined") {
    return false;
  }
  return document.visibilityState === "hidden";
};
var useIsBackgrounded = () => {
  const isBackgrounded = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(getIsBackgrounded());
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    const onVisibilityChange = () => {
      isBackgrounded.current = getIsBackgrounded();
    };
    document.addEventListener("visibilitychange", onVisibilityChange);
    return () => {
      document.removeEventListener("visibilitychange", onVisibilityChange);
    };
  }, []);
  return isBackgrounded;
};

// src/use-playback.ts
var usePlayback = ({
  loop,
  playbackRate,
  moveToBeginningWhenEnded,
  inFrame,
  outFrame,
  browserMediaControlsBehavior,
  getCurrentFrame
}) => {
  const config = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.useUnsafeVideoConfig();
  const frame = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.Timeline.useTimelinePosition();
  const { playing, pause, emitter, isPlaying } = usePlayer();
  const setFrame = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.Timeline.useTimelineSetFrame();
  const isBackgroundedRef = useIsBackgrounded();
  const lastTimeUpdateEvent = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(null);
  const context = (0,react__WEBPACK_IMPORTED_MODULE_2__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.BufferingContextReact);
  if (!context) {
    throw new Error("Missing the buffering context. Most likely you have a Remotion version mismatch.");
  }
  useBrowserMediaSession({
    browserMediaControlsBehavior,
    playbackRate,
    videoConfig: config
  });
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (!config) {
      return;
    }
    if (!playing) {
      return;
    }
    let hasBeenStopped = false;
    let reqAnimFrameCall = null;
    let startedTime = performance.now();
    let framesAdvanced = 0;
    const cancelQueuedFrame = () => {
      if (reqAnimFrameCall !== null) {
        if (reqAnimFrameCall.type === "raf") {
          cancelAnimationFrame(reqAnimFrameCall.id);
        } else {
          clearTimeout(reqAnimFrameCall.id);
        }
      }
    };
    const stop = () => {
      hasBeenStopped = true;
      cancelQueuedFrame();
    };
    const callback = () => {
      if (hasBeenStopped) {
        return;
      }
      if (!isPlaying()) {
        return;
      }
      const time = performance.now() - startedTime;
      const actualLastFrame = outFrame ?? config.durationInFrames - 1;
      const actualFirstFrame = inFrame ?? 0;
      const currentFrame = getCurrentFrame();
      const { nextFrame, framesToAdvance, hasEnded } = calculateNextFrame({
        time,
        currentFrame,
        playbackSpeed: playbackRate,
        fps: config.fps,
        actualFirstFrame,
        actualLastFrame,
        framesAdvanced,
        shouldLoop: loop
      });
      framesAdvanced += framesToAdvance;
      if (nextFrame !== getCurrentFrame() && (!hasEnded || moveToBeginningWhenEnded)) {
        setFrame((c) => ({ ...c, [config.id]: nextFrame }));
      }
      if (hasEnded) {
        stop();
        pause();
        emitter.dispatchEnded();
        return;
      }
      queueNextFrame();
    };
    const queueNextFrame = () => {
      if (context.buffering.current) {
        const stopListening = context.listenForResume(() => {
          stopListening.remove();
          startedTime = performance.now();
          framesAdvanced = 0;
          queueNextFrame();
        });
        return;
      }
      if (isBackgroundedRef.current) {
        reqAnimFrameCall = {
          type: "timeout",
          id: setTimeout(callback, 1000 / config.fps)
        };
        return;
      }
      reqAnimFrameCall = { type: "raf", id: requestAnimationFrame(callback) };
    };
    queueNextFrame();
    const onVisibilityChange = () => {
      if (document.visibilityState === "visible") {
        return;
      }
      cancelQueuedFrame();
      callback();
    };
    window.addEventListener("visibilitychange", onVisibilityChange);
    return () => {
      window.removeEventListener("visibilitychange", onVisibilityChange);
      stop();
    };
  }, [
    config,
    loop,
    pause,
    playing,
    setFrame,
    emitter,
    playbackRate,
    inFrame,
    outFrame,
    moveToBeginningWhenEnded,
    isBackgroundedRef,
    getCurrentFrame,
    context,
    isPlaying
  ]);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    const interval = setInterval(() => {
      if (lastTimeUpdateEvent.current === getCurrentFrame()) {
        return;
      }
      emitter.dispatchTimeUpdate({ frame: getCurrentFrame() });
      lastTimeUpdateEvent.current = getCurrentFrame();
    }, 250);
    return () => clearInterval(interval);
  }, [emitter, getCurrentFrame]);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    emitter.dispatchFrameUpdate({ frame });
  }, [emitter, frame]);
};

// src/utils/use-element-size.ts

var elementSizeHooks = [];
var updateAllElementsSizes = () => {
  for (const listener of elementSizeHooks) {
    listener();
  }
};
var useElementSize = (ref, options) => {
  const [size, setSize] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(() => {
    if (!ref.current) {
      return null;
    }
    const rect = ref.current.getClientRects();
    if (!rect[0]) {
      return null;
    }
    return {
      width: rect[0].width,
      height: rect[0].height,
      left: rect[0].x,
      top: rect[0].y,
      windowSize: {
        height: window.innerHeight,
        width: window.innerWidth
      }
    };
  });
  const observer = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    if (typeof ResizeObserver === "undefined") {
      return null;
    }
    return new ResizeObserver((entries) => {
      const { contentRect, target } = entries[0];
      const newSize = target.getClientRects();
      if (!newSize?.[0]) {
        setSize(null);
        return;
      }
      const probableCssParentScale = contentRect.width === 0 ? 1 : newSize[0].width / contentRect.width;
      const width = options.shouldApplyCssTransforms || probableCssParentScale === 0 ? newSize[0].width : newSize[0].width * (1 / probableCssParentScale);
      const height = options.shouldApplyCssTransforms || probableCssParentScale === 0 ? newSize[0].height : newSize[0].height * (1 / probableCssParentScale);
      setSize((prevState) => {
        const isSame = prevState && prevState.width === width && prevState.height === height && prevState.left === newSize[0].x && prevState.top === newSize[0].y && prevState.windowSize.height === window.innerHeight && prevState.windowSize.width === window.innerWidth;
        if (isSame) {
          return prevState;
        }
        return {
          width,
          height,
          left: newSize[0].x,
          top: newSize[0].y,
          windowSize: {
            height: window.innerHeight,
            width: window.innerWidth
          }
        };
      });
    });
  }, [options.shouldApplyCssTransforms]);
  const updateSize = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    if (!ref.current) {
      return;
    }
    const rect = ref.current.getClientRects();
    if (!rect[0]) {
      setSize(null);
      return;
    }
    setSize((prevState) => {
      const isSame = prevState && prevState.width === rect[0].width && prevState.height === rect[0].height && prevState.left === rect[0].x && prevState.top === rect[0].y && prevState.windowSize.height === window.innerHeight && prevState.windowSize.width === window.innerWidth;
      if (isSame) {
        return prevState;
      }
      return {
        width: rect[0].width,
        height: rect[0].height,
        left: rect[0].x,
        top: rect[0].y,
        windowSize: {
          height: window.innerHeight,
          width: window.innerWidth
        }
      };
    });
  }, [ref]);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (!observer) {
      return;
    }
    const { current } = ref;
    if (current) {
      observer.observe(current);
    }
    return () => {
      if (current) {
        observer.unobserve(current);
      }
    };
  }, [observer, ref, updateSize]);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (!options.triggerOnWindowResize) {
      return;
    }
    window.addEventListener("resize", updateSize);
    return () => {
      window.removeEventListener("resize", updateSize);
    };
  }, [options.triggerOnWindowResize, updateSize]);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    elementSizeHooks.push(updateSize);
    return () => {
      elementSizeHooks = elementSizeHooks.filter((e) => e !== updateSize);
    };
  }, [updateSize]);
  return (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    if (!size) {
      return null;
    }
    return { ...size, refresh: updateSize };
  }, [size, updateSize]);
};

// src/Player.tsx



// src/player-css-classname.ts
var playerCssClassname = (override) => {
  return override ?? "__remotion-player";
};

// src/PlayerUI.tsx



// src/error-boundary.tsx


var errorStyle = {
  display: "flex",
  justifyContent: "center",
  alignItems: "center",
  flex: 1,
  height: "100%",
  width: "100%"
};

class ErrorBoundary extends react__WEBPACK_IMPORTED_MODULE_2__.Component {
  state = { hasError: null };
  static getDerivedStateFromError(error) {
    return { hasError: error };
  }
  componentDidCatch(error) {
    this.props.onError(error);
  }
  render() {
    if (this.state.hasError) {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
        style: errorStyle,
        children: this.props.errorFallback({
          error: this.state.hasError
        })
      });
    }
    return this.props.children;
  }
}

// src/license-blacklist.tsx


var getHashOfDomain = async () => {
  if (typeof window === "undefined") {
    return null;
  }
  if (typeof window.crypto === "undefined") {
    return null;
  }
  if (typeof window.crypto.subtle === "undefined") {
    return null;
  }
  try {
    const hashBuffer = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(window.location.hostname));
    return Array.from(new Uint8Array(hashBuffer)).map((b) => b.toString(16).padStart(2, "0")).join("");
  } catch {
    return null;
  }
};
var style = {
  backgroundColor: "red",
  position: "absolute",
  padding: 12,
  fontFamily: "Arial"
};
var DOMAIN_BLACKLIST = [
  "28d262b44cc61fa750f1686b16ad0604dabfe193fbc263eec05c89b7ad4c2cd6",
  "4db1b0a94be33165dfefcb3ba03d04c7a2666dd27c496d3dc9fa41858e94925e",
  "fbc48530bbf245da790f63675e84e06bab38c3b114fab07eb350025119922bdc",
  "7baf10a8932757b1b3a22b3fce10a048747ac2f8eaf638603487e3705b07eb83",
  "8a6c21a598d8c667272b5207c051b85997bf5b45d5fb712378be3f27cd72c6a6",
  "a2f7aaac9c50a9255e7fc376110c4e0bfe153722dc66ed3c5d3bf2a135f65518"
];
var ran = false;
var RenderWarningIfBlacklist = () => {
  const [unlicensed, setUnlicensed] = react__WEBPACK_IMPORTED_MODULE_2__.useState(false);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (ran) {
      return;
    }
    ran = true;
    getHashOfDomain().then((hash) => {
      if (hash && DOMAIN_BLACKLIST.includes(hash)) {
        setUnlicensed(true);
      }
    }).catch(() => {});
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (!unlicensed) {
      return;
    }
    const ensureBanner = () => {
      const banner = document.querySelector(".warning-banner");
      if (!banner) {
        const div = document.createElement("div");
        div.className = "warning-banner";
        Object.assign(div.style, style, {
          zIndex: "9999",
          cssText: `${style.cssText} !important;`
        });
        div.innerHTML = `
	        <a href="https://github.com/remotion-dev/remotion/pull/4589" style="color: white;">
	          Remotion Unlicensed – Contact hi@remotion.dev
	        </a>
	      `;
        document.body.appendChild(div);
      }
    };
    const observer = new MutationObserver(() => ensureBanner());
    observer.observe(document.body, { childList: true, subtree: true });
    return () => {
      observer.disconnect();
    };
  }, [unlicensed]);
  if (!unlicensed) {
    return null;
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
    style,
    className: "warning-banner",
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("a", {
      style: { color: "white" },
      href: "https://github.com/remotion-dev/remotion/pull/4589",
      children: "Remotion Unlicensed – Contact hi@remotion.dev"
    })
  });
};

// src/PlayerControls.tsx


// src/DefaultPlayPauseButton.tsx

var DefaultPlayPauseButton = ({ playing, buffering }) => {
  if (playing && buffering) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(BufferingIndicator, {
      type: "player"
    });
  }
  if (playing) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(PauseIcon, {});
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(PlayIcon, {});
};

// src/MediaVolumeSlider.tsx



// src/render-volume-slider.tsx



var KNOB_SIZE = 12;
var BAR_HEIGHT = 5;
var DefaultVolumeSlider = ({
  volume,
  isVertical,
  onBlur,
  inputRef,
  setVolume
}) => {
  const sliderContainer = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    const paddingLeft = 5;
    const common = {
      paddingLeft,
      height: ICON_SIZE,
      width: VOLUME_SLIDER_WIDTH,
      display: "inline-flex",
      alignItems: "center"
    };
    if (isVertical) {
      return {
        ...common,
        position: "absolute",
        transform: `rotate(-90deg) translateX(${VOLUME_SLIDER_WIDTH / 2 + ICON_SIZE / 2}px)`
      };
    }
    return {
      ...common
    };
  }, [isVertical]);
  const randomId = typeof react__WEBPACK_IMPORTED_MODULE_2__.useId === "undefined" ? "volume-slider" : react__WEBPACK_IMPORTED_MODULE_2__.useId();
  const [randomClass] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(() => `__remotion-volume-slider-${(0,remotion__WEBPACK_IMPORTED_MODULE_1__.random)(randomId)}`.replace(".", ""));
  const onVolumeChange = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((e) => {
    setVolume(parseFloat(e.target.value));
  }, [setVolume]);
  const inputStyle = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    const commonStyle = {
      WebkitAppearance: "none",
      backgroundColor: "rgba(255, 255, 255, 0.5)",
      borderRadius: BAR_HEIGHT / 2,
      cursor: "pointer",
      height: BAR_HEIGHT,
      width: VOLUME_SLIDER_WIDTH,
      backgroundImage: `linear-gradient(
				to right,
				white ${volume * 100}%, rgba(255, 255, 255, 0) ${volume * 100}%
			)`
    };
    if (isVertical) {
      return {
        ...commonStyle,
        bottom: ICON_SIZE + VOLUME_SLIDER_WIDTH / 2
      };
    }
    return commonStyle;
  }, [isVertical, volume]);
  const sliderStyle = `
	.${randomClass}::-webkit-slider-thumb {
		-webkit-appearance: none;
		background-color: white;
		border-radius: ${KNOB_SIZE / 2}px;
		box-shadow: 0 0 2px black;
		height: ${KNOB_SIZE}px;
		width: ${KNOB_SIZE}px;
	}

	.${randomClass}::-moz-range-thumb {
		-webkit-appearance: none;
		background-color: white;
		border-radius: ${KNOB_SIZE / 2}px;
		box-shadow: 0 0 2px black;
		height: ${KNOB_SIZE}px;
		width: ${KNOB_SIZE}px;
	}
`;
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
    style: sliderContainer,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("style", {
        dangerouslySetInnerHTML: {
          __html: sliderStyle
        }
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("input", {
        ref: inputRef,
        "aria-label": "Change volume",
        className: randomClass,
        max: 1,
        min: 0,
        onBlur,
        onChange: onVolumeChange,
        step: 0.01,
        type: "range",
        value: volume,
        style: inputStyle
      })
    ]
  });
};
var renderDefaultVolumeSlider = (props) => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(DefaultVolumeSlider, {
    ...props
  });
};

// src/MediaVolumeSlider.tsx

var VOLUME_SLIDER_WIDTH = 100;
var MediaVolumeSlider = ({ displayVerticalVolumeSlider, renderMuteButton, renderVolumeSlider }) => {
  const [mediaMuted, setMediaMuted] = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.useMediaMutedState();
  const [mediaVolume, setMediaVolume] = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.useMediaVolumeState();
  const [focused, setFocused] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(false);
  const parentDivRef = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(null);
  const inputRef = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(null);
  const hover = useHoverState(parentDivRef, false);
  const onBlur = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    setTimeout(() => {
      if (inputRef.current && document.activeElement !== inputRef.current) {
        setFocused(false);
      }
    }, 10);
  }, []);
  const isVolume0 = mediaVolume === 0;
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    if (isVolume0) {
      setMediaVolume(1);
      setMediaMuted(false);
      return;
    }
    setMediaMuted((mute) => !mute);
  }, [isVolume0, setMediaMuted, setMediaVolume]);
  const parentDivStyle = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      display: "inline-flex",
      background: "none",
      border: "none",
      justifyContent: "center",
      alignItems: "center",
      touchAction: "none",
      ...displayVerticalVolumeSlider && { position: "relative" }
    };
  }, [displayVerticalVolumeSlider]);
  const volumeContainer = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      display: "inline",
      width: ICON_SIZE,
      height: ICON_SIZE,
      cursor: "pointer",
      appearance: "none",
      background: "none",
      border: "none",
      padding: 0
    };
  }, []);
  const renderDefaultMuteButton = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(({ muted, volume }) => {
    const isMutedOrZero = muted || volume === 0;
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("button", {
      "aria-label": isMutedOrZero ? "Unmute sound" : "Mute sound",
      title: isMutedOrZero ? "Unmute sound" : "Mute sound",
      onClick,
      onBlur,
      onFocus: () => setFocused(true),
      style: volumeContainer,
      type: "button",
      children: isMutedOrZero ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(VolumeOffIcon, {}) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(VolumeOnIcon, {})
    });
  }, [onBlur, onClick, volumeContainer]);
  const muteButton = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return renderMuteButton ? renderMuteButton({ muted: mediaMuted, volume: mediaVolume }) : renderDefaultMuteButton({ muted: mediaMuted, volume: mediaVolume });
  }, [mediaMuted, mediaVolume, renderDefaultMuteButton, renderMuteButton]);
  const volumeSlider = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return (focused || hover) && !mediaMuted && !remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.isIosSafari() ? (renderVolumeSlider ?? renderDefaultVolumeSlider)({
      isVertical: displayVerticalVolumeSlider,
      volume: mediaVolume,
      onBlur: () => setFocused(false),
      inputRef,
      setVolume: setMediaVolume
    }) : null;
  }, [
    displayVerticalVolumeSlider,
    focused,
    hover,
    mediaMuted,
    mediaVolume,
    renderVolumeSlider,
    setMediaVolume
  ]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
    ref: parentDivRef,
    style: parentDivStyle,
    children: [
      muteButton,
      volumeSlider
    ]
  });
};

// src/PlaybackrateControl.tsx



// src/utils/use-component-visible.ts

function useComponentVisible(initialIsVisible) {
  const [isComponentVisible, setIsComponentVisible] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(initialIsVisible);
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(null);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    const handleClickOutside = (event) => {
      if (ref.current && !ref.current.contains(event.target)) {
        setIsComponentVisible(false);
      }
    };
    document.addEventListener("pointerup", handleClickOutside, true);
    return () => {
      document.removeEventListener("pointerup", handleClickOutside, true);
    };
  }, []);
  return { ref, isComponentVisible, setIsComponentVisible };
}

// src/PlaybackrateControl.tsx

var BOTTOM = 35;
var THRESHOLD = 70;
var rateDiv = {
  height: 30,
  paddingRight: 15,
  paddingLeft: 12,
  display: "flex",
  flexDirection: "row",
  alignItems: "center"
};
var checkmarkContainer = {
  width: 22,
  display: "flex",
  alignItems: "center"
};
var checkmarkStyle = {
  width: 14,
  height: 14,
  color: "black"
};
var Checkmark = () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("svg", {
  viewBox: "0 0 512 512",
  style: checkmarkStyle,
  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("path", {
    fill: "currentColor",
    d: "M435.848 83.466L172.804 346.51l-96.652-96.652c-4.686-4.686-12.284-4.686-16.971 0l-28.284 28.284c-4.686 4.686-4.686 12.284 0 16.971l133.421 133.421c4.686 4.686 12.284 4.686 16.971 0l299.813-299.813c4.686-4.686 4.686-12.284 0-16.971l-28.284-28.284c-4.686-4.686-12.284-4.686-16.97 0z"
  })
});
var formatPlaybackRate = (rate) => {
  const str = rate.toString();
  return str.includes(".") ? str : str + ".0";
};
var PlaybackrateOption = ({ rate, onSelect, selectedRate, keyboardSelectedRate }) => {
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((e) => {
    e.stopPropagation();
    e.preventDefault();
    onSelect(rate);
  }, [onSelect, rate]);
  const [hovered, setHovered] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(false);
  const onMouseEnter = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    setHovered(true);
  }, []);
  const onMouseLeave = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    setHovered(false);
  }, []);
  const isFocused = keyboardSelectedRate === rate;
  const actualStyle = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      ...rateDiv,
      backgroundColor: hovered || isFocused ? "#eee" : "transparent"
    };
  }, [hovered, isFocused]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
    onPointerEnter: onMouseEnter,
    onPointerLeave: onMouseLeave,
    tabIndex: 0,
    style: actualStyle,
    onClick,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
        style: checkmarkContainer,
        children: rate === selectedRate ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(Checkmark, {}) : null
      }),
      formatPlaybackRate(rate),
      "x"
    ]
  }, rate);
};
var PlaybackPopup = ({ setIsComponentVisible, playbackRates, canvasSize }) => {
  const { setPlaybackRate, playbackRate } = (0,react__WEBPACK_IMPORTED_MODULE_2__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.TimelineContext);
  const [keyboardSelectedRate, setKeyboardSelectedRate] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(playbackRate);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    const listener = (e) => {
      e.preventDefault();
      if (e.key === "ArrowUp") {
        const currentIndex = playbackRates.findIndex((rate) => rate === keyboardSelectedRate);
        if (currentIndex === 0) {
          return;
        }
        if (currentIndex === -1) {
          setKeyboardSelectedRate(playbackRates[0]);
        } else {
          setKeyboardSelectedRate(playbackRates[currentIndex - 1]);
        }
      } else if (e.key === "ArrowDown") {
        const currentIndex = playbackRates.findIndex((rate) => rate === keyboardSelectedRate);
        if (currentIndex === playbackRates.length - 1) {
          return;
        }
        if (currentIndex === -1) {
          setKeyboardSelectedRate(playbackRates[playbackRates.length - 1]);
        } else {
          setKeyboardSelectedRate(playbackRates[currentIndex + 1]);
        }
      } else if (e.key === "Enter") {
        setPlaybackRate(keyboardSelectedRate);
        setIsComponentVisible(false);
      }
    };
    window.addEventListener("keydown", listener);
    return () => {
      window.removeEventListener("keydown", listener);
    };
  }, [
    playbackRates,
    keyboardSelectedRate,
    setPlaybackRate,
    setIsComponentVisible
  ]);
  const onSelect = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((rate) => {
    setPlaybackRate(rate);
    setIsComponentVisible(false);
  }, [setIsComponentVisible, setPlaybackRate]);
  const playbackPopup = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      position: "absolute",
      right: 0,
      width: 125,
      maxHeight: canvasSize.height - THRESHOLD - BOTTOM,
      bottom: 35,
      background: "#fff",
      borderRadius: 4,
      overflow: "auto",
      color: "black",
      textAlign: "left"
    };
  }, [canvasSize.height]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
    style: playbackPopup,
    children: playbackRates.map((rate) => {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(PlaybackrateOption, {
        selectedRate: playbackRate,
        onSelect,
        rate,
        keyboardSelectedRate
      }, rate);
    })
  });
};
var label = {
  fontSize: 13,
  fontWeight: "bold",
  color: "white",
  border: "2px solid white",
  borderRadius: 20,
  paddingLeft: 8,
  paddingRight: 8,
  paddingTop: 2,
  paddingBottom: 2
};
var playerButtonStyle = {
  appearance: "none",
  backgroundColor: "transparent",
  border: "none",
  cursor: "pointer",
  paddingLeft: 0,
  paddingRight: 0,
  paddingTop: 6,
  paddingBottom: 6,
  height: 37,
  display: "inline-flex",
  marginBottom: 0,
  marginTop: 0,
  alignItems: "center"
};
var button = {
  ...playerButtonStyle,
  position: "relative"
};
var PlaybackrateControl = ({ playbackRates, canvasSize }) => {
  const { ref, isComponentVisible, setIsComponentVisible } = useComponentVisible(false);
  const { playbackRate } = (0,react__WEBPACK_IMPORTED_MODULE_2__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.TimelineContext);
  const onClick = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((e) => {
    e.stopPropagation();
    e.preventDefault();
    setIsComponentVisible((prevIsComponentVisible) => !prevIsComponentVisible);
  }, [setIsComponentVisible]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
    ref,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("button", {
      type: "button",
      "aria-label": "Change playback rate",
      style: button,
      onClick,
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
          style: label,
          children: [
            playbackRate,
            "x"
          ]
        }),
        isComponentVisible && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(PlaybackPopup, {
          canvasSize,
          playbackRates,
          setIsComponentVisible
        })
      ]
    })
  });
};

// src/PlayerSeekBar.tsx



var getFrameFromX = (clientX, durationInFrames, width) => {
  const pos = clientX;
  const frame = Math.round((0,remotion__WEBPACK_IMPORTED_MODULE_1__.interpolate)(pos, [0, width], [0, durationInFrames - 1], {
    extrapolateLeft: "clamp",
    extrapolateRight: "clamp"
  }));
  return frame;
};
var BAR_HEIGHT2 = 5;
var KNOB_SIZE2 = 12;
var VERTICAL_PADDING = 4;
var containerStyle = {
  userSelect: "none",
  WebkitUserSelect: "none",
  paddingTop: VERTICAL_PADDING,
  paddingBottom: VERTICAL_PADDING,
  boxSizing: "border-box",
  cursor: "pointer",
  position: "relative",
  touchAction: "none"
};
var barBackground = {
  height: BAR_HEIGHT2,
  backgroundColor: "rgba(255, 255, 255, 0.25)",
  width: "100%",
  borderRadius: BAR_HEIGHT2 / 2
};
var findBodyInWhichDivIsLocated = (div) => {
  let current = div;
  while (current.parentElement) {
    current = current.parentElement;
  }
  return current;
};
var PlayerSeekBar = ({ durationInFrames, onSeekEnd, onSeekStart, inFrame, outFrame }) => {
  const containerRef = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(null);
  const barHovered = useHoverState(containerRef, false);
  const size = useElementSize(containerRef, {
    triggerOnWindowResize: true,
    shouldApplyCssTransforms: true
  });
  const { seek, play, pause, playing } = usePlayer();
  const frame = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.Timeline.useTimelinePosition();
  const [dragging, setDragging] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)({
    dragging: false
  });
  const width = size?.width ?? 0;
  const onPointerDown = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((e) => {
    if (e.button !== 0) {
      return;
    }
    const posLeft = containerRef.current?.getBoundingClientRect().left;
    const _frame = getFrameFromX(e.clientX - posLeft, durationInFrames, width);
    pause();
    seek(_frame);
    setDragging({
      dragging: true,
      wasPlaying: playing
    });
    onSeekStart();
  }, [durationInFrames, width, pause, seek, playing, onSeekStart]);
  const onPointerMove = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((e) => {
    if (!size) {
      throw new Error("Player has no size");
    }
    if (!dragging.dragging) {
      return;
    }
    const posLeft = containerRef.current?.getBoundingClientRect().left;
    const _frame = getFrameFromX(e.clientX - posLeft, durationInFrames, size.width);
    seek(_frame);
  }, [dragging.dragging, durationInFrames, seek, size]);
  const onPointerUp = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    setDragging({
      dragging: false
    });
    if (!dragging.dragging) {
      return;
    }
    if (dragging.wasPlaying) {
      play();
    } else {
      pause();
    }
    onSeekEnd();
  }, [dragging, onSeekEnd, pause, play]);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (!dragging.dragging) {
      return;
    }
    const body = findBodyInWhichDivIsLocated(containerRef.current);
    body.addEventListener("pointermove", onPointerMove);
    body.addEventListener("pointerup", onPointerUp);
    return () => {
      body.removeEventListener("pointermove", onPointerMove);
      body.removeEventListener("pointerup", onPointerUp);
    };
  }, [dragging.dragging, onPointerMove, onPointerUp]);
  const knobStyle = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      height: KNOB_SIZE2,
      width: KNOB_SIZE2,
      borderRadius: KNOB_SIZE2 / 2,
      position: "absolute",
      top: VERTICAL_PADDING - KNOB_SIZE2 / 2 + 5 / 2,
      backgroundColor: "white",
      left: Math.max(0, frame / Math.max(1, durationInFrames - 1) * width - KNOB_SIZE2 / 2),
      boxShadow: "0 0 2px black",
      opacity: Number(barHovered || dragging.dragging)
    };
  }, [barHovered, dragging.dragging, durationInFrames, frame, width]);
  const fillStyle = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      height: BAR_HEIGHT2,
      backgroundColor: "rgba(255, 255, 255, 1)",
      width: (frame - (inFrame ?? 0)) / (durationInFrames - 1) * width,
      marginLeft: (inFrame ?? 0) / (durationInFrames - 1) * width,
      borderRadius: BAR_HEIGHT2 / 2
    };
  }, [durationInFrames, frame, inFrame, width]);
  const active = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      height: BAR_HEIGHT2,
      backgroundColor: "rgba(255, 255, 255, 0.25)",
      width: ((outFrame ?? durationInFrames - 1) - (inFrame ?? 0)) / (durationInFrames - 1) * 100 + "%",
      marginLeft: (inFrame ?? 0) / (durationInFrames - 1) * 100 + "%",
      borderRadius: BAR_HEIGHT2 / 2,
      position: "absolute"
    };
  }, [durationInFrames, inFrame, outFrame]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
    ref: containerRef,
    onPointerDown,
    style: containerStyle,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
        style: barBackground,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
            style: active
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
            style: fillStyle
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
        style: knobStyle
      })
    ]
  });
};

// src/PlayerTimeLabel.tsx



// src/format-time.ts
var formatTime = (timeInSeconds) => {
  const minutes = Math.floor(timeInSeconds / 60);
  const seconds = Math.floor(timeInSeconds - minutes * 60);
  return `${String(minutes)}:${String(seconds).padStart(2, "0")}`;
};

// src/PlayerTimeLabel.tsx

var PlayerTimeLabel = ({ durationInFrames, maxTimeLabelWidth, fps }) => {
  const frame = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.Timeline.useTimelinePosition();
  const timeLabel = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      color: "white",
      fontFamily: "sans-serif",
      fontSize: 14,
      maxWidth: maxTimeLabelWidth === null ? undefined : maxTimeLabelWidth,
      overflow: "hidden",
      textOverflow: "ellipsis"
    };
  }, [maxTimeLabelWidth]);
  const isLastFrame = frame === durationInFrames - 1;
  const frameToDisplay = isLastFrame ? frame + 1 : frame;
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
    style: timeLabel,
    children: [
      formatTime(frameToDisplay / fps),
      " / ",
      formatTime(durationInFrames / fps)
    ]
  });
};

// src/use-video-controls-resize.ts

var X_SPACER = 10;
var X_PADDING = 12;
var useVideoControlsResize = ({
  allowFullscreen: allowFullScreen,
  playerWidth
}) => {
  const resizeInfo = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    const playPauseIconSize = ICON_SIZE;
    const volumeIconSize = ICON_SIZE;
    const _fullscreenIconSize = allowFullScreen ? fullscreenIconSize : 0;
    const elementsSize = volumeIconSize + playPauseIconSize + _fullscreenIconSize + X_PADDING * 2 + X_SPACER * 2;
    const maxTimeLabelWidth = playerWidth - elementsSize;
    const maxTimeLabelWidthWithoutNegativeValue = Math.max(maxTimeLabelWidth, 0);
    const availableTimeLabelWidthIfVolumeOpen = maxTimeLabelWidthWithoutNegativeValue - VOLUME_SLIDER_WIDTH;
    const computedLabelWidth = availableTimeLabelWidthIfVolumeOpen < VOLUME_SLIDER_WIDTH ? maxTimeLabelWidthWithoutNegativeValue : availableTimeLabelWidthIfVolumeOpen;
    const minWidthForHorizontalDisplay = computedLabelWidth + elementsSize + VOLUME_SLIDER_WIDTH;
    const displayVerticalVolumeSlider = playerWidth < minWidthForHorizontalDisplay;
    return {
      maxTimeLabelWidth: maxTimeLabelWidthWithoutNegativeValue === 0 ? null : maxTimeLabelWidthWithoutNegativeValue,
      displayVerticalVolumeSlider
    };
  }, [allowFullScreen, playerWidth]);
  return resizeInfo;
};

// src/PlayerControls.tsx

var gradientSteps = [
  0,
  0.013,
  0.049,
  0.104,
  0.175,
  0.259,
  0.352,
  0.45,
  0.55,
  0.648,
  0.741,
  0.825,
  0.896,
  0.951,
  0.987
];
var gradientOpacities = [
  0,
  8.1,
  15.5,
  22.5,
  29,
  35.3,
  41.2,
  47.1,
  52.9,
  58.8,
  64.7,
  71,
  77.5,
  84.5,
  91.9
];
var globalGradientOpacity = 1 / 0.7;
var containerStyle2 = {
  boxSizing: "border-box",
  position: "absolute",
  bottom: 0,
  width: "100%",
  paddingTop: 40,
  paddingBottom: 10,
  backgroundImage: `linear-gradient(to bottom,${gradientSteps.map((g, i) => {
    return `hsla(0, 0%, 0%, ${g}) ${gradientOpacities[i] * globalGradientOpacity}%`;
  }).join(", ")}, hsl(0, 0%, 0%) 100%)`,
  backgroundSize: "auto 145px",
  display: "flex",
  paddingRight: X_PADDING,
  paddingLeft: X_PADDING,
  flexDirection: "column",
  transition: "opacity 0.3s"
};
var controlsRow = {
  display: "flex",
  flexDirection: "row",
  width: "100%",
  alignItems: "center",
  justifyContent: "center",
  userSelect: "none",
  WebkitUserSelect: "none"
};
var leftPartStyle = {
  display: "flex",
  flexDirection: "row",
  userSelect: "none",
  WebkitUserSelect: "none",
  alignItems: "center"
};
var xSpacer = {
  width: 12
};
var ySpacer = {
  height: 8
};
var flex1 = {
  flex: 1
};
var fullscreen = {};
var Controls = ({
  durationInFrames,
  isFullscreen,
  fps,
  showVolumeControls,
  onFullscreenButtonClick,
  allowFullscreen,
  onExitFullscreenButtonClick,
  spaceKeyToPlayOrPause,
  onSeekEnd,
  onSeekStart,
  inFrame,
  outFrame,
  initiallyShowControls,
  canvasSize,
  renderPlayPauseButton,
  renderFullscreenButton,
  alwaysShowControls,
  showPlaybackRateControl,
  containerRef,
  buffering,
  hideControlsWhenPointerDoesntMove,
  onPointerDown,
  onDoubleClick,
  renderMuteButton,
  renderVolumeSlider,
  playing,
  toggle,
  renderCustomControls
}) => {
  const playButtonRef = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(null);
  const [supportsFullscreen, setSupportsFullscreen] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(false);
  const hovered = useHoverState(containerRef, hideControlsWhenPointerDoesntMove);
  const { maxTimeLabelWidth, displayVerticalVolumeSlider } = useVideoControlsResize({
    allowFullscreen,
    playerWidth: canvasSize?.width ?? 0
  });
  const [shouldShowInitially, setInitiallyShowControls] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(() => {
    if (typeof initiallyShowControls === "boolean") {
      return initiallyShowControls;
    }
    if (typeof initiallyShowControls === "number") {
      if (initiallyShowControls % 1 !== 0) {
        throw new Error("initiallyShowControls must be an integer or a boolean");
      }
      if (Number.isNaN(initiallyShowControls)) {
        throw new Error("initiallyShowControls must not be NaN");
      }
      if (!Number.isFinite(initiallyShowControls)) {
        throw new Error("initiallyShowControls must be finite");
      }
      if (initiallyShowControls <= 0) {
        throw new Error("initiallyShowControls must be a positive integer");
      }
      return initiallyShowControls;
    }
    throw new TypeError("initiallyShowControls must be a number or a boolean");
  });
  const containerCss = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    const shouldShow = hovered || !playing || shouldShowInitially || alwaysShowControls;
    return {
      ...containerStyle2,
      opacity: Number(shouldShow)
    };
  }, [hovered, shouldShowInitially, playing, alwaysShowControls]);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (playButtonRef.current && spaceKeyToPlayOrPause) {
      playButtonRef.current.focus({
        preventScroll: true
      });
    }
  }, [playing, spaceKeyToPlayOrPause]);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    setSupportsFullscreen((typeof document !== "undefined" && (document.fullscreenEnabled || document.webkitFullscreenEnabled)) ?? false);
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (shouldShowInitially === false) {
      return;
    }
    const time = shouldShowInitially === true ? 2000 : shouldShowInitially;
    const timeout = setTimeout(() => {
      setInitiallyShowControls(false);
    }, time);
    return () => {
      clearInterval(timeout);
    };
  }, [shouldShowInitially]);
  const playbackRates = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    if (showPlaybackRateControl === true) {
      return [0.5, 0.8, 1, 1.2, 1.5, 1.8, 2, 2.5, 3];
    }
    if (Array.isArray(showPlaybackRateControl)) {
      for (const rate of showPlaybackRateControl) {
        if (typeof rate !== "number") {
          throw new Error("Every item in showPlaybackRateControl must be a number");
        }
        if (rate <= 0) {
          throw new Error("Every item in showPlaybackRateControl must be positive");
        }
      }
      return showPlaybackRateControl;
    }
    return null;
  }, [showPlaybackRateControl]);
  const customControlsElement = renderCustomControls ? renderCustomControls() : null;
  const ref = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(null);
  const flexRef = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(null);
  const onPointerDownIfContainer = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((e) => {
    if (e.target === ref.current || e.target === flexRef.current) {
      onPointerDown?.(e);
    }
  }, [onPointerDown]);
  const onDoubleClickIfContainer = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((e) => {
    if (e.target === ref.current || e.target === flexRef.current) {
      onDoubleClick?.(e);
    }
  }, [onDoubleClick]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
    ref,
    style: containerCss,
    onPointerDown: onPointerDownIfContainer,
    onDoubleClick: onDoubleClickIfContainer,
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
        ref: flexRef,
        style: controlsRow,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
            style: leftPartStyle,
            children: [
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("button", {
                ref: playButtonRef,
                type: "button",
                style: playerButtonStyle,
                onClick: toggle,
                "aria-label": playing ? "Pause video" : "Play video",
                title: playing ? "Pause video" : "Play video",
                children: renderPlayPauseButton === null ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(DefaultPlayPauseButton, {
                  buffering,
                  playing
                }) : renderPlayPauseButton({
                  playing,
                  isBuffering: buffering
                }) ?? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(DefaultPlayPauseButton, {
                  buffering,
                  playing
                })
              }),
              showVolumeControls ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
                children: [
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
                    style: xSpacer
                  }),
                  /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(MediaVolumeSlider, {
                    renderMuteButton,
                    renderVolumeSlider,
                    displayVerticalVolumeSlider
                  })
                ]
              }) : null,
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
                style: xSpacer
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(PlayerTimeLabel, {
                durationInFrames,
                fps,
                maxTimeLabelWidth
              }),
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
                style: xSpacer
              })
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
            style: flex1
          }),
          customControlsElement,
          customControlsElement && playbackRates && canvasSize ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
            style: xSpacer
          }) : null,
          playbackRates && canvasSize && /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(PlaybackrateControl, {
            canvasSize,
            playbackRates
          }),
          playbackRates && supportsFullscreen && allowFullscreen ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
            style: xSpacer
          }) : null,
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
            style: fullscreen,
            children: supportsFullscreen && allowFullscreen ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("button", {
              type: "button",
              "aria-label": isFullscreen ? "Exit fullscreen" : "Enter Fullscreen",
              title: isFullscreen ? "Exit fullscreen" : "Enter Fullscreen",
              style: playerButtonStyle,
              onClick: isFullscreen ? onExitFullscreenButtonClick : onFullscreenButtonClick,
              children: renderFullscreenButton === null ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(FullscreenIcon, {
                isFullscreen
              }) : renderFullscreenButton({ isFullscreen })
            }) : null
          })
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
        style: ySpacer
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(PlayerSeekBar, {
        onSeekEnd,
        onSeekStart,
        durationInFrames,
        inFrame,
        outFrame
      })
    ]
  });
};

// src/utils/is-node.ts
var IS_NODE = typeof document === "undefined";

// src/utils/use-click-prevention-on-double-click.ts


// src/utils/cancellable-promise.ts
var cancellablePromise = (promise) => {
  let isCanceled = false;
  const wrappedPromise = new Promise((resolve, reject) => {
    promise.then((value) => {
      if (isCanceled) {
        reject({ isCanceled, value });
        return;
      }
      resolve(value);
    }).catch((error) => {
      reject({ isCanceled, error });
    });
  });
  return {
    promise: wrappedPromise,
    cancel: () => {
      isCanceled = true;
    }
  };
};

// src/utils/delay.ts
var delay = (n) => new Promise((resolve) => setTimeout(resolve, n));

// src/utils/use-cancellable-promises.ts

var useCancellablePromises = () => {
  const pendingPromises = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)([]);
  const appendPendingPromise = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((promise) => {
    pendingPromises.current = [...pendingPromises.current, promise];
  }, []);
  const removePendingPromise = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((promise) => {
    pendingPromises.current = pendingPromises.current.filter((p) => p !== promise);
  }, []);
  const clearPendingPromises = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => pendingPromises.current.map((p) => p.cancel()), []);
  const api = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => ({
    appendPendingPromise,
    removePendingPromise,
    clearPendingPromises
  }), [appendPendingPromise, clearPendingPromises, removePendingPromise]);
  return api;
};

// src/utils/use-click-prevention-on-double-click.ts
var useClickPreventionOnDoubleClick = (onClick, onDoubleClick, doubleClickToFullscreen) => {
  const api = useCancellablePromises();
  const handleClick = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(async (e) => {
    if (e instanceof PointerEvent ? e.pointerType === "touch" : e.nativeEvent.pointerType === "touch") {
      onClick(e);
      return;
    }
    api.clearPendingPromises();
    const waitForClick = cancellablePromise(delay(200));
    api.appendPendingPromise(waitForClick);
    try {
      await waitForClick.promise;
      api.removePendingPromise(waitForClick);
      onClick(e);
    } catch (errorInfo) {
      const info = errorInfo;
      api.removePendingPromise(waitForClick);
      if (!info.isCanceled) {
        throw info.error;
      }
    }
  }, [api, onClick]);
  const handlePointerDown = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    document.addEventListener("pointerup", (newEvt) => {
      handleClick(newEvt);
    }, {
      once: true
    });
  }, [handleClick]);
  const handleDoubleClick = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    api.clearPendingPromises();
    onDoubleClick();
  }, [api, onDoubleClick]);
  const returnValue = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    if (!doubleClickToFullscreen) {
      return { handlePointerDown: onClick, handleDoubleClick: () => {
        return;
      } };
    }
    return { handlePointerDown, handleDoubleClick };
  }, [doubleClickToFullscreen, handleDoubleClick, handlePointerDown, onClick]);
  return returnValue;
};

// src/PlayerUI.tsx

var reactVersion = react__WEBPACK_IMPORTED_MODULE_2__.version.split(".")[0];
if (reactVersion === "0") {
  throw new Error(`Version ${reactVersion} of "react" is not supported by Remotion`);
}
var doesReactVersionSupportSuspense = parseInt(reactVersion, 10) >= 18;
var PlayerUI = ({
  controls,
  style: style2,
  loop,
  autoPlay,
  allowFullscreen,
  inputProps,
  clickToPlay,
  showVolumeControls,
  doubleClickToFullscreen,
  spaceKeyToPlayOrPause,
  errorFallback,
  playbackRate,
  renderLoading,
  renderPoster,
  className: className2,
  moveToBeginningWhenEnded,
  showPosterWhenUnplayed,
  showPosterWhenEnded,
  showPosterWhenPaused,
  showPosterWhenBuffering,
  showPosterWhenBufferingAndPaused,
  inFrame,
  outFrame,
  initiallyShowControls,
  renderFullscreen: renderFullscreenButton,
  renderPlayPauseButton,
  renderMuteButton,
  renderVolumeSlider,
  renderCustomControls,
  alwaysShowControls,
  showPlaybackRateControl,
  posterFillMode,
  bufferStateDelayInMilliseconds,
  hideControlsWhenPointerDoesntMove,
  overflowVisible,
  browserMediaControlsBehavior,
  overrideInternalClassName,
  noSuspense
}, ref) => {
  const config = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.useUnsafeVideoConfig();
  const video = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.useVideo();
  const container = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(null);
  const canvasSize = useElementSize(container, {
    triggerOnWindowResize: false,
    shouldApplyCssTransforms: false
  });
  const [hasPausedToResume, setHasPausedToResume] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(false);
  const [shouldAutoplay, setShouldAutoPlay] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(autoPlay);
  const [isFullscreen, setIsFullscreen] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(() => false);
  const [seeking, setSeeking] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(false);
  const supportsFullScreen = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    if (typeof document === "undefined") {
      return false;
    }
    return Boolean(document.fullscreenEnabled || document.webkitFullscreenEnabled);
  }, []);
  const player = usePlayer();
  const playerToggle = player.toggle;
  usePlayback({
    loop,
    playbackRate,
    moveToBeginningWhenEnded,
    inFrame,
    outFrame,
    getCurrentFrame: player.getCurrentFrame,
    browserMediaControlsBehavior
  });
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (hasPausedToResume && !player.playing) {
      setHasPausedToResume(false);
      player.play();
    }
  }, [hasPausedToResume, player]);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    const { current } = container;
    if (!current) {
      return;
    }
    const onFullscreenChange = () => {
      const newValue = document.fullscreenElement === current || document.webkitFullscreenElement === current;
      setIsFullscreen(newValue);
    };
    document.addEventListener("fullscreenchange", onFullscreenChange);
    document.addEventListener("webkitfullscreenchange", onFullscreenChange);
    return () => {
      document.removeEventListener("fullscreenchange", onFullscreenChange);
      document.removeEventListener("webkitfullscreenchange", onFullscreenChange);
    };
  }, []);
  const toggle = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((e) => {
    playerToggle(e);
  }, [playerToggle]);
  const requestFullscreen = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    if (!allowFullscreen) {
      throw new Error("allowFullscreen is false");
    }
    if (!supportsFullScreen) {
      throw new Error("Browser doesnt support fullscreen");
    }
    if (!container.current) {
      throw new Error("No player ref found");
    }
    if (container.current.webkitRequestFullScreen) {
      container.current.webkitRequestFullScreen();
    } else {
      container.current.requestFullscreen();
    }
  }, [allowFullscreen, supportsFullScreen]);
  const exitFullscreen = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    if (document.webkitExitFullscreen) {
      document.webkitExitFullscreen();
    } else {
      document.exitFullscreen();
    }
  }, []);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    const { current } = container;
    if (!current) {
      return;
    }
    const fullscreenChange = () => {
      const element = document.webkitFullscreenElement ?? document.fullscreenElement;
      if (element && element === container.current) {
        player.emitter.dispatchFullscreenChange({
          isFullscreen: true
        });
      } else {
        player.emitter.dispatchFullscreenChange({
          isFullscreen: false
        });
      }
    };
    current.addEventListener("webkitfullscreenchange", fullscreenChange);
    current.addEventListener("fullscreenchange", fullscreenChange);
    return () => {
      current.removeEventListener("webkitfullscreenchange", fullscreenChange);
      current.removeEventListener("fullscreenchange", fullscreenChange);
    };
  }, [player.emitter]);
  const durationInFrames = config?.durationInFrames ?? 1;
  const layout = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    if (!config || !canvasSize) {
      return null;
    }
    return calculateCanvasTransformation({
      canvasSize,
      compositionHeight: config.height,
      compositionWidth: config.width,
      previewSize: "auto"
    });
  }, [canvasSize, config]);
  const scale = layout?.scale ?? 1;
  const initialScaleIgnored = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(false);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (!initialScaleIgnored.current) {
      initialScaleIgnored.current = true;
      return;
    }
    player.emitter.dispatchScaleChange(scale);
  }, [player.emitter, scale]);
  const { setMediaVolume, setMediaMuted } = (0,react__WEBPACK_IMPORTED_MODULE_2__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.SetMediaVolumeContext);
  const { mediaMuted, mediaVolume } = (0,react__WEBPACK_IMPORTED_MODULE_2__.useContext)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.MediaVolumeContext);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    player.emitter.dispatchVolumeChange(mediaVolume);
  }, [player.emitter, mediaVolume]);
  const isMuted = mediaMuted || mediaVolume === 0;
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    player.emitter.dispatchMuteChange({
      isMuted
    });
  }, [player.emitter, isMuted]);
  const [showBufferIndicator, setShowBufferState] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(false);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    let timeout = null;
    let stopped = false;
    const onBuffer = () => {
      stopped = false;
      requestAnimationFrame(() => {
        if (bufferStateDelayInMilliseconds === 0) {
          setShowBufferState(true);
        } else {
          timeout = setTimeout(() => {
            if (!stopped) {
              setShowBufferState(true);
            }
          }, bufferStateDelayInMilliseconds);
        }
      });
    };
    const onResume = () => {
      requestAnimationFrame(() => {
        stopped = true;
        setShowBufferState(false);
        if (timeout) {
          clearTimeout(timeout);
        }
      });
    };
    player.emitter.addEventListener("waiting", onBuffer);
    player.emitter.addEventListener("resume", onResume);
    return () => {
      player.emitter.removeEventListener("waiting", onBuffer);
      player.emitter.removeEventListener("resume", onResume);
      setShowBufferState(false);
      if (timeout) {
        clearTimeout(timeout);
      }
      stopped = true;
    };
  }, [bufferStateDelayInMilliseconds, player.emitter]);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useImperativeHandle)(ref, () => {
    const methods = {
      play: player.play,
      pause: () => {
        setHasPausedToResume(false);
        player.pause();
      },
      toggle,
      getContainerNode: () => container.current,
      getCurrentFrame: player.getCurrentFrame,
      isPlaying: player.isPlaying,
      seekTo: (f) => {
        const lastFrame = durationInFrames - 1;
        const frameToSeekTo = Math.max(0, Math.min(lastFrame, f));
        if (player.isPlaying()) {
          const pauseToResume = frameToSeekTo !== lastFrame || loop;
          setHasPausedToResume(pauseToResume);
          player.pause();
        }
        if (frameToSeekTo === lastFrame && !loop) {
          player.emitter.dispatchEnded();
        }
        player.seek(frameToSeekTo);
      },
      isFullscreen: () => {
        const { current } = container;
        if (!current) {
          return false;
        }
        return document.fullscreenElement === current || document.webkitFullscreenElement === current;
      },
      requestFullscreen,
      exitFullscreen,
      getVolume: () => {
        if (mediaMuted) {
          return 0;
        }
        return mediaVolume;
      },
      setVolume: (vol) => {
        if (typeof vol !== "number") {
          throw new TypeError(`setVolume() takes a number, got value of type ${typeof vol}`);
        }
        if (isNaN(vol)) {
          throw new TypeError(`setVolume() got a number that is NaN. Volume must be between 0 and 1.`);
        }
        if (vol < 0 || vol > 1) {
          throw new TypeError(`setVolume() got a number that is out of range. Must be between 0 and 1, got ${typeof vol}`);
        }
        setMediaVolume(vol);
      },
      isMuted: () => isMuted,
      mute: () => {
        setMediaMuted(true);
      },
      unmute: () => {
        setMediaMuted(false);
      },
      getScale: () => scale,
      pauseAndReturnToPlayStart: () => {
        player.pauseAndReturnToPlayStart();
      }
    };
    return Object.assign(player.emitter, methods);
  }, [
    durationInFrames,
    exitFullscreen,
    loop,
    mediaMuted,
    isMuted,
    mediaVolume,
    player,
    requestFullscreen,
    setMediaMuted,
    setMediaVolume,
    toggle,
    scale
  ]);
  const VideoComponent = video ? video.component : null;
  const outerStyle = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return calculateOuterStyle({
      canvasSize,
      config,
      style: style2,
      overflowVisible,
      layout
    });
  }, [canvasSize, config, layout, overflowVisible, style2]);
  const outer = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return calculateOuter({ config, layout, scale, overflowVisible });
  }, [config, layout, overflowVisible, scale]);
  const containerStyle3 = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return calculateContainerStyle({
      config,
      layout,
      scale,
      overflowVisible
    });
  }, [config, layout, overflowVisible, scale]);
  const playerPause = player.pause;
  const playerDispatchError = player.emitter.dispatchError;
  const onError = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((error) => {
    playerPause();
    playerDispatchError(error);
  }, [playerDispatchError, playerPause]);
  const onFullscreenButtonClick = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((e) => {
    e.stopPropagation();
    requestFullscreen();
  }, [requestFullscreen]);
  const onExitFullscreenButtonClick = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((e) => {
    e.stopPropagation();
    exitFullscreen();
  }, [exitFullscreen]);
  const onSingleClick = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((e) => {
    const rightClick = e instanceof MouseEvent ? e.button === 2 : e.nativeEvent.button;
    if (rightClick) {
      return;
    }
    toggle(e);
  }, [toggle]);
  const onSeekStart = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    setSeeking(true);
  }, []);
  const onSeekEnd = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    setSeeking(false);
  }, []);
  const onDoubleClick = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)(() => {
    if (isFullscreen) {
      exitFullscreen();
    } else {
      requestFullscreen();
    }
  }, [exitFullscreen, isFullscreen, requestFullscreen]);
  const { handlePointerDown, handleDoubleClick } = useClickPreventionOnDoubleClick(onSingleClick, onDoubleClick, doubleClickToFullscreen && allowFullscreen && supportsFullScreen);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    if (shouldAutoplay) {
      player.play();
      setShouldAutoPlay(false);
    }
  }, [shouldAutoplay, player]);
  const loadingMarkup = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return renderLoading ? renderLoading({
      height: outerStyle.height,
      width: outerStyle.width,
      isBuffering: showBufferIndicator
    }) : null;
  }, [outerStyle.height, outerStyle.width, renderLoading, showBufferIndicator]);
  const currentScale = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      type: "scale",
      scale
    };
  }, [scale]);
  if (!config) {
    return null;
  }
  const poster = renderPoster ? renderPoster({
    height: posterFillMode === "player-size" ? outerStyle.height : config.height,
    width: posterFillMode === "player-size" ? outerStyle.width : config.width,
    isBuffering: showBufferIndicator
  }) : null;
  if (poster === undefined) {
    throw new TypeError("renderPoster() must return a React element, but undefined was returned");
  }
  const shouldShowPoster = poster && [
    showPosterWhenPaused && !player.isPlaying() && !seeking,
    showPosterWhenEnded && player.isLastFrame && !player.isPlaying(),
    showPosterWhenUnplayed && !player.hasPlayed && !player.isPlaying(),
    showPosterWhenBuffering && showBufferIndicator && player.isPlaying(),
    showPosterWhenBufferingAndPaused && showBufferIndicator && !player.isPlaying()
  ].some(Boolean);
  const { left, top, width, height, ...outerWithoutScale } = outer;
  const content = /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
        style: outer,
        onPointerDown: clickToPlay ? handlePointerDown : undefined,
        onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined,
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsxs)("div", {
            style: containerStyle3,
            className: playerCssClassname(overrideInternalClassName),
            children: [
              VideoComponent ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ErrorBoundary, {
                onError,
                errorFallback,
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.CurrentScaleContext.Provider, {
                  value: currentScale,
                  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(VideoComponent, {
                    ...video?.props ?? {},
                    ...inputProps ?? {}
                  })
                })
              }) : null,
              shouldShowPoster && posterFillMode === "composition-size" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
                style: {
                  ...outerWithoutScale,
                  width: config.width,
                  height: config.height
                },
                onPointerDown: clickToPlay ? handlePointerDown : undefined,
                onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined,
                children: poster
              }) : null
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(RenderWarningIfBlacklist, {})
        ]
      }),
      shouldShowPoster && posterFillMode === "player-size" ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
        style: outer,
        onPointerDown: clickToPlay ? handlePointerDown : undefined,
        onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined,
        children: poster
      }) : null,
      controls ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(Controls, {
        fps: config.fps,
        playing: player.playing,
        toggle: player.toggle,
        durationInFrames: config.durationInFrames,
        containerRef: container,
        onFullscreenButtonClick,
        isFullscreen,
        allowFullscreen,
        showVolumeControls,
        onExitFullscreenButtonClick,
        spaceKeyToPlayOrPause,
        onSeekEnd,
        onSeekStart,
        inFrame,
        outFrame,
        initiallyShowControls,
        canvasSize,
        renderFullscreenButton,
        renderPlayPauseButton,
        alwaysShowControls,
        showPlaybackRateControl,
        buffering: showBufferIndicator,
        hideControlsWhenPointerDoesntMove,
        onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined,
        onPointerDown: clickToPlay ? handlePointerDown : undefined,
        renderMuteButton,
        renderVolumeSlider,
        renderCustomControls
      }) : null
    ]
  });
  if (noSuspense || IS_NODE && !doesReactVersionSupportSuspense) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
      ref: container,
      style: outerStyle,
      className: className2,
      children: content
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
    ref: container,
    style: outerStyle,
    className: className2,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(react__WEBPACK_IMPORTED_MODULE_2__.Suspense, {
      fallback: loadingMarkup,
      children: content
    })
  });
};
var PlayerUI_default = (0,react__WEBPACK_IMPORTED_MODULE_2__.forwardRef)(PlayerUI);

// src/SharedPlayerContext.tsx



// src/volume-persistance.ts

var DEFAULT_VOLUME_PERSISTANCE_KEY = "remotion.volumePreference";
var persistVolume = (volume, logLevel, volumePersistenceKey) => {
  if (typeof window === "undefined") {
    return;
  }
  try {
    window.localStorage.setItem(volumePersistenceKey ?? DEFAULT_VOLUME_PERSISTANCE_KEY, String(volume));
  } catch (e) {
    remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.Log.error({ logLevel, tag: null }, "Could not persist volume", e);
  }
};
var getPreferredVolume = (volumePersistenceKey) => {
  if (typeof window === "undefined") {
    return 1;
  }
  try {
    const val = window.localStorage.getItem(volumePersistenceKey ?? DEFAULT_VOLUME_PERSISTANCE_KEY);
    return val ? Number(val) : 1;
  } catch {
    return 1;
  }
};

// src/SharedPlayerContext.tsx

var PLAYER_COMP_ID = "player-comp";
var SharedPlayerContexts = ({
  children,
  timelineContext,
  fps,
  compositionHeight,
  compositionWidth,
  durationInFrames,
  component,
  numberOfSharedAudioTags,
  initiallyMuted,
  logLevel,
  audioLatencyHint,
  volumePersistenceKey,
  inputProps,
  audioEnabled
}) => {
  const compositionManagerContext = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    const context = {
      compositions: [
        {
          component,
          durationInFrames,
          height: compositionHeight,
          width: compositionWidth,
          fps,
          id: PLAYER_COMP_ID,
          nonce: 777,
          folderName: null,
          parentFolderName: null,
          schema: null,
          calculateMetadata: null
        }
      ],
      folders: [],
      currentCompositionMetadata: {
        defaultCodec: null,
        defaultOutName: null,
        defaultPixelFormat: null,
        defaultProResProfile: null,
        defaultVideoImageFormat: null,
        durationInFrames,
        fps,
        height: compositionHeight,
        width: compositionWidth,
        props: inputProps
      },
      canvasContent: { type: "composition", compositionId: "player-comp" }
    };
    return context;
  }, [
    component,
    durationInFrames,
    compositionHeight,
    compositionWidth,
    fps,
    inputProps
  ]);
  const [mediaMuted, setMediaMuted] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(() => initiallyMuted);
  const [mediaVolume, setMediaVolume] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(() => getPreferredVolume(volumePersistenceKey ?? null));
  const mediaVolumeContextValue = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      mediaMuted,
      mediaVolume
    };
  }, [mediaMuted, mediaVolume]);
  const setMediaVolumeAndPersist = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((vol) => {
    setMediaVolume(vol);
    persistVolume(vol, logLevel, volumePersistenceKey ?? null);
  }, [logLevel, volumePersistenceKey]);
  const setMediaVolumeContextValue = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      setMediaMuted,
      setMediaVolume: setMediaVolumeAndPersist
    };
  }, [setMediaVolumeAndPersist]);
  const logLevelContext = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      logLevel,
      mountTime: Date.now()
    };
  }, [logLevel]);
  const env = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      isPlayer: true,
      isRendering: false,
      isStudio: false,
      isClientSideRendering: false,
      isReadOnlyStudio: false
    };
  }, []);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.RemotionEnvironmentContext.Provider, {
    value: env,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.LogLevelContext.Provider, {
      value: logLevelContext,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.CanUseRemotionHooksProvider, {
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.TimelineContext.Provider, {
          value: timelineContext,
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.CompositionManager.Provider, {
            value: compositionManagerContext,
            children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.PrefetchProvider, {
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.DurationsContextProvider, {
                children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.MediaVolumeContext.Provider, {
                  value: mediaVolumeContextValue,
                  children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.SetMediaVolumeContext.Provider, {
                    value: setMediaVolumeContextValue,
                    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.SharedAudioContextProvider, {
                      numberOfAudioTags: numberOfSharedAudioTags,
                      audioLatencyHint,
                      audioEnabled,
                      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.BufferingProvider, {
                        children
                      })
                    })
                  })
                })
              })
            })
          })
        })
      })
    })
  });
};

// src/use-remotion-license-acknowledge.ts

var warningShown = false;
var acknowledgeRemotionLicenseMessage = (acknowledge, logLevel) => {
  if (acknowledge) {
    return;
  }
  if (warningShown) {
    return;
  }
  warningShown = true;
  remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.Log.warn({ logLevel, tag: null }, "Note: Some companies are required to obtain a license to use Remotion. See: https://remotion.dev/license\nPass the `acknowledgeRemotionLicense` prop to `<Player />` function to make this message disappear.");
};

// src/utils/validate-in-out-frame.ts
var validateSingleFrame = (frame, variableName) => {
  if (typeof frame === "undefined" || frame === null) {
    return frame ?? null;
  }
  if (typeof frame !== "number") {
    throw new TypeError(`"${variableName}" must be a number, but is ${JSON.stringify(frame)}`);
  }
  if (Number.isNaN(frame)) {
    throw new TypeError(`"${variableName}" must not be NaN, but is ${JSON.stringify(frame)}`);
  }
  if (!Number.isFinite(frame)) {
    throw new TypeError(`"${variableName}" must be finite, but is ${JSON.stringify(frame)}`);
  }
  if (frame % 1 !== 0) {
    throw new TypeError(`"${variableName}" must be an integer, but is ${JSON.stringify(frame)}`);
  }
  return frame;
};
var validateInOutFrames = ({
  inFrame,
  durationInFrames,
  outFrame
}) => {
  const validatedInFrame = validateSingleFrame(inFrame, "inFrame");
  const validatedOutFrame = validateSingleFrame(outFrame, "outFrame");
  if (validatedInFrame === null && validatedOutFrame === null) {
    return;
  }
  if (validatedInFrame !== null && validatedInFrame > durationInFrames - 1) {
    throw new Error("inFrame must be less than (durationInFrames - 1), but is " + validatedInFrame);
  }
  if (validatedOutFrame !== null && validatedOutFrame > durationInFrames - 1) {
    throw new Error("outFrame must be less than (durationInFrames - 1), but is " + validatedOutFrame);
  }
  if (validatedInFrame !== null && validatedInFrame < 0) {
    throw new Error("inFrame must be greater than 0, but is " + validatedInFrame);
  }
  if (validatedOutFrame !== null && validatedOutFrame <= 0) {
    throw new Error(`outFrame must be greater than 0, but is ${validatedOutFrame}. If you want to render a single frame, use <Thumbnail /> instead.`);
  }
  if (validatedOutFrame !== null && validatedInFrame !== null && validatedOutFrame <= validatedInFrame) {
    throw new Error("outFrame must be greater than inFrame, but is " + validatedOutFrame + " <= " + validatedInFrame);
  }
};

// src/utils/validate-initial-frame.ts
var validateInitialFrame = ({
  initialFrame,
  durationInFrames
}) => {
  if (typeof durationInFrames !== "number") {
    throw new Error(`\`durationInFrames\` must be a number, but is ${JSON.stringify(durationInFrames)}`);
  }
  if (typeof initialFrame === "undefined") {
    return;
  }
  if (typeof initialFrame !== "number") {
    throw new Error(`\`initialFrame\` must be a number, but is ${JSON.stringify(initialFrame)}`);
  }
  if (Number.isNaN(initialFrame)) {
    throw new Error(`\`initialFrame\` must be a number, but is NaN`);
  }
  if (!Number.isFinite(initialFrame)) {
    throw new Error(`\`initialFrame\` must be a number, but is Infinity`);
  }
  if (initialFrame % 1 !== 0) {
    throw new Error(`\`initialFrame\` must be an integer, but is ${JSON.stringify(initialFrame)}`);
  }
  if (initialFrame > durationInFrames - 1) {
    throw new Error(`\`initialFrame\` must be less or equal than \`durationInFrames - 1\`, but is ${JSON.stringify(initialFrame)}`);
  }
};

// src/utils/validate-playbackrate.ts
var validatePlaybackRate = (playbackRate) => {
  if (playbackRate === undefined) {
    return;
  }
  if (playbackRate > 4) {
    throw new Error(`The highest possible playback rate is 4. You passed: ${playbackRate}`);
  }
  if (playbackRate < -4) {
    throw new Error(`The lowest possible playback rate is -4. You passed: ${playbackRate}`);
  }
  if (playbackRate === 0) {
    throw new Error(`A playback rate of 0 is not supported.`);
  }
};

// src/validate.ts

var validateFps = remotion_no_react__WEBPACK_IMPORTED_MODULE_3__.NoReactInternals.validateFps;
var validateDimension = remotion_no_react__WEBPACK_IMPORTED_MODULE_3__.NoReactInternals.validateDimension;
var validateDurationInFrames = remotion_no_react__WEBPACK_IMPORTED_MODULE_3__.NoReactInternals.validateDurationInFrames;
var validateDefaultAndInputProps = remotion_no_react__WEBPACK_IMPORTED_MODULE_3__.NoReactInternals.validateDefaultAndInputProps;

// src/Player.tsx

var componentOrNullIfLazy = (props) => {
  if ("component" in props) {
    return props.component;
  }
  return null;
};
var PlayerFn = ({
  durationInFrames,
  compositionHeight,
  compositionWidth,
  fps,
  inputProps,
  style: style2,
  controls = false,
  loop = false,
  autoPlay = false,
  showVolumeControls = true,
  allowFullscreen = true,
  clickToPlay,
  doubleClickToFullscreen = false,
  spaceKeyToPlayOrPause = true,
  moveToBeginningWhenEnded = true,
  numberOfSharedAudioTags = 5,
  errorFallback = () => "⚠️",
  playbackRate = 1,
  renderLoading,
  className: className2,
  showPosterWhenUnplayed,
  showPosterWhenEnded,
  showPosterWhenPaused,
  showPosterWhenBuffering,
  showPosterWhenBufferingAndPaused,
  initialFrame,
  renderPoster,
  inFrame,
  outFrame,
  initiallyShowControls,
  renderFullscreenButton,
  renderPlayPauseButton,
  renderVolumeSlider,
  renderCustomControls,
  alwaysShowControls = false,
  initiallyMuted = false,
  showPlaybackRateControl = false,
  posterFillMode = "player-size",
  bufferStateDelayInMilliseconds,
  hideControlsWhenPointerDoesntMove = true,
  overflowVisible = false,
  renderMuteButton,
  browserMediaControlsBehavior: passedBrowserMediaControlsBehavior,
  overrideInternalClassName,
  logLevel = "info",
  noSuspense,
  acknowledgeRemotionLicense,
  audioLatencyHint = "interactive",
  volumePersistenceKey,
  ...componentProps
}, ref) => {
  if (typeof window !== "undefined") {
    window.remotion_isPlayer = true;
  }
  if (componentProps.defaultProps !== undefined) {
    throw new Error("The <Player /> component does not accept `defaultProps`, but some were passed. Use `inputProps` instead.");
  }
  const componentForValidation = componentOrNullIfLazy(componentProps);
  if (componentForValidation?.type === remotion__WEBPACK_IMPORTED_MODULE_1__.Composition) {
    throw new TypeError(`'component' should not be an instance of <Composition/>. Pass the React component directly, and set the duration, fps and dimensions as separate props. See https://www.remotion.dev/docs/player/examples for an example.`);
  }
  if (componentForValidation === remotion__WEBPACK_IMPORTED_MODULE_1__.Composition) {
    throw new TypeError(`'component' must not be the 'Composition' component. Pass your own React component directly, and set the duration, fps and dimensions as separate props. See https://www.remotion.dev/docs/player/examples for an example.`);
  }
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(() => acknowledgeRemotionLicenseMessage(Boolean(acknowledgeRemotionLicense), logLevel));
  const component = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.useLazyComponent({
    compProps: componentProps,
    componentName: "Player",
    noSuspense: Boolean(noSuspense)
  });
  validateInitialFrame({ initialFrame, durationInFrames });
  const [frame, setFrame] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(() => ({
    [PLAYER_COMP_ID]: initialFrame ?? 0
  }));
  const [playing, setPlaying] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(false);
  const [rootId] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)("player-comp");
  const rootRef = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(null);
  const audioAndVideoTags = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)([]);
  const imperativePlaying = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(false);
  const [currentPlaybackRate, setCurrentPlaybackRate] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(playbackRate);
  if (typeof compositionHeight !== "number") {
    throw new TypeError(`'compositionHeight' must be a number but got '${typeof compositionHeight}' instead`);
  }
  if (typeof compositionWidth !== "number") {
    throw new TypeError(`'compositionWidth' must be a number but got '${typeof compositionWidth}' instead`);
  }
  validateDimension(compositionHeight, "compositionHeight", "of the <Player /> component");
  validateDimension(compositionWidth, "compositionWidth", "of the <Player /> component");
  validateDurationInFrames(durationInFrames, {
    component: "of the <Player/> component",
    allowFloats: false
  });
  validateFps(fps, "as a prop of the <Player/> component", false);
  validateDefaultAndInputProps(inputProps, "inputProps", null);
  validateInOutFrames({
    durationInFrames,
    inFrame,
    outFrame
  });
  if (typeof controls !== "boolean" && typeof controls !== "undefined") {
    throw new TypeError(`'controls' must be a boolean or undefined but got '${typeof controls}' instead`);
  }
  if (typeof autoPlay !== "boolean" && typeof autoPlay !== "undefined") {
    throw new TypeError(`'autoPlay' must be a boolean or undefined but got '${typeof autoPlay}' instead`);
  }
  if (typeof loop !== "boolean" && typeof loop !== "undefined") {
    throw new TypeError(`'loop' must be a boolean or undefined but got '${typeof loop}' instead`);
  }
  if (typeof doubleClickToFullscreen !== "boolean" && typeof doubleClickToFullscreen !== "undefined") {
    throw new TypeError(`'doubleClickToFullscreen' must be a boolean or undefined but got '${typeof doubleClickToFullscreen}' instead`);
  }
  if (typeof showVolumeControls !== "boolean" && typeof showVolumeControls !== "undefined") {
    throw new TypeError(`'showVolumeControls' must be a boolean or undefined but got '${typeof showVolumeControls}' instead`);
  }
  if (typeof allowFullscreen !== "boolean" && typeof allowFullscreen !== "undefined") {
    throw new TypeError(`'allowFullscreen' must be a boolean or undefined but got '${typeof allowFullscreen}' instead`);
  }
  if (typeof clickToPlay !== "boolean" && typeof clickToPlay !== "undefined") {
    throw new TypeError(`'clickToPlay' must be a boolean or undefined but got '${typeof clickToPlay}' instead`);
  }
  if (typeof spaceKeyToPlayOrPause !== "boolean" && typeof spaceKeyToPlayOrPause !== "undefined") {
    throw new TypeError(`'spaceKeyToPlayOrPause' must be a boolean or undefined but got '${typeof spaceKeyToPlayOrPause}' instead`);
  }
  if (typeof numberOfSharedAudioTags !== "number" || numberOfSharedAudioTags % 1 !== 0 || !Number.isFinite(numberOfSharedAudioTags) || Number.isNaN(numberOfSharedAudioTags) || numberOfSharedAudioTags < 0) {
    throw new TypeError(`'numberOfSharedAudioTags' must be an integer but got '${numberOfSharedAudioTags}' instead`);
  }
  validatePlaybackRate(currentPlaybackRate);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useEffect)(() => {
    setCurrentPlaybackRate(playbackRate);
  }, [playbackRate]);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useImperativeHandle)(ref, () => rootRef.current, []);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(() => {
    remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.playbackLogging({
      logLevel,
      message: `[player] Mounting <Player>. User agent = ${typeof navigator === "undefined" ? "server" : navigator.userAgent}`,
      tag: "player",
      mountTime: Date.now()
    });
  });
  const timelineContextValue = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      frame,
      playing,
      rootId,
      playbackRate: currentPlaybackRate,
      imperativePlaying,
      setPlaybackRate: (rate) => {
        setCurrentPlaybackRate(rate);
      },
      audioAndVideoTags
    };
  }, [frame, currentPlaybackRate, playing, rootId]);
  const setTimelineContextValue = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      setFrame,
      setPlaying
    };
  }, [setFrame]);
  if (typeof window !== "undefined") {
    (0,react__WEBPACK_IMPORTED_MODULE_2__.useLayoutEffect)(() => {
      remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.CSSUtils.injectCSS(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.CSSUtils.makeDefaultPreviewCSS(`.${playerCssClassname(overrideInternalClassName)}`, "#fff"));
    }, [overrideInternalClassName]);
  }
  const actualInputProps = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => inputProps ?? {}, [inputProps]);
  const browserMediaControlsBehavior = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return passedBrowserMediaControlsBehavior ?? {
      mode: "prevent-media-session"
    };
  }, [passedBrowserMediaControlsBehavior]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.IsPlayerContextProvider, {
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(SharedPlayerContexts, {
      timelineContext: timelineContextValue,
      component,
      compositionHeight,
      compositionWidth,
      durationInFrames,
      fps,
      numberOfSharedAudioTags,
      initiallyMuted,
      logLevel,
      audioLatencyHint,
      volumePersistenceKey,
      inputProps: actualInputProps,
      audioEnabled: true,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.SetTimelineContext.Provider, {
        value: setTimelineContextValue,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(PlayerEmitterProvider, {
          currentPlaybackRate,
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(PlayerUI_default, {
            ref: rootRef,
            posterFillMode,
            renderLoading,
            autoPlay: Boolean(autoPlay),
            loop: Boolean(loop),
            controls: Boolean(controls),
            errorFallback,
            style: style2,
            inputProps: actualInputProps,
            allowFullscreen: Boolean(allowFullscreen),
            moveToBeginningWhenEnded: Boolean(moveToBeginningWhenEnded),
            clickToPlay: typeof clickToPlay === "boolean" ? clickToPlay : Boolean(controls),
            showVolumeControls: Boolean(showVolumeControls),
            doubleClickToFullscreen: Boolean(doubleClickToFullscreen),
            spaceKeyToPlayOrPause: Boolean(spaceKeyToPlayOrPause),
            playbackRate: currentPlaybackRate,
            className: className2 ?? undefined,
            showPosterWhenUnplayed: Boolean(showPosterWhenUnplayed),
            showPosterWhenEnded: Boolean(showPosterWhenEnded),
            showPosterWhenPaused: Boolean(showPosterWhenPaused),
            showPosterWhenBuffering: Boolean(showPosterWhenBuffering),
            showPosterWhenBufferingAndPaused: Boolean(showPosterWhenBufferingAndPaused),
            renderPoster,
            inFrame: inFrame ?? null,
            outFrame: outFrame ?? null,
            initiallyShowControls: initiallyShowControls ?? true,
            renderFullscreen: renderFullscreenButton ?? null,
            renderPlayPauseButton: renderPlayPauseButton ?? null,
            renderMuteButton: renderMuteButton ?? null,
            renderVolumeSlider: renderVolumeSlider ?? null,
            renderCustomControls: renderCustomControls ?? null,
            alwaysShowControls,
            showPlaybackRateControl,
            bufferStateDelayInMilliseconds: bufferStateDelayInMilliseconds ?? 300,
            hideControlsWhenPointerDoesntMove,
            overflowVisible,
            browserMediaControlsBehavior,
            overrideInternalClassName: overrideInternalClassName ?? undefined,
            noSuspense: Boolean(noSuspense)
          })
        })
      })
    })
  });
};
var forward = react__WEBPACK_IMPORTED_MODULE_2__.forwardRef;
var Player = forward(PlayerFn);
// src/Thumbnail.tsx



// src/ThumbnailUI.tsx



// src/use-thumbnail.ts

var useThumbnail = () => {
  const emitter = (0,react__WEBPACK_IMPORTED_MODULE_2__.useContext)(ThumbnailEmitterContext);
  if (!emitter) {
    throw new TypeError("Expected Player event emitter context");
  }
  const returnValue = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      emitter
    };
  }, [emitter]);
  return returnValue;
};

// src/ThumbnailUI.tsx

var reactVersion2 = react__WEBPACK_IMPORTED_MODULE_2__.version.split(".")[0];
if (reactVersion2 === "0") {
  throw new Error(`Version ${reactVersion2} of "react" is not supported by Remotion`);
}
var doesReactVersionSupportSuspense2 = parseInt(reactVersion2, 10) >= 18;
var ThumbnailUI = ({
  style: style2,
  inputProps,
  errorFallback,
  renderLoading,
  className: className2,
  overflowVisible,
  noSuspense,
  overrideInternalClassName
}, ref) => {
  const config = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.useUnsafeVideoConfig();
  const video = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.useVideo();
  const container = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(null);
  const canvasSize = useElementSize(container, {
    triggerOnWindowResize: false,
    shouldApplyCssTransforms: false
  });
  const layout = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    if (!config || !canvasSize) {
      return null;
    }
    return calculateCanvasTransformation({
      canvasSize,
      compositionHeight: config.height,
      compositionWidth: config.width,
      previewSize: "auto"
    });
  }, [canvasSize, config]);
  const scale = layout?.scale ?? 1;
  const thumbnail = useThumbnail();
  useBufferStateEmitter(thumbnail.emitter);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useImperativeHandle)(ref, () => {
    const methods = {
      getContainerNode: () => container.current,
      getScale: () => scale
    };
    return Object.assign(thumbnail.emitter, methods);
  }, [scale, thumbnail.emitter]);
  const VideoComponent = video ? video.component : null;
  const outerStyle = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return calculateOuterStyle({
      config,
      style: style2,
      canvasSize,
      overflowVisible,
      layout
    });
  }, [canvasSize, config, layout, overflowVisible, style2]);
  const outer = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return calculateOuter({ config, layout, scale, overflowVisible });
  }, [config, layout, overflowVisible, scale]);
  const containerStyle3 = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return calculateContainerStyle({
      config,
      layout,
      scale,
      overflowVisible
    });
  }, [config, layout, overflowVisible, scale]);
  const onError = (0,react__WEBPACK_IMPORTED_MODULE_2__.useCallback)((error) => {
    thumbnail.emitter.dispatchError(error);
  }, [thumbnail.emitter]);
  const loadingMarkup = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return renderLoading ? renderLoading({
      height: outerStyle.height,
      width: outerStyle.width,
      isBuffering: false
    }) : null;
  }, [outerStyle.height, outerStyle.width, renderLoading]);
  const currentScaleContext = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return {
      type: "scale",
      scale
    };
  }, [scale]);
  if (!config) {
    return null;
  }
  const content = /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
    style: outer,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
      style: containerStyle3,
      className: playerCssClassname(overrideInternalClassName),
      children: VideoComponent ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ErrorBoundary, {
        onError,
        errorFallback,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.CurrentScaleContext.Provider, {
          value: currentScaleContext,
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(VideoComponent, {
            ...video?.props ?? {},
            ...inputProps ?? {}
          })
        })
      }) : null
    })
  });
  if (noSuspense || IS_NODE && !doesReactVersionSupportSuspense2) {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
      ref: container,
      style: outerStyle,
      className: className2,
      children: content
    });
  }
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)("div", {
    ref: container,
    style: outerStyle,
    className: className2,
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(react__WEBPACK_IMPORTED_MODULE_2__.Suspense, {
      fallback: loadingMarkup,
      children: content
    })
  });
};
var ThumbnailUI_default = (0,react__WEBPACK_IMPORTED_MODULE_2__.forwardRef)(ThumbnailUI);

// src/Thumbnail.tsx

var ThumbnailFn = ({
  frameToDisplay,
  style: style2,
  inputProps,
  compositionHeight,
  compositionWidth,
  durationInFrames,
  fps,
  className: className2,
  errorFallback = () => "⚠️",
  renderLoading,
  overflowVisible = false,
  overrideInternalClassName,
  logLevel = "info",
  noSuspense,
  ...componentProps
}, ref) => {
  if (typeof window !== "undefined") {
    (0,react__WEBPACK_IMPORTED_MODULE_2__.useLayoutEffect)(() => {
      window.remotion_isPlayer = true;
    }, []);
  }
  const [thumbnailId] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(() => String((0,remotion__WEBPACK_IMPORTED_MODULE_1__.random)(null)));
  const rootRef = (0,react__WEBPACK_IMPORTED_MODULE_2__.useRef)(null);
  const timelineState = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    const value = {
      playing: false,
      frame: {
        [PLAYER_COMP_ID]: frameToDisplay
      },
      rootId: thumbnailId,
      imperativePlaying: {
        current: false
      },
      playbackRate: 1,
      setPlaybackRate: () => {
        throw new Error("thumbnail");
      },
      audioAndVideoTags: { current: [] }
    };
    return value;
  }, [frameToDisplay, thumbnailId]);
  (0,react__WEBPACK_IMPORTED_MODULE_2__.useImperativeHandle)(ref, () => rootRef.current, []);
  const Component = remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.useLazyComponent({
    compProps: componentProps,
    componentName: "Thumbnail",
    noSuspense: Boolean(noSuspense)
  });
  const [emitter] = (0,react__WEBPACK_IMPORTED_MODULE_2__.useState)(() => new ThumbnailEmitter);
  const passedInputProps = (0,react__WEBPACK_IMPORTED_MODULE_2__.useMemo)(() => {
    return inputProps ?? {};
  }, [inputProps]);
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(remotion__WEBPACK_IMPORTED_MODULE_1__.Internals.IsPlayerContextProvider, {
    children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(SharedPlayerContexts, {
      timelineContext: timelineState,
      component: Component,
      compositionHeight,
      compositionWidth,
      durationInFrames,
      fps,
      numberOfSharedAudioTags: 0,
      initiallyMuted: true,
      logLevel,
      audioLatencyHint: "playback",
      inputProps: passedInputProps,
      audioEnabled: false,
      children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ThumbnailEmitterContext.Provider, {
        value: emitter,
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_0__.jsx)(ThumbnailUI_default, {
          ref: rootRef,
          className: className2,
          errorFallback,
          inputProps: passedInputProps,
          renderLoading,
          style: style2,
          overflowVisible,
          overrideInternalClassName,
          noSuspense: Boolean(noSuspense)
        })
      })
    })
  });
};
var forward2 = react__WEBPACK_IMPORTED_MODULE_2__.forwardRef;
var Thumbnail = forward2(ThumbnailFn);

// src/index.ts
var PlayerInternals = {
  PlayerEventEmitterContext,
  PlayerEmitter,
  usePlayer,
  usePlayback,
  useElementSize,
  calculateCanvasTransformation,
  useHoverState,
  updateAllElementsSizes,
  PlayerEmitterProvider,
  BufferingIndicator,
  useFrameImperative
};



/***/ },

/***/ 2896
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   B: () => (/* binding */ BrowserSafeApis)
/* harmony export */ });
/* harmony import */ var remotion_no_react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(9382);
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4848);
// src/client.ts


// src/browser/TimeoutSettings.ts
var DEFAULT_TIMEOUT = 30000;

class TimeoutSettings {
  #defaultTimeout;
  #defaultNavigationTimeout;
  constructor() {
    this.#defaultTimeout = null;
    this.#defaultNavigationTimeout = null;
  }
  setDefaultTimeout(timeout) {
    this.#defaultTimeout = timeout;
  }
  setDefaultNavigationTimeout(timeout) {
    this.#defaultNavigationTimeout = timeout;
  }
  navigationTimeout() {
    if (this.#defaultNavigationTimeout !== null) {
      return this.#defaultNavigationTimeout;
    }
    if (this.#defaultTimeout !== null) {
      return this.#defaultTimeout;
    }
    return DEFAULT_TIMEOUT;
  }
  timeout() {
    if (this.#defaultTimeout !== null) {
      return this.#defaultTimeout;
    }
    return DEFAULT_TIMEOUT;
  }
}

// src/codec.ts
var validCodecs = [
  "h264",
  "h265",
  "vp8",
  "vp9",
  "mp3",
  "aac",
  "wav",
  "prores",
  "h264-mkv",
  "h264-ts",
  "gif"
];
var DEFAULT_CODEC = "h264";

// src/crf.ts
var defaultCrfMap = {
  h264: 18,
  h265: 23,
  vp8: 9,
  vp9: 28,
  prores: null,
  gif: null,
  "h264-mkv": 18,
  "h264-ts": 18,
  aac: null,
  mp3: null,
  wav: null
};
var getDefaultCrfForCodec = (codec) => {
  const val = defaultCrfMap[codec];
  if (val === undefined) {
    throw new TypeError(`Got unexpected codec "${codec}"`);
  }
  return val;
};
var crfRanges = {
  h264: [1, 51],
  h265: [0, 51],
  vp8: [4, 63],
  vp9: [0, 63],
  prores: [0, 0],
  gif: [0, 0],
  "h264-mkv": [1, 51],
  "h264-ts": [1, 51],
  aac: [0, 0],
  mp3: [0, 0],
  wav: [0, 0]
};
var getValidCrfRanges = (codec) => {
  const val = crfRanges[codec];
  if (val === undefined) {
    throw new TypeError(`Got unexpected codec "${codec}"`);
  }
  return val;
};

// src/codec-supports-media.ts
var codecSupportsVideoBitrateMap = {
  "h264-mkv": true,
  "h264-ts": true,
  aac: false,
  gif: false,
  h264: true,
  h265: true,
  mp3: false,
  prores: false,
  vp8: true,
  vp9: true,
  wav: false
};
var codecSupportsCrf = (codec) => {
  const range = getValidCrfRanges(codec);
  return range[0] !== range[1];
};
var codecSupportsVideoBitrate = (codec) => {
  return codecSupportsVideoBitrateMap[codec];
};

// src/file-extensions.ts
var defaultFileExtensionMap = {
  "h264-mkv": {
    default: "mkv",
    forAudioCodec: {
      "pcm-16": { possible: ["mkv"], default: "mkv" },
      mp3: { possible: ["mkv"], default: "mkv" }
    }
  },
  "h264-ts": {
    default: "ts",
    forAudioCodec: {
      "pcm-16": { possible: ["ts"], default: "ts" },
      aac: { possible: ["ts"], default: "ts" }
    }
  },
  aac: {
    default: "aac",
    forAudioCodec: {
      aac: {
        possible: ["aac", "3gp", "m4a", "m4b", "mpg", "mpeg"],
        default: "aac"
      },
      "pcm-16": {
        possible: ["wav"],
        default: "wav"
      }
    }
  },
  gif: {
    default: "gif",
    forAudioCodec: {}
  },
  h264: {
    default: "mp4",
    forAudioCodec: {
      "pcm-16": { possible: ["mkv", "mov"], default: "mkv" },
      aac: { possible: ["mp4", "mkv", "mov"], default: "mp4" },
      mp3: { possible: ["mp4", "mkv", "mov"], default: "mp4" }
    }
  },
  h265: {
    default: "mp4",
    forAudioCodec: {
      aac: { possible: ["mp4", "mkv", "hevc"], default: "mp4" },
      "pcm-16": { possible: ["mkv"], default: "mkv" }
    }
  },
  mp3: {
    default: "mp3",
    forAudioCodec: {
      mp3: { possible: ["mp3"], default: "mp3" },
      "pcm-16": { possible: ["wav"], default: "wav" }
    }
  },
  prores: {
    default: "mov",
    forAudioCodec: {
      aac: { possible: ["mov", "mkv", "mxf"], default: "mov" },
      "pcm-16": { possible: ["mov", "mkv", "mxf"], default: "mov" }
    }
  },
  vp8: {
    default: "webm",
    forAudioCodec: {
      "pcm-16": { possible: ["mkv"], default: "mkv" },
      opus: { possible: ["webm"], default: "webm" }
    }
  },
  vp9: {
    default: "webm",
    forAudioCodec: {
      "pcm-16": { possible: ["mkv"], default: "mkv" },
      opus: { possible: ["webm"], default: "webm" }
    }
  },
  wav: {
    default: "wav",
    forAudioCodec: {
      "pcm-16": { possible: ["wav"], default: "wav" }
    }
  }
};

// src/get-extension-from-codec.ts
var getFileExtensionFromCodec = (codec, audioCodec) => {
  if (!validCodecs.includes(codec)) {
    throw new Error(`Codec must be one of the following: ${validCodecs.join(", ")}, but got ${codec}`);
  }
  const map = defaultFileExtensionMap[codec];
  if (audioCodec === null) {
    return map.default;
  }
  const typedAudioCodec = audioCodec;
  if (!(typedAudioCodec in map.forAudioCodec)) {
    throw new Error(`Audio codec ${typedAudioCodec} is not supported for codec ${codec}`);
  }
  return map.forAudioCodec[audioCodec].default;
};
var makeFileExtensionMap = () => {
  const map = {};
  Object.keys(defaultFileExtensionMap).forEach((_codec) => {
    const codec = _codec;
    const fileExtMap = defaultFileExtensionMap[codec];
    const audioCodecs = Object.keys(fileExtMap.forAudioCodec);
    const possibleExtensionsForAudioCodec = audioCodecs.map((audioCodec) => fileExtMap.forAudioCodec[audioCodec].possible);
    const allPossibleExtensions = [
      fileExtMap.default,
      ...possibleExtensionsForAudioCodec.flat(1)
    ];
    for (const extension of allPossibleExtensions) {
      if (!map[extension]) {
        map[extension] = [];
      }
      if (!map[extension].includes(codec)) {
        map[extension].push(codec);
      }
    }
  });
  return map;
};
var defaultCodecsForFileExtension = {
  "3gp": "aac",
  aac: "aac",
  gif: "gif",
  hevc: "h265",
  m4a: "aac",
  m4b: "aac",
  mkv: "h264-mkv",
  mov: "prores",
  mp3: "mp3",
  mp4: "h264",
  mpeg: "aac",
  mpg: "aac",
  mxf: "prores",
  wav: "wav",
  webm: "vp8",
  ts: "h264-ts"
};

// src/image-format.ts
var validVideoImageFormats = ["png", "jpeg", "none"];
var validStillImageFormats = ["png", "jpeg", "pdf", "webp"];

// src/jpeg-quality.ts
var DEFAULT_JPEG_QUALITY = 80;
var validateJpegQuality = (q) => {
  if (typeof q !== "undefined" && typeof q !== "number") {
    throw new Error(`JPEG Quality option must be a number or undefined. Got ${typeof q} (${JSON.stringify(q)})`);
  }
  if (typeof q === "undefined") {
    return;
  }
  if (!Number.isFinite(q)) {
    throw new RangeError(`JPEG Quality must be a finite number, but is ${q}`);
  }
  if (Number.isNaN(q)) {
    throw new RangeError(`JPEG Quality is NaN, but must be a real number`);
  }
  if (q > 100 || q < 0) {
    throw new RangeError("JPEG Quality option must be between 0 and 100.");
  }
};

// src/log-level.ts
var logLevels = ["trace", "verbose", "info", "warn", "error"];
var getNumberForLogLevel = (level) => {
  return logLevels.indexOf(level);
};
var isValidLogLevel = (level) => {
  return getNumberForLogLevel(level) > -1;
};

// src/options/api-key.tsx

var currentApiKey = null;
var cliFlag = "api-key";
var apiKeyOption = {
  name: "API key",
  cliFlag,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "API key for sending a usage event using ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "@remotion/licensing"
      }),
      "."
    ]
  }),
  ssrName: "apiKey",
  docLink: "https://www.remotion.dev/docs/licensing",
  type: null,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag]
      };
    }
    return {
      source: "default",
      value: currentApiKey
    };
  },
  setConfig: (value) => {
    currentApiKey = value;
  },
  id: cliFlag
};

// src/options/ask-ai.tsx

var askAIEnabled = true;
var cliFlag2 = "disable-ask-ai";
var askAIOption = {
  name: "Disable or Enable the Ask AI option",
  cliFlag: cliFlag2,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "If the Cmd + I shortcut of the Ask AI modal conflicts with your Studio, you can disable it using this."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config#setaskaienabled",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag2] !== undefined) {
      askAIEnabled = false;
      return {
        value: askAIEnabled,
        source: "cli"
      };
    }
    return {
      value: askAIEnabled,
      source: "config"
    };
  },
  setConfig(value) {
    askAIEnabled = value;
  },
  id: cliFlag2
};

// src/options/audio-bitrate.tsx

var cliFlag3 = "audio-bitrate";
var audioBitrate = null;
var audioBitrateOption = {
  name: "Audio Bitrate",
  cliFlag: cliFlag3,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Specify the target bitrate for the generated video. The syntax for FFmpeg",
      "'",
      "s ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "-b:a"
      }),
      " parameter should be used. FFmpeg may encode the video in a way that will not result in the exact audio bitrate specified. Example values: ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "512K"
      }),
      " for 512 kbps, ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "1M"
      }),
      " for 1 Mbps. Default: ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "320k"
      })
    ]
  }),
  ssrName: "audioBitrate",
  docLink: "https://www.remotion.dev/docs/renderer/render-media#audiobitrate-",
  type: "0",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag3]) {
      return {
        value: commandLine[cliFlag3],
        source: "cli"
      };
    }
    if (audioBitrate) {
      return {
        value: audioBitrate,
        source: "config file"
      };
    }
    return {
      value: null,
      source: "default"
    };
  },
  setConfig: (value) => {
    audioBitrate = value;
  },
  id: cliFlag3
};

// src/options/separate-audio.tsx
var DEFAULT = null;
var cliFlag4 = "separate-audio-to";
var separateAudioOption = {
  cliFlag: cliFlag4,
  description: () => `If set, the audio will not be included in the main output but rendered as a separate file at the location you pass. It is recommended to use an absolute path. If a relative path is passed, it is relative to the Remotion Root.`,
  docLink: "https://remotion.dev/docs/renderer/render-media",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag4]) {
      return {
        source: "cli",
        value: commandLine[cliFlag4]
      };
    }
    return {
      source: "default",
      value: DEFAULT
    };
  },
  name: "Separate audio to",
  setConfig: () => {
    throw new Error("Not implemented");
  },
  ssrName: "separateAudioTo",
  type: "string",
  id: cliFlag4
};

// src/options/audio-codec.tsx
var validAudioCodecs = ["pcm-16", "aac", "mp3", "opus"];
var supportedAudioCodecs = {
  h264: ["aac", "pcm-16", "mp3"],
  "h264-mkv": ["pcm-16", "mp3"],
  "h264-ts": ["pcm-16", "aac"],
  aac: ["aac", "pcm-16"],
  avi: [],
  gif: [],
  h265: ["aac", "pcm-16"],
  mp3: ["mp3", "pcm-16"],
  prores: ["aac", "pcm-16"],
  vp8: ["opus", "pcm-16"],
  vp9: ["opus", "pcm-16"],
  wav: ["pcm-16"]
};
var _satisfies = supportedAudioCodecs;
if (_satisfies) {}
var cliFlag5 = "audio-codec";
var ssrName = "audioCodec";
var defaultAudioCodecs = {
  "h264-mkv": {
    lossless: "pcm-16",
    compressed: "pcm-16"
  },
  "h264-ts": {
    lossless: "pcm-16",
    compressed: "aac"
  },
  aac: {
    lossless: "pcm-16",
    compressed: "aac"
  },
  gif: {
    lossless: null,
    compressed: null
  },
  h264: {
    lossless: "pcm-16",
    compressed: "aac"
  },
  h265: {
    lossless: "pcm-16",
    compressed: "aac"
  },
  mp3: {
    lossless: "pcm-16",
    compressed: "mp3"
  },
  prores: {
    lossless: "pcm-16",
    compressed: "pcm-16"
  },
  vp8: {
    lossless: "pcm-16",
    compressed: "opus"
  },
  vp9: {
    lossless: "pcm-16",
    compressed: "opus"
  },
  wav: {
    lossless: "pcm-16",
    compressed: "pcm-16"
  }
};
var extensionMap = {
  aac: "aac",
  mp3: "mp3",
  opus: "opus",
  "pcm-16": "wav"
};
var getExtensionFromAudioCodec = (audioCodec) => {
  if (extensionMap[audioCodec]) {
    return extensionMap[audioCodec];
  }
  throw new Error(`Unsupported audio codec: ${audioCodec}`);
};
var resolveAudioCodec = ({
  codec,
  setting,
  preferLossless,
  separateAudioTo
}) => {
  let derivedFromSeparateAudioToExtension = null;
  if (separateAudioTo) {
    const extension = separateAudioTo.split(".").pop();
    for (const [key, value] of Object.entries(extensionMap)) {
      if (value === extension) {
        derivedFromSeparateAudioToExtension = key;
        if (!supportedAudioCodecs[codec].includes(derivedFromSeparateAudioToExtension) && derivedFromSeparateAudioToExtension) {
          throw new Error(`The codec is ${codec} but the audio codec derived from --${separateAudioOption.cliFlag} is ${derivedFromSeparateAudioToExtension}. The only supported codecs are: ${supportedAudioCodecs[codec].join(", ")}`);
        }
      }
    }
  }
  if (preferLossless) {
    const selected = getDefaultAudioCodec({ codec, preferLossless });
    if (derivedFromSeparateAudioToExtension && selected !== derivedFromSeparateAudioToExtension) {
      throw new Error(`The audio codec derived from --${separateAudioOption.cliFlag} is ${derivedFromSeparateAudioToExtension}, but does not match the audio codec derived from the "Prefer lossless" option (${selected}). Remove any conflicting options.`);
    }
    return selected;
  }
  if (setting === null) {
    if (derivedFromSeparateAudioToExtension) {
      return derivedFromSeparateAudioToExtension;
    }
    return getDefaultAudioCodec({ codec, preferLossless });
  }
  if (derivedFromSeparateAudioToExtension !== setting && derivedFromSeparateAudioToExtension) {
    throw new Error(`The audio codec derived from --${separateAudioOption.cliFlag} is ${derivedFromSeparateAudioToExtension}, but does not match the audio codec derived from your ${audioCodecOption.name} setting (${setting}). Remove any conflicting options.`);
  }
  return setting;
};
var getDefaultAudioCodec = ({
  codec,
  preferLossless
}) => {
  return defaultAudioCodecs[codec][preferLossless ? "lossless" : "compressed"];
};
var _audioCodec = null;
var audioCodecOption = {
  cliFlag: cliFlag5,
  setConfig: (audioCodec) => {
    if (audioCodec === null) {
      _audioCodec = null;
      return;
    }
    if (!validAudioCodecs.includes(audioCodec)) {
      throw new Error(`Audio codec must be one of the following: ${validAudioCodecs.join(", ")}, but got ${audioCodec}`);
    }
    _audioCodec = audioCodec;
  },
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag5]) {
      const codec = commandLine[cliFlag5];
      if (!validAudioCodecs.includes(commandLine[cliFlag5])) {
        throw new Error(`Audio codec must be one of the following: ${validAudioCodecs.join(", ")}, but got ${codec}`);
      }
      return {
        source: "cli",
        value: commandLine[cliFlag5]
      };
    }
    if (_audioCodec !== null) {
      return {
        source: "config",
        value: _audioCodec
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  description: () => `Set the format of the audio that is embedded in the video. Not all codec and audio codec combinations are supported and certain combinations require a certain file extension and container format. See the table in the docs to see possible combinations.`,
  docLink: "https://www.remotion.dev/docs/encoding/#audio-codec",
  name: "Audio Codec",
  ssrName,
  type: "aac",
  id: cliFlag5
};

// src/options/beep-on-finish.tsx

var beepOnFinish = false;
var cliFlag6 = "beep-on-finish";
var beepOnFinishOption = {
  name: "Beep on finish",
  cliFlag: cliFlag6,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Whether the Remotion Studio tab should beep when the render is finished."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config#setbeeponfinish",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag6] !== undefined) {
      return {
        value: commandLine[cliFlag6],
        source: "cli"
      };
    }
    if (beepOnFinish !== false) {
      return {
        value: beepOnFinish,
        source: "config"
      };
    }
    return {
      value: false,
      source: "default"
    };
  },
  setConfig(value) {
    beepOnFinish = value;
  },
  id: cliFlag6
};

// src/options/binaries-directory.tsx

var cliFlag7 = "binaries-directory";
var currentDirectory = null;
var binariesDirectoryOption = {
  name: "Binaries Directory",
  cliFlag: cliFlag7,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "The directory where the platform-specific binaries and libraries that Remotion needs are located. Those include an ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "ffmpeg"
      }),
      " and",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "ffprobe"
      }),
      " binary, a Rust binary for various tasks, and various shared libraries. If the value is set to ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "null"
      }),
      ", which is the default, then the path of a platform-specific package located at",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "node_modules/@remotion/compositor-*"
      }),
      " is selected.",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      "This option is useful in environments where Remotion is not officially supported to run like bundled serverless functions or Electron."
    ]
  }),
  ssrName: "binariesDirectory",
  docLink: "https://www.remotion.dev/docs/renderer",
  type: "",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag7] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag7]
      };
    }
    if (currentDirectory !== null) {
      return {
        source: "config",
        value: currentDirectory
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value) => {
    currentDirectory = value;
  },
  id: cliFlag7
};

// src/options/browser.tsx

var cliFlag8 = "browser";
var browserOption = {
  name: "Browser",
  cliFlag: cliFlag8,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Specify the browser which should be used for opening a tab. The default browser will be used by default. Pass an absolute path or",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: '"chrome"'
      }),
      " to use Chrome. If Chrome is selected as the browser and you are on macOS, Remotion will try to reuse an existing tab."
    ]
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/cli/studio#--browser",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag8] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag8]
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: () => {
    throw new Error("setBrowser is not supported. Pass --browser via the CLI instead.");
  },
  type: "",
  id: cliFlag8
};

// src/options/browser-executable.tsx

var currentBrowserExecutablePath = null;
var cliFlag9 = "browser-executable";
var browserExecutableOption = {
  name: "Browser executable",
  cliFlag: cliFlag9,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Set a custom Chrome or Chromium executable path. By default Remotion will try to find an existing version of Chrome on your system and if not found, it will download one. This flag is useful if you don't have Chrome installed in a standard location and you want to prevent downloading an additional browser or need support for the H264 codec."
  }),
  ssrName: "browserExecutable",
  docLink: "https://www.remotion.dev/docs/config#setbrowserexecutable",
  type: null,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag9] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag9]
      };
    }
    if (currentBrowserExecutablePath !== null) {
      return {
        source: "config",
        value: currentBrowserExecutablePath
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value) => {
    currentBrowserExecutablePath = value;
  },
  id: cliFlag9
};

// src/options/bundle-cache.tsx

var cliFlag10 = "bundle-cache";
var cachingEnabled = true;
var bundleCacheOption = {
  name: "Webpack Bundle Caching",
  cliFlag: cliFlag10,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Enable or disable Webpack caching. This flag is enabled by default, use",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "--bundle-cache=false"
      }),
      " to disable caching."
    ]
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config#setcachingenabled",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag10] !== undefined && commandLine[cliFlag10] !== null) {
      return {
        source: "cli",
        value: Boolean(commandLine[cliFlag10])
      };
    }
    return {
      source: cachingEnabled ? "default" : "config",
      value: cachingEnabled
    };
  },
  setConfig: (value) => {
    if (typeof value !== "boolean") {
      throw new TypeError(`Value for "${cliFlag10}" must be a boolean, but got ${typeof value}.`);
    }
    cachingEnabled = value;
  },
  type: true,
  id: cliFlag10
};

// src/options/chrome-mode.tsx

var validChromeModeOptions = [
  "headless-shell",
  "chrome-for-testing"
];
var cliFlag11 = "chrome-mode";
var configSelection = null;
var chromeModeOption = {
  cliFlag: cliFlag11,
  name: "Chrome Mode",
  ssrName: "chromeMode",
  description: () => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
      children: [
        "One of",
        " ",
        validChromeModeOptions.map((option, i) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("code", {
          children: [
            option,
            i === validChromeModeOptions.length - 1 ? "" : ", "
          ]
        }, option)),
        ". Default ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "headless-shell"
        }),
        ".",
        " ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("a", {
          href: "https://remotion.dev/docs/miscellaneous/chrome-headless-shell",
          children: [
            "Use ",
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
              children: "chrome-for-testing"
            }),
            " to take advantage of GPU drivers on Linux."
          ]
        })
      ]
    });
  },
  docLink: "https://www.remotion.dev/chrome-for-testing",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag11]) {
      if (!validChromeModeOptions.includes(commandLine[cliFlag11])) {
        throw new Error(`Invalid \`--${cliFlag11}\` value passed. Accepted values: ${validChromeModeOptions.map((l) => `'${l}'`).join(", ")}.`);
      }
      return {
        value: commandLine[cliFlag11],
        source: "cli"
      };
    }
    if (configSelection !== null) {
      return {
        value: configSelection,
        source: "config"
      };
    }
    return {
      value: "headless-shell",
      source: "default"
    };
  },
  setConfig: (newChromeMode) => {
    configSelection = newChromeMode;
  },
  type: "headless-shell",
  id: cliFlag11
};

// src/options/color-space.tsx


var validV4ColorSpaces = ["default", "bt601", "bt709", "bt2020-ncl"];
var validV5ColorSpaces = ["bt601", "bt709", "bt2020-ncl"];
var validColorSpaces = remotion_no_react__WEBPACK_IMPORTED_MODULE_0__.NoReactInternals.ENABLE_V5_BREAKING_CHANGES ? validV5ColorSpaces : validV4ColorSpaces;
var DEFAULT_COLOR_SPACE = remotion_no_react__WEBPACK_IMPORTED_MODULE_0__.NoReactInternals.ENABLE_V5_BREAKING_CHANGES ? "bt709" : "default";
var colorSpace = DEFAULT_COLOR_SPACE;
var cliFlag12 = "color-space";
var colorSpaceOption = {
  name: "Color space",
  cliFlag: "color-space",
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Color space to use for the video. Acceptable values:",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("code", {
        children: [
          '"',
          DEFAULT_COLOR_SPACE,
          '"'
        ]
      }),
      "(default since 5.0),",
      " ",
      remotion_no_react__WEBPACK_IMPORTED_MODULE_0__.NoReactInternals.ENABLE_V5_BREAKING_CHANGES ? /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("code", {
        children: [
          '"',
          "bt601",
          '"',
          ", "
        ]
      }) : /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("code", {
            children: [
              '"',
              "bt601",
              '"'
            ]
          }),
          " ",
          "(same as",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("code", {
            children: [
              '"',
              "default",
              '"'
            ]
          }),
          ", since v4.0.424),",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("code", {
            children: [
              '"',
              "bt709",
              '"'
            ]
          }),
          " ",
          "(since v4.0.28),",
          " "
        ]
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("code", {
        children: [
          '"',
          "bt2020-ncl",
          '"'
        ]
      }),
      " ",
      "(since v4.0.88),",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("code", {
        children: [
          '"',
          "bt2020-cl",
          '"'
        ]
      }),
      " ",
      "(since v4.0.88), .",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      "For best color accuracy, it is recommended to also use",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("code", {
        children: [
          '"',
          "png",
          '"'
        ]
      }),
      " ",
      "as the image format to have accurate color transformations throughout.",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      "Only since v4.0.83, colorspace conversion is actually performed, previously it would only tag the metadata of the video."
    ]
  }),
  docLink: "https://www.remotion.dev/docs/renderer/render-media#colorspace",
  ssrName: "colorSpace",
  type: DEFAULT_COLOR_SPACE,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag12] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag12]
      };
    }
    if (colorSpace !== DEFAULT_COLOR_SPACE) {
      return {
        source: "config",
        value: colorSpace
      };
    }
    return {
      source: "default",
      value: DEFAULT_COLOR_SPACE
    };
  },
  setConfig: (value) => {
    colorSpace = value ?? DEFAULT_COLOR_SPACE;
  },
  id: cliFlag12
};

// src/options/concurrency.tsx

var currentConcurrency = null;
var cliFlag13 = "concurrency";
var validateConcurrencyValue = (value, setting) => {
  if (typeof value === "undefined" || value === null) {
    return;
  }
  if (typeof value !== "number" && typeof value !== "string") {
    throw new Error(setting + " must a number or a string but is " + value);
  }
  if (typeof value === "number") {
    if (value % 1 !== 0) {
      throw new Error(setting + " must be an integer, but is " + value);
    }
  } else if (!/^\d+(\.\d+)?%$/.test(value)) {
    throw new Error(`${setting} must be a number or percentage, but is ${JSON.stringify(value)}`);
  }
};
var concurrencyOption = {
  name: "Concurrency",
  cliFlag: cliFlag13,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "How many CPU threads to use. Minimum 1. The maximum is the amount of threads you have (In Node.JS ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "os.cpus().length"
      }),
      "). You can also provide a percentage value (e.g. ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "50%"
      }),
      ")."
    ]
  }),
  ssrName: "concurrency",
  docLink: "https://www.remotion.dev/docs/config#setconcurrency",
  type: null,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag13] !== undefined) {
      const value = commandLine[cliFlag13];
      validateConcurrencyValue(value, "concurrency");
      return {
        source: "cli",
        value
      };
    }
    if (currentConcurrency !== null) {
      return {
        source: "config",
        value: currentConcurrency
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value) => {
    validateConcurrencyValue(value, "Config.setConcurrency");
    currentConcurrency = value;
  },
  id: cliFlag13
};

// src/options/config.tsx

var cliFlag14 = "config";
var configOption = {
  name: "Config file",
  cliFlag: cliFlag14,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Specify a location for the Remotion config file."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag14] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag14]
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: () => {
    throw new Error("setConfig is not supported. Pass --config via the CLI instead.");
  },
  type: "",
  id: cliFlag14
};

// src/options/crf.tsx

var currentCrf;
var validateCrf = (newCrf) => {
  if (typeof newCrf !== "number" && newCrf !== undefined) {
    throw new TypeError("The CRF must be a number or undefined.");
  }
};
var cliFlag15 = "crf";
var crfOption = {
  name: "CRF",
  cliFlag: cliFlag15,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "No matter which codec you end up using, there's always a tradeoff between file size and video quality. You can control it by setting the CRF (Constant Rate Factor). The lower the number, the better the quality, the higher the number, the smaller the file is – of course at the cost of quality."
  }),
  ssrName: "crf",
  docLink: "https://www.remotion.dev/docs/encoding/#controlling-quality-using-the-crf-setting",
  type: 0,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag15] !== undefined) {
      validateCrf(commandLine[cliFlag15]);
      return {
        source: "cli",
        value: commandLine[cliFlag15]
      };
    }
    if (currentCrf !== null) {
      return {
        source: "config",
        value: currentCrf
      };
    }
    return {
      source: "default",
      value: undefined
    };
  },
  setConfig: (crf) => {
    validateCrf(crf);
    currentCrf = crf;
  },
  id: cliFlag15
};

// src/options/cross-site-isolation.tsx

var enableCrossSiteIsolation = false;
var cliFlag16 = "cross-site-isolation";
var enableCrossSiteIsolationOption = {
  name: "Enable Cross-Site Isolation",
  cliFlag: cliFlag16,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Enable Cross-Site Isolation in the Studio (sets Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy HTTP headers, required for",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "@remotion/whisper-web"
      }),
      ")."
    ]
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config#setenablecrosssiteisolation",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag16] !== undefined) {
      return {
        value: commandLine[cliFlag16],
        source: "cli"
      };
    }
    return {
      value: enableCrossSiteIsolation,
      source: "config"
    };
  },
  setConfig(value) {
    enableCrossSiteIsolation = value;
  },
  id: cliFlag16
};

// src/options/dark-mode.tsx

var DEFAULT_VALUE = false;
var darkMode = DEFAULT_VALUE;
var cliFlag17 = "dark-mode";
var darkModeOption = {
  name: "Dark Mode",
  cliFlag: cliFlag17,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Whether Chromium should pretend to be in dark mode by emulating the media feature 'prefers-color-scheme: dark'. Default is",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: String(DEFAULT_VALUE)
      }),
      "."
    ]
  }),
  ssrName: "darkMode",
  docLink: "https://www.remotion.dev/docs/chromium-flags#--dark-mode",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag17] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag17]
      };
    }
    if (darkMode !== DEFAULT_VALUE) {
      return {
        source: "config",
        value: darkMode
      };
    }
    return {
      source: "default",
      value: DEFAULT_VALUE
    };
  },
  setConfig: (value) => {
    darkMode = value;
  },
  id: cliFlag17
};

// src/options/delete-after.tsx

var cliFlag18 = "delete-after";
var deleteAfter = null;
var deleteAfterOption = {
  name: "Lambda render expiration",
  cliFlag: cliFlag18,
  description: () => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
      children: [
        "Automatically delete the render after a certain period. Accepted values are ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "1-day"
        }),
        ", ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "3-days"
        }),
        ", ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "7-days"
        }),
        " and",
        " ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "30-days"
        }),
        ".",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
        " For this to work, your bucket needs to have",
        " ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
          href: "/docs/lambda/autodelete",
          children: "lifecycles enabled"
        }),
        "."
      ]
    });
  },
  ssrName: "deleteAfter",
  docLink: "https://www.remotion.dev/docs/lambda/autodelete",
  type: "1-day",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag18] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag18]
      };
    }
    if (deleteAfter !== null) {
      return {
        source: "config",
        value: deleteAfter
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value) => {
    deleteAfter = value;
  },
  id: cliFlag18
};

// src/options/disable-git-source.tsx
var DEFAULT2 = false;
var cliFlag19 = "disable-git-source";
var disableGitSourceOption = {
  cliFlag: cliFlag19,
  description: () => `Disables the Git Source being connected to the Remotion Studio. Clicking on stack traces and certain menu items will be disabled.`,
  docLink: "https://remotion.dev/docs/bundle",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag19]) {
      return {
        source: "cli",
        value: commandLine[cliFlag19]
      };
    }
    return {
      source: "default",
      value: DEFAULT2
    };
  },
  name: "Disable Git source",
  setConfig: () => {
    throw new Error("Not implemented");
  },
  ssrName: "disableGitSource",
  type: false,
  id: cliFlag19
};

// src/options/disable-web-security.tsx

var disableWebSecurity = false;
var cliFlag20 = "disable-web-security";
var disableWebSecurityOption = {
  name: "Disable web security",
  cliFlag: cliFlag20,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "This will most notably disable CORS in Chrome among other security features."
  }),
  ssrName: "disableWebSecurity",
  docLink: "https://www.remotion.dev/docs/chromium-flags#--disable-web-security",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag20] !== undefined) {
      return {
        source: "cli",
        value: Boolean(commandLine[cliFlag20])
      };
    }
    if (disableWebSecurity) {
      return {
        source: "config",
        value: disableWebSecurity
      };
    }
    return {
      source: "default",
      value: false
    };
  },
  setConfig: (value) => {
    disableWebSecurity = value;
  },
  id: cliFlag20
};

// src/options/disallow-parallel-encoding.tsx

var disallowParallelEncoding = false;
var cliFlag21 = "disallow-parallel-encoding";
var disallowParallelEncodingOption = {
  name: "Disallow parallel encoding",
  cliFlag: cliFlag21,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Disallows the renderer from doing rendering frames and encoding at the same time. This makes the rendering process more memory-efficient, but possibly slower."
  }),
  ssrName: "disallowParallelEncoding",
  docLink: "https://www.remotion.dev/docs/config#setdisallowparallelencoding",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag21] !== undefined) {
      return {
        value: commandLine[cliFlag21],
        source: "cli"
      };
    }
    if (disallowParallelEncoding !== false) {
      return {
        value: disallowParallelEncoding,
        source: "config"
      };
    }
    return {
      value: false,
      source: "default"
    };
  },
  setConfig(value) {
    disallowParallelEncoding = value;
  },
  id: cliFlag21
};

// src/options/enable-lambda-insights.tsx

var cliFlag22 = "enable-lambda-insights";
var option = false;
var enableLambdaInsights = {
  name: "Enable Lambda Insights",
  cliFlag: cliFlag22,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Enable",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
        href: "https://remotion.dev/docs/lambda/insights",
        children: "Lambda Insights in AWS CloudWatch"
      }),
      ". For this to work, you may have to update your role permission."
    ]
  }),
  ssrName: "enableLambdaInsights",
  docLink: "https://www.remotion.dev/docs/lambda/insights",
  type: false,
  setConfig: (value) => {
    option = value;
  },
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag22] !== undefined) {
      return {
        value: commandLine[cliFlag22],
        source: "cli"
      };
    }
    if (option) {
      return {
        value: option,
        source: "config"
      };
    }
    return {
      value: false,
      source: "default"
    };
  },
  id: cliFlag22
};

// src/options/enable-multiprocess-on-linux.tsx

var DEFAULT_VALUE2 = true;
var multiProcessOnLinux = DEFAULT_VALUE2;
var cliFlag23 = "enable-multiprocess-on-linux";
var enableMultiprocessOnLinuxOption = {
  name: "Enable Multiprocess on Linux",
  cliFlag: cliFlag23,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Removes the ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "--single-process"
      }),
      " flag that gets passed to Chromium on Linux by default. This will make the render faster because multiple processes can be used, but may cause issues with some Linux distributions or if window server libraries are missing.",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      "Default: ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "false"
      }),
      " until v4.0.136, then ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "true"
      }),
      " from v4.0.137 on because newer Chrome versions ",
      "don't",
      " allow rendering with the ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "--single-process"
      }),
      " flag. ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      "This flag will be removed in Remotion v5.0."
    ]
  }),
  ssrName: "chromiumOptions.enableMultiprocessOnLinux",
  docLink: "https://www.remotion.dev/docs/chromium-flags",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag23] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag23]
      };
    }
    if (multiProcessOnLinux !== false) {
      return {
        source: "config",
        value: multiProcessOnLinux
      };
    }
    return {
      source: "default",
      value: DEFAULT_VALUE2
    };
  },
  setConfig: (value) => {
    multiProcessOnLinux = value;
  },
  id: cliFlag23
};

// src/options/encoding-buffer-size.tsx

var encodingBufferSize = null;
var setEncodingBufferSize = (bitrate) => {
  encodingBufferSize = bitrate;
};
var cliFlag24 = "buffer-size";
var encodingBufferSizeOption = {
  name: "FFmpeg -bufsize flag",
  cliFlag: cliFlag24,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "The value for the ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "-bufsize"
      }),
      " flag of FFmpeg. Should be used in conjunction with the encoding max rate flag."
    ]
  }),
  ssrName: "encodingBufferSize",
  docLink: "https://www.remotion.dev/docs/renderer/render-media#encodingbuffersize",
  type: "",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag24] !== undefined) {
      return {
        value: commandLine[cliFlag24],
        source: "cli"
      };
    }
    if (encodingBufferSize !== null) {
      return {
        value: encodingBufferSize,
        source: "config"
      };
    }
    return {
      value: null,
      source: "default"
    };
  },
  setConfig: setEncodingBufferSize,
  id: cliFlag24
};

// src/options/encoding-max-rate.tsx

var encodingMaxRate = null;
var cliFlag25 = "max-rate";
var encodingMaxRateOption = {
  name: "FFmpeg -maxrate flag",
  cliFlag: cliFlag25,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "The value for the ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "-maxrate"
      }),
      " flag of FFmpeg. Should be used in conjunction with the encoding buffer size flag."
    ]
  }),
  ssrName: "encodingMaxRate",
  docLink: "https://www.remotion.dev/docs/renderer/render-media#encodingmaxrate",
  type: "",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag25] !== undefined) {
      return {
        value: commandLine[cliFlag25],
        source: "cli"
      };
    }
    if (encodingMaxRate !== null) {
      return {
        value: encodingMaxRate,
        source: "config"
      };
    }
    return {
      value: null,
      source: "default"
    };
  },
  setConfig: (newMaxRate) => {
    encodingMaxRate = newMaxRate;
  },
  id: cliFlag25
};

// src/options/enforce-audio.tsx

var DEFAULT_ENFORCE_AUDIO_TRACK = false;
var enforceAudioTrackState = DEFAULT_ENFORCE_AUDIO_TRACK;
var cliFlag26 = "enforce-audio-track";
var enforceAudioOption = {
  name: "Enforce Audio Track",
  cliFlag: cliFlag26,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Render a silent audio track if there would be none otherwise."
  }),
  ssrName: "enforceAudioTrack",
  docLink: "https://www.remotion.dev/docs/config#setenforceaudiotrack-",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag26]) {
      return {
        source: "cli",
        value: true
      };
    }
    if (enforceAudioTrackState !== DEFAULT_ENFORCE_AUDIO_TRACK) {
      return {
        source: "config",
        value: enforceAudioTrackState
      };
    }
    return {
      source: "default",
      value: DEFAULT_ENFORCE_AUDIO_TRACK
    };
  },
  setConfig: (value) => {
    enforceAudioTrackState = value;
  },
  id: cliFlag26
};

// src/options/env-file.tsx

var cliFlag27 = "env-file";
var envFileLocation = null;
var envFileOption = {
  name: "Env File",
  cliFlag: cliFlag27,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Specify a location for a dotenv file. Default ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: ".env"
      }),
      "."
    ]
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/cli/render#--env-file",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag27] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag27]
      };
    }
    if (envFileLocation !== null) {
      return {
        source: "config",
        value: envFileLocation
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value) => {
    envFileLocation = value;
  },
  type: "",
  id: cliFlag27
};

// src/options/every-nth-frame.tsx

var DEFAULT_EVERY_NTH_FRAME = 1;
var everyNthFrame = DEFAULT_EVERY_NTH_FRAME;
var cliFlag28 = "every-nth-frame";
var everyNthFrameOption = {
  name: "Every nth frame",
  cliFlag: cliFlag28,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "This option may only be set when rendering GIFs. It determines how many frames are rendered, while the other ones get skipped in order to lower the FPS of the GIF. For example, if the ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "fps"
      }),
      " is 30, and",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "everyNthFrame"
      }),
      " is 2, the FPS of the GIF is ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "15"
      }),
      "."
    ]
  }),
  ssrName: "everyNthFrame",
  docLink: "https://www.remotion.dev/docs/config#seteverynthframe",
  type: DEFAULT_EVERY_NTH_FRAME,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag28] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag28]
      };
    }
    if (everyNthFrame !== DEFAULT_EVERY_NTH_FRAME) {
      return {
        source: "config",
        value: everyNthFrame
      };
    }
    return {
      source: "default",
      value: DEFAULT_EVERY_NTH_FRAME
    };
  },
  setConfig: (value) => {
    everyNthFrame = value;
  },
  id: cliFlag28
};

// src/options/experimental-client-side-rendering.tsx

var experimentalClientSideRenderingEnabled = false;
var cliFlag29 = "enable-experimental-client-side-rendering";
var experimentalClientSideRenderingOption = {
  name: "Enable Experimental Client-Side Rendering",
  cliFlag: cliFlag29,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Enable WIP client-side rendering in the Remotion Studio. See https://www.remotion.dev/docs/client-side-rendering/ for notes."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/client-side-rendering",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag29] !== null) {
      return {
        value: commandLine[cliFlag29],
        source: "cli"
      };
    }
    return {
      value: experimentalClientSideRenderingEnabled,
      source: "config"
    };
  },
  setConfig(value) {
    experimentalClientSideRenderingEnabled = value;
  },
  id: cliFlag29
};

// src/options/experimental-visual-mode.tsx

var experimentalVisualModeEnabled = false;
var cliFlag30 = "experimental-visual-mode";
var experimentalVisualModeOption = {
  name: "Experimental Visual Mode",
  cliFlag: cliFlag30,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Nothing here yet, but this is our playground for experiments."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config#setexperimentalvisualmode",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag30] !== null) {
      return {
        value: commandLine[cliFlag30],
        source: "cli"
      };
    }
    return {
      value: experimentalVisualModeEnabled,
      source: "config"
    };
  },
  setConfig(value) {
    experimentalVisualModeEnabled = value;
  },
  id: cliFlag30
};

// src/options/folder-expiry.tsx

var enableFolderExpiry = null;
var cliFlag31 = "enable-folder-expiry";
var folderExpiryOption = {
  name: "Lambda render expiration",
  cliFlag: cliFlag31,
  description: () => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
      children: [
        "When deploying sites, enable or disable S3 Lifecycle policies which allow for renders to auto-delete after a certain time. Default is",
        " ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "null"
        }),
        ", which does not change any lifecycle policies of the S3 bucket. See: ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
          href: "/docs/lambda/autodelete",
          children: "Lambda autodelete"
        }),
        "."
      ]
    });
  },
  ssrName: "enableFolderExpiry",
  docLink: "https://www.remotion.dev/docs/lambda/autodelete",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag31] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag31]
      };
    }
    if (enableFolderExpiry !== null) {
      return {
        source: "config",
        value: enableFolderExpiry
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value) => {
    enableFolderExpiry = value;
  },
  id: cliFlag31
};

// src/options/for-seamless-aac-concatenation.tsx

var DEFAULT3 = false;
var forSeamlessAacConcatenation = DEFAULT3;
var cliFlag32 = "for-seamless-aac-concatenation";
var forSeamlessAacConcatenationOption = {
  name: "For seamless AAC concatenation",
  cliFlag: cliFlag32,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "If enabled, the audio is trimmed to the nearest AAC frame, which is required for seamless concatenation of AAC files. This is a requirement if you later want to combine multiple video snippets seamlessly.",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      " This option is used internally. There is currently no documentation yet for to concatenate the audio chunks."
    ]
  }),
  docLink: "https://remotion.dev/docs/renderer",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag32]) {
      return {
        source: "cli",
        value: true
      };
    }
    if (forSeamlessAacConcatenation !== DEFAULT3) {
      return {
        source: "config",
        value: forSeamlessAacConcatenation
      };
    }
    return {
      source: "default",
      value: DEFAULT3
    };
  },
  setConfig: (value) => {
    forSeamlessAacConcatenation = value;
  },
  ssrName: "forSeamlessAacConcatenation",
  type: false,
  id: cliFlag32
};

// src/options/force-new-studio.tsx

var forceNewEnabled = false;
var cliFlag33 = "force-new";
var forceNewStudioOption = {
  name: "Force New Studio",
  cliFlag: cliFlag33,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Forces starting a new Studio instance even if one is already running on the same port for the same project."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config#setforcenewstudioenabled",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag33] !== undefined) {
      return {
        value: commandLine[cliFlag33],
        source: "cli"
      };
    }
    return {
      value: forceNewEnabled,
      source: "config"
    };
  },
  setConfig(value) {
    forceNewEnabled = value;
  },
  id: cliFlag33
};

// src/frame-range.ts
var validateFrameRange = (frameRange) => {
  if (frameRange === null) {
    return;
  }
  if (typeof frameRange === "number") {
    if (frameRange < 0) {
      throw new TypeError("Frame must be a non-negative number, got " + frameRange);
    }
    if (!Number.isFinite(frameRange)) {
      throw new TypeError("Frame must be a finite number, got " + frameRange);
    }
    if (!Number.isInteger(frameRange)) {
      throw new Error(`Frame must be an integer, but got a float (${frameRange})`);
    }
    return;
  }
  if (Array.isArray(frameRange)) {
    if (frameRange.length !== 2) {
      throw new TypeError("Frame range must be a tuple, got an array with length " + frameRange.length);
    }
    const [first, second] = frameRange;
    if (typeof first !== "number") {
      throw new Error(`The first value of frame range must be a number, but got ${typeof first} (${JSON.stringify(first)})`);
    }
    if (!Number.isFinite(first)) {
      throw new TypeError("The first value of frame range must be finite, but got " + first);
    }
    if (!Number.isInteger(first)) {
      throw new Error(`The first value of frame range must be an integer, but got a float (${first})`);
    }
    if (first < 0) {
      throw new Error(`The first value of frame range must be non-negative, but got ${first}`);
    }
    if (second === null) {
      return;
    }
    if (typeof second !== "number") {
      throw new Error(`The second value of frame range must be a number or null, but got ${typeof second} (${JSON.stringify(second)})`);
    }
    if (!Number.isFinite(second)) {
      throw new TypeError("The second value of frame range must be finite, but got " + second);
    }
    if (!Number.isInteger(second)) {
      throw new Error(`The second value of frame range must be an integer, but got a float (${second})`);
    }
    if (second < 0) {
      throw new Error(`The second value of frame range must be non-negative, but got ${second}`);
    }
    if (second < first) {
      throw new Error("The second value of frame range must be not smaller than the first one, but got " + frameRange.join("-"));
    }
    return;
  }
  throw new TypeError("Frame range must be a number or a tuple of numbers, but got object of type " + typeof frameRange);
};

// src/options/frames.tsx

var cliFlag34 = "frames";
var frameRange = null;
var parseFrameRangeFromCli = (newFrameRange) => {
  if (typeof newFrameRange === "number") {
    if (newFrameRange < 0) {
      return [0, Math.abs(newFrameRange)];
    }
    return newFrameRange;
  }
  if (typeof newFrameRange === "string") {
    if (newFrameRange.trim() === "") {
      throw new Error("--frames flag must be a single number, or 2 numbers separated by `-`");
    }
    const parts = newFrameRange.split("-");
    if (parts.length > 2 || parts.length <= 0) {
      throw new Error(`--frames flag must be a number or 2 numbers separated by '-', instead got ${parts.length} numbers`);
    }
    if (parts.length === 1) {
      const value = Number(parts[0]);
      if (isNaN(value)) {
        throw new Error("--frames flag must be a single number, or 2 numbers separated by `-`");
      }
      return value;
    }
    const [firstPart, secondPart] = parts;
    if (secondPart === "" && firstPart !== "") {
      const start = Number(firstPart);
      if (isNaN(start)) {
        throw new Error("--frames flag must be a single number, or 2 numbers separated by `-`");
      }
      return [start, null];
    }
    const parsed = parts.map((f) => Number(f));
    const [first, second] = parsed;
    for (const value of parsed) {
      if (isNaN(value)) {
        throw new Error("--frames flag must be a single number, or 2 numbers separated by `-`");
      }
    }
    if (second < first) {
      throw new Error("The second number of the --frames flag number should be greater or equal than first number");
    }
    return [first, second];
  }
  throw new Error("--frames flag must be a single number, or 2 numbers separated by `-`");
};
var framesOption = {
  name: "Frame Range",
  cliFlag: cliFlag34,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Render a subset of a video. Pass a single number to render a still, or a range (e.g. ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "0-9"
      }),
      ") to render a subset of frames. Pass",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "100-"
      }),
      " to render from frame 100 to the end."
    ]
  }),
  ssrName: "frameRange",
  docLink: "https://www.remotion.dev/docs/config#setframerange",
  type: null,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag34] !== undefined) {
      const value = parseFrameRangeFromCli(commandLine[cliFlag34]);
      validateFrameRange(value);
      return {
        source: "cli",
        value
      };
    }
    return {
      source: "config",
      value: frameRange
    };
  },
  setConfig: (value) => {
    if (value !== null) {
      validateFrameRange(value);
    }
    frameRange = value;
  },
  id: cliFlag34
};

// src/options/gl.tsx

var validOpenGlRenderers = [
  "swangle",
  "angle",
  "egl",
  "swiftshader",
  "vulkan",
  "angle-egl"
];
var DEFAULT_OPENGL_RENDERER = null;
var openGlRenderer = DEFAULT_OPENGL_RENDERER;
var AngleChangelog = () => {
  return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("details", {
    style: { fontSize: "0.9em", marginBottom: "1em" },
    children: [
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("summary", {
        children: "Changelog"
      }),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("ul", {
        children: [
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("li", {
            children: [
              "From Remotion v2.6.7 until v3.0.7, the default for Remotion Lambda was",
              " ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
                children: "swiftshader"
              }),
              ", but from v3.0.8 the default is",
              " ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
                children: "swangle"
              }),
              " (Swiftshader on Angle) since Chrome 101 added support for it."
            ]
          }),
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("li", {
            children: [
              "From Remotion v2.4.3 until v2.6.6, the default was ",
              /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
                children: "angle"
              }),
              ", however it turns out to have a small memory leak that could crash long Remotion renders."
            ]
          })
        ]
      })
    ]
  });
};
var cliFlag35 = "gl";
var glOption = {
  cliFlag: cliFlag35,
  docLink: "https://www.remotion.dev/docs/chromium-flags#--gl",
  name: "OpenGL renderer",
  type: "angle",
  ssrName: "gl",
  description: () => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
      children: [
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(AngleChangelog, {}),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("p", {
          children: [
            "Select the OpenGL renderer backend for Chromium. ",
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
            "Accepted values:"
          ]
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("ul", {
          children: [
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("li", {
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
                children: '"angle"'
              })
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("li", {
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
                children: '"egl"'
              })
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("li", {
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
                children: '"swiftshader"'
              })
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("li", {
              children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
                children: '"swangle"'
              })
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("li", {
              children: [
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
                  children: '"vulkan"'
                }),
                " (",
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("em", {
                  children: "from Remotion v4.0.41"
                }),
                ")"
              ]
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("li", {
              children: [
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
                  children: '"angle-egl"'
                }),
                " (",
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("em", {
                  children: "from Remotion v4.0.51"
                }),
                ")"
              ]
            })
          ]
        }),
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("p", {
          children: [
            "The default is ",
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
              children: "null"
            }),
            ", letting Chrome decide, except on Lambda where the default is ",
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
              children: '"swangle"'
            })
          ]
        })
      ]
    });
  },
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag35]) {
      validateOpenGlRenderer(commandLine[cliFlag35]);
      return {
        value: commandLine[cliFlag35],
        source: "cli"
      };
    }
    if (openGlRenderer !== DEFAULT_OPENGL_RENDERER) {
      return {
        value: openGlRenderer,
        source: "config"
      };
    }
    return {
      value: DEFAULT_OPENGL_RENDERER,
      source: "default"
    };
  },
  setConfig: (value) => {
    validateOpenGlRenderer(value);
    openGlRenderer = value;
  },
  id: cliFlag35
};
var validateOpenGlRenderer = (option2) => {
  if (option2 === null) {
    return null;
  }
  if (!validOpenGlRenderers.includes(option2)) {
    throw new TypeError(`${option2} is not a valid GL backend. Accepted values: ${validOpenGlRenderers.join(", ")}`);
  }
  return option2;
};

// src/options/hardware-acceleration.tsx
var hardwareAccelerationOptions = [
  "disable",
  "if-possible",
  "required"
];
var cliFlag36 = "hardware-acceleration";
var currentValue = null;
var hardwareAccelerationOption = {
  name: "Hardware Acceleration",
  cliFlag: cliFlag36,
  description: () => `
			One of
			${new Intl.ListFormat("en", { type: "disjunction" }).format(hardwareAccelerationOptions.map((a) => JSON.stringify(a)))}
			. Default "disable". Encode using a hardware-accelerated encoder if
			available. If set to "required" and no hardware-accelerated encoder is
			available, then the render will fail.
		`,
  ssrName: "hardwareAcceleration",
  docLink: "https://www.remotion.dev/docs/encoding",
  type: "disable",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag36] !== undefined) {
      const value = commandLine[cliFlag36];
      if (!hardwareAccelerationOptions.includes(value)) {
        throw new Error(`Invalid value for --${cliFlag36}: ${value}`);
      }
      return {
        source: "cli",
        value
      };
    }
    if (currentValue !== null) {
      return {
        source: "config",
        value: currentValue
      };
    }
    return {
      source: "default",
      value: "disable"
    };
  },
  setConfig: (value) => {
    if (!hardwareAccelerationOptions.includes(value)) {
      throw new Error(`Invalid value for --${cliFlag36}: ${value}`);
    }
    currentValue = value;
  },
  id: cliFlag36
};

// src/options/headless.tsx

var DEFAULT4 = true;
var headlessMode = DEFAULT4;
var cliFlag37 = "disable-headless";
var headlessOption = {
  name: "Disable Headless Mode",
  cliFlag: cliFlag37,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Deprecated - will be removed in 5.0.0. With the migration to",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
        href: "/docs/miscellaneous/chrome-headless-shell",
        children: "Chrome Headless Shell"
      }),
      ", this option is not functional anymore.",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      " If disabled, the render will open an actual Chrome window where you can see the render happen. The default is headless mode."
    ]
  }),
  ssrName: "headless",
  docLink: "https://www.remotion.dev/docs/chromium-flags#--disable-headless",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag37] !== undefined) {
      return {
        source: "cli",
        value: !commandLine[cliFlag37]
      };
    }
    if (headlessMode !== DEFAULT4) {
      return {
        source: "config",
        value: headlessMode
      };
    }
    return {
      source: "default",
      value: headlessMode
    };
  },
  setConfig: (value) => {
    headlessMode = value;
  },
  id: cliFlag37
};

// src/options/ignore-certificate-errors.tsx

var ignoreCertificateErrors = false;
var cliFlag38 = "ignore-certificate-errors";
var ignoreCertificateErrorsOption = {
  name: "Ignore certificate errors",
  cliFlag: cliFlag38,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Results in invalid SSL certificates in Chrome, such as self-signed ones, being ignored."
  }),
  ssrName: "ignoreCertificateErrors",
  docLink: "https://www.remotion.dev/docs/chromium-flags#--ignore-certificate-errors",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag38] !== undefined) {
      return {
        source: "cli",
        value: Boolean(commandLine[cliFlag38])
      };
    }
    if (ignoreCertificateErrors) {
      return {
        source: "config",
        value: ignoreCertificateErrors
      };
    }
    return {
      source: "default",
      value: false
    };
  },
  setConfig: (value) => {
    ignoreCertificateErrors = value;
  },
  id: cliFlag38
};

// src/options/image-sequence.tsx

var cliFlag39 = "sequence";
var imageSequence = false;
var imageSequenceOption = {
  name: "Image Sequence",
  cliFlag: cliFlag39,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Pass this flag to output an image sequence instead of a video. The default image format is JPEG. See",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
        href: "/docs/config#setimagesequence",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "setImageSequence()"
        })
      }),
      " ",
      "for more details."
    ]
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config#setimagesequence",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag39] !== undefined) {
      return {
        source: "cli",
        value: Boolean(commandLine[cliFlag39])
      };
    }
    return {
      source: imageSequence ? "config" : "default",
      value: imageSequence
    };
  },
  setConfig: (value) => {
    imageSequence = value;
  },
  type: false,
  id: cliFlag39
};

// src/options/image-sequence-pattern.tsx

var cliFlag40 = "image-sequence-pattern";
var currentImageSequencePattern = null;
var imageSequencePatternOption = {
  name: "Image Sequence Pattern",
  cliFlag: cliFlag40,
  ssrName: "imageSequencePattern",
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Pattern for naming image sequence files. Supports ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "[frame]"
      }),
      " for the zero-padded frame number and ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "[ext]"
      }),
      " for the file extension."
    ]
  }),
  docLink: null,
  type: "string",
  getValue: ({ commandLine }) => {
    if (currentImageSequencePattern !== null) {
      return {
        value: currentImageSequencePattern,
        source: "config"
      };
    }
    return {
      value: commandLine[cliFlag40],
      source: "cli"
    };
  },
  setConfig: (pattern) => {
    currentImageSequencePattern = pattern;
  },
  id: cliFlag40
};

// src/options/ipv4.tsx

var forceIPv4 = false;
var cliFlag41 = "ipv4";
var ipv4Option = {
  name: "IPv4",
  cliFlag: cliFlag41,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Forces Remotion to bind to an IPv4 interface for the Studio server."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/cli/studio",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag41] !== undefined) {
      return {
        value: commandLine[cliFlag41],
        source: "cli"
      };
    }
    return {
      value: forceIPv4,
      source: "config"
    };
  },
  setConfig(value) {
    forceIPv4 = value;
  },
  id: cliFlag41
};

// src/options/is-production.tsx

var cliFlag42 = "is-production";
var currentIsProductionKey = null;
var isProductionOption = {
  name: "Is Production",
  cliFlag: cliFlag42,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Pass ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "false"
      }),
      " if this a development render to not count it as a billable render on remotion.pro. Only can be used in conjuction with",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "licenseKey"
      }),
      "."
    ]
  }),
  ssrName: "isProduction",
  docLink: "https://www.remotion.dev/docs/licensing",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag42] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag42]
      };
    }
    if (currentIsProductionKey !== null) {
      return {
        source: "config",
        value: currentIsProductionKey
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value) => {
    currentIsProductionKey = value;
  },
  type: false,
  id: cliFlag42
};

// src/options/jpeg-quality.tsx

var defaultValue = DEFAULT_JPEG_QUALITY;
var quality = defaultValue;
var setJpegQuality = (q) => {
  validateJpegQuality(q);
  if (q === 0 || q === undefined) {
    quality = defaultValue;
    return;
  }
  quality = q;
};
var cliFlag43 = "jpeg-quality";
var jpegQualityOption = {
  name: "JPEG Quality",
  cliFlag: cliFlag43,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Sets the quality of the generated JPEG images. Must be an integer between 0 and 100. Default: 80."
  }),
  ssrName: "jpegQuality",
  docLink: "https://www.remotion.dev/docs/renderer/render-media#jpeg-quality",
  type: 0,
  setConfig: setJpegQuality,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag43] !== undefined) {
      validateJpegQuality(commandLine[cliFlag43]);
      return {
        source: "cli",
        value: commandLine[cliFlag43]
      };
    }
    if (quality !== defaultValue) {
      return {
        source: "config",
        value: quality
      };
    }
    return {
      source: "default",
      value: defaultValue
    };
  },
  id: cliFlag43
};

// src/options/keyboard-shortcuts.tsx

var keyboardShortcutsEnabled = true;
var cliFlag44 = "disable-keyboard-shortcuts";
var keyboardShortcutsOption = {
  name: "Disable or Enable keyboard shortcuts",
  cliFlag: cliFlag44,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Enable or disable keyboard shortcuts in the Remotion Studio."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config#setkeyboardshortcutsenabled",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag44] !== undefined) {
      keyboardShortcutsEnabled = commandLine[cliFlag44] === false;
      return {
        value: keyboardShortcutsEnabled,
        source: "cli"
      };
    }
    return {
      value: keyboardShortcutsEnabled,
      source: "config"
    };
  },
  setConfig(value) {
    keyboardShortcutsEnabled = value;
  },
  id: cliFlag44
};

// src/options/latency-hint.tsx

var cliFlag45 = "audio-latency-hint";
var value = null;
var audioLatencyHintOption = {
  name: "Audio Latency Hint",
  cliFlag: cliFlag45,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Sets the",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
        href: "https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/AudioContext",
        children: "audio latency"
      }),
      " ",
      "hint for the global ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "AudioContext"
      }),
      " context that Remotion uses to play audio.",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      "Possible values: ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "interactive"
      }),
      ", ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "balanced"
      }),
      ",",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "playback"
      })
    ]
  }),
  ssrName: "audioLatencyHint",
  docLink: "https://www.remotion.dev/docs/renderer/render-media",
  type: "interactive",
  getValue: ({ commandLine }) => {
    const val = commandLine[cliFlag45];
    if (typeof val !== "undefined") {
      return { value: val, source: "cli" };
    }
    if (value !== null) {
      return { value, source: "config" };
    }
    return { value: null, source: "default" };
  },
  setConfig: (profile) => {
    value = profile;
  },
  id: cliFlag45
};

// src/options/license-key.tsx

var currentLicenseKey = null;
var cliFlag46 = "license-key";
var licenseKeyOption = {
  name: "License key",
  cliFlag: cliFlag46,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "License key for sending a usage event using",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "@remotion/licensing"
      }),
      "."
    ]
  }),
  ssrName: "licenseKey",
  docLink: "https://www.remotion.dev/docs/licensing",
  type: null,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag46] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag46]
      };
    }
    return {
      source: "default",
      value: currentLicenseKey
    };
  },
  setConfig: (value2) => {
    currentLicenseKey = value2;
  },
  id: cliFlag46
};

// src/options/log-level.tsx

var logLevel = "info";
var cliFlag47 = "log";
var logLevelOption = {
  cliFlag: cliFlag47,
  name: "Log Level",
  ssrName: "logLevel",
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "One of ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "trace"
      }),
      ", ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "verbose"
      }),
      ", ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "info"
      }),
      ",",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "warn"
      }),
      ", ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "error"
      }),
      ".",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      " Determines how much info is being logged to the console.",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      " Default ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "info"
      }),
      "."
    ]
  }),
  docLink: "https://www.remotion.dev/docs/troubleshooting/debug-failed-render",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag47]) {
      if (!isValidLogLevel(commandLine[cliFlag47])) {
        throw new Error(`Invalid \`--log\` value passed. Accepted values: ${logLevels.map((l) => `'${l}'`).join(", ")}.`);
      }
      return { value: commandLine[cliFlag47], source: "cli" };
    }
    if (logLevel !== "info") {
      return { value: logLevel, source: "config" };
    }
    return { value: "info", source: "default" };
  },
  setConfig: (newLogLevel) => {
    logLevel = newLogLevel;
  },
  type: "error",
  id: cliFlag47
};

// src/options/metadata.tsx

var metadata = {};
var cliFlag48 = "metadata";
var metadataOption = {
  name: "Metadata",
  cliFlag: cliFlag48,
  description: (mode) => {
    if (mode === "ssr") {
      return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
        children: [
          "An object containing metadata to be embedded in the video. See",
          " ",
          /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
            href: "/docs/metadata",
            children: "here"
          }),
          " for which metadata is accepted."
        ]
      });
    }
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
      children: [
        "Metadata to be embedded in the video. See",
        " ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
          href: "/docs/metadata",
          children: "here"
        }),
        " for which metadata is accepted.",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
        "The parameter must be in the format of ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "--metadata key=value"
        }),
        " ",
        "and can be passed multiple times."
      ]
    });
  },
  docLink: "https://www.remotion.dev/docs/metadata",
  type: {},
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag48] !== undefined) {
      const val = commandLine[cliFlag48];
      const array = typeof val === "string" ? [val] : val;
      const keyValues = array.map((a) => {
        if (!a.includes("=")) {
          throw new Error(`"metadata" must be in the format of key=value, but got ${a}`);
        }
        const splitted = a.split("=");
        if (splitted.length !== 2) {
          throw new Error(`"metadata" must be in the format of key=value, but got ${a}`);
        }
        return [splitted[0], splitted[1]];
      });
      const value2 = Object.fromEntries(keyValues);
      return {
        source: "config",
        value: value2
      };
    }
    return {
      source: "config",
      value: metadata
    };
  },
  setConfig: (newMetadata) => {
    metadata = newMetadata;
  },
  ssrName: "metadata",
  id: cliFlag48
};

// src/options/mute.tsx

var DEFAULT_MUTED_STATE = false;
var mutedState = DEFAULT_MUTED_STATE;
var cliFlag49 = "muted";
var mutedOption = {
  name: "Muted",
  cliFlag: cliFlag49,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "The Audio of the video will be omitted."
  }),
  ssrName: "muted",
  docLink: "https://www.remotion.dev/docs/audio/muting",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag49] !== null) {
      return {
        source: "cli",
        value: commandLine[cliFlag49]
      };
    }
    if (mutedState !== DEFAULT_MUTED_STATE) {
      return {
        source: "config",
        value: mutedState
      };
    }
    return {
      source: "config",
      value: mutedState
    };
  },
  setConfig: () => {
    mutedState = true;
  },
  id: cliFlag49
};

// src/options/no-open.tsx

var shouldOpenBrowser = true;
var cliFlag50 = "no-open";
var noOpenOption = {
  name: "Disable browser auto-open",
  cliFlag: cliFlag50,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "If specified, Remotion will not open a browser window when starting the Studio."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/cli/studio#--no-open",
  type: false,
  getValue: ({ commandLine }) => {
    const cliValue = commandLine.open;
    if (cliValue === false) {
      return { value: true, source: "cli" };
    }
    if (!shouldOpenBrowser) {
      return { value: true, source: "config" };
    }
    return { value: false, source: "default" };
  },
  setConfig: (shouldOpen) => {
    shouldOpenBrowser = shouldOpen;
  },
  id: cliFlag50
};

// src/options/number-of-gif-loops.tsx

var currentLoop = null;
var validate = (newLoop) => {
  if (newLoop !== null && typeof newLoop !== "number") {
    throw new Error("--number-of-gif-loops flag must be a number.");
  }
};
var cliFlag51 = "number-of-gif-loops";
var numberOfGifLoopsOption = {
  name: "Number of GIF loops",
  cliFlag: cliFlag51,
  description: () => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
      children: [
        "Allows you to set the number of loops as follows:",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("ul", {
          children: [
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("li", {
              children: [
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
                  children: "null"
                }),
                " (or omitting in the CLI) plays the GIF indefinitely."
              ]
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("li", {
              children: [
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
                  children: "0"
                }),
                " disables looping"
              ]
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("li", {
              children: [
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
                  children: "1"
                }),
                " loops the GIF once (plays twice in total)"
              ]
            }),
            /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("li", {
              children: [
                /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
                  children: "2"
                }),
                " loops the GIF twice (plays three times in total) and so on."
              ]
            })
          ]
        })
      ]
    });
  },
  ssrName: "numberOfGifLoops",
  docLink: "https://www.remotion.dev/docs/render-as-gif#changing-the-number-of-loops",
  type: 0,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag51] !== undefined) {
      validate(commandLine[cliFlag51]);
      return {
        value: commandLine[cliFlag51],
        source: "cli"
      };
    }
    if (currentLoop !== null) {
      return {
        value: currentLoop,
        source: "config"
      };
    }
    return {
      value: null,
      source: "default"
    };
  },
  setConfig: (newLoop) => {
    validate(newLoop);
    currentLoop = newLoop;
  },
  id: cliFlag51
};

// src/options/number-of-shared-audio-tags.tsx

var numberOfSharedAudioTags = 0;
var cliFlag52 = "number-of-shared-audio-tags";
var numberOfSharedAudioTagsOption = {
  name: "Number of shared audio tags",
  cliFlag: cliFlag52,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Set number of shared audio tags. See",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
        href: "https://www.remotion.dev/docs/player/autoplay#using-the-numberofsharedaudiotags-prop",
        children: "Using the numberOfSharedAudioTags prop"
      }),
      " ",
      "for more information."
    ]
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config#setnumberofsharedaudiotags",
  type: 0,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag52] !== undefined) {
      return {
        value: commandLine[cliFlag52],
        source: "cli"
      };
    }
    return {
      value: numberOfSharedAudioTags,
      source: "config"
    };
  },
  setConfig(value2) {
    numberOfSharedAudioTags = value2;
  },
  id: cliFlag52
};

// src/options/offthreadvideo-cache-size.tsx

var offthreadVideoCacheSizeInBytes = null;
var cliFlag53 = "offthreadvideo-cache-size-in-bytes";
var offthreadVideoCacheSizeInBytesOption = {
  name: "OffthreadVideo cache size",
  cliFlag: cliFlag53,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "From v4.0, Remotion has a cache for",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
        href: "https://remotion.dev/docs/offthreadvideo",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "<OffthreadVideo>"
        })
      }),
      " ",
      "frames. The default is ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "null"
      }),
      ", corresponding to half of the system memory available when the render starts.",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      " This option allows to override the size of the cache. The higher it is, the faster the render will be, but the more memory will be used.",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      "The used value will be printed when running in verbose mode.",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      "Default: ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "null"
      })
    ]
  }),
  ssrName: "offthreadVideoCacheSizeInBytes",
  docLink: "https://www.remotion.dev/docs/offthreadvideo",
  type: 0,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag53] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag53]
      };
    }
    if (offthreadVideoCacheSizeInBytes !== null) {
      return {
        source: "config",
        value: offthreadVideoCacheSizeInBytes
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (size) => {
    offthreadVideoCacheSizeInBytes = size ?? null;
  },
  id: cliFlag53
};

// src/options/offthreadvideo-threads.tsx

var value2 = null;
var cliFlag54 = "offthreadvideo-video-threads";
var offthreadVideoThreadsOption = {
  name: "OffthreadVideo threads",
  cliFlag: cliFlag54,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "The number of threads that",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
        href: "https://remotion.dev/docs/offthreadvideo",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "<OffthreadVideo>"
        })
      }),
      " ",
      "can start to extract frames. The default is",
      " ",
      DEFAULT_RENDER_FRAMES_OFFTHREAD_VIDEO_THREADS,
      ". Increase carefully, as too many threads may cause instability."
    ]
  }),
  ssrName: "offthreadVideoThreads",
  docLink: "https://www.remotion.dev/docs/offthreadvideo",
  type: 0,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag54] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag54]
      };
    }
    if (value2 !== null) {
      return {
        source: "config",
        value: value2
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (size) => {
    value2 = size ?? null;
  },
  id: cliFlag54
};
var DEFAULT_RENDER_FRAMES_OFFTHREAD_VIDEO_THREADS = 2;

// src/options/on-browser-download.tsx

var cliFlag55 = "on-browser-download";
var onBrowserDownloadOption = {
  name: "Browser download callback function",
  cliFlag: cliFlag55,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Gets called when no compatible local browser is detected on the system and this API needs to download a browser. Return a callback to observe progress.",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
        href: "/docs/renderer/ensure-browser#onbrowserdownload",
        children: "See here for how to use this option."
      })
    ]
  }),
  ssrName: "onBrowserDownload",
  docLink: "https://www.remotion.dev/docs/renderer/ensure-browser",
  type: undefined,
  getValue: () => {
    throw new Error("does not support config file");
  },
  setConfig: () => {
    throw new Error("does not support config file");
  },
  id: cliFlag55
};

// src/options/out-dir.tsx

var cliFlag56 = "out-dir";
var currentOutDir = null;
var outDirOption = {
  name: "Output Directory",
  cliFlag: cliFlag56,
  description: () => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
      children: [
        "Define the location of the resulting bundle. By default it is a folder called ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "build"
        }),
        ", adjacent to the",
        " ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
          href: "/docs/terminology/remotion-root",
          children: "Remotion Root"
        }),
        "."
      ]
    });
  },
  ssrName: "outDir",
  docLink: "https://www.remotion.dev/docs/cli/bundle#--out-dir",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag56] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag56]
      };
    }
    if (currentOutDir !== null) {
      return {
        source: "config",
        value: currentOutDir
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value3) => {
    currentOutDir = value3;
  },
  type: "",
  id: cliFlag56
};

// src/validate.ts

var validateFps = remotion_no_react__WEBPACK_IMPORTED_MODULE_0__.NoReactInternals.validateFps;
var validateDimension = remotion_no_react__WEBPACK_IMPORTED_MODULE_0__.NoReactInternals.validateDimension;
var validateDurationInFrames = remotion_no_react__WEBPACK_IMPORTED_MODULE_0__.NoReactInternals.validateDurationInFrames;

// src/options/override-duration.tsx

var currentDuration = null;
var cliFlag57 = "duration";
var overrideDurationOption = {
  name: "Override Duration",
  cliFlag: cliFlag57,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Overrides the duration in frames of the composition."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config#overrideduration",
  type: null,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag57] !== undefined) {
      const value3 = commandLine[cliFlag57];
      validateDurationInFrames(value3, {
        component: "in --duration flag",
        allowFloats: false
      });
      return {
        source: "cli",
        value: value3
      };
    }
    if (currentDuration !== null) {
      return {
        source: "config",
        value: currentDuration
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (duration) => {
    validateDurationInFrames(duration, {
      component: "in Config.overrideDuration()",
      allowFloats: false
    });
    currentDuration = duration;
  },
  id: cliFlag57
};

// src/options/override-fps.tsx

var currentFps = null;
var cliFlag58 = "fps";
var overrideFpsOption = {
  name: "Override FPS",
  cliFlag: cliFlag58,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Overrides the frames per second of the composition."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config#overridefps",
  type: null,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag58] !== undefined) {
      const value3 = commandLine[cliFlag58];
      validateFps(value3, "in --fps flag", false);
      return {
        source: "cli",
        value: value3
      };
    }
    if (currentFps !== null) {
      return {
        source: "config",
        value: currentFps
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (fps) => {
    validateFps(fps, "in Config.overrideFps()", false);
    currentFps = fps;
  },
  id: cliFlag58
};

// src/options/override-height.tsx

var currentHeight = null;
var cliFlag59 = "height";
var overrideHeightOption = {
  name: "Override Height",
  cliFlag: cliFlag59,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Overrides the height of the composition."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config#overrideheight",
  type: null,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag59] !== undefined) {
      const value3 = commandLine[cliFlag59];
      validateDimension(value3, "height", "in --height flag");
      return {
        source: "cli",
        value: value3
      };
    }
    if (currentHeight !== null) {
      return {
        source: "config",
        value: currentHeight
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (height) => {
    validateDimension(height, "height", "in Config.overrideHeight()");
    currentHeight = height;
  },
  id: cliFlag59
};

// src/options/override-width.tsx

var currentWidth = null;
var cliFlag60 = "width";
var overrideWidthOption = {
  name: "Override Width",
  cliFlag: cliFlag60,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Overrides the width of the composition."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config#overridewidth",
  type: null,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag60] !== undefined) {
      const value3 = commandLine[cliFlag60];
      validateDimension(value3, "width", "in --width flag");
      return {
        source: "cli",
        value: value3
      };
    }
    if (currentWidth !== null) {
      return {
        source: "config",
        value: currentWidth
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (width) => {
    validateDimension(width, "width", "in Config.overrideWidth()");
    currentWidth = width;
  },
  id: cliFlag60
};

// src/options/overwrite.tsx

var shouldOverwrite = null;
var cliFlag61 = "overwrite";
var validate2 = (value3) => {
  if (typeof value3 !== "boolean") {
    throw new Error(`overwriteExisting must be a boolean but got ${typeof value3} (${value3})`);
  }
};
var overwriteOption = {
  name: "Overwrite output",
  cliFlag: cliFlag61,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "If set to ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "false"
      }),
      ", will prevent rendering to a path that already exists. Default is ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "true"
      }),
      "."
    ]
  }),
  ssrName: "overwrite",
  docLink: "https://www.remotion.dev/docs/config#setoverwriteoutput",
  type: false,
  getValue: ({ commandLine }, defaultValue2) => {
    if (commandLine[cliFlag61] !== undefined) {
      validate2(commandLine[cliFlag61]);
      return {
        source: "cli",
        value: commandLine[cliFlag61]
      };
    }
    if (shouldOverwrite !== null) {
      return {
        source: "config",
        value: shouldOverwrite
      };
    }
    return {
      source: "default",
      value: defaultValue2
    };
  },
  setConfig: (value3) => {
    validate2(value3);
    shouldOverwrite = value3;
  },
  id: cliFlag61
};

// src/options/package-manager.tsx

var cliFlag62 = "package-manager";
var currentPackageManager = null;
var packageManagerOption = {
  name: "Package Manager",
  cliFlag: cliFlag62,
  description: () => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
      children: [
        "Forces a specific package manager to be used. By default, Remotion will auto-detect the package manager based on your lockfile.",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
        "Acceptable values are ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "npm"
        }),
        ", ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "yarn"
        }),
        ",",
        " ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "pnpm"
        }),
        " and ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "bun"
        }),
        "."
      ]
    });
  },
  ssrName: "packageManager",
  docLink: "https://www.remotion.dev/docs/cli/upgrade#--package-manager",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag62] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag62]
      };
    }
    if (currentPackageManager !== null) {
      return {
        source: "config",
        value: currentPackageManager
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value3) => {
    currentPackageManager = value3;
  },
  type: "",
  id: cliFlag62
};

// src/pixel-format.ts
var validPixelFormats = [
  "yuv420p",
  "yuva420p",
  "yuv422p",
  "yuv444p",
  "yuv420p10le",
  "yuv422p10le",
  "yuv444p10le",
  "yuva444p10le"
];
var DEFAULT_PIXEL_FORMAT = "yuv420p";
var validPixelFormatsForCodec = (codec) => {
  if (codec === "vp8" || codec === "vp9") {
    return validPixelFormats;
  }
  return validPixelFormats.filter((format) => format !== "yuva420p");
};

// src/options/pixel-format.tsx

var currentPixelFormat = DEFAULT_PIXEL_FORMAT;
var cliFlag63 = "pixel-format";
var pixelFormatOption = {
  name: "Pixel format",
  cliFlag: cliFlag63,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Sets the pixel format in FFmpeg. See",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
        href: "https://trac.ffmpeg.org/wiki/Chroma%20Subsampling",
        children: "the FFmpeg docs for an explanation"
      }),
      ". Acceptable values: ",
      validPixelFormats.map((f) => `"${f}"`).join(", "),
      "."
    ]
  }),
  ssrName: "pixelFormat",
  docLink: "https://www.remotion.dev/docs/config#setpixelformat",
  type: DEFAULT_PIXEL_FORMAT,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag63] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag63]
      };
    }
    if (currentPixelFormat !== DEFAULT_PIXEL_FORMAT) {
      return {
        source: "config",
        value: currentPixelFormat
      };
    }
    return {
      source: "default",
      value: DEFAULT_PIXEL_FORMAT
    };
  },
  setConfig: (value3) => {
    if (!validPixelFormats.includes(value3)) {
      throw new TypeError(`Value ${value3} is not valid as a pixel format.`);
    }
    currentPixelFormat = value3;
  },
  id: cliFlag63
};

// src/options/port.tsx

var cliFlag64 = "port";
var currentPort = null;
var portOption = {
  name: "Port",
  cliFlag: cliFlag64,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Set a custom HTTP server port for the Studio or the render process. If not defined, Remotion will try to find a free port."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config#setstudioport",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag64] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag64]
      };
    }
    if (currentPort !== null) {
      return {
        source: "config",
        value: currentPort
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value3) => {
    currentPort = value3;
  },
  type: 0,
  id: cliFlag64
};

// src/options/prefer-lossless.tsx

var cliFlag65 = "prefer-lossless";
var input = false;
var preferLosslessAudioOption = {
  name: "Prefer lossless",
  cliFlag: cliFlag65,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Uses a lossless audio codec, if one is available for the codec. If you set",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "audioCodec"
      }),
      ", it takes priority over",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "preferLossless"
      }),
      "."
    ]
  }),
  docLink: "https://www.remotion.dev/docs/encoding",
  type: false,
  ssrName: "preferLossless",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag65]) {
      return { value: true, source: "cli" };
    }
    if (input === true) {
      return { value: true, source: "config" };
    }
    return { value: false, source: "default" };
  },
  setConfig: (val) => {
    input = val;
  },
  id: cliFlag65
};

// src/options/props.tsx

var cliFlag66 = "props";
var propsOption = {
  name: "Input Props",
  cliFlag: cliFlag66,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Input Props to pass to the selected composition of your video. Must be a serialized JSON string (",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)("code", {
        children: [
          "--props='",
          "{",
          '"hello": "world"',
          "}",
          "'"
        ]
      }),
      ") or a path to a JSON file (",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "./path/to/props.json"
      }),
      ")."
    ]
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/passing-props#passing-input-props-in-the-cli",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag66] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag66]
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: () => {
    throw new Error("setProps is not supported. Pass --props via the CLI instead.");
  },
  type: "",
  id: cliFlag66
};

// src/options/prores-profile.tsx

var validProResProfiles = [
  "4444-xq",
  "4444",
  "hq",
  "standard",
  "light",
  "proxy"
];
var proResProfile;
var cliFlag67 = "prores-profile";
var proResProfileOption = {
  name: "ProRes profile",
  cliFlag: cliFlag67,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Set the ProRes profile. This option is only valid if the codec has been set to ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "prores"
      }),
      ". Possible values:",
      " ",
      validProResProfiles.map((p) => `"${p}"`).join(", "),
      ". Default:",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: '"hq"'
      }),
      ". See",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
        href: "https://video.stackexchange.com/a/14715",
        children: "here"
      }),
      " for an explanation of possible values."
    ]
  }),
  ssrName: "proResProfile",
  docLink: "https://www.remotion.dev/docs/config#setproresprofile",
  type: undefined,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag67] !== undefined) {
      return {
        source: "cli",
        value: String(commandLine[cliFlag67])
      };
    }
    if (proResProfile !== undefined) {
      return {
        source: "config",
        value: proResProfile
      };
    }
    return {
      source: "default",
      value: undefined
    };
  },
  setConfig: (value3) => {
    proResProfile = value3;
  },
  id: cliFlag67
};

// src/options/public-dir.tsx

var cliFlag68 = "public-dir";
var currentPublicDir = null;
var publicDirOption = {
  name: "Public Directory",
  cliFlag: cliFlag68,
  description: () => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
      children: [
        "Define the location of the",
        " ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
          href: "/docs/terminology/public-dir",
          children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
            children: "public/ directory"
          })
        }),
        ". If not defined, Remotion will assume the location is the `public` folder in your Remotion root."
      ]
    });
  },
  ssrName: "publicDir",
  docLink: "https://www.remotion.dev/docs/terminology/public-dir",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag68] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag68]
      };
    }
    if (currentPublicDir !== null) {
      return {
        source: "config",
        value: currentPublicDir
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value3) => {
    currentPublicDir = value3;
  },
  type: "",
  id: cliFlag68
};

// src/options/public-license-key.tsx

var cliFlag69 = "public-license-key";
var currentPublicLicenseKey = null;
var publicLicenseKeyOption = {
  name: "Public License Key",
  cliFlag: cliFlag69,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      'The public license key for your company license, obtained from the "Usage" tab on ',
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
        href: "https://remotion.pro/dashboard",
        children: "remotion.pro"
      }),
      '. If you are eligible for the free license, pass "free-license".'
    ]
  }),
  ssrName: "publicLicenseKey",
  docLink: "https://www.remotion.dev/docs/licensing",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag69] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag69]
      };
    }
    if (currentPublicLicenseKey !== null) {
      return {
        source: "config",
        value: currentPublicLicenseKey
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value3) => {
    if (value3 && value3 !== "free-license" && !value3.startsWith("rm_pub_")) {
      throw new Error('Invalid public license key. It must start with "rm_pub_" or be "free-license".');
    }
    currentPublicLicenseKey = value3;
  },
  type: null,
  id: cliFlag69
};

// src/options/public-path.tsx

var cliFlag70 = "public-path";
var currentPublicPath = null;
var publicPathOption = {
  name: "Public Path",
  cliFlag: cliFlag70,
  description: () => {
    return /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
      children: [
        "The path of the URL where the bundle is going to be hosted. By default it is ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "/"
        }),
        ", meaning that the bundle is going to be hosted at the root of the domain (e.g. ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "https://localhost:3000/"
        }),
        "). If you are deploying to a subdirectory (e.g. ",
        /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "/sites/my-site/"
        }),
        "), you should set this to the subdirectory."
      ]
    });
  },
  ssrName: "publicPath",
  docLink: "https://www.remotion.dev/docs/renderer",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag70] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag70]
      };
    }
    if (currentPublicPath !== null) {
      return {
        source: "config",
        value: currentPublicPath
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value3) => {
    currentPublicPath = value3;
  },
  type: "",
  id: cliFlag70
};

// src/options/repro.tsx

var enableRepro = false;
var setRepro = (should) => {
  enableRepro = should;
};
var cliFlag71 = "repro";
var reproOption = {
  name: "Create reproduction",
  cliFlag: cliFlag71,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Create a ZIP that you can submit to Remotion if asked for a reproduction."
  }),
  ssrName: "repro",
  docLink: "https://www.remotion.dev/docs/render-media#repro",
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag71] !== undefined) {
      return {
        value: commandLine[cliFlag71],
        source: "cli"
      };
    }
    if (enableRepro) {
      return {
        value: enableRepro,
        source: "config"
      };
    }
    return {
      value: false,
      source: "default"
    };
  },
  setConfig: setRepro,
  id: cliFlag71
};

// src/options/rspack.tsx

var rspackEnabled = false;
var cliFlag72 = "experimental-rspack";
var rspackOption = {
  name: "Experimental Rspack",
  cliFlag: cliFlag72,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Uses Rspack instead of Webpack as the bundler for the Studio or bundle."
  }),
  ssrName: null,
  docLink: null,
  type: false,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag72] !== undefined) {
      rspackEnabled = true;
      return {
        value: commandLine[cliFlag72],
        source: "cli"
      };
    }
    return {
      value: rspackEnabled,
      source: "config"
    };
  },
  setConfig(value3) {
    rspackEnabled = value3;
  },
  id: cliFlag72
};

// src/options/runs.tsx

var DEFAULT_RUNS = 3;
var currentRuns = DEFAULT_RUNS;
var cliFlag73 = "runs";
var runsOption = {
  name: "Benchmark runs",
  cliFlag: cliFlag73,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Specify how many times the video should be rendered during a benchmark. Default ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: DEFAULT_RUNS
      }),
      "."
    ]
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/cli/benchmark#--runs",
  type: DEFAULT_RUNS,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag73] !== undefined) {
      const value3 = Number(commandLine[cliFlag73]);
      if (isNaN(value3) || value3 < 1) {
        throw new Error(`--runs must be a positive number, but got ${commandLine[cliFlag73]}`);
      }
      return { value: value3, source: "cli" };
    }
    if (currentRuns !== DEFAULT_RUNS) {
      return { value: currentRuns, source: "config" };
    }
    return { value: DEFAULT_RUNS, source: "default" };
  },
  setConfig: (value3) => {
    if (typeof value3 !== "number" || isNaN(value3) || value3 < 1) {
      throw new Error(`Runs must be a positive number, but got ${value3}`);
    }
    currentRuns = value3;
  },
  id: cliFlag73
};

// src/options/scale.tsx

var currentScale = 1;
var cliFlag74 = "scale";
var validateScale = (value3) => {
  if (typeof value3 !== "number") {
    throw new Error("scale must be a number.");
  }
};
var scaleOption = {
  name: "Scale",
  cliFlag: cliFlag74,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Scales the output dimensions by a factor. For example, a 1280x720px frame will become a 1920x1080px frame with a scale factor of ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "1.5"
      }),
      ". See ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
        href: "https://www.remotion.dev/docs/scaling",
        children: "Scaling"
      }),
      " for more details."
    ]
  }),
  ssrName: "scale",
  docLink: "https://www.remotion.dev/docs/scaling",
  type: 0,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag74] !== undefined) {
      validateScale(commandLine[cliFlag74]);
      return {
        source: "cli",
        value: commandLine[cliFlag74]
      };
    }
    if (currentScale !== null) {
      return {
        source: "config",
        value: currentScale
      };
    }
    return {
      source: "default",
      value: 1
    };
  },
  setConfig: (scale) => {
    currentScale = scale;
  },
  id: cliFlag74
};

// src/options/still-frame.tsx


var cliFlag75 = "frame";
var currentFrame = null;
var validate3 = (frame) => {
  remotion_no_react__WEBPACK_IMPORTED_MODULE_0__.NoReactInternals.validateFrame({
    frame,
    durationInFrames: Infinity,
    allowFloats: false
  });
};
var stillFrameOption = {
  name: "Frame",
  cliFlag: cliFlag75,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Which frame should be rendered when rendering a still. Default",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "0"
      }),
      ". From v3.2.27, negative values are allowed, with",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "-1"
      }),
      " being the last frame."
    ]
  }),
  ssrName: "frame",
  docLink: "https://www.remotion.dev/docs/cli/still#--frame",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag75] !== undefined) {
      const frame = Number(commandLine[cliFlag75]);
      validate3(frame);
      return {
        source: "cli",
        value: frame
      };
    }
    if (currentFrame !== null) {
      return {
        source: "config",
        value: currentFrame
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value3) => {
    if (value3 !== null) {
      validate3(value3);
    }
    currentFrame = value3;
  },
  type: 0,
  id: cliFlag75
};

// src/options/still-image-format.tsx

var currentStillImageFormat = null;
var cliFlag76 = "image-format";
var stillImageFormatOption = {
  name: "Still Image Format",
  cliFlag: cliFlag76,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "The image format to use when rendering a still. Must be one of",
      " ",
      validStillImageFormats.map((f) => `"${f}"`).join(", "),
      ". Default:",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: '"png"'
      }),
      "."
    ]
  }),
  ssrName: "imageFormat",
  docLink: "https://www.remotion.dev/docs/renderer/render-still#imageformat",
  type: null,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag76] !== undefined) {
      const value3 = commandLine[cliFlag76];
      if (!validStillImageFormats.includes(value3)) {
        throw new Error(`Invalid still image format: ${value3}. Must be one of: ${validStillImageFormats.join(", ")}`);
      }
      return {
        source: "cli",
        value: value3
      };
    }
    if (currentStillImageFormat !== null) {
      return {
        source: "config",
        value: currentStillImageFormat
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value3) => {
    if (value3 === null) {
      currentStillImageFormat = null;
      return;
    }
    if (!validStillImageFormats.includes(value3)) {
      throw new TypeError([
        `Value ${value3} is not valid as a still image format.`,
        value3 === "jpg" ? 'Did you mean "jpeg"?' : null
      ].filter(Boolean).join(" "));
    }
    currentStillImageFormat = value3;
  },
  id: "still-image-format"
};

// src/options/throw-if-site-exists.tsx
var DEFAULT5 = false;
var cliFlag77 = "throw-if-site-exists";
var throwIfSiteExistsOption = {
  cliFlag: cliFlag77,
  description: () => `Prevents accidential update of an existing site. If there are any files in the subfolder where the site should be placed, the function will throw.`,
  docLink: "https://remotion.dev/docs/lambda/deploy-site",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag77]) {
      return {
        source: "cli",
        value: commandLine[cliFlag77]
      };
    }
    return {
      source: "default",
      value: DEFAULT5
    };
  },
  name: "Throw if site exists",
  setConfig: () => {
    throw new Error("Not implemented");
  },
  ssrName: "throwIfSiteExists",
  type: false,
  id: cliFlag77
};

// src/options/timeout.tsx

var currentTimeout = DEFAULT_TIMEOUT;
var validate4 = (value3) => {
  if (typeof value3 !== "number") {
    throw new Error("--timeout flag / setDelayRenderTimeoutInMilliseconds() must be a number, but got " + JSON.stringify(value3));
  }
};
var cliFlag78 = "timeout";
var delayRenderTimeoutInMillisecondsOption = {
  name: "delayRender() timeout",
  cliFlag: cliFlag78,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "A number describing how long the render may take to resolve all",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
        href: "https://remotion.dev/docs/delay-render",
        children: /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
          children: "delayRender()"
        })
      }),
      " ",
      "calls",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("a", {
        style: { fontSize: "inherit" },
        href: "https://remotion.dev/docs/timeout",
        children: "before it times out"
      }),
      ". Default: ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "30000"
      })
    ]
  }),
  ssrName: "timeoutInMilliseconds",
  docLink: "https://www.remotion.dev/docs/timeout",
  type: 0,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag78] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag78]
      };
    }
    if (currentTimeout !== null) {
      validate4(currentTimeout);
      return {
        source: "config",
        value: currentTimeout
      };
    }
    return {
      source: "default",
      value: DEFAULT_TIMEOUT
    };
  },
  setConfig: (value3) => {
    validate4(value3);
    currentTimeout = value3;
  },
  id: cliFlag78
};

// src/options/user-agent.tsx

var userAgent = null;
var cliFlag79 = "user-agent";
var userAgentOption = {
  name: "User agent",
  cliFlag: cliFlag79,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Lets you set a custom user agent that the headless Chrome browser assumes."
  }),
  ssrName: "userAgent",
  docLink: "https://www.remotion.dev/docs/chromium-flags#--user-agent",
  type: null,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag79] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag79]
      };
    }
    if (userAgent !== null) {
      return {
        source: "config",
        value: userAgent
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value3) => {
    userAgent = value3;
  },
  id: cliFlag79
};

// src/options/version-flag.tsx

var cliFlag80 = "version";
var versionFlagOption = {
  name: "Version",
  cliFlag: cliFlag80,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Install a specific version. Also enables downgrading to an older version."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/cli/upgrade#--version",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag80] !== undefined) {
      return {
        source: "cli",
        value: String(commandLine[cliFlag80])
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: () => {
    throw new Error("Cannot set version via config file");
  },
  type: "",
  id: cliFlag80
};

// src/options/video-bitrate.tsx

var videoBitrate = null;
var cliFlag81 = "video-bitrate";
var videoBitrateOption = {
  name: "Video Bitrate",
  cliFlag: cliFlag81,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Specify the target bitrate for the generated video. The syntax for FFmpeg",
      "'",
      "s",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "-b:v"
      }),
      " parameter should be used. FFmpeg may encode the video in a way that will not result in the exact video bitrate specified. Example values: ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "512K"
      }),
      " for 512 kbps, ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "1M"
      }),
      " for 1 Mbps."
    ]
  }),
  ssrName: "videoBitrate",
  docLink: "https://www.remotion.dev/docs/renderer/render-media#videobitrate",
  type: "",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag81] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag81]
      };
    }
    if (videoBitrate !== null) {
      return {
        source: "config",
        value: videoBitrate
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (bitrate) => {
    videoBitrate = bitrate;
  },
  id: cliFlag81
};

// src/options/video-cache-size.tsx

var mediaCacheSizeInBytes = null;
var cliFlag82 = "media-cache-size-in-bytes";
var mediaCacheSizeInBytesOption = {
  name: "@remotion/media cache size",
  cliFlag: cliFlag82,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Specify the maximum size of the cache that ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "<Video>"
      }),
      " and",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "<Audio>"
      }),
      " from ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "@remotion/media"
      }),
      " may use combined, in bytes. ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      "The default is half of the available system memory when the render starts."
    ]
  }),
  ssrName: "mediaCacheSizeInBytes",
  docLink: "https://www.remotion.dev/docs/media/video#setting-the-cache-size",
  type: 0,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag82] !== undefined) {
      return {
        source: "cli",
        value: commandLine[cliFlag82]
      };
    }
    if (mediaCacheSizeInBytes !== null) {
      return {
        source: "config",
        value: mediaCacheSizeInBytes
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (size) => {
    mediaCacheSizeInBytes = size ?? null;
  },
  id: cliFlag82
};

// src/path-normalize.ts
var SLASH = 47;
var DOT = 46;
var assertPath = (path) => {
  const t = typeof path;
  if (t !== "string") {
    throw new TypeError(`Expected a string, got a ${t}`);
  }
};
var posixNormalize = (path, allowAboveRoot) => {
  let res = "";
  let lastSegmentLength = 0;
  let lastSlash = -1;
  let dots = 0;
  let code;
  for (let i = 0;i <= path.length; ++i) {
    if (i < path.length) {
      code = path.charCodeAt(i);
    } else if (code === SLASH) {
      break;
    } else {
      code = SLASH;
    }
    if (code === SLASH) {
      if (lastSlash === i - 1 || dots === 1) {} else if (lastSlash !== i - 1 && dots === 2) {
        if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== DOT || res.charCodeAt(res.length - 2) !== DOT) {
          if (res.length > 2) {
            const lastSlashIndex = res.lastIndexOf("/");
            if (lastSlashIndex !== res.length - 1) {
              if (lastSlashIndex === -1) {
                res = "";
                lastSegmentLength = 0;
              } else {
                res = res.slice(0, lastSlashIndex);
                lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
              }
              lastSlash = i;
              dots = 0;
              continue;
            }
          } else if (res.length === 2 || res.length === 1) {
            res = "";
            lastSegmentLength = 0;
            lastSlash = i;
            dots = 0;
            continue;
          }
        }
        if (allowAboveRoot) {
          if (res.length > 0) {
            res += "/..";
          } else {
            res = "..";
          }
          lastSegmentLength = 2;
        }
      } else {
        if (res.length > 0) {
          res += "/" + path.slice(lastSlash + 1, i);
        } else {
          res = path.slice(lastSlash + 1, i);
        }
        lastSegmentLength = i - lastSlash - 1;
      }
      lastSlash = i;
      dots = 0;
    } else if (code === DOT && dots !== -1) {
      ++dots;
    } else {
      dots = -1;
    }
  }
  return res;
};
var decode = (s) => {
  try {
    return decodeURIComponent(s);
  } catch {
    return s;
  }
};
var pathNormalize = (p) => {
  assertPath(p);
  let path = p;
  if (path.length === 0) {
    return ".";
  }
  const isAbsolute = path.charCodeAt(0) === SLASH;
  const trailingSeparator = path.charCodeAt(path.length - 1) === SLASH;
  path = decode(path);
  path = posixNormalize(path, !isAbsolute);
  if (path.length === 0 && !isAbsolute) {
    path = ".";
  }
  if (path.length > 0 && trailingSeparator) {
    path += "/";
  }
  if (isAbsolute) {
    return "/" + path;
  }
  return path;
};

// src/get-extension-of-filename.ts
var getExtensionOfFilename = (filename) => {
  if (filename === null) {
    return null;
  }
  const filenameArr = pathNormalize(filename).split(".");
  const hasExtension = filenameArr.length >= 2;
  const filenameArrLength = filenameArr.length;
  const extension = hasExtension ? filenameArr[filenameArrLength - 1] : null;
  return extension;
};

// src/options/video-codec.tsx

var codec;
var setCodec = (newCodec) => {
  if (newCodec === undefined) {
    codec = undefined;
    return;
  }
  if (!validCodecs.includes(newCodec)) {
    throw new Error(`Codec must be one of the following: ${validCodecs.join(", ")}, but got ${newCodec}`);
  }
  codec = newCodec;
};
var getOutputCodecOrUndefined = () => {
  return codec;
};
var deriveCodecsFromFilename = (extension) => {
  if (extension === null) {
    return { possible: [], default: null };
  }
  return {
    default: defaultCodecsForFileExtension[extension] ?? null,
    possible: makeFileExtensionMap()[extension] ?? []
  };
};
var cliFlag83 = "codec";
var videoCodecOption = {
  name: "Codec",
  cliFlag: cliFlag83,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "H264 works well in most cases, but sometimes it's worth going for a different codec. WebM achieves higher compression but is slower to render. WebM, GIF and ProRes support transparency."
  }),
  ssrName: "codec",
  docLink: "https://www.remotion.dev/docs/encoding/#choosing-a-codec",
  type: "",
  getValue: ({ commandLine }, {
    compositionCodec,
    configFile,
    downloadName,
    outName,
    uiCodec
  }) => {
    if (uiCodec) {
      return { value: uiCodec, source: "via UI" };
    }
    const downloadNameExtension = getExtensionOfFilename(downloadName);
    const outNameExtension = getExtensionOfFilename(outName);
    const derivedDownloadCodecs = deriveCodecsFromFilename(downloadNameExtension);
    const derivedOutNameCodecs = deriveCodecsFromFilename(outNameExtension);
    if (derivedDownloadCodecs.possible.length > 0 && derivedOutNameCodecs.possible.length > 0 && derivedDownloadCodecs.possible.join("") !== derivedOutNameCodecs.possible.join("")) {
      throw new TypeError(`The download name is ${downloadName} but the output name is ${outName}. The file extensions must match`);
    }
    const cliArgument = commandLine[cliFlag83];
    if (cliArgument) {
      if (derivedDownloadCodecs.possible.length > 0 && derivedDownloadCodecs.possible.indexOf(cliArgument) === -1) {
        throw new TypeError(`The download name is ${downloadName} but --codec=${cliArgument} was passed. The download name implies a codec of ${derivedDownloadCodecs.possible.join(" or ")} which does not align with the --codec flag.`);
      }
      if (derivedOutNameCodecs.possible.length > 0 && derivedOutNameCodecs.possible.indexOf(cliArgument) === -1) {
        throw new TypeError(`The out name is ${outName} but --codec=${cliArgument} was passed. The out name implies a codec of ${derivedOutNameCodecs.possible.join(" or ")} which does not align with the --codec flag.`);
      }
      return { value: cliArgument, source: "from --codec flag" };
    }
    if (derivedDownloadCodecs.possible.length > 0) {
      return {
        value: derivedDownloadCodecs.default,
        source: "derived from download name"
      };
    }
    if (derivedOutNameCodecs.possible.length > 0) {
      if (compositionCodec && derivedOutNameCodecs.possible.includes(compositionCodec)) {
        return {
          value: compositionCodec,
          source: "derived from out name + compositionCodec from calculateMetadata"
        };
      }
      if (configFile && derivedOutNameCodecs.possible.includes(configFile)) {
        return {
          value: configFile,
          source: "derived from out name + config file"
        };
      }
      return {
        value: derivedOutNameCodecs.default,
        source: "derived from out name"
      };
    }
    if (compositionCodec) {
      return { value: compositionCodec, source: "via calculateMetadata" };
    }
    if (configFile) {
      return {
        value: configFile,
        source: "Config file"
      };
    }
    return { value: DEFAULT_CODEC, source: "default" };
  },
  setConfig: setCodec,
  id: cliFlag83
};

// src/options/video-image-format.tsx

var currentVideoImageFormat = null;
var cliFlag84 = "image-format";
var videoImageFormatOption = {
  name: "Video Image Format",
  cliFlag: cliFlag84,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "The image format to use when rendering frames for a video. Must be one of",
      " ",
      validVideoImageFormats.map((f) => `"${f}"`).join(", "),
      ". Default:",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: '"jpeg"'
      }),
      ". JPEG is faster, but does not support transparency."
    ]
  }),
  ssrName: "imageFormat",
  docLink: "https://www.remotion.dev/docs/renderer/render-media#imageformat",
  type: null,
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag84] !== undefined) {
      const value3 = commandLine[cliFlag84];
      if (!validVideoImageFormats.includes(value3)) {
        throw new Error(`Invalid video image format: ${value3}. Must be one of: ${validVideoImageFormats.join(", ")}`);
      }
      return {
        source: "cli",
        value: value3
      };
    }
    if (currentVideoImageFormat !== null) {
      return {
        source: "config",
        value: currentVideoImageFormat
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value3) => {
    if (value3 === null) {
      currentVideoImageFormat = null;
      return;
    }
    if (!validVideoImageFormats.includes(value3)) {
      throw new TypeError([
        `Value ${value3} is not valid as a video image format.`,
        value3 === "jpg" ? 'Did you mean "jpeg"?' : null
      ].filter(Boolean).join(" "));
    }
    currentVideoImageFormat = value3;
  },
  id: "video-image-format"
};

// src/options/webhook-custom-data.tsx

var cliFlag85 = "webhook-custom-data";
var webhookCustomDataOption = {
  name: "Webhook custom data",
  cliFlag: cliFlag85,
  description: (type) => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Pass up to 1,024 bytes of a JSON-serializable object to the webhook. This data will be included in the webhook payload.",
      " ",
      type === "cli" ? "Alternatively, pass a file path pointing to a JSON file" : null
    ]
  }),
  ssrName: "customData",
  docLink: "https://www.remotion.dev/docs/lambda/webhooks",
  type: {},
  getValue: () => {
    throw new Error("Option resolution not implemented");
  },
  setConfig: () => {
    throw new Error("Not implemented");
  },
  id: cliFlag85
};

// src/options/webpack-poll.tsx

var cliFlag86 = "webpack-poll";
var webpackPolling = null;
var webpackPollOption = {
  name: "Webpack Polling",
  cliFlag: cliFlag86,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: "Enables Webpack polling instead of the file system event listeners for hot reloading. This is useful if you are inside a virtual machine or have a remote file system. Pass a value in milliseconds."
  }),
  ssrName: null,
  docLink: "https://www.remotion.dev/docs/config#setwebpackpollinginmilliseconds",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag86] !== undefined) {
      const val = commandLine[cliFlag86];
      if (typeof val !== "number") {
        throw new TypeError(`Webpack polling must be a number, got ${JSON.stringify(val)}`);
      }
      return {
        source: "cli",
        value: val
      };
    }
    if (webpackPolling !== null) {
      return {
        source: "config",
        value: webpackPolling
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  setConfig: (value3) => {
    if (typeof value3 !== "number" && value3 !== null) {
      throw new TypeError(`Polling must be a number or null, got ${JSON.stringify(value3)} instead.`);
    }
    webpackPolling = value3;
  },
  type: 0,
  id: cliFlag86
};

// src/options/x264-preset.tsx

var x264PresetOptions = [
  "ultrafast",
  "superfast",
  "veryfast",
  "faster",
  "fast",
  "medium",
  "slow",
  "slower",
  "veryslow",
  "placebo"
];
var preset = null;
var cliFlag87 = "x264-preset";
var DEFAULT_PRESET = "medium";
var x264Option = {
  name: "x264 Preset",
  cliFlag: cliFlag87,
  description: () => /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsxs)(react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.Fragment, {
    children: [
      "Sets a x264 preset profile. Only applies to videos rendered with",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "h264"
      }),
      " codec.",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      "Possible values: ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "superfast"
      }),
      ", ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "veryfast"
      }),
      ",",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "faster"
      }),
      ", ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "fast"
      }),
      ", ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "medium"
      }),
      ",",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "slow"
      }),
      ", ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "slower"
      }),
      ", ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "veryslow"
      }),
      ",",
      " ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: "placebo"
      }),
      ".",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("br", {}),
      "Default: ",
      /* @__PURE__ */ (0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_1__.jsx)("code", {
        children: DEFAULT_PRESET
      })
    ]
  }),
  ssrName: "x264Preset",
  docLink: "https://www.remotion.dev/docs/renderer/render-media",
  type: "fast",
  getValue: ({ commandLine }) => {
    const value3 = commandLine[cliFlag87];
    if (typeof value3 !== "undefined") {
      return { value: value3, source: "cli" };
    }
    if (preset !== null) {
      return { value: preset, source: "config" };
    }
    return { value: null, source: "default" };
  },
  setConfig: (profile) => {
    preset = profile;
  },
  id: cliFlag87
};

// src/options/index.tsx
var allOptions = {
  audioCodecOption,
  browserExecutableOption,
  concurrencyOption,
  scaleOption,
  crfOption,
  jpegQualityOption,
  videoBitrateOption,
  audioBitrateOption,
  enforceAudioOption,
  everyNthFrameOption,
  mutedOption,
  videoCodecOption,
  offthreadVideoCacheSizeInBytesOption,
  offthreadVideoThreadsOption,
  webhookCustomDataOption,
  colorSpaceOption,
  deleteAfterOption,
  disableWebSecurityOption,
  disallowParallelEncodingOption,
  folderExpiryOption,
  enableMultiprocessOnLinuxOption,
  glOption,
  enableLambdaInsights,
  encodingMaxRateOption,
  encodingBufferSizeOption,
  beepOnFinishOption,
  numberOfGifLoopsOption,
  reproOption,
  runsOption,
  noOpenOption,
  pixelFormatOption,
  preferLosslessOption: preferLosslessAudioOption,
  proResProfileOption,
  x264Option,
  logLevelOption,
  delayRenderTimeoutInMillisecondsOption,
  headlessOption,
  overwriteOption,
  binariesDirectoryOption,
  forSeamlessAacConcatenationOption,
  separateAudioOption,
  publicPathOption,
  publicDirOption,
  onBrowserDownloadOption,
  throwIfSiteExistsOption,
  disableGitSourceOption,
  metadataOption,
  hardwareAccelerationOption,
  chromeModeOption,
  apiKeyOption,
  licenseKeyOption,
  audioLatencyHintOption,
  enableCrossSiteIsolationOption,
  ignoreCertificateErrorsOption,
  imageSequencePatternOption,
  mediaCacheSizeInBytesOption,
  darkModeOption,
  publicLicenseKeyOption,
  isProductionOption,
  askAIOption,
  experimentalClientSideRenderingOption,
  experimentalVisualModeOption,
  keyboardShortcutsOption,
  framesOption,
  forceNewStudioOption,
  numberOfSharedAudioTagsOption,
  ipv4Option,
  stillImageFormatOption,
  userAgentOption,
  videoImageFormatOption,
  overrideHeightOption,
  overrideWidthOption,
  overrideFpsOption,
  overrideDurationOption,
  rspackOption,
  outDirOption,
  packageManagerOption,
  webpackPollOption,
  stillFrameOption,
  imageSequenceOption,
  versionFlagOption,
  bundleCacheOption,
  envFileOption,
  portOption,
  propsOption,
  configOption,
  browserOption
};

// src/options/options-map.ts
var optionsMap = {
  renderMedia: {
    mediaCacheSizeInBytes: mediaCacheSizeInBytesOption,
    offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytesOption,
    offthreadVideoThreads: offthreadVideoThreadsOption,
    videoBitrate: videoBitrateOption,
    numberOfGifLoops: numberOfGifLoopsOption,
    repro: reproOption,
    x264Preset: x264Option,
    audioBitrate: audioBitrateOption,
    colorSpace: colorSpaceOption,
    codec: videoCodecOption,
    disallowParallelEncoding: disallowParallelEncodingOption,
    jpegQuality: jpegQualityOption,
    encodingMaxRate: encodingMaxRateOption,
    encodingBufferSize: encodingBufferSizeOption,
    muted: mutedOption,
    logLevel: logLevelOption,
    timeoutInMilliseconds: delayRenderTimeoutInMillisecondsOption,
    binariesDirectory: binariesDirectoryOption,
    forSeamlessAacConcatenation: forSeamlessAacConcatenationOption,
    separateAudioTo: separateAudioOption,
    audioCodec: audioCodecOption,
    onBrowserDownload: onBrowserDownloadOption,
    hardwareAcceleration: hardwareAccelerationOption,
    chromeMode: chromeModeOption,
    licenseKey: licenseKeyOption
  },
  stitchFramesToVideo: {
    separateAudioTo: separateAudioOption,
    hardwareAcceleration: hardwareAccelerationOption
  },
  renderStill: {
    mediaCacheSizeInBytes: mediaCacheSizeInBytesOption,
    offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytesOption,
    offthreadVideoThreads: offthreadVideoThreadsOption,
    jpegQuality: jpegQualityOption,
    logLevel: logLevelOption,
    timeoutInMilliseconds: delayRenderTimeoutInMillisecondsOption,
    binariesDirectory: binariesDirectoryOption,
    onBrowserDownload: onBrowserDownloadOption,
    chromeMode: chromeModeOption,
    apiKey: apiKeyOption,
    licenseKey: licenseKeyOption
  },
  getCompositions: {
    mediaCacheSizeInBytes: mediaCacheSizeInBytesOption,
    offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytesOption,
    offthreadVideoThreads: offthreadVideoThreadsOption,
    logLevel: logLevelOption,
    timeoutInMilliseconds: delayRenderTimeoutInMillisecondsOption,
    binariesDirectory: binariesDirectoryOption,
    onBrowserDownload: onBrowserDownloadOption,
    chromeMode: chromeModeOption
  },
  selectComposition: {
    mediaCacheSizeInBytes: mediaCacheSizeInBytesOption,
    offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytesOption,
    offthreadVideoThreads: offthreadVideoThreadsOption,
    logLevel: logLevelOption,
    timeoutInMilliseconds: delayRenderTimeoutInMillisecondsOption,
    binariesDirectory: binariesDirectoryOption,
    onBrowserDownload: onBrowserDownloadOption,
    chromeMode: chromeModeOption
  },
  renderFrames: {
    mediaCacheSizeInBytes: mediaCacheSizeInBytesOption,
    forSeamlessAacConcatenation: forSeamlessAacConcatenationOption,
    offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytesOption,
    offthreadVideoThreads: offthreadVideoThreadsOption,
    jpegQuality: jpegQualityOption,
    logLevel: logLevelOption,
    timeoutInMilliseconds: delayRenderTimeoutInMillisecondsOption,
    binariesDirectory: binariesDirectoryOption,
    onBrowserDownload: onBrowserDownloadOption,
    chromeMode: chromeModeOption,
    imageSequencePattern: imageSequencePatternOption
  },
  renderMediaOnLambda: {
    mediaCacheSizeInBytes: mediaCacheSizeInBytesOption,
    offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytesOption,
    offthreadVideoThreads: offthreadVideoThreadsOption,
    videoBitrate: videoBitrateOption,
    numberOfGifLoops: numberOfGifLoopsOption,
    preferLossless: preferLosslessAudioOption,
    audioBitrate: audioBitrateOption,
    deleteAfter: deleteAfterOption,
    x264Preset: x264Option,
    encodingMaxRate: encodingMaxRateOption,
    encodingBufferSize: encodingBufferSizeOption,
    colorSpace: colorSpaceOption,
    muted: mutedOption,
    logLevel: logLevelOption,
    timeoutInMilliseconds: delayRenderTimeoutInMillisecondsOption,
    apiKey: apiKeyOption,
    licenseKey: licenseKeyOption
  },
  renderStillOnLambda: {
    mediaCacheSizeInBytes: mediaCacheSizeInBytesOption,
    offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytesOption,
    offthreadVideoThreads: offthreadVideoThreadsOption,
    jpegQuality: jpegQualityOption,
    logLevel: logLevelOption,
    deleteAfter: deleteAfterOption,
    scale: scaleOption,
    timeoutInMilliseconds: delayRenderTimeoutInMillisecondsOption,
    apiKey: apiKeyOption,
    licenseKey: licenseKeyOption
  },
  getCompositionsOnLambda: {
    mediaCacheSizeInBytes: mediaCacheSizeInBytesOption,
    offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytesOption,
    logLevel: logLevelOption,
    timeoutInMilliseconds: delayRenderTimeoutInMillisecondsOption
  },
  renderMediaOnCloudRun: {
    mediaCacheSizeInBytes: mediaCacheSizeInBytesOption,
    offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytesOption,
    offthreadVideoThreads: offthreadVideoThreadsOption,
    numberOfGifLoops: numberOfGifLoopsOption,
    preferLossless: preferLosslessAudioOption,
    colorSpace: colorSpaceOption,
    audioBitrate: audioBitrateOption,
    videoBitrate: videoBitrateOption,
    x264Preset: x264Option,
    encodingMaxRate: encodingMaxRateOption,
    encodingBufferSize: encodingBufferSizeOption,
    muted: mutedOption,
    logLevel: logLevelOption,
    delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMillisecondsOption,
    enforceAudioTrack: enforceAudioOption,
    scale: scaleOption,
    crf: crfOption,
    jpegQuality: jpegQualityOption
  },
  renderStillOnCloudRun: {
    mediaCacheSizeInBytes: mediaCacheSizeInBytesOption,
    offthreadVideoCacheSizeInBytes: offthreadVideoCacheSizeInBytesOption,
    offthreadVideoThreads: offthreadVideoThreadsOption,
    logLevel: logLevelOption,
    scale: scaleOption,
    jpegQuality: jpegQualityOption,
    delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMillisecondsOption
  },
  ensureBrowser: {
    logLevel: logLevelOption,
    onBrowserDownload: onBrowserDownloadOption,
    chromeMode: chromeModeOption
  },
  openBrowser: {
    logLevel: logLevelOption,
    onBrowserDownload: onBrowserDownloadOption,
    chromeMode: chromeModeOption
  },
  deploySiteLambda: {
    logLevel: logLevelOption,
    throwIfSiteExists: throwIfSiteExistsOption
  },
  deploySiteCloudRun: {
    logLevel: logLevelOption
  }
};

// src/validate-output-filename.ts
var validateOutputFilename = ({
  codec: codec2,
  audioCodecSetting,
  extension,
  preferLossless,
  separateAudioTo
}) => {
  if (!defaultFileExtensionMap[codec2]) {
    throw new TypeError(`The codec "${codec2}" is not supported. Supported codecs are: ${Object.keys(defaultFileExtensionMap).join(", ")}`);
  }
  const map = defaultFileExtensionMap[codec2];
  const resolvedAudioCodec = resolveAudioCodec({
    codec: codec2,
    preferLossless,
    setting: audioCodecSetting,
    separateAudioTo
  });
  if (resolvedAudioCodec === null) {
    if (extension !== map.default) {
      throw new TypeError(`When using the ${codec2} codec, the output filename must end in .${map.default}.`);
    }
    return;
  }
  if (!(resolvedAudioCodec in map.forAudioCodec)) {
    throw new Error(`Audio codec ${resolvedAudioCodec} is not supported for codec ${codec2}`);
  }
  const acceptableExtensions = map.forAudioCodec[resolvedAudioCodec].possible;
  if (!acceptableExtensions.includes(extension) && !separateAudioTo) {
    throw new TypeError(`When using the ${codec2} codec with the ${resolvedAudioCodec} audio codec, the output filename must end in one of the following: ${acceptableExtensions.join(", ")}.`);
  }
};

// src/client.ts
var BrowserSafeApis = {
  getFileExtensionFromCodec,
  validCodecs,
  validAudioCodecs,
  getDefaultCrfForCodec,
  getValidCrfRanges,
  proResProfileOptions: remotion_no_react__WEBPACK_IMPORTED_MODULE_0__.NoReactInternals.proResProfileOptions,
  x264PresetOptions,
  hardwareAccelerationOptions,
  validPixelFormats,
  validOpenGlRenderers,
  validPixelFormatsForCodec,
  validVideoImageFormats,
  validStillImageFormats,
  DEFAULT_PIXEL_FORMAT,
  DEFAULT_TIMEOUT,
  DEFAULT_JPEG_QUALITY,
  DEFAULT_COLOR_SPACE,
  supportedAudioCodecs,
  defaultFileExtensionMap,
  defaultAudioCodecs,
  defaultCodecsForFileExtension,
  validateOutputFilename,
  options: allOptions,
  validColorSpaces,
  optionsMap,
  codecSupportsCrf,
  codecSupportsVideoBitrate,
  logLevels,
  getOutputCodecOrUndefined,
  getExtensionFromAudioCodec,
  validChromeModeOptions
};



/***/ },

/***/ 1891
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   c: () => (/* binding */ NoReactAPIs)
/* harmony export */ });
// src/is-audio-codec.ts
var isAudioCodec = (codec) => {
  return codec === "mp3" || codec === "aac" || codec === "wav";
};

// src/codec-supports-media.ts
var support = {
  "h264-mkv": {
    audio: true,
    video: true
  },
  aac: {
    audio: true,
    video: false
  },
  gif: {
    video: true,
    audio: false
  },
  h264: {
    video: true,
    audio: true
  },
  "h264-ts": {
    video: true,
    audio: true
  },
  h265: {
    video: true,
    audio: true
  },
  mp3: {
    audio: true,
    video: false
  },
  prores: {
    audio: true,
    video: true
  },
  vp8: {
    audio: true,
    video: true
  },
  vp9: {
    audio: true,
    video: true
  },
  wav: {
    audio: true,
    video: false
  }
};
var codecSupportsMedia = (codec) => {
  return support[codec];
};

// src/get-duration-from-frame-range.ts
var getFramesToRender = (frameRange, everyNthFrame) => {
  if (everyNthFrame === 0) {
    throw new Error("everyNthFrame cannot be 0");
  }
  return new Array(frameRange[1] - frameRange[0] + 1).fill(true).map((_, index) => {
    return index + frameRange[0];
  }).filter((index) => {
    return index % everyNthFrame === 0;
  });
};

// src/codec.ts
var validCodecs = [
  "h264",
  "h265",
  "vp8",
  "vp9",
  "mp3",
  "aac",
  "wav",
  "prores",
  "h264-mkv",
  "h264-ts",
  "gif"
];

// src/file-extensions.ts
var defaultFileExtensionMap = {
  "h264-mkv": {
    default: "mkv",
    forAudioCodec: {
      "pcm-16": { possible: ["mkv"], default: "mkv" },
      mp3: { possible: ["mkv"], default: "mkv" }
    }
  },
  "h264-ts": {
    default: "ts",
    forAudioCodec: {
      "pcm-16": { possible: ["ts"], default: "ts" },
      aac: { possible: ["ts"], default: "ts" }
    }
  },
  aac: {
    default: "aac",
    forAudioCodec: {
      aac: {
        possible: ["aac", "3gp", "m4a", "m4b", "mpg", "mpeg"],
        default: "aac"
      },
      "pcm-16": {
        possible: ["wav"],
        default: "wav"
      }
    }
  },
  gif: {
    default: "gif",
    forAudioCodec: {}
  },
  h264: {
    default: "mp4",
    forAudioCodec: {
      "pcm-16": { possible: ["mkv", "mov"], default: "mkv" },
      aac: { possible: ["mp4", "mkv", "mov"], default: "mp4" },
      mp3: { possible: ["mp4", "mkv", "mov"], default: "mp4" }
    }
  },
  h265: {
    default: "mp4",
    forAudioCodec: {
      aac: { possible: ["mp4", "mkv", "hevc"], default: "mp4" },
      "pcm-16": { possible: ["mkv"], default: "mkv" }
    }
  },
  mp3: {
    default: "mp3",
    forAudioCodec: {
      mp3: { possible: ["mp3"], default: "mp3" },
      "pcm-16": { possible: ["wav"], default: "wav" }
    }
  },
  prores: {
    default: "mov",
    forAudioCodec: {
      aac: { possible: ["mov", "mkv", "mxf"], default: "mov" },
      "pcm-16": { possible: ["mov", "mkv", "mxf"], default: "mov" }
    }
  },
  vp8: {
    default: "webm",
    forAudioCodec: {
      "pcm-16": { possible: ["mkv"], default: "mkv" },
      opus: { possible: ["webm"], default: "webm" }
    }
  },
  vp9: {
    default: "webm",
    forAudioCodec: {
      "pcm-16": { possible: ["mkv"], default: "mkv" },
      opus: { possible: ["webm"], default: "webm" }
    }
  },
  wav: {
    default: "wav",
    forAudioCodec: {
      "pcm-16": { possible: ["wav"], default: "wav" }
    }
  }
};

// src/get-extension-from-codec.ts
var getFileExtensionFromCodec = (codec, audioCodec) => {
  if (!validCodecs.includes(codec)) {
    throw new Error(`Codec must be one of the following: ${validCodecs.join(", ")}, but got ${codec}`);
  }
  const map = defaultFileExtensionMap[codec];
  if (audioCodec === null) {
    return map.default;
  }
  const typedAudioCodec = audioCodec;
  if (!(typedAudioCodec in map.forAudioCodec)) {
    throw new Error(`Audio codec ${typedAudioCodec} is not supported for codec ${codec}`);
  }
  return map.forAudioCodec[audioCodec].default;
};

// src/path-normalize.ts
var SLASH = 47;
var DOT = 46;
var assertPath = (path) => {
  const t = typeof path;
  if (t !== "string") {
    throw new TypeError(`Expected a string, got a ${t}`);
  }
};
var posixNormalize = (path, allowAboveRoot) => {
  let res = "";
  let lastSegmentLength = 0;
  let lastSlash = -1;
  let dots = 0;
  let code;
  for (let i = 0;i <= path.length; ++i) {
    if (i < path.length) {
      code = path.charCodeAt(i);
    } else if (code === SLASH) {
      break;
    } else {
      code = SLASH;
    }
    if (code === SLASH) {
      if (lastSlash === i - 1 || dots === 1) {} else if (lastSlash !== i - 1 && dots === 2) {
        if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== DOT || res.charCodeAt(res.length - 2) !== DOT) {
          if (res.length > 2) {
            const lastSlashIndex = res.lastIndexOf("/");
            if (lastSlashIndex !== res.length - 1) {
              if (lastSlashIndex === -1) {
                res = "";
                lastSegmentLength = 0;
              } else {
                res = res.slice(0, lastSlashIndex);
                lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
              }
              lastSlash = i;
              dots = 0;
              continue;
            }
          } else if (res.length === 2 || res.length === 1) {
            res = "";
            lastSegmentLength = 0;
            lastSlash = i;
            dots = 0;
            continue;
          }
        }
        if (allowAboveRoot) {
          if (res.length > 0) {
            res += "/..";
          } else {
            res = "..";
          }
          lastSegmentLength = 2;
        }
      } else {
        if (res.length > 0) {
          res += "/" + path.slice(lastSlash + 1, i);
        } else {
          res = path.slice(lastSlash + 1, i);
        }
        lastSegmentLength = i - lastSlash - 1;
      }
      lastSlash = i;
      dots = 0;
    } else if (code === DOT && dots !== -1) {
      ++dots;
    } else {
      dots = -1;
    }
  }
  return res;
};
var decode = (s) => {
  try {
    return decodeURIComponent(s);
  } catch {
    return s;
  }
};
var pathNormalize = (p) => {
  assertPath(p);
  let path = p;
  if (path.length === 0) {
    return ".";
  }
  const isAbsolute = path.charCodeAt(0) === SLASH;
  const trailingSeparator = path.charCodeAt(path.length - 1) === SLASH;
  path = decode(path);
  path = posixNormalize(path, !isAbsolute);
  if (path.length === 0 && !isAbsolute) {
    path = ".";
  }
  if (path.length > 0 && trailingSeparator) {
    path += "/";
  }
  if (isAbsolute) {
    return "/" + path;
  }
  return path;
};

// src/get-extension-of-filename.ts
var getExtensionOfFilename = (filename) => {
  if (filename === null) {
    return null;
  }
  const filenameArr = pathNormalize(filename).split(".");
  const hasExtension = filenameArr.length >= 2;
  const filenameArrLength = filenameArr.length;
  const extension = hasExtension ? filenameArr[filenameArrLength - 1] : null;
  return extension;
};

// src/options/separate-audio.tsx
var DEFAULT = null;
var cliFlag = "separate-audio-to";
var separateAudioOption = {
  cliFlag,
  description: () => `If set, the audio will not be included in the main output but rendered as a separate file at the location you pass. It is recommended to use an absolute path. If a relative path is passed, it is relative to the Remotion Root.`,
  docLink: "https://remotion.dev/docs/renderer/render-media",
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag]) {
      return {
        source: "cli",
        value: commandLine[cliFlag]
      };
    }
    return {
      source: "default",
      value: DEFAULT
    };
  },
  name: "Separate audio to",
  setConfig: () => {
    throw new Error("Not implemented");
  },
  ssrName: "separateAudioTo",
  type: "string",
  id: cliFlag
};

// src/options/audio-codec.tsx
var validAudioCodecs = ["pcm-16", "aac", "mp3", "opus"];
var supportedAudioCodecs = {
  h264: ["aac", "pcm-16", "mp3"],
  "h264-mkv": ["pcm-16", "mp3"],
  "h264-ts": ["pcm-16", "aac"],
  aac: ["aac", "pcm-16"],
  avi: [],
  gif: [],
  h265: ["aac", "pcm-16"],
  mp3: ["mp3", "pcm-16"],
  prores: ["aac", "pcm-16"],
  vp8: ["opus", "pcm-16"],
  vp9: ["opus", "pcm-16"],
  wav: ["pcm-16"]
};
var _satisfies = supportedAudioCodecs;
if (_satisfies) {}
var cliFlag2 = "audio-codec";
var ssrName = "audioCodec";
var defaultAudioCodecs = {
  "h264-mkv": {
    lossless: "pcm-16",
    compressed: "pcm-16"
  },
  "h264-ts": {
    lossless: "pcm-16",
    compressed: "aac"
  },
  aac: {
    lossless: "pcm-16",
    compressed: "aac"
  },
  gif: {
    lossless: null,
    compressed: null
  },
  h264: {
    lossless: "pcm-16",
    compressed: "aac"
  },
  h265: {
    lossless: "pcm-16",
    compressed: "aac"
  },
  mp3: {
    lossless: "pcm-16",
    compressed: "mp3"
  },
  prores: {
    lossless: "pcm-16",
    compressed: "pcm-16"
  },
  vp8: {
    lossless: "pcm-16",
    compressed: "opus"
  },
  vp9: {
    lossless: "pcm-16",
    compressed: "opus"
  },
  wav: {
    lossless: "pcm-16",
    compressed: "pcm-16"
  }
};
var extensionMap = {
  aac: "aac",
  mp3: "mp3",
  opus: "opus",
  "pcm-16": "wav"
};
var resolveAudioCodec = ({
  codec,
  setting,
  preferLossless,
  separateAudioTo
}) => {
  let derivedFromSeparateAudioToExtension = null;
  if (separateAudioTo) {
    const extension = separateAudioTo.split(".").pop();
    for (const [key, value] of Object.entries(extensionMap)) {
      if (value === extension) {
        derivedFromSeparateAudioToExtension = key;
        if (!supportedAudioCodecs[codec].includes(derivedFromSeparateAudioToExtension) && derivedFromSeparateAudioToExtension) {
          throw new Error(`The codec is ${codec} but the audio codec derived from --${separateAudioOption.cliFlag} is ${derivedFromSeparateAudioToExtension}. The only supported codecs are: ${supportedAudioCodecs[codec].join(", ")}`);
        }
      }
    }
  }
  if (preferLossless) {
    const selected = getDefaultAudioCodec({ codec, preferLossless });
    if (derivedFromSeparateAudioToExtension && selected !== derivedFromSeparateAudioToExtension) {
      throw new Error(`The audio codec derived from --${separateAudioOption.cliFlag} is ${derivedFromSeparateAudioToExtension}, but does not match the audio codec derived from the "Prefer lossless" option (${selected}). Remove any conflicting options.`);
    }
    return selected;
  }
  if (setting === null) {
    if (derivedFromSeparateAudioToExtension) {
      return derivedFromSeparateAudioToExtension;
    }
    return getDefaultAudioCodec({ codec, preferLossless });
  }
  if (derivedFromSeparateAudioToExtension !== setting && derivedFromSeparateAudioToExtension) {
    throw new Error(`The audio codec derived from --${separateAudioOption.cliFlag} is ${derivedFromSeparateAudioToExtension}, but does not match the audio codec derived from your ${audioCodecOption.name} setting (${setting}). Remove any conflicting options.`);
  }
  return setting;
};
var getDefaultAudioCodec = ({
  codec,
  preferLossless
}) => {
  return defaultAudioCodecs[codec][preferLossless ? "lossless" : "compressed"];
};
var _audioCodec = null;
var audioCodecOption = {
  cliFlag: cliFlag2,
  setConfig: (audioCodec) => {
    if (audioCodec === null) {
      _audioCodec = null;
      return;
    }
    if (!validAudioCodecs.includes(audioCodec)) {
      throw new Error(`Audio codec must be one of the following: ${validAudioCodecs.join(", ")}, but got ${audioCodec}`);
    }
    _audioCodec = audioCodec;
  },
  getValue: ({ commandLine }) => {
    if (commandLine[cliFlag2]) {
      const codec = commandLine[cliFlag2];
      if (!validAudioCodecs.includes(commandLine[cliFlag2])) {
        throw new Error(`Audio codec must be one of the following: ${validAudioCodecs.join(", ")}, but got ${codec}`);
      }
      return {
        source: "cli",
        value: commandLine[cliFlag2]
      };
    }
    if (_audioCodec !== null) {
      return {
        source: "config",
        value: _audioCodec
      };
    }
    return {
      source: "default",
      value: null
    };
  },
  description: () => `Set the format of the audio that is embedded in the video. Not all codec and audio codec combinations are supported and certain combinations require a certain file extension and container format. See the table in the docs to see possible combinations.`,
  docLink: "https://www.remotion.dev/docs/encoding/#audio-codec",
  name: "Audio Codec",
  ssrName,
  type: "aac",
  id: cliFlag2
};

// src/validate-output-filename.ts
var validateOutputFilename = ({
  codec,
  audioCodecSetting,
  extension,
  preferLossless,
  separateAudioTo
}) => {
  if (!defaultFileExtensionMap[codec]) {
    throw new TypeError(`The codec "${codec}" is not supported. Supported codecs are: ${Object.keys(defaultFileExtensionMap).join(", ")}`);
  }
  const map = defaultFileExtensionMap[codec];
  const resolvedAudioCodec = resolveAudioCodec({
    codec,
    preferLossless,
    setting: audioCodecSetting,
    separateAudioTo
  });
  if (resolvedAudioCodec === null) {
    if (extension !== map.default) {
      throw new TypeError(`When using the ${codec} codec, the output filename must end in .${map.default}.`);
    }
    return;
  }
  if (!(resolvedAudioCodec in map.forAudioCodec)) {
    throw new Error(`Audio codec ${resolvedAudioCodec} is not supported for codec ${codec}`);
  }
  const acceptableExtensions = map.forAudioCodec[resolvedAudioCodec].possible;
  if (!acceptableExtensions.includes(extension) && !separateAudioTo) {
    throw new TypeError(`When using the ${codec} codec with the ${resolvedAudioCodec} audio codec, the output filename must end in one of the following: ${acceptableExtensions.join(", ")}.`);
  }
};

// src/pure.ts
var NoReactAPIs = {
  getExtensionOfFilename,
  getFileExtensionFromCodec,
  validateOutputFilename,
  getFramesToRender,
  codecSupportsMedia,
  isAudioCodec
};



/***/ },

/***/ 9249
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";

// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  A4: () => (/* binding */ getDefaultAudioCodecForContainer),
  Xq: () => (/* binding */ esm_getEncodableAudioCodecs),
  cQ: () => (/* binding */ esm_getEncodableVideoCodecs),
  w_: () => (/* binding */ getSupportedAudioCodecsForContainer),
  lT: () => (/* binding */ getSupportedVideoCodecsForContainer),
  CE: () => (/* binding */ renderMediaOnWeb),
  Uu: () => (/* binding */ renderStillOnWeb)
});

// UNUSED EXPORTS: canRenderMediaOnWeb, getDefaultVideoCodecForContainer

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/codec.js
var src_codec = __webpack_require__(1188);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/id3.js
var id3 = __webpack_require__(7576);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/metadata.js
var src_metadata = __webpack_require__(5165);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/misc.js
var misc = __webpack_require__(3912);
;// ./node_modules/mediabunny/dist/modules/src/muxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

class Muxer {
    constructor(output) {
        this.mutex = new misc/* AsyncMutex */.aD();
        /**
         * This field is used to synchronize multiple MediaStreamTracks. They use the same time coordinate system across
         * tracks, and to ensure correct audio-video sync, we must use the same offset for all of them. The reason an offset
         * is needed at all is because the timestamps typically don't start at zero.
         */
        this.firstMediaStreamTimestamp = null;
        this.trackTimestampInfo = new WeakMap();
        this.output = output;
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    onTrackClose(track) { }
    validateAndNormalizeTimestamp(track, timestampInSeconds, isKeyPacket) {
        timestampInSeconds += track.source._timestampOffset;
        let timestampInfo = this.trackTimestampInfo.get(track);
        if (!timestampInfo) {
            if (!isKeyPacket) {
                throw new Error('First packet must be a key packet.');
            }
            timestampInfo = {
                maxTimestamp: timestampInSeconds,
                maxTimestampBeforeLastKeyPacket: timestampInSeconds,
            };
            this.trackTimestampInfo.set(track, timestampInfo);
        }
        if (timestampInSeconds < 0) {
            throw new Error(`Timestamps must be non-negative (got ${timestampInSeconds}s).`);
        }
        if (isKeyPacket) {
            timestampInfo.maxTimestampBeforeLastKeyPacket = timestampInfo.maxTimestamp;
        }
        if (timestampInSeconds < timestampInfo.maxTimestampBeforeLastKeyPacket) {
            throw new Error(`Timestamps cannot be smaller than the largest timestamp of the previous GOP (a GOP begins with a key`
                + ` packet and ends right before the next key packet). Got ${timestampInSeconds}s, but largest`
                + ` timestamp is ${timestampInfo.maxTimestampBeforeLastKeyPacket}s.`);
        }
        timestampInfo.maxTimestamp = Math.max(timestampInfo.maxTimestamp, timestampInSeconds);
        return timestampInSeconds;
    }
}

;// ./node_modules/mediabunny/dist/modules/src/adts/adts-misc.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

const buildAdtsHeaderTemplate = (config) => {
    const header = new Uint8Array(7);
    const bitstream = new misc/* Bitstream */._c(header);
    const { objectType, frequencyIndex, channelConfiguration } = config;
    const profile = objectType - 1;
    bitstream.writeBits(12, 0b1111_11111111); // Syncword
    bitstream.writeBits(1, 0); // MPEG Version
    bitstream.writeBits(2, 0); // Layer
    bitstream.writeBits(1, 1); // Protection absence
    bitstream.writeBits(2, profile); // Profile
    bitstream.writeBits(4, frequencyIndex); // MPEG-4 Sampling Frequency Index
    bitstream.writeBits(1, 0); // Private bit
    bitstream.writeBits(3, channelConfiguration); // MPEG-4 Channel Configuration
    bitstream.writeBits(1, 0); // Originality
    bitstream.writeBits(1, 0); // Home
    bitstream.writeBits(1, 0); // Copyright ID bit
    bitstream.writeBits(1, 0); // Copyright ID start
    bitstream.skipBits(13); // Frame length (to be filled per packet)
    bitstream.writeBits(11, 0x7ff); // Buffer fullness
    bitstream.writeBits(2, 0); // Number of AAC frames minus 1
    // Omit CRC check
    return { header, bitstream };
};
const writeAdtsFrameLength = (bitstream, frameLength) => {
    bitstream.pos = 30;
    bitstream.writeBits(13, frameLength);
};

;// ./node_modules/mediabunny/dist/modules/src/adts/adts-muxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */






class AdtsMuxer extends Muxer {
    constructor(output, format) {
        super(output);
        this.header = null;
        this.headerBitstream = null;
        this.inputIsAdts = null;
        this.format = format;
        this.writer = output._writer;
    }
    async start() {
        if (!(0,src_metadata/* metadataTagsAreEmpty */.cc)(this.output._metadataTags)) {
            const id3Writer = new id3/* Id3V2Writer */.Ov(this.writer);
            id3Writer.writeId3V2Tag(this.output._metadataTags);
        }
    }
    async getMimeType() {
        return 'audio/aac';
    }
    async addEncodedVideoPacket() {
        throw new Error('ADTS does not support video.');
    }
    async addEncodedAudioPacket(track, packet, meta) {
        const release = await this.mutex.acquire();
        try {
            this.validateAndNormalizeTimestamp(track, packet.timestamp, packet.type === 'key');
            // First packet - determine input format from metadata
            if (this.inputIsAdts === null) {
                (0,src_codec/* validateAudioChunkMetadata */.P7)(meta);
                const description = meta?.decoderConfig?.description;
                // Follows from the Mediabunny Codec Registry:
                this.inputIsAdts = !description;
                if (!this.inputIsAdts) {
                    const config = (0,src_codec/* parseAacAudioSpecificConfig */.zF)((0,misc/* toUint8Array */.Fo)(description));
                    const template = buildAdtsHeaderTemplate(config);
                    this.header = template.header;
                    this.headerBitstream = template.bitstream;
                }
            }
            if (this.inputIsAdts) {
                // Packets are already ADTS frames, write them directly
                const startPos = this.writer.getPos();
                this.writer.write(packet.data);
                if (this.format._options.onFrame) {
                    this.format._options.onFrame(packet.data, startPos);
                }
            }
            else {
                (0,misc/* assert */.vA)(this.header);
                // Packets are raw AAC, we gotta turn it into ADTS
                const frameLength = packet.data.byteLength + this.header.byteLength;
                writeAdtsFrameLength(this.headerBitstream, frameLength);
                const startPos = this.writer.getPos();
                this.writer.write(this.header);
                this.writer.write(packet.data);
                if (this.format._options.onFrame) {
                    const frameBytes = new Uint8Array(frameLength);
                    frameBytes.set(this.header, 0);
                    frameBytes.set(packet.data, this.header.byteLength);
                    this.format._options.onFrame(frameBytes, startPos);
                }
            }
            await this.writer.flush();
        }
        finally {
            release();
        }
    }
    async addSubtitleCue() {
        throw new Error('ADTS does not support subtitles.');
    }
    async finalize() {
        const release = await this.mutex.acquire(); // Required so that finalize() can't resolve before other calls
        release();
    }
}

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/codec-data.js
var codec_data = __webpack_require__(6297);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/reader.js
var reader = __webpack_require__(7735);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/flac/flac-misc.js
var flac_misc = __webpack_require__(5828);
;// ./node_modules/mediabunny/dist/modules/src/flac/flac-muxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */







const FLAC_HEADER = /* #__PURE__ */ new Uint8Array([0x66, 0x4c, 0x61, 0x43]); // 'fLaC'
const STREAMINFO_SIZE = 38;
const STREAMINFO_BLOCK_SIZE = 34;
class FlacMuxer extends Muxer {
    constructor(output, format) {
        super(output);
        this.metadataWritten = false;
        this.blockSizes = [];
        this.frameSizes = [];
        this.sampleRate = null;
        this.channels = null;
        this.bitsPerSample = null;
        this.writer = output._writer;
        this.format = format;
    }
    async start() {
        this.writer.write(FLAC_HEADER);
    }
    writeHeader({ bitsPerSample, minimumBlockSize, maximumBlockSize, minimumFrameSize, maximumFrameSize, sampleRate, channels, totalSamples, }) {
        (0,misc/* assert */.vA)(this.writer.getPos() === 4);
        const hasMetadata = !(0,src_metadata/* metadataTagsAreEmpty */.cc)(this.output._metadataTags);
        const headerBitstream = new misc/* Bitstream */._c(new Uint8Array(4));
        headerBitstream.writeBits(1, Number(!hasMetadata)); // isLastMetadata
        headerBitstream.writeBits(7, codec_data/* FlacBlockType */.A3.STREAMINFO); // metaBlockType = streaminfo
        headerBitstream.writeBits(24, STREAMINFO_BLOCK_SIZE); // size
        this.writer.write(headerBitstream.bytes);
        const contentBitstream = new misc/* Bitstream */._c(new Uint8Array(18));
        contentBitstream.writeBits(16, minimumBlockSize);
        contentBitstream.writeBits(16, maximumBlockSize);
        contentBitstream.writeBits(24, minimumFrameSize);
        contentBitstream.writeBits(24, maximumFrameSize);
        contentBitstream.writeBits(20, sampleRate);
        contentBitstream.writeBits(3, channels - 1);
        contentBitstream.writeBits(5, bitsPerSample - 1);
        // Bitstream operations are only safe until 32bit, breaks when using 36 bits
        // Splitting up into writing 4 0 bits and then 32 bits is safe
        // This is safe for audio up to (2 ** 32 / 44100 / 3600) -> 27 hours
        // Not implementing support for more than 32 bits now
        if (totalSamples >= 2 ** 32) {
            throw new Error('This muxer only supports writing up to 2 ** 32 samples');
        }
        contentBitstream.writeBits(4, 0);
        contentBitstream.writeBits(32, totalSamples);
        this.writer.write(contentBitstream.bytes);
        // The MD5 hash is calculated from decoded audio data, but we do not have access
        // to it here. We are allowed to set 0:
        // "A value of 0 signifies that the value is not known."
        // https://www.rfc-editor.org/rfc/rfc9639.html#name-streaminfo
        this.writer.write(new Uint8Array(16));
    }
    writePictureBlock(picture) {
        // Header size:
        // 4 bytes: picture type
        // 4 bytes: media type length
        // x bytes: media type
        // 4 bytes: description length
        // y bytes: description
        // 1 bytes: width
        // 1 bytes: height
        // 1 bytes: color depth
        // 1 bytes: number of indexed colors
        // 4 bytes: picture data length
        // z bytes: picture data
        // Total: 20 + x + y + z
        const headerSize = 32
            + picture.mimeType.length
            + (picture.description?.length ?? 0)
            + picture.data.length;
        const header = new Uint8Array(headerSize);
        let offset = 0;
        const dataView = (0,misc/* toDataView */.Zc)(header);
        dataView.setUint32(offset, picture.kind === 'coverFront' ? 3 : picture.kind === 'coverBack' ? 4 : 0);
        offset += 4;
        dataView.setUint32(offset, picture.mimeType.length);
        offset += 4;
        header.set(misc/* textEncoder */.UG.encode(picture.mimeType), 8);
        offset += picture.mimeType.length;
        dataView.setUint32(offset, picture.description?.length ?? 0);
        offset += 4;
        header.set(misc/* textEncoder */.UG.encode(picture.description ?? ''), offset);
        offset += picture.description?.length ?? 0;
        offset += 4 + 4 + 4 + 4; // setting width, height, color depth, number of indexed colors to 0
        dataView.setUint32(offset, picture.data.length);
        offset += 4;
        header.set(picture.data, offset);
        offset += picture.data.length;
        (0,misc/* assert */.vA)(offset === headerSize);
        const headerBitstream = new misc/* Bitstream */._c(new Uint8Array(4));
        headerBitstream.writeBits(1, 0); // Last metadata block -> false, will be continued by vorbis comment
        headerBitstream.writeBits(7, codec_data/* FlacBlockType */.A3.PICTURE); // Type -> Picture
        headerBitstream.writeBits(24, headerSize);
        this.writer.write(headerBitstream.bytes);
        this.writer.write(header);
    }
    writeVorbisCommentAndPictureBlock() {
        this.writer.seek(STREAMINFO_SIZE + FLAC_HEADER.byteLength);
        if ((0,src_metadata/* metadataTagsAreEmpty */.cc)(this.output._metadataTags)) {
            this.metadataWritten = true;
            return;
        }
        const pictures = this.output._metadataTags.images ?? [];
        for (const picture of pictures) {
            this.writePictureBlock(picture);
        }
        const vorbisComment = (0,codec_data/* createVorbisComments */.WY)(new Uint8Array(0), this.output._metadataTags, false);
        const headerBitstream = new misc/* Bitstream */._c(new Uint8Array(4));
        headerBitstream.writeBits(1, 1); // Last metadata block -> true
        headerBitstream.writeBits(7, codec_data/* FlacBlockType */.A3.VORBIS_COMMENT); // Type -> Vorbis comment
        headerBitstream.writeBits(24, vorbisComment.length);
        this.writer.write(headerBitstream.bytes);
        this.writer.write(vorbisComment);
        this.metadataWritten = true;
    }
    async getMimeType() {
        return 'audio/flac';
    }
    async addEncodedVideoPacket() {
        throw new Error('FLAC does not support video.');
    }
    async addEncodedAudioPacket(track, packet, meta) {
        const release = await this.mutex.acquire();
        (0,src_codec/* validateAudioChunkMetadata */.P7)(meta);
        (0,misc/* assert */.vA)(meta);
        (0,misc/* assert */.vA)(meta.decoderConfig);
        (0,misc/* assert */.vA)(meta.decoderConfig.description);
        try {
            this.validateAndNormalizeTimestamp(track, packet.timestamp, packet.type === 'key');
            if (this.sampleRate === null) {
                this.sampleRate = meta.decoderConfig.sampleRate;
            }
            if (this.channels === null) {
                this.channels = meta.decoderConfig.numberOfChannels;
            }
            if (this.bitsPerSample === null) {
                const descriptionBitstream = new misc/* Bitstream */._c((0,misc/* toUint8Array */.Fo)(meta.decoderConfig.description));
                // skip 'fLaC' + block size + frame size + sample rate + number of channels
                // See demuxer for the exact structure
                descriptionBitstream.skipBits(103 + 64);
                const bitsPerSample = descriptionBitstream.readBits(5) + 1;
                this.bitsPerSample = bitsPerSample;
            }
            if (!this.metadataWritten) {
                this.writeVorbisCommentAndPictureBlock();
            }
            const slice = reader/* FileSlice */.x$.tempFromBytes(packet.data);
            (0,reader/* readBytes */.io)(slice, 2);
            const bytes = (0,reader/* readBytes */.io)(slice, 2);
            const bitstream = new misc/* Bitstream */._c(bytes);
            const blockSizeOrUncommon = (0,flac_misc/* getBlockSizeOrUncommon */.iv)(bitstream.readBits(4));
            if (blockSizeOrUncommon === null) {
                throw new Error('Invalid FLAC frame: Invalid block size.');
            }
            (0,flac_misc/* readCodedNumber */.X7)(slice); // num
            const blockSize = (0,flac_misc/* readBlockSize */.f6)(slice, blockSizeOrUncommon);
            this.blockSizes.push(blockSize);
            this.frameSizes.push(packet.data.length);
            const startPos = this.writer.getPos();
            this.writer.write(packet.data);
            if (this.format._options.onFrame) {
                this.format._options.onFrame(packet.data, startPos);
            }
            await this.writer.flush();
        }
        finally {
            release();
        }
    }
    addSubtitleCue() {
        throw new Error('FLAC does not support subtitles.');
    }
    async finalize() {
        const release = await this.mutex.acquire();
        let minimumBlockSize = Infinity;
        let maximumBlockSize = 0;
        let minimumFrameSize = Infinity;
        let maximumFrameSize = 0;
        let totalSamples = 0;
        for (let i = 0; i < this.blockSizes.length; i++) {
            minimumFrameSize = Math.min(minimumFrameSize, this.frameSizes[i]);
            maximumFrameSize = Math.max(maximumFrameSize, this.frameSizes[i]);
            maximumBlockSize = Math.max(maximumBlockSize, this.blockSizes[i]);
            totalSamples += this.blockSizes[i];
            // Excluding the last frame from block size calculation
            // https://www.rfc-editor.org/rfc/rfc9639.html#name-streaminfo
            // "The minimum block size (in samples) used in the stream, excluding the last block."
            const isLastFrame = i === this.blockSizes.length - 1;
            if (isLastFrame) {
                continue;
            }
            minimumBlockSize = Math.min(minimumBlockSize, this.blockSizes[i]);
        }
        (0,misc/* assert */.vA)(this.sampleRate !== null);
        (0,misc/* assert */.vA)(this.channels !== null);
        (0,misc/* assert */.vA)(this.bitsPerSample !== null);
        this.writer.seek(4);
        this.writeHeader({
            minimumBlockSize,
            maximumBlockSize,
            minimumFrameSize,
            maximumFrameSize,
            sampleRate: this.sampleRate,
            channels: this.channels,
            bitsPerSample: this.bitsPerSample,
            totalSamples,
        });
        release();
    }
}

;// ./node_modules/mediabunny/dist/modules/src/subtitles.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */
const cueBlockHeaderRegex = /(?:(.+?)\n)?((?:\d{2}:)?\d{2}:\d{2}.\d{3})\s+-->\s+((?:\d{2}:)?\d{2}:\d{2}.\d{3})/g;
const preambleStartRegex = /^WEBVTT(.|\n)*?\n{2}/;
const inlineTimestampRegex = /<(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})>/g;
class SubtitleParser {
    constructor(options) {
        this.preambleText = null;
        this.preambleEmitted = false;
        this.options = options;
    }
    parse(text) {
        text = text.replaceAll('\r\n', '\n').replaceAll('\r', '\n');
        cueBlockHeaderRegex.lastIndex = 0;
        let match;
        if (!this.preambleText) {
            if (!preambleStartRegex.test(text)) {
                throw new Error('WebVTT preamble incorrect.');
            }
            match = cueBlockHeaderRegex.exec(text);
            const preamble = text.slice(0, match?.index ?? text.length).trimEnd();
            if (!preamble) {
                throw new Error('No WebVTT preamble provided.');
            }
            this.preambleText = preamble;
            if (match) {
                text = text.slice(match.index);
                cueBlockHeaderRegex.lastIndex = 0;
            }
        }
        while ((match = cueBlockHeaderRegex.exec(text))) {
            const notes = text.slice(0, match.index);
            const cueIdentifier = match[1];
            const matchEnd = match.index + match[0].length;
            const bodyStart = text.indexOf('\n', matchEnd) + 1;
            const cueSettings = text.slice(matchEnd, bodyStart).trim();
            let bodyEnd = text.indexOf('\n\n', matchEnd);
            if (bodyEnd === -1)
                bodyEnd = text.length;
            const startTime = parseSubtitleTimestamp(match[2]);
            const endTime = parseSubtitleTimestamp(match[3]);
            const duration = endTime - startTime;
            const body = text.slice(bodyStart, bodyEnd).trim();
            text = text.slice(bodyEnd).trimStart();
            cueBlockHeaderRegex.lastIndex = 0;
            const cue = {
                timestamp: startTime / 1000,
                duration: duration / 1000,
                text: body,
                identifier: cueIdentifier,
                settings: cueSettings,
                notes,
            };
            const meta = {};
            if (!this.preambleEmitted) {
                meta.config = {
                    description: this.preambleText,
                };
                this.preambleEmitted = true;
            }
            this.options.output(cue, meta);
        }
    }
}
const timestampRegex = /(?:(\d{2}):)?(\d{2}):(\d{2}).(\d{3})/;
const parseSubtitleTimestamp = (string) => {
    const match = timestampRegex.exec(string);
    if (!match)
        throw new Error('Expected match.');
    return 60 * 60 * 1000 * Number(match[1] || '0')
        + 60 * 1000 * Number(match[2])
        + 1000 * Number(match[3])
        + Number(match[4]);
};
const formatSubtitleTimestamp = (timestamp) => {
    const hours = Math.floor(timestamp / (60 * 60 * 1000));
    const minutes = Math.floor((timestamp % (60 * 60 * 1000)) / (60 * 1000));
    const seconds = Math.floor((timestamp % (60 * 1000)) / 1000);
    const milliseconds = timestamp % 1000;
    return hours.toString().padStart(2, '0') + ':'
        + minutes.toString().padStart(2, '0') + ':'
        + seconds.toString().padStart(2, '0') + '.'
        + milliseconds.toString().padStart(3, '0');
};

;// ./node_modules/mediabunny/dist/modules/src/isobmff/isobmff-boxes.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */






class IsobmffBoxWriter {
    constructor(writer) {
        this.writer = writer;
        this.helper = new Uint8Array(8);
        this.helperView = new DataView(this.helper.buffer);
        /**
         * Stores the position from the start of the file to where boxes elements have been written. This is used to
         * rewrite/edit elements that were already added before, and to measure sizes of things.
         */
        this.offsets = new WeakMap();
    }
    writeU32(value) {
        this.helperView.setUint32(0, value, false);
        this.writer.write(this.helper.subarray(0, 4));
    }
    writeU64(value) {
        this.helperView.setUint32(0, Math.floor(value / 2 ** 32), false);
        this.helperView.setUint32(4, value, false);
        this.writer.write(this.helper.subarray(0, 8));
    }
    writeAscii(text) {
        for (let i = 0; i < text.length; i++) {
            this.helperView.setUint8(i % 8, text.charCodeAt(i));
            if (i % 8 === 7)
                this.writer.write(this.helper);
        }
        if (text.length % 8 !== 0) {
            this.writer.write(this.helper.subarray(0, text.length % 8));
        }
    }
    writeBox(box) {
        this.offsets.set(box, this.writer.getPos());
        if (box.contents && !box.children) {
            this.writeBoxHeader(box, box.size ?? box.contents.byteLength + 8);
            this.writer.write(box.contents);
        }
        else {
            const startPos = this.writer.getPos();
            this.writeBoxHeader(box, 0);
            if (box.contents)
                this.writer.write(box.contents);
            if (box.children)
                for (const child of box.children)
                    if (child)
                        this.writeBox(child);
            const endPos = this.writer.getPos();
            const size = box.size ?? endPos - startPos;
            this.writer.seek(startPos);
            this.writeBoxHeader(box, size);
            this.writer.seek(endPos);
        }
    }
    writeBoxHeader(box, size) {
        this.writeU32(box.largeSize ? 1 : size);
        this.writeAscii(box.type);
        if (box.largeSize)
            this.writeU64(size);
    }
    measureBoxHeader(box) {
        return 8 + (box.largeSize ? 8 : 0);
    }
    patchBox(box) {
        const boxOffset = this.offsets.get(box);
        (0,misc/* assert */.vA)(boxOffset !== undefined);
        const endPos = this.writer.getPos();
        this.writer.seek(boxOffset);
        this.writeBox(box);
        this.writer.seek(endPos);
    }
    measureBox(box) {
        if (box.contents && !box.children) {
            const headerSize = this.measureBoxHeader(box);
            return headerSize + box.contents.byteLength;
        }
        else {
            let result = this.measureBoxHeader(box);
            if (box.contents)
                result += box.contents.byteLength;
            if (box.children)
                for (const child of box.children)
                    if (child)
                        result += this.measureBox(child);
            return result;
        }
    }
}
const bytes = /* #__PURE__ */ new Uint8Array(8);
const view = /* #__PURE__ */ new DataView(bytes.buffer);
const u8 = (value) => {
    return [(value % 0x100 + 0x100) % 0x100];
};
const u16 = (value) => {
    view.setUint16(0, value, false);
    return [bytes[0], bytes[1]];
};
const i16 = (value) => {
    view.setInt16(0, value, false);
    return [bytes[0], bytes[1]];
};
const u24 = (value) => {
    view.setUint32(0, value, false);
    return [bytes[1], bytes[2], bytes[3]];
};
const u32 = (value) => {
    view.setUint32(0, value, false);
    return [bytes[0], bytes[1], bytes[2], bytes[3]];
};
const i32 = (value) => {
    view.setInt32(0, value, false);
    return [bytes[0], bytes[1], bytes[2], bytes[3]];
};
const u64 = (value) => {
    view.setUint32(0, Math.floor(value / 2 ** 32), false);
    view.setUint32(4, value, false);
    return [bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]];
};
const fixed_8_8 = (value) => {
    view.setInt16(0, 2 ** 8 * value, false);
    return [bytes[0], bytes[1]];
};
const fixed_16_16 = (value) => {
    view.setInt32(0, 2 ** 16 * value, false);
    return [bytes[0], bytes[1], bytes[2], bytes[3]];
};
const fixed_2_30 = (value) => {
    view.setInt32(0, 2 ** 30 * value, false);
    return [bytes[0], bytes[1], bytes[2], bytes[3]];
};
const variableUnsignedInt = (value, byteLength) => {
    const bytes = [];
    let remaining = value;
    do {
        let byte = remaining & 0x7f;
        remaining >>= 7;
        // If this isn't the first byte we're adding (meaning there will be more bytes after it
        // when we reverse the array), set the continuation bit
        if (bytes.length > 0) {
            byte |= 0x80;
        }
        bytes.push(byte);
        if (byteLength !== undefined) {
            byteLength--;
        }
    } while (remaining > 0 || byteLength);
    // Reverse the array since we built it backwards
    return bytes.reverse();
};
const ascii = (text, nullTerminated = false) => {
    const bytes = Array(text.length).fill(null).map((_, i) => text.charCodeAt(i));
    if (nullTerminated)
        bytes.push(0x00);
    return bytes;
};
const lastPresentedSample = (samples) => {
    let result = null;
    for (const sample of samples) {
        if (!result || sample.timestamp > result.timestamp) {
            result = sample;
        }
    }
    return result;
};
const rotationMatrix = (rotationInDegrees) => {
    const theta = rotationInDegrees * (Math.PI / 180);
    const cosTheta = Math.round(Math.cos(theta));
    const sinTheta = Math.round(Math.sin(theta));
    // Matrices are post-multiplied in ISOBMFF, meaning this is the transpose of your typical rotation matrix
    return [
        cosTheta, sinTheta, 0,
        -sinTheta, cosTheta, 0,
        0, 0, 1,
    ];
};
const IDENTITY_MATRIX = /* #__PURE__ */ rotationMatrix(0);
const matrixToBytes = (matrix) => {
    return [
        fixed_16_16(matrix[0]), fixed_16_16(matrix[1]), fixed_2_30(matrix[2]),
        fixed_16_16(matrix[3]), fixed_16_16(matrix[4]), fixed_2_30(matrix[5]),
        fixed_16_16(matrix[6]), fixed_16_16(matrix[7]), fixed_2_30(matrix[8]),
    ];
};
const box = (type, contents, children) => ({
    type,
    contents: contents && new Uint8Array(contents.flat(10)),
    children,
});
/** A FullBox always starts with a version byte, followed by three flag bytes. */
const fullBox = (type, version, flags, contents, children) => box(type, [u8(version), u24(flags), contents ?? []], children);
/**
 * File Type Compatibility Box: Allows the reader to determine whether this is a type of file that the
 * reader understands.
 */
const ftyp = (details) => {
    // You can find the full logic for this at
    // https://github.com/FFmpeg/FFmpeg/blob/de2fb43e785773738c660cdafb9309b1ef1bc80d/libavformat/movenc.c#L5518
    // Obviously, this lib only needs a small subset of that logic.
    const minorVersion = 0x200;
    if (details.isQuickTime) {
        return box('ftyp', [
            ascii('qt  '), // Major brand
            u32(minorVersion), // Minor version
            // Compatible brands
            ascii('qt  '),
        ]);
    }
    if (details.fragmented) {
        return box('ftyp', [
            ascii('iso5'), // Major brand
            u32(minorVersion), // Minor version
            // Compatible brands
            ascii('iso5'),
            ascii('iso6'),
            ascii('mp41'),
        ]);
    }
    return box('ftyp', [
        ascii('isom'), // Major brand
        u32(minorVersion), // Minor version
        // Compatible brands
        ascii('isom'),
        details.holdsAvc ? ascii('avc1') : [],
        ascii('mp41'),
    ]);
};
/** Movie Sample Data Box. Contains the actual frames/samples of the media. */
const mdat = (reserveLargeSize) => ({ type: 'mdat', largeSize: reserveLargeSize });
/** Free Space Box: A box that designates unused space in the movie data file. */
const free = (size) => ({ type: 'free', size });
/**
 * Movie Box: Used to specify the information that defines a movie - that is, the information that allows
 * an application to interpret the sample data that is stored elsewhere.
 */
const moov = (muxer) => box('moov', undefined, [
    mvhd(muxer.creationTime, muxer.trackDatas),
    ...muxer.trackDatas.map(x => trak(x, muxer.creationTime)),
    muxer.isFragmented ? mvex(muxer.trackDatas) : null,
    udta(muxer),
]);
/** Movie Header Box: Used to specify the characteristics of the entire movie, such as timescale and duration. */
const mvhd = (creationTime, trackDatas) => {
    const duration = intoTimescale(Math.max(0, ...trackDatas
        .filter(x => x.samples.length > 0)
        .map((x) => {
        const lastSample = lastPresentedSample(x.samples);
        return lastSample.timestamp + lastSample.duration;
    })), GLOBAL_TIMESCALE);
    const nextTrackId = Math.max(0, ...trackDatas.map(x => x.track.id)) + 1;
    // Conditionally use u64 if u32 isn't enough
    const needsU64 = !(0,misc/* isU32 */.vv)(creationTime) || !(0,misc/* isU32 */.vv)(duration);
    const u32OrU64 = needsU64 ? u64 : u32;
    return fullBox('mvhd', +needsU64, 0, [
        u32OrU64(creationTime), // Creation time
        u32OrU64(creationTime), // Modification time
        u32(GLOBAL_TIMESCALE), // Timescale
        u32OrU64(duration), // Duration
        fixed_16_16(1), // Preferred rate
        fixed_8_8(1), // Preferred volume
        Array(10).fill(0), // Reserved
        matrixToBytes(IDENTITY_MATRIX), // Matrix
        Array(24).fill(0), // Pre-defined
        u32(nextTrackId), // Next track ID
    ]);
};
/**
 * Track Box: Defines a single track of a movie. A movie may consist of one or more tracks. Each track is
 * independent of the other tracks in the movie and carries its own temporal and spatial information. Each Track Box
 * contains its associated Media Box.
 */
const trak = (trackData, creationTime) => {
    const trackMetadata = getTrackMetadata(trackData);
    return box('trak', undefined, [
        tkhd(trackData, creationTime),
        mdia(trackData, creationTime),
        trackMetadata.name !== undefined
            ? box('udta', undefined, [
                box('name', [
                    ...misc/* textEncoder */.UG.encode(trackMetadata.name),
                ]),
            ])
            : null,
    ]);
};
/** Track Header Box: Specifies the characteristics of a single track within a movie. */
const tkhd = (trackData, creationTime) => {
    const lastSample = lastPresentedSample(trackData.samples);
    const durationInGlobalTimescale = intoTimescale(lastSample ? lastSample.timestamp + lastSample.duration : 0, GLOBAL_TIMESCALE);
    const needsU64 = !(0,misc/* isU32 */.vv)(creationTime) || !(0,misc/* isU32 */.vv)(durationInGlobalTimescale);
    const u32OrU64 = needsU64 ? u64 : u32;
    let matrix;
    if (trackData.type === 'video') {
        const rotation = trackData.track.metadata.rotation;
        matrix = rotationMatrix(rotation ?? 0);
    }
    else {
        matrix = IDENTITY_MATRIX;
    }
    let flags = 0x2; // Track in movie
    if (trackData.track.metadata.disposition?.default !== false) {
        flags |= 0x1; // Track enabled
    }
    return fullBox('tkhd', +needsU64, flags, [
        u32OrU64(creationTime), // Creation time
        u32OrU64(creationTime), // Modification time
        u32(trackData.track.id), // Track ID
        u32(0), // Reserved
        u32OrU64(durationInGlobalTimescale), // Duration
        Array(8).fill(0), // Reserved
        u16(0), // Layer
        u16(trackData.track.id), // Alternate group
        fixed_8_8(trackData.type === 'audio' ? 1 : 0), // Volume
        u16(0), // Reserved
        matrixToBytes(matrix), // Matrix
        fixed_16_16(trackData.type === 'video' ? trackData.info.width : 0), // Track width
        fixed_16_16(trackData.type === 'video' ? trackData.info.height : 0), // Track height
    ]);
};
/** Media Box: Describes and define a track's media type and sample data. */
const mdia = (trackData, creationTime) => box('mdia', undefined, [
    mdhd(trackData, creationTime),
    hdlr(true, TRACK_TYPE_TO_COMPONENT_SUBTYPE[trackData.type], TRACK_TYPE_TO_HANDLER_NAME[trackData.type]),
    minf(trackData),
]);
/** Media Header Box: Specifies the characteristics of a media, including timescale and duration. */
const mdhd = (trackData, creationTime) => {
    const lastSample = lastPresentedSample(trackData.samples);
    const localDuration = intoTimescale(lastSample ? lastSample.timestamp + lastSample.duration : 0, trackData.timescale);
    const needsU64 = !(0,misc/* isU32 */.vv)(creationTime) || !(0,misc/* isU32 */.vv)(localDuration);
    const u32OrU64 = needsU64 ? u64 : u32;
    return fullBox('mdhd', +needsU64, 0, [
        u32OrU64(creationTime), // Creation time
        u32OrU64(creationTime), // Modification time
        u32(trackData.timescale), // Timescale
        u32OrU64(localDuration), // Duration
        u16(getLanguageCodeInt(trackData.track.metadata.languageCode ?? misc/* UNDETERMINED_LANGUAGE */.IR)), // Language
        u16(0), // Quality
    ]);
};
const TRACK_TYPE_TO_COMPONENT_SUBTYPE = {
    video: 'vide',
    audio: 'soun',
    subtitle: 'text',
};
const TRACK_TYPE_TO_HANDLER_NAME = {
    video: 'MediabunnyVideoHandler',
    audio: 'MediabunnySoundHandler',
    subtitle: 'MediabunnyTextHandler',
};
/** Handler Reference Box. */
const hdlr = (hasComponentType, handlerType, name, manufacturer = '\0\0\0\0') => fullBox('hdlr', 0, 0, [
    hasComponentType ? ascii('mhlr') : u32(0), // Component type
    ascii(handlerType), // Component subtype
    ascii(manufacturer), // Component manufacturer
    u32(0), // Component flags
    u32(0), // Component flags mask
    ascii(name, true), // Component name
]);
/**
 * Media Information Box: Stores handler-specific information for a track's media data. The media handler uses this
 * information to map from media time to media data and to process the media data.
 */
const minf = (trackData) => box('minf', undefined, [
    TRACK_TYPE_TO_HEADER_BOX[trackData.type](),
    dinf(),
    stbl(trackData),
]);
/** Video Media Information Header Box: Defines specific color and graphics mode information. */
const vmhd = () => fullBox('vmhd', 0, 1, [
    u16(0), // Graphics mode
    u16(0), // Opcolor R
    u16(0), // Opcolor G
    u16(0), // Opcolor B
]);
/** Sound Media Information Header Box: Stores the sound media's control information, such as balance. */
const smhd = () => fullBox('smhd', 0, 0, [
    u16(0), // Balance
    u16(0), // Reserved
]);
/** Null Media Header Box. */
const nmhd = () => fullBox('nmhd', 0, 0);
const TRACK_TYPE_TO_HEADER_BOX = {
    video: vmhd,
    audio: smhd,
    subtitle: nmhd,
};
/**
 * Data Information Box: Contains information specifying the data handler component that provides access to the
 * media data. The data handler component uses the Data Information Box to interpret the media's data.
 */
const dinf = () => box('dinf', undefined, [
    dref(),
]);
/**
 * Data Reference Box: Contains tabular data that instructs the data handler component how to access the media's data.
 */
const dref = () => fullBox('dref', 0, 0, [
    u32(1), // Entry count
], [
    url(),
]);
const url = () => fullBox('url ', 0, 1); // Self-reference flag enabled
/**
 * Sample Table Box: Contains information for converting from media time to sample number to sample location. This box
 * also indicates how to interpret the sample (for example, whether to decompress the video data and, if so, how).
 */
const stbl = (trackData) => {
    const needsCtts = trackData.compositionTimeOffsetTable.length > 1
        || trackData.compositionTimeOffsetTable.some(x => x.sampleCompositionTimeOffset !== 0);
    return box('stbl', undefined, [
        stsd(trackData),
        stts(trackData),
        needsCtts ? ctts(trackData) : null,
        needsCtts ? cslg(trackData) : null,
        stsc(trackData),
        stsz(trackData),
        stco(trackData),
        stss(trackData),
    ]);
};
/**
 * Sample Description Box: Stores information that allows you to decode samples in the media. The data stored in the
 * sample description varies, depending on the media type.
 */
const stsd = (trackData) => {
    let sampleDescription;
    if (trackData.type === 'video') {
        sampleDescription = videoSampleDescription(videoCodecToBoxName(trackData.track.source._codec, trackData.info.decoderConfig.codec), trackData);
    }
    else if (trackData.type === 'audio') {
        const boxName = audioCodecToBoxName(trackData.track.source._codec, trackData.muxer.isQuickTime);
        (0,misc/* assert */.vA)(boxName);
        sampleDescription = soundSampleDescription(boxName, trackData);
    }
    else if (trackData.type === 'subtitle') {
        sampleDescription = subtitleSampleDescription(SUBTITLE_CODEC_TO_BOX_NAME[trackData.track.source._codec], trackData);
    }
    (0,misc/* assert */.vA)(sampleDescription);
    return fullBox('stsd', 0, 0, [
        u32(1), // Entry count
    ], [
        sampleDescription,
    ]);
};
/** Video Sample Description Box: Contains information that defines how to interpret video media data. */
const videoSampleDescription = (compressionType, trackData) => box(compressionType, [
    Array(6).fill(0), // Reserved
    u16(1), // Data reference index
    u16(0), // Pre-defined
    u16(0), // Reserved
    Array(12).fill(0), // Pre-defined
    u16(trackData.info.width), // Width
    u16(trackData.info.height), // Height
    u32(0x00480000), // Horizontal resolution
    u32(0x00480000), // Vertical resolution
    u32(0), // Reserved
    u16(1), // Frame count
    Array(32).fill(0), // Compressor name
    u16(0x0018), // Depth
    i16(0xffff), // Pre-defined
], [
    VIDEO_CODEC_TO_CONFIGURATION_BOX[trackData.track.source._codec](trackData),
    (0,misc/* colorSpaceIsComplete */.HV)(trackData.info.decoderConfig.colorSpace) ? colr(trackData) : null,
]);
/** Colour Information Box: Specifies the color space of the video. */
const colr = (trackData) => box('colr', [
    ascii('nclx'), // Colour type
    u16(misc/* COLOR_PRIMARIES_MAP */.wd[trackData.info.decoderConfig.colorSpace.primaries]), // Colour primaries
    u16(misc/* TRANSFER_CHARACTERISTICS_MAP */.uN[trackData.info.decoderConfig.colorSpace.transfer]), // Transfer characteristics
    u16(misc/* MATRIX_COEFFICIENTS_MAP */.Au[trackData.info.decoderConfig.colorSpace.matrix]), // Matrix coefficients
    u8((trackData.info.decoderConfig.colorSpace.fullRange ? 1 : 0) << 7), // Full range flag
]);
/** AVC Configuration Box: Provides additional information to the decoder. */
const avcC = (trackData) => trackData.info.decoderConfig && box('avcC', [
    // For AVC, description is an AVCDecoderConfigurationRecord, so nothing else to do here
    ...(0,misc/* toUint8Array */.Fo)(trackData.info.decoderConfig.description),
]);
/** HEVC Configuration Box: Provides additional information to the decoder. */
const hvcC = (trackData) => trackData.info.decoderConfig && box('hvcC', [
    // For HEVC, description is an HEVCDecoderConfigurationRecord, so nothing else to do here
    ...(0,misc/* toUint8Array */.Fo)(trackData.info.decoderConfig.description),
]);
/** VP Configuration Box: Provides additional information to the decoder. */
const vpcC = (trackData) => {
    // Reference: https://www.webmproject.org/vp9/mp4/
    if (!trackData.info.decoderConfig) {
        return null;
    }
    const decoderConfig = trackData.info.decoderConfig;
    const parts = decoderConfig.codec.split('.'); // We can derive the required values from the codec string
    const profile = Number(parts[1]);
    const level = Number(parts[2]);
    const bitDepth = Number(parts[3]);
    const chromaSubsampling = parts[4] ? Number(parts[4]) : 1; // 4:2:0 colocated with luma (0,0)
    const videoFullRangeFlag = parts[8] ? Number(parts[8]) : Number(decoderConfig.colorSpace?.fullRange ?? 0);
    const thirdByte = (bitDepth << 4) + (chromaSubsampling << 1) + videoFullRangeFlag;
    const colourPrimaries = parts[5]
        ? Number(parts[5])
        : decoderConfig.colorSpace?.primaries
            ? misc/* COLOR_PRIMARIES_MAP */.wd[decoderConfig.colorSpace.primaries]
            : 2; // Default to undetermined
    const transferCharacteristics = parts[6]
        ? Number(parts[6])
        : decoderConfig.colorSpace?.transfer
            ? misc/* TRANSFER_CHARACTERISTICS_MAP */.uN[decoderConfig.colorSpace.transfer]
            : 2;
    const matrixCoefficients = parts[7]
        ? Number(parts[7])
        : decoderConfig.colorSpace?.matrix
            ? misc/* MATRIX_COEFFICIENTS_MAP */.Au[decoderConfig.colorSpace.matrix]
            : 2;
    return fullBox('vpcC', 1, 0, [
        u8(profile), // Profile
        u8(level), // Level
        u8(thirdByte), // Bit depth, chroma subsampling, full range
        u8(colourPrimaries), // Colour primaries
        u8(transferCharacteristics), // Transfer characteristics
        u8(matrixCoefficients), // Matrix coefficients
        u16(0), // Codec initialization data size
    ]);
};
/** AV1 Configuration Box: Provides additional information to the decoder. */
const av1C = (trackData) => {
    return box('av1C', (0,src_codec/* generateAv1CodecConfigurationFromCodecString */.DC)(trackData.info.decoderConfig.codec));
};
/** Sound Sample Description Box: Contains information that defines how to interpret sound media data. */
const soundSampleDescription = (compressionType, trackData) => {
    let version = 0;
    let contents;
    let sampleSizeInBits = 16;
    if (src_codec/* PCM_AUDIO_CODECS */.Wq.includes(trackData.track.source._codec)) {
        const codec = trackData.track.source._codec;
        const { sampleSize } = (0,src_codec/* parsePcmCodec */.Ei)(codec);
        sampleSizeInBits = 8 * sampleSize;
        if (sampleSizeInBits > 16) {
            version = 1;
        }
    }
    if (version === 0) {
        contents = [
            Array(6).fill(0), // Reserved
            u16(1), // Data reference index
            u16(version), // Version
            u16(0), // Revision level
            u32(0), // Vendor
            u16(trackData.info.numberOfChannels), // Number of channels
            u16(sampleSizeInBits), // Sample size (bits)
            u16(0), // Compression ID
            u16(0), // Packet size
            u16(trackData.info.sampleRate < 2 ** 16 ? trackData.info.sampleRate : 0), // Sample rate (upper)
            u16(0), // Sample rate (lower)
        ];
    }
    else {
        contents = [
            Array(6).fill(0), // Reserved
            u16(1), // Data reference index
            u16(version), // Version
            u16(0), // Revision level
            u32(0), // Vendor
            u16(trackData.info.numberOfChannels), // Number of channels
            u16(Math.min(sampleSizeInBits, 16)), // Sample size (bits)
            u16(0), // Compression ID
            u16(0), // Packet size
            u16(trackData.info.sampleRate < 2 ** 16 ? trackData.info.sampleRate : 0), // Sample rate (upper)
            u16(0), // Sample rate (lower)
            u32(1), // Samples per packet (must be 1 for uncompressed formats)
            u32(sampleSizeInBits / 8), // Bytes per packet
            u32(trackData.info.numberOfChannels * sampleSizeInBits / 8), // Bytes per frame
            u32(2), // Bytes per sample (constant in FFmpeg)
        ];
    }
    return box(compressionType, contents, [
        audioCodecToConfigurationBox(trackData.track.source._codec, trackData.muxer.isQuickTime)?.(trackData) ?? null,
    ]);
};
/** MPEG-4 Elementary Stream Descriptor Box. */
const esds = (trackData) => {
    // We build up the bytes in a layered way which reflects the nested structure
    let objectTypeIndication;
    switch (trackData.track.source._codec) {
        case 'aac':
            {
                objectTypeIndication = 0x40;
            }
            ;
            break;
        case 'mp3':
            {
                objectTypeIndication = 0x6b;
            }
            ;
            break;
        case 'vorbis':
            {
                objectTypeIndication = 0xdd;
            }
            ;
            break;
        default: throw new Error(`Unhandled audio codec: ${trackData.track.source._codec}`);
    }
    let bytes = [
        ...u8(objectTypeIndication), // Object type indication
        ...u8(0x15), // stream type(6bits)=5 audio, flags(2bits)=1
        ...u24(0), // 24bit buffer size
        ...u32(0), // max bitrate
        ...u32(0), // avg bitrate
    ];
    if (trackData.info.decoderConfig.description) {
        const description = (0,misc/* toUint8Array */.Fo)(trackData.info.decoderConfig.description);
        // Add the decoder description to the end
        bytes = [
            ...bytes,
            ...u8(0x05), // TAG(5) = DecoderSpecificInfo
            ...variableUnsignedInt(description.byteLength),
            ...description,
        ];
    }
    bytes = [
        ...u16(1), // ES_ID = 1
        ...u8(0x00), // flags etc = 0
        ...u8(0x04), // TAG(4) = ES Descriptor
        ...variableUnsignedInt(bytes.length),
        ...bytes,
        ...u8(0x06), // TAG(6)
        ...u8(0x01), // length
        ...u8(0x02), // data
    ];
    bytes = [
        ...u8(0x03), // TAG(3) = Object Descriptor
        ...variableUnsignedInt(bytes.length),
        ...bytes,
    ];
    return fullBox('esds', 0, 0, bytes);
};
const wave = (trackData) => {
    return box('wave', undefined, [
        frma(trackData),
        enda(trackData),
        box('\x00\x00\x00\x00'), // NULL tag at the end
    ]);
};
const frma = (trackData) => {
    return box('frma', [
        ascii(audioCodecToBoxName(trackData.track.source._codec, trackData.muxer.isQuickTime)),
    ]);
};
// This box specifies PCM endianness
const enda = (trackData) => {
    const { littleEndian } = (0,src_codec/* parsePcmCodec */.Ei)(trackData.track.source._codec);
    return box('enda', [
        u16(+littleEndian),
    ]);
};
/** Opus Specific Box. */
const dOps = (trackData) => {
    let outputChannelCount = trackData.info.numberOfChannels;
    // Default PreSkip, should be at least 80 milliseconds worth of playback, measured in 48000 Hz samples
    let preSkip = 3840;
    let inputSampleRate = trackData.info.sampleRate;
    let outputGain = 0;
    let channelMappingFamily = 0;
    let channelMappingTable = new Uint8Array(0);
    // Read preskip and from codec private data from the encoder
    // https://www.rfc-editor.org/rfc/rfc7845#section-5
    const description = trackData.info.decoderConfig?.description;
    if (description) {
        (0,misc/* assert */.vA)(description.byteLength >= 18);
        const bytes = (0,misc/* toUint8Array */.Fo)(description);
        const header = (0,codec_data/* parseOpusIdentificationHeader */.Qf)(bytes);
        outputChannelCount = header.outputChannelCount;
        preSkip = header.preSkip;
        inputSampleRate = header.inputSampleRate;
        outputGain = header.outputGain;
        channelMappingFamily = header.channelMappingFamily;
        if (header.channelMappingTable) {
            channelMappingTable = header.channelMappingTable;
        }
    }
    // https://www.opus-codec.org/docs/opus_in_isobmff.html
    return box('dOps', [
        u8(0), // Version
        u8(outputChannelCount), // OutputChannelCount
        u16(preSkip), // PreSkip
        u32(inputSampleRate), // InputSampleRate
        i16(outputGain), // OutputGain
        u8(channelMappingFamily), // ChannelMappingFamily
        ...channelMappingTable,
    ]);
};
/** FLAC specific box. */
const dfLa = (trackData) => {
    const description = trackData.info.decoderConfig?.description;
    (0,misc/* assert */.vA)(description);
    const bytes = (0,misc/* toUint8Array */.Fo)(description);
    return fullBox('dfLa', 0, 0, [
        ...bytes.subarray(4),
    ]);
};
/** PCM Configuration Box, ISO/IEC 23003-5. */
const pcmC = (trackData) => {
    const { littleEndian, sampleSize } = (0,src_codec/* parsePcmCodec */.Ei)(trackData.track.source._codec);
    const formatFlags = +littleEndian;
    return fullBox('pcmC', 0, 0, [
        u8(formatFlags),
        u8(8 * sampleSize),
    ]);
};
/** AC3SpecificBox */
const dac3 = (trackData) => {
    const frameInfo = (0,codec_data/* parseAc3SyncFrame */.LM)(trackData.info.firstPacket.data);
    if (!frameInfo) {
        throw new Error('Couldn\'t extract AC-3 frame info from the audio packet. '
            + 'Ensure the packets contain valid AC-3 sync frames (as specified in ETSI TS 102 366).');
    }
    const bytes = new Uint8Array(3);
    const bitstream = new misc/* Bitstream */._c(bytes);
    bitstream.writeBits(2, frameInfo.fscod);
    bitstream.writeBits(5, frameInfo.bsid);
    bitstream.writeBits(3, frameInfo.bsmod);
    bitstream.writeBits(3, frameInfo.acmod);
    bitstream.writeBits(1, frameInfo.lfeon);
    bitstream.writeBits(5, frameInfo.bitRateCode);
    bitstream.writeBits(5, 0); // reserved
    return box('dac3', [...bytes]);
};
/** EC3SpecificBox */
const dec3 = (trackData) => {
    const frameInfo = (0,codec_data/* parseEac3SyncFrame */.oL)(trackData.info.firstPacket.data);
    if (!frameInfo) {
        throw new Error('Couldn\'t extract E-AC-3 frame info from the audio packet. '
            + 'Ensure the packets contain valid E-AC-3 sync frames (as specified in ETSI TS 102 366).');
    }
    // Calculate size
    let totalBits = 16; // header: data_rate (13) + num_ind_sub (3)
    for (const sub of frameInfo.substreams) {
        totalBits += 23; // fixed fields per substream
        if (sub.numDepSub > 0) {
            totalBits += 9; // chan_loc
        }
        else {
            totalBits += 1; // reserved
        }
    }
    const size = Math.ceil(totalBits / 8);
    const bytes = new Uint8Array(size);
    const bitstream = new misc/* Bitstream */._c(bytes);
    bitstream.writeBits(13, frameInfo.dataRate);
    bitstream.writeBits(3, frameInfo.substreams.length - 1); // num_ind_sub
    for (const sub of frameInfo.substreams) {
        bitstream.writeBits(2, sub.fscod);
        bitstream.writeBits(5, sub.bsid);
        bitstream.writeBits(1, 0); // reserved
        bitstream.writeBits(1, 0); // asvc = 0
        bitstream.writeBits(3, sub.bsmod);
        bitstream.writeBits(3, sub.acmod);
        bitstream.writeBits(1, sub.lfeon);
        bitstream.writeBits(3, 0); // reserved
        bitstream.writeBits(4, sub.numDepSub);
        if (sub.numDepSub > 0) {
            bitstream.writeBits(9, sub.chanLoc);
        }
        else {
            bitstream.writeBits(1, 0); // reserved
        }
    }
    return box('dec3', [...bytes]);
};
const subtitleSampleDescription = (compressionType, trackData) => box(compressionType, [
    Array(6).fill(0), // Reserved
    u16(1), // Data reference index
], [
    SUBTITLE_CODEC_TO_CONFIGURATION_BOX[trackData.track.source._codec](trackData),
]);
const vttC = (trackData) => box('vttC', [
    ...misc/* textEncoder */.UG.encode(trackData.info.config.description),
]);
const txtC = (textConfig) => fullBox('txtC', 0, 0, [
    ...textConfig, 0, // Text config (null-terminated)
]);
/**
 * Time-To-Sample Box: Stores duration information for a media's samples, providing a mapping from a time in a media
 * to the corresponding data sample. The table is compact, meaning that consecutive samples with the same time delta
 * will be grouped.
 */
const stts = (trackData) => {
    return fullBox('stts', 0, 0, [
        u32(trackData.timeToSampleTable.length), // Number of entries
        trackData.timeToSampleTable.map(x => [
            u32(x.sampleCount), // Sample count
            u32(x.sampleDelta), // Sample duration
        ]),
    ]);
};
/** Sync Sample Box: Identifies the key frames in the media, marking the random access points within a stream. */
const stss = (trackData) => {
    if (trackData.samples.every(x => x.type === 'key'))
        return null; // No stss box -> every frame is a key frame
    const keySamples = [...trackData.samples.entries()].filter(([, sample]) => sample.type === 'key');
    return fullBox('stss', 0, 0, [
        u32(keySamples.length), // Number of entries
        keySamples.map(([index]) => u32(index + 1)), // Sync sample table
    ]);
};
/**
 * Sample-To-Chunk Box: As samples are added to a media, they are collected into chunks that allow optimized data
 * access. A chunk contains one or more samples. Chunks in a media may have different sizes, and the samples within a
 * chunk may have different sizes. The Sample-To-Chunk Box stores chunk information for the samples in a media, stored
 * in a compactly-coded fashion.
 */
const stsc = (trackData) => {
    return fullBox('stsc', 0, 0, [
        u32(trackData.compactlyCodedChunkTable.length), // Number of entries
        trackData.compactlyCodedChunkTable.map(x => [
            u32(x.firstChunk), // First chunk
            u32(x.samplesPerChunk), // Samples per chunk
            u32(1), // Sample description index
        ]),
    ]);
};
/** Sample Size Box: Specifies the byte size of each sample in the media. */
const stsz = (trackData) => {
    if (trackData.type === 'audio' && trackData.info.requiresPcmTransformation) {
        const { sampleSize } = (0,src_codec/* parsePcmCodec */.Ei)(trackData.track.source._codec);
        // With PCM, every sample has the same size
        return fullBox('stsz', 0, 0, [
            u32(sampleSize * trackData.info.numberOfChannels), // Sample size
            u32(trackData.samples.reduce((acc, x) => acc + intoTimescale(x.duration, trackData.timescale), 0)),
        ]);
    }
    return fullBox('stsz', 0, 0, [
        u32(0), // Sample size (0 means non-constant size)
        u32(trackData.samples.length), // Number of entries
        trackData.samples.map(x => u32(x.size)), // Sample size table
    ]);
};
/** Chunk Offset Box: Identifies the location of each chunk of data in the media's data stream, relative to the file. */
const stco = (trackData) => {
    if (trackData.finalizedChunks.length > 0 && (0,misc/* last */._g)(trackData.finalizedChunks).offset >= 2 ** 32) {
        // If the file is large, use the co64 box
        return fullBox('co64', 0, 0, [
            u32(trackData.finalizedChunks.length), // Number of entries
            trackData.finalizedChunks.map(x => u64(x.offset)), // Chunk offset table
        ]);
    }
    return fullBox('stco', 0, 0, [
        u32(trackData.finalizedChunks.length), // Number of entries
        trackData.finalizedChunks.map(x => u32(x.offset)), // Chunk offset table
    ]);
};
/**
 * Composition Time to Sample Box: Stores composition time offset information (PTS-DTS) for a
 * media's samples. The table is compact, meaning that consecutive samples with the same time
 * composition time offset will be grouped.
 */
const ctts = (trackData) => {
    return fullBox('ctts', 1, 0, [
        u32(trackData.compositionTimeOffsetTable.length), // Number of entries
        trackData.compositionTimeOffsetTable.map(x => [
            u32(x.sampleCount), // Sample count
            i32(x.sampleCompositionTimeOffset), // Sample offset
        ]),
    ]);
};
/**
 * Composition to Decode Box: Stores information about the composition and display times of the media samples.
 */
const cslg = (trackData) => {
    let leastDecodeToDisplayDelta = Infinity;
    let greatestDecodeToDisplayDelta = -Infinity;
    let compositionStartTime = Infinity;
    let compositionEndTime = -Infinity;
    (0,misc/* assert */.vA)(trackData.compositionTimeOffsetTable.length > 0);
    (0,misc/* assert */.vA)(trackData.samples.length > 0);
    for (let i = 0; i < trackData.compositionTimeOffsetTable.length; i++) {
        const entry = trackData.compositionTimeOffsetTable[i];
        leastDecodeToDisplayDelta = Math.min(leastDecodeToDisplayDelta, entry.sampleCompositionTimeOffset);
        greatestDecodeToDisplayDelta = Math.max(greatestDecodeToDisplayDelta, entry.sampleCompositionTimeOffset);
    }
    for (let i = 0; i < trackData.samples.length; i++) {
        const sample = trackData.samples[i];
        compositionStartTime = Math.min(compositionStartTime, intoTimescale(sample.timestamp, trackData.timescale));
        compositionEndTime = Math.max(compositionEndTime, intoTimescale(sample.timestamp + sample.duration, trackData.timescale));
    }
    const compositionToDtsShift = Math.max(-leastDecodeToDisplayDelta, 0);
    if (compositionEndTime >= 2 ** 31) {
        // For very large files, the composition end time can't be represented in i32, so let's just scrap the box in
        // that case. QuickTime fails to read the file if there's a cslg box with version 1, so that's sadly not an
        // option.
        return null;
    }
    return fullBox('cslg', 0, 0, [
        i32(compositionToDtsShift), // Composition to DTS shift
        i32(leastDecodeToDisplayDelta), // Least decode to display delta
        i32(greatestDecodeToDisplayDelta), // Greatest decode to display delta
        i32(compositionStartTime), // Composition start time
        i32(compositionEndTime), // Composition end time
    ]);
};
/**
 * Movie Extends Box: This box signals to readers that the file is fragmented. Contains a single Track Extends Box
 * for each track in the movie.
 */
const mvex = (trackDatas) => {
    return box('mvex', undefined, trackDatas.map(trex));
};
/** Track Extends Box: Contains the default values used by the movie fragments. */
const trex = (trackData) => {
    return fullBox('trex', 0, 0, [
        u32(trackData.track.id), // Track ID
        u32(1), // Default sample description index
        u32(0), // Default sample duration
        u32(0), // Default sample size
        u32(0), // Default sample flags
    ]);
};
/**
 * Movie Fragment Box: The movie fragments extend the presentation in time. They provide the information that would
 * previously have been	in the Movie Box.
 */
const moof = (sequenceNumber, trackDatas) => {
    return box('moof', undefined, [
        mfhd(sequenceNumber),
        ...trackDatas.map(traf),
    ]);
};
/** Movie Fragment Header Box: Contains a sequence number as a safety check. */
const mfhd = (sequenceNumber) => {
    return fullBox('mfhd', 0, 0, [
        u32(sequenceNumber), // Sequence number
    ]);
};
const fragmentSampleFlags = (sample) => {
    let byte1 = 0;
    let byte2 = 0;
    const byte3 = 0;
    const byte4 = 0;
    const sampleIsDifferenceSample = sample.type === 'delta';
    byte2 |= +sampleIsDifferenceSample;
    if (sampleIsDifferenceSample) {
        byte1 |= 1; // There is redundant coding in this sample
    }
    else {
        byte1 |= 2; // There is no redundant coding in this sample
    }
    // Note that there are a lot of other flags to potentially set here, but most are irrelevant / non-necessary
    return byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;
};
/** Track Fragment Box */
const traf = (trackData) => {
    return box('traf', undefined, [
        tfhd(trackData),
        tfdt(trackData),
        trun(trackData),
    ]);
};
/** Track Fragment Header Box: Provides a reference to the extended track, and flags. */
const tfhd = (trackData) => {
    (0,misc/* assert */.vA)(trackData.currentChunk);
    let tfFlags = 0;
    tfFlags |= 0x00008; // Default sample duration present
    tfFlags |= 0x00010; // Default sample size present
    tfFlags |= 0x00020; // Default sample flags present
    tfFlags |= 0x20000; // Default base is moof
    // Prefer the second sample over the first one, as the first one is a sync sample and therefore the "odd one out"
    const referenceSample = trackData.currentChunk.samples[1] ?? trackData.currentChunk.samples[0];
    const referenceSampleInfo = {
        duration: referenceSample.timescaleUnitsToNextSample,
        size: referenceSample.size,
        flags: fragmentSampleFlags(referenceSample),
    };
    return fullBox('tfhd', 0, tfFlags, [
        u32(trackData.track.id), // Track ID
        u32(referenceSampleInfo.duration), // Default sample duration
        u32(referenceSampleInfo.size), // Default sample size
        u32(referenceSampleInfo.flags), // Default sample flags
    ]);
};
/**
 * Track Fragment Decode Time Box: Provides the absolute decode time of the first sample of the fragment. This is
 * useful for performing random access on the media file.
 */
const tfdt = (trackData) => {
    (0,misc/* assert */.vA)(trackData.currentChunk);
    return fullBox('tfdt', 1, 0, [
        u64(intoTimescale(trackData.currentChunk.startTimestamp, trackData.timescale)), // Base Media Decode Time
    ]);
};
/** Track Run Box: Specifies a run of contiguous samples for a given track. */
const trun = (trackData) => {
    (0,misc/* assert */.vA)(trackData.currentChunk);
    const allSampleDurations = trackData.currentChunk.samples.map(x => x.timescaleUnitsToNextSample);
    const allSampleSizes = trackData.currentChunk.samples.map(x => x.size);
    const allSampleFlags = trackData.currentChunk.samples.map(fragmentSampleFlags);
    const allSampleCompositionTimeOffsets = trackData.currentChunk.samples
        .map(x => intoTimescale(x.timestamp - x.decodeTimestamp, trackData.timescale));
    const uniqueSampleDurations = new Set(allSampleDurations);
    const uniqueSampleSizes = new Set(allSampleSizes);
    const uniqueSampleFlags = new Set(allSampleFlags);
    const uniqueSampleCompositionTimeOffsets = new Set(allSampleCompositionTimeOffsets);
    const firstSampleFlagsPresent = uniqueSampleFlags.size === 2 && allSampleFlags[0] !== allSampleFlags[1];
    const sampleDurationPresent = uniqueSampleDurations.size > 1;
    const sampleSizePresent = uniqueSampleSizes.size > 1;
    const sampleFlagsPresent = !firstSampleFlagsPresent && uniqueSampleFlags.size > 1;
    const sampleCompositionTimeOffsetsPresent = uniqueSampleCompositionTimeOffsets.size > 1 || [...uniqueSampleCompositionTimeOffsets].some(x => x !== 0);
    let flags = 0;
    flags |= 0x0001; // Data offset present
    flags |= 0x0004 * +firstSampleFlagsPresent; // First sample flags present
    flags |= 0x0100 * +sampleDurationPresent; // Sample duration present
    flags |= 0x0200 * +sampleSizePresent; // Sample size present
    flags |= 0x0400 * +sampleFlagsPresent; // Sample flags present
    flags |= 0x0800 * +sampleCompositionTimeOffsetsPresent; // Sample composition time offsets present
    return fullBox('trun', 1, flags, [
        u32(trackData.currentChunk.samples.length), // Sample count
        u32(trackData.currentChunk.offset - trackData.currentChunk.moofOffset || 0), // Data offset
        firstSampleFlagsPresent ? u32(allSampleFlags[0]) : [],
        trackData.currentChunk.samples.map((_, i) => [
            sampleDurationPresent ? u32(allSampleDurations[i]) : [], // Sample duration
            sampleSizePresent ? u32(allSampleSizes[i]) : [], // Sample size
            sampleFlagsPresent ? u32(allSampleFlags[i]) : [], // Sample flags
            // Sample composition time offsets
            sampleCompositionTimeOffsetsPresent ? i32(allSampleCompositionTimeOffsets[i]) : [],
        ]),
    ]);
};
/**
 * Movie Fragment Random Access Box: For each track, provides pointers to sync samples within the file
 * for random access.
 */
const mfra = (trackDatas) => {
    return box('mfra', undefined, [
        ...trackDatas.map(tfra),
        mfro(),
    ]);
};
/** Track Fragment Random Access Box: Provides pointers to sync samples within the file for random access. */
const tfra = (trackData, trackIndex) => {
    const version = 1; // Using this version allows us to use 64-bit time and offset values
    return fullBox('tfra', version, 0, [
        u32(trackData.track.id), // Track ID
        u32(0b111111), // This specifies that traf number, trun number and sample number are 32-bit ints
        u32(trackData.finalizedChunks.length), // Number of entries
        trackData.finalizedChunks.map(chunk => [
            u64(intoTimescale(chunk.samples[0].timestamp, trackData.timescale)), // Time (in presentation time)
            u64(chunk.moofOffset), // moof offset
            u32(trackIndex + 1), // traf number
            u32(1), // trun number
            u32(1), // Sample number
        ]),
    ]);
};
/**
 * Movie Fragment Random Access Offset Box: Provides the size of the enclosing mfra box. This box can be used by readers
 * to quickly locate the mfra box by searching from the end of the file.
 */
const mfro = () => {
    return fullBox('mfro', 0, 0, [
        // This value needs to be overwritten manually from the outside, where the actual size of the enclosing mfra box
        // is known
        u32(0), // Size
    ]);
};
/** VTT Empty Cue Box */
const vtte = () => box('vtte');
/** VTT Cue Box */
const vttc = (payload, timestamp, identifier, settings, sourceId) => box('vttc', undefined, [
    sourceId !== null ? box('vsid', [i32(sourceId)]) : null,
    identifier !== null ? box('iden', [...misc/* textEncoder */.UG.encode(identifier)]) : null,
    timestamp !== null ? box('ctim', [...misc/* textEncoder */.UG.encode(formatSubtitleTimestamp(timestamp))]) : null,
    settings !== null ? box('sttg', [...misc/* textEncoder */.UG.encode(settings)]) : null,
    box('payl', [...misc/* textEncoder */.UG.encode(payload)]),
]);
/** VTT Additional Text Box */
const vtta = (notes) => box('vtta', [...misc/* textEncoder */.UG.encode(notes)]);
/** User Data Box */
const udta = (muxer) => {
    const boxes = [];
    const metadataFormat = muxer.format._options.metadataFormat ?? 'auto';
    const metadataTags = muxer.output._metadataTags;
    // Depending on the format, metadata tags are written differently
    if (metadataFormat === 'mdir' || (metadataFormat === 'auto' && !muxer.isQuickTime)) {
        const metaBox = metaMdir(metadataTags);
        if (metaBox)
            boxes.push(metaBox);
    }
    else if (metadataFormat === 'mdta') {
        const metaBox = metaMdta(metadataTags);
        if (metaBox)
            boxes.push(metaBox);
    }
    else if (metadataFormat === 'udta' || (metadataFormat === 'auto' && muxer.isQuickTime)) {
        addQuickTimeMetadataTagBoxes(boxes, muxer.output._metadataTags);
    }
    if (boxes.length === 0) {
        return null;
    }
    return box('udta', undefined, boxes);
};
const addQuickTimeMetadataTagBoxes = (boxes, tags) => {
    // https://exiftool.org/TagNames/QuickTime.html (QuickTime UserData Tags)
    // For QuickTime files, metadata tags are dumped into the udta box
    for (const { key, value } of (0,misc/* keyValueIterator */.rk)(tags)) {
        switch (key) {
            case 'title':
                {
                    boxes.push(metadataTagStringBoxShort('©nam', value));
                }
                ;
                break;
            case 'description':
                {
                    boxes.push(metadataTagStringBoxShort('©des', value));
                }
                ;
                break;
            case 'artist':
                {
                    boxes.push(metadataTagStringBoxShort('©ART', value));
                }
                ;
                break;
            case 'album':
                {
                    boxes.push(metadataTagStringBoxShort('©alb', value));
                }
                ;
                break;
            case 'albumArtist':
                {
                    boxes.push(metadataTagStringBoxShort('albr', value));
                }
                ;
                break;
            case 'genre':
                {
                    boxes.push(metadataTagStringBoxShort('©gen', value));
                }
                ;
                break;
            case 'date':
                {
                    boxes.push(metadataTagStringBoxShort('©day', value.toISOString().slice(0, 10)));
                }
                ;
                break;
            case 'comment':
                {
                    boxes.push(metadataTagStringBoxShort('©cmt', value));
                }
                ;
                break;
            case 'lyrics':
                {
                    boxes.push(metadataTagStringBoxShort('©lyr', value));
                }
                ;
                break;
            case 'raw':
                {
                    // Handled later
                }
                ;
                break;
            case 'discNumber':
            case 'discsTotal':
            case 'trackNumber':
            case 'tracksTotal':
            case 'images':
                {
                    // Not written for QuickTime (common Apple L)
                }
                ;
                break;
            default: (0,misc/* assertNever */.xb)(key);
        }
    }
    if (tags.raw) {
        for (const key in tags.raw) {
            const value = tags.raw[key];
            if (value == null || key.length !== 4 || boxes.some(x => x.type === key)) {
                continue;
            }
            if (typeof value === 'string') {
                boxes.push(metadataTagStringBoxShort(key, value));
            }
            else if (value instanceof Uint8Array) {
                boxes.push(box(key, Array.from(value)));
            }
        }
    }
};
const metadataTagStringBoxShort = (name, value) => {
    const encoded = misc/* textEncoder */.UG.encode(value);
    return box(name, [
        u16(encoded.length),
        u16(getLanguageCodeInt('und')),
        Array.from(encoded),
    ]);
};
const DATA_BOX_MIME_TYPE_MAP = {
    'image/jpeg': 13,
    'image/png': 14,
    'image/bmp': 27,
};
/**
 * Generates key-value metadata for inclusion in the "meta" box.
 */
const generateMetadataPairs = (tags, isMdta) => {
    const pairs = [];
    // https://exiftool.org/TagNames/QuickTime.html (QuickTime ItemList Tags)
    // This is the metadata format used for MP4 files
    for (const { key, value } of (0,misc/* keyValueIterator */.rk)(tags)) {
        switch (key) {
            case 'title':
                {
                    pairs.push({ key: isMdta ? 'title' : '©nam', value: dataStringBoxLong(value) });
                }
                ;
                break;
            case 'description':
                {
                    pairs.push({ key: isMdta ? 'description' : '©des', value: dataStringBoxLong(value) });
                }
                ;
                break;
            case 'artist':
                {
                    pairs.push({ key: isMdta ? 'artist' : '©ART', value: dataStringBoxLong(value) });
                }
                ;
                break;
            case 'album':
                {
                    pairs.push({ key: isMdta ? 'album' : '©alb', value: dataStringBoxLong(value) });
                }
                ;
                break;
            case 'albumArtist':
                {
                    pairs.push({ key: isMdta ? 'album_artist' : 'aART', value: dataStringBoxLong(value) });
                }
                ;
                break;
            case 'comment':
                {
                    pairs.push({ key: isMdta ? 'comment' : '©cmt', value: dataStringBoxLong(value) });
                }
                ;
                break;
            case 'genre':
                {
                    pairs.push({ key: isMdta ? 'genre' : '©gen', value: dataStringBoxLong(value) });
                }
                ;
                break;
            case 'lyrics':
                {
                    pairs.push({ key: isMdta ? 'lyrics' : '©lyr', value: dataStringBoxLong(value) });
                }
                ;
                break;
            case 'date':
                {
                    pairs.push({
                        key: isMdta ? 'date' : '©day',
                        value: dataStringBoxLong(value.toISOString().slice(0, 10)),
                    });
                }
                ;
                break;
            case 'images':
                {
                    for (const image of value) {
                        if (image.kind !== 'coverFront') {
                            continue;
                        }
                        pairs.push({ key: 'covr', value: box('data', [
                                u32(DATA_BOX_MIME_TYPE_MAP[image.mimeType] ?? 0), // Type indicator
                                u32(0), // Locale indicator
                                Array.from(image.data), // Kinda slow, hopefully temp
                            ]) });
                    }
                }
                ;
                break;
            case 'trackNumber':
                {
                    if (isMdta) {
                        const string = tags.tracksTotal !== undefined
                            ? `${value}/${tags.tracksTotal}`
                            : value.toString();
                        pairs.push({ key: 'track', value: dataStringBoxLong(string) });
                    }
                    else {
                        pairs.push({ key: 'trkn', value: box('data', [
                                u32(0), // 8 bytes empty
                                u32(0),
                                u16(0), // Empty
                                u16(value),
                                u16(tags.tracksTotal ?? 0),
                                u16(0), // Empty
                            ]) });
                    }
                }
                ;
                break;
            case 'discNumber':
                {
                    if (!isMdta) {
                        // Only written for mdir
                        pairs.push({ key: 'disc', value: box('data', [
                                u32(0), // 8 bytes empty
                                u32(0),
                                u16(0), // Empty
                                u16(value),
                                u16(tags.discsTotal ?? 0),
                                u16(0), // Empty
                            ]) });
                    }
                }
                ;
                break;
            case 'tracksTotal':
            case 'discsTotal':
                {
                    // These are included with 'trackNumber' and 'discNumber' respectively
                }
                ;
                break;
            case 'raw':
                {
                    // Handled later
                }
                ;
                break;
            default: (0,misc/* assertNever */.xb)(key);
        }
    }
    if (tags.raw) {
        for (const key in tags.raw) {
            const value = tags.raw[key];
            if (value == null || (!isMdta && key.length !== 4) || pairs.some(x => x.key === key)) {
                continue;
            }
            if (typeof value === 'string') {
                pairs.push({ key, value: dataStringBoxLong(value) });
            }
            else if (value instanceof Uint8Array) {
                pairs.push({ key, value: box('data', [
                        u32(0), // Type indicator
                        u32(0), // Locale indicator
                        Array.from(value),
                    ]) });
            }
            else if (value instanceof src_metadata/* RichImageData */.sF) {
                pairs.push({ key, value: box('data', [
                        u32(DATA_BOX_MIME_TYPE_MAP[value.mimeType] ?? 0), // Type indicator
                        u32(0), // Locale indicator
                        Array.from(value.data), // Kinda slow, hopefully temp
                    ]) });
            }
        }
    }
    return pairs;
};
/** Metadata Box (mdir format) */
const metaMdir = (tags) => {
    const pairs = generateMetadataPairs(tags, false);
    if (pairs.length === 0) {
        return null;
    }
    // fullBox format
    return fullBox('meta', 0, 0, undefined, [
        hdlr(false, 'mdir', '', 'appl'), // mdir handler
        box('ilst', undefined, pairs.map(pair => box(pair.key, undefined, [pair.value]))), // Item list without keys box
    ]);
};
/** Metadata Box (mdta format with keys box) */
const metaMdta = (tags) => {
    const pairs = generateMetadataPairs(tags, true);
    if (pairs.length === 0) {
        return null;
    }
    // box without version and flags
    return box('meta', undefined, [
        hdlr(false, 'mdta', ''), // mdta handler
        fullBox('keys', 0, 0, [
            u32(pairs.length),
        ], pairs.map(pair => box('mdta', [
            ...misc/* textEncoder */.UG.encode(pair.key),
        ]))),
        box('ilst', undefined, pairs.map((pair, i) => {
            const boxName = String.fromCharCode(...u32(i + 1));
            return box(boxName, undefined, [pair.value]);
        })),
    ]);
};
const dataStringBoxLong = (value) => {
    return box('data', [
        u32(1), // Type indicator (UTF-8)
        u32(0), // Locale indicator
        ...misc/* textEncoder */.UG.encode(value),
    ]);
};
const videoCodecToBoxName = (codec, fullCodecString) => {
    switch (codec) {
        case 'avc': return fullCodecString.startsWith('avc3') ? 'avc3' : 'avc1';
        case 'hevc': return 'hvc1';
        case 'vp8': return 'vp08';
        case 'vp9': return 'vp09';
        case 'av1': return 'av01';
    }
};
const VIDEO_CODEC_TO_CONFIGURATION_BOX = {
    avc: avcC,
    hevc: hvcC,
    vp8: vpcC,
    vp9: vpcC,
    av1: av1C,
};
const audioCodecToBoxName = (codec, isQuickTime) => {
    switch (codec) {
        case 'aac': return 'mp4a';
        case 'mp3': return 'mp4a';
        case 'opus': return 'Opus';
        case 'vorbis': return 'mp4a';
        case 'flac': return 'fLaC';
        case 'ulaw': return 'ulaw';
        case 'alaw': return 'alaw';
        case 'pcm-u8': return 'raw ';
        case 'pcm-s8': return 'sowt';
        case 'ac3': return 'ac-3';
        case 'eac3': return 'ec-3';
    }
    // Logic diverges here
    if (isQuickTime) {
        switch (codec) {
            case 'pcm-s16': return 'sowt';
            case 'pcm-s16be': return 'twos';
            case 'pcm-s24': return 'in24';
            case 'pcm-s24be': return 'in24';
            case 'pcm-s32': return 'in32';
            case 'pcm-s32be': return 'in32';
            case 'pcm-f32': return 'fl32';
            case 'pcm-f32be': return 'fl32';
            case 'pcm-f64': return 'fl64';
            case 'pcm-f64be': return 'fl64';
        }
    }
    else {
        switch (codec) {
            case 'pcm-s16': return 'ipcm';
            case 'pcm-s16be': return 'ipcm';
            case 'pcm-s24': return 'ipcm';
            case 'pcm-s24be': return 'ipcm';
            case 'pcm-s32': return 'ipcm';
            case 'pcm-s32be': return 'ipcm';
            case 'pcm-f32': return 'fpcm';
            case 'pcm-f32be': return 'fpcm';
            case 'pcm-f64': return 'fpcm';
            case 'pcm-f64be': return 'fpcm';
        }
    }
};
const audioCodecToConfigurationBox = (codec, isQuickTime) => {
    switch (codec) {
        case 'aac': return esds;
        case 'mp3': return esds;
        case 'opus': return dOps;
        case 'vorbis': return esds;
        case 'flac': return dfLa;
        case 'ac3': return dac3;
        case 'eac3': return dec3;
    }
    // Logic diverges here
    if (isQuickTime) {
        switch (codec) {
            case 'pcm-s24': return wave;
            case 'pcm-s24be': return wave;
            case 'pcm-s32': return wave;
            case 'pcm-s32be': return wave;
            case 'pcm-f32': return wave;
            case 'pcm-f32be': return wave;
            case 'pcm-f64': return wave;
            case 'pcm-f64be': return wave;
        }
    }
    else {
        switch (codec) {
            case 'pcm-s16': return pcmC;
            case 'pcm-s16be': return pcmC;
            case 'pcm-s24': return pcmC;
            case 'pcm-s24be': return pcmC;
            case 'pcm-s32': return pcmC;
            case 'pcm-s32be': return pcmC;
            case 'pcm-f32': return pcmC;
            case 'pcm-f32be': return pcmC;
            case 'pcm-f64': return pcmC;
            case 'pcm-f64be': return pcmC;
        }
    }
    return null;
};
const SUBTITLE_CODEC_TO_BOX_NAME = {
    webvtt: 'wvtt',
};
const SUBTITLE_CODEC_TO_CONFIGURATION_BOX = {
    webvtt: vttC,
};
const getLanguageCodeInt = (code) => {
    (0,misc/* assert */.vA)(code.length === 3);
    ;
    let language = 0;
    for (let i = 0; i < 3; i++) {
        language <<= 5;
        language += code.charCodeAt(i) - 0x60;
    }
    return language;
};

;// ./node_modules/mediabunny/dist/modules/src/writer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

class Writer {
    constructor() {
        /** Setting this to true will cause the writer to ensure data is written in a strictly monotonic, streamable way. */
        this.ensureMonotonicity = false;
        this.trackedWrites = null;
        this.trackedStart = -1;
        this.trackedEnd = -1;
    }
    start() { }
    maybeTrackWrites(data) {
        if (!this.trackedWrites) {
            return;
        }
        // Handle negative relative write positions
        let pos = this.getPos();
        if (pos < this.trackedStart) {
            if (pos + data.byteLength <= this.trackedStart) {
                return;
            }
            data = data.subarray(this.trackedStart - pos);
            pos = 0;
        }
        const neededSize = pos + data.byteLength - this.trackedStart;
        let newLength = this.trackedWrites.byteLength;
        while (newLength < neededSize) {
            newLength *= 2;
        }
        // Check if we need to resize the buffer
        if (newLength !== this.trackedWrites.byteLength) {
            const copy = new Uint8Array(newLength);
            copy.set(this.trackedWrites, 0);
            this.trackedWrites = copy;
        }
        this.trackedWrites.set(data, pos - this.trackedStart);
        this.trackedEnd = Math.max(this.trackedEnd, pos + data.byteLength);
    }
    startTrackingWrites() {
        this.trackedWrites = new Uint8Array(2 ** 10);
        this.trackedStart = this.getPos();
        this.trackedEnd = this.trackedStart;
    }
    stopTrackingWrites() {
        if (!this.trackedWrites) {
            throw new Error('Internal error: Can\'t get tracked writes since nothing was tracked.');
        }
        const slice = this.trackedWrites.subarray(0, this.trackedEnd - this.trackedStart);
        const result = {
            data: slice,
            start: this.trackedStart,
            end: this.trackedEnd,
        };
        this.trackedWrites = null;
        return result;
    }
}
const ARRAY_BUFFER_INITIAL_SIZE = 2 ** 16;
const ARRAY_BUFFER_MAX_SIZE = 2 ** 32;
class BufferTargetWriter extends Writer {
    constructor(target) {
        super();
        this.pos = 0;
        this.maxPos = 0;
        this.target = target;
        this.supportsResize = 'resize' in new ArrayBuffer(0);
        if (this.supportsResize) {
            try {
                // @ts-expect-error Don't want to bump "lib" in tsconfig
                this.buffer = new ArrayBuffer(ARRAY_BUFFER_INITIAL_SIZE, { maxByteLength: ARRAY_BUFFER_MAX_SIZE });
            }
            catch {
                this.buffer = new ArrayBuffer(ARRAY_BUFFER_INITIAL_SIZE);
                this.supportsResize = false;
            }
        }
        else {
            this.buffer = new ArrayBuffer(ARRAY_BUFFER_INITIAL_SIZE);
        }
        this.bytes = new Uint8Array(this.buffer);
    }
    ensureSize(size) {
        let newLength = this.buffer.byteLength;
        while (newLength < size)
            newLength *= 2;
        if (newLength === this.buffer.byteLength)
            return;
        if (newLength > ARRAY_BUFFER_MAX_SIZE) {
            throw new Error(`ArrayBuffer exceeded maximum size of ${ARRAY_BUFFER_MAX_SIZE} bytes. Please consider using another`
                + ` target.`);
        }
        if (this.supportsResize) {
            // Use resize if it exists
            // @ts-expect-error Don't want to bump "lib" in tsconfig
            // eslint-disable-next-line @typescript-eslint/no-unsafe-call
            this.buffer.resize(newLength);
            // The Uint8Array scales automatically
        }
        else {
            const newBuffer = new ArrayBuffer(newLength);
            const newBytes = new Uint8Array(newBuffer);
            newBytes.set(this.bytes, 0);
            this.buffer = newBuffer;
            this.bytes = newBytes;
        }
    }
    write(data) {
        this.maybeTrackWrites(data);
        this.ensureSize(this.pos + data.byteLength);
        this.bytes.set(data, this.pos);
        this.target.onwrite?.(this.pos, this.pos + data.byteLength);
        this.pos += data.byteLength;
        this.maxPos = Math.max(this.maxPos, this.pos);
    }
    seek(newPos) {
        this.pos = newPos;
    }
    getPos() {
        return this.pos;
    }
    async flush() { }
    async finalize() {
        this.ensureSize(this.pos);
        this.target.buffer = this.buffer.slice(0, Math.max(this.maxPos, this.pos));
    }
    async close() { }
    getSlice(start, end) {
        return this.bytes.slice(start, end);
    }
}
const DEFAULT_CHUNK_SIZE = 2 ** 24;
const MAX_CHUNKS_AT_ONCE = 2;
/**
 * Writes to a StreamTarget every time it is flushed, sending out all of the new data written since the
 * last flush. This is useful for streaming applications, like piping the output to disk. When using the chunked mode,
 * data will first be accumulated in larger chunks, and then the entire chunk will be flushed out at once when ready.
 */
class StreamTargetWriter extends Writer {
    constructor(target) {
        super();
        this.pos = 0;
        this.sections = [];
        this.lastWriteEnd = 0;
        this.lastFlushEnd = 0;
        this.writer = null;
        this.writeError = null;
        /**
         * The data is divided up into fixed-size chunks, whose contents are first filled in RAM and then flushed out.
         * A chunk is flushed if all of its contents have been written.
         */
        this.chunks = [];
        this.target = target;
        this.chunked = target._options.chunked ?? false;
        this.chunkSize = target._options.chunkSize ?? DEFAULT_CHUNK_SIZE;
    }
    start() {
        this.writer = this.target._writable.getWriter();
    }
    write(data) {
        if (this.pos > this.lastWriteEnd) {
            const paddingBytesNeeded = this.pos - this.lastWriteEnd;
            this.pos = this.lastWriteEnd;
            this.write(new Uint8Array(paddingBytesNeeded));
        }
        this.maybeTrackWrites(data);
        this.sections.push({
            data: data.slice(),
            start: this.pos,
        });
        this.target.onwrite?.(this.pos, this.pos + data.byteLength);
        this.pos += data.byteLength;
        this.lastWriteEnd = Math.max(this.lastWriteEnd, this.pos);
    }
    seek(newPos) {
        this.pos = newPos;
    }
    getPos() {
        return this.pos;
    }
    async flush() {
        if (this.writeError !== null) {
            // eslint-disable-next-line @typescript-eslint/only-throw-error
            throw this.writeError;
        }
        if (this.pos > this.lastWriteEnd) {
            // There's a "void" between the last written byte and the next byte we're about to write. Let's pad that
            // void with zeroes explicitly.
            const paddingBytesNeeded = this.pos - this.lastWriteEnd;
            this.pos = this.lastWriteEnd;
            this.write(new Uint8Array(paddingBytesNeeded));
        }
        (0,misc/* assert */.vA)(this.writer);
        if (this.sections.length === 0)
            return;
        const chunks = [];
        const sorted = [...this.sections].sort((a, b) => a.start - b.start);
        chunks.push({
            start: sorted[0].start,
            size: sorted[0].data.byteLength,
        });
        // Figure out how many contiguous chunks we have
        for (let i = 1; i < sorted.length; i++) {
            const lastChunk = chunks[chunks.length - 1];
            const section = sorted[i];
            if (section.start <= lastChunk.start + lastChunk.size) {
                lastChunk.size = Math.max(lastChunk.size, section.start + section.data.byteLength - lastChunk.start);
            }
            else {
                chunks.push({
                    start: section.start,
                    size: section.data.byteLength,
                });
            }
        }
        for (const chunk of chunks) {
            chunk.data = new Uint8Array(chunk.size);
            // Make sure to write the data in the correct order for correct overwriting
            for (const section of this.sections) {
                // Check if the section is in the chunk
                if (chunk.start <= section.start && section.start < chunk.start + chunk.size) {
                    chunk.data.set(section.data, section.start - chunk.start);
                }
            }
            if (this.writer.desiredSize !== null && this.writer.desiredSize <= 0) {
                await this.writer.ready; // Allow the writer to apply backpressure
            }
            if (this.chunked) {
                // Let's first gather the data into bigger chunks before writing it
                this.writeDataIntoChunks(chunk.data, chunk.start);
                this.tryToFlushChunks();
            }
            else {
                if (this.ensureMonotonicity && chunk.start !== this.lastFlushEnd) {
                    throw new Error('Internal error: Monotonicity violation.');
                }
                void this.writer.write({
                    type: 'write',
                    data: chunk.data,
                    position: chunk.start,
                }).catch((error) => {
                    this.writeError ??= error;
                });
                this.lastFlushEnd = chunk.start + chunk.data.byteLength;
            }
        }
        this.sections.length = 0;
    }
    writeDataIntoChunks(data, position) {
        // First, find the chunk to write the data into, or create one if none exists
        let chunkIndex = this.chunks.findIndex(x => x.start <= position && position < x.start + this.chunkSize);
        if (chunkIndex === -1)
            chunkIndex = this.createChunk(position);
        const chunk = this.chunks[chunkIndex];
        // Figure out how much to write to the chunk, and then write to the chunk
        const relativePosition = position - chunk.start;
        const toWrite = data.subarray(0, Math.min(this.chunkSize - relativePosition, data.byteLength));
        chunk.data.set(toWrite, relativePosition);
        // Create a section describing the region of data that was just written to
        const section = {
            start: relativePosition,
            end: relativePosition + toWrite.byteLength,
        };
        this.insertSectionIntoChunk(chunk, section);
        // Queue chunk for flushing to target if it has been fully written to
        if (chunk.written[0].start === 0 && chunk.written[0].end === this.chunkSize) {
            chunk.shouldFlush = true;
        }
        // Make sure we don't hold too many chunks in memory at once to keep memory usage down
        if (this.chunks.length > MAX_CHUNKS_AT_ONCE) {
            // Flush all but the last chunk
            for (let i = 0; i < this.chunks.length - 1; i++) {
                this.chunks[i].shouldFlush = true;
            }
            this.tryToFlushChunks();
        }
        // If the data didn't fit in one chunk, recurse with the remaining data
        if (toWrite.byteLength < data.byteLength) {
            this.writeDataIntoChunks(data.subarray(toWrite.byteLength), position + toWrite.byteLength);
        }
    }
    insertSectionIntoChunk(chunk, section) {
        let low = 0;
        let high = chunk.written.length - 1;
        let index = -1;
        // Do a binary search to find the last section with a start not larger than `section`'s start
        while (low <= high) {
            const mid = Math.floor(low + (high - low + 1) / 2);
            if (chunk.written[mid].start <= section.start) {
                low = mid + 1;
                index = mid;
            }
            else {
                high = mid - 1;
            }
        }
        // Insert the new section
        chunk.written.splice(index + 1, 0, section);
        if (index === -1 || chunk.written[index].end < section.start)
            index++;
        // Merge overlapping sections
        while (index < chunk.written.length - 1 && chunk.written[index].end >= chunk.written[index + 1].start) {
            chunk.written[index].end = Math.max(chunk.written[index].end, chunk.written[index + 1].end);
            chunk.written.splice(index + 1, 1);
        }
    }
    createChunk(includesPosition) {
        const start = Math.floor(includesPosition / this.chunkSize) * this.chunkSize;
        const chunk = {
            start,
            data: new Uint8Array(this.chunkSize),
            written: [],
            shouldFlush: false,
        };
        this.chunks.push(chunk);
        this.chunks.sort((a, b) => a.start - b.start);
        return this.chunks.indexOf(chunk);
    }
    tryToFlushChunks(force = false) {
        (0,misc/* assert */.vA)(this.writer);
        for (let i = 0; i < this.chunks.length; i++) {
            const chunk = this.chunks[i];
            if (!chunk.shouldFlush && !force)
                continue;
            for (const section of chunk.written) {
                const position = chunk.start + section.start;
                if (this.ensureMonotonicity && position !== this.lastFlushEnd) {
                    throw new Error('Internal error: Monotonicity violation.');
                }
                void this.writer.write({
                    type: 'write',
                    data: chunk.data.subarray(section.start, section.end),
                    position,
                }).catch((error) => {
                    this.writeError ??= error;
                });
                this.lastFlushEnd = chunk.start + section.end;
            }
            this.chunks.splice(i--, 1);
        }
    }
    async finalize() {
        if (this.chunked) {
            this.tryToFlushChunks(true);
        }
        if (this.writeError !== null) {
            // eslint-disable-next-line @typescript-eslint/only-throw-error
            throw this.writeError;
        }
        (0,misc/* assert */.vA)(this.writer);
        await this.writer.ready;
        return this.writer.close();
    }
    async close() {
        return this.writer?.close();
    }
}
class NullTargetWriter extends Writer {
    constructor(target) {
        super();
        this.target = target;
        this.pos = 0;
    }
    write(data) {
        this.maybeTrackWrites(data);
        this.target.onwrite?.(this.pos, this.pos + data.byteLength);
        this.pos += data.byteLength;
    }
    getPos() {
        return this.pos;
    }
    seek(newPos) {
        this.pos = newPos;
    }
    async flush() { }
    async finalize() { }
    async close() { }
}

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/adts/adts-reader.js
var adts_reader = __webpack_require__(8475);
// EXTERNAL MODULE: ./node.js (ignored)
var node_ignored_ = __webpack_require__(1845);
var node_ignored_namespaceObject = /*#__PURE__*/__webpack_require__.t(node_ignored_, 2);
;// ./node_modules/mediabunny/dist/modules/src/target.js
/* unused harmony import specifier */ var target_NullTargetWriter;
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */



const node = typeof node_ignored_namespaceObject !== 'undefined'
    ? node_ignored_namespaceObject // Aliasing it prevents some bundler warnings
    : undefined;
/**
 * Base class for targets, specifying where output files are written.
 * @group Output targets
 * @public
 */
class Target {
    constructor() {
        /** @internal */
        this._output = null;
        /**
         * Called each time data is written to the target. Will be called with the byte range into which data was written.
         *
         * Use this callback to track the size of the output file as it grows. But be warned, this function is chatty and
         * gets called *extremely* often.
         */
        this.onwrite = null;
    }
}
/**
 * A target that writes data directly into an ArrayBuffer in memory. Great for performance, but not suitable for very
 * large files. The buffer will be available once the output has been finalized.
 * @group Output targets
 * @public
 */
class BufferTarget extends Target {
    constructor() {
        super(...arguments);
        /** Stores the final output buffer. Until the output is finalized, this will be `null`. */
        this.buffer = null;
    }
    /** @internal */
    _createWriter() {
        return new BufferTargetWriter(this);
    }
}
/**
 * This target writes data to a [`WritableStream`](https://developer.mozilla.org/en-US/docs/Web/API/WritableStream),
 * making it a general-purpose target for writing data anywhere. It is also compatible with
 * [`FileSystemWritableFileStream`](https://developer.mozilla.org/en-US/docs/Web/API/FileSystemWritableFileStream) for
 * use with the [File System Access API](https://developer.mozilla.org/en-US/docs/Web/API/File_System_API). The
 * `WritableStream` can also apply backpressure, which will propagate to the output and throttle the encoders.
 * @group Output targets
 * @public
 */
class StreamTarget extends Target {
    /** Creates a new {@link StreamTarget} which writes to the specified `writable`. */
    constructor(writable, options = {}) {
        super();
        if (!(writable instanceof WritableStream)) {
            throw new TypeError('StreamTarget requires a WritableStream instance.');
        }
        if (options != null && typeof options !== 'object') {
            throw new TypeError('StreamTarget options, when provided, must be an object.');
        }
        if (options.chunked !== undefined && typeof options.chunked !== 'boolean') {
            throw new TypeError('options.chunked, when provided, must be a boolean.');
        }
        if (options.chunkSize !== undefined && (!Number.isInteger(options.chunkSize) || options.chunkSize < 1024)) {
            throw new TypeError('options.chunkSize, when provided, must be an integer and not smaller than 1024.');
        }
        this._writable = writable;
        this._options = options;
    }
    /** @internal */
    _createWriter() {
        return new StreamTargetWriter(this);
    }
}
/**
 * A target that writes to a file at the specified path. Intended for server-side usage in Node, Bun, or Deno.
 *
 * Writing is chunked by default. The internally held file handle will be closed when `.finalize()` or `.cancel()` are
 * called on the corresponding {@link Output}.
 * @group Output targets
 * @public
 */
class FilePathTarget extends Target {
    /** Creates a new {@link FilePathTarget} that writes to the file at the specified file path. */
    constructor(filePath, options = {}) {
        if (typeof filePath !== 'string') {
            throw new TypeError('filePath must be a string.');
        }
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        super();
        /** @internal */
        this._fileHandle = null;
        // Let's back this target with a StreamTarget, makes the implementation very simple
        const writable = new WritableStream({
            start: async () => {
                this._fileHandle = await node.fs.open(filePath, 'w');
            },
            write: async (chunk) => {
                (0,misc/* assert */.vA)(this._fileHandle);
                await this._fileHandle.write(chunk.data, 0, chunk.data.byteLength, chunk.position);
            },
            close: async () => {
                if (this._fileHandle) {
                    await this._fileHandle.close();
                    this._fileHandle = null;
                }
            },
        });
        this._streamTarget = new StreamTarget(writable, {
            chunked: true,
            ...options,
        });
        this._streamTarget._output = this._output;
    }
    /** @internal */
    _createWriter() {
        return this._streamTarget._createWriter();
    }
}
/**
 * This target just discards all incoming data. It is useful for when you need an {@link Output} but extract data from
 * it differently, for example through format-specific callbacks (`onMoof`, `onMdat`, ...) or encoder events.
 * @group Output targets
 * @public
 */
class NullTarget extends (/* unused pure expression or super */ null && (Target)) {
    /** @internal */
    _createWriter() {
        return new target_NullTargetWriter(this);
    }
}

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/isobmff/isobmff-misc.js
var isobmff_misc = __webpack_require__(1826);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/isobmff/isobmff-reader.js
var isobmff_reader = __webpack_require__(8561);
;// ./node_modules/mediabunny/dist/modules/src/isobmff/isobmff-muxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */













const GLOBAL_TIMESCALE = 1000;
const TIMESTAMP_OFFSET = 2_082_844_800; // Seconds between Jan 1 1904 and Jan 1 1970
const getTrackMetadata = (trackData) => {
    const metadata = {};
    const track = trackData.track;
    if (track.metadata.name !== undefined) {
        metadata.name = track.metadata.name;
    }
    return metadata;
};
const intoTimescale = (timeInSeconds, timescale, round = true) => {
    const value = timeInSeconds * timescale;
    return round ? Math.round(value) : value;
};
class IsobmffMuxer extends Muxer {
    constructor(output, format) {
        super(output);
        this.auxTarget = new BufferTarget();
        this.auxWriter = this.auxTarget._createWriter();
        this.auxBoxWriter = new IsobmffBoxWriter(this.auxWriter);
        this.mdat = null;
        this.ftypSize = null;
        this.trackDatas = [];
        this.allTracksKnown = (0,misc/* promiseWithResolvers */.nJ)();
        this.creationTime = Math.floor(Date.now() / 1000) + TIMESTAMP_OFFSET;
        this.finalizedChunks = [];
        this.nextFragmentNumber = 1;
        // Only relevant for fragmented files, to make sure new fragments start with the highest timestamp seen so far
        this.maxWrittenTimestamp = -Infinity;
        this.format = format;
        this.writer = output._writer;
        this.boxWriter = new IsobmffBoxWriter(this.writer);
        this.isQuickTime = format instanceof MovOutputFormat;
        // If the fastStart option isn't defined, enable in-memory fast start if the target is an ArrayBuffer, as the
        // memory usage remains identical
        const fastStartDefault = this.writer instanceof BufferTargetWriter ? 'in-memory' : false;
        this.fastStart = format._options.fastStart ?? fastStartDefault;
        this.isFragmented = this.fastStart === 'fragmented';
        if (this.fastStart === 'in-memory' || this.isFragmented) {
            this.writer.ensureMonotonicity = true;
        }
        this.minimumFragmentDuration = format._options.minimumFragmentDuration ?? 1;
    }
    async start() {
        const release = await this.mutex.acquire();
        const holdsAvc = this.output._tracks.some(x => x.type === 'video' && x.source._codec === 'avc');
        // Write the header
        {
            if (this.format._options.onFtyp) {
                this.writer.startTrackingWrites();
            }
            this.boxWriter.writeBox(ftyp({
                isQuickTime: this.isQuickTime,
                holdsAvc: holdsAvc,
                fragmented: this.isFragmented,
            }));
            if (this.format._options.onFtyp) {
                const { data, start } = this.writer.stopTrackingWrites();
                this.format._options.onFtyp(data, start);
            }
        }
        this.ftypSize = this.writer.getPos();
        if (this.fastStart === 'in-memory') {
            // We're write at finalization
        }
        else if (this.fastStart === 'reserve') {
            // Validate that all tracks have set maximumPacketCount
            for (const track of this.output._tracks) {
                if (track.metadata.maximumPacketCount === undefined) {
                    throw new Error('All tracks must specify maximumPacketCount in their metadata when using'
                        + ' fastStart: \'reserve\'.');
                }
            }
            // We'll start writing once we know all tracks
        }
        else if (this.isFragmented) {
            // We write the moov box once we write out the first fragment to make sure we get the decoder configs
        }
        else {
            if (this.format._options.onMdat) {
                this.writer.startTrackingWrites();
            }
            this.mdat = mdat(true); // Reserve large size by default, can refine this when finalizing.
            this.boxWriter.writeBox(this.mdat);
        }
        await this.writer.flush();
        release();
    }
    allTracksAreKnown() {
        for (const track of this.output._tracks) {
            if (!track.source._closed && !this.trackDatas.some(x => x.track === track)) {
                return false; // We haven't seen a sample from this open track yet
            }
        }
        return true;
    }
    async getMimeType() {
        await this.allTracksKnown.promise;
        const codecStrings = this.trackDatas.map((trackData) => {
            if (trackData.type === 'video') {
                return trackData.info.decoderConfig.codec;
            }
            else if (trackData.type === 'audio') {
                return trackData.info.decoderConfig.codec;
            }
            else {
                const map = {
                    webvtt: 'wvtt',
                };
                return map[trackData.track.source._codec];
            }
        });
        return (0,isobmff_misc/* buildIsobmffMimeType */.X)({
            isQuickTime: this.isQuickTime,
            hasVideo: this.trackDatas.some(x => x.type === 'video'),
            hasAudio: this.trackDatas.some(x => x.type === 'audio'),
            codecStrings,
        });
    }
    getVideoTrackData(track, packet, meta) {
        const existingTrackData = this.trackDatas.find(x => x.track === track);
        if (existingTrackData) {
            return existingTrackData;
        }
        (0,src_codec/* validateVideoChunkMetadata */.aF)(meta);
        (0,misc/* assert */.vA)(meta);
        (0,misc/* assert */.vA)(meta.decoderConfig);
        const decoderConfig = { ...meta.decoderConfig };
        (0,misc/* assert */.vA)(decoderConfig.codedWidth !== undefined);
        (0,misc/* assert */.vA)(decoderConfig.codedHeight !== undefined);
        let requiresAnnexBTransformation = false;
        if (track.source._codec === 'avc' && !decoderConfig.description) {
            // ISOBMFF can only hold AVC in the AVCC format, not in Annex B, but the missing description indicates
            // Annex B. This means we'll need to do some converterino.
            const decoderConfigurationRecord = (0,codec_data/* extractAvcDecoderConfigurationRecord */.fH)(packet.data);
            if (!decoderConfigurationRecord) {
                throw new Error('Couldn\'t extract an AVCDecoderConfigurationRecord from the AVC packet. Make sure the packets are'
                    + ' in Annex B format (as specified in ITU-T-REC-H.264) when not providing a description, or'
                    + ' provide a description (must be an AVCDecoderConfigurationRecord as specified in ISO 14496-15)'
                    + ' and ensure the packets are in AVCC format.');
            }
            decoderConfig.description = (0,codec_data/* serializeAvcDecoderConfigurationRecord */.KU)(decoderConfigurationRecord);
            requiresAnnexBTransformation = true;
        }
        else if (track.source._codec === 'hevc' && !decoderConfig.description) {
            // ISOBMFF can only hold HEVC in the HEVC format, not in Annex B, but the missing description indicates
            // Annex B. This means we'll need to do some converterino.
            const decoderConfigurationRecord = (0,codec_data/* extractHevcDecoderConfigurationRecord */.D5)(packet.data);
            if (!decoderConfigurationRecord) {
                throw new Error('Couldn\'t extract an HEVCDecoderConfigurationRecord from the HEVC packet. Make sure the packets'
                    + ' are in Annex B format (as specified in ITU-T-REC-H.265) when not providing a description, or'
                    + ' provide a description (must be an HEVCDecoderConfigurationRecord as specified in ISO 14496-15)'
                    + ' and ensure the packets are in HEVC format.');
            }
            decoderConfig.description = (0,codec_data/* serializeHevcDecoderConfigurationRecord */.Us)(decoderConfigurationRecord);
            requiresAnnexBTransformation = true;
        }
        // The frame rate set by the user may not be an integer. Since timescale is an integer, we'll approximate the
        // frame time (inverse of frame rate) with a rational number, then use that approximation's denominator
        // as the timescale.
        const timescale = (0,misc/* computeRationalApproximation */.b_)(1 / (track.metadata.frameRate ?? 57600), 1e6).denominator;
        const newTrackData = {
            muxer: this,
            track,
            type: 'video',
            info: {
                width: decoderConfig.codedWidth,
                height: decoderConfig.codedHeight,
                decoderConfig: decoderConfig,
                requiresAnnexBTransformation,
            },
            timescale,
            samples: [],
            sampleQueue: [],
            timestampProcessingQueue: [],
            timeToSampleTable: [],
            compositionTimeOffsetTable: [],
            lastTimescaleUnits: null,
            lastSample: null,
            finalizedChunks: [],
            currentChunk: null,
            compactlyCodedChunkTable: [],
        };
        this.trackDatas.push(newTrackData);
        this.trackDatas.sort((a, b) => a.track.id - b.track.id);
        if (this.allTracksAreKnown()) {
            this.allTracksKnown.resolve();
        }
        return newTrackData;
    }
    getAudioTrackData(track, packet, meta) {
        const existingTrackData = this.trackDatas.find(x => x.track === track);
        if (existingTrackData) {
            return existingTrackData;
        }
        (0,src_codec/* validateAudioChunkMetadata */.P7)(meta);
        (0,misc/* assert */.vA)(meta);
        (0,misc/* assert */.vA)(meta.decoderConfig);
        const decoderConfig = { ...meta.decoderConfig };
        let requiresAdtsStripping = false;
        if (track.source._codec === 'aac' && !decoderConfig.description) {
            // ISOBMFF can only hold AAC in raw format, not ADTS, but the missing description indicates ADTS.
            // Parse the first packet to extract the AudioSpecificConfig.
            const adtsFrame = (0,adts_reader/* readAdtsFrameHeader */.lh)(reader/* FileSlice */.x$.tempFromBytes(packet.data));
            if (!adtsFrame) {
                throw new Error('Couldn\'t parse ADTS header from the AAC packet. Make sure the packets are in ADTS format'
                    + ' (as specified in ISO 13818-7) when not providing a description, or provide a description'
                    + ' (must be an AudioSpecificConfig as specified in ISO 14496-3) and ensure the packets'
                    + ' are raw AAC data.');
            }
            const sampleRate = src_codec/* aacFrequencyTable */.Im[adtsFrame.samplingFrequencyIndex];
            const numberOfChannels = src_codec/* aacChannelMap */.Ti[adtsFrame.channelConfiguration];
            if (sampleRate === undefined || numberOfChannels === undefined) {
                throw new Error('Invalid ADTS frame header.');
            }
            decoderConfig.description = (0,src_codec/* buildAacAudioSpecificConfig */.Wz)({
                objectType: adtsFrame.objectType,
                sampleRate,
                numberOfChannels,
            });
            requiresAdtsStripping = true;
        }
        const newTrackData = {
            muxer: this,
            track,
            type: 'audio',
            info: {
                numberOfChannels: meta.decoderConfig.numberOfChannels,
                sampleRate: meta.decoderConfig.sampleRate,
                decoderConfig,
                requiresPcmTransformation: !this.isFragmented
                    && src_codec/* PCM_AUDIO_CODECS */.Wq.includes(track.source._codec),
                requiresAdtsStripping,
                firstPacket: packet,
            },
            timescale: decoderConfig.sampleRate,
            samples: [],
            sampleQueue: [],
            timestampProcessingQueue: [],
            timeToSampleTable: [],
            compositionTimeOffsetTable: [],
            lastTimescaleUnits: null,
            lastSample: null,
            finalizedChunks: [],
            currentChunk: null,
            compactlyCodedChunkTable: [],
        };
        this.trackDatas.push(newTrackData);
        this.trackDatas.sort((a, b) => a.track.id - b.track.id);
        if (this.allTracksAreKnown()) {
            this.allTracksKnown.resolve();
        }
        return newTrackData;
    }
    getSubtitleTrackData(track, meta) {
        const existingTrackData = this.trackDatas.find(x => x.track === track);
        if (existingTrackData) {
            return existingTrackData;
        }
        (0,src_codec/* validateSubtitleMetadata */.GL)(meta);
        (0,misc/* assert */.vA)(meta);
        (0,misc/* assert */.vA)(meta.config);
        const newTrackData = {
            muxer: this,
            track,
            type: 'subtitle',
            info: {
                config: meta.config,
            },
            timescale: 1000, // Reasonable
            samples: [],
            sampleQueue: [],
            timestampProcessingQueue: [],
            timeToSampleTable: [],
            compositionTimeOffsetTable: [],
            lastTimescaleUnits: null,
            lastSample: null,
            finalizedChunks: [],
            currentChunk: null,
            compactlyCodedChunkTable: [],
            lastCueEndTimestamp: 0,
            cueQueue: [],
            nextSourceId: 0,
            cueToSourceId: new WeakMap(),
        };
        this.trackDatas.push(newTrackData);
        this.trackDatas.sort((a, b) => a.track.id - b.track.id);
        if (this.allTracksAreKnown()) {
            this.allTracksKnown.resolve();
        }
        return newTrackData;
    }
    async addEncodedVideoPacket(track, packet, meta) {
        const release = await this.mutex.acquire();
        try {
            const trackData = this.getVideoTrackData(track, packet, meta);
            let packetData = packet.data;
            if (trackData.info.requiresAnnexBTransformation) {
                const nalUnits = [...(0,codec_data/* iterateNalUnitsInAnnexB */._u)(packetData)]
                    .map(loc => packetData.subarray(loc.offset, loc.offset + loc.length));
                if (nalUnits.length === 0) {
                    // It's not valid Annex B data
                    throw new Error('Failed to transform packet data. Make sure all packets are provided in Annex B format, as'
                        + ' specified in ITU-T-REC-H.264 and ITU-T-REC-H.265.');
                }
                // We don't strip things like SPS or PPS NALUs here, mainly because they can also appear in the middle
                // of a stream and potentially modify the parameters of it. So, let's just leave them in to be sure.
                packetData = (0,codec_data/* concatNalUnitsInLengthPrefixed */.pc)(nalUnits, 4);
            }
            const timestamp = this.validateAndNormalizeTimestamp(trackData.track, packet.timestamp, packet.type === 'key');
            const internalSample = this.createSampleForTrack(trackData, packetData, timestamp, packet.duration, packet.type);
            await this.registerSample(trackData, internalSample);
        }
        finally {
            release();
        }
    }
    async addEncodedAudioPacket(track, packet, meta) {
        const release = await this.mutex.acquire();
        try {
            const trackData = this.getAudioTrackData(track, packet, meta);
            let packetData = packet.data;
            if (trackData.info.requiresAdtsStripping) {
                const adtsFrame = (0,adts_reader/* readAdtsFrameHeader */.lh)(reader/* FileSlice */.x$.tempFromBytes(packetData));
                if (!adtsFrame) {
                    throw new Error('Expected ADTS frame, didn\'t get one.');
                }
                const headerLength = adtsFrame.crcCheck === null
                    ? adts_reader/* MIN_ADTS_FRAME_HEADER_SIZE */.gc
                    : adts_reader/* MAX_ADTS_FRAME_HEADER_SIZE */.Y$;
                packetData = packetData.subarray(headerLength);
            }
            const timestamp = this.validateAndNormalizeTimestamp(trackData.track, packet.timestamp, packet.type === 'key');
            const internalSample = this.createSampleForTrack(trackData, packetData, timestamp, packet.duration, packet.type);
            if (trackData.info.requiresPcmTransformation) {
                await this.maybePadWithSilence(trackData, timestamp);
            }
            await this.registerSample(trackData, internalSample);
        }
        finally {
            release();
        }
    }
    async maybePadWithSilence(trackData, untilTimestamp) {
        // The PCM transformation assumes that all samples are contiguous. This is not something that is enforced, so
        // we need to pad the "holes" in between samples (and before the first sample) with additional
        // "silence samples".
        const lastSample = (0,misc/* last */._g)(trackData.samples);
        const lastEndTimestamp = lastSample
            ? lastSample.timestamp + lastSample.duration
            : 0;
        const delta = untilTimestamp - lastEndTimestamp;
        const deltaInTimescale = intoTimescale(delta, trackData.timescale);
        if (deltaInTimescale > 0) {
            const { sampleSize, silentValue } = (0,src_codec/* parsePcmCodec */.Ei)(trackData.info.decoderConfig.codec);
            const samplesNeeded = deltaInTimescale * trackData.info.numberOfChannels;
            const data = new Uint8Array(sampleSize * samplesNeeded).fill(silentValue);
            const paddingSample = this.createSampleForTrack(trackData, new Uint8Array(data.buffer), lastEndTimestamp, delta, 'key');
            await this.registerSample(trackData, paddingSample);
        }
    }
    async addSubtitleCue(track, cue, meta) {
        const release = await this.mutex.acquire();
        try {
            const trackData = this.getSubtitleTrackData(track, meta);
            this.validateAndNormalizeTimestamp(trackData.track, cue.timestamp, true);
            if (track.source._codec === 'webvtt') {
                trackData.cueQueue.push(cue);
                await this.processWebVTTCues(trackData, cue.timestamp);
            }
            else {
                // TODO
            }
        }
        finally {
            release();
        }
    }
    async processWebVTTCues(trackData, until) {
        // WebVTT cues need to undergo special processing as empty sections need to be padded out with samples, and
        // overlapping samples require special logic. The algorithm produces the format specified in ISO 14496-30.
        while (trackData.cueQueue.length > 0) {
            const timestamps = new Set([]);
            for (const cue of trackData.cueQueue) {
                (0,misc/* assert */.vA)(cue.timestamp <= until);
                (0,misc/* assert */.vA)(trackData.lastCueEndTimestamp <= cue.timestamp + cue.duration);
                timestamps.add(Math.max(cue.timestamp, trackData.lastCueEndTimestamp)); // Start timestamp
                timestamps.add(cue.timestamp + cue.duration); // End timestamp
            }
            const sortedTimestamps = [...timestamps].sort((a, b) => a - b);
            // These are the timestamps of the next sample we'll create:
            const sampleStart = sortedTimestamps[0];
            const sampleEnd = sortedTimestamps[1] ?? sampleStart;
            if (until < sampleEnd) {
                break;
            }
            // We may need to pad out empty space with an vtte box
            if (trackData.lastCueEndTimestamp < sampleStart) {
                this.auxWriter.seek(0);
                const box = vtte();
                this.auxBoxWriter.writeBox(box);
                const body = this.auxWriter.getSlice(0, this.auxWriter.getPos());
                const sample = this.createSampleForTrack(trackData, body, trackData.lastCueEndTimestamp, sampleStart - trackData.lastCueEndTimestamp, 'key');
                await this.registerSample(trackData, sample);
                trackData.lastCueEndTimestamp = sampleStart;
            }
            this.auxWriter.seek(0);
            for (let i = 0; i < trackData.cueQueue.length; i++) {
                const cue = trackData.cueQueue[i];
                if (cue.timestamp >= sampleEnd) {
                    break;
                }
                inlineTimestampRegex.lastIndex = 0;
                const containsTimestamp = inlineTimestampRegex.test(cue.text);
                const endTimestamp = cue.timestamp + cue.duration;
                let sourceId = trackData.cueToSourceId.get(cue);
                if (sourceId === undefined && sampleEnd < endTimestamp) {
                    // We know this cue will appear in more than one sample, therefore we need to mark it with a
                    // unique ID
                    sourceId = trackData.nextSourceId++;
                    trackData.cueToSourceId.set(cue, sourceId);
                }
                if (cue.notes) {
                    // Any notes/comments are included in a special vtta box
                    const box = vtta(cue.notes);
                    this.auxBoxWriter.writeBox(box);
                }
                const box = vttc(cue.text, containsTimestamp ? sampleStart : null, cue.identifier ?? null, cue.settings ?? null, sourceId ?? null);
                this.auxBoxWriter.writeBox(box);
                if (endTimestamp === sampleEnd) {
                    // The cue won't appear in any future sample, so we're done with it
                    trackData.cueQueue.splice(i--, 1);
                }
            }
            const body = this.auxWriter.getSlice(0, this.auxWriter.getPos());
            const sample = this.createSampleForTrack(trackData, body, sampleStart, sampleEnd - sampleStart, 'key');
            await this.registerSample(trackData, sample);
            trackData.lastCueEndTimestamp = sampleEnd;
        }
    }
    createSampleForTrack(trackData, data, timestamp, duration, type) {
        const sample = {
            timestamp,
            decodeTimestamp: timestamp, // This may be refined later
            duration,
            data,
            size: data.byteLength,
            type,
            timescaleUnitsToNextSample: intoTimescale(duration, trackData.timescale), // Will be refined
        };
        return sample;
    }
    processTimestamps(trackData, nextSample) {
        if (trackData.timestampProcessingQueue.length === 0) {
            return;
        }
        if (trackData.type === 'audio' && trackData.info.requiresPcmTransformation) {
            let totalDuration = 0;
            // Compute the total duration in the track timescale (which is equal to the amount of PCM audio samples)
            // and simply say that's how many new samples there are.
            for (let i = 0; i < trackData.timestampProcessingQueue.length; i++) {
                const sample = trackData.timestampProcessingQueue[i];
                const duration = intoTimescale(sample.duration, trackData.timescale);
                totalDuration += duration;
            }
            if (trackData.timeToSampleTable.length === 0) {
                trackData.timeToSampleTable.push({
                    sampleCount: totalDuration,
                    sampleDelta: 1,
                });
            }
            else {
                const lastEntry = (0,misc/* last */._g)(trackData.timeToSampleTable);
                lastEntry.sampleCount += totalDuration;
            }
            trackData.timestampProcessingQueue.length = 0;
            return;
        }
        const sortedTimestamps = trackData.timestampProcessingQueue.map(x => x.timestamp).sort((a, b) => a - b);
        for (let i = 0; i < trackData.timestampProcessingQueue.length; i++) {
            const sample = trackData.timestampProcessingQueue[i];
            // Since the user only supplies presentation time, but these may be out of order, we reverse-engineer from
            // that a sensible decode timestamp. The notion of a decode timestamp doesn't really make sense
            // (presentation timestamp & decode order are all you need), but it is a concept in ISOBMFF so we need to
            // model it.
            sample.decodeTimestamp = sortedTimestamps[i];
            if (!this.isFragmented && trackData.lastTimescaleUnits === null) {
                // In non-fragmented files, the first decode timestamp is always zero. If the first presentation
                // timestamp isn't zero, we'll simply use the composition time offset to achieve it.
                sample.decodeTimestamp = 0;
            }
            const sampleCompositionTimeOffset = intoTimescale(sample.timestamp - sample.decodeTimestamp, trackData.timescale);
            const durationInTimescale = intoTimescale(sample.duration, trackData.timescale);
            if (trackData.lastTimescaleUnits !== null) {
                (0,misc/* assert */.vA)(trackData.lastSample);
                const timescaleUnits = intoTimescale(sample.decodeTimestamp, trackData.timescale, false);
                const delta = Math.round(timescaleUnits - trackData.lastTimescaleUnits);
                (0,misc/* assert */.vA)(delta >= 0);
                trackData.lastTimescaleUnits += delta;
                trackData.lastSample.timescaleUnitsToNextSample = delta;
                if (!this.isFragmented) {
                    let lastTableEntry = (0,misc/* last */._g)(trackData.timeToSampleTable);
                    (0,misc/* assert */.vA)(lastTableEntry);
                    if (lastTableEntry.sampleCount === 1) {
                        lastTableEntry.sampleDelta = delta;
                        const entryBefore = trackData.timeToSampleTable[trackData.timeToSampleTable.length - 2];
                        if (entryBefore && entryBefore.sampleDelta === delta) {
                            // If the delta is the same as the previous one, merge the two entries
                            entryBefore.sampleCount++;
                            trackData.timeToSampleTable.pop();
                            lastTableEntry = entryBefore;
                        }
                    }
                    else if (lastTableEntry.sampleDelta !== delta) {
                        // The delta has changed, so we need a new entry to reach the current sample
                        lastTableEntry.sampleCount--;
                        trackData.timeToSampleTable.push(lastTableEntry = {
                            sampleCount: 1,
                            sampleDelta: delta,
                        });
                    }
                    if (lastTableEntry.sampleDelta === durationInTimescale) {
                        // The sample's duration matches the delta, so we can increment the count
                        lastTableEntry.sampleCount++;
                    }
                    else {
                        // Add a new entry in order to maintain the last sample's true duration
                        trackData.timeToSampleTable.push({
                            sampleCount: 1,
                            sampleDelta: durationInTimescale,
                        });
                    }
                    const lastCompositionTimeOffsetTableEntry = (0,misc/* last */._g)(trackData.compositionTimeOffsetTable);
                    (0,misc/* assert */.vA)(lastCompositionTimeOffsetTableEntry);
                    if (lastCompositionTimeOffsetTableEntry.sampleCompositionTimeOffset === sampleCompositionTimeOffset) {
                        // Simply increment the count
                        lastCompositionTimeOffsetTableEntry.sampleCount++;
                    }
                    else {
                        // The composition time offset has changed, so create a new entry with the new composition time
                        // offset
                        trackData.compositionTimeOffsetTable.push({
                            sampleCount: 1,
                            sampleCompositionTimeOffset: sampleCompositionTimeOffset,
                        });
                    }
                }
            }
            else {
                // Decode timestamp of the first sample
                trackData.lastTimescaleUnits = intoTimescale(sample.decodeTimestamp, trackData.timescale, false);
                if (!this.isFragmented) {
                    trackData.timeToSampleTable.push({
                        sampleCount: 1,
                        sampleDelta: durationInTimescale,
                    });
                    trackData.compositionTimeOffsetTable.push({
                        sampleCount: 1,
                        sampleCompositionTimeOffset: sampleCompositionTimeOffset,
                    });
                }
            }
            trackData.lastSample = sample;
        }
        trackData.timestampProcessingQueue.length = 0;
        (0,misc/* assert */.vA)(trackData.lastSample);
        (0,misc/* assert */.vA)(trackData.lastTimescaleUnits !== null);
        if (nextSample !== undefined && trackData.lastSample.timescaleUnitsToNextSample === 0) {
            (0,misc/* assert */.vA)(nextSample.type === 'key');
            // Given the next sample, we can make a guess about the duration of the last sample. This avoids having
            // the last sample's duration in each fragment be "0" for fragmented files. The guess we make here is
            // actually correct most of the time, since typically, no delta frame with a lower timestamp follows the key
            // frame (although it can happen).
            const timescaleUnits = intoTimescale(nextSample.timestamp, trackData.timescale, false);
            const delta = Math.round(timescaleUnits - trackData.lastTimescaleUnits);
            trackData.lastSample.timescaleUnitsToNextSample = delta;
        }
    }
    async registerSample(trackData, sample) {
        if (sample.type === 'key') {
            this.processTimestamps(trackData, sample);
        }
        trackData.timestampProcessingQueue.push(sample);
        if (this.isFragmented) {
            trackData.sampleQueue.push(sample);
            await this.interleaveSamples();
        }
        else if (this.fastStart === 'reserve') {
            await this.registerSampleFastStartReserve(trackData, sample);
        }
        else {
            await this.addSampleToTrack(trackData, sample);
        }
    }
    async addSampleToTrack(trackData, sample) {
        if (!this.isFragmented) {
            trackData.samples.push(sample);
            if (this.fastStart === 'reserve') {
                const maximumPacketCount = trackData.track.metadata.maximumPacketCount;
                (0,misc/* assert */.vA)(maximumPacketCount !== undefined);
                if (trackData.samples.length > maximumPacketCount) {
                    throw new Error(`Track #${trackData.track.id} has already reached the maximum packet count`
                        + ` (${maximumPacketCount}). Either add less packets or increase the maximum packet count.`);
                }
            }
        }
        let beginNewChunk = false;
        if (!trackData.currentChunk) {
            beginNewChunk = true;
        }
        else {
            // Timestamp don't need to be monotonic (think B-frames), so we may need to update the start timestamp of
            // the chunk
            trackData.currentChunk.startTimestamp = Math.min(trackData.currentChunk.startTimestamp, sample.timestamp);
            const currentChunkDuration = sample.timestamp - trackData.currentChunk.startTimestamp;
            if (this.isFragmented) {
                // We can only finalize this fragment (and begin a new one) if we know that each track will be able to
                // start the new one with a key frame.
                const keyFrameQueuedEverywhere = this.trackDatas.every((otherTrackData) => {
                    if (trackData === otherTrackData) {
                        return sample.type === 'key';
                    }
                    const firstQueuedSample = otherTrackData.sampleQueue[0];
                    if (firstQueuedSample) {
                        return firstQueuedSample.type === 'key';
                    }
                    return otherTrackData.track.source._closed;
                });
                if (currentChunkDuration >= this.minimumFragmentDuration
                    && keyFrameQueuedEverywhere
                    && sample.timestamp > this.maxWrittenTimestamp) {
                    beginNewChunk = true;
                    await this.finalizeFragment();
                }
            }
            else {
                beginNewChunk = currentChunkDuration >= 0.5; // Chunk is long enough, we need a new one
            }
        }
        if (beginNewChunk) {
            if (trackData.currentChunk) {
                await this.finalizeCurrentChunk(trackData);
            }
            trackData.currentChunk = {
                startTimestamp: sample.timestamp,
                samples: [],
                offset: null,
                moofOffset: null,
            };
        }
        (0,misc/* assert */.vA)(trackData.currentChunk);
        trackData.currentChunk.samples.push(sample);
        if (this.isFragmented) {
            this.maxWrittenTimestamp = Math.max(this.maxWrittenTimestamp, sample.timestamp);
        }
    }
    async finalizeCurrentChunk(trackData) {
        (0,misc/* assert */.vA)(!this.isFragmented);
        if (!trackData.currentChunk)
            return;
        trackData.finalizedChunks.push(trackData.currentChunk);
        this.finalizedChunks.push(trackData.currentChunk);
        let sampleCount = trackData.currentChunk.samples.length;
        if (trackData.type === 'audio' && trackData.info.requiresPcmTransformation) {
            sampleCount = trackData.currentChunk.samples
                .reduce((acc, sample) => acc + intoTimescale(sample.duration, trackData.timescale), 0);
        }
        if (trackData.compactlyCodedChunkTable.length === 0
            || (0,misc/* last */._g)(trackData.compactlyCodedChunkTable).samplesPerChunk !== sampleCount) {
            trackData.compactlyCodedChunkTable.push({
                firstChunk: trackData.finalizedChunks.length, // 1-indexed
                samplesPerChunk: sampleCount,
            });
        }
        if (this.fastStart === 'in-memory') {
            trackData.currentChunk.offset = 0; // We'll compute the proper offset when finalizing
            return;
        }
        // Write out the data
        trackData.currentChunk.offset = this.writer.getPos();
        for (const sample of trackData.currentChunk.samples) {
            (0,misc/* assert */.vA)(sample.data);
            this.writer.write(sample.data);
            sample.data = null; // Can be GC'd
        }
        await this.writer.flush();
    }
    async interleaveSamples(isFinalCall = false) {
        (0,misc/* assert */.vA)(this.isFragmented);
        if (!isFinalCall && !this.allTracksAreKnown()) {
            return; // We can't interleave yet as we don't yet know how many tracks we'll truly have
        }
        outer: while (true) {
            let trackWithMinTimestamp = null;
            let minTimestamp = Infinity;
            for (const trackData of this.trackDatas) {
                if (!isFinalCall && trackData.sampleQueue.length === 0 && !trackData.track.source._closed) {
                    break outer;
                }
                if (trackData.sampleQueue.length > 0 && trackData.sampleQueue[0].timestamp < minTimestamp) {
                    trackWithMinTimestamp = trackData;
                    minTimestamp = trackData.sampleQueue[0].timestamp;
                }
            }
            if (!trackWithMinTimestamp) {
                break;
            }
            const sample = trackWithMinTimestamp.sampleQueue.shift();
            await this.addSampleToTrack(trackWithMinTimestamp, sample);
        }
    }
    async finalizeFragment(flushWriter = true) {
        (0,misc/* assert */.vA)(this.isFragmented);
        const fragmentNumber = this.nextFragmentNumber++;
        if (fragmentNumber === 1) {
            if (this.format._options.onMoov) {
                this.writer.startTrackingWrites();
            }
            // Write the moov box now that we have all decoder configs
            const movieBox = moov(this);
            this.boxWriter.writeBox(movieBox);
            if (this.format._options.onMoov) {
                const { data, start } = this.writer.stopTrackingWrites();
                this.format._options.onMoov(data, start);
            }
        }
        // Not all tracks need to be present in every fragment
        const tracksInFragment = this.trackDatas.filter(x => x.currentChunk);
        // Create an initial moof box and measure it; we need this to know where the following mdat box will begin
        const moofBox = moof(fragmentNumber, tracksInFragment);
        const moofOffset = this.writer.getPos();
        const mdatStartPos = moofOffset + this.boxWriter.measureBox(moofBox);
        let currentPos = mdatStartPos + isobmff_reader/* MIN_BOX_HEADER_SIZE */.ZM;
        let fragmentStartTimestamp = Infinity;
        for (const trackData of tracksInFragment) {
            trackData.currentChunk.offset = currentPos;
            trackData.currentChunk.moofOffset = moofOffset;
            for (const sample of trackData.currentChunk.samples) {
                currentPos += sample.size;
            }
            fragmentStartTimestamp = Math.min(fragmentStartTimestamp, trackData.currentChunk.startTimestamp);
        }
        const mdatSize = currentPos - mdatStartPos;
        const needsLargeMdatSize = mdatSize >= 2 ** 32;
        if (needsLargeMdatSize) {
            // Shift all offsets by 8. Previously, all chunks were shifted assuming the large box size, but due to what
            // I suspect is a bug in WebKit, it failed in Safari (when livestreaming with MSE, not for static playback).
            for (const trackData of tracksInFragment) {
                trackData.currentChunk.offset += isobmff_reader/* MAX_BOX_HEADER_SIZE */.Xk - isobmff_reader/* MIN_BOX_HEADER_SIZE */.ZM;
            }
        }
        if (this.format._options.onMoof) {
            this.writer.startTrackingWrites();
        }
        const newMoofBox = moof(fragmentNumber, tracksInFragment);
        this.boxWriter.writeBox(newMoofBox);
        if (this.format._options.onMoof) {
            const { data, start } = this.writer.stopTrackingWrites();
            this.format._options.onMoof(data, start, fragmentStartTimestamp);
        }
        (0,misc/* assert */.vA)(this.writer.getPos() === mdatStartPos);
        if (this.format._options.onMdat) {
            this.writer.startTrackingWrites();
        }
        const mdatBox = mdat(needsLargeMdatSize);
        mdatBox.size = mdatSize;
        this.boxWriter.writeBox(mdatBox);
        this.writer.seek(mdatStartPos + (needsLargeMdatSize ? isobmff_reader/* MAX_BOX_HEADER_SIZE */.Xk : isobmff_reader/* MIN_BOX_HEADER_SIZE */.ZM));
        // Write sample data
        for (const trackData of tracksInFragment) {
            for (const sample of trackData.currentChunk.samples) {
                this.writer.write(sample.data);
                sample.data = null; // Can be GC'd
            }
        }
        if (this.format._options.onMdat) {
            const { data, start } = this.writer.stopTrackingWrites();
            this.format._options.onMdat(data, start);
        }
        for (const trackData of tracksInFragment) {
            trackData.finalizedChunks.push(trackData.currentChunk);
            this.finalizedChunks.push(trackData.currentChunk);
            trackData.currentChunk = null;
        }
        if (flushWriter) {
            await this.writer.flush();
        }
    }
    async registerSampleFastStartReserve(trackData, sample) {
        if (this.allTracksAreKnown()) {
            if (!this.mdat) {
                // We finally know all tracks, let's reserve space for the moov box
                const moovBox = moov(this);
                const moovSize = this.boxWriter.measureBox(moovBox);
                const reservedSize = moovSize
                    + this.computeSampleTableSizeUpperBound()
                    + 4096; // Just a little extra headroom
                (0,misc/* assert */.vA)(this.ftypSize !== null);
                this.writer.seek(this.ftypSize + reservedSize);
                if (this.format._options.onMdat) {
                    this.writer.startTrackingWrites();
                }
                this.mdat = mdat(true);
                this.boxWriter.writeBox(this.mdat);
                // Now write everything that was queued
                for (const trackData of this.trackDatas) {
                    for (const sample of trackData.sampleQueue) {
                        await this.addSampleToTrack(trackData, sample);
                    }
                    trackData.sampleQueue.length = 0;
                }
            }
            await this.addSampleToTrack(trackData, sample);
        }
        else {
            // Queue it for when we know all tracks
            trackData.sampleQueue.push(sample);
        }
    }
    computeSampleTableSizeUpperBound() {
        (0,misc/* assert */.vA)(this.fastStart === 'reserve');
        let upperBound = 0;
        for (const trackData of this.trackDatas) {
            const n = trackData.track.metadata.maximumPacketCount;
            (0,misc/* assert */.vA)(n !== undefined); // We validated this earlier
            // Given the max allowed packet count, compute the space they'll take up in the Sample Table Box, assuming
            // the worst case for each individual box:
            // stts box - since it is compactly coded, the maximum length of this table will be 2/3n
            upperBound += (4 + 4) * Math.ceil(2 / 3 * n);
            // stss box - 1 entry per sample
            upperBound += 4 * n;
            // ctts box - since it is compactly coded, the maximum length of this table will be 2/3n
            upperBound += (4 + 4) * Math.ceil(2 / 3 * n);
            // stsc box - since it is compactly coded, the maximum length of this table will be 2/3n
            upperBound += (4 + 4 + 4) * Math.ceil(2 / 3 * n);
            // stsz box - 1 entry per sample
            upperBound += 4 * n;
            // co64 box - we assume 1 sample per chunk and 64-bit chunk offsets (co64 instead of stco)
            upperBound += 8 * n;
        }
        return upperBound;
    }
    // eslint-disable-next-line @typescript-eslint/no-misused-promises
    async onTrackClose(track) {
        const release = await this.mutex.acquire();
        if (track.type === 'subtitle' && track.source._codec === 'webvtt') {
            const trackData = this.trackDatas.find(x => x.track === track);
            if (trackData) {
                await this.processWebVTTCues(trackData, Infinity);
            }
        }
        if (this.allTracksAreKnown()) {
            this.allTracksKnown.resolve();
        }
        if (this.isFragmented) {
            // Since a track is now closed, we may be able to write out chunks that were previously waiting
            await this.interleaveSamples();
        }
        release();
    }
    /** Finalizes the file, making it ready for use. Must be called after all video and audio chunks have been added. */
    async finalize() {
        const release = await this.mutex.acquire();
        this.allTracksKnown.resolve();
        for (const trackData of this.trackDatas) {
            if (trackData.type === 'subtitle' && trackData.track.source._codec === 'webvtt') {
                await this.processWebVTTCues(trackData, Infinity);
            }
        }
        if (this.isFragmented) {
            await this.interleaveSamples(true);
            for (const trackData of this.trackDatas) {
                this.processTimestamps(trackData);
            }
            await this.finalizeFragment(false); // Don't flush the last fragment as we will flush it with the mfra box
        }
        else {
            for (const trackData of this.trackDatas) {
                this.processTimestamps(trackData);
                await this.finalizeCurrentChunk(trackData);
            }
        }
        if (this.fastStart === 'in-memory') {
            this.mdat = mdat(false);
            let mdatSize;
            // We know how many chunks there are, but computing the chunk positions requires an iterative approach:
            // In order to know where the first chunk should go, we first need to know the size of the moov box. But we
            // cannot write a proper moov box without first knowing all chunk positions. So, we generate a tentative
            // moov box with placeholder values (0) for the chunk offsets to be able to compute its size. If it then
            // turns out that appending all chunks exceeds 4 GiB, we need to repeat this process, now with the co64 box
            // being used in the moov box instead, which will make it larger. After that, we definitely know the final
            // size of the moov box and can compute the proper chunk positions.
            for (let i = 0; i < 2; i++) {
                const movieBox = moov(this);
                const movieBoxSize = this.boxWriter.measureBox(movieBox);
                mdatSize = this.boxWriter.measureBox(this.mdat);
                let currentChunkPos = this.writer.getPos() + movieBoxSize + mdatSize;
                for (const chunk of this.finalizedChunks) {
                    chunk.offset = currentChunkPos;
                    for (const { data } of chunk.samples) {
                        (0,misc/* assert */.vA)(data);
                        currentChunkPos += data.byteLength;
                        mdatSize += data.byteLength;
                    }
                }
                if (currentChunkPos < 2 ** 32)
                    break;
                if (mdatSize >= 2 ** 32)
                    this.mdat.largeSize = true;
            }
            if (this.format._options.onMoov) {
                this.writer.startTrackingWrites();
            }
            const movieBox = moov(this);
            this.boxWriter.writeBox(movieBox);
            if (this.format._options.onMoov) {
                const { data, start } = this.writer.stopTrackingWrites();
                this.format._options.onMoov(data, start);
            }
            if (this.format._options.onMdat) {
                this.writer.startTrackingWrites();
            }
            this.mdat.size = mdatSize;
            this.boxWriter.writeBox(this.mdat);
            for (const chunk of this.finalizedChunks) {
                for (const sample of chunk.samples) {
                    (0,misc/* assert */.vA)(sample.data);
                    this.writer.write(sample.data);
                    sample.data = null;
                }
            }
            if (this.format._options.onMdat) {
                const { data, start } = this.writer.stopTrackingWrites();
                this.format._options.onMdat(data, start);
            }
        }
        else if (this.isFragmented) {
            // Append the mfra box to the end of the file for better random access
            const startPos = this.writer.getPos();
            const mfraBox = mfra(this.trackDatas);
            this.boxWriter.writeBox(mfraBox);
            // Patch the 'size' field of the mfro box at the end of the mfra box now that we know its actual size
            const mfraBoxSize = this.writer.getPos() - startPos;
            this.writer.seek(this.writer.getPos() - 4);
            this.boxWriter.writeU32(mfraBoxSize);
        }
        else {
            (0,misc/* assert */.vA)(this.mdat);
            const mdatPos = this.boxWriter.offsets.get(this.mdat);
            (0,misc/* assert */.vA)(mdatPos !== undefined);
            const mdatSize = this.writer.getPos() - mdatPos;
            this.mdat.size = mdatSize;
            this.mdat.largeSize = mdatSize >= 2 ** 32; // Only use the large size if we need it
            this.boxWriter.patchBox(this.mdat);
            if (this.format._options.onMdat) {
                const { data, start } = this.writer.stopTrackingWrites();
                this.format._options.onMdat(data, start);
            }
            const movieBox = moov(this);
            if (this.fastStart === 'reserve') {
                (0,misc/* assert */.vA)(this.ftypSize !== null);
                this.writer.seek(this.ftypSize);
                if (this.format._options.onMoov) {
                    this.writer.startTrackingWrites();
                }
                this.boxWriter.writeBox(movieBox);
                // Fill the remaining space with a free box. If there are less than 8 bytes left, sucks I guess
                const remainingSpace = this.boxWriter.offsets.get(this.mdat) - this.writer.getPos();
                this.boxWriter.writeBox(free(remainingSpace));
            }
            else {
                if (this.format._options.onMoov) {
                    this.writer.startTrackingWrites();
                }
                this.boxWriter.writeBox(movieBox);
            }
            if (this.format._options.onMoov) {
                const { data, start } = this.writer.stopTrackingWrites();
                this.format._options.onMoov(data, start);
            }
        }
        release();
    }
}

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/matroska/ebml.js
var ebml = __webpack_require__(6411);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/matroska/matroska-misc.js
var matroska_misc = __webpack_require__(3616);
;// ./node_modules/mediabunny/dist/modules/src/matroska/matroska-muxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */











const MIN_CLUSTER_TIMESTAMP_MS = -(2 ** 15);
const MAX_CLUSTER_TIMESTAMP_MS = 2 ** 15 - 1;
const APP_NAME = 'Mediabunny';
const SEGMENT_SIZE_BYTES = 6;
const CLUSTER_SIZE_BYTES = 5;
const TRACK_TYPE_MAP = {
    video: 1,
    audio: 2,
    subtitle: 17,
};
class MatroskaMuxer extends Muxer {
    constructor(output, format) {
        super(output);
        this.trackDatas = [];
        this.allTracksKnown = (0,misc/* promiseWithResolvers */.nJ)();
        this.segment = null;
        this.segmentInfo = null;
        this.seekHead = null;
        this.tracksElement = null;
        this.tagsElement = null;
        this.attachmentsElement = null;
        this.segmentDuration = null;
        this.cues = null;
        this.currentCluster = null;
        this.currentClusterStartMsTimestamp = null;
        this.currentClusterMaxMsTimestamp = null;
        this.trackDatasInCurrentCluster = new Map();
        this.duration = 0;
        this.writer = output._writer;
        this.format = format;
        this.ebmlWriter = new ebml/* EBMLWriter */.Qn(this.writer);
        if (this.format._options.appendOnly) {
            this.writer.ensureMonotonicity = true;
        }
    }
    async start() {
        const release = await this.mutex.acquire();
        this.writeEBMLHeader();
        this.createSegmentInfo();
        this.createCues();
        await this.writer.flush();
        release();
    }
    writeEBMLHeader() {
        if (this.format._options.onEbmlHeader) {
            this.writer.startTrackingWrites();
        }
        const ebmlHeader = { id: ebml/* EBMLId */.Cl.EBML, data: [
                { id: ebml/* EBMLId */.Cl.EBMLVersion, data: 1 },
                { id: ebml/* EBMLId */.Cl.EBMLReadVersion, data: 1 },
                { id: ebml/* EBMLId */.Cl.EBMLMaxIDLength, data: 4 },
                { id: ebml/* EBMLId */.Cl.EBMLMaxSizeLength, data: 8 },
                { id: ebml/* EBMLId */.Cl.DocType, data: this.format instanceof WebMOutputFormat ? 'webm' : 'matroska' },
                { id: ebml/* EBMLId */.Cl.DocTypeVersion, data: 2 },
                { id: ebml/* EBMLId */.Cl.DocTypeReadVersion, data: 2 },
            ] };
        this.ebmlWriter.writeEBML(ebmlHeader);
        if (this.format._options.onEbmlHeader) {
            const { data, start } = this.writer.stopTrackingWrites(); // start should be 0
            this.format._options.onEbmlHeader(data, start);
        }
    }
    /**
     * Creates a SeekHead element which is positioned near the start of the file and allows the media player to seek to
     * relevant sections more easily. Since we don't know the positions of those sections yet, we'll set them later.
     */
    maybeCreateSeekHead(writeOffsets) {
        if (this.format._options.appendOnly) {
            return;
        }
        const kaxCues = new Uint8Array([0x1c, 0x53, 0xbb, 0x6b]);
        const kaxInfo = new Uint8Array([0x15, 0x49, 0xa9, 0x66]);
        const kaxTracks = new Uint8Array([0x16, 0x54, 0xae, 0x6b]);
        const kaxAttachments = new Uint8Array([0x19, 0x41, 0xa4, 0x69]);
        const kaxTags = new Uint8Array([0x12, 0x54, 0xc3, 0x67]);
        const seekHead = { id: ebml/* EBMLId */.Cl.SeekHead, data: [
                { id: ebml/* EBMLId */.Cl.Seek, data: [
                        { id: ebml/* EBMLId */.Cl.SeekID, data: kaxCues },
                        {
                            id: ebml/* EBMLId */.Cl.SeekPosition,
                            size: 5,
                            data: writeOffsets
                                ? this.ebmlWriter.offsets.get(this.cues) - this.segmentDataOffset
                                : 0,
                        },
                    ] },
                { id: ebml/* EBMLId */.Cl.Seek, data: [
                        { id: ebml/* EBMLId */.Cl.SeekID, data: kaxInfo },
                        {
                            id: ebml/* EBMLId */.Cl.SeekPosition,
                            size: 5,
                            data: writeOffsets
                                ? this.ebmlWriter.offsets.get(this.segmentInfo) - this.segmentDataOffset
                                : 0,
                        },
                    ] },
                { id: ebml/* EBMLId */.Cl.Seek, data: [
                        { id: ebml/* EBMLId */.Cl.SeekID, data: kaxTracks },
                        {
                            id: ebml/* EBMLId */.Cl.SeekPosition,
                            size: 5,
                            data: writeOffsets
                                ? this.ebmlWriter.offsets.get(this.tracksElement) - this.segmentDataOffset
                                : 0,
                        },
                    ] },
                this.attachmentsElement
                    ? { id: ebml/* EBMLId */.Cl.Seek, data: [
                            { id: ebml/* EBMLId */.Cl.SeekID, data: kaxAttachments },
                            {
                                id: ebml/* EBMLId */.Cl.SeekPosition,
                                size: 5,
                                data: writeOffsets
                                    ? this.ebmlWriter.offsets.get(this.attachmentsElement) - this.segmentDataOffset
                                    : 0,
                            },
                        ] }
                    : null,
                this.tagsElement
                    ? { id: ebml/* EBMLId */.Cl.Seek, data: [
                            { id: ebml/* EBMLId */.Cl.SeekID, data: kaxTags },
                            {
                                id: ebml/* EBMLId */.Cl.SeekPosition,
                                size: 5,
                                data: writeOffsets
                                    ? this.ebmlWriter.offsets.get(this.tagsElement) - this.segmentDataOffset
                                    : 0,
                            },
                        ] }
                    : null,
            ] };
        this.seekHead = seekHead;
    }
    createSegmentInfo() {
        const segmentDuration = { id: ebml/* EBMLId */.Cl.Duration, data: new ebml/* EBMLFloat64 */.Z4(0) };
        this.segmentDuration = segmentDuration;
        const segmentInfo = { id: ebml/* EBMLId */.Cl.Info, data: [
                { id: ebml/* EBMLId */.Cl.TimestampScale, data: 1e6 },
                { id: ebml/* EBMLId */.Cl.MuxingApp, data: APP_NAME },
                { id: ebml/* EBMLId */.Cl.WritingApp, data: APP_NAME },
                !this.format._options.appendOnly ? segmentDuration : null,
            ] };
        this.segmentInfo = segmentInfo;
    }
    createTracks() {
        const tracksElement = { id: ebml/* EBMLId */.Cl.Tracks, data: [] };
        this.tracksElement = tracksElement;
        for (const trackData of this.trackDatas) {
            const codecId = ebml/* CODEC_STRING_MAP */.oo[trackData.track.source._codec];
            (0,misc/* assert */.vA)(codecId);
            let seekPreRollNs = 0;
            if (trackData.type === 'audio' && trackData.track.source._codec === 'opus') {
                seekPreRollNs = 1e6 * 80; // In "Matroska ticks" (nanoseconds)
                const description = trackData.info.decoderConfig.description;
                if (description) {
                    const bytes = (0,misc/* toUint8Array */.Fo)(description);
                    const header = (0,codec_data/* parseOpusIdentificationHeader */.Qf)(bytes);
                    // Use the preSkip value from the header
                    seekPreRollNs = Math.round(1e9 * (header.preSkip / src_codec/* OPUS_SAMPLE_RATE */.yo));
                }
            }
            tracksElement.data.push({ id: ebml/* EBMLId */.Cl.TrackEntry, data: [
                    { id: ebml/* EBMLId */.Cl.TrackNumber, data: trackData.track.id },
                    { id: ebml/* EBMLId */.Cl.TrackUID, data: trackData.track.id },
                    { id: ebml/* EBMLId */.Cl.TrackType, data: TRACK_TYPE_MAP[trackData.type] },
                    trackData.track.metadata.disposition?.default === false
                        ? { id: ebml/* EBMLId */.Cl.FlagDefault, data: 0 }
                        : null,
                    trackData.track.metadata.disposition?.forced
                        ? { id: ebml/* EBMLId */.Cl.FlagForced, data: 1 }
                        : null,
                    trackData.track.metadata.disposition?.hearingImpaired
                        ? { id: ebml/* EBMLId */.Cl.FlagHearingImpaired, data: 1 }
                        : null,
                    trackData.track.metadata.disposition?.visuallyImpaired
                        ? { id: ebml/* EBMLId */.Cl.FlagVisualImpaired, data: 1 }
                        : null,
                    trackData.track.metadata.disposition?.original
                        ? { id: ebml/* EBMLId */.Cl.FlagOriginal, data: 1 }
                        : null,
                    trackData.track.metadata.disposition?.commentary
                        ? { id: ebml/* EBMLId */.Cl.FlagCommentary, data: 1 }
                        : null,
                    { id: ebml/* EBMLId */.Cl.FlagLacing, data: 0 },
                    { id: ebml/* EBMLId */.Cl.Language, data: trackData.track.metadata.languageCode ?? misc/* UNDETERMINED_LANGUAGE */.IR },
                    { id: ebml/* EBMLId */.Cl.CodecID, data: codecId },
                    { id: ebml/* EBMLId */.Cl.CodecDelay, data: 0 },
                    { id: ebml/* EBMLId */.Cl.SeekPreRoll, data: seekPreRollNs },
                    trackData.track.metadata.name !== undefined
                        ? { id: ebml/* EBMLId */.Cl.Name, data: new ebml/* EBMLUnicodeString */.lT(trackData.track.metadata.name) }
                        : null,
                    (trackData.type === 'video' ? this.videoSpecificTrackInfo(trackData) : null),
                    (trackData.type === 'audio' ? this.audioSpecificTrackInfo(trackData) : null),
                    (trackData.type === 'subtitle' ? this.subtitleSpecificTrackInfo(trackData) : null),
                ] });
        }
    }
    videoSpecificTrackInfo(trackData) {
        const { frameRate, rotation } = trackData.track.metadata;
        const elements = [
            (trackData.info.decoderConfig.description
                ? {
                    id: ebml/* EBMLId */.Cl.CodecPrivate,
                    data: (0,misc/* toUint8Array */.Fo)(trackData.info.decoderConfig.description),
                }
                : null),
            (frameRate
                ? {
                    id: ebml/* EBMLId */.Cl.DefaultDuration,
                    data: 1e9 / frameRate,
                }
                : null),
        ];
        // Convert from clockwise to counter-clockwise
        const flippedRotation = rotation ? (0,misc/* normalizeRotation */.qT)(-rotation) : 0;
        const colorSpace = trackData.info.decoderConfig.colorSpace;
        const videoElement = { id: ebml/* EBMLId */.Cl.Video, data: [
                { id: ebml/* EBMLId */.Cl.PixelWidth, data: trackData.info.width },
                { id: ebml/* EBMLId */.Cl.PixelHeight, data: trackData.info.height },
                trackData.info.alphaMode ? { id: ebml/* EBMLId */.Cl.AlphaMode, data: 1 } : null,
                ((0,misc/* colorSpaceIsComplete */.HV)(colorSpace)
                    ? {
                        id: ebml/* EBMLId */.Cl.Colour,
                        data: [
                            {
                                id: ebml/* EBMLId */.Cl.MatrixCoefficients,
                                data: misc/* MATRIX_COEFFICIENTS_MAP */.Au[colorSpace.matrix],
                            },
                            {
                                id: ebml/* EBMLId */.Cl.TransferCharacteristics,
                                data: misc/* TRANSFER_CHARACTERISTICS_MAP */.uN[colorSpace.transfer],
                            },
                            {
                                id: ebml/* EBMLId */.Cl.Primaries,
                                data: misc/* COLOR_PRIMARIES_MAP */.wd[colorSpace.primaries],
                            },
                            {
                                id: ebml/* EBMLId */.Cl.Range,
                                data: colorSpace.fullRange ? 2 : 1,
                            },
                        ],
                    }
                    : null),
                (flippedRotation
                    ? {
                        id: ebml/* EBMLId */.Cl.Projection,
                        data: [
                            {
                                id: ebml/* EBMLId */.Cl.ProjectionType,
                                data: 0, // rectangular
                            },
                            {
                                id: ebml/* EBMLId */.Cl.ProjectionPoseRoll,
                                data: new ebml/* EBMLFloat32 */._v((flippedRotation + 180) % 360 - 180), // [0, 270] -> [-180, 90]
                            },
                        ],
                    }
                    : null),
            ] };
        elements.push(videoElement);
        return elements;
    }
    audioSpecificTrackInfo(trackData) {
        const pcmInfo = src_codec/* PCM_AUDIO_CODECS */.Wq.includes(trackData.track.source._codec)
            ? (0,src_codec/* parsePcmCodec */.Ei)(trackData.track.source._codec)
            : null;
        return [
            (trackData.info.decoderConfig.description
                ? {
                    id: ebml/* EBMLId */.Cl.CodecPrivate,
                    data: (0,misc/* toUint8Array */.Fo)(trackData.info.decoderConfig.description),
                }
                : null),
            { id: ebml/* EBMLId */.Cl.Audio, data: [
                    { id: ebml/* EBMLId */.Cl.SamplingFrequency, data: new ebml/* EBMLFloat32 */._v(trackData.info.sampleRate) },
                    { id: ebml/* EBMLId */.Cl.Channels, data: trackData.info.numberOfChannels },
                    pcmInfo ? { id: ebml/* EBMLId */.Cl.BitDepth, data: 8 * pcmInfo.sampleSize } : null,
                ] },
        ];
    }
    subtitleSpecificTrackInfo(trackData) {
        return [
            { id: ebml/* EBMLId */.Cl.CodecPrivate, data: misc/* textEncoder */.UG.encode(trackData.info.config.description) },
        ];
    }
    maybeCreateTags() {
        const simpleTags = [];
        const addSimpleTag = (key, value) => {
            simpleTags.push({ id: ebml/* EBMLId */.Cl.SimpleTag, data: [
                    { id: ebml/* EBMLId */.Cl.TagName, data: new ebml/* EBMLUnicodeString */.lT(key) },
                    typeof value === 'string'
                        ? { id: ebml/* EBMLId */.Cl.TagString, data: new ebml/* EBMLUnicodeString */.lT(value) }
                        : { id: ebml/* EBMLId */.Cl.TagBinary, data: value },
                ] });
        };
        const metadataTags = this.output._metadataTags;
        const writtenTags = new Set();
        for (const { key, value } of (0,misc/* keyValueIterator */.rk)(metadataTags)) {
            switch (key) {
                case 'title':
                    {
                        addSimpleTag('TITLE', value);
                        writtenTags.add('TITLE');
                    }
                    ;
                    break;
                case 'description':
                    {
                        addSimpleTag('DESCRIPTION', value);
                        writtenTags.add('DESCRIPTION');
                    }
                    ;
                    break;
                case 'artist':
                    {
                        addSimpleTag('ARTIST', value);
                        writtenTags.add('ARTIST');
                    }
                    ;
                    break;
                case 'album':
                    {
                        addSimpleTag('ALBUM', value);
                        writtenTags.add('ALBUM');
                    }
                    ;
                    break;
                case 'albumArtist':
                    {
                        addSimpleTag('ALBUM_ARTIST', value);
                        writtenTags.add('ALBUM_ARTIST');
                    }
                    ;
                    break;
                case 'genre':
                    {
                        addSimpleTag('GENRE', value);
                        writtenTags.add('GENRE');
                    }
                    ;
                    break;
                case 'comment':
                    {
                        addSimpleTag('COMMENT', value);
                        writtenTags.add('COMMENT');
                    }
                    ;
                    break;
                case 'lyrics':
                    {
                        addSimpleTag('LYRICS', value);
                        writtenTags.add('LYRICS');
                    }
                    ;
                    break;
                case 'date':
                    {
                        addSimpleTag('DATE', value.toISOString().slice(0, 10));
                        writtenTags.add('DATE');
                    }
                    ;
                    break;
                case 'trackNumber':
                    {
                        const string = metadataTags.tracksTotal !== undefined
                            ? `${value}/${metadataTags.tracksTotal}`
                            : value.toString();
                        addSimpleTag('PART_NUMBER', string);
                        writtenTags.add('PART_NUMBER');
                    }
                    ;
                    break;
                case 'discNumber':
                    {
                        const string = metadataTags.discsTotal !== undefined
                            ? `${value}/${metadataTags.discsTotal}`
                            : value.toString();
                        addSimpleTag('DISC', string);
                        writtenTags.add('DISC');
                    }
                    ;
                    break;
                case 'tracksTotal':
                case 'discsTotal':
                    {
                        // Handled with trackNumber and discNumber respectively
                    }
                    ;
                    break;
                case 'images':
                case 'raw':
                    {
                        // Handled elsewhere
                    }
                    ;
                    break;
                default: (0,misc/* assertNever */.xb)(key);
            }
        }
        if (metadataTags.raw) {
            for (const key in metadataTags.raw) {
                const value = metadataTags.raw[key];
                if (value == null || writtenTags.has(key)) {
                    continue;
                }
                if (typeof value === 'string' || value instanceof Uint8Array) {
                    addSimpleTag(key, value);
                }
            }
        }
        if (simpleTags.length === 0) {
            return;
        }
        this.tagsElement = {
            id: ebml/* EBMLId */.Cl.Tags,
            data: [{ id: ebml/* EBMLId */.Cl.Tag, data: [
                        { id: ebml/* EBMLId */.Cl.Targets, data: [
                                { id: ebml/* EBMLId */.Cl.TargetTypeValue, data: 50 },
                                { id: ebml/* EBMLId */.Cl.TargetType, data: 'MOVIE' },
                            ] },
                        ...simpleTags,
                    ] }],
        };
    }
    maybeCreateAttachments() {
        const metadataTags = this.output._metadataTags;
        const elements = [];
        const existingFileUids = new Set();
        const images = metadataTags.images ?? [];
        for (const image of images) {
            let imageName = image.name;
            if (imageName === undefined) {
                const baseName = image.kind === 'coverFront' ? 'cover' : image.kind === 'coverBack' ? 'back' : 'image';
                imageName = baseName + ((0,misc/* imageMimeTypeToExtension */.sX)(image.mimeType) ?? '');
            }
            let fileUid;
            while (true) {
                // Generate a random 64-bit unsigned integer
                fileUid = 0n;
                for (let i = 0; i < 8; i++) {
                    fileUid <<= 8n;
                    fileUid |= BigInt(Math.floor(Math.random() * 256));
                }
                if (fileUid !== 0n && !existingFileUids.has(fileUid)) {
                    break;
                }
            }
            existingFileUids.add(fileUid);
            elements.push({
                id: ebml/* EBMLId */.Cl.AttachedFile,
                data: [
                    image.description !== undefined
                        ? { id: ebml/* EBMLId */.Cl.FileDescription, data: new ebml/* EBMLUnicodeString */.lT(image.description) }
                        : null,
                    { id: ebml/* EBMLId */.Cl.FileName, data: new ebml/* EBMLUnicodeString */.lT(imageName) },
                    { id: ebml/* EBMLId */.Cl.FileMediaType, data: image.mimeType },
                    { id: ebml/* EBMLId */.Cl.FileData, data: image.data },
                    { id: ebml/* EBMLId */.Cl.FileUID, data: fileUid },
                ],
            });
        }
        // Add all AttachedFiles from the raw metadata
        for (const [key, value] of Object.entries(metadataTags.raw ?? {})) {
            if (!(value instanceof src_metadata/* AttachedFile */.VF)) {
                continue;
            }
            const keyIsNumeric = /^\d+$/.test(key);
            if (!keyIsNumeric) {
                continue;
            }
            if (images.find(x => x.mimeType === value.mimeType && (0,misc/* uint8ArraysAreEqual */.ju)(x.data, value.data))) {
                // This attached file has very likely already been added as an image above
                // (happens when remuxing Matroska)
                continue;
            }
            elements.push({
                id: ebml/* EBMLId */.Cl.AttachedFile,
                data: [
                    value.description !== undefined
                        ? { id: ebml/* EBMLId */.Cl.FileDescription, data: new ebml/* EBMLUnicodeString */.lT(value.description) }
                        : null,
                    { id: ebml/* EBMLId */.Cl.FileName, data: new ebml/* EBMLUnicodeString */.lT(value.name ?? '') },
                    { id: ebml/* EBMLId */.Cl.FileMediaType, data: value.mimeType ?? '' },
                    { id: ebml/* EBMLId */.Cl.FileData, data: value.data },
                    { id: ebml/* EBMLId */.Cl.FileUID, data: BigInt(key) },
                ],
            });
        }
        if (elements.length === 0) {
            return;
        }
        this.attachmentsElement = { id: ebml/* EBMLId */.Cl.Attachments, data: elements };
    }
    createSegment() {
        this.createTracks();
        this.maybeCreateTags();
        this.maybeCreateAttachments();
        this.maybeCreateSeekHead(false);
        const segment = {
            id: ebml/* EBMLId */.Cl.Segment,
            size: this.format._options.appendOnly ? -1 : SEGMENT_SIZE_BYTES,
            data: [
                this.seekHead, // null if append-only
                this.segmentInfo,
                this.tracksElement,
                // Matroska spec says put this at the end of the file, but I think placing it before the first cluster
                // makes more sense, and FFmpeg agrees (argumentum ad ffmpegum fallacy)
                this.attachmentsElement,
                this.tagsElement,
            ],
        };
        this.segment = segment;
        if (this.format._options.onSegmentHeader) {
            this.writer.startTrackingWrites();
        }
        this.ebmlWriter.writeEBML(segment);
        if (this.format._options.onSegmentHeader) {
            const { data, start } = this.writer.stopTrackingWrites();
            this.format._options.onSegmentHeader(data, start);
        }
    }
    createCues() {
        this.cues = { id: ebml/* EBMLId */.Cl.Cues, data: [] };
    }
    get segmentDataOffset() {
        (0,misc/* assert */.vA)(this.segment);
        return this.ebmlWriter.dataOffsets.get(this.segment);
    }
    allTracksAreKnown() {
        for (const track of this.output._tracks) {
            if (!track.source._closed && !this.trackDatas.some(x => x.track === track)) {
                return false; // We haven't seen a sample from this open track yet
            }
        }
        return true;
    }
    async getMimeType() {
        await this.allTracksKnown.promise;
        const codecStrings = this.trackDatas.map((trackData) => {
            if (trackData.type === 'video') {
                return trackData.info.decoderConfig.codec;
            }
            else if (trackData.type === 'audio') {
                return trackData.info.decoderConfig.codec;
            }
            else {
                const map = {
                    webvtt: 'wvtt',
                };
                return map[trackData.track.source._codec];
            }
        });
        return (0,matroska_misc/* buildMatroskaMimeType */.V)({
            isWebM: this.format instanceof WebMOutputFormat,
            hasVideo: this.trackDatas.some(x => x.type === 'video'),
            hasAudio: this.trackDatas.some(x => x.type === 'audio'),
            codecStrings,
        });
    }
    getVideoTrackData(track, packet, meta) {
        const existingTrackData = this.trackDatas.find(x => x.track === track);
        if (existingTrackData) {
            return existingTrackData;
        }
        (0,src_codec/* validateVideoChunkMetadata */.aF)(meta);
        (0,misc/* assert */.vA)(meta);
        (0,misc/* assert */.vA)(meta.decoderConfig);
        (0,misc/* assert */.vA)(meta.decoderConfig.codedWidth !== undefined);
        (0,misc/* assert */.vA)(meta.decoderConfig.codedHeight !== undefined);
        const newTrackData = {
            track,
            type: 'video',
            info: {
                width: meta.decoderConfig.codedWidth,
                height: meta.decoderConfig.codedHeight,
                decoderConfig: meta.decoderConfig,
                alphaMode: !!packet.sideData.alpha, // The first packet determines if this track has alpha or not
            },
            chunkQueue: [],
            lastWrittenMsTimestamp: null,
        };
        if (track.source._codec === 'vp9') {
            // https://www.webmproject.org/docs/container specifies that VP9 "SHOULD" make use of the CodecPrivate
            // field. Since WebCodecs makes no use of the description field for VP9, we need to derive it ourselves:
            newTrackData.info.decoderConfig = {
                ...newTrackData.info.decoderConfig,
                description: new Uint8Array((0,src_codec/* generateVp9CodecConfigurationFromCodecString */.mD)(newTrackData.info.decoderConfig.codec)),
            };
        }
        else if (track.source._codec === 'av1') {
            // Per https://github.com/ietf-wg-cellar/matroska-specification/blob/master/codec/av1.md, AV1 requires
            // CodecPrivate to be set, but WebCodecs makes no use of the description field for AV1. Thus, let's derive
            // it ourselves:
            newTrackData.info.decoderConfig = {
                ...newTrackData.info.decoderConfig,
                description: new Uint8Array((0,src_codec/* generateAv1CodecConfigurationFromCodecString */.DC)(newTrackData.info.decoderConfig.codec)),
            };
        }
        this.trackDatas.push(newTrackData);
        this.trackDatas.sort((a, b) => a.track.id - b.track.id);
        if (this.allTracksAreKnown()) {
            this.allTracksKnown.resolve();
        }
        return newTrackData;
    }
    getAudioTrackData(track, packet, meta) {
        const existingTrackData = this.trackDatas.find(x => x.track === track);
        if (existingTrackData) {
            return existingTrackData;
        }
        (0,src_codec/* validateAudioChunkMetadata */.P7)(meta);
        (0,misc/* assert */.vA)(meta);
        (0,misc/* assert */.vA)(meta.decoderConfig);
        const decoderConfig = { ...meta.decoderConfig };
        let requiresAdtsStripping = false;
        if (track.source._codec === 'aac' && !decoderConfig.description) {
            // Matroska stores raw AAC with AudioSpecificConfig in CodecPrivate, not ADTS-wrapped data.
            // Parse the first packet to extract the AudioSpecificConfig.
            const adtsFrame = (0,adts_reader/* readAdtsFrameHeader */.lh)(reader/* FileSlice */.x$.tempFromBytes(packet.data));
            if (!adtsFrame) {
                throw new Error('Couldn\'t parse ADTS header from the AAC packet. Make sure the packets are in ADTS format'
                    + ' (as specified in ISO 13818-7) when not providing a description, or provide a description'
                    + ' (must be an AudioSpecificConfig as specified in ISO 14496-3) and ensure the packets'
                    + ' are raw AAC data.');
            }
            const sampleRate = src_codec/* aacFrequencyTable */.Im[adtsFrame.samplingFrequencyIndex];
            const numberOfChannels = src_codec/* aacChannelMap */.Ti[adtsFrame.channelConfiguration];
            if (sampleRate === undefined || numberOfChannels === undefined) {
                throw new Error('Invalid ADTS frame header.');
            }
            decoderConfig.description = (0,src_codec/* buildAacAudioSpecificConfig */.Wz)({
                objectType: adtsFrame.objectType,
                sampleRate,
                numberOfChannels,
            });
            requiresAdtsStripping = true;
        }
        const newTrackData = {
            track,
            type: 'audio',
            info: {
                numberOfChannels: meta.decoderConfig.numberOfChannels,
                sampleRate: meta.decoderConfig.sampleRate,
                decoderConfig,
                requiresAdtsStripping,
            },
            chunkQueue: [],
            lastWrittenMsTimestamp: null,
        };
        this.trackDatas.push(newTrackData);
        this.trackDatas.sort((a, b) => a.track.id - b.track.id);
        if (this.allTracksAreKnown()) {
            this.allTracksKnown.resolve();
        }
        return newTrackData;
    }
    getSubtitleTrackData(track, meta) {
        const existingTrackData = this.trackDatas.find(x => x.track === track);
        if (existingTrackData) {
            return existingTrackData;
        }
        (0,src_codec/* validateSubtitleMetadata */.GL)(meta);
        (0,misc/* assert */.vA)(meta);
        (0,misc/* assert */.vA)(meta.config);
        const newTrackData = {
            track,
            type: 'subtitle',
            info: {
                config: meta.config,
            },
            chunkQueue: [],
            lastWrittenMsTimestamp: null,
        };
        this.trackDatas.push(newTrackData);
        this.trackDatas.sort((a, b) => a.track.id - b.track.id);
        if (this.allTracksAreKnown()) {
            this.allTracksKnown.resolve();
        }
        return newTrackData;
    }
    async addEncodedVideoPacket(track, packet, meta) {
        const release = await this.mutex.acquire();
        try {
            const trackData = this.getVideoTrackData(track, packet, meta);
            const isKeyFrame = packet.type === 'key';
            let timestamp = this.validateAndNormalizeTimestamp(trackData.track, packet.timestamp, isKeyFrame);
            let duration = packet.duration;
            if (track.metadata.frameRate !== undefined) {
                // Constrain the time values to the frame rate
                timestamp = (0,misc/* roundToMultiple */["in"])(timestamp, 1 / track.metadata.frameRate);
                duration = (0,misc/* roundToMultiple */["in"])(duration, 1 / track.metadata.frameRate);
            }
            const additions = trackData.info.alphaMode
                ? packet.sideData.alpha ?? null
                : null;
            const videoChunk = this.createInternalChunk(packet.data, timestamp, duration, packet.type, additions);
            if (track.source._codec === 'vp9')
                this.fixVP9ColorSpace(trackData, videoChunk);
            trackData.chunkQueue.push(videoChunk);
            await this.interleaveChunks();
        }
        finally {
            release();
        }
    }
    async addEncodedAudioPacket(track, packet, meta) {
        const release = await this.mutex.acquire();
        try {
            const trackData = this.getAudioTrackData(track, packet, meta);
            let packetData = packet.data;
            if (trackData.info.requiresAdtsStripping) {
                const adtsFrame = (0,adts_reader/* readAdtsFrameHeader */.lh)(reader/* FileSlice */.x$.tempFromBytes(packetData));
                if (!adtsFrame) {
                    throw new Error('Expected ADTS frame, didn\'t get one.');
                }
                const headerLength = adtsFrame.crcCheck === null
                    ? adts_reader/* MIN_ADTS_FRAME_HEADER_SIZE */.gc
                    : adts_reader/* MAX_ADTS_FRAME_HEADER_SIZE */.Y$;
                packetData = packetData.subarray(headerLength);
            }
            const isKeyFrame = packet.type === 'key';
            const timestamp = this.validateAndNormalizeTimestamp(trackData.track, packet.timestamp, isKeyFrame);
            const audioChunk = this.createInternalChunk(packetData, timestamp, packet.duration, packet.type);
            trackData.chunkQueue.push(audioChunk);
            await this.interleaveChunks();
        }
        finally {
            release();
        }
    }
    async addSubtitleCue(track, cue, meta) {
        const release = await this.mutex.acquire();
        try {
            const trackData = this.getSubtitleTrackData(track, meta);
            const timestamp = this.validateAndNormalizeTimestamp(trackData.track, cue.timestamp, true);
            let bodyText = cue.text;
            const timestampMs = Math.round(timestamp * 1000);
            // Replace in-body timestamps so that they're relative to the cue start time
            inlineTimestampRegex.lastIndex = 0;
            bodyText = bodyText.replace(inlineTimestampRegex, (match) => {
                const time = parseSubtitleTimestamp(match.slice(1, -1));
                const offsetTime = time - timestampMs;
                return `<${formatSubtitleTimestamp(offsetTime)}>`;
            });
            const body = misc/* textEncoder */.UG.encode(bodyText);
            const additions = `${cue.settings ?? ''}\n${cue.identifier ?? ''}\n${cue.notes ?? ''}`;
            const subtitleChunk = this.createInternalChunk(body, timestamp, cue.duration, 'key', additions.trim() ? misc/* textEncoder */.UG.encode(additions) : null);
            trackData.chunkQueue.push(subtitleChunk);
            await this.interleaveChunks();
        }
        finally {
            release();
        }
    }
    async interleaveChunks(isFinalCall = false) {
        if (!isFinalCall && !this.allTracksAreKnown()) {
            return; // We can't interleave yet as we don't yet know how many tracks we'll truly have
        }
        outer: while (true) {
            let trackWithMinTimestamp = null;
            let minTimestamp = Infinity;
            for (const trackData of this.trackDatas) {
                if (!isFinalCall && trackData.chunkQueue.length === 0 && !trackData.track.source._closed) {
                    break outer;
                }
                if (trackData.chunkQueue.length > 0 && trackData.chunkQueue[0].timestamp < minTimestamp) {
                    trackWithMinTimestamp = trackData;
                    minTimestamp = trackData.chunkQueue[0].timestamp;
                }
            }
            if (!trackWithMinTimestamp) {
                break;
            }
            const chunk = trackWithMinTimestamp.chunkQueue.shift();
            this.writeBlock(trackWithMinTimestamp, chunk);
        }
        if (!isFinalCall) {
            await this.writer.flush();
        }
    }
    /**
     * Due to [a bug in Chromium](https://bugs.chromium.org/p/chromium/issues/detail?id=1377842), VP9 streams often
     * lack color space information. This method patches in that information.
     */
    fixVP9ColorSpace(trackData, chunk) {
        // http://downloads.webmproject.org/docs/vp9/vp9-bitstream_superframe-and-uncompressed-header_v1.0.pdf
        if (chunk.type !== 'key')
            return;
        if (!trackData.info.decoderConfig.colorSpace || !trackData.info.decoderConfig.colorSpace.matrix)
            return;
        const bitstream = new misc/* Bitstream */._c(chunk.data);
        bitstream.skipBits(2);
        const profileLowBit = bitstream.readBits(1);
        const profileHighBit = bitstream.readBits(1);
        const profile = (profileHighBit << 1) + profileLowBit;
        if (profile === 3)
            bitstream.skipBits(1);
        const showExistingFrame = bitstream.readBits(1);
        if (showExistingFrame)
            return;
        const frameType = bitstream.readBits(1);
        if (frameType !== 0)
            return; // Just to be sure
        bitstream.skipBits(2);
        const syncCode = bitstream.readBits(24);
        if (syncCode !== 0x498342)
            return;
        if (profile >= 2)
            bitstream.skipBits(1);
        const colorSpaceID = {
            rgb: 7,
            bt709: 2,
            bt470bg: 1,
            smpte170m: 3,
        }[trackData.info.decoderConfig.colorSpace.matrix];
        // The bitstream position is now at the start of the color space bits.
        // We can use the global writeBits function here as requested.
        (0,misc/* writeBits */.Wo)(chunk.data, bitstream.pos, bitstream.pos + 3, colorSpaceID);
    }
    /** Converts a read-only external chunk into an internal one for easier use. */
    createInternalChunk(data, timestamp, duration, type, additions = null) {
        const internalChunk = {
            data,
            type,
            timestamp,
            duration,
            additions,
        };
        return internalChunk;
    }
    /** Writes a block containing media data to the file. */
    writeBlock(trackData, chunk) {
        // Due to the interlacing algorithm, this code will be run once we've seen one chunk from every media track.
        if (!this.segment) {
            this.createSegment();
        }
        const msTimestamp = Math.round(1000 * chunk.timestamp);
        // We wanna only finalize this cluster (and begin a new one) if we know that each track will be able to
        // start the new one with a key frame.
        const keyFrameQueuedEverywhere = this.trackDatas.every((otherTrackData) => {
            if (trackData === otherTrackData) {
                return chunk.type === 'key';
            }
            const firstQueuedSample = otherTrackData.chunkQueue[0];
            if (firstQueuedSample) {
                return firstQueuedSample.type === 'key';
            }
            return otherTrackData.track.source._closed;
        });
        let shouldCreateNewCluster = false;
        if (!this.currentCluster) {
            shouldCreateNewCluster = true;
        }
        else {
            (0,misc/* assert */.vA)(this.currentClusterStartMsTimestamp !== null);
            (0,misc/* assert */.vA)(this.currentClusterMaxMsTimestamp !== null);
            const relativeTimestamp = msTimestamp - this.currentClusterStartMsTimestamp;
            shouldCreateNewCluster = (keyFrameQueuedEverywhere
                // This check is required because that means there is already a block with this timestamp in the
                // CURRENT chunk, meaning that starting the next cluster at the same timestamp is forbidden (since
                // the already-written block would belong into it instead).
                && msTimestamp > this.currentClusterMaxMsTimestamp
                && relativeTimestamp >= 1000 * (this.format._options.minimumClusterDuration ?? 1))
                // The cluster would exceed its maximum allowed length. This puts us in an unfortunate position and forces
                // us to begin the next cluster with a delta frame. Although this is undesirable, it is not forbidden by the
                // spec and is supported by players.
                || relativeTimestamp > MAX_CLUSTER_TIMESTAMP_MS;
        }
        if (shouldCreateNewCluster) {
            this.createNewCluster(msTimestamp);
        }
        const relativeTimestamp = msTimestamp - this.currentClusterStartMsTimestamp;
        if (relativeTimestamp < MIN_CLUSTER_TIMESTAMP_MS) {
            // The block lies too far in the past, it's not representable within this cluster
            return;
        }
        const prelude = new Uint8Array(4);
        const view = new DataView(prelude.buffer);
        // 0x80 to indicate it's the last byte of a multi-byte number
        view.setUint8(0, 0x80 | trackData.track.id);
        view.setInt16(1, relativeTimestamp, false);
        const msDuration = Math.round(1000 * chunk.duration);
        if (!chunk.additions) {
            // No additions, we can write out a SimpleBlock
            view.setUint8(3, Number(chunk.type === 'key') << 7); // Flags (keyframe flag only present for SimpleBlock)
            const simpleBlock = { id: ebml/* EBMLId */.Cl.SimpleBlock, data: [
                    prelude,
                    chunk.data,
                ] };
            this.ebmlWriter.writeEBML(simpleBlock);
        }
        else {
            const blockGroup = { id: ebml/* EBMLId */.Cl.BlockGroup, data: [
                    { id: ebml/* EBMLId */.Cl.Block, data: [
                            prelude,
                            chunk.data,
                        ] },
                    chunk.type === 'delta'
                        ? {
                            id: ebml/* EBMLId */.Cl.ReferenceBlock,
                            data: new ebml/* EBMLSignedInt */.ys(trackData.lastWrittenMsTimestamp - msTimestamp),
                        }
                        : null,
                    chunk.additions
                        ? { id: ebml/* EBMLId */.Cl.BlockAdditions, data: [
                                { id: ebml/* EBMLId */.Cl.BlockMore, data: [
                                        { id: ebml/* EBMLId */.Cl.BlockAddID, data: 1 }, // Some players expect BlockAddID to come first
                                        { id: ebml/* EBMLId */.Cl.BlockAdditional, data: chunk.additions },
                                    ] },
                            ] }
                        : null,
                    msDuration > 0 ? { id: ebml/* EBMLId */.Cl.BlockDuration, data: msDuration } : null,
                ] };
            this.ebmlWriter.writeEBML(blockGroup);
        }
        this.duration = Math.max(this.duration, msTimestamp + msDuration);
        trackData.lastWrittenMsTimestamp = msTimestamp;
        if (!this.trackDatasInCurrentCluster.has(trackData)) {
            this.trackDatasInCurrentCluster.set(trackData, {
                firstMsTimestamp: msTimestamp,
            });
        }
        this.currentClusterMaxMsTimestamp = Math.max(this.currentClusterMaxMsTimestamp, msTimestamp);
    }
    /** Creates a new Cluster element to contain media chunks. */
    createNewCluster(msTimestamp) {
        if (this.currentCluster) {
            this.finalizeCurrentCluster();
        }
        if (this.format._options.onCluster) {
            this.writer.startTrackingWrites();
        }
        this.currentCluster = {
            id: ebml/* EBMLId */.Cl.Cluster,
            size: this.format._options.appendOnly ? -1 : CLUSTER_SIZE_BYTES,
            data: [
                { id: ebml/* EBMLId */.Cl.Timestamp, data: msTimestamp },
            ],
        };
        this.ebmlWriter.writeEBML(this.currentCluster);
        this.currentClusterStartMsTimestamp = msTimestamp;
        this.currentClusterMaxMsTimestamp = msTimestamp;
        this.trackDatasInCurrentCluster.clear();
    }
    finalizeCurrentCluster() {
        (0,misc/* assert */.vA)(this.currentCluster);
        if (!this.format._options.appendOnly) {
            const clusterSize = this.writer.getPos() - this.ebmlWriter.dataOffsets.get(this.currentCluster);
            const endPos = this.writer.getPos();
            // Write the size now that we know it
            this.writer.seek(this.ebmlWriter.offsets.get(this.currentCluster) + 4);
            this.ebmlWriter.writeVarInt(clusterSize, CLUSTER_SIZE_BYTES);
            this.writer.seek(endPos);
        }
        if (this.format._options.onCluster) {
            (0,misc/* assert */.vA)(this.currentClusterStartMsTimestamp !== null);
            const { data, start } = this.writer.stopTrackingWrites();
            this.format._options.onCluster(data, start, this.currentClusterStartMsTimestamp / 1000);
        }
        const clusterOffsetFromSegment = this.ebmlWriter.offsets.get(this.currentCluster) - this.segmentDataOffset;
        // Group tracks by their first timestamp and create a CuePoint for each unique timestamp
        const groupedByTimestamp = new Map();
        for (const [trackData, { firstMsTimestamp }] of this.trackDatasInCurrentCluster) {
            if (!groupedByTimestamp.has(firstMsTimestamp)) {
                groupedByTimestamp.set(firstMsTimestamp, []);
            }
            groupedByTimestamp.get(firstMsTimestamp).push(trackData);
        }
        const groupedAndSortedByTimestamp = [...groupedByTimestamp.entries()].sort((a, b) => a[0] - b[0]);
        // Add CuePoints to the Cues element for better seeking
        for (const [msTimestamp, trackDatas] of groupedAndSortedByTimestamp) {
            (0,misc/* assert */.vA)(this.cues);
            this.cues.data.push({ id: ebml/* EBMLId */.Cl.CuePoint, data: [
                    { id: ebml/* EBMLId */.Cl.CueTime, data: msTimestamp },
                    // Create CueTrackPositions for each track that starts at this timestamp
                    ...trackDatas.map((trackData) => {
                        return { id: ebml/* EBMLId */.Cl.CueTrackPositions, data: [
                                { id: ebml/* EBMLId */.Cl.CueTrack, data: trackData.track.id },
                                { id: ebml/* EBMLId */.Cl.CueClusterPosition, data: clusterOffsetFromSegment },
                            ] };
                    }),
                ] });
        }
    }
    // eslint-disable-next-line @typescript-eslint/no-misused-promises
    async onTrackClose() {
        const release = await this.mutex.acquire();
        if (this.allTracksAreKnown()) {
            this.allTracksKnown.resolve();
        }
        // Since a track is now closed, we may be able to write out chunks that were previously waiting
        await this.interleaveChunks();
        release();
    }
    /** Finalizes the file, making it ready for use. Must be called after all media chunks have been added. */
    async finalize() {
        const release = await this.mutex.acquire();
        this.allTracksKnown.resolve();
        if (!this.segment) {
            this.createSegment();
        }
        // Flush any remaining queued chunks to the file
        await this.interleaveChunks(true);
        if (this.currentCluster) {
            this.finalizeCurrentCluster();
        }
        (0,misc/* assert */.vA)(this.cues);
        this.ebmlWriter.writeEBML(this.cues);
        if (!this.format._options.appendOnly) {
            const endPos = this.writer.getPos();
            // Write the Segment size
            const segmentSize = this.writer.getPos() - this.segmentDataOffset;
            this.writer.seek(this.ebmlWriter.offsets.get(this.segment) + 4);
            this.ebmlWriter.writeVarInt(segmentSize, SEGMENT_SIZE_BYTES);
            // Write the duration of the media to the Segment
            this.segmentDuration.data = new ebml/* EBMLFloat64 */.Z4(this.duration);
            this.writer.seek(this.ebmlWriter.offsets.get(this.segmentDuration));
            this.ebmlWriter.writeEBML(this.segmentDuration);
            // Fill in SeekHead position data and write it again
            (0,misc/* assert */.vA)(this.seekHead);
            this.writer.seek(this.ebmlWriter.offsets.get(this.seekHead));
            this.maybeCreateSeekHead(true);
            this.ebmlWriter.writeEBML(this.seekHead);
            this.writer.seek(endPos);
        }
        release();
    }
}

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/shared/mp3-misc.js
var mp3_misc = __webpack_require__(2788);
;// ./node_modules/mediabunny/dist/modules/src/mp3/mp3-writer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

class Mp3Writer {
    constructor(writer) {
        this.writer = writer;
        this.helper = new Uint8Array(8);
        this.helperView = new DataView(this.helper.buffer);
    }
    writeU32(value) {
        this.helperView.setUint32(0, value, false);
        this.writer.write(this.helper.subarray(0, 4));
    }
    writeXingFrame(data) {
        const startPos = this.writer.getPos();
        const firstByte = 0xff;
        const secondByte = 0xe0 | (data.mpegVersionId << 3) | (data.layer << 1);
        let lowSamplingFrequency;
        if (data.mpegVersionId & 2) {
            lowSamplingFrequency = (data.mpegVersionId & 1) ? 0 : 1;
        }
        else {
            lowSamplingFrequency = 1;
        }
        const padding = 0;
        const neededBytes = 155;
        let bitrateIndex = -1;
        const bitrateOffset = lowSamplingFrequency * 16 * 4 + data.layer * 16;
        // Let's find the lowest bitrate for which the frame size is sufficiently large to fit all the data
        for (let i = 0; i < 16; i++) {
            const kbr = mp3_misc/* KILOBIT_RATES */.D0[bitrateOffset + i];
            const size = (0,mp3_misc/* computeMp3FrameSize */.c9)(lowSamplingFrequency, data.layer, 1000 * kbr, data.sampleRate, padding);
            if (size >= neededBytes) {
                bitrateIndex = i;
                break;
            }
        }
        if (bitrateIndex === -1) {
            throw new Error('No suitable bitrate found.');
        }
        const thirdByte = (bitrateIndex << 4) | (data.frequencyIndex << 2) | padding << 1;
        const fourthByte = (data.channel << 6)
            | (data.modeExtension << 4)
            | (data.copyright << 3)
            | (data.original << 2)
            | data.emphasis;
        this.helper[0] = firstByte;
        this.helper[1] = secondByte;
        this.helper[2] = thirdByte;
        this.helper[3] = fourthByte;
        this.writer.write(this.helper.subarray(0, 4));
        const xingOffset = (0,mp3_misc/* getXingOffset */.EZ)(data.mpegVersionId, data.channel);
        this.writer.seek(startPos + xingOffset);
        this.writeU32(mp3_misc/* XING */.hY);
        let flags = 0;
        if (data.frameCount !== null) {
            flags |= 1;
        }
        if (data.fileSize !== null) {
            flags |= 2;
        }
        if (data.toc !== null) {
            flags |= 4;
        }
        this.writeU32(flags);
        this.writeU32(data.frameCount ?? 0);
        this.writeU32(data.fileSize ?? 0);
        this.writer.write(data.toc ?? new Uint8Array(100));
        const kilobitRate = mp3_misc/* KILOBIT_RATES */.D0[bitrateOffset + bitrateIndex];
        const frameSize = (0,mp3_misc/* computeMp3FrameSize */.c9)(lowSamplingFrequency, data.layer, 1000 * kilobitRate, data.sampleRate, padding);
        this.writer.seek(startPos + frameSize);
    }
}

;// ./node_modules/mediabunny/dist/modules/src/mp3/mp3-muxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */






class Mp3Muxer extends Muxer {
    constructor(output, format) {
        super(output);
        this.xingFrameData = null;
        this.frameCount = 0;
        this.framePositions = [];
        this.xingFramePos = null;
        this.format = format;
        this.writer = output._writer;
        this.mp3Writer = new Mp3Writer(output._writer);
    }
    async start() {
        if (!(0,src_metadata/* metadataTagsAreEmpty */.cc)(this.output._metadataTags)) {
            const id3Writer = new id3/* Id3V2Writer */.Ov(this.writer);
            id3Writer.writeId3V2Tag(this.output._metadataTags);
        }
    }
    async getMimeType() {
        return 'audio/mpeg';
    }
    async addEncodedVideoPacket() {
        throw new Error('MP3 does not support video.');
    }
    async addEncodedAudioPacket(track, packet) {
        const release = await this.mutex.acquire();
        try {
            const writeXingHeader = this.format._options.xingHeader !== false;
            if (!this.xingFrameData && writeXingHeader) {
                const view = (0,misc/* toDataView */.Zc)(packet.data);
                if (view.byteLength < 4) {
                    throw new Error('Invalid MP3 header in sample.');
                }
                const word = view.getUint32(0, false);
                const header = (0,mp3_misc/* readMp3FrameHeader */.P8)(word, null).header;
                if (!header) {
                    throw new Error('Invalid MP3 header in sample.');
                }
                const xingOffset = (0,mp3_misc/* getXingOffset */.EZ)(header.mpegVersionId, header.channel);
                if (view.byteLength >= xingOffset + 4) {
                    const word = view.getUint32(xingOffset, false);
                    const isXing = word === mp3_misc/* XING */.hY || word === mp3_misc/* INFO */.rD;
                    if (isXing) {
                        // This is not a data frame, so let's completely ignore this sample
                        return;
                    }
                }
                this.xingFrameData = {
                    mpegVersionId: header.mpegVersionId,
                    layer: header.layer,
                    frequencyIndex: header.frequencyIndex,
                    sampleRate: header.sampleRate,
                    channel: header.channel,
                    modeExtension: header.modeExtension,
                    copyright: header.copyright,
                    original: header.original,
                    emphasis: header.emphasis,
                    frameCount: null,
                    fileSize: null,
                    toc: null,
                };
                // Write a Xing frame because this muxer doesn't make any bitrate constraints, meaning we don't know if
                // this will be a constant or variable bitrate file. Therefore, always write the Xing frame.
                this.xingFramePos = this.writer.getPos();
                this.mp3Writer.writeXingFrame(this.xingFrameData);
                this.frameCount++;
            }
            this.validateAndNormalizeTimestamp(track, packet.timestamp, packet.type === 'key');
            this.writer.write(packet.data);
            this.frameCount++;
            await this.writer.flush();
            if (writeXingHeader) {
                this.framePositions.push(this.writer.getPos());
            }
        }
        finally {
            release();
        }
    }
    async addSubtitleCue() {
        throw new Error('MP3 does not support subtitles.');
    }
    async finalize() {
        if (!this.xingFrameData || this.xingFramePos === null) {
            return;
        }
        const release = await this.mutex.acquire();
        const endPos = this.writer.getPos();
        this.writer.seek(this.xingFramePos);
        const toc = new Uint8Array(100);
        for (let i = 0; i < 100; i++) {
            const index = Math.floor(this.framePositions.length * (i / 100));
            (0,misc/* assert */.vA)(index !== -1 && index < this.framePositions.length);
            const byteOffset = this.framePositions[index];
            toc[i] = 256 * (byteOffset / endPos);
        }
        this.xingFrameData.frameCount = this.frameCount;
        this.xingFrameData.fileSize = endPos;
        this.xingFrameData.toc = toc;
        if (this.format._options.onXingFrame) {
            this.writer.startTrackingWrites();
        }
        this.mp3Writer.writeXingFrame(this.xingFrameData);
        if (this.format._options.onXingFrame) {
            const { data, start } = this.writer.stopTrackingWrites();
            this.format._options.onXingFrame(data, start);
        }
        this.writer.seek(endPos);
        release();
    }
}

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/ogg/ogg-misc.js
var ogg_misc = __webpack_require__(9730);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/ogg/ogg-reader.js
var ogg_reader = __webpack_require__(9841);
;// ./node_modules/mediabunny/dist/modules/src/ogg/ogg-muxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */






const PAGE_SIZE_TARGET = 8192;
class OggMuxer extends Muxer {
    constructor(output, format) {
        super(output);
        this.trackDatas = [];
        this.bosPagesWritten = false;
        this.allTracksKnown = (0,misc/* promiseWithResolvers */.nJ)();
        this.pageBytes = new Uint8Array(ogg_reader/* MAX_PAGE_SIZE */.H4);
        this.pageView = new DataView(this.pageBytes.buffer);
        this.format = format;
        this.writer = output._writer;
        this.writer.ensureMonotonicity = true; // Ogg is always monotonically written!
    }
    async start() {
        // Nothin'
    }
    async getMimeType() {
        await this.allTracksKnown.promise;
        return (0,ogg_misc/* buildOggMimeType */.Ob)({
            codecStrings: this.trackDatas.map(x => x.codecInfo.codec),
        });
    }
    addEncodedVideoPacket() {
        throw new Error('Video tracks are not supported.');
    }
    getTrackData(track, meta) {
        const existingTrackData = this.trackDatas.find(td => td.track === track);
        if (existingTrackData) {
            return existingTrackData;
        }
        // Give the track a unique random serial number
        let serialNumber;
        do {
            serialNumber = Math.floor(2 ** 32 * Math.random());
        } while (this.trackDatas.some(td => td.serialNumber === serialNumber));
        (0,misc/* assert */.vA)(track.source._codec === 'vorbis' || track.source._codec === 'opus');
        (0,src_codec/* validateAudioChunkMetadata */.P7)(meta);
        (0,misc/* assert */.vA)(meta);
        (0,misc/* assert */.vA)(meta.decoderConfig);
        const newTrackData = {
            track,
            serialNumber,
            internalSampleRate: track.source._codec === 'opus'
                ? src_codec/* OPUS_SAMPLE_RATE */.yo
                : meta.decoderConfig.sampleRate,
            codecInfo: {
                codec: track.source._codec,
                vorbisInfo: null,
                opusInfo: null,
            },
            vorbisLastBlocksize: null,
            packetQueue: [],
            currentTimestampInSamples: 0,
            pagesWritten: 0,
            currentGranulePosition: 0,
            currentLacingValues: [],
            currentPageData: [],
            currentPageSize: 27,
            currentPageStartsWithFreshPacket: true,
            currentPageStartTimestampInSamples: 0,
        };
        this.queueHeaderPackets(newTrackData, meta);
        this.trackDatas.push(newTrackData);
        if (this.allTracksAreKnown()) {
            this.allTracksKnown.resolve();
        }
        return newTrackData;
    }
    queueHeaderPackets(trackData, meta) {
        (0,misc/* assert */.vA)(meta.decoderConfig);
        if (trackData.track.source._codec === 'vorbis') {
            (0,misc/* assert */.vA)(meta.decoderConfig.description);
            const bytes = (0,misc/* toUint8Array */.Fo)(meta.decoderConfig.description);
            if (bytes[0] !== 2) {
                throw new TypeError('First byte of Vorbis decoder description must be 2.');
            }
            let pos = 1;
            const readPacketLength = () => {
                let length = 0;
                while (true) {
                    const value = bytes[pos++];
                    if (value === undefined) {
                        throw new TypeError('Vorbis decoder description is too short.');
                    }
                    length += value;
                    if (value < 255) {
                        return length;
                    }
                }
            };
            const identificationHeaderLength = readPacketLength();
            const commentHeaderLength = readPacketLength();
            const setupHeaderLength = bytes.length - pos; // Setup header fills the remaining bytes
            if (setupHeaderLength <= 0) {
                throw new TypeError('Vorbis decoder description is too short.');
            }
            const identificationHeader = bytes.subarray(pos, pos += identificationHeaderLength);
            pos += commentHeaderLength; // Skip the comment header, we'll build our own
            const setupHeader = bytes.subarray(pos);
            const commentHeaderHeader = new Uint8Array(7);
            commentHeaderHeader[0] = 3; // Packet type
            commentHeaderHeader[1] = 0x76; // 'v'
            commentHeaderHeader[2] = 0x6f; // 'o'
            commentHeaderHeader[3] = 0x72; // 'r'
            commentHeaderHeader[4] = 0x62; // 'b'
            commentHeaderHeader[5] = 0x69; // 'i'
            commentHeaderHeader[6] = 0x73; // 's'
            const commentHeader = (0,codec_data/* createVorbisComments */.WY)(commentHeaderHeader, this.output._metadataTags, true);
            trackData.packetQueue.push({
                data: identificationHeader,
                timestampInSamples: 0,
                durationInSamples: 0,
                forcePageFlush: true,
            }, {
                data: commentHeader,
                timestampInSamples: 0,
                durationInSamples: 0,
                forcePageFlush: false,
            }, {
                data: setupHeader,
                timestampInSamples: 0,
                durationInSamples: 0,
                forcePageFlush: true, // The last header packet must flush the page
            });
            const view = (0,misc/* toDataView */.Zc)(identificationHeader);
            const blockSizeByte = view.getUint8(28);
            trackData.codecInfo.vorbisInfo = {
                blocksizes: [
                    1 << (blockSizeByte & 0xf),
                    1 << (blockSizeByte >> 4),
                ],
                modeBlockflags: (0,codec_data/* parseModesFromVorbisSetupPacket */.Co)(setupHeader).modeBlockflags,
            };
        }
        else if (trackData.track.source._codec === 'opus') {
            if (!meta.decoderConfig.description) {
                throw new TypeError('For Ogg, Opus decoder description is required.');
            }
            const identificationHeader = (0,misc/* toUint8Array */.Fo)(meta.decoderConfig.description);
            const commentHeaderHeader = new Uint8Array(8);
            const commentHeaderHeaderView = (0,misc/* toDataView */.Zc)(commentHeaderHeader);
            commentHeaderHeaderView.setUint32(0, 0x4f707573, false); // 'Opus'
            commentHeaderHeaderView.setUint32(4, 0x54616773, false); // 'Tags'
            const commentHeader = (0,codec_data/* createVorbisComments */.WY)(commentHeaderHeader, this.output._metadataTags, true);
            trackData.packetQueue.push({
                data: identificationHeader,
                timestampInSamples: 0,
                durationInSamples: 0,
                forcePageFlush: true,
            }, {
                data: commentHeader,
                timestampInSamples: 0,
                durationInSamples: 0,
                forcePageFlush: true, // The last header packet must flush the page
            });
            trackData.codecInfo.opusInfo = {
                preSkip: (0,codec_data/* parseOpusIdentificationHeader */.Qf)(identificationHeader).preSkip,
            };
        }
    }
    async addEncodedAudioPacket(track, packet, meta) {
        const release = await this.mutex.acquire();
        try {
            const trackData = this.getTrackData(track, meta);
            this.validateAndNormalizeTimestamp(trackData.track, packet.timestamp, packet.type === 'key');
            const currentTimestampInSamples = trackData.currentTimestampInSamples;
            const { durationInSamples, vorbisBlockSize } = (0,ogg_misc/* extractSampleMetadata */.nL)(packet.data, trackData.codecInfo, trackData.vorbisLastBlocksize);
            trackData.currentTimestampInSamples += durationInSamples;
            trackData.vorbisLastBlocksize = vorbisBlockSize;
            trackData.packetQueue.push({
                data: packet.data,
                timestampInSamples: currentTimestampInSamples,
                durationInSamples,
                forcePageFlush: false,
            });
            await this.interleavePages();
        }
        finally {
            release();
        }
    }
    addSubtitleCue() {
        throw new Error('Subtitle tracks are not supported.');
    }
    allTracksAreKnown() {
        for (const track of this.output._tracks) {
            if (!track.source._closed && !this.trackDatas.some(x => x.track === track)) {
                return false; // We haven't seen a sample from this open track yet
            }
        }
        return true;
    }
    async interleavePages(isFinalCall = false) {
        if (!this.bosPagesWritten) {
            if (!this.allTracksAreKnown() && !isFinalCall) {
                return; // We can't interleave yet as we don't yet know how many tracks we'll truly have
            }
            // Write the header page for all bitstreams
            for (const trackData of this.trackDatas) {
                while (trackData.packetQueue.length > 0) {
                    const packet = trackData.packetQueue.shift();
                    this.writePacket(trackData, packet, false);
                    if (packet.forcePageFlush) {
                        // We say the header page ends once the first packet is encountered that forces a page flush
                        break;
                    }
                }
            }
            this.bosPagesWritten = true;
        }
        outer: while (true) {
            let trackWithMinTimestamp = null;
            let minTimestamp = Infinity;
            for (const trackData of this.trackDatas) {
                if (!isFinalCall
                    && trackData.packetQueue.length <= 1 // Limit is 1, not 0, for correct EOS flag logic
                    && !trackData.track.source._closed) {
                    break outer;
                }
                if (trackData.packetQueue.length > 0
                    && trackData.packetQueue[0].timestampInSamples < minTimestamp) {
                    trackWithMinTimestamp = trackData;
                    minTimestamp = trackData.packetQueue[0].timestampInSamples;
                }
            }
            if (!trackWithMinTimestamp) {
                break;
            }
            const packet = trackWithMinTimestamp.packetQueue.shift();
            const isFinalPacket = trackWithMinTimestamp.packetQueue.length === 0;
            this.writePacket(trackWithMinTimestamp, packet, isFinalPacket);
        }
        if (!isFinalCall) {
            await this.writer.flush();
        }
    }
    writePacket(trackData, packet, isFinalPacket) {
        const packetEndTimestampInSamples = packet.timestampInSamples + packet.durationInSamples;
        if (this.format._options.maximumPageDuration !== undefined) {
            const maxDurationInSamples = this.format._options.maximumPageDuration * trackData.internalSampleRate;
            if (trackData.currentLacingValues.length > 0
                && packetEndTimestampInSamples - trackData.currentPageStartTimestampInSamples > maxDurationInSamples) {
                // Flush the current page early to avoid exceeding the maximum page duration
                this.writePage(trackData, false);
            }
        }
        let remainingLength = packet.data.length;
        let dataStartOffset = 0;
        let dataOffset = 0;
        while (true) {
            if (trackData.currentLacingValues.length === 0 && dataStartOffset > 0) {
                // This is a packet spanning multiple pages
                trackData.currentPageStartsWithFreshPacket = false;
            }
            const segmentSize = Math.min(255, remainingLength);
            trackData.currentLacingValues.push(segmentSize);
            trackData.currentPageSize++;
            dataOffset += segmentSize;
            const segmentIsLastOfPacket = remainingLength < 255;
            if (trackData.currentLacingValues.length === 255) {
                // The page is full, we need to add part of the packet data and then flush the page
                const slice = packet.data.subarray(dataStartOffset, dataOffset);
                dataStartOffset = dataOffset;
                trackData.currentPageData.push(slice);
                trackData.currentPageSize += slice.length;
                this.writePage(trackData, isFinalPacket && segmentIsLastOfPacket);
                if (segmentIsLastOfPacket) {
                    return;
                }
            }
            if (segmentIsLastOfPacket) {
                break;
            }
            remainingLength -= 255;
        }
        const slice = packet.data.subarray(dataStartOffset);
        trackData.currentPageData.push(slice);
        trackData.currentPageSize += slice.length;
        trackData.currentGranulePosition = packetEndTimestampInSamples;
        if (trackData.currentPageSize >= PAGE_SIZE_TARGET || packet.forcePageFlush) {
            this.writePage(trackData, isFinalPacket);
        }
    }
    writePage(trackData, isEos) {
        this.pageView.setUint32(0, ogg_misc/* OGGS */.Zk, true); // Capture pattern
        this.pageView.setUint8(4, 0); // Version
        let headerType = 0;
        if (!trackData.currentPageStartsWithFreshPacket) {
            headerType |= 1;
        }
        if (trackData.pagesWritten === 0) {
            headerType |= 2; // Beginning of stream
        }
        if (isEos) {
            headerType |= 4; // End of stream
        }
        this.pageView.setUint8(5, headerType); // Header type
        const granulePosition = trackData.currentLacingValues.every(x => x === 255)
            ? -1 // No packets end on this page
            : trackData.currentGranulePosition;
        (0,misc/* setInt64 */._j)(this.pageView, 6, granulePosition, true); // Granule position
        this.pageView.setUint32(14, trackData.serialNumber, true); // Serial number
        this.pageView.setUint32(18, trackData.pagesWritten, true); // Page sequence number
        this.pageView.setUint32(22, 0, true); // Checksum placeholder
        this.pageView.setUint8(26, trackData.currentLacingValues.length); // Number of page segments
        this.pageBytes.set(trackData.currentLacingValues, 27);
        let pos = 27 + trackData.currentLacingValues.length;
        for (const data of trackData.currentPageData) {
            this.pageBytes.set(data, pos);
            pos += data.length;
        }
        const slice = this.pageBytes.subarray(0, pos);
        const crc = (0,ogg_misc/* computeOggPageCrc */._S)(slice);
        this.pageView.setUint32(22, crc, true); // Checksum
        trackData.pagesWritten++;
        trackData.currentLacingValues.length = 0;
        trackData.currentPageData.length = 0;
        trackData.currentPageSize = 27;
        trackData.currentPageStartsWithFreshPacket = true;
        trackData.currentPageStartTimestampInSamples = trackData.currentGranulePosition;
        if (this.format._options.onPage) {
            this.writer.startTrackingWrites();
        }
        this.writer.write(slice);
        if (this.format._options.onPage) {
            const { data, start } = this.writer.stopTrackingWrites();
            this.format._options.onPage(data, start, trackData.track.source);
        }
    }
    // eslint-disable-next-line @typescript-eslint/no-misused-promises
    async onTrackClose() {
        const release = await this.mutex.acquire();
        if (this.allTracksAreKnown()) {
            this.allTracksKnown.resolve();
        }
        // Since a track is now closed, we may be able to write out chunks that were previously waiting
        await this.interleavePages();
        release();
    }
    async finalize() {
        const release = await this.mutex.acquire();
        this.allTracksKnown.resolve();
        await this.interleavePages(true);
        for (const trackData of this.trackDatas) {
            if (trackData.currentLacingValues.length > 0) {
                this.writePage(trackData, true);
            }
        }
        release();
    }
}

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/mpeg-ts/mpeg-ts-misc.js
var mpeg_ts_misc = __webpack_require__(2490);
;// ./node_modules/mediabunny/dist/modules/src/mpeg-ts/mpeg-ts-muxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */






// Resources:
// ISO/IEC 13818-1
const PAT_PID = 0x0000;
const PMT_PID = 0x1000;
const FIRST_TRACK_PID = 0x0100;
const VIDEO_STREAM_ID_BASE = 0xE0;
const AUDIO_STREAM_ID_BASE = 0xC0;
const AVC_AUD_NAL = new Uint8Array([0x09, 0xF0]);
const HEVC_AUD_NAL = new Uint8Array([0x46, 0x01]);
class MpegTsMuxer extends Muxer {
    constructor(output, format) {
        super(output);
        this.trackDatas = [];
        this.tablesWritten = false;
        this.continuityCounters = new Map();
        this.packetBuffer = new Uint8Array(mpeg_ts_misc/* TS_PACKET_SIZE */.ZT);
        this.packetView = (0,misc/* toDataView */.Zc)(this.packetBuffer);
        this.allTracksKnown = (0,misc/* promiseWithResolvers */.nJ)();
        this.videoTrackIndex = 0;
        this.audioTrackIndex = 0;
        this.adaptationFieldBuffer = new Uint8Array(184);
        this.payloadBuffer = new Uint8Array(184);
        this.format = format;
        this.writer = output._writer;
        this.writer.ensureMonotonicity = true;
    }
    async start() {
        // Nothing to do here
    }
    async getMimeType() {
        await this.allTracksKnown.promise;
        return (0,mpeg_ts_misc/* buildMpegTsMimeType */.Vx)(this.trackDatas.map(x => x.codecString));
    }
    getVideoTrackData(track, meta) {
        const existingTrackData = this.trackDatas.find(x => x.track === track);
        if (existingTrackData) {
            return existingTrackData;
        }
        (0,src_codec/* validateVideoChunkMetadata */.aF)(meta);
        (0,misc/* assert */.vA)(meta?.decoderConfig);
        const codec = track.source._codec;
        (0,misc/* assert */.vA)(codec === 'avc' || codec === 'hevc');
        const streamType = codec === 'avc'
            ? 27 /* MpegTsStreamType.AVC */
            : 36 /* MpegTsStreamType.HEVC */;
        const pid = FIRST_TRACK_PID + this.trackDatas.length;
        const streamId = VIDEO_STREAM_ID_BASE + this.videoTrackIndex++;
        const newTrackData = {
            track,
            pid,
            streamType,
            streamId,
            codecString: meta.decoderConfig.codec,
            timestampProcessingQueue: [],
            packetQueue: [],
            inputIsAnnexB: null,
            inputIsAdts: null,
            avcDecoderConfig: null,
            hevcDecoderConfig: null,
            adtsHeader: null,
            adtsHeaderBitstream: null,
            firstPacketWritten: false,
        };
        this.trackDatas.push(newTrackData);
        if (this.allTracksAreKnown()) {
            this.allTracksKnown.resolve();
        }
        return newTrackData;
    }
    getAudioTrackData(track, meta) {
        const existingTrackData = this.trackDatas.find(x => x.track === track);
        if (existingTrackData) {
            return existingTrackData;
        }
        (0,src_codec/* validateAudioChunkMetadata */.P7)(meta);
        (0,misc/* assert */.vA)(meta?.decoderConfig);
        const codec = track.source._codec;
        (0,misc/* assert */.vA)(codec === 'aac' || codec === 'mp3' || codec === 'ac3' || codec === 'eac3');
        let streamType;
        let streamId;
        switch (codec) {
            case 'aac':
                {
                    streamType = 15 /* MpegTsStreamType.AAC */;
                    streamId = AUDIO_STREAM_ID_BASE + this.audioTrackIndex++;
                }
                ;
                break;
            case 'mp3':
                {
                    streamType = 3 /* MpegTsStreamType.MP3_MPEG1 */;
                    streamId = AUDIO_STREAM_ID_BASE + this.audioTrackIndex++;
                }
                ;
                break;
            case 'ac3':
                {
                    streamType = 129 /* MpegTsStreamType.AC3_SYSTEM_A */;
                    streamId = 0xbd;
                }
                ;
                break;
            case 'eac3':
                {
                    streamType = 135 /* MpegTsStreamType.EAC3_SYSTEM_A */;
                    streamId = 0xbd;
                }
                ;
                break;
        }
        const pid = FIRST_TRACK_PID + this.trackDatas.length;
        const newTrackData = {
            track,
            pid,
            streamType,
            streamId,
            codecString: meta.decoderConfig.codec,
            timestampProcessingQueue: [],
            packetQueue: [],
            inputIsAnnexB: null,
            inputIsAdts: null,
            avcDecoderConfig: null,
            hevcDecoderConfig: null,
            adtsHeader: null,
            adtsHeaderBitstream: null,
            firstPacketWritten: false,
        };
        this.trackDatas.push(newTrackData);
        if (this.allTracksAreKnown()) {
            this.allTracksKnown.resolve();
        }
        return newTrackData;
    }
    async addEncodedVideoPacket(track, packet, meta) {
        const release = await this.mutex.acquire();
        try {
            const trackData = this.getVideoTrackData(track, meta);
            const timestamp = this.validateAndNormalizeTimestamp(trackData.track, packet.timestamp, packet.type === 'key');
            const preparedData = this.prepareVideoPacket(trackData, packet, meta);
            if (packet.type === 'key') {
                await this.flushTimestampQueue(trackData);
            }
            trackData.timestampProcessingQueue.push({
                data: preparedData,
                presentationTimestamp: timestamp,
                decodeTimestamp: null,
                isKeyframe: packet.type === 'key',
            });
        }
        finally {
            release();
        }
    }
    async addEncodedAudioPacket(track, packet, meta) {
        const release = await this.mutex.acquire();
        try {
            const trackData = this.getAudioTrackData(track, meta);
            const timestamp = this.validateAndNormalizeTimestamp(trackData.track, packet.timestamp, packet.type === 'key');
            const preparedData = this.prepareAudioPacket(trackData, packet, meta);
            if (packet.type === 'key') {
                await this.flushTimestampQueue(trackData);
            }
            trackData.timestampProcessingQueue.push({
                data: preparedData,
                presentationTimestamp: timestamp,
                decodeTimestamp: null,
                isKeyframe: packet.type === 'key',
            });
        }
        finally {
            release();
        }
    }
    async addSubtitleCue() {
        throw new Error('MPEG-TS does not support subtitles.');
    }
    prepareVideoPacket(trackData, packet, meta) {
        const codec = trackData.track.source._codec;
        if (trackData.inputIsAnnexB === null) {
            // This is the first packet
            const description = meta?.decoderConfig?.description;
            trackData.inputIsAnnexB = !description;
            if (!trackData.inputIsAnnexB) {
                const bytes = (0,misc/* toUint8Array */.Fo)(description);
                if (codec === 'avc') {
                    trackData.avcDecoderConfig = (0,codec_data/* deserializeAvcDecoderConfigurationRecord */.BP)(bytes);
                }
                else {
                    trackData.hevcDecoderConfig = (0,codec_data/* deserializeHevcDecoderConfigurationRecord */.hf)(bytes);
                }
            }
        }
        if (trackData.inputIsAnnexB) {
            return this.prepareAnnexBVideoPacket(packet.data, codec);
        }
        else {
            return this.prepareLengthPrefixedVideoPacket(trackData, packet, codec);
        }
    }
    prepareAnnexBVideoPacket(data, codec) {
        const nalUnits = [];
        for (const loc of (0,codec_data/* iterateNalUnitsInAnnexB */._u)(data)) {
            const nalUnit = data.subarray(loc.offset, loc.offset + loc.length);
            const isAud = codec === 'avc'
                ? (0,codec_data/* extractNalUnitTypeForAvc */.uN)(nalUnit[0]) === codec_data/* AvcNalUnitType */.mY.AUD
                : (0,codec_data/* extractNalUnitTypeForHevc */.O9)(nalUnit[0]) === codec_data/* HevcNalUnitType */.iJ.AUD_NUT;
            if (!isAud) {
                nalUnits.push(nalUnit);
            }
        }
        // Pretend the AUD
        const aud = codec === 'avc'
            ? AVC_AUD_NAL
            : HEVC_AUD_NAL;
        nalUnits.unshift(aud);
        return (0,codec_data/* concatNalUnitsInAnnexB */.GE)(nalUnits);
    }
    prepareLengthPrefixedVideoPacket(trackData, packet, codec) {
        const data = packet.data;
        const lengthSize = codec === 'avc'
            ? (trackData.avcDecoderConfig.lengthSizeMinusOne + 1)
            : (trackData.hevcDecoderConfig.lengthSizeMinusOne + 1);
        const nalUnits = [];
        for (const loc of (0,codec_data/* iterateNalUnitsInLengthPrefixed */.HR)(data, lengthSize)) {
            const nalUnit = data.subarray(loc.offset, loc.offset + loc.length);
            const isAud = codec === 'avc'
                ? (0,codec_data/* extractNalUnitTypeForAvc */.uN)(nalUnit[0]) === codec_data/* AvcNalUnitType */.mY.AUD
                : (0,codec_data/* extractNalUnitTypeForHevc */.O9)(nalUnit[0]) === codec_data/* HevcNalUnitType */.iJ.AUD_NUT;
            if (!isAud) {
                nalUnits.push(nalUnit);
            }
        }
        if (packet.type === 'key') {
            // Add whichever NALUs are missing
            if (codec === 'avc') {
                const config = trackData.avcDecoderConfig;
                for (const pps of config.pictureParameterSets) {
                    nalUnits.unshift(pps);
                }
                for (const sps of config.sequenceParameterSets) {
                    nalUnits.unshift(sps);
                }
            }
            else {
                const config = trackData.hevcDecoderConfig;
                for (const arr of config.arrays) {
                    if (arr.nalUnitType === codec_data/* HevcNalUnitType */.iJ.PPS_NUT) {
                        for (const nal of arr.nalUnits) {
                            nalUnits.unshift(nal);
                        }
                    }
                }
                for (const arr of config.arrays) {
                    if (arr.nalUnitType === codec_data/* HevcNalUnitType */.iJ.SPS_NUT) {
                        for (const nal of arr.nalUnits) {
                            nalUnits.unshift(nal);
                        }
                    }
                }
                for (const arr of config.arrays) {
                    if (arr.nalUnitType === codec_data/* HevcNalUnitType */.iJ.VPS_NUT) {
                        for (const nal of arr.nalUnits) {
                            nalUnits.unshift(nal);
                        }
                    }
                }
            }
        }
        // Prepend the AUD
        const aud = codec === 'avc'
            ? AVC_AUD_NAL
            : HEVC_AUD_NAL;
        nalUnits.unshift(aud);
        return (0,codec_data/* concatNalUnitsInAnnexB */.GE)(nalUnits);
    }
    prepareAudioPacket(trackData, packet, meta) {
        const codec = trackData.track.source._codec;
        if (codec === 'mp3' || codec === 'ac3' || codec === 'eac3') {
            // We're good
            return packet.data;
        }
        if (trackData.inputIsAdts === null) {
            // It's the first packet
            const description = meta?.decoderConfig?.description;
            trackData.inputIsAdts = !description;
            if (!trackData.inputIsAdts) {
                const config = (0,src_codec/* parseAacAudioSpecificConfig */.zF)((0,misc/* toUint8Array */.Fo)(description));
                const template = buildAdtsHeaderTemplate(config);
                trackData.adtsHeader = template.header;
                trackData.adtsHeaderBitstream = template.bitstream;
            }
        }
        if (trackData.inputIsAdts) {
            return packet.data;
        }
        (0,misc/* assert */.vA)(trackData.adtsHeader);
        (0,misc/* assert */.vA)(trackData.adtsHeaderBitstream);
        const header = trackData.adtsHeader;
        const frameLength = packet.data.byteLength + header.byteLength;
        writeAdtsFrameLength(trackData.adtsHeaderBitstream, frameLength);
        const result = new Uint8Array(frameLength);
        result.set(header, 0);
        result.set(packet.data, header.byteLength);
        return result;
    }
    allTracksAreKnown() {
        for (const track of this.output._tracks) {
            if (!track.source._closed && !this.trackDatas.some(x => x.track === track)) {
                return false;
            }
        }
        return true;
    }
    async flushTimestampQueue(trackData, alsoInterleave = true) {
        if (trackData.timestampProcessingQueue.length === 0) {
            return;
        }
        const sortedTimestamps = trackData.timestampProcessingQueue
            .map(packet => packet.presentationTimestamp)
            .sort((a, b) => a - b);
        for (let i = 0; i < trackData.timestampProcessingQueue.length; i++) {
            const queuedPacket = trackData.timestampProcessingQueue[i];
            queuedPacket.decodeTimestamp = sortedTimestamps[i];
            trackData.packetQueue.push(queuedPacket);
        }
        trackData.timestampProcessingQueue.length = 0;
        if (alsoInterleave) {
            await this.interleavePackets();
        }
    }
    async interleavePackets(isFinalCall = false) {
        if (!this.tablesWritten) {
            if (!this.allTracksAreKnown() && !isFinalCall) {
                return;
            }
            this.writeTables();
        }
        outer: while (true) {
            let trackWithMinTimestamp = null;
            let minTimestamp = Infinity;
            for (const trackData of this.trackDatas) {
                if (!isFinalCall
                    && trackData.packetQueue.length === 0
                    && !trackData.track.source._closed) {
                    break outer;
                }
                if (trackData.packetQueue.length > 0
                    && trackData.packetQueue[0].presentationTimestamp < minTimestamp) {
                    trackWithMinTimestamp = trackData;
                    minTimestamp = trackData.packetQueue[0].presentationTimestamp;
                }
            }
            if (!trackWithMinTimestamp) {
                break;
            }
            const queuedPacket = trackWithMinTimestamp.packetQueue.shift();
            this.writePesPacket(trackWithMinTimestamp, queuedPacket);
        }
        if (!isFinalCall) {
            await this.writer.flush();
        }
    }
    writeTables() {
        (0,misc/* assert */.vA)(!this.tablesWritten);
        this.writePsiSection(PAT_PID, PAT_SECTION);
        this.writePsiSection(PMT_PID, buildPmt(this.trackDatas));
        this.tablesWritten = true;
    }
    writePsiSection(pid, section) {
        let offset = 0;
        let isFirst = true;
        // Long PSI sections might span more than one TS packet
        while (offset < section.length) {
            const pointerFieldSize = isFirst ? 1 : 0;
            const availablePayload = 184 - pointerFieldSize;
            const remainingData = section.length - offset;
            const chunkSize = Math.min(availablePayload, remainingData);
            let payload;
            if (isFirst) {
                payload = this.payloadBuffer.subarray(0, 1 + chunkSize);
                payload[0] = 0x00; // pointer_field
                payload.set(section.subarray(offset, offset + chunkSize), 1);
            }
            else {
                payload = section.subarray(offset, offset + chunkSize);
            }
            this.writeTsPacket(pid, isFirst, null, payload);
            offset += chunkSize;
            isFirst = false;
        }
    }
    writePesPacket(trackData, queuedPacket) {
        const includeDts = trackData.track.type === 'video';
        const headerDataLength = includeDts ? 10 : 5;
        const pesHeaderBuffer = new Uint8Array(9 + headerDataLength);
        const pesView = (0,misc/* toDataView */.Zc)(pesHeaderBuffer);
        const ptsDtsBitstream = new misc/* Bitstream */._c(pesHeaderBuffer.subarray(9));
        (0,misc/* setUint24 */.jD)(pesView, 0, 0x000001, false); // packet_start_code_prefix
        pesHeaderBuffer[3] = trackData.streamId; // stream_id
        const pesPacketLength = trackData.track.type === 'video'
            ? 0 // Unbounded
            : Math.min(8 + queuedPacket.data.length, 0xFFFF); // Required for audio for some reason
        pesView.setUint16(4, pesPacketLength, false);
        // '10' marker, PES_scrambling_control=0, PES_priority=0,
        // data_alignment_indicator=1, copyright=0, original_or_copy=0
        pesView.setUint8(6, 0x84);
        pesView.setUint8(7, includeDts ? 0xC0 : 0x80); // PTS_DTS_flags, other flags=0
        pesView.setUint8(8, headerDataLength); // PES_header_data_length
        const pts = Math.round(queuedPacket.presentationTimestamp * mpeg_ts_misc/* TIMESCALE */.cS);
        ptsDtsBitstream.pos = 0;
        ptsDtsBitstream.writeBits(4, includeDts ? 0b0011 : 0b0010); // marker
        ptsDtsBitstream.writeBits(3, (pts >>> 30) & 0x7); // PTS[32:30]
        ptsDtsBitstream.writeBits(1, 1); // marker_bit
        ptsDtsBitstream.writeBits(15, (pts >>> 15) & 0x7FFF); // PTS[29:15]
        ptsDtsBitstream.writeBits(1, 1); // marker_bit
        ptsDtsBitstream.writeBits(15, pts & 0x7FFF); // PTS[14:0]
        ptsDtsBitstream.writeBits(1, 1); // marker_bit
        if (includeDts) {
            (0,misc/* assert */.vA)(queuedPacket.decodeTimestamp !== null);
            const dts = Math.round(queuedPacket.decodeTimestamp * mpeg_ts_misc/* TIMESCALE */.cS);
            ptsDtsBitstream.writeBits(4, 0b0001);
            ptsDtsBitstream.writeBits(3, (dts >>> 30) & 0x7); // DTS[32:30]
            ptsDtsBitstream.writeBits(1, 1); // marker_bit
            ptsDtsBitstream.writeBits(15, (dts >>> 15) & 0x7FFF); // DTS[29:15]
            ptsDtsBitstream.writeBits(1, 1); // marker_bit
            ptsDtsBitstream.writeBits(15, dts & 0x7FFF); // DTS[14:0]
            ptsDtsBitstream.writeBits(1, 1); // marker_bit
        }
        const totalLength = pesHeaderBuffer.length + queuedPacket.data.length;
        let offset = 0;
        let isFirstTsPacket = true;
        while (offset < totalLength) {
            const pusi = isFirstTsPacket;
            const remainingData = totalLength - offset;
            const randomAccessIndicator = isFirstTsPacket && queuedPacket.isKeyframe;
            const discontinuityIndicator = isFirstTsPacket && !trackData.firstPacketWritten;
            const basePaddingNeeded = Math.max(0, 184 - remainingData);
            let adaptationFieldSize;
            if (randomAccessIndicator || discontinuityIndicator) {
                // We need at least two bytes
                adaptationFieldSize = Math.max(2, basePaddingNeeded);
            }
            else {
                adaptationFieldSize = basePaddingNeeded;
            }
            let adaptationField = null;
            if (adaptationFieldSize > 0) {
                const buf = this.adaptationFieldBuffer;
                if (adaptationFieldSize === 1) {
                    buf[0] = 0; // adaptation_field_length
                }
                else {
                    buf[0] = adaptationFieldSize - 1; // adaptation_field_length
                    buf[1]
                        = (Number(discontinuityIndicator) << 7) // discontinuity_indicator
                            | (Number(randomAccessIndicator) << 6); // random_access_indicator
                    buf.fill(0xFF, 2, adaptationFieldSize); // stuffing_bytes
                }
                adaptationField = buf.subarray(0, adaptationFieldSize);
            }
            const payloadSize = Math.min(184 - adaptationFieldSize, remainingData);
            const payload = this.payloadBuffer.subarray(0, payloadSize);
            let payloadOffset = 0;
            if (offset < pesHeaderBuffer.length) {
                const headerBytes = Math.min(pesHeaderBuffer.length - offset, payloadSize);
                payload.set(pesHeaderBuffer.subarray(offset, offset + headerBytes), 0);
                payloadOffset = headerBytes;
            }
            const dataStart = Math.max(0, offset - pesHeaderBuffer.length);
            const dataEnd = dataStart + (payloadSize - payloadOffset);
            if (payloadOffset < payloadSize) {
                payload.set(queuedPacket.data.subarray(dataStart, dataEnd), payloadOffset);
            }
            this.writeTsPacket(trackData.pid, pusi, adaptationField, payload);
            offset += payloadSize;
            isFirstTsPacket = false;
        }
        trackData.firstPacketWritten = true;
    }
    writeTsPacket(pid, pusi, adaptationField, payload) {
        const cc = this.continuityCounters.get(pid) ?? 0;
        const hasPayload = payload.length > 0;
        const adaptCtrl = adaptationField
            ? (hasPayload ? 0b11 : 0b10)
            : (hasPayload ? 0b01 : 0b00);
        this.packetBuffer[0] = 0x47; // sync_byte
        this.packetView.setUint16(1, (pusi ? 0x4000 : 0) | (pid & 0x1FFF), false); // TEI=0, PUSI, priority=0, PID
        // scrambling=0, adaptation_field_control, continuity_counter
        this.packetBuffer[3] = (adaptCtrl << 4) | (cc & 0x0F);
        if (hasPayload) {
            this.continuityCounters.set(pid, (cc + 1) & 0x0F);
        }
        let offset = 4;
        if (adaptationField) {
            this.packetBuffer.set(adaptationField, offset);
            offset += adaptationField.length;
        }
        this.packetBuffer.set(payload, offset);
        offset += payload.length;
        if (offset < mpeg_ts_misc/* TS_PACKET_SIZE */.ZT) {
            this.packetBuffer.fill(0xFF, offset); // stuffing_bytes
        }
        const startPos = this.writer.getPos();
        this.writer.write(this.packetBuffer);
        if (this.format._options.onPacket) {
            this.format._options.onPacket(this.packetBuffer.slice(), startPos);
        }
    }
    // eslint-disable-next-line @typescript-eslint/no-misused-promises
    async onTrackClose(track) {
        const release = await this.mutex.acquire();
        if (this.allTracksAreKnown()) {
            this.allTracksKnown.resolve();
        }
        const trackData = this.trackDatas.find(x => x.track === track);
        if (trackData) {
            await this.flushTimestampQueue(trackData, false);
        }
        await this.interleavePackets();
        release();
    }
    async finalize() {
        const release = await this.mutex.acquire();
        this.allTracksKnown.resolve();
        for (const trackData of this.trackDatas) {
            await this.flushTimestampQueue(trackData, false);
        }
        await this.interleavePackets(true);
        release();
    }
}
// CRC-32 for MPEG-TS (polynomial 0x04C11DB7, initial value 0xFFFFFFFF)
const MPEG_TS_CRC_POLYNOMIAL = 0x04c11db7;
const MPEG_TS_CRC_TABLE = new Uint32Array(256);
for (let n = 0; n < 256; n++) {
    let crc = n << 24;
    for (let k = 0; k < 8; k++) {
        crc = (crc & 0x80000000)
            ? ((crc << 1) ^ MPEG_TS_CRC_POLYNOMIAL)
            : (crc << 1);
    }
    MPEG_TS_CRC_TABLE[n] = (crc >>> 0) & 0xffffffff;
}
const computeMpegTsCrc32 = (data) => {
    let crc = 0xFFFFFFFF;
    for (let i = 0; i < data.length; i++) {
        const byte = data[i];
        crc = ((crc << 8) ^ MPEG_TS_CRC_TABLE[(crc >>> 24) ^ byte]) >>> 0;
    }
    return crc;
};
const PAT_SECTION = new Uint8Array(16);
{
    const view = (0,misc/* toDataView */.Zc)(PAT_SECTION);
    PAT_SECTION[0] = 0x00; // table_id
    view.setUint16(1, 0xB00D, false); // section_syntax_indicator=1, '0', reserved=11, section_length=13
    view.setUint16(3, 0x0001, false); // transport_stream_id
    PAT_SECTION[5] = 0xC1; // reserved=11, version_number=0, current_next_indicator=1
    PAT_SECTION[6] = 0x00; // section_number
    PAT_SECTION[7] = 0x00; // last_section_number
    view.setUint16(8, 0x0001, false); // program_number
    view.setUint16(10, 0xE000 | (PMT_PID & 0x1FFF), false); // reserved=111, program_map_PID
    view.setUint32(12, computeMpegTsCrc32(PAT_SECTION.subarray(0, 12)), false); // CRC_32
}
const buildPmt = (trackDatas) => {
    let totalEsBytes = 0;
    for (const trackData of trackDatas) {
        totalEsBytes += 5;
        if (trackData.streamType === 129 /* MpegTsStreamType.AC3_SYSTEM_A */) {
            totalEsBytes += codec_data/* AC3_REGISTRATION_DESCRIPTOR */._b.length;
        }
        else if (trackData.streamType === 135 /* MpegTsStreamType.EAC3_SYSTEM_A */) {
            totalEsBytes += codec_data/* EAC3_REGISTRATION_DESCRIPTOR */.nV.length;
        }
    }
    const sectionLength = 9 + totalEsBytes + 4;
    const section = new Uint8Array(3 + sectionLength - 4);
    const view = (0,misc/* toDataView */.Zc)(section);
    section[0] = 0x02; // table_id
    // section_syntax_indicator=1, '0', reserved=11, section_length
    view.setUint16(1, 0xB000 | (sectionLength & 0x0FFF), false);
    view.setUint16(3, 0x0001, false); // program_number
    section[5] = 0xC1; // reserved=11, version_number=0, current_next_indicator=1
    section[6] = 0x00; // section_number
    section[7] = 0x00; // last_section_number
    view.setUint16(8, 0xE000 | 0x1FFF, false); // reserved=111, PCR_PID=0x1FFF (none)
    view.setUint16(10, 0xF000, false); // reserved=1111, program_info_length=0
    let offset = 12;
    for (const trackData of trackDatas) {
        section[offset++] = trackData.streamType; // stream_type
        view.setUint16(offset, 0xE000 | (trackData.pid & 0x1FFF), false); // reserved=111, elementary_PID
        offset += 2;
        if (trackData.streamType === 129 /* MpegTsStreamType.AC3_SYSTEM_A */) {
            view.setUint16(offset, 0xF000 | codec_data/* AC3_REGISTRATION_DESCRIPTOR */._b.length, false);
            offset += 2;
            section.set(codec_data/* AC3_REGISTRATION_DESCRIPTOR */._b, offset);
            offset += codec_data/* AC3_REGISTRATION_DESCRIPTOR */._b.length;
        }
        else if (trackData.streamType === 135 /* MpegTsStreamType.EAC3_SYSTEM_A */) {
            view.setUint16(offset, 0xF000 | codec_data/* EAC3_REGISTRATION_DESCRIPTOR */.nV.length, false);
            offset += 2;
            section.set(codec_data/* EAC3_REGISTRATION_DESCRIPTOR */.nV, offset);
            offset += codec_data/* EAC3_REGISTRATION_DESCRIPTOR */.nV.length;
        }
        else {
            view.setUint16(offset, 0xF000, false); // reserved=1111, ES_info_length=0
            offset += 2;
        }
    }
    const crc = computeMpegTsCrc32(section);
    const result = new Uint8Array(section.length + 4);
    result.set(section, 0);
    (0,misc/* toDataView */.Zc)(result).setUint32(section.length, crc, false); // CRC_32
    return result;
};

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/wave/wave-demuxer.js
var wave_demuxer = __webpack_require__(260);
;// ./node_modules/mediabunny/dist/modules/src/wave/riff-writer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */
class RiffWriter {
    constructor(writer) {
        this.writer = writer;
        this.helper = new Uint8Array(8);
        this.helperView = new DataView(this.helper.buffer);
    }
    writeU16(value) {
        this.helperView.setUint16(0, value, true);
        this.writer.write(this.helper.subarray(0, 2));
    }
    writeU32(value) {
        this.helperView.setUint32(0, value, true);
        this.writer.write(this.helper.subarray(0, 4));
    }
    writeU64(value) {
        this.helperView.setUint32(0, value, true);
        this.helperView.setUint32(4, Math.floor(value / 2 ** 32), true);
        this.writer.write(this.helper);
    }
    writeAscii(text) {
        this.writer.write(new TextEncoder().encode(text));
    }
}

;// ./node_modules/mediabunny/dist/modules/src/wave/wave-muxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */







class WaveMuxer extends Muxer {
    constructor(output, format) {
        super(output);
        this.headerWritten = false;
        this.dataSize = 0;
        this.sampleRate = null;
        this.sampleCount = 0;
        this.riffSizePos = null;
        this.dataSizePos = null;
        this.ds64RiffSizePos = null;
        this.ds64DataSizePos = null;
        this.ds64SampleCountPos = null;
        this.format = format;
        this.writer = output._writer;
        this.riffWriter = new RiffWriter(output._writer);
        this.isRf64 = !!format._options.large;
    }
    async start() {
        // Nothing needed here - we'll write the header with the first sample
    }
    async getMimeType() {
        return 'audio/wav';
    }
    async addEncodedVideoPacket() {
        throw new Error('WAVE does not support video.');
    }
    async addEncodedAudioPacket(track, packet, meta) {
        const release = await this.mutex.acquire();
        try {
            if (!this.headerWritten) {
                (0,src_codec/* validateAudioChunkMetadata */.P7)(meta);
                (0,misc/* assert */.vA)(meta);
                (0,misc/* assert */.vA)(meta.decoderConfig);
                this.writeHeader(track, meta.decoderConfig);
                this.sampleRate = meta.decoderConfig.sampleRate;
                this.headerWritten = true;
            }
            this.validateAndNormalizeTimestamp(track, packet.timestamp, packet.type === 'key');
            if (!this.isRf64 && this.writer.getPos() + packet.data.byteLength >= 2 ** 32) {
                throw new Error('Adding more audio data would exceed the maximum RIFF size of 4 GiB. To write larger files, use'
                    + ' RF64 by setting `large: true` in the WavOutputFormatOptions.');
            }
            this.writer.write(packet.data);
            this.dataSize += packet.data.byteLength;
            this.sampleCount += Math.round(packet.duration * this.sampleRate);
            await this.writer.flush();
        }
        finally {
            release();
        }
    }
    async addSubtitleCue() {
        throw new Error('WAVE does not support subtitles.');
    }
    writeHeader(track, config) {
        if (this.format._options.onHeader) {
            this.writer.startTrackingWrites();
        }
        let format;
        const codec = track.source._codec;
        const pcmInfo = (0,src_codec/* parsePcmCodec */.Ei)(codec);
        if (pcmInfo.dataType === 'ulaw') {
            format = wave_demuxer/* WaveFormat */.D.MULAW;
        }
        else if (pcmInfo.dataType === 'alaw') {
            format = wave_demuxer/* WaveFormat */.D.ALAW;
        }
        else if (pcmInfo.dataType === 'float') {
            format = wave_demuxer/* WaveFormat */.D.IEEE_FLOAT;
        }
        else {
            format = wave_demuxer/* WaveFormat */.D.PCM;
        }
        const channels = config.numberOfChannels;
        const sampleRate = config.sampleRate;
        const blockSize = pcmInfo.sampleSize * channels;
        // RIFF header
        this.riffWriter.writeAscii(this.isRf64 ? 'RF64' : 'RIFF');
        if (this.isRf64) {
            this.riffWriter.writeU32(0xffffffff); // Not used in RF64
        }
        else {
            this.riffSizePos = this.writer.getPos();
            this.riffWriter.writeU32(0); // File size placeholder
        }
        this.riffWriter.writeAscii('WAVE');
        if (this.isRf64) {
            this.riffWriter.writeAscii('ds64');
            this.riffWriter.writeU32(28); // Chunk size
            this.ds64RiffSizePos = this.writer.getPos();
            this.riffWriter.writeU64(0); // RIFF size placeholder
            this.ds64DataSizePos = this.writer.getPos();
            this.riffWriter.writeU64(0); // Data size placeholder
            this.ds64SampleCountPos = this.writer.getPos();
            this.riffWriter.writeU64(0); // Sample count placeholder
            this.riffWriter.writeU32(0); // Table length
            // Empty table
        }
        // fmt chunk
        this.riffWriter.writeAscii('fmt ');
        this.riffWriter.writeU32(16); // Chunk size
        this.riffWriter.writeU16(format);
        this.riffWriter.writeU16(channels);
        this.riffWriter.writeU32(sampleRate);
        this.riffWriter.writeU32(sampleRate * blockSize); // Bytes per second
        this.riffWriter.writeU16(blockSize);
        this.riffWriter.writeU16(8 * pcmInfo.sampleSize);
        // Metadata tags
        if (!(0,src_metadata/* metadataTagsAreEmpty */.cc)(this.output._metadataTags)) {
            const metadataFormat = this.format._options.metadataFormat ?? 'info';
            if (metadataFormat === 'info') {
                this.writeInfoChunk(this.output._metadataTags);
            }
            else if (metadataFormat === 'id3') {
                this.writeId3Chunk(this.output._metadataTags);
            }
            else {
                (0,misc/* assertNever */.xb)(metadataFormat);
            }
        }
        // data chunk
        this.riffWriter.writeAscii('data');
        if (this.isRf64) {
            this.riffWriter.writeU32(0xffffffff); // Not used in RF64
        }
        else {
            this.dataSizePos = this.writer.getPos();
            this.riffWriter.writeU32(0); // Data size placeholder
        }
        if (this.format._options.onHeader) {
            const { data, start } = this.writer.stopTrackingWrites();
            this.format._options.onHeader(data, start);
        }
    }
    writeInfoChunk(metadata) {
        const startPos = this.writer.getPos();
        this.riffWriter.writeAscii('LIST');
        this.riffWriter.writeU32(0); // Size placeholder
        this.riffWriter.writeAscii('INFO');
        const writtenTags = new Set();
        const writeInfoTag = (tag, value) => {
            if (!(0,misc/* isIso88591Compatible */.H9)(value)) {
                // No Unicode supported here
                console.warn(`Didn't write tag '${tag}' because '${value}' is not ISO 8859-1-compatible.`);
                return;
            }
            const size = value.length + 1; // +1 for null terminator
            const bytes = new Uint8Array(size);
            for (let i = 0; i < value.length; i++) {
                bytes[i] = value.charCodeAt(i);
            }
            this.riffWriter.writeAscii(tag);
            this.riffWriter.writeU32(size);
            this.writer.write(bytes);
            // Add padding byte if size is odd
            if (size & 1) {
                this.writer.write(new Uint8Array(1));
            }
            writtenTags.add(tag);
        };
        for (const { key, value } of (0,misc/* keyValueIterator */.rk)(metadata)) {
            switch (key) {
                case 'title':
                    {
                        writeInfoTag('INAM', value);
                        writtenTags.add('INAM');
                    }
                    ;
                    break;
                case 'artist':
                    {
                        writeInfoTag('IART', value);
                        writtenTags.add('IART');
                    }
                    ;
                    break;
                case 'album':
                    {
                        writeInfoTag('IPRD', value);
                        writtenTags.add('IPRD');
                    }
                    ;
                    break;
                case 'trackNumber':
                    {
                        const string = metadata.tracksTotal !== undefined
                            ? `${value}/${metadata.tracksTotal}`
                            : value.toString();
                        writeInfoTag('ITRK', string);
                        writtenTags.add('ITRK');
                    }
                    ;
                    break;
                case 'genre':
                    {
                        writeInfoTag('IGNR', value);
                        writtenTags.add('IGNR');
                    }
                    ;
                    break;
                case 'date':
                    {
                        writeInfoTag('ICRD', value.toISOString().slice(0, 10));
                        writtenTags.add('ICRD');
                    }
                    ;
                    break;
                case 'comment':
                    {
                        writeInfoTag('ICMT', value);
                        writtenTags.add('ICMT');
                    }
                    ;
                    break;
                case 'albumArtist':
                case 'discNumber':
                case 'tracksTotal':
                case 'discsTotal':
                case 'description':
                case 'lyrics':
                case 'images':
                    {
                        // Not supported in RIFF INFO
                    }
                    ;
                    break;
                case 'raw':
                    {
                        // Handled later
                    }
                    ;
                    break;
                default: (0,misc/* assertNever */.xb)(key);
            }
        }
        if (metadata.raw) {
            for (const key in metadata.raw) {
                const value = metadata.raw[key];
                if (value == null || key.length !== 4 || writtenTags.has(key)) {
                    continue;
                }
                if (typeof value === 'string') {
                    writeInfoTag(key, value);
                }
            }
        }
        const endPos = this.writer.getPos();
        const chunkSize = endPos - startPos - 8;
        this.writer.seek(startPos + 4);
        this.riffWriter.writeU32(chunkSize);
        this.writer.seek(endPos);
        // Add padding byte if chunk size is odd
        if (chunkSize & 1) {
            this.writer.write(new Uint8Array(1));
        }
    }
    writeId3Chunk(metadata) {
        const startPos = this.writer.getPos();
        // Write RIFF chunk header
        this.riffWriter.writeAscii('ID3 ');
        this.riffWriter.writeU32(0); // Size placeholder
        const id3Writer = new id3/* Id3V2Writer */.Ov(this.writer);
        const id3TagSize = id3Writer.writeId3V2Tag(metadata);
        const endPos = this.writer.getPos();
        // Update RIFF chunk size
        this.writer.seek(startPos + 4);
        this.riffWriter.writeU32(id3TagSize);
        this.writer.seek(endPos);
        // Add padding byte if chunk size is odd
        if (id3TagSize & 1) {
            this.writer.write(new Uint8Array(1));
        }
    }
    async finalize() {
        const release = await this.mutex.acquire();
        const endPos = this.writer.getPos();
        if (this.isRf64) {
            // Write riff size
            (0,misc/* assert */.vA)(this.ds64RiffSizePos !== null);
            this.writer.seek(this.ds64RiffSizePos);
            this.riffWriter.writeU64(endPos - 8);
            // Write data size
            (0,misc/* assert */.vA)(this.ds64DataSizePos !== null);
            this.writer.seek(this.ds64DataSizePos);
            this.riffWriter.writeU64(this.dataSize);
            // Write sample count
            (0,misc/* assert */.vA)(this.ds64SampleCountPos !== null);
            this.writer.seek(this.ds64SampleCountPos);
            this.riffWriter.writeU64(this.sampleCount);
        }
        else {
            // Write file size
            (0,misc/* assert */.vA)(this.riffSizePos !== null);
            this.writer.seek(this.riffSizePos);
            this.riffWriter.writeU32(endPos - 8);
            // Write data chunk size
            (0,misc/* assert */.vA)(this.dataSizePos !== null);
            this.writer.seek(this.dataSizePos);
            this.riffWriter.writeU32(this.dataSize);
        }
        this.writer.seek(endPos);
        release();
    }
}

;// ./node_modules/mediabunny/dist/modules/src/output-format.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */









/**
 * Base class representing an output media file format.
 * @group Output formats
 * @public
 */
class OutputFormat {
    /** Returns a list of video codecs that this output format can contain. */
    getSupportedVideoCodecs() {
        return this.getSupportedCodecs()
            .filter(codec => src_codec/* VIDEO_CODECS */.WN.includes(codec));
    }
    /** Returns a list of audio codecs that this output format can contain. */
    getSupportedAudioCodecs() {
        return this.getSupportedCodecs()
            .filter(codec => src_codec/* AUDIO_CODECS */.PP.includes(codec));
    }
    /** Returns a list of subtitle codecs that this output format can contain. */
    getSupportedSubtitleCodecs() {
        return this.getSupportedCodecs()
            .filter(codec => src_codec/* SUBTITLE_CODECS */.VW.includes(codec));
    }
    /** @internal */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    _codecUnsupportedHint(codec) {
        return '';
    }
}
/**
 * Format representing files compatible with the ISO base media file format (ISOBMFF), like MP4 or MOV files.
 * @group Output formats
 * @public
 */
class IsobmffOutputFormat extends OutputFormat {
    /** Internal constructor. */
    constructor(options = {}) {
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (options.fastStart !== undefined
            && ![false, 'in-memory', 'reserve', 'fragmented'].includes(options.fastStart)) {
            throw new TypeError('options.fastStart, when provided, must be false, \'in-memory\', \'reserve\', or \'fragmented\'.');
        }
        if (options.minimumFragmentDuration !== undefined
            && (!Number.isFinite(options.minimumFragmentDuration) || options.minimumFragmentDuration < 0)) {
            throw new TypeError('options.minimumFragmentDuration, when provided, must be a non-negative number.');
        }
        if (options.onFtyp !== undefined && typeof options.onFtyp !== 'function') {
            throw new TypeError('options.onFtyp, when provided, must be a function.');
        }
        if (options.onMoov !== undefined && typeof options.onMoov !== 'function') {
            throw new TypeError('options.onMoov, when provided, must be a function.');
        }
        if (options.onMdat !== undefined && typeof options.onMdat !== 'function') {
            throw new TypeError('options.onMdat, when provided, must be a function.');
        }
        if (options.onMoof !== undefined && typeof options.onMoof !== 'function') {
            throw new TypeError('options.onMoof, when provided, must be a function.');
        }
        if (options.metadataFormat !== undefined
            && !['mdir', 'mdta', 'udta', 'auto'].includes(options.metadataFormat)) {
            throw new TypeError('options.metadataFormat, when provided, must be either \'auto\', \'mdir\', \'mdta\', or \'udta\'.');
        }
        super();
        this._options = options;
    }
    getSupportedTrackCounts() {
        const max = 2 ** 32 - 1; // Have fun reaching this one
        return {
            video: { min: 0, max },
            audio: { min: 0, max },
            subtitle: { min: 0, max },
            total: { min: 1, max },
        };
    }
    get supportsVideoRotationMetadata() {
        return true;
    }
    get supportsTimestampedMediaData() {
        return true;
    }
    /** @internal */
    _createMuxer(output) {
        return new IsobmffMuxer(output, this);
    }
}
/**
 * MPEG-4 Part 14 (MP4) file format. Supports most codecs.
 * @group Output formats
 * @public
 */
class Mp4OutputFormat extends IsobmffOutputFormat {
    /** Creates a new {@link Mp4OutputFormat} configured with the specified `options`. */
    constructor(options) {
        super(options);
    }
    /** @internal */
    get _name() {
        return 'MP4';
    }
    get fileExtension() {
        return '.mp4';
    }
    get mimeType() {
        return 'video/mp4';
    }
    getSupportedCodecs() {
        return [
            ...src_codec/* VIDEO_CODECS */.WN,
            ...src_codec/* NON_PCM_AUDIO_CODECS */.YB,
            // These are supported via ISO/IEC 23003-5:
            'pcm-s16',
            'pcm-s16be',
            'pcm-s24',
            'pcm-s24be',
            'pcm-s32',
            'pcm-s32be',
            'pcm-f32',
            'pcm-f32be',
            'pcm-f64',
            'pcm-f64be',
            ...src_codec/* SUBTITLE_CODECS */.VW,
        ];
    }
    /** @internal */
    _codecUnsupportedHint(codec) {
        if (new MovOutputFormat().getSupportedCodecs().includes(codec)) {
            return ' Switching to MOV will grant support for this codec.';
        }
        return '';
    }
}
/**
 * QuickTime File Format (QTFF), often called MOV. Supports all video and audio codecs, but not subtitle codecs.
 * @group Output formats
 * @public
 */
class MovOutputFormat extends IsobmffOutputFormat {
    /** Creates a new {@link MovOutputFormat} configured with the specified `options`. */
    constructor(options) {
        super(options);
    }
    /** @internal */
    get _name() {
        return 'MOV';
    }
    get fileExtension() {
        return '.mov';
    }
    get mimeType() {
        return 'video/quicktime';
    }
    getSupportedCodecs() {
        return [
            ...src_codec/* VIDEO_CODECS */.WN,
            ...src_codec/* AUDIO_CODECS */.PP,
        ];
    }
    /** @internal */
    _codecUnsupportedHint(codec) {
        if (new Mp4OutputFormat().getSupportedCodecs().includes(codec)) {
            return ' Switching to MP4 will grant support for this codec.';
        }
        return '';
    }
}
/**
 * Matroska file format.
 *
 * Supports writing transparent video. For a video track to be marked as transparent, the first packet added must
 * contain alpha side data.
 *
 * @group Output formats
 * @public
 */
class MkvOutputFormat extends OutputFormat {
    /** Creates a new {@link MkvOutputFormat} configured with the specified `options`. */
    constructor(options = {}) {
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (options.appendOnly !== undefined && typeof options.appendOnly !== 'boolean') {
            throw new TypeError('options.appendOnly, when provided, must be a boolean.');
        }
        if (options.minimumClusterDuration !== undefined
            && (!Number.isFinite(options.minimumClusterDuration) || options.minimumClusterDuration < 0)) {
            throw new TypeError('options.minimumClusterDuration, when provided, must be a non-negative number.');
        }
        if (options.onEbmlHeader !== undefined && typeof options.onEbmlHeader !== 'function') {
            throw new TypeError('options.onEbmlHeader, when provided, must be a function.');
        }
        if (options.onSegmentHeader !== undefined && typeof options.onSegmentHeader !== 'function') {
            throw new TypeError('options.onHeader, when provided, must be a function.');
        }
        if (options.onCluster !== undefined && typeof options.onCluster !== 'function') {
            throw new TypeError('options.onCluster, when provided, must be a function.');
        }
        super();
        this._options = options;
    }
    /** @internal */
    _createMuxer(output) {
        return new MatroskaMuxer(output, this);
    }
    /** @internal */
    get _name() {
        return 'Matroska';
    }
    getSupportedTrackCounts() {
        const max = 127;
        return {
            video: { min: 0, max },
            audio: { min: 0, max },
            subtitle: { min: 0, max },
            total: { min: 1, max },
        };
    }
    get fileExtension() {
        return '.mkv';
    }
    get mimeType() {
        return 'video/x-matroska';
    }
    getSupportedCodecs() {
        return [
            ...src_codec/* VIDEO_CODECS */.WN,
            ...src_codec/* NON_PCM_AUDIO_CODECS */.YB,
            ...src_codec/* PCM_AUDIO_CODECS */.Wq.filter(codec => !['pcm-s8', 'pcm-f32be', 'pcm-f64be', 'ulaw', 'alaw'].includes(codec)),
            ...src_codec/* SUBTITLE_CODECS */.VW,
        ];
    }
    get supportsVideoRotationMetadata() {
        // While it technically does support it with ProjectionPoseRoll, many players appear to ignore this value
        return false;
    }
    get supportsTimestampedMediaData() {
        return true;
    }
}
/**
 * WebM file format, based on Matroska.
 *
 * Supports writing transparent video. For a video track to be marked as transparent, the first packet added must
 * contain alpha side data.
 *
 * @group Output formats
 * @public
 */
class WebMOutputFormat extends MkvOutputFormat {
    /** Creates a new {@link WebMOutputFormat} configured with the specified `options`. */
    constructor(options) {
        super(options);
    }
    getSupportedCodecs() {
        return [
            ...src_codec/* VIDEO_CODECS */.WN.filter(codec => ['vp8', 'vp9', 'av1'].includes(codec)),
            ...src_codec/* AUDIO_CODECS */.PP.filter(codec => ['opus', 'vorbis'].includes(codec)),
            ...src_codec/* SUBTITLE_CODECS */.VW,
        ];
    }
    /** @internal */
    get _name() {
        return 'WebM';
    }
    get fileExtension() {
        return '.webm';
    }
    get mimeType() {
        return 'video/webm';
    }
    /** @internal */
    _codecUnsupportedHint(codec) {
        if (new MkvOutputFormat().getSupportedCodecs().includes(codec)) {
            return ' Switching to MKV will grant support for this codec.';
        }
        return '';
    }
}
/**
 * MP3 file format.
 * @group Output formats
 * @public
 */
class Mp3OutputFormat extends OutputFormat {
    /** Creates a new {@link Mp3OutputFormat} configured with the specified `options`. */
    constructor(options = {}) {
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (options.xingHeader !== undefined && typeof options.xingHeader !== 'boolean') {
            throw new TypeError('options.xingHeader, when provided, must be a boolean.');
        }
        if (options.onXingFrame !== undefined && typeof options.onXingFrame !== 'function') {
            throw new TypeError('options.onXingFrame, when provided, must be a function.');
        }
        super();
        this._options = options;
    }
    /** @internal */
    _createMuxer(output) {
        return new Mp3Muxer(output, this);
    }
    /** @internal */
    get _name() {
        return 'MP3';
    }
    getSupportedTrackCounts() {
        return {
            video: { min: 0, max: 0 },
            audio: { min: 1, max: 1 },
            subtitle: { min: 0, max: 0 },
            total: { min: 1, max: 1 },
        };
    }
    get fileExtension() {
        return '.mp3';
    }
    get mimeType() {
        return 'audio/mpeg';
    }
    getSupportedCodecs() {
        return ['mp3'];
    }
    get supportsVideoRotationMetadata() {
        return false;
    }
    get supportsTimestampedMediaData() {
        return false;
    }
}
/**
 * WAVE file format, based on RIFF.
 * @group Output formats
 * @public
 */
class WavOutputFormat extends OutputFormat {
    /** Creates a new {@link WavOutputFormat} configured with the specified `options`. */
    constructor(options = {}) {
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (options.large !== undefined && typeof options.large !== 'boolean') {
            throw new TypeError('options.large, when provided, must be a boolean.');
        }
        if (options.metadataFormat !== undefined && !['info', 'id3'].includes(options.metadataFormat)) {
            throw new TypeError('options.metadataFormat, when provided, must be either \'info\' or \'id3\'.');
        }
        if (options.onHeader !== undefined && typeof options.onHeader !== 'function') {
            throw new TypeError('options.onHeader, when provided, must be a function.');
        }
        super();
        this._options = options;
    }
    /** @internal */
    _createMuxer(output) {
        return new WaveMuxer(output, this);
    }
    /** @internal */
    get _name() {
        return 'WAVE';
    }
    getSupportedTrackCounts() {
        return {
            video: { min: 0, max: 0 },
            audio: { min: 1, max: 1 },
            subtitle: { min: 0, max: 0 },
            total: { min: 1, max: 1 },
        };
    }
    get fileExtension() {
        return '.wav';
    }
    get mimeType() {
        return 'audio/wav';
    }
    getSupportedCodecs() {
        return [
            ...src_codec/* PCM_AUDIO_CODECS */.Wq.filter(codec => ['pcm-s16', 'pcm-s24', 'pcm-s32', 'pcm-f32', 'pcm-u8', 'ulaw', 'alaw'].includes(codec)),
        ];
    }
    get supportsVideoRotationMetadata() {
        return false;
    }
    get supportsTimestampedMediaData() {
        return false;
    }
}
/**
 * Ogg file format.
 * @group Output formats
 * @public
 */
class OggOutputFormat extends OutputFormat {
    /** Creates a new {@link OggOutputFormat} configured with the specified `options`. */
    constructor(options = {}) {
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (options.maximumPageDuration !== undefined
            && (!Number.isFinite(options.maximumPageDuration) || options.maximumPageDuration <= 0)) {
            throw new TypeError('options.maximumPageDuration, when provided, must be a positive number.');
        }
        if (options.onPage !== undefined && typeof options.onPage !== 'function') {
            throw new TypeError('options.onPage, when provided, must be a function.');
        }
        super();
        this._options = options;
    }
    /** @internal */
    _createMuxer(output) {
        return new OggMuxer(output, this);
    }
    /** @internal */
    get _name() {
        return 'Ogg';
    }
    getSupportedTrackCounts() {
        const max = 2 ** 32; // Have fun reaching this one
        return {
            video: { min: 0, max: 0 },
            audio: { min: 0, max },
            subtitle: { min: 0, max: 0 },
            total: { min: 1, max },
        };
    }
    get fileExtension() {
        return '.ogg';
    }
    get mimeType() {
        return 'application/ogg';
    }
    getSupportedCodecs() {
        return [
            ...src_codec/* AUDIO_CODECS */.PP.filter(codec => ['vorbis', 'opus'].includes(codec)),
        ];
    }
    get supportsVideoRotationMetadata() {
        return false;
    }
    get supportsTimestampedMediaData() {
        return false;
    }
}
/**
 * ADTS file format.
 * @group Output formats
 * @public
 */
class AdtsOutputFormat extends OutputFormat {
    /** Creates a new {@link AdtsOutputFormat} configured with the specified `options`. */
    constructor(options = {}) {
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (options.onFrame !== undefined && typeof options.onFrame !== 'function') {
            throw new TypeError('options.onFrame, when provided, must be a function.');
        }
        super();
        this._options = options;
    }
    /** @internal */
    _createMuxer(output) {
        return new AdtsMuxer(output, this);
    }
    /** @internal */
    get _name() {
        return 'ADTS';
    }
    getSupportedTrackCounts() {
        return {
            video: { min: 0, max: 0 },
            audio: { min: 1, max: 1 },
            subtitle: { min: 0, max: 0 },
            total: { min: 1, max: 1 },
        };
    }
    get fileExtension() {
        return '.aac';
    }
    get mimeType() {
        return 'audio/aac';
    }
    getSupportedCodecs() {
        return ['aac'];
    }
    get supportsVideoRotationMetadata() {
        return false;
    }
    get supportsTimestampedMediaData() {
        return false;
    }
}
/**
 * FLAC file format.
 * @group Output formats
 * @public
 */
class FlacOutputFormat extends OutputFormat {
    /** Creates a new {@link FlacOutputFormat} configured with the specified `options`. */
    constructor(options = {}) {
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        super();
        this._options = options;
    }
    /** @internal */
    _createMuxer(output) {
        return new FlacMuxer(output, this);
    }
    /** @internal */
    get _name() {
        return 'FLAC';
    }
    getSupportedTrackCounts() {
        return {
            video: { min: 0, max: 0 },
            audio: { min: 1, max: 1 },
            subtitle: { min: 0, max: 0 },
            total: { min: 1, max: 1 },
        };
    }
    get fileExtension() {
        return '.flac';
    }
    get mimeType() {
        return 'audio/flac';
    }
    getSupportedCodecs() {
        return ['flac'];
    }
    get supportsVideoRotationMetadata() {
        return false;
    }
    get supportsTimestampedMediaData() {
        return false;
    }
}
/**
 * MPEG Transport Stream file format.
 * @group Output formats
 * @public
 */
class MpegTsOutputFormat extends OutputFormat {
    /** Creates a new {@link MpegTsOutputFormat} configured with the specified `options`. */
    constructor(options = {}) {
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (options.onPacket !== undefined && typeof options.onPacket !== 'function') {
            throw new TypeError('options.onPacket, when provided, must be a function.');
        }
        super();
        this._options = options;
    }
    /** @internal */
    _createMuxer(output) {
        return new MpegTsMuxer(output, this);
    }
    /** @internal */
    get _name() {
        return 'MPEG-TS';
    }
    getSupportedTrackCounts() {
        const maxVideo = 16; // Stream IDs 0xE0-0xEF
        const maxAudio = 32;
        const maxTotal = maxVideo + maxAudio;
        return {
            video: { min: 0, max: maxVideo },
            audio: { min: 0, max: maxAudio },
            subtitle: { min: 0, max: 0 },
            total: { min: 1, max: maxTotal },
        };
    }
    get fileExtension() {
        return '.ts';
    }
    get mimeType() {
        return 'video/MP2T';
    }
    getSupportedCodecs() {
        return [
            ...src_codec/* VIDEO_CODECS */.WN.filter(codec => ['avc', 'hevc'].includes(codec)),
            ...src_codec/* AUDIO_CODECS */.PP.filter(codec => ['aac', 'mp3', 'ac3', 'eac3'].includes(codec)),
        ];
    }
    get supportsVideoRotationMetadata() {
        return false;
    }
    get supportsTimestampedMediaData() {
        return true;
    }
}

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/custom-coder.js
var custom_coder = __webpack_require__(8647);
;// ./node_modules/mediabunny/dist/modules/src/encode.js
/* unused harmony import specifier */ var VIDEO_CODECS;
/* unused harmony import specifier */ var AUDIO_CODECS;
/* unused harmony import specifier */ var SUBTITLE_CODECS;
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */



const validateVideoEncodingConfig = (config) => {
    if (!config || typeof config !== 'object') {
        throw new TypeError('Encoding config must be an object.');
    }
    if (!src_codec/* VIDEO_CODECS */.WN.includes(config.codec)) {
        throw new TypeError(`Invalid video codec '${config.codec}'. Must be one of: ${src_codec/* VIDEO_CODECS */.WN.join(', ')}.`);
    }
    if (!(config.bitrate instanceof Quality) && (!Number.isInteger(config.bitrate) || config.bitrate <= 0)) {
        throw new TypeError('config.bitrate must be a positive integer or a quality.');
    }
    if (config.keyFrameInterval !== undefined
        && (!Number.isFinite(config.keyFrameInterval) || config.keyFrameInterval < 0)) {
        throw new TypeError('config.keyFrameInterval, when provided, must be a non-negative number.');
    }
    if (config.sizeChangeBehavior !== undefined
        && !['deny', 'passThrough', 'fill', 'contain', 'cover'].includes(config.sizeChangeBehavior)) {
        throw new TypeError('config.sizeChangeBehavior, when provided, must be \'deny\', \'passThrough\', \'fill\', \'contain\''
            + ' or \'cover\'.');
    }
    if (config.onEncodedPacket !== undefined && typeof config.onEncodedPacket !== 'function') {
        throw new TypeError('config.onEncodedChunk, when provided, must be a function.');
    }
    if (config.onEncoderConfig !== undefined && typeof config.onEncoderConfig !== 'function') {
        throw new TypeError('config.onEncoderConfig, when provided, must be a function.');
    }
    validateVideoEncodingAdditionalOptions(config.codec, config);
};
const validateVideoEncodingAdditionalOptions = (codec, options) => {
    if (!options || typeof options !== 'object') {
        throw new TypeError('Encoding options must be an object.');
    }
    if (options.alpha !== undefined && !['discard', 'keep'].includes(options.alpha)) {
        throw new TypeError('options.alpha, when provided, must be \'discard\' or \'keep\'.');
    }
    if (options.bitrateMode !== undefined && !['constant', 'variable'].includes(options.bitrateMode)) {
        throw new TypeError('bitrateMode, when provided, must be \'constant\' or \'variable\'.');
    }
    if (options.latencyMode !== undefined && !['quality', 'realtime'].includes(options.latencyMode)) {
        throw new TypeError('latencyMode, when provided, must be \'quality\' or \'realtime\'.');
    }
    if (options.fullCodecString !== undefined && typeof options.fullCodecString !== 'string') {
        throw new TypeError('fullCodecString, when provided, must be a string.');
    }
    if (options.fullCodecString !== undefined && (0,src_codec/* inferCodecFromCodecString */.oU)(options.fullCodecString) !== codec) {
        throw new TypeError(`fullCodecString, when provided, must be a string that matches the specified codec (${codec}).`);
    }
    if (options.hardwareAcceleration !== undefined
        && !['no-preference', 'prefer-hardware', 'prefer-software'].includes(options.hardwareAcceleration)) {
        throw new TypeError('hardwareAcceleration, when provided, must be \'no-preference\', \'prefer-hardware\' or'
            + ' \'prefer-software\'.');
    }
    if (options.scalabilityMode !== undefined && typeof options.scalabilityMode !== 'string') {
        throw new TypeError('scalabilityMode, when provided, must be a string.');
    }
    if (options.contentHint !== undefined && typeof options.contentHint !== 'string') {
        throw new TypeError('contentHint, when provided, must be a string.');
    }
};
const buildVideoEncoderConfig = (options) => {
    const resolvedBitrate = options.bitrate instanceof Quality
        ? options.bitrate._toVideoBitrate(options.codec, options.width, options.height)
        : options.bitrate;
    return {
        codec: options.fullCodecString ?? (0,src_codec/* buildVideoCodecString */.j7)(options.codec, options.width, options.height, resolvedBitrate),
        width: options.width,
        height: options.height,
        bitrate: resolvedBitrate,
        bitrateMode: options.bitrateMode,
        alpha: options.alpha ?? 'discard',
        framerate: options.framerate,
        latencyMode: options.latencyMode,
        hardwareAcceleration: options.hardwareAcceleration,
        scalabilityMode: options.scalabilityMode,
        contentHint: options.contentHint,
        ...(0,src_codec/* getVideoEncoderConfigExtension */.Rc)(options.codec),
    };
};
const validateAudioEncodingConfig = (config) => {
    if (!config || typeof config !== 'object') {
        throw new TypeError('Encoding config must be an object.');
    }
    if (!src_codec/* AUDIO_CODECS */.PP.includes(config.codec)) {
        throw new TypeError(`Invalid audio codec '${config.codec}'. Must be one of: ${src_codec/* AUDIO_CODECS */.PP.join(', ')}.`);
    }
    if (config.bitrate === undefined
        && (!src_codec/* PCM_AUDIO_CODECS */.Wq.includes(config.codec) || config.codec === 'flac')) {
        throw new TypeError('config.bitrate must be provided for compressed audio codecs.');
    }
    if (config.bitrate !== undefined
        && !(config.bitrate instanceof Quality)
        && (!Number.isInteger(config.bitrate) || config.bitrate <= 0)) {
        throw new TypeError('config.bitrate, when provided, must be a positive integer or a quality.');
    }
    if (config.onEncodedPacket !== undefined && typeof config.onEncodedPacket !== 'function') {
        throw new TypeError('config.onEncodedChunk, when provided, must be a function.');
    }
    if (config.onEncoderConfig !== undefined && typeof config.onEncoderConfig !== 'function') {
        throw new TypeError('config.onEncoderConfig, when provided, must be a function.');
    }
    validateAudioEncodingAdditionalOptions(config.codec, config);
};
const validateAudioEncodingAdditionalOptions = (codec, options) => {
    if (!options || typeof options !== 'object') {
        throw new TypeError('Encoding options must be an object.');
    }
    if (options.bitrateMode !== undefined && !['constant', 'variable'].includes(options.bitrateMode)) {
        throw new TypeError('bitrateMode, when provided, must be \'constant\' or \'variable\'.');
    }
    if (options.fullCodecString !== undefined && typeof options.fullCodecString !== 'string') {
        throw new TypeError('fullCodecString, when provided, must be a string.');
    }
    if (options.fullCodecString !== undefined && (0,src_codec/* inferCodecFromCodecString */.oU)(options.fullCodecString) !== codec) {
        throw new TypeError(`fullCodecString, when provided, must be a string that matches the specified codec (${codec}).`);
    }
};
const buildAudioEncoderConfig = (options) => {
    const resolvedBitrate = options.bitrate instanceof Quality
        ? options.bitrate._toAudioBitrate(options.codec)
        : options.bitrate;
    return {
        codec: options.fullCodecString ?? (0,src_codec/* buildAudioCodecString */.KZ)(options.codec, options.numberOfChannels, options.sampleRate),
        numberOfChannels: options.numberOfChannels,
        sampleRate: options.sampleRate,
        bitrate: resolvedBitrate,
        bitrateMode: options.bitrateMode,
        ...(0,src_codec/* getAudioEncoderConfigExtension */.IJ)(options.codec),
    };
};
/**
 * Represents a subjective media quality level.
 * @group Encoding
 * @public
 */
class Quality {
    /** @internal */
    constructor(factor) {
        this._factor = factor;
    }
    /** @internal */
    _toVideoBitrate(codec, width, height) {
        const pixels = width * height;
        const codecEfficiencyFactors = {
            avc: 1.0, // H.264/AVC (baseline)
            hevc: 0.6, // H.265/HEVC (~40% more efficient than AVC)
            vp9: 0.6, // Similar to HEVC
            av1: 0.4, // ~60% more efficient than AVC
            vp8: 1.2, // Slightly less efficient than AVC
        };
        const referencePixels = 1920 * 1080;
        const referenceBitrate = 3000000;
        const scaleFactor = Math.pow(pixels / referencePixels, 0.95); // Slight non-linear scaling
        const baseBitrate = referenceBitrate * scaleFactor;
        const codecAdjustedBitrate = baseBitrate * codecEfficiencyFactors[codec];
        const finalBitrate = codecAdjustedBitrate * this._factor;
        return Math.ceil(finalBitrate / 1000) * 1000;
    }
    /** @internal */
    _toAudioBitrate(codec) {
        if (src_codec/* PCM_AUDIO_CODECS */.Wq.includes(codec) || codec === 'flac') {
            return undefined;
        }
        const baseRates = {
            aac: 128000, // 128kbps base for AAC
            opus: 64000, // 64kbps base for Opus
            mp3: 160000, // 160kbps base for MP3
            vorbis: 64000, // 64kbps base for Vorbis
            ac3: 384000, // 384kbps base for AC-3
            eac3: 192000, // 192kbps base for E-AC-3
        };
        const baseBitrate = baseRates[codec];
        if (!baseBitrate) {
            throw new Error(`Unhandled codec: ${codec}`);
        }
        let finalBitrate = baseBitrate * this._factor;
        if (codec === 'aac') {
            // AAC only works with specific bitrates, let's find the closest
            const validRates = [96000, 128000, 160000, 192000];
            finalBitrate = validRates.reduce((prev, curr) => Math.abs(curr - finalBitrate) < Math.abs(prev - finalBitrate) ? curr : prev);
        }
        else if (codec === 'opus' || codec === 'vorbis') {
            finalBitrate = Math.max(6000, finalBitrate);
        }
        else if (codec === 'mp3') {
            const validRates = [
                8000, 16000, 24000, 32000, 40000, 48000, 64000, 80000,
                96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000,
            ];
            finalBitrate = validRates.reduce((prev, curr) => Math.abs(curr - finalBitrate) < Math.abs(prev - finalBitrate) ? curr : prev);
        }
        return Math.round(finalBitrate / 1000) * 1000;
    }
}
/**
 * Represents a very low media quality.
 * @group Encoding
 * @public
 */
const QUALITY_VERY_LOW = /* #__PURE__ */ new Quality(0.3);
/**
 * Represents a low media quality.
 * @group Encoding
 * @public
 */
const QUALITY_LOW = /* #__PURE__ */ new Quality(0.6);
/**
 * Represents a medium media quality.
 * @group Encoding
 * @public
 */
const QUALITY_MEDIUM = /* #__PURE__ */ new Quality(1);
/**
 * Represents a high media quality.
 * @group Encoding
 * @public
 */
const QUALITY_HIGH = /* #__PURE__ */ new Quality(2);
/**
 * Represents a very high media quality.
 * @group Encoding
 * @public
 */
const QUALITY_VERY_HIGH = /* #__PURE__ */ new Quality(4);
/**
 * Checks if the browser is able to encode the given codec.
 * @group Encoding
 * @public
 */
const canEncode = (codec) => {
    if (VIDEO_CODECS.includes(codec)) {
        return canEncodeVideo(codec);
    }
    else if (AUDIO_CODECS.includes(codec)) {
        return canEncodeAudio(codec);
    }
    else if (SUBTITLE_CODECS.includes(codec)) {
        return canEncodeSubtitles(codec);
    }
    throw new TypeError(`Unknown codec '${codec}'.`);
};
/**
 * Checks if the browser is able to encode the given video codec with the given parameters.
 * @group Encoding
 * @public
 */
const canEncodeVideo = async (codec, options = {}) => {
    const { width = 1280, height = 720, bitrate = 1e6, ...restOptions } = options;
    if (!src_codec/* VIDEO_CODECS */.WN.includes(codec)) {
        return false;
    }
    if (!Number.isInteger(width) || width <= 0) {
        throw new TypeError('width must be a positive integer.');
    }
    if (!Number.isInteger(height) || height <= 0) {
        throw new TypeError('height must be a positive integer.');
    }
    if (!(bitrate instanceof Quality) && (!Number.isInteger(bitrate) || bitrate <= 0)) {
        throw new TypeError('bitrate must be a positive integer or a quality.');
    }
    validateVideoEncodingAdditionalOptions(codec, restOptions);
    let encoderConfig = null;
    if (custom_coder/* customVideoEncoders */.WE.length > 0) {
        encoderConfig ??= buildVideoEncoderConfig({
            codec,
            width,
            height,
            bitrate,
            framerate: undefined,
            ...restOptions,
        });
        if (custom_coder/* customVideoEncoders */.WE.some(x => x.supports(codec, encoderConfig))) {
            // There's a custom encoder
            return true;
        }
    }
    if (typeof VideoEncoder === 'undefined') {
        return false;
    }
    const hasOddDimension = width % 2 === 1 || height % 2 === 1;
    if (hasOddDimension
        && (codec === 'avc' || codec === 'hevc')) {
        // Disallow odd dimensions for certain codecs
        return false;
    }
    encoderConfig ??= buildVideoEncoderConfig({
        codec,
        width,
        height,
        bitrate,
        framerate: undefined,
        ...restOptions,
        alpha: 'discard', // Since we handle alpha ourselves
    });
    const support = await VideoEncoder.isConfigSupported(encoderConfig);
    if (!support.supported) {
        return false;
    }
    if ((0,misc/* isFirefox */.gm)()) {
        // isConfigSupported on Firefox appears to unreliably indicate if encoding will actually succeed. Therefore, we
        // just try encoding a frame to see if it actually works.
        // https://github.com/Vanilagy/mediabunny/issues/222
        // eslint-disable-next-line @typescript-eslint/no-misused-promises, no-async-promise-executor
        return new Promise(async (resolve) => {
            try {
                const encoder = new VideoEncoder({
                    output: () => { },
                    error: () => resolve(false),
                });
                encoder.configure(encoderConfig);
                const frameData = new Uint8Array(width * height * 4);
                const frame = new VideoFrame(frameData, {
                    format: 'RGBA',
                    codedWidth: width,
                    codedHeight: height,
                    timestamp: 0,
                });
                encoder.encode(frame);
                frame.close();
                await encoder.flush();
                resolve(true);
            }
            catch {
                resolve(false);
            }
        });
    }
    else {
        return true;
    }
};
/**
 * Checks if the browser is able to encode the given audio codec with the given parameters.
 * @group Encoding
 * @public
 */
const canEncodeAudio = async (codec, options = {}) => {
    const { numberOfChannels = 2, sampleRate = 48000, bitrate = 128e3, ...restOptions } = options;
    if (!src_codec/* AUDIO_CODECS */.PP.includes(codec)) {
        return false;
    }
    if (!Number.isInteger(numberOfChannels) || numberOfChannels <= 0) {
        throw new TypeError('numberOfChannels must be a positive integer.');
    }
    if (!Number.isInteger(sampleRate) || sampleRate <= 0) {
        throw new TypeError('sampleRate must be a positive integer.');
    }
    if (!(bitrate instanceof Quality) && (!Number.isInteger(bitrate) || bitrate <= 0)) {
        throw new TypeError('bitrate must be a positive integer.');
    }
    validateAudioEncodingAdditionalOptions(codec, restOptions);
    let encoderConfig = null;
    if (custom_coder/* customAudioEncoders */.Lr.length > 0) {
        encoderConfig ??= buildAudioEncoderConfig({
            codec,
            numberOfChannels,
            sampleRate,
            bitrate,
            ...restOptions,
        });
        if (custom_coder/* customAudioEncoders */.Lr.some(x => x.supports(codec, encoderConfig))) {
            // There's a custom encoder
            return true;
        }
    }
    if (src_codec/* PCM_AUDIO_CODECS */.Wq.includes(codec)) {
        return true; // Because we encode these ourselves
    }
    if (typeof AudioEncoder === 'undefined') {
        return false;
    }
    encoderConfig ??= buildAudioEncoderConfig({
        codec,
        numberOfChannels,
        sampleRate,
        bitrate,
        ...restOptions,
    });
    const support = await AudioEncoder.isConfigSupported(encoderConfig);
    return support.supported === true;
};
/**
 * Checks if the browser is able to encode the given subtitle codec.
 * @group Encoding
 * @public
 */
const canEncodeSubtitles = async (codec) => {
    if (!SUBTITLE_CODECS.includes(codec)) {
        return false;
    }
    return true;
};
/**
 * Returns the list of all media codecs that can be encoded by the browser.
 * @group Encoding
 * @public
 */
const getEncodableCodecs = async () => {
    const [videoCodecs, audioCodecs, subtitleCodecs] = await Promise.all([
        getEncodableVideoCodecs(),
        getEncodableAudioCodecs(),
        getEncodableSubtitleCodecs(),
    ]);
    return [...videoCodecs, ...audioCodecs, ...subtitleCodecs];
};
/**
 * Returns the list of all video codecs that can be encoded by the browser.
 * @group Encoding
 * @public
 */
const getEncodableVideoCodecs = async (checkedCodecs = src_codec/* VIDEO_CODECS */.WN, options) => {
    const bools = await Promise.all(checkedCodecs.map(codec => canEncodeVideo(codec, options)));
    return checkedCodecs.filter((_, i) => bools[i]);
};
/**
 * Returns the list of all audio codecs that can be encoded by the browser.
 * @group Encoding
 * @public
 */
const getEncodableAudioCodecs = async (checkedCodecs = src_codec/* AUDIO_CODECS */.PP, options) => {
    const bools = await Promise.all(checkedCodecs.map(codec => canEncodeAudio(codec, options)));
    return checkedCodecs.filter((_, i) => bools[i]);
};
/**
 * Returns the list of all subtitle codecs that can be encoded by the browser.
 * @group Encoding
 * @public
 */
const getEncodableSubtitleCodecs = async (checkedCodecs = SUBTITLE_CODECS) => {
    const bools = await Promise.all(checkedCodecs.map(canEncodeSubtitles));
    return checkedCodecs.filter((_, i) => bools[i]);
};
/**
 * Returns the first video codec from the given list that can be encoded by the browser.
 * @group Encoding
 * @public
 */
const getFirstEncodableVideoCodec = async (checkedCodecs, options) => {
    for (const codec of checkedCodecs) {
        if (await canEncodeVideo(codec, options)) {
            return codec;
        }
    }
    return null;
};
/**
 * Returns the first audio codec from the given list that can be encoded by the browser.
 * @group Encoding
 * @public
 */
const getFirstEncodableAudioCodec = async (checkedCodecs, options) => {
    for (const codec of checkedCodecs) {
        if (await canEncodeAudio(codec, options)) {
            return codec;
        }
    }
    return null;
};
/**
 * Returns the first subtitle codec from the given list that can be encoded by the browser.
 * @group Encoding
 * @public
 */
const getFirstEncodableSubtitleCodec = async (checkedCodecs) => {
    for (const codec of checkedCodecs) {
        if (await canEncodeSubtitles(codec)) {
            return codec;
        }
    }
    return null;
};

// EXTERNAL MODULE: ./node_modules/remotion/dist/esm/index.mjs
var esm = __webpack_require__(3947);
;// ./node_modules/remotion/dist/esm/version.mjs
// src/version.ts
var VERSION = "4.0.429";


// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/sample.js
var src_sample = __webpack_require__(4166);
// EXTERNAL MODULE: ./node_modules/remotion/dist/esm/no-react.mjs
var no_react = __webpack_require__(9382);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/pcm.js
var pcm = __webpack_require__(358);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/packet.js
var src_packet = __webpack_require__(3936);
;// ./node_modules/mediabunny/dist/modules/src/media-source.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */








/**
 * Base class for media sources. Media sources are used to add media samples to an output file.
 * @group Media sources
 * @public
 */
class MediaSource {
    constructor() {
        /** @internal */
        this._connectedTrack = null;
        /** @internal */
        this._closingPromise = null;
        /** @internal */
        this._closed = false;
        /**
         * @internal
         * A time offset in seconds that is added to all timestamps generated by this source.
         */
        this._timestampOffset = 0;
    }
    /** @internal */
    _ensureValidAdd() {
        if (!this._connectedTrack) {
            throw new Error('Source is not connected to an output track.');
        }
        if (this._connectedTrack.output.state === 'canceled') {
            throw new Error('Output has been canceled.');
        }
        if (this._connectedTrack.output.state === 'finalizing' || this._connectedTrack.output.state === 'finalized') {
            throw new Error('Output has been finalized.');
        }
        if (this._connectedTrack.output.state === 'pending') {
            throw new Error('Output has not started.');
        }
        if (this._closed) {
            throw new Error('Source is closed.');
        }
    }
    /** @internal */
    async _start() { }
    /** @internal */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    async _flushAndClose(forceClose) { }
    /**
     * Closes this source. This prevents future samples from being added and signals to the output file that no further
     * samples will come in for this track. Calling `.close()` is optional but recommended after adding the
     * last sample - for improved performance and reduced memory usage.
     */
    close() {
        if (this._closingPromise) {
            return;
        }
        const connectedTrack = this._connectedTrack;
        if (!connectedTrack) {
            throw new Error('Cannot call close without connecting the source to an output track.');
        }
        if (connectedTrack.output.state === 'pending') {
            throw new Error('Cannot call close before output has been started.');
        }
        this._closingPromise = (async () => {
            await this._flushAndClose(false);
            this._closed = true;
            if (connectedTrack.output.state === 'finalizing' || connectedTrack.output.state === 'finalized') {
                return;
            }
            connectedTrack.output._muxer.onTrackClose(connectedTrack);
        })();
    }
    /** @internal */
    async _flushOrWaitForOngoingClose(forceClose) {
        return this._closingPromise ??= (async () => {
            await this._flushAndClose(forceClose);
            this._closed = true;
        })();
    }
}
/**
 * Base class for video sources - sources for video tracks.
 * @group Media sources
 * @public
 */
class VideoSource extends MediaSource {
    /** Internal constructor. */
    constructor(codec) {
        super();
        /** @internal */
        this._connectedTrack = null;
        if (!src_codec/* VIDEO_CODECS */.WN.includes(codec)) {
            throw new TypeError(`Invalid video codec '${codec}'. Must be one of: ${src_codec/* VIDEO_CODECS */.WN.join(', ')}.`);
        }
        this._codec = codec;
    }
}
/**
 * The most basic video source; can be used to directly pipe encoded packets into the output file.
 * @group Media sources
 * @public
 */
class EncodedVideoPacketSource extends VideoSource {
    /** Creates a new {@link EncodedVideoPacketSource} whose packets are encoded using `codec`. */
    constructor(codec) {
        super(codec);
    }
    /**
     * Adds an encoded packet to the output video track. Packets must be added in *decode order*, while a packet's
     * timestamp must be its *presentation timestamp*. B-frames are handled automatically.
     *
     * @param meta - Additional metadata from the encoder. You should pass this for the first call, including a valid
     * decoder config.
     *
     * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise
     * to respect writer and encoder backpressure.
     */
    add(packet, meta) {
        if (!(packet instanceof src_packet/* EncodedPacket */.Z)) {
            throw new TypeError('packet must be an EncodedPacket.');
        }
        if (packet.isMetadataOnly) {
            throw new TypeError('Metadata-only packets cannot be added.');
        }
        if (meta !== undefined && (!meta || typeof meta !== 'object')) {
            throw new TypeError('meta, when provided, must be an object.');
        }
        this._ensureValidAdd();
        return this._connectedTrack.output._muxer.addEncodedVideoPacket(this._connectedTrack, packet, meta);
    }
}
class VideoEncoderWrapper {
    constructor(source, encodingConfig) {
        this.source = source;
        this.encodingConfig = encodingConfig;
        this.ensureEncoderPromise = null;
        this.encoderInitialized = false;
        this.encoder = null;
        this.muxer = null;
        this.lastMultipleOfKeyFrameInterval = -1;
        this.codedWidth = null;
        this.codedHeight = null;
        this.resizeCanvas = null;
        this.customEncoder = null;
        this.customEncoderCallSerializer = new misc/* CallSerializer */.dY();
        this.customEncoderQueueSize = 0;
        // Alpha stuff
        this.alphaEncoder = null;
        this.splitter = null;
        this.splitterCreationFailed = false;
        this.alphaFrameQueue = [];
        /**
         * Encoders typically throw their errors "out of band", meaning asynchronously in some other execution context.
         * However, we want to surface these errors to the user within the normal control flow, so they don't go uncaught.
         * So, we keep track of the encoder error and throw it as soon as we get the chance.
         */
        this.error = null;
    }
    async add(videoSample, shouldClose, encodeOptions) {
        try {
            this.checkForEncoderError();
            this.source._ensureValidAdd();
            // Ensure video sample size remains constant
            if (this.codedWidth !== null && this.codedHeight !== null) {
                if (videoSample.codedWidth !== this.codedWidth || videoSample.codedHeight !== this.codedHeight) {
                    const sizeChangeBehavior = this.encodingConfig.sizeChangeBehavior ?? 'deny';
                    if (sizeChangeBehavior === 'passThrough') {
                        // Do nada
                    }
                    else if (sizeChangeBehavior === 'deny') {
                        throw new Error(`Video sample size must remain constant. Expected ${this.codedWidth}x${this.codedHeight},`
                            + ` got ${videoSample.codedWidth}x${videoSample.codedHeight}. To allow the sample size to`
                            + ` change over time, set \`sizeChangeBehavior\` to a value other than 'strict' in the`
                            + ` encoding options.`);
                    }
                    else {
                        let canvasIsNew = false;
                        if (!this.resizeCanvas) {
                            if (typeof document !== 'undefined') {
                                // Prefer an HTMLCanvasElement
                                this.resizeCanvas = document.createElement('canvas');
                                this.resizeCanvas.width = this.codedWidth;
                                this.resizeCanvas.height = this.codedHeight;
                            }
                            else {
                                this.resizeCanvas = new OffscreenCanvas(this.codedWidth, this.codedHeight);
                            }
                            canvasIsNew = true;
                        }
                        const context = this.resizeCanvas.getContext('2d', {
                            alpha: (0,misc/* isFirefox */.gm)(), // Firefox has VideoFrame glitches with opaque canvases
                        });
                        (0,misc/* assert */.vA)(context);
                        if (!canvasIsNew) {
                            if ((0,misc/* isFirefox */.gm)()) {
                                context.fillStyle = 'black';
                                context.fillRect(0, 0, this.codedWidth, this.codedHeight);
                            }
                            else {
                                context.clearRect(0, 0, this.codedWidth, this.codedHeight);
                            }
                        }
                        videoSample.drawWithFit(context, { fit: sizeChangeBehavior });
                        if (shouldClose) {
                            videoSample.close();
                        }
                        videoSample = new src_sample/* VideoSample */.U2(this.resizeCanvas, {
                            timestamp: videoSample.timestamp,
                            duration: videoSample.duration,
                            rotation: videoSample.rotation,
                        });
                        shouldClose = true;
                    }
                }
            }
            else {
                this.codedWidth = videoSample.codedWidth;
                this.codedHeight = videoSample.codedHeight;
            }
            if (!this.encoderInitialized) {
                if (!this.ensureEncoderPromise) {
                    this.ensureEncoder(videoSample);
                }
                // No, this "if" statement is not useless. Sometimes, the above call to `ensureEncoder` might have
                // synchronously completed and the encoder is already initialized. In this case, we don't need to await
                // the promise anymore. This also fixes nasty async race condition bugs when multiple code paths are
                // calling this method: It's important that the call that initialized the encoder go through this
                // code first.
                if (!this.encoderInitialized) {
                    await this.ensureEncoderPromise;
                }
            }
            (0,misc/* assert */.vA)(this.encoderInitialized);
            const keyFrameInterval = this.encodingConfig.keyFrameInterval ?? 5;
            const multipleOfKeyFrameInterval = Math.floor(videoSample.timestamp / keyFrameInterval);
            // Ensure a key frame every keyFrameInterval seconds. It is important that all video tracks follow the same
            // "key frame" rhythm, because aligned key frames are required to start new fragments in ISOBMFF or clusters
            // in Matroska (or at least desirable).
            const finalEncodeOptions = {
                ...encodeOptions,
                keyFrame: encodeOptions?.keyFrame
                    || keyFrameInterval === 0
                    || multipleOfKeyFrameInterval !== this.lastMultipleOfKeyFrameInterval,
            };
            this.lastMultipleOfKeyFrameInterval = multipleOfKeyFrameInterval;
            if (this.customEncoder) {
                this.customEncoderQueueSize++;
                // We clone the sample so it cannot be closed on us from the outside before it reaches the encoder
                const clonedSample = videoSample.clone();
                const promise = this.customEncoderCallSerializer
                    .call(() => this.customEncoder.encode(clonedSample, finalEncodeOptions))
                    .then(() => this.customEncoderQueueSize--)
                    .catch((error) => this.error ??= error)
                    .finally(() => {
                    clonedSample.close();
                    // `videoSample` gets closed in the finally block at the end of the method
                });
                if (this.customEncoderQueueSize >= 4) {
                    await promise;
                }
            }
            else {
                (0,misc/* assert */.vA)(this.encoder);
                const videoFrame = videoSample.toVideoFrame();
                if (!this.alphaEncoder) {
                    // No alpha encoder, simple case
                    this.encoder.encode(videoFrame, finalEncodeOptions);
                    videoFrame.close();
                }
                else {
                    // We're expected to encode alpha as well
                    const frameDefinitelyHasNoAlpha = !!videoFrame.format && !videoFrame.format.includes('A');
                    if (frameDefinitelyHasNoAlpha || this.splitterCreationFailed) {
                        this.alphaFrameQueue.push(null);
                        this.encoder.encode(videoFrame, finalEncodeOptions);
                        videoFrame.close();
                    }
                    else {
                        const width = videoFrame.displayWidth;
                        const height = videoFrame.displayHeight;
                        if (!this.splitter) {
                            try {
                                this.splitter = new ColorAlphaSplitter(width, height);
                            }
                            catch (error) {
                                console.error('Due to an error, only color data will be encoded.', error);
                                this.splitterCreationFailed = true;
                                this.alphaFrameQueue.push(null);
                                this.encoder.encode(videoFrame, finalEncodeOptions);
                                videoFrame.close();
                            }
                        }
                        if (this.splitter) {
                            const colorFrame = this.splitter.extractColor(videoFrame);
                            const alphaFrame = this.splitter.extractAlpha(videoFrame);
                            this.alphaFrameQueue.push(alphaFrame);
                            this.encoder.encode(colorFrame, finalEncodeOptions);
                            colorFrame.close();
                            videoFrame.close();
                        }
                    }
                }
                if (shouldClose) {
                    videoSample.close();
                }
                // We need to do this after sending the frame to the encoder as the frame otherwise might be closed
                if (this.encoder.encodeQueueSize >= 4) {
                    await new Promise(resolve => this.encoder.addEventListener('dequeue', resolve, { once: true }));
                }
            }
            await this.muxer.mutex.currentPromise; // Allow the writer to apply backpressure
        }
        finally {
            if (shouldClose) {
                // Make sure it's always closed, even if there was an error
                videoSample.close();
            }
        }
    }
    ensureEncoder(videoSample) {
        this.ensureEncoderPromise = (async () => {
            const encoderConfig = buildVideoEncoderConfig({
                width: videoSample.codedWidth,
                height: videoSample.codedHeight,
                ...this.encodingConfig,
                framerate: this.source._connectedTrack?.metadata.frameRate,
            });
            this.encodingConfig.onEncoderConfig?.(encoderConfig);
            const MatchingCustomEncoder = custom_coder/* customVideoEncoders */.WE.find(x => x.supports(this.encodingConfig.codec, encoderConfig));
            if (MatchingCustomEncoder) {
                // @ts-expect-error "Can't create instance of abstract class 🤓"
                this.customEncoder = new MatchingCustomEncoder();
                // @ts-expect-error It's technically readonly
                this.customEncoder.codec = this.encodingConfig.codec;
                // @ts-expect-error It's technically readonly
                this.customEncoder.config = encoderConfig;
                // @ts-expect-error It's technically readonly
                this.customEncoder.onPacket = (packet, meta) => {
                    if (!(packet instanceof src_packet/* EncodedPacket */.Z)) {
                        throw new TypeError('The first argument passed to onPacket must be an EncodedPacket.');
                    }
                    if (meta !== undefined && (!meta || typeof meta !== 'object')) {
                        throw new TypeError('The second argument passed to onPacket must be an object or undefined.');
                    }
                    this.encodingConfig.onEncodedPacket?.(packet, meta);
                    void this.muxer.addEncodedVideoPacket(this.source._connectedTrack, packet, meta)
                        .catch((error) => {
                        this.error ??= error;
                    });
                };
                await this.customEncoder.init();
            }
            else {
                if (typeof VideoEncoder === 'undefined') {
                    throw new Error('VideoEncoder is not supported by this browser.');
                }
                encoderConfig.alpha = 'discard'; // Since we handle alpha ourselves
                if (this.encodingConfig.alpha === 'keep') {
                    // Encoding alpha requires using two parallel encoders, so we need to make sure they stay in sync
                    // and that neither of them drops frames. Setting latencyMode to 'quality' achieves this, because
                    // "User Agents MUST not drop frames to achieve the target bitrate and/or framerate."
                    encoderConfig.latencyMode = 'quality';
                }
                const hasOddDimension = encoderConfig.width % 2 === 1 || encoderConfig.height % 2 === 1;
                if (hasOddDimension
                    && (this.encodingConfig.codec === 'avc' || this.encodingConfig.codec === 'hevc')) {
                    // Throw a special error for this case as it gets hit often
                    throw new Error(`The dimensions ${encoderConfig.width}x${encoderConfig.height} are not supported for codec`
                        + ` '${this.encodingConfig.codec}'; both width and height must be even numbers. Make sure to`
                        + ` round your dimensions to the nearest even number.`);
                }
                const support = await VideoEncoder.isConfigSupported(encoderConfig);
                if (!support.supported) {
                    throw new Error(`This specific encoder configuration (${encoderConfig.codec}, ${encoderConfig.bitrate} bps,`
                        + ` ${encoderConfig.width}x${encoderConfig.height}, hardware acceleration:`
                        + ` ${encoderConfig.hardwareAcceleration ?? 'no-preference'}) is not supported by this browser.`
                        + ` Consider using another codec or changing your video parameters.`);
                }
                /** Queue of color chunks waiting for their alpha counterpart. */
                const colorChunkQueue = [];
                /** Each value is the number of encoded alpha chunks at which a null alpha chunk should be added. */
                const nullAlphaChunkQueue = [];
                let encodedAlphaChunkCount = 0;
                let alphaEncoderQueue = 0;
                const addPacket = (colorChunk, alphaChunk, meta) => {
                    const sideData = {};
                    if (alphaChunk) {
                        const alphaData = new Uint8Array(alphaChunk.byteLength);
                        alphaChunk.copyTo(alphaData);
                        sideData.alpha = alphaData;
                    }
                    const packet = src_packet/* EncodedPacket */.Z.fromEncodedChunk(colorChunk, sideData);
                    this.encodingConfig.onEncodedPacket?.(packet, meta);
                    void this.muxer.addEncodedVideoPacket(this.source._connectedTrack, packet, meta)
                        .catch((error) => {
                        this.error ??= error;
                    });
                };
                const stack = new Error('Encoding error').stack;
                this.encoder = new VideoEncoder({
                    output: (chunk, meta) => {
                        if (!this.alphaEncoder) {
                            // We're done
                            addPacket(chunk, null, meta);
                            return;
                        }
                        const alphaFrame = this.alphaFrameQueue.shift();
                        (0,misc/* assert */.vA)(alphaFrame !== undefined);
                        if (alphaFrame) {
                            this.alphaEncoder.encode(alphaFrame, {
                                // Crucial: The alpha frame is forced to be a key frame whenever the color frame
                                // also is. Without this, playback can glitch and even crash in some browsers.
                                // This is the reason why the two encoders are wired in series and not in parallel.
                                keyFrame: chunk.type === 'key',
                            });
                            alphaEncoderQueue++;
                            alphaFrame.close();
                            colorChunkQueue.push({ chunk, meta });
                        }
                        else {
                            // There was no alpha component for this frame
                            if (alphaEncoderQueue === 0) {
                                // No pending alpha encodes either, so we're done
                                addPacket(chunk, null, meta);
                            }
                            else {
                                // There are still alpha encodes pending, so we can't add the packet immediately since
                                // we'd end up with out-of-order packets. Instead, let's queue a null alpha chunk to be
                                // added in the future, after the current encoder workload has completed:
                                nullAlphaChunkQueue.push(encodedAlphaChunkCount + alphaEncoderQueue);
                                colorChunkQueue.push({ chunk, meta });
                            }
                        }
                    },
                    error: (error) => {
                        error.stack = stack; // Provide a more useful stack trace, the default one sucks
                        this.error ??= error;
                    },
                });
                this.encoder.configure(encoderConfig);
                if (this.encodingConfig.alpha === 'keep') {
                    const stack = new Error('Encoding error').stack;
                    // We need to encode alpha as well, which we do with a separate encoder
                    this.alphaEncoder = new VideoEncoder({
                        // We ignore the alpha chunk's metadata
                        // eslint-disable-next-line @typescript-eslint/no-unused-vars
                        output: (chunk, meta) => {
                            alphaEncoderQueue--;
                            // There has to be a color chunk because the encoders are wired in series
                            const colorChunk = colorChunkQueue.shift();
                            (0,misc/* assert */.vA)(colorChunk !== undefined);
                            addPacket(colorChunk.chunk, chunk, colorChunk.meta);
                            // See if there are any null alpha chunks queued up
                            encodedAlphaChunkCount++;
                            while (nullAlphaChunkQueue.length > 0
                                && nullAlphaChunkQueue[0] === encodedAlphaChunkCount) {
                                nullAlphaChunkQueue.shift();
                                const colorChunk = colorChunkQueue.shift();
                                (0,misc/* assert */.vA)(colorChunk !== undefined);
                                addPacket(colorChunk.chunk, null, colorChunk.meta);
                            }
                        },
                        error: (error) => {
                            error.stack = stack; // Provide a more useful stack trace
                            this.error ??= error;
                        },
                    });
                    this.alphaEncoder.configure(encoderConfig);
                }
            }
            (0,misc/* assert */.vA)(this.source._connectedTrack);
            this.muxer = this.source._connectedTrack.output._muxer;
            this.encoderInitialized = true;
        })();
    }
    async flushAndClose(forceClose) {
        if (!forceClose)
            this.checkForEncoderError();
        if (this.customEncoder) {
            if (!forceClose) {
                void this.customEncoderCallSerializer.call(() => this.customEncoder.flush());
            }
            await this.customEncoderCallSerializer.call(() => this.customEncoder.close());
        }
        else if (this.encoder) {
            if (!forceClose) {
                // These are wired in series, therefore they must also be flushed in series
                await this.encoder.flush();
                await this.alphaEncoder?.flush();
            }
            if (this.encoder.state !== 'closed') {
                this.encoder.close();
            }
            if (this.alphaEncoder && this.alphaEncoder.state !== 'closed') {
                this.alphaEncoder.close();
            }
            this.alphaFrameQueue.forEach(x => x?.close());
            this.splitter?.close();
        }
        if (!forceClose)
            this.checkForEncoderError();
    }
    getQueueSize() {
        if (this.customEncoder) {
            return this.customEncoderQueueSize;
        }
        else {
            // Because the color and alpha encoders are wired in series, there's no need to also include the alpha
            // encoder's queue size here
            return this.encoder?.encodeQueueSize ?? 0;
        }
    }
    checkForEncoderError() {
        if (this.error) {
            throw this.error;
        }
    }
}
/** Utility class for splitting a composite frame into separate color and alpha components. */
class ColorAlphaSplitter {
    constructor(initialWidth, initialHeight) {
        this.lastFrame = null;
        if (typeof OffscreenCanvas !== 'undefined') {
            this.canvas = new OffscreenCanvas(initialWidth, initialHeight);
        }
        else {
            this.canvas = document.createElement('canvas');
            this.canvas.width = initialWidth;
            this.canvas.height = initialHeight;
        }
        const gl = this.canvas.getContext('webgl2', {
            alpha: true, // Needed due to the YUV thing we do for alpha
        }); // Casting because of some TypeScript weirdness
        if (!gl) {
            throw new Error('Couldn\'t acquire WebGL 2 context.');
        }
        this.gl = gl;
        this.colorProgram = this.createColorProgram();
        this.alphaProgram = this.createAlphaProgram();
        this.vao = this.createVAO();
        this.sourceTexture = this.createTexture();
        this.alphaResolutionLocation = this.gl.getUniformLocation(this.alphaProgram, 'u_resolution');
        this.gl.useProgram(this.colorProgram);
        this.gl.uniform1i(this.gl.getUniformLocation(this.colorProgram, 'u_sourceTexture'), 0);
        this.gl.useProgram(this.alphaProgram);
        this.gl.uniform1i(this.gl.getUniformLocation(this.alphaProgram, 'u_sourceTexture'), 0);
    }
    createVertexShader() {
        return this.createShader(this.gl.VERTEX_SHADER, `#version 300 es
			in vec2 a_position;
			in vec2 a_texCoord;
			out vec2 v_texCoord;
			
			void main() {
				gl_Position = vec4(a_position, 0.0, 1.0);
				v_texCoord = a_texCoord;
			}
		`);
    }
    createColorProgram() {
        const vertexShader = this.createVertexShader();
        // This shader is simple, simply copy the color information while setting alpha to 1
        const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, `#version 300 es
			precision highp float;
			
			uniform sampler2D u_sourceTexture;
			in vec2 v_texCoord;
			out vec4 fragColor;
			
			void main() {
				vec4 source = texture(u_sourceTexture, v_texCoord);
				fragColor = vec4(source.rgb, 1.0);
			}
		`);
        const program = this.gl.createProgram();
        this.gl.attachShader(program, vertexShader);
        this.gl.attachShader(program, fragmentShader);
        this.gl.linkProgram(program);
        return program;
    }
    createAlphaProgram() {
        const vertexShader = this.createVertexShader();
        // This shader's more complex. The main reason is that this shader writes data in I420 (yuv420) pixel format
        // instead of regular RGBA. In other words, we use the shader to write out I420 data into an RGBA canvas, which
        // we then later read out with JavaScript. The reason being that browsers weirdly encode canvases and mess up
        // the color spaces, and the only way to have full control over the color space is by outputting YUV data
        // directly (avoiding the RGB conversion). Doing this conversion in JS is painfully slow, so let's utlize the
        // GPU since we're already calling it anyway.
        const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, `#version 300 es
			precision highp float;
			
			uniform sampler2D u_sourceTexture;
			uniform vec2 u_resolution; // The width and height of the canvas
			in vec2 v_texCoord;
			out vec4 fragColor;

			// This function determines the value for a single byte in the YUV stream
			float getByteValue(float byteOffset) {
				float width = u_resolution.x;
				float height = u_resolution.y;

				float yPlaneSize = width * height;

				if (byteOffset < yPlaneSize) {
					// This byte is in the luma plane. Find the corresponding pixel coordinates to sample from
					float y = floor(byteOffset / width);
					float x = mod(byteOffset, width);
					
					// Add 0.5 to sample the center of the texel
					vec2 sampleCoord = (vec2(x, y) + 0.5) / u_resolution;
					
					// The luma value is the alpha from the source texture
					return texture(u_sourceTexture, sampleCoord).a;
				} else {
					// Write a fixed value for chroma and beyond
					return 128.0 / 255.0;
				}
			}
			
			void main() {
				// Each fragment writes 4 bytes (R, G, B, A)
				float pixelIndex = floor(gl_FragCoord.y) * u_resolution.x + floor(gl_FragCoord.x);
				float baseByteOffset = pixelIndex * 4.0;

				vec4 result;
				for (int i = 0; i < 4; i++) {
					float currentByteOffset = baseByteOffset + float(i);
					result[i] = getByteValue(currentByteOffset);
				}
				
				fragColor = result;
			}
		`);
        const program = this.gl.createProgram();
        this.gl.attachShader(program, vertexShader);
        this.gl.attachShader(program, fragmentShader);
        this.gl.linkProgram(program);
        return program;
    }
    createShader(type, source) {
        const shader = this.gl.createShader(type);
        this.gl.shaderSource(shader, source);
        this.gl.compileShader(shader);
        if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
            console.error('Shader compile error:', this.gl.getShaderInfoLog(shader));
        }
        return shader;
    }
    createVAO() {
        const vao = this.gl.createVertexArray();
        this.gl.bindVertexArray(vao);
        const vertices = new Float32Array([
            -1, -1, 0, 1,
            1, -1, 1, 1,
            -1, 1, 0, 0,
            1, 1, 1, 0,
        ]);
        const buffer = this.gl.createBuffer();
        this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
        this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);
        const positionLocation = this.gl.getAttribLocation(this.colorProgram, 'a_position');
        const texCoordLocation = this.gl.getAttribLocation(this.colorProgram, 'a_texCoord');
        this.gl.enableVertexAttribArray(positionLocation);
        this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 16, 0);
        this.gl.enableVertexAttribArray(texCoordLocation);
        this.gl.vertexAttribPointer(texCoordLocation, 2, this.gl.FLOAT, false, 16, 8);
        return vao;
    }
    createTexture() {
        const texture = this.gl.createTexture();
        this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
        return texture;
    }
    updateTexture(sourceFrame) {
        if (this.lastFrame === sourceFrame) {
            return;
        }
        if (sourceFrame.displayWidth !== this.canvas.width || sourceFrame.displayHeight !== this.canvas.height) {
            this.canvas.width = sourceFrame.displayWidth;
            this.canvas.height = sourceFrame.displayHeight;
        }
        this.gl.activeTexture(this.gl.TEXTURE0);
        this.gl.bindTexture(this.gl.TEXTURE_2D, this.sourceTexture);
        this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, sourceFrame);
        this.lastFrame = sourceFrame;
    }
    extractColor(sourceFrame) {
        this.updateTexture(sourceFrame);
        this.gl.useProgram(this.colorProgram);
        this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
        this.gl.clear(this.gl.COLOR_BUFFER_BIT);
        this.gl.bindVertexArray(this.vao);
        this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
        return new VideoFrame(this.canvas, {
            timestamp: sourceFrame.timestamp,
            duration: sourceFrame.duration ?? undefined,
            alpha: 'discard',
        });
    }
    extractAlpha(sourceFrame) {
        this.updateTexture(sourceFrame);
        this.gl.useProgram(this.alphaProgram);
        this.gl.uniform2f(this.alphaResolutionLocation, this.canvas.width, this.canvas.height);
        this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
        this.gl.clear(this.gl.COLOR_BUFFER_BIT);
        this.gl.bindVertexArray(this.vao);
        this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
        const { width, height } = this.canvas;
        const chromaSamples = Math.ceil(width / 2) * Math.ceil(height / 2);
        const yuvSize = width * height + chromaSamples * 2;
        const requiredHeight = Math.ceil(yuvSize / (width * 4));
        let yuv = new Uint8Array(4 * width * requiredHeight);
        this.gl.readPixels(0, 0, width, requiredHeight, this.gl.RGBA, this.gl.UNSIGNED_BYTE, yuv);
        yuv = yuv.subarray(0, yuvSize);
        (0,misc/* assert */.vA)(yuv[width * height] === 128); // Where chroma data starts
        (0,misc/* assert */.vA)(yuv[yuv.length - 1] === 128); // Assert the YUV data has been fully written
        // Defining this separately because TypeScript doesn't know `transfer` and I can't be bothered to do declaration
        // merging right now
        const init = {
            format: 'I420',
            codedWidth: width,
            codedHeight: height,
            timestamp: sourceFrame.timestamp,
            duration: sourceFrame.duration ?? undefined,
            transfer: [yuv.buffer],
        };
        return new VideoFrame(yuv, init);
    }
    close() {
        this.gl.getExtension('WEBGL_lose_context')?.loseContext();
        this.gl = null;
    }
}
/**
 * This source can be used to add raw, unencoded video samples (frames) to an output video track. These frames will
 * automatically be encoded and then piped into the output.
 * @group Media sources
 * @public
 */
class VideoSampleSource extends VideoSource {
    /**
     * Creates a new {@link VideoSampleSource} whose samples are encoded according to the specified
     * {@link VideoEncodingConfig}.
     */
    constructor(encodingConfig) {
        validateVideoEncodingConfig(encodingConfig);
        super(encodingConfig.codec);
        this._encoder = new VideoEncoderWrapper(this, encodingConfig);
    }
    /**
     * Encodes a video sample (frame) and then adds it to the output.
     *
     * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise
     * to respect writer and encoder backpressure.
     */
    add(videoSample, encodeOptions) {
        if (!(videoSample instanceof src_sample/* VideoSample */.U2)) {
            throw new TypeError('videoSample must be a VideoSample.');
        }
        return this._encoder.add(videoSample, false, encodeOptions);
    }
    /** @internal */
    _flushAndClose(forceClose) {
        return this._encoder.flushAndClose(forceClose);
    }
}
/**
 * This source can be used to add video frames to the output track from a fixed canvas element. Since canvases are often
 * used for rendering, this source provides a convenient wrapper around {@link VideoSampleSource}.
 * @group Media sources
 * @public
 */
class CanvasSource extends VideoSource {
    /**
     * Creates a new {@link CanvasSource} from a canvas element or `OffscreenCanvas` whose samples are encoded
     * according to the specified {@link VideoEncodingConfig}.
     */
    constructor(canvas, encodingConfig) {
        if (!(typeof HTMLCanvasElement !== 'undefined' && canvas instanceof HTMLCanvasElement)
            && !(typeof OffscreenCanvas !== 'undefined' && canvas instanceof OffscreenCanvas)) {
            throw new TypeError('canvas must be an HTMLCanvasElement or OffscreenCanvas.');
        }
        validateVideoEncodingConfig(encodingConfig);
        super(encodingConfig.codec);
        this._encoder = new VideoEncoderWrapper(this, encodingConfig);
        this._canvas = canvas;
    }
    /**
     * Captures the current canvas state as a video sample (frame), encodes it and adds it to the output.
     *
     * @param timestamp - The timestamp of the sample, in seconds.
     * @param duration - The duration of the sample, in seconds.
     *
     * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise
     * to respect writer and encoder backpressure.
     */
    add(timestamp, duration = 0, encodeOptions) {
        if (!Number.isFinite(timestamp) || timestamp < 0) {
            throw new TypeError('timestamp must be a non-negative number.');
        }
        if (!Number.isFinite(duration) || duration < 0) {
            throw new TypeError('duration must be a non-negative number.');
        }
        const sample = new src_sample/* VideoSample */.U2(this._canvas, { timestamp, duration });
        return this._encoder.add(sample, true, encodeOptions);
    }
    /** @internal */
    _flushAndClose(forceClose) {
        return this._encoder.flushAndClose(forceClose);
    }
}
/**
 * Video source that encodes the frames of a
 * [`MediaStreamVideoTrack`](https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack) and pipes them into the
 * output. This is useful for capturing live or real-time data such as webcams or screen captures. Frames will
 * automatically start being captured once the connected {@link Output} is started, and will keep being captured until
 * the {@link Output} is finalized or this source is closed.
 * @group Media sources
 * @public
 */
class MediaStreamVideoTrackSource extends VideoSource {
    /** A promise that rejects upon any error within this source. This promise never resolves. */
    get errorPromise() {
        this._errorPromiseAccessed = true;
        return this._promiseWithResolvers.promise;
    }
    /** Whether this source is currently paused as a result of calling `.pause()`. */
    get paused() {
        return this._paused;
    }
    /**
     * Creates a new {@link MediaStreamVideoTrackSource} from a
     * [`MediaStreamVideoTrack`](https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack), which will pull
     * video samples from the stream in real time and encode them according to {@link VideoEncodingConfig}.
     */
    constructor(track, encodingConfig) {
        if (!(track instanceof MediaStreamTrack) || track.kind !== 'video') {
            throw new TypeError('track must be a video MediaStreamTrack.');
        }
        validateVideoEncodingConfig(encodingConfig);
        encodingConfig = {
            ...encodingConfig,
            latencyMode: 'realtime',
        };
        super(encodingConfig.codec);
        /** @internal */
        this._abortController = null;
        /** @internal */
        this._workerTrackId = null;
        /** @internal */
        this._workerListener = null;
        /** @internal */
        this._promiseWithResolvers = (0,misc/* promiseWithResolvers */.nJ)();
        /** @internal */
        this._errorPromiseAccessed = false;
        /** @internal */
        this._paused = false;
        /** @internal */
        this._lastSampleTimestamp = null;
        /** @internal */
        this._pauseOffset = 0;
        this._encoder = new VideoEncoderWrapper(this, encodingConfig);
        this._track = track;
    }
    /** @internal */
    async _start() {
        if (!this._errorPromiseAccessed) {
            console.warn('Make sure not to ignore the `errorPromise` field on MediaStreamVideoTrackSource, so that any internal'
                + ' errors get bubbled up properly.');
        }
        this._abortController = new AbortController();
        let firstVideoFrameTimestamp = null;
        let errored = false;
        const onVideoFrame = (videoFrame) => {
            if (errored) {
                videoFrame.close();
                return;
            }
            const currentTimestamp = videoFrame.timestamp / 1e6;
            if (this._paused) {
                const frameSeen = firstVideoFrameTimestamp !== null;
                if (frameSeen) {
                    if (this._lastSampleTimestamp !== null) {
                        // In addition to dropping this frame, let's also keep track of the time we have lost due to the
                        // pause. Doing it like this instead of simply keeping track of the paused time is better since
                        // it retains the frame rate of the underlying source.
                        const timeDelta = currentTimestamp - this._lastSampleTimestamp;
                        // We modify this field instead of _timestampOffset since we still might have data in flight
                        // in the encoder, with which we don't want to mess.
                        this._pauseOffset -= timeDelta;
                    }
                    this._lastSampleTimestamp = currentTimestamp;
                }
                videoFrame.close();
                return;
            }
            if (firstVideoFrameTimestamp === null) {
                firstVideoFrameTimestamp = currentTimestamp;
                const muxer = this._connectedTrack.output._muxer;
                if (muxer.firstMediaStreamTimestamp === null) {
                    muxer.firstMediaStreamTimestamp = performance.now() / 1000;
                    this._timestampOffset = -firstVideoFrameTimestamp;
                }
                else {
                    this._timestampOffset = (performance.now() / 1000 - muxer.firstMediaStreamTimestamp)
                        - firstVideoFrameTimestamp;
                }
            }
            this._lastSampleTimestamp = currentTimestamp;
            if (this._encoder.getQueueSize() >= 4) {
                // Drop frames if the encoder is overloaded
                videoFrame.close();
                return;
            }
            const sample = new src_sample/* VideoSample */.U2(videoFrame, {
                timestamp: currentTimestamp + this._pauseOffset,
            });
            void this._encoder.add(sample, true)
                .catch((error) => {
                errored = true;
                this._abortController?.abort();
                this._promiseWithResolvers.reject(error);
                if (this._workerTrackId !== null) {
                    // Tell the worker to stop the track
                    sendMessageToMediaStreamTrackProcessorWorker({
                        type: 'stopTrack',
                        trackId: this._workerTrackId,
                    });
                }
            });
        };
        if (typeof MediaStreamTrackProcessor !== 'undefined') {
            // We can do it here directly, perfect
            const processor = new MediaStreamTrackProcessor({ track: this._track });
            const consumer = new WritableStream({ write: onVideoFrame });
            processor.readable.pipeTo(consumer, {
                signal: this._abortController.signal,
            }).catch((error) => {
                // Handle AbortError silently
                if (error instanceof DOMException && error.name === 'AbortError')
                    return;
                this._promiseWithResolvers.reject(error);
            });
        }
        else {
            // It might still be supported in a worker, so let's check that
            const supportedInWorker = await mediaStreamTrackProcessorIsSupportedInWorker();
            if (supportedInWorker) {
                this._workerTrackId = nextMediaStreamTrackProcessorWorkerId++;
                sendMessageToMediaStreamTrackProcessorWorker({
                    type: 'videoTrack',
                    trackId: this._workerTrackId,
                    track: this._track,
                });
                this._workerListener = (event) => {
                    const message = event.data;
                    if (message.type === 'videoFrame' && message.trackId === this._workerTrackId) {
                        onVideoFrame(message.videoFrame);
                    }
                    else if (message.type === 'error' && message.trackId === this._workerTrackId) {
                        this._promiseWithResolvers.reject(message.error);
                    }
                };
                mediaStreamTrackProcessorWorker.addEventListener('message', this._workerListener);
            }
            else {
                throw new Error('MediaStreamTrackProcessor is required but not supported by this browser.');
            }
        }
    }
    /**
     * Pauses the capture of video frames - any video frames emitted by the underlying media stream will be ignored
     * while paused. This does *not* close the underlying `MediaStreamVideoTrack`, it just ignores its output.
     */
    pause() {
        this._paused = true;
    }
    /** Resumes the capture of video frames after being paused. */
    resume() {
        this._paused = false;
    }
    /** @internal */
    async _flushAndClose(forceClose) {
        if (this._abortController) {
            this._abortController.abort();
            this._abortController = null;
        }
        if (this._workerTrackId !== null) {
            (0,misc/* assert */.vA)(this._workerListener);
            sendMessageToMediaStreamTrackProcessorWorker({
                type: 'stopTrack',
                trackId: this._workerTrackId,
            });
            // Wait for the worker to stop the track
            await new Promise((resolve) => {
                const listener = (event) => {
                    const message = event.data;
                    if (message.type === 'trackStopped' && message.trackId === this._workerTrackId) {
                        (0,misc/* assert */.vA)(this._workerListener);
                        mediaStreamTrackProcessorWorker.removeEventListener('message', this._workerListener);
                        mediaStreamTrackProcessorWorker.removeEventListener('message', listener);
                        resolve();
                    }
                };
                mediaStreamTrackProcessorWorker.addEventListener('message', listener);
            });
        }
        await this._encoder.flushAndClose(forceClose);
    }
}
/**
 * Base class for audio sources - sources for audio tracks.
 * @group Media sources
 * @public
 */
class AudioSource extends MediaSource {
    /** Internal constructor. */
    constructor(codec) {
        super();
        /** @internal */
        this._connectedTrack = null;
        if (!src_codec/* AUDIO_CODECS */.PP.includes(codec)) {
            throw new TypeError(`Invalid audio codec '${codec}'. Must be one of: ${src_codec/* AUDIO_CODECS */.PP.join(', ')}.`);
        }
        this._codec = codec;
    }
}
/**
 * The most basic audio source; can be used to directly pipe encoded packets into the output file.
 * @group Media sources
 * @public
 */
class EncodedAudioPacketSource extends AudioSource {
    /** Creates a new {@link EncodedAudioPacketSource} whose packets are encoded using `codec`. */
    constructor(codec) {
        super(codec);
    }
    /**
     * Adds an encoded packet to the output audio track. Packets must be added in *decode order*.
     *
     * @param meta - Additional metadata from the encoder. You should pass this for the first call, including a valid
     * decoder config.
     *
     * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise
     * to respect writer and encoder backpressure.
     */
    add(packet, meta) {
        if (!(packet instanceof src_packet/* EncodedPacket */.Z)) {
            throw new TypeError('packet must be an EncodedPacket.');
        }
        if (packet.isMetadataOnly) {
            throw new TypeError('Metadata-only packets cannot be added.');
        }
        if (meta !== undefined && (!meta || typeof meta !== 'object')) {
            throw new TypeError('meta, when provided, must be an object.');
        }
        this._ensureValidAdd();
        return this._connectedTrack.output._muxer.addEncodedAudioPacket(this._connectedTrack, packet, meta);
    }
}
class AudioEncoderWrapper {
    constructor(source, encodingConfig) {
        this.source = source;
        this.encodingConfig = encodingConfig;
        this.ensureEncoderPromise = null;
        this.encoderInitialized = false;
        this.encoder = null;
        this.muxer = null;
        this.lastNumberOfChannels = null;
        this.lastSampleRate = null;
        this.isPcmEncoder = false;
        this.outputSampleSize = null;
        this.writeOutputValue = null;
        this.customEncoder = null;
        this.customEncoderCallSerializer = new misc/* CallSerializer */.dY();
        this.customEncoderQueueSize = 0;
        this.lastEndSampleIndex = null;
        /**
         * Encoders typically throw their errors "out of band", meaning asynchronously in some other execution context.
         * However, we want to surface these errors to the user within the normal control flow, so they don't go uncaught.
         * So, we keep track of the encoder error and throw it as soon as we get the chance.
         */
        this.error = null;
    }
    async add(audioSample, shouldClose) {
        try {
            this.checkForEncoderError();
            this.source._ensureValidAdd();
            // Ensure audio parameters remain constant
            if (this.lastNumberOfChannels !== null && this.lastSampleRate !== null) {
                if (audioSample.numberOfChannels !== this.lastNumberOfChannels
                    || audioSample.sampleRate !== this.lastSampleRate) {
                    throw new Error(`Audio parameters must remain constant. Expected ${this.lastNumberOfChannels} channels at`
                        + ` ${this.lastSampleRate} Hz, got ${audioSample.numberOfChannels} channels at`
                        + ` ${audioSample.sampleRate} Hz.`);
                }
            }
            else {
                this.lastNumberOfChannels = audioSample.numberOfChannels;
                this.lastSampleRate = audioSample.sampleRate;
            }
            if (!this.encoderInitialized) {
                if (!this.ensureEncoderPromise) {
                    this.ensureEncoder(audioSample);
                }
                // No, this "if" statement is not useless. Sometimes, the above call to `ensureEncoder` might have
                // synchronously completed and the encoder is already initialized. In this case, we don't need to await
                // the promise anymore. This also fixes nasty async race condition bugs when multiple code paths are
                // calling this method: It's important that the call that initialized the encoder go through this
                // code first.
                if (!this.encoderInitialized) {
                    await this.ensureEncoderPromise;
                }
            }
            (0,misc/* assert */.vA)(this.encoderInitialized);
            // Handle padding of gaps with silence to avoid audio drift over time, like in
            // https://github.com/Vanilagy/mediabunny/issues/176
            // TODO An open question is how encoders deal with the first AudioData having a non-zero timestamp, and with
            // AudioDatas that have an overlapping timestamp range.
            {
                const startSampleIndex = Math.round(audioSample.timestamp * audioSample.sampleRate);
                const endSampleIndex = Math.round((audioSample.timestamp + audioSample.duration) * audioSample.sampleRate);
                if (this.lastEndSampleIndex === null) {
                    this.lastEndSampleIndex = endSampleIndex;
                }
                else {
                    const sampleDiff = startSampleIndex - this.lastEndSampleIndex;
                    if (sampleDiff >= 64) {
                        // The gap is big enough, let's add a correction sample
                        const fillSample = new src_sample/* AudioSample */.B1({
                            data: new Float32Array(sampleDiff * audioSample.numberOfChannels),
                            format: 'f32-planar',
                            sampleRate: audioSample.sampleRate,
                            numberOfChannels: audioSample.numberOfChannels,
                            numberOfFrames: sampleDiff,
                            timestamp: this.lastEndSampleIndex / audioSample.sampleRate,
                        });
                        await this.add(fillSample, true); // Recursive call
                    }
                    this.lastEndSampleIndex += audioSample.numberOfFrames;
                }
            }
            if (this.customEncoder) {
                this.customEncoderQueueSize++;
                // We clone the sample so it cannot be closed on us from the outside before it reaches the encoder
                const clonedSample = audioSample.clone();
                const promise = this.customEncoderCallSerializer
                    .call(() => this.customEncoder.encode(clonedSample))
                    .then(() => this.customEncoderQueueSize--)
                    .catch((error) => this.error ??= error)
                    .finally(() => {
                    clonedSample.close();
                    // `audioSample` gets closed in the finally block at the end of the method
                });
                if (this.customEncoderQueueSize >= 4) {
                    await promise;
                }
                await this.muxer.mutex.currentPromise; // Allow the writer to apply backpressure
            }
            else if (this.isPcmEncoder) {
                await this.doPcmEncoding(audioSample, shouldClose);
            }
            else {
                (0,misc/* assert */.vA)(this.encoder);
                const audioData = audioSample.toAudioData();
                this.encoder.encode(audioData);
                audioData.close();
                if (shouldClose) {
                    audioSample.close();
                }
                if (this.encoder.encodeQueueSize >= 4) {
                    await new Promise(resolve => this.encoder.addEventListener('dequeue', resolve, { once: true }));
                }
                await this.muxer.mutex.currentPromise; // Allow the writer to apply backpressure
            }
        }
        finally {
            if (shouldClose) {
                // Make sure it's always closed, even if there was an error
                audioSample.close();
            }
        }
    }
    async doPcmEncoding(audioSample, shouldClose) {
        (0,misc/* assert */.vA)(this.outputSampleSize);
        (0,misc/* assert */.vA)(this.writeOutputValue);
        // Need to extract data from the audio data before we close it
        const { numberOfChannels, numberOfFrames, sampleRate, timestamp } = audioSample;
        const CHUNK_SIZE = 2048;
        const outputs = [];
        // Prepare all of the output buffers, each being bounded by CHUNK_SIZE so we don't generate huge packets
        for (let frame = 0; frame < numberOfFrames; frame += CHUNK_SIZE) {
            const frameCount = Math.min(CHUNK_SIZE, audioSample.numberOfFrames - frame);
            const outputSize = frameCount * numberOfChannels * this.outputSampleSize;
            const outputBuffer = new ArrayBuffer(outputSize);
            const outputView = new DataView(outputBuffer);
            outputs.push({ frameCount, view: outputView });
        }
        const allocationSize = audioSample.allocationSize(({ planeIndex: 0, format: 'f32-planar' }));
        const floats = new Float32Array(allocationSize / Float32Array.BYTES_PER_ELEMENT);
        for (let i = 0; i < numberOfChannels; i++) {
            audioSample.copyTo(floats, { planeIndex: i, format: 'f32-planar' });
            for (let j = 0; j < outputs.length; j++) {
                const { frameCount, view } = outputs[j];
                for (let k = 0; k < frameCount; k++) {
                    this.writeOutputValue(view, (k * numberOfChannels + i) * this.outputSampleSize, floats[j * CHUNK_SIZE + k]);
                }
            }
        }
        if (shouldClose) {
            audioSample.close();
        }
        const meta = {
            decoderConfig: {
                codec: this.encodingConfig.codec,
                numberOfChannels,
                sampleRate,
            },
        };
        for (let i = 0; i < outputs.length; i++) {
            const { frameCount, view } = outputs[i];
            const outputBuffer = view.buffer;
            const startFrame = i * CHUNK_SIZE;
            const packet = new src_packet/* EncodedPacket */.Z(new Uint8Array(outputBuffer), 'key', timestamp + startFrame / sampleRate, frameCount / sampleRate);
            this.encodingConfig.onEncodedPacket?.(packet, meta);
            await this.muxer.addEncodedAudioPacket(this.source._connectedTrack, packet, meta); // With backpressure
        }
    }
    ensureEncoder(audioSample) {
        this.ensureEncoderPromise = (async () => {
            const { numberOfChannels, sampleRate } = audioSample;
            const encoderConfig = buildAudioEncoderConfig({
                numberOfChannels,
                sampleRate,
                ...this.encodingConfig,
            });
            this.encodingConfig.onEncoderConfig?.(encoderConfig);
            const MatchingCustomEncoder = custom_coder/* customAudioEncoders */.Lr.find(x => x.supports(this.encodingConfig.codec, encoderConfig));
            if (MatchingCustomEncoder) {
                // @ts-expect-error "Can't create instance of abstract class 🤓"
                this.customEncoder = new MatchingCustomEncoder();
                // @ts-expect-error It's technically readonly
                this.customEncoder.codec = this.encodingConfig.codec;
                // @ts-expect-error It's technically readonly
                this.customEncoder.config = encoderConfig;
                // @ts-expect-error It's technically readonly
                this.customEncoder.onPacket = (packet, meta) => {
                    if (!(packet instanceof src_packet/* EncodedPacket */.Z)) {
                        throw new TypeError('The first argument passed to onPacket must be an EncodedPacket.');
                    }
                    if (meta !== undefined && (!meta || typeof meta !== 'object')) {
                        throw new TypeError('The second argument passed to onPacket must be an object or undefined.');
                    }
                    this.encodingConfig.onEncodedPacket?.(packet, meta);
                    void this.muxer.addEncodedAudioPacket(this.source._connectedTrack, packet, meta)
                        .catch((error) => {
                        this.error ??= error;
                    });
                };
                await this.customEncoder.init();
            }
            else if (src_codec/* PCM_AUDIO_CODECS */.Wq.includes(this.encodingConfig.codec)) {
                this.initPcmEncoder();
            }
            else {
                if (typeof AudioEncoder === 'undefined') {
                    throw new Error('AudioEncoder is not supported by this browser.');
                }
                const support = await AudioEncoder.isConfigSupported(encoderConfig);
                if (!support.supported) {
                    throw new Error(`This specific encoder configuration (${encoderConfig.codec}, ${encoderConfig.bitrate} bps,`
                        + ` ${encoderConfig.numberOfChannels} channels, ${encoderConfig.sampleRate} Hz) is not`
                        + ` supported by this browser. Consider using another codec or changing your audio parameters.`);
                }
                const stack = new Error('Encoding error').stack;
                this.encoder = new AudioEncoder({
                    output: (chunk, meta) => {
                        // WebKit emits an invalid description for AAC (https://bugs.webkit.org/show_bug.cgi?id=302253),
                        // which we try to detect here. If detected, we'll provide our own description instead, derived
                        // from the codec string and audio parameters.
                        if (this.encodingConfig.codec === 'aac' && meta?.decoderConfig) {
                            let needsDescriptionOverwrite = false;
                            if (!meta.decoderConfig.description || meta.decoderConfig.description.byteLength < 2) {
                                needsDescriptionOverwrite = true;
                            }
                            else {
                                const audioSpecificConfig = (0,src_codec/* parseAacAudioSpecificConfig */.zF)((0,misc/* toUint8Array */.Fo)(meta.decoderConfig.description));
                                needsDescriptionOverwrite = audioSpecificConfig.objectType === 0;
                            }
                            if (needsDescriptionOverwrite) {
                                const objectType = Number((0,misc/* last */._g)(encoderConfig.codec.split('.')));
                                meta.decoderConfig.description = (0,src_codec/* buildAacAudioSpecificConfig */.Wz)({
                                    objectType,
                                    numberOfChannels: meta.decoderConfig.numberOfChannels,
                                    sampleRate: meta.decoderConfig.sampleRate,
                                });
                            }
                        }
                        const packet = src_packet/* EncodedPacket */.Z.fromEncodedChunk(chunk);
                        this.encodingConfig.onEncodedPacket?.(packet, meta);
                        void this.muxer.addEncodedAudioPacket(this.source._connectedTrack, packet, meta)
                            .catch((error) => {
                            this.error ??= error;
                        });
                    },
                    error: (error) => {
                        error.stack = stack; // Provide a more useful stack trace
                        this.error ??= error;
                    },
                });
                this.encoder.configure(encoderConfig);
            }
            (0,misc/* assert */.vA)(this.source._connectedTrack);
            this.muxer = this.source._connectedTrack.output._muxer;
            this.encoderInitialized = true;
        })();
    }
    initPcmEncoder() {
        this.isPcmEncoder = true;
        const codec = this.encodingConfig.codec;
        const { dataType, sampleSize, littleEndian } = (0,src_codec/* parsePcmCodec */.Ei)(codec);
        this.outputSampleSize = sampleSize;
        // All these functions receive a float sample as input and map it into the desired format
        switch (sampleSize) {
            case 1:
                {
                    if (dataType === 'unsigned') {
                        this.writeOutputValue = (view, byteOffset, value) => view.setUint8(byteOffset, (0,misc/* clamp */.qE)((value + 1) * 127.5, 0, 255));
                    }
                    else if (dataType === 'signed') {
                        this.writeOutputValue = (view, byteOffset, value) => {
                            view.setInt8(byteOffset, (0,misc/* clamp */.qE)(Math.round(value * 128), -128, 127));
                        };
                    }
                    else if (dataType === 'ulaw') {
                        this.writeOutputValue = (view, byteOffset, value) => {
                            const int16 = (0,misc/* clamp */.qE)(Math.floor(value * 32767), -32768, 32767);
                            view.setUint8(byteOffset, (0,pcm/* toUlaw */.vX)(int16));
                        };
                    }
                    else if (dataType === 'alaw') {
                        this.writeOutputValue = (view, byteOffset, value) => {
                            const int16 = (0,misc/* clamp */.qE)(Math.floor(value * 32767), -32768, 32767);
                            view.setUint8(byteOffset, (0,pcm/* toAlaw */.xq)(int16));
                        };
                    }
                    else {
                        (0,misc/* assert */.vA)(false);
                    }
                }
                ;
                break;
            case 2:
                {
                    if (dataType === 'unsigned') {
                        this.writeOutputValue = (view, byteOffset, value) => view.setUint16(byteOffset, (0,misc/* clamp */.qE)((value + 1) * 32767.5, 0, 65535), littleEndian);
                    }
                    else if (dataType === 'signed') {
                        this.writeOutputValue = (view, byteOffset, value) => view.setInt16(byteOffset, (0,misc/* clamp */.qE)(Math.round(value * 32767), -32768, 32767), littleEndian);
                    }
                    else {
                        (0,misc/* assert */.vA)(false);
                    }
                }
                ;
                break;
            case 3:
                {
                    if (dataType === 'unsigned') {
                        this.writeOutputValue = (view, byteOffset, value) => (0,misc/* setUint24 */.jD)(view, byteOffset, (0,misc/* clamp */.qE)((value + 1) * 8388607.5, 0, 16777215), littleEndian);
                    }
                    else if (dataType === 'signed') {
                        this.writeOutputValue = (view, byteOffset, value) => (0,misc/* setInt24 */.iP)(view, byteOffset, (0,misc/* clamp */.qE)(Math.round(value * 8388607), -8388608, 8388607), littleEndian);
                    }
                    else {
                        (0,misc/* assert */.vA)(false);
                    }
                }
                ;
                break;
            case 4:
                {
                    if (dataType === 'unsigned') {
                        this.writeOutputValue = (view, byteOffset, value) => view.setUint32(byteOffset, (0,misc/* clamp */.qE)((value + 1) * 2147483647.5, 0, 4294967295), littleEndian);
                    }
                    else if (dataType === 'signed') {
                        this.writeOutputValue = (view, byteOffset, value) => view.setInt32(byteOffset, (0,misc/* clamp */.qE)(Math.round(value * 2147483647), -2147483648, 2147483647), littleEndian);
                    }
                    else if (dataType === 'float') {
                        this.writeOutputValue = (view, byteOffset, value) => view.setFloat32(byteOffset, value, littleEndian);
                    }
                    else {
                        (0,misc/* assert */.vA)(false);
                    }
                }
                ;
                break;
            case 8:
                {
                    if (dataType === 'float') {
                        this.writeOutputValue = (view, byteOffset, value) => view.setFloat64(byteOffset, value, littleEndian);
                    }
                    else {
                        (0,misc/* assert */.vA)(false);
                    }
                }
                ;
                break;
            default:
                {
                    (0,misc/* assertNever */.xb)(sampleSize);
                    (0,misc/* assert */.vA)(false);
                }
                ;
        }
    }
    async flushAndClose(forceClose) {
        if (!forceClose)
            this.checkForEncoderError();
        if (this.customEncoder) {
            if (!forceClose) {
                void this.customEncoderCallSerializer.call(() => this.customEncoder.flush());
            }
            await this.customEncoderCallSerializer.call(() => this.customEncoder.close());
        }
        else if (this.encoder) {
            if (!forceClose) {
                await this.encoder.flush();
            }
            if (this.encoder.state !== 'closed') {
                this.encoder.close();
            }
        }
        if (!forceClose)
            this.checkForEncoderError();
    }
    getQueueSize() {
        if (this.customEncoder) {
            return this.customEncoderQueueSize;
        }
        else if (this.isPcmEncoder) {
            return 0;
        }
        else {
            return this.encoder?.encodeQueueSize ?? 0;
        }
    }
    checkForEncoderError() {
        if (this.error) {
            throw this.error;
        }
    }
}
/**
 * This source can be used to add raw, unencoded audio samples to an output audio track. These samples will
 * automatically be encoded and then piped into the output.
 * @group Media sources
 * @public
 */
class AudioSampleSource extends AudioSource {
    /**
     * Creates a new {@link AudioSampleSource} whose samples are encoded according to the specified
     * {@link AudioEncodingConfig}.
     */
    constructor(encodingConfig) {
        validateAudioEncodingConfig(encodingConfig);
        super(encodingConfig.codec);
        this._encoder = new AudioEncoderWrapper(this, encodingConfig);
    }
    /**
     * Encodes an audio sample and then adds it to the output.
     *
     * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise
     * to respect writer and encoder backpressure.
     */
    add(audioSample) {
        if (!(audioSample instanceof src_sample/* AudioSample */.B1)) {
            throw new TypeError('audioSample must be an AudioSample.');
        }
        return this._encoder.add(audioSample, false);
    }
    /** @internal */
    _flushAndClose(forceClose) {
        return this._encoder.flushAndClose(forceClose);
    }
}
/**
 * This source can be used to add audio data from an AudioBuffer to the output track. This is useful when working with
 * the Web Audio API.
 * @group Media sources
 * @public
 */
class AudioBufferSource extends AudioSource {
    /**
     * Creates a new {@link AudioBufferSource} whose `AudioBuffer` instances are encoded according to the specified
     * {@link AudioEncodingConfig}.
     */
    constructor(encodingConfig) {
        validateAudioEncodingConfig(encodingConfig);
        super(encodingConfig.codec);
        /** @internal */
        this._accumulatedTime = 0;
        this._encoder = new AudioEncoderWrapper(this, encodingConfig);
    }
    /**
     * Converts an AudioBuffer to audio samples, encodes them and adds them to the output. The first AudioBuffer will
     * be played at timestamp 0, and any subsequent AudioBuffer will have a timestamp equal to the total duration of
     * all previous AudioBuffers.
     *
     * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise
     * to respect writer and encoder backpressure.
     */
    async add(audioBuffer) {
        if (!(audioBuffer instanceof AudioBuffer)) {
            throw new TypeError('audioBuffer must be an AudioBuffer.');
        }
        const iterator = src_sample/* AudioSample */.B1._fromAudioBuffer(audioBuffer, this._accumulatedTime);
        this._accumulatedTime += audioBuffer.duration;
        for (const audioSample of iterator) {
            await this._encoder.add(audioSample, true);
        }
    }
    /** @internal */
    _flushAndClose(forceClose) {
        return this._encoder.flushAndClose(forceClose);
    }
}
/**
 * Audio source that encodes the data of a
 * [`MediaStreamAudioTrack`](https://developer.mozilla.org/en-US/docs/Web/API/MediaStreamTrack) and pipes it into the
 * output. This is useful for capturing live or real-time audio such as microphones or audio from other media elements.
 * Audio will automatically start being captured once the connected {@link Output} is started, and will keep being
 * captured until the {@link Output} is finalized or this source is closed.
 * @group Media sources
 * @public
 */
class MediaStreamAudioTrackSource extends AudioSource {
    /** A promise that rejects upon any error within this source. This promise never resolves. */
    get errorPromise() {
        this._errorPromiseAccessed = true;
        return this._promiseWithResolvers.promise;
    }
    /** Whether this source is currently paused as a result of calling `.pause()`. */
    get paused() {
        return this._paused;
    }
    /**
     * Creates a new {@link MediaStreamAudioTrackSource} from a `MediaStreamAudioTrack`, which will pull audio samples
     * from the stream in real time and encode them according to {@link AudioEncodingConfig}.
     */
    constructor(track, encodingConfig) {
        if (!(track instanceof MediaStreamTrack) || track.kind !== 'audio') {
            throw new TypeError('track must be an audio MediaStreamTrack.');
        }
        validateAudioEncodingConfig(encodingConfig);
        super(encodingConfig.codec);
        /** @internal */
        this._abortController = null;
        /** @internal */
        this._audioContext = null;
        /** @internal */
        this._scriptProcessorNode = null; // Deprecated but goated
        /** @internal */
        this._promiseWithResolvers = (0,misc/* promiseWithResolvers */.nJ)();
        /** @internal */
        this._errorPromiseAccessed = false;
        /** @internal */
        this._paused = false;
        /** @internal */
        this._lastSampleTimestamp = null;
        /** @internal */
        this._pauseOffset = 0;
        this._encoder = new AudioEncoderWrapper(this, encodingConfig);
        this._track = track;
    }
    /** @internal */
    async _start() {
        if (!this._errorPromiseAccessed) {
            console.warn('Make sure not to ignore the `errorPromise` field on MediaStreamVideoTrackSource, so that any internal'
                + ' errors get bubbled up properly.');
        }
        this._abortController = new AbortController();
        let firstAudioDataTimestamp = null;
        let errored = false;
        const onAudioSample = (audioSample) => {
            if (errored) {
                audioSample.close();
                return;
            }
            const currentTimestamp = audioSample.timestamp;
            if (this._paused) {
                const dataSeen = firstAudioDataTimestamp !== null;
                if (dataSeen) {
                    if (this._lastSampleTimestamp !== null) {
                        // In addition to dropping this sample, let's also keep track of the time we have lost due to
                        // the pause. Doing it like this instead of simply keeping track of the paused time is better
                        // since it retains the sample rate of the underlying source.
                        const timeDelta = currentTimestamp - this._lastSampleTimestamp;
                        // We modify this field instead of _timestampOffset since we still might have data in flight
                        // in the encoder, with which we don't want to mess.
                        this._pauseOffset -= timeDelta;
                    }
                    this._lastSampleTimestamp = currentTimestamp;
                }
                audioSample.close();
                return;
            }
            if (firstAudioDataTimestamp === null) {
                firstAudioDataTimestamp = audioSample.timestamp;
                const muxer = this._connectedTrack.output._muxer;
                if (muxer.firstMediaStreamTimestamp === null) {
                    muxer.firstMediaStreamTimestamp = performance.now() / 1000;
                    this._timestampOffset = -firstAudioDataTimestamp;
                }
                else {
                    this._timestampOffset = (performance.now() / 1000 - muxer.firstMediaStreamTimestamp)
                        - firstAudioDataTimestamp;
                }
            }
            this._lastSampleTimestamp = currentTimestamp;
            if (this._encoder.getQueueSize() >= 4) {
                // Drop data if the encoder is overloaded
                audioSample.close();
                return;
            }
            audioSample.setTimestamp(currentTimestamp + this._pauseOffset);
            void this._encoder.add(audioSample, true)
                .catch((error) => {
                errored = true;
                this._abortController?.abort();
                this._promiseWithResolvers.reject(error);
                void this._audioContext?.suspend();
            });
        };
        if (typeof MediaStreamTrackProcessor !== 'undefined') {
            // Great, MediaStreamTrackProcessor is supported, this is the preferred way of doing things
            const processor = new MediaStreamTrackProcessor({ track: this._track });
            const consumer = new WritableStream({
                write: audioData => onAudioSample(new src_sample/* AudioSample */.B1(audioData)),
            });
            processor.readable.pipeTo(consumer, {
                signal: this._abortController.signal,
            }).catch((error) => {
                // Handle AbortError silently
                if (error instanceof DOMException && error.name === 'AbortError')
                    return;
                this._promiseWithResolvers.reject(error);
            });
        }
        else {
            // Let's fall back to an AudioContext approach
            // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
            const AudioContext = window.AudioContext || window.webkitAudioContext;
            this._audioContext = new AudioContext({ sampleRate: this._track.getSettings().sampleRate });
            const sourceNode = this._audioContext.createMediaStreamSource(new MediaStream([this._track]));
            this._scriptProcessorNode = this._audioContext.createScriptProcessor(4096);
            if (this._audioContext.state === 'suspended') {
                await this._audioContext.resume();
            }
            sourceNode.connect(this._scriptProcessorNode);
            this._scriptProcessorNode.connect(this._audioContext.destination);
            let totalDuration = 0;
            this._scriptProcessorNode.onaudioprocess = (event) => {
                const iterator = src_sample/* AudioSample */.B1._fromAudioBuffer(event.inputBuffer, totalDuration);
                totalDuration += event.inputBuffer.duration;
                for (const audioSample of iterator) {
                    onAudioSample(audioSample);
                }
            };
        }
    }
    /**
     * Pauses the capture of audio data - any audio data emitted by the underlying media stream will be ignored
     * while paused. This does *not* close the underlying `MediaStreamAudioTrack`, it just ignores its output.
     */
    pause() {
        this._paused = true;
    }
    /** Resumes the capture of audio data after being paused. */
    resume() {
        this._paused = false;
    }
    /** @internal */
    async _flushAndClose(forceClose) {
        if (this._abortController) {
            this._abortController.abort();
            this._abortController = null;
        }
        if (this._audioContext) {
            (0,misc/* assert */.vA)(this._scriptProcessorNode);
            this._scriptProcessorNode.disconnect();
            await this._audioContext.suspend();
        }
        await this._encoder.flushAndClose(forceClose);
    }
}
const mediaStreamTrackProcessorWorkerCode = () => {
    const sendMessage = (message, transfer) => {
        if (transfer) {
            self.postMessage(message, { transfer });
        }
        else {
            self.postMessage(message);
        }
    };
    // Immediately send a message to the main thread, letting them know of the support
    sendMessage({
        type: 'support',
        supported: typeof MediaStreamTrackProcessor !== 'undefined',
    });
    const abortControllers = new Map();
    const activeTracks = new Map();
    self.addEventListener('message', (event) => {
        const message = event.data;
        switch (message.type) {
            case 'videoTrack':
                {
                    activeTracks.set(message.trackId, message.track);
                    const processor = new MediaStreamTrackProcessor({ track: message.track });
                    const consumer = new WritableStream({
                        write: (videoFrame) => {
                            if (!activeTracks.has(message.trackId)) {
                                videoFrame.close();
                                return;
                            }
                            // Send it to the main thread
                            sendMessage({
                                type: 'videoFrame',
                                trackId: message.trackId,
                                videoFrame,
                            }, [videoFrame]);
                        },
                    });
                    const abortController = new AbortController();
                    abortControllers.set(message.trackId, abortController);
                    processor.readable.pipeTo(consumer, {
                        signal: abortController.signal,
                    }).catch((error) => {
                        // Handle AbortError silently
                        if (error instanceof DOMException && error.name === 'AbortError')
                            return;
                        sendMessage({
                            type: 'error',
                            trackId: message.trackId,
                            error,
                        });
                    });
                }
                ;
                break;
            case 'stopTrack':
                {
                    const abortController = abortControllers.get(message.trackId);
                    if (abortController) {
                        abortController.abort();
                        abortControllers.delete(message.trackId);
                    }
                    const track = activeTracks.get(message.trackId);
                    track?.stop();
                    activeTracks.delete(message.trackId);
                    sendMessage({
                        type: 'trackStopped',
                        trackId: message.trackId,
                    });
                }
                ;
                break;
            default: (0,misc/* assertNever */.xb)(message);
        }
    });
};
let nextMediaStreamTrackProcessorWorkerId = 0;
let mediaStreamTrackProcessorWorker = null;
const initMediaStreamTrackProcessorWorker = () => {
    const blob = new Blob([`(${mediaStreamTrackProcessorWorkerCode.toString()})()`], { type: 'application/javascript' });
    const url = URL.createObjectURL(blob);
    mediaStreamTrackProcessorWorker = new Worker(url);
};
let mediaStreamTrackProcessorIsSupportedInWorkerCache = null;
const mediaStreamTrackProcessorIsSupportedInWorker = async () => {
    if (mediaStreamTrackProcessorIsSupportedInWorkerCache !== null) {
        return mediaStreamTrackProcessorIsSupportedInWorkerCache;
    }
    if (!mediaStreamTrackProcessorWorker) {
        initMediaStreamTrackProcessorWorker();
    }
    return new Promise((resolve) => {
        (0,misc/* assert */.vA)(mediaStreamTrackProcessorWorker);
        const listener = (event) => {
            const message = event.data;
            if (message.type === 'support') {
                mediaStreamTrackProcessorIsSupportedInWorkerCache = message.supported;
                mediaStreamTrackProcessorWorker.removeEventListener('message', listener);
                resolve(message.supported);
            }
        };
        mediaStreamTrackProcessorWorker.addEventListener('message', listener);
    });
};
const sendMessageToMediaStreamTrackProcessorWorker = (message, transfer) => {
    (0,misc/* assert */.vA)(mediaStreamTrackProcessorWorker);
    if (transfer) {
        mediaStreamTrackProcessorWorker.postMessage(message, transfer);
    }
    else {
        mediaStreamTrackProcessorWorker.postMessage(message);
    }
};
/**
 * Base class for subtitle sources - sources for subtitle tracks.
 * @group Media sources
 * @public
 */
class SubtitleSource extends MediaSource {
    /** Internal constructor. */
    constructor(codec) {
        super();
        /** @internal */
        this._connectedTrack = null;
        if (!src_codec/* SUBTITLE_CODECS */.VW.includes(codec)) {
            throw new TypeError(`Invalid subtitle codec '${codec}'. Must be one of: ${src_codec/* SUBTITLE_CODECS */.VW.join(', ')}.`);
        }
        this._codec = codec;
    }
}
/**
 * This source can be used to add subtitles from a subtitle text file.
 * @group Media sources
 * @public
 */
class TextSubtitleSource extends SubtitleSource {
    /** Creates a new {@link TextSubtitleSource} where added text chunks are in the specified `codec`. */
    constructor(codec) {
        super(codec);
        /** @internal */
        this._error = null;
        this._parser = new SubtitleParser({
            codec,
            output: (cue, metadata) => {
                void this._connectedTrack?.output._muxer.addSubtitleCue(this._connectedTrack, cue, metadata)
                    .catch((error) => {
                    this._error ??= error;
                });
            },
        });
    }
    /**
     * Parses the subtitle text according to the specified codec and adds it to the output track. You don't have to
     * add the entire subtitle file at once here; you can provide it in chunks.
     *
     * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise
     * to respect writer and encoder backpressure.
     */
    add(text) {
        if (typeof text !== 'string') {
            throw new TypeError('text must be a string.');
        }
        this._checkForError();
        this._ensureValidAdd();
        this._parser.parse(text);
        return this._connectedTrack.output._muxer.mutex.currentPromise;
    }
    /** @internal */
    _checkForError() {
        if (this._error) {
            throw this._error;
        }
    }
    /** @internal */
    async _flushAndClose(forceClose) {
        if (!forceClose) {
            this._checkForError();
        }
    }
}

// EXTERNAL MODULE: ./node_modules/react/index.js
var react = __webpack_require__(6540);
// EXTERNAL MODULE: ./node_modules/react-dom/index.js
var react_dom = __webpack_require__(961);
// EXTERNAL MODULE: ./node_modules/react-dom/client.js
var client = __webpack_require__(5338);
// EXTERNAL MODULE: ./node_modules/react/jsx-runtime.js
var jsx_runtime = __webpack_require__(4848);
;// ./node_modules/mediabunny/dist/modules/src/output.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */





/**
 * List of all track types.
 * @group Miscellaneous
 * @public
 */
const ALL_TRACK_TYPES = ['video', 'audio', 'subtitle'];
const validateBaseTrackMetadata = (metadata) => {
    if (!metadata || typeof metadata !== 'object') {
        throw new TypeError('metadata must be an object.');
    }
    if (metadata.languageCode !== undefined && !(0,misc/* isIso639Dash2LanguageCode */.Nu)(metadata.languageCode)) {
        throw new TypeError('metadata.languageCode, when provided, must be a three-letter, ISO 639-2/T language code.');
    }
    if (metadata.name !== undefined && typeof metadata.name !== 'string') {
        throw new TypeError('metadata.name, when provided, must be a string.');
    }
    if (metadata.disposition !== undefined) {
        (0,src_metadata/* validateTrackDisposition */.Ze)(metadata.disposition);
    }
    if (metadata.maximumPacketCount !== undefined
        && (!Number.isInteger(metadata.maximumPacketCount) || metadata.maximumPacketCount < 0)) {
        throw new TypeError('metadata.maximumPacketCount, when provided, must be a non-negative integer.');
    }
};
/**
 * Main class orchestrating the creation of a new media file.
 * @group Output files
 * @public
 */
class Output {
    /**
     * Creates a new instance of {@link Output} which can then be used to create a new media file according to the
     * specified {@link OutputOptions}.
     */
    constructor(options) {
        /** The current state of the output. */
        this.state = 'pending';
        /** @internal */
        this._tracks = [];
        /** @internal */
        this._startPromise = null;
        /** @internal */
        this._cancelPromise = null;
        /** @internal */
        this._finalizePromise = null;
        /** @internal */
        this._mutex = new misc/* AsyncMutex */.aD();
        /** @internal */
        this._metadataTags = {};
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (!(options.format instanceof OutputFormat)) {
            throw new TypeError('options.format must be an OutputFormat.');
        }
        if (!(options.target instanceof Target)) {
            throw new TypeError('options.target must be a Target.');
        }
        if (options.target._output) {
            throw new Error('Target is already used for another output.');
        }
        options.target._output = this;
        this.format = options.format;
        this.target = options.target;
        this._writer = options.target._createWriter();
        this._muxer = options.format._createMuxer(this);
    }
    /** Adds a video track to the output with the given source. Can only be called before the output is started. */
    addVideoTrack(source, metadata = {}) {
        if (!(source instanceof VideoSource)) {
            throw new TypeError('source must be a VideoSource.');
        }
        validateBaseTrackMetadata(metadata);
        if (metadata.rotation !== undefined && ![0, 90, 180, 270].includes(metadata.rotation)) {
            throw new TypeError(`Invalid video rotation: ${metadata.rotation}. Has to be 0, 90, 180 or 270.`);
        }
        if (!this.format.supportsVideoRotationMetadata && metadata.rotation) {
            throw new Error(`${this.format._name} does not support video rotation metadata.`);
        }
        if (metadata.frameRate !== undefined
            && (!Number.isFinite(metadata.frameRate) || metadata.frameRate <= 0)) {
            throw new TypeError(`Invalid video frame rate: ${metadata.frameRate}. Must be a positive number.`);
        }
        this._addTrack('video', source, metadata);
    }
    /** Adds an audio track to the output with the given source. Can only be called before the output is started. */
    addAudioTrack(source, metadata = {}) {
        if (!(source instanceof AudioSource)) {
            throw new TypeError('source must be an AudioSource.');
        }
        validateBaseTrackMetadata(metadata);
        this._addTrack('audio', source, metadata);
    }
    /** Adds a subtitle track to the output with the given source. Can only be called before the output is started. */
    addSubtitleTrack(source, metadata = {}) {
        if (!(source instanceof SubtitleSource)) {
            throw new TypeError('source must be a SubtitleSource.');
        }
        validateBaseTrackMetadata(metadata);
        this._addTrack('subtitle', source, metadata);
    }
    /**
     * Sets descriptive metadata tags about the media file, such as title, author, date, or cover art. When called
     * multiple times, only the metadata from the last call will be used.
     *
     * Can only be called before the output is started.
     */
    setMetadataTags(tags) {
        (0,src_metadata/* validateMetadataTags */.VD)(tags);
        if (this.state !== 'pending') {
            throw new Error('Cannot set metadata tags after output has been started or canceled.');
        }
        this._metadataTags = tags;
    }
    /** @internal */
    _addTrack(type, source, metadata) {
        if (this.state !== 'pending') {
            throw new Error('Cannot add track after output has been started or canceled.');
        }
        if (source._connectedTrack) {
            throw new Error('Source is already used for a track.');
        }
        // Verify maximum track count constraints
        const supportedTrackCounts = this.format.getSupportedTrackCounts();
        const presentTracksOfThisType = this._tracks.reduce((count, track) => count + (track.type === type ? 1 : 0), 0);
        const maxCount = supportedTrackCounts[type].max;
        if (presentTracksOfThisType === maxCount) {
            throw new Error(maxCount === 0
                ? `${this.format._name} does not support ${type} tracks.`
                : (`${this.format._name} does not support more than ${maxCount} ${type} track`
                    + `${maxCount === 1 ? '' : 's'}.`));
        }
        const maxTotalCount = supportedTrackCounts.total.max;
        if (this._tracks.length === maxTotalCount) {
            throw new Error(`${this.format._name} does not support more than ${maxTotalCount} tracks`
                + `${maxTotalCount === 1 ? '' : 's'} in total.`);
        }
        const track = {
            id: this._tracks.length + 1,
            output: this,
            type,
            source: source,
            metadata,
        };
        if (track.type === 'video') {
            const supportedVideoCodecs = this.format.getSupportedVideoCodecs();
            if (supportedVideoCodecs.length === 0) {
                throw new Error(`${this.format._name} does not support video tracks.`
                    + this.format._codecUnsupportedHint(track.source._codec));
            }
            else if (!supportedVideoCodecs.includes(track.source._codec)) {
                throw new Error(`Codec '${track.source._codec}' cannot be contained within ${this.format._name}. Supported`
                    + ` video codecs are: ${supportedVideoCodecs.map(codec => `'${codec}'`).join(', ')}.`
                    + this.format._codecUnsupportedHint(track.source._codec));
            }
        }
        else if (track.type === 'audio') {
            const supportedAudioCodecs = this.format.getSupportedAudioCodecs();
            if (supportedAudioCodecs.length === 0) {
                throw new Error(`${this.format._name} does not support audio tracks.`
                    + this.format._codecUnsupportedHint(track.source._codec));
            }
            else if (!supportedAudioCodecs.includes(track.source._codec)) {
                throw new Error(`Codec '${track.source._codec}' cannot be contained within ${this.format._name}. Supported`
                    + ` audio codecs are: ${supportedAudioCodecs.map(codec => `'${codec}'`).join(', ')}.`
                    + this.format._codecUnsupportedHint(track.source._codec));
            }
        }
        else if (track.type === 'subtitle') {
            const supportedSubtitleCodecs = this.format.getSupportedSubtitleCodecs();
            if (supportedSubtitleCodecs.length === 0) {
                throw new Error(`${this.format._name} does not support subtitle tracks.`
                    + this.format._codecUnsupportedHint(track.source._codec));
            }
            else if (!supportedSubtitleCodecs.includes(track.source._codec)) {
                throw new Error(`Codec '${track.source._codec}' cannot be contained within ${this.format._name}. Supported`
                    + ` subtitle codecs are: ${supportedSubtitleCodecs.map(codec => `'${codec}'`).join(', ')}.`
                    + this.format._codecUnsupportedHint(track.source._codec));
            }
        }
        this._tracks.push(track);
        source._connectedTrack = track;
    }
    /**
     * Starts the creation of the output file. This method should be called after all tracks have been added. Only after
     * the output has started can media samples be added to the tracks.
     *
     * @returns A promise that resolves when the output has successfully started and is ready to receive media samples.
     */
    async start() {
        // Verify minimum track count constraints
        const supportedTrackCounts = this.format.getSupportedTrackCounts();
        for (const trackType of ALL_TRACK_TYPES) {
            const presentTracksOfThisType = this._tracks.reduce((count, track) => count + (track.type === trackType ? 1 : 0), 0);
            const minCount = supportedTrackCounts[trackType].min;
            if (presentTracksOfThisType < minCount) {
                throw new Error(minCount === supportedTrackCounts[trackType].max
                    ? (`${this.format._name} requires exactly ${minCount} ${trackType}`
                        + ` track${minCount === 1 ? '' : 's'}.`)
                    : (`${this.format._name} requires at least ${minCount} ${trackType}`
                        + ` track${minCount === 1 ? '' : 's'}.`));
            }
        }
        const totalMinCount = supportedTrackCounts.total.min;
        if (this._tracks.length < totalMinCount) {
            throw new Error(totalMinCount === supportedTrackCounts.total.max
                ? (`${this.format._name} requires exactly ${totalMinCount} track`
                    + `${totalMinCount === 1 ? '' : 's'}.`)
                : (`${this.format._name} requires at least ${totalMinCount} track`
                    + `${totalMinCount === 1 ? '' : 's'}.`));
        }
        if (this.state === 'canceled') {
            throw new Error('Output has been canceled.');
        }
        if (this._startPromise) {
            console.warn('Output has already been started.');
            return this._startPromise;
        }
        return this._startPromise = (async () => {
            this.state = 'started';
            this._writer.start();
            const release = await this._mutex.acquire();
            await this._muxer.start();
            const promises = this._tracks.map(track => track.source._start());
            await Promise.all(promises);
            release();
        })();
    }
    /**
     * Resolves with the full MIME type of the output file, including track codecs.
     *
     * The returned promise will resolve only once the precise codec strings of all tracks are known.
     */
    getMimeType() {
        return this._muxer.getMimeType();
    }
    /**
     * Cancels the creation of the output file, releasing internal resources like encoders and preventing further
     * samples from being added.
     *
     * @returns A promise that resolves once all internal resources have been released.
     */
    async cancel() {
        if (this._cancelPromise) {
            console.warn('Output has already been canceled.');
            return this._cancelPromise;
        }
        else if (this.state === 'finalizing' || this.state === 'finalized') {
            console.warn('Output has already been finalized.');
            return;
        }
        return this._cancelPromise = (async () => {
            this.state = 'canceled';
            const release = await this._mutex.acquire();
            const promises = this._tracks.map(x => x.source._flushOrWaitForOngoingClose(true)); // Force close
            await Promise.all(promises);
            await this._writer.close();
            release();
        })();
    }
    /**
     * Finalizes the output file. This method must be called after all media samples across all tracks have been added.
     * Once the Promise returned by this method completes, the output file is ready.
     */
    async finalize() {
        if (this.state === 'pending') {
            throw new Error('Cannot finalize before starting.');
        }
        if (this.state === 'canceled') {
            throw new Error('Cannot finalize after canceling.');
        }
        if (this._finalizePromise) {
            console.warn('Output has already been finalized.');
            return this._finalizePromise;
        }
        return this._finalizePromise = (async () => {
            this.state = 'finalizing';
            const release = await this._mutex.acquire();
            const promises = this._tracks.map(x => x.source._flushOrWaitForOngoingClose(false));
            await Promise.all(promises);
            await this._muxer.finalize();
            await this._writer.flush();
            await this._writer.finalize();
            this.state = 'finalized';
            release();
        })();
    }
}

;// ./node_modules/@remotion/web-renderer/dist/esm/index.mjs
/* unused harmony import specifier */ var esm_canEncodeVideo;
var __dispose = Symbol.dispose || /* @__PURE__ */ Symbol.for("Symbol.dispose");
var __asyncDispose = Symbol.asyncDispose || /* @__PURE__ */ Symbol.for("Symbol.asyncDispose");
var __using = (stack, value, async) => {
  if (value != null) {
    if (typeof value !== "object" && typeof value !== "function")
      throw TypeError('Object expected to be assigned to "using" declaration');
    var dispose;
    if (async)
      dispose = value[__asyncDispose];
    if (dispose === undefined)
      dispose = value[__dispose];
    if (typeof dispose !== "function")
      throw TypeError("Object not disposable");
    stack.push([async, dispose, value]);
  } else if (async) {
    stack.push([async]);
  }
  return value;
};
var __callDispose = (stack, error, hasError) => {
  var E = typeof SuppressedError === "function" ? SuppressedError : function(e, s, m, _) {
    return _ = Error(m), _.name = "SuppressedError", _.error = e, _.suppressed = s, _;
  }, fail = (e) => error = hasError ? new E(e, error, "An error was suppressed during disposal") : (hasError = true, e), next = (it) => {
    while (it = stack.pop()) {
      try {
        var result = it[1] && it[1].call(it[2]);
        if (it[0])
          return Promise.resolve(result).then(next, (e) => (fail(e), next()));
      } catch (e) {
        fail(e);
      }
    }
    if (hasError)
      throw error;
  };
  return next();
};

// src/symbol-dispose.ts
if (typeof Symbol.dispose !== "symbol")
  Object.defineProperty(Symbol, "dispose", { value: Symbol.for("dispose") });
if (typeof Symbol.asyncDispose !== "symbol")
  Object.defineProperty(Symbol, "asyncDispose", {
    value: Symbol.for("asyncDispose")
  });

// src/can-render-media-on-web.ts


// src/can-use-webfs-target.ts
var canUseWebFsWriter = async () => {
  if (!("storage" in navigator)) {
    return false;
  }
  if (!("getDirectory" in navigator.storage)) {
    return false;
  }
  try {
    const directoryHandle = await navigator.storage.getDirectory();
    const fileHandle = await directoryHandle.getFileHandle("remotion-probe-web-fs-support", {
      create: true
    });
    const canUse = fileHandle.createWritable !== undefined;
    return canUse;
  } catch {
    return false;
  }
};

// src/check-webgl-support.ts
var checkWebGLSupport = () => {
  try {
    const canvas = new OffscreenCanvas(1, 1);
    const gl = canvas.getContext("webgl2") || canvas.getContext("webgl");
    if (!gl) {
      return {
        type: "webgl-unsupported",
        message: "WebGL is not supported. 3D CSS transforms will fail.",
        severity: "error"
      };
    }
    return null;
  } catch {
    return {
      type: "webgl-unsupported",
      message: "WebGL is not supported. 3D CSS transforms will fail.",
      severity: "error"
    };
  }
};

// src/mediabunny-mappings.ts

var codecToMediabunnyCodec = (codec) => {
  switch (codec) {
    case "h264":
      return "avc";
    case "h265":
      return "hevc";
    case "vp8":
      return "vp8";
    case "vp9":
      return "vp9";
    case "av1":
      return "av1";
    default:
      throw new Error(`Unsupported codec: ${codec}`);
  }
};
var containerToMediabunnyContainer = (container) => {
  switch (container) {
    case "mp4":
      return new Mp4OutputFormat;
    case "webm":
      return new WebMOutputFormat;
    default:
      throw new Error(`Unsupported container: ${container}`);
  }
};
var getDefaultVideoCodecForContainer = (container) => {
  switch (container) {
    case "mp4":
      return "h264";
    case "webm":
      return "vp8";
    default:
      throw new Error(`Unsupported container: ${container}`);
  }
};
var getQualityForWebRendererQuality = (quality) => {
  switch (quality) {
    case "very-low":
      return QUALITY_VERY_LOW;
    case "low":
      return QUALITY_LOW;
    case "medium":
      return QUALITY_MEDIUM;
    case "high":
      return QUALITY_HIGH;
    case "very-high":
      return QUALITY_VERY_HIGH;
    default:
      throw new Error(`Unsupported quality: ${quality}`);
  }
};
var getMimeType = (container) => {
  switch (container) {
    case "mp4":
      return "video/mp4";
    case "webm":
      return "video/webm";
    default:
      throw new Error(`Unsupported container: ${container}`);
  }
};
var getDefaultAudioCodecForContainer = (container) => {
  switch (container) {
    case "mp4":
      return "aac";
    case "webm":
      return "opus";
    default:
      throw new Error(`Unsupported container: ${container}`);
  }
};
var WEB_RENDERER_VIDEO_CODECS = [
  "h264",
  "h265",
  "vp8",
  "vp9",
  "av1"
];
var getSupportedVideoCodecsForContainer = (container) => {
  const format = containerToMediabunnyContainer(container);
  const allSupported = format.getSupportedVideoCodecs();
  return WEB_RENDERER_VIDEO_CODECS.filter((codec) => allSupported.includes(codecToMediabunnyCodec(codec)));
};
var WEB_RENDERER_AUDIO_CODECS = ["aac", "opus"];
var getSupportedAudioCodecsForContainer = (container) => {
  const format = containerToMediabunnyContainer(container);
  const allSupported = format.getSupportedAudioCodecs();
  return WEB_RENDERER_AUDIO_CODECS.filter((codec) => allSupported.includes(codec));
};
var audioCodecToMediabunnyAudioCodec = (audioCodec) => {
  return audioCodec;
};

// src/resolve-audio-codec.ts

var resolveAudioCodec = async (options) => {
  const issues = [];
  const { container, requestedCodec, userSpecifiedAudioCodec, bitrate } = options;
  const audioCodec = requestedCodec ?? getDefaultAudioCodecForContainer(container);
  const supportedAudioCodecs = getSupportedAudioCodecsForContainer(container);
  if (!supportedAudioCodecs.includes(audioCodec)) {
    issues.push({
      type: "audio-codec-unsupported",
      message: `Audio codec "${audioCodec}" is not supported for container "${container}". Supported: ${supportedAudioCodecs.join(", ")}`,
      severity: "error"
    });
    return { codec: null, issues };
  }
  const mediabunnyAudioCodec = audioCodecToMediabunnyAudioCodec(audioCodec);
  const canEncode = await canEncodeAudio(mediabunnyAudioCodec, { bitrate });
  if (canEncode) {
    return { codec: audioCodec, issues };
  }
  if (userSpecifiedAudioCodec) {
    issues.push({
      type: "audio-codec-unsupported",
      message: `Audio codec "${audioCodec}" cannot be encoded by this browser. This is common for AAC on Firefox. Try using "opus" instead.`,
      severity: "error"
    });
    return { codec: null, issues };
  }
  for (const fallbackCodec of supportedAudioCodecs) {
    if (fallbackCodec !== audioCodec) {
      const fallbackMediabunnyCodec = audioCodecToMediabunnyAudioCodec(fallbackCodec);
      const canEncodeFallback = await canEncodeAudio(fallbackMediabunnyCodec, {
        bitrate
      });
      if (canEncodeFallback) {
        issues.push({
          type: "audio-codec-unsupported",
          message: `Falling back from audio codec "${audioCodec}" to "${fallbackCodec}" because the original codec cannot be encoded by this browser.`,
          severity: "warning"
        });
        return { codec: fallbackCodec, issues };
      }
    }
  }
  issues.push({
    type: "audio-codec-unsupported",
    message: `No audio codec can be encoded by this browser for container "${container}".`,
    severity: "error"
  });
  return { codec: null, issues };
};

// src/validate-dimensions.ts
var validateDimensions = (options) => {
  const { width, height, codec } = options;
  if (codec === "h264" || codec === "h265") {
    if (width % 2 !== 0 || height % 2 !== 0) {
      return {
        type: "invalid-dimensions",
        message: `${codec.toUpperCase()} codec requires width and height to be multiples of 2. Got ${width}x${height}`,
        severity: "error"
      };
    }
  }
  return null;
};

// src/can-render-media-on-web.ts
var canRenderMediaOnWeb = async (options) => {
  const issues = [];
  if (typeof VideoEncoder === "undefined") {
    issues.push({
      type: "webcodecs-unavailable",
      message: "WebCodecs API is not available in this browser. A modern browser with WebCodecs support is required.",
      severity: "error"
    });
  }
  const container = options.container ?? "mp4";
  const videoCodec = options.videoCodec ?? getDefaultVideoCodecForContainer(container);
  const transparent = options.transparent ?? false;
  const muted = options.muted ?? false;
  const { width, height } = options;
  const resolvedVideoBitrate = typeof options.videoBitrate === "number" ? options.videoBitrate : getQualityForWebRendererQuality(options.videoBitrate ?? "medium");
  const resolvedAudioBitrate = typeof options.audioBitrate === "number" ? options.audioBitrate : getQualityForWebRendererQuality(options.audioBitrate ?? "medium");
  const format = containerToMediabunnyContainer(container);
  if (!format.getSupportedCodecs().includes(codecToMediabunnyCodec(videoCodec))) {
    issues.push({
      type: "container-codec-mismatch",
      message: `Codec ${videoCodec} is not supported for container ${container}`,
      severity: "error"
    });
  }
  const dimensionIssue = validateDimensions({ width, height, codec: videoCodec });
  if (dimensionIssue) {
    issues.push(dimensionIssue);
  }
  const canEncodeVideoResult = await esm_canEncodeVideo(codecToMediabunnyCodec(videoCodec), { bitrate: resolvedVideoBitrate });
  if (!canEncodeVideoResult) {
    issues.push({
      type: "video-codec-unsupported",
      message: `Video codec "${videoCodec}" cannot be encoded by this browser`,
      severity: "error"
    });
  }
  if (transparent && !["vp8", "vp9"].includes(videoCodec)) {
    issues.push({
      type: "transparent-video-unsupported",
      message: `Transparent video requires VP8 or VP9 codec with WebM container. ${videoCodec} does not support alpha channel.`,
      severity: "error"
    });
  }
  let resolvedAudioCodec = null;
  if (!muted) {
    const audioResult = await resolveAudioCodec({
      container,
      requestedCodec: options.audioCodec,
      userSpecifiedAudioCodec: options.audioCodec !== undefined && options.audioCodec !== null,
      bitrate: resolvedAudioBitrate
    });
    resolvedAudioCodec = audioResult.codec;
    issues.push(...audioResult.issues);
  }
  const webglIssue = checkWebGLSupport();
  if (webglIssue) {
    issues.push(webglIssue);
  }
  const canUseWebFs = await canUseWebFsWriter();
  let resolvedOutputTarget;
  if (options.outputTarget === "web-fs") {
    if (!canUseWebFs) {
      issues.push({
        type: "output-target-unsupported",
        message: 'The "web-fs" output target is not supported in this browser. The File System Access API is required.',
        severity: "error"
      });
    }
    resolvedOutputTarget = "web-fs";
  } else if (options.outputTarget === "arraybuffer") {
    resolvedOutputTarget = "arraybuffer";
  } else {
    resolvedOutputTarget = canUseWebFs ? "web-fs" : "arraybuffer";
  }
  return {
    canRender: issues.filter((i) => i.severity === "error").length === 0,
    issues,
    resolvedVideoCodec: videoCodec,
    resolvedAudioCodec,
    resolvedOutputTarget
  };
};
// src/get-encodable-codecs.ts

var esm_getEncodableVideoCodecs = async (container, options) => {
  const supported = getSupportedVideoCodecsForContainer(container);
  const mediabunnyCodecs = supported.map(codecToMediabunnyCodec);
  const resolvedBitrate = options?.videoBitrate ? typeof options.videoBitrate === "number" ? options.videoBitrate : getQualityForWebRendererQuality(options.videoBitrate) : undefined;
  const encodable = await getEncodableVideoCodecs(mediabunnyCodecs, {
    bitrate: resolvedBitrate
  });
  return supported.filter((c) => encodable.includes(codecToMediabunnyCodec(c)));
};
var esm_getEncodableAudioCodecs = async (container, options) => {
  const supported = getSupportedAudioCodecsForContainer(container);
  const resolvedBitrate = options?.audioBitrate ? typeof options.audioBitrate === "number" ? options.audioBitrate : getQualityForWebRendererQuality(options.audioBitrate) : undefined;
  const encodable = await getEncodableAudioCodecs(supported, {
    bitrate: resolvedBitrate
  });
  return supported.filter((c) => encodable.includes(c));
};
// src/render-media-on-web.tsx




// src/add-sample.ts

var addVideoSampleAndCloseFrame = async (frameToEncode, videoSampleSource) => {
  const sample = new src_sample/* VideoSample */.U2(frameToEncode);
  try {
    await videoSampleSource.add(sample);
  } finally {
    sample.close();
    frameToEncode.close();
  }
};
var addAudioSample = async (audio, audioSampleSource) => {
  const sample = new src_sample/* AudioSample */.B1(audio);
  try {
    await audioSampleSource.add(sample);
  } finally {
    sample.close();
  }
};

// src/artifact.ts

var onlyArtifact = async ({
  assets,
  frameBuffer
}) => {
  const artifacts = assets.filter((asset) => asset.type === "artifact");
  let frameBufferUint8 = null;
  const result = [];
  for (const artifact of artifacts) {
    if (artifact.contentType === "binary" || artifact.contentType === "text") {
      result.push({
        frame: artifact.frame,
        content: artifact.content,
        filename: artifact.filename,
        downloadBehavior: artifact.downloadBehavior
      });
      continue;
    }
    if (artifact.contentType === "thumbnail") {
      if (frameBuffer === null) {
        continue;
      }
      const ab = frameBuffer instanceof Blob ? await frameBuffer.arrayBuffer() : new Uint8Array(await (await frameBuffer.convertToBlob({ type: "image/png" })).arrayBuffer());
      frameBufferUint8 = new Uint8Array(ab);
      result.push({
        frame: artifact.frame,
        content: frameBufferUint8,
        filename: artifact.filename,
        downloadBehavior: artifact.downloadBehavior
      });
      continue;
    }
    throw new Error("Unknown artifact type: " + artifact);
  }
  return result.filter(no_react.NoReactInternals.truthy);
};
var handleArtifacts = () => {
  const previousArtifacts = [];
  const handle = async ({
    imageData,
    frame,
    assets: artifactAssets,
    onArtifact
  }) => {
    const artifacts = await onlyArtifact({
      assets: artifactAssets,
      frameBuffer: imageData
    });
    for (const artifact of artifacts) {
      const previousArtifact = previousArtifacts.find((a) => a.filename === artifact.filename);
      if (previousArtifact) {
        throw new Error(`An artifact with output "${artifact.filename}" was already registered at frame ${previousArtifact.frame}, but now registered again at frame ${frame}. Artifacts must have unique names. https://remotion.dev/docs/artifacts`);
      }
      onArtifact(artifact);
      previousArtifacts.push({ frame, filename: artifact.filename });
    }
  };
  return { handle };
};

// src/audio.ts
var TARGET_NUMBER_OF_CHANNELS = 2;
var TARGET_SAMPLE_RATE = 48000;
function mixAudio(waves, length) {
  if (waves.length === 1 && waves[0].length === length) {
    return waves[0];
  }
  const mixed = new Int16Array(length);
  if (waves.length === 1) {
    mixed.set(waves[0].subarray(0, length));
    return mixed;
  }
  for (let i = 0;i < length; i++) {
    const sum = waves.reduce((acc, wave) => {
      return acc + (wave[i] ?? 0);
    }, 0);
    mixed[i] = Math.max(-32768, Math.min(32767, sum));
  }
  return mixed;
}
var onlyInlineAudio = ({
  assets,
  fps,
  timestamp
}) => {
  const inlineAudio = assets.filter((asset) => asset.type === "inline-audio");
  if (inlineAudio.length === 0) {
    return null;
  }
  const expectedLength = Math.round(TARGET_NUMBER_OF_CHANNELS * TARGET_SAMPLE_RATE / fps);
  for (const asset of inlineAudio) {
    if (asset.toneFrequency !== 1) {
      throw new Error("Setting the toneFrequency is not supported yet in web rendering.");
    }
  }
  const mixedAudio = mixAudio(inlineAudio.map((asset) => asset.audio), expectedLength);
  return new AudioData({
    data: mixedAudio,
    format: "s16",
    numberOfChannels: TARGET_NUMBER_OF_CHANNELS,
    numberOfFrames: expectedLength / TARGET_NUMBER_OF_CHANNELS,
    sampleRate: TARGET_SAMPLE_RATE,
    timestamp
  });
};

// src/background-keepalive.ts

var WORKER_CODE = `
let intervalId = null;
self.onmessage = (e) => {
	if (e.data.type === 'start') {
		if (intervalId !== null) {
			clearInterval(intervalId);
		}
		intervalId = setInterval(() => self.postMessage('tick'), e.data.intervalMs);
	} else if (e.data.type === 'stop') {
		if (intervalId !== null) {
			clearInterval(intervalId);
			intervalId = null;
		}
	}
};
`;
function createBackgroundKeepalive({
  fps,
  logLevel
}) {
  const intervalMs = Math.round(1000 / fps);
  let pendingResolvers = [];
  let worker = null;
  let disposed = false;
  if (typeof Worker === "undefined") {
    esm.Internals.Log.warn({ logLevel, tag: "@remotion/web-renderer" }, "Web Workers not available. Rendering may pause when tab is backgrounded.");
    return {
      waitForTick: () => {
        return new Promise((resolve) => {
          setTimeout(resolve, intervalMs);
        });
      },
      [Symbol.dispose]: () => {}
    };
  }
  const blob = new Blob([WORKER_CODE], { type: "application/javascript" });
  const workerUrl = URL.createObjectURL(blob);
  worker = new Worker(workerUrl);
  worker.onmessage = () => {
    const resolvers = pendingResolvers;
    pendingResolvers = [];
    for (const resolve of resolvers) {
      resolve();
    }
  };
  worker.onerror = (event) => {
    esm.Internals.Log.error({ logLevel, tag: "@remotion/web-renderer" }, "Background keepalive worker encountered an error and will be terminated.", event);
    const resolvers = pendingResolvers;
    pendingResolvers = [];
    for (const resolve of resolvers) {
      resolve();
    }
    if (!disposed) {
      disposed = true;
      worker?.terminate();
      worker = null;
      URL.revokeObjectURL(workerUrl);
    }
  };
  worker.postMessage({ type: "start", intervalMs });
  return {
    waitForTick: () => {
      return new Promise((resolve) => {
        pendingResolvers.push(resolve);
      });
    },
    [Symbol.dispose]: () => {
      if (disposed) {
        return;
      }
      disposed = true;
      worker?.postMessage({ type: "stop" });
      worker?.terminate();
      worker = null;
      URL.revokeObjectURL(workerUrl);
      const resolvers = pendingResolvers;
      pendingResolvers = [];
      for (const resolve of resolvers) {
        resolve();
      }
    }
  };
}

// src/create-audio-sample-source.ts

var createAudioSampleSource = ({
  muted,
  codec,
  bitrate
}) => {
  if (muted || codec === null) {
    return null;
  }
  const audioSampleSource = new AudioSampleSource({
    codec,
    bitrate
  });
  return { audioSampleSource, [Symbol.dispose]: () => audioSampleSource.close() };
};

// src/create-scaffold.tsx





// src/update-time.tsx




var UpdateTime = ({
  children,
  audioEnabled,
  videoEnabled,
  logLevel,
  compId,
  initialFrame,
  timeUpdater
}) => {
  const [frame, setFrame] = (0,react.useState)(initialFrame);
  (0,react.useImperativeHandle)(timeUpdater, () => ({
    update: (f) => {
      (0,react_dom.flushSync)(() => {
        setFrame(f);
      });
    }
  }));
  return /* @__PURE__ */ (0,jsx_runtime.jsx)(esm.Internals.RemotionRootContexts, {
    audioEnabled,
    videoEnabled,
    logLevel,
    numberOfAudioTags: 0,
    audioLatencyHint: "interactive",
    frameState: {
      [compId]: frame
    },
    nonceContextSeed: 0,
    children
  });
};

// src/create-scaffold.tsx

function checkForError(errorHolder) {
  if (errorHolder.error) {
    throw errorHolder.error;
  }
}
function createScaffold({
  width,
  height,
  delayRenderTimeoutInMilliseconds,
  logLevel,
  resolvedProps,
  id,
  mediaCacheSizeInBytes,
  durationInFrames,
  fps,
  initialFrame,
  schema,
  Component,
  audioEnabled,
  videoEnabled,
  defaultCodec,
  defaultOutName
}) {
  if (!client.createRoot) {
    throw new Error("@remotion/web-renderer requires React 18 or higher");
  }
  const div = document.createElement("div");
  div.style.position = "fixed";
  div.style.display = "flex";
  div.style.flexDirection = "column";
  div.style.backgroundColor = "transparent";
  div.style.width = `${width}px`;
  div.style.height = `${height}px`;
  div.style.zIndex = "-9999";
  div.style.top = "0";
  div.style.left = "0";
  div.style.right = "0";
  div.style.bottom = "0";
  div.style.visibility = "hidden";
  div.style.pointerEvents = "none";
  const scaffoldClassName = `remotion-scaffold-${Math.random().toString(36).substring(2, 15)}`;
  div.className = scaffoldClassName;
  const cleanupCSS = esm.Internals.CSSUtils.injectCSS(esm.Internals.CSSUtils.makeDefaultPreviewCSS(`.${scaffoldClassName}`, "white"));
  document.body.appendChild(div);
  const errorHolder = { error: null };
  const root = client.createRoot(div, {
    onUncaughtError: (err) => {
      errorHolder.error = err instanceof Error ? err : new Error(String(err));
    }
  });
  const delayRenderScope = {
    remotion_renderReady: true,
    remotion_delayRenderTimeouts: {},
    remotion_puppeteerTimeout: delayRenderTimeoutInMilliseconds,
    remotion_attempt: 0,
    remotion_delayRenderHandles: []
  };
  const timeUpdater = (0,react.createRef)();
  const collectAssets = (0,react.createRef)();
  (0,react_dom.flushSync)(() => {
    root.render(/* @__PURE__ */ (0,jsx_runtime.jsx)(esm.Internals.MaxMediaCacheSizeContext.Provider, {
      value: mediaCacheSizeInBytes,
      children: /* @__PURE__ */ (0,jsx_runtime.jsx)(esm.Internals.RemotionEnvironmentContext.Provider, {
        value: {
          isStudio: false,
          isRendering: true,
          isPlayer: false,
          isReadOnlyStudio: false,
          isClientSideRendering: true
        },
        children: /* @__PURE__ */ (0,jsx_runtime.jsx)(esm.Internals.DelayRenderContextType.Provider, {
          value: delayRenderScope,
          children: /* @__PURE__ */ (0,jsx_runtime.jsx)(esm.Internals.CompositionManager.Provider, {
            value: {
              compositions: [
                {
                  id,
                  component: Component,
                  nonce: 0,
                  defaultProps: {},
                  folderName: null,
                  parentFolderName: null,
                  schema: schema ?? null,
                  calculateMetadata: null,
                  durationInFrames,
                  fps,
                  height,
                  width
                }
              ],
              canvasContent: {
                type: "composition",
                compositionId: id
              },
              currentCompositionMetadata: {
                props: resolvedProps,
                durationInFrames,
                fps,
                height,
                width,
                defaultCodec: defaultCodec ?? null,
                defaultOutName: defaultOutName ?? null,
                defaultVideoImageFormat: null,
                defaultPixelFormat: null,
                defaultProResProfile: null
              },
              folders: []
            },
            children: /* @__PURE__ */ (0,jsx_runtime.jsx)(esm.Internals.RenderAssetManagerProvider, {
              collectAssets,
              children: /* @__PURE__ */ (0,jsx_runtime.jsx)(UpdateTime, {
                audioEnabled,
                videoEnabled,
                logLevel,
                compId: id,
                initialFrame,
                timeUpdater,
                children: /* @__PURE__ */ (0,jsx_runtime.jsx)(esm.Internals.CanUseRemotionHooks.Provider, {
                  value: true,
                  children: /* @__PURE__ */ (0,jsx_runtime.jsx)(Component, {
                    ...resolvedProps
                  })
                })
              })
            })
          })
        })
      })
    }));
  });
  return {
    delayRenderScope,
    div,
    errorHolder,
    [Symbol.dispose]: () => {
      root.unmount();
      div.remove();
      cleanupCSS();
    },
    timeUpdater,
    collectAssets
  };
}

// src/frame-range.ts
var getRealFrameRange = (durationInFrames, frameRange) => {
  if (frameRange === null) {
    return [0, durationInFrames - 1];
  }
  if (typeof frameRange === "number") {
    if (frameRange < 0 || frameRange >= durationInFrames) {
      throw new Error(`Frame number is out of range, must be between 0 and ${durationInFrames - 1} but got ${frameRange}`);
    }
    return [frameRange, frameRange];
  }
  const resolved = [
    frameRange[0],
    frameRange[1] === null ? durationInFrames - 1 : frameRange[1]
  ];
  if (resolved[0] < 0 || resolved[1] >= durationInFrames || resolved[0] > resolved[1]) {
    throw new Error(`The "durationInFrames" of the composition was evaluated to be ${durationInFrames}, but frame range ${resolved.join("-")} is not inbetween 0-${durationInFrames - 1}`);
  }
  return resolved;
};

// src/internal-state.ts
var makeInternalState = () => {
  let drawnPrecomposedPixels = 0;
  let precomposedTextures = 0;
  let waitForReadyTime = 0;
  let addSampleTime = 0;
  let createFrameTime = 0;
  let audioMixingTime = 0;
  const helperCanvasState = {
    current: null
  };
  return {
    getDrawn3dPixels: () => drawnPrecomposedPixels,
    getPrecomposedTiles: () => precomposedTextures,
    addPrecompose: ({
      canvasWidth,
      canvasHeight
    }) => {
      drawnPrecomposedPixels += canvasWidth * canvasHeight;
      precomposedTextures++;
    },
    helperCanvasState,
    [Symbol.dispose]: () => {
      if (helperCanvasState.current) {
        helperCanvasState.current.cleanup();
      }
    },
    getWaitForReadyTime: () => waitForReadyTime,
    addWaitForReadyTime: (time) => {
      waitForReadyTime += time;
    },
    getAddSampleTime: () => addSampleTime,
    addAddSampleTime: (time) => {
      addSampleTime += time;
    },
    getCreateFrameTime: () => createFrameTime,
    addCreateFrameTime: (time) => {
      createFrameTime += time;
    },
    getAudioMixingTime: () => audioMixingTime,
    addAudioMixingTime: (time) => {
      audioMixingTime += time;
    }
  };
};

// src/mediabunny-cleanups.ts

var makeOutputWithCleanup = (options) => {
  const output = new Output(options);
  return {
    output,
    [Symbol.dispose]: () => {
      if (output.state === "finalized" || output.state === "canceled") {
        return;
      }
      output.cancel();
    }
  };
};
var makeVideoSampleSourceCleanup = (encodingConfig) => {
  const videoSampleSource = new VideoSampleSource(encodingConfig);
  return {
    videoSampleSource,
    [Symbol.dispose]: () => {
      videoSampleSource.close();
    }
  };
};

// src/render-operations-queue.ts
var onlyOneRenderAtATimeQueue = {
  ref: Promise.resolve()
};

// ../licensing/dist/esm/index.mjs
function isNetworkError(error) {
  if (error.message.includes("Failed to fetch") || error.message.includes("Load failed") || error.message.includes("NetworkError when attempting to fetch resource")) {
    return true;
  }
  return false;
}
var HOST = "https://www.remotion.pro";
var DEFAULT_MAX_RETRIES = 3;
var exponentialBackoffMs = (attempt) => {
  return 1000 * 2 ** (attempt - 1);
};
var sleep = (ms) => {
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  });
};
var internalRegisterUsageEvent = async ({
  host,
  succeeded,
  event,
  isStill,
  isProduction,
  licenseKey
}) => {
  let lastError;
  const totalAttempts = DEFAULT_MAX_RETRIES + 1;
  for (let attempt = 1;attempt <= totalAttempts; attempt++) {
    const abortController = new AbortController;
    const timeout = setTimeout(() => {
      abortController.abort();
    }, 1e4);
    try {
      const res = await fetch(`${HOST}/api/track/register-usage-point`, {
        method: "POST",
        body: JSON.stringify({
          event,
          apiKey: licenseKey,
          host,
          succeeded,
          isStill,
          isProduction
        }),
        headers: {
          "Content-Type": "application/json"
        },
        signal: abortController.signal
      });
      clearTimeout(timeout);
      const json = await res.json();
      if (json.success) {
        return {
          billable: json.billable,
          classification: json.classification
        };
      }
      if (!res.ok) {
        throw new Error(json.error);
      }
      throw new Error(`Unexpected response from server: ${JSON.stringify(json)}`);
    } catch (err) {
      clearTimeout(timeout);
      const error = err;
      const isTimeout = error.name === "AbortError";
      const isRetryable = isNetworkError(error) || isTimeout;
      if (!isRetryable) {
        throw err;
      }
      lastError = isTimeout ? new Error("Request timed out after 10 seconds") : error;
      if (attempt < totalAttempts) {
        const backoffMs = exponentialBackoffMs(attempt);
        console.log(`Failed to send usage event (attempt ${attempt}/${totalAttempts}), retrying in ${backoffMs}ms...`, err);
        await sleep(backoffMs);
      }
    }
  }
  throw lastError;
};
var LicensingInternals = {
  internalRegisterUsageEvent
};

// src/send-telemetry-event.ts

var sendUsageEvent = async ({
  licenseKey,
  succeeded,
  apiName,
  isStill,
  isProduction
}) => {
  const host = typeof window === "undefined" ? null : typeof window.location === "undefined" ? null : window.location.origin ?? null;
  if (host === null) {
    return;
  }
  if (licenseKey === null) {
    esm.Internals.Log.warn({ logLevel: "warn", tag: "web-renderer" }, `Pass "licenseKey" to ${apiName}(). If you qualify for the Free License (https://remotion.dev/license), pass "free-license" instead.`);
  }
  await LicensingInternals.internalRegisterUsageEvent({
    licenseKey: licenseKey === "free-license" ? null : licenseKey,
    event: "web-render",
    host,
    succeeded,
    isStill,
    isProduction
  });
};

// src/tree-walker-cleanup-after-children.ts
var createTreeWalkerCleanupAfterChildren = (treeWalker) => {
  const cleanupAfterChildren = [];
  const checkCleanUpAtBeginningOfIteration = () => {
    for (let i = 0;i < cleanupAfterChildren.length; ) {
      const cleanup = cleanupAfterChildren[i];
      if (!(cleanup.element === treeWalker.currentNode || cleanup.element.contains(treeWalker.currentNode))) {
        cleanup.cleanupFn();
        cleanupAfterChildren.splice(i, 1);
      } else {
        i++;
      }
    }
  };
  const addCleanup = (element, cleanupFn) => {
    cleanupAfterChildren.unshift({
      element,
      cleanupFn
    });
  };
  const cleanupInTheEndOfTheIteration = () => {
    for (const cleanup of cleanupAfterChildren) {
      cleanup.cleanupFn();
    }
  };
  return {
    checkCleanUpAtBeginningOfIteration,
    addCleanup,
    [Symbol.dispose]: cleanupInTheEndOfTheIteration
  };
};

// src/drawing/calculate-object-fit.ts
var calculateFill = ({
  containerSize,
  intrinsicSize
}) => {
  return {
    sourceX: 0,
    sourceY: 0,
    sourceWidth: intrinsicSize.width,
    sourceHeight: intrinsicSize.height,
    destX: containerSize.left,
    destY: containerSize.top,
    destWidth: containerSize.width,
    destHeight: containerSize.height
  };
};
var calculateContain = ({
  containerSize,
  intrinsicSize
}) => {
  const containerAspect = containerSize.width / containerSize.height;
  const imageAspect = intrinsicSize.width / intrinsicSize.height;
  let destWidth;
  let destHeight;
  if (imageAspect > containerAspect) {
    destWidth = containerSize.width;
    destHeight = containerSize.width / imageAspect;
  } else {
    destHeight = containerSize.height;
    destWidth = containerSize.height * imageAspect;
  }
  const destX = containerSize.left + (containerSize.width - destWidth) / 2;
  const destY = containerSize.top + (containerSize.height - destHeight) / 2;
  return {
    sourceX: 0,
    sourceY: 0,
    sourceWidth: intrinsicSize.width,
    sourceHeight: intrinsicSize.height,
    destX,
    destY,
    destWidth,
    destHeight
  };
};
var calculateCover = ({
  containerSize,
  intrinsicSize
}) => {
  if (containerSize.height <= 0 || intrinsicSize.height <= 0) {
    return {
      sourceX: 0,
      sourceY: 0,
      sourceWidth: 0,
      sourceHeight: 0,
      destX: containerSize.left,
      destY: containerSize.top,
      destWidth: 0,
      destHeight: 0
    };
  }
  const containerAspect = containerSize.width / containerSize.height;
  const imageAspect = intrinsicSize.width / intrinsicSize.height;
  let sourceX = 0;
  let sourceY = 0;
  let sourceWidth = intrinsicSize.width;
  let sourceHeight = intrinsicSize.height;
  if (imageAspect > containerAspect) {
    sourceWidth = intrinsicSize.height * containerAspect;
    sourceX = (intrinsicSize.width - sourceWidth) / 2;
  } else {
    sourceHeight = intrinsicSize.width / containerAspect;
    sourceY = (intrinsicSize.height - sourceHeight) / 2;
  }
  return {
    sourceX,
    sourceY,
    sourceWidth,
    sourceHeight,
    destX: containerSize.left,
    destY: containerSize.top,
    destWidth: containerSize.width,
    destHeight: containerSize.height
  };
};
var calculateNone = ({
  containerSize,
  intrinsicSize
}) => {
  const centeredX = containerSize.left + (containerSize.width - intrinsicSize.width) / 2;
  const centeredY = containerSize.top + (containerSize.height - intrinsicSize.height) / 2;
  let sourceX = 0;
  let sourceY = 0;
  let sourceWidth = intrinsicSize.width;
  let sourceHeight = intrinsicSize.height;
  let destX = centeredX;
  let destY = centeredY;
  let destWidth = intrinsicSize.width;
  let destHeight = intrinsicSize.height;
  if (destX < containerSize.left) {
    const clipAmount = containerSize.left - destX;
    sourceX = clipAmount;
    sourceWidth -= clipAmount;
    destX = containerSize.left;
    destWidth -= clipAmount;
  }
  if (destY < containerSize.top) {
    const clipAmount = containerSize.top - destY;
    sourceY = clipAmount;
    sourceHeight -= clipAmount;
    destY = containerSize.top;
    destHeight -= clipAmount;
  }
  const containerRight = containerSize.left + containerSize.width;
  if (destX + destWidth > containerRight) {
    const clipAmount = destX + destWidth - containerRight;
    sourceWidth -= clipAmount;
    destWidth -= clipAmount;
  }
  const containerBottom = containerSize.top + containerSize.height;
  if (destY + destHeight > containerBottom) {
    const clipAmount = destY + destHeight - containerBottom;
    sourceHeight -= clipAmount;
    destHeight -= clipAmount;
  }
  return {
    sourceX,
    sourceY,
    sourceWidth,
    sourceHeight,
    destX,
    destY,
    destWidth,
    destHeight
  };
};
var calculateObjectFit = ({
  objectFit,
  containerSize,
  intrinsicSize
}) => {
  switch (objectFit) {
    case "fill":
      return calculateFill({ containerSize, intrinsicSize });
    case "contain":
      return calculateContain({ containerSize, intrinsicSize });
    case "cover":
      return calculateCover({ containerSize, intrinsicSize });
    case "none":
      return calculateNone({ containerSize, intrinsicSize });
    case "scale-down": {
      const containResult = calculateContain({ containerSize, intrinsicSize });
      const noneResult = calculateNone({ containerSize, intrinsicSize });
      const containArea = containResult.destWidth * containResult.destHeight;
      const noneArea = noneResult.destWidth * noneResult.destHeight;
      return containArea < noneArea ? containResult : noneResult;
    }
    default: {
      const exhaustiveCheck = objectFit;
      throw new Error(`Unknown object-fit value: ${exhaustiveCheck}`);
    }
  }
};
var parseObjectFit = (value) => {
  if (!value) {
    return "fill";
  }
  const normalized = value.trim().toLowerCase();
  switch (normalized) {
    case "fill":
    case "contain":
    case "cover":
    case "none":
    case "scale-down":
      return normalized;
    default:
      return "fill";
  }
};

// src/drawing/fit-svg-into-its-dimensions.ts
var fitSvgIntoItsContainer = ({
  containerSize,
  elementSize
}) => {
  if (Math.round(containerSize.width) === Math.round(elementSize.width) && Math.round(containerSize.height) === Math.round(elementSize.height)) {
    return {
      width: containerSize.width,
      height: containerSize.height,
      top: containerSize.top,
      left: containerSize.left
    };
  }
  if (containerSize.width <= 0 || containerSize.height <= 0) {
    throw new Error(`Container must have positive dimensions, but got ${containerSize.width}x${containerSize.height}`);
  }
  if (elementSize.width <= 0 || elementSize.height <= 0) {
    throw new Error(`Element must have positive dimensions, but got ${elementSize.width}x${elementSize.height}`);
  }
  const heightRatio = containerSize.height / elementSize.height;
  const widthRatio = containerSize.width / elementSize.width;
  const ratio = Math.min(heightRatio, widthRatio);
  const newWidth = elementSize.width * ratio;
  const newHeight = elementSize.height * ratio;
  if (newWidth > containerSize.width + 0.000001 || newHeight > containerSize.height + 0.000001) {
    throw new Error(`Element is too big to fit into the container. Max size: ${containerSize.width}x${containerSize.height}, element size: ${newWidth}x${newHeight}`);
  }
  return {
    width: newWidth,
    height: newHeight,
    top: (containerSize.height - newHeight) / 2 + containerSize.top,
    left: (containerSize.width - newWidth) / 2 + containerSize.left
  };
};

// src/drawing/turn-svg-into-drawable.ts
var turnSvgIntoDrawable = (svg) => {
  const { fill, color } = getComputedStyle(svg);
  const originalTransform = svg.style.transform;
  const originalTransformOrigin = svg.style.transformOrigin;
  const originalMarginLeft = svg.style.marginLeft;
  const originalMarginRight = svg.style.marginRight;
  const originalMarginTop = svg.style.marginTop;
  const originalMarginBottom = svg.style.marginBottom;
  const originalFill = svg.style.fill;
  const originalColor = svg.style.color;
  svg.style.transform = "none";
  svg.style.transformOrigin = "";
  svg.style.marginLeft = "0";
  svg.style.marginRight = "0";
  svg.style.marginTop = "0";
  svg.style.marginBottom = "0";
  svg.style.fill = fill;
  svg.style.color = color;
  const svgData = new XMLSerializer().serializeToString(svg);
  svg.style.marginLeft = originalMarginLeft;
  svg.style.marginRight = originalMarginRight;
  svg.style.marginTop = originalMarginTop;
  svg.style.marginBottom = originalMarginBottom;
  svg.style.transform = originalTransform;
  svg.style.transformOrigin = originalTransformOrigin;
  svg.style.fill = originalFill;
  svg.style.color = originalColor;
  return new Promise((resolve, reject) => {
    const image = new Image;
    const url = `data:image/svg+xml;base64,${btoa(svgData)}`;
    image.onload = function() {
      resolve(image);
    };
    image.onerror = () => {
      reject(new Error("Failed to convert SVG to image"));
    };
    image.src = url;
  });
};

// src/drawing/draw-dom-element.ts
var getReadableImageError = (err, node) => {
  if (!(err instanceof DOMException)) {
    return null;
  }
  if (err.name === "SecurityError") {
    return new Error(`Could not draw image with src="${node.src}" to canvas: ` + `The image is tainted due to CORS restrictions. ` + `The server hosting this image must respond with the "Access-Control-Allow-Origin" header. ` + `See: https://remotion.dev/docs/client-side-rendering/migration`);
  }
  if (err.name === "InvalidStateError") {
    return new Error(`Could not draw image with src="${node.src}" to canvas: ` + `The image is in a broken state. ` + `This usually means the image failed to load - check that the URL is valid and accessible.`);
  }
  return null;
};
var drawSvg = ({
  drawable,
  dimensions,
  contextToDraw
}) => {
  const fitted = fitSvgIntoItsContainer({
    containerSize: dimensions,
    elementSize: {
      width: drawable.width,
      height: drawable.height
    }
  });
  contextToDraw.drawImage(drawable, fitted.left, fitted.top, fitted.width, fitted.height);
};
var drawReplacedElement = ({
  drawable,
  dimensions,
  computedStyle,
  contextToDraw
}) => {
  const objectFit = parseObjectFit(computedStyle.objectFit);
  const intrinsicSize = drawable instanceof HTMLImageElement ? { width: drawable.naturalWidth, height: drawable.naturalHeight } : { width: drawable.width, height: drawable.height };
  const result = calculateObjectFit({
    objectFit,
    containerSize: {
      width: dimensions.width,
      height: dimensions.height,
      left: dimensions.left,
      top: dimensions.top
    },
    intrinsicSize
  });
  contextToDraw.drawImage(drawable, result.sourceX, result.sourceY, result.sourceWidth, result.sourceHeight, result.destX, result.destY, result.destWidth, result.destHeight);
};
var drawDomElement = (node) => {
  const domDrawFn = async ({
    dimensions,
    contextToDraw,
    computedStyle
  }) => {
    if (node instanceof SVGSVGElement) {
      const drawable = await turnSvgIntoDrawable(node);
      drawSvg({ drawable, dimensions, contextToDraw });
      return;
    }
    if (node instanceof HTMLImageElement || node instanceof HTMLCanvasElement) {
      try {
        drawReplacedElement({
          drawable: node,
          dimensions,
          computedStyle,
          contextToDraw
        });
      } catch (err) {
        if (node instanceof HTMLImageElement) {
          const readableError = getReadableImageError(err, node);
          if (readableError) {
            throw readableError;
          }
        }
        throw err;
      }
    }
  };
  return domDrawFn;
};

// src/drawing/process-node.ts


// src/drawing/has-transform.ts
var hasTransformCssValue = (style) => {
  return style.transform !== "none" && style.transform !== "";
};
var hasRotateCssValue = (style) => {
  return style.rotate !== "none" && style.rotate !== "";
};
var hasScaleCssValue = (style) => {
  return style.scale !== "none" && style.scale !== "";
};
var hasAnyTransformCssValue = (style) => {
  return hasTransformCssValue(style) || hasRotateCssValue(style) || hasScaleCssValue(style);
};

// src/drawing/parse-linear-gradient.ts

var isValidColor = (color) => {
  try {
    const result = no_react.NoReactInternals.processColor(color);
    return result !== null && result !== undefined;
  } catch {
    return false;
  }
};
var parseDirection = (directionStr) => {
  const trimmed = directionStr.trim().toLowerCase();
  if (trimmed.startsWith("to ")) {
    const direction = trimmed.substring(3).trim();
    switch (direction) {
      case "top":
        return 0;
      case "right":
        return 90;
      case "bottom":
        return 180;
      case "left":
        return 270;
      case "top right":
      case "right top":
        return 45;
      case "bottom right":
      case "right bottom":
        return 135;
      case "bottom left":
      case "left bottom":
        return 225;
      case "top left":
      case "left top":
        return 315;
      default:
        return 180;
    }
  }
  const angleMatch = trimmed.match(/^(-?\d+\.?\d*)(deg|rad|grad|turn)$/);
  if (angleMatch) {
    const value = parseFloat(angleMatch[1]);
    const unit = angleMatch[2];
    switch (unit) {
      case "deg":
        return value;
      case "rad":
        return value * 180 / Math.PI;
      case "grad":
        return value * 360 / 400;
      case "turn":
        return value * 360;
      default:
        return value;
    }
  }
  return 180;
};
var parseColorStops = (colorStopsStr) => {
  const parts = colorStopsStr.split(/,(?![^(]*\))/);
  const stops = [];
  for (const part of parts) {
    const trimmed = part.trim();
    if (!trimmed)
      continue;
    const colorMatch = trimmed.match(/(rgba?\([^)]+\)|hsla?\([^)]+\)|#[0-9a-f]{3,8}|[a-z]+)/i);
    if (!colorMatch) {
      continue;
    }
    const colorStr = colorMatch[0];
    if (!isValidColor(colorStr)) {
      continue;
    }
    const remaining = trimmed.substring(colorMatch.index + colorStr.length).trim();
    const normalizedColor = colorStr;
    let position = null;
    if (remaining) {
      const posMatch = remaining.match(/(-?\d+\.?\d*)(%|px)?/);
      if (posMatch) {
        const value = parseFloat(posMatch[1]);
        const unit = posMatch[2];
        if (unit === "%") {
          position = value / 100;
        } else if (unit === "px") {
          position = null;
        } else {
          position = value / 100;
        }
      }
    }
    stops.push({
      color: normalizedColor,
      position: position !== null ? position : -1
    });
  }
  if (stops.length === 0) {
    return null;
  }
  let lastExplicitIndex = -1;
  let lastExplicitPosition = 0;
  for (let i = 0;i < stops.length; i++) {
    if (stops[i].position !== -1) {
      if (lastExplicitIndex >= 0) {
        const numImplicit = i - lastExplicitIndex - 1;
        if (numImplicit > 0) {
          const step = (stops[i].position - lastExplicitPosition) / (numImplicit + 1);
          for (let j = lastExplicitIndex + 1;j < i; j++) {
            stops[j].position = lastExplicitPosition + step * (j - lastExplicitIndex);
          }
        }
      } else {
        const numImplicit = i;
        if (numImplicit > 0) {
          const step = stops[i].position / (numImplicit + 1);
          for (let j = 0;j < i; j++) {
            stops[j].position = step * (j + 1);
          }
        }
      }
      lastExplicitIndex = i;
      lastExplicitPosition = stops[i].position;
    }
  }
  if (stops.every((s) => s.position === -1)) {
    if (stops.length === 1) {
      stops[0].position = 0.5;
    } else {
      for (let i = 0;i < stops.length; i++) {
        stops[i].position = i / (stops.length - 1);
      }
    }
  } else if (lastExplicitIndex < stops.length - 1) {
    const numImplicit = stops.length - 1 - lastExplicitIndex;
    const step = (1 - lastExplicitPosition) / (numImplicit + 1);
    for (let i = lastExplicitIndex + 1;i < stops.length; i++) {
      stops[i].position = lastExplicitPosition + step * (i - lastExplicitIndex);
    }
  }
  for (const stop of stops) {
    stop.position = Math.max(0, Math.min(1, stop.position));
  }
  return stops;
};
var extractGradientContent = (backgroundImage) => {
  const prefix = "linear-gradient(";
  const startIndex = backgroundImage.toLowerCase().indexOf(prefix);
  if (startIndex === -1) {
    return null;
  }
  let depth = 0;
  const contentStart = startIndex + prefix.length;
  for (let i = contentStart;i < backgroundImage.length; i++) {
    const char = backgroundImage[i];
    if (char === "(") {
      depth++;
    } else if (char === ")") {
      if (depth === 0) {
        return backgroundImage.substring(contentStart, i).trim();
      }
      depth--;
    }
  }
  return null;
};
var parseLinearGradient = (backgroundImage) => {
  if (!backgroundImage || backgroundImage === "none") {
    return null;
  }
  const content = extractGradientContent(backgroundImage);
  if (!content) {
    return null;
  }
  const parts = content.split(/,(?![^(]*\))/);
  let angle = 180;
  let colorStopsStart = 0;
  if (parts.length > 0) {
    const firstPart = parts[0].trim();
    const isDirection = firstPart.startsWith("to ") || /^-?\d+\.?\d*(deg|rad|grad|turn)$/.test(firstPart);
    if (isDirection) {
      angle = parseDirection(firstPart);
      colorStopsStart = 1;
    }
  }
  const colorStopsStr = parts.slice(colorStopsStart).join(",");
  const colorStops = parseColorStops(colorStopsStr);
  if (!colorStops || colorStops.length === 0) {
    return null;
  }
  return {
    angle,
    colorStops
  };
};
var createCanvasGradient = ({
  ctx,
  rect,
  gradientInfo,
  offsetLeft,
  offsetTop
}) => {
  const angleRad = (gradientInfo.angle - 90) * Math.PI / 180;
  const centerX = rect.left - offsetLeft + rect.width / 2;
  const centerY = rect.top - offsetTop + rect.height / 2;
  const cos = Math.cos(angleRad);
  const sin = Math.sin(angleRad);
  const halfWidth = rect.width / 2;
  const halfHeight = rect.height / 2;
  let length = Math.abs(cos) * halfWidth + Math.abs(sin) * halfHeight;
  if (!Number.isFinite(length) || length === 0) {
    length = Math.sqrt(halfWidth ** 2 + halfHeight ** 2);
  }
  const x0 = centerX - cos * length;
  const y0 = centerY - sin * length;
  const x1 = centerX + cos * length;
  const y1 = centerY + sin * length;
  const gradient = ctx.createLinearGradient(x0, y0, x1, y1);
  for (const stop of gradientInfo.colorStops) {
    gradient.addColorStop(stop.position, stop.color);
  }
  return gradient;
};

// src/drawing/mask-image.ts
var getMaskImageValue = (computedStyle) => {
  const { maskImage, webkitMaskImage } = computedStyle;
  const value = maskImage || webkitMaskImage;
  if (!value || value === "none") {
    return null;
  }
  return value;
};
var parseMaskImage = (maskImageValue) => {
  return parseLinearGradient(maskImageValue);
};

// src/drawing/parse-transform-origin.ts
var parseTransformOrigin = (transformOrigin) => {
  if (transformOrigin.trim() === "") {
    return null;
  }
  const [x, y] = transformOrigin.split(" ");
  return { x: parseFloat(x), y: parseFloat(y) };
};

// src/drawing/calculate-transforms.ts
var getInternalTransformOrigin = (transform) => {
  const centerX = transform.boundingClientRect.width / 2;
  const centerY = transform.boundingClientRect.height / 2;
  const origin = parseTransformOrigin(transform.transformOrigin) ?? {
    x: centerX,
    y: centerY
  };
  return origin;
};
var getGlobalTransformOrigin = ({ transform }) => {
  const { x: originX, y: originY } = getInternalTransformOrigin(transform);
  return {
    x: originX + transform.boundingClientRect.left,
    y: originY + transform.boundingClientRect.top
  };
};
var calculateTransforms = ({
  element,
  rootElement
}) => {
  let parent = element;
  const transforms = [];
  const toReset = [];
  let opacity = 1;
  let elementComputedStyle = null;
  let maskImageInfo = null;
  while (parent) {
    const computedStyle = getComputedStyle(parent);
    if (parent === element) {
      elementComputedStyle = computedStyle;
      opacity = parseFloat(computedStyle.opacity);
      const maskImageValue = getMaskImageValue(computedStyle);
      maskImageInfo = maskImageValue ? parseMaskImage(maskImageValue) : null;
      const originalMaskImage = parent.style.maskImage;
      const originalWebkitMaskImage = parent.style.webkitMaskImage;
      parent.style.maskImage = "none";
      parent.style.webkitMaskImage = "none";
      const parentRef = parent;
      toReset.push(() => {
        parentRef.style.maskImage = originalMaskImage;
        parentRef.style.webkitMaskImage = originalWebkitMaskImage;
      });
    }
    if (hasAnyTransformCssValue(computedStyle) || parent === element) {
      const toParse = hasTransformCssValue(computedStyle) ? computedStyle.transform : undefined;
      const matrix = new DOMMatrix(toParse);
      const { transform, scale, rotate } = parent.style;
      const additionalMatrices = [];
      if (rotate !== "" && rotate !== "none") {
        additionalMatrices.push(new DOMMatrix(`rotate(${rotate})`));
      }
      if (scale !== "" && scale !== "none") {
        additionalMatrices.push(new DOMMatrix(`scale(${scale})`));
      }
      additionalMatrices.push(matrix);
      parent.style.transform = "none";
      parent.style.scale = "none";
      parent.style.rotate = "none";
      transforms.push({
        element: parent,
        transformOrigin: computedStyle.transformOrigin,
        boundingClientRect: null,
        matrices: additionalMatrices
      });
      const parentRef = parent;
      toReset.push(() => {
        parentRef.style.transform = transform;
        parentRef.style.scale = scale;
        parentRef.style.rotate = rotate;
      });
    }
    if (parent === rootElement) {
      break;
    }
    parent = parent.parentElement;
  }
  for (const transform of transforms) {
    transform.boundingClientRect = transform.element.getBoundingClientRect();
  }
  const dimensions = transforms[0].boundingClientRect;
  const nativeTransformOrigin = getInternalTransformOrigin(transforms[0]);
  const totalMatrix = new DOMMatrix;
  for (const transform of transforms.slice().reverse()) {
    for (const matrix of transform.matrices) {
      const globalTransformOrigin = getGlobalTransformOrigin({
        transform
      });
      const transformMatrix = new DOMMatrix().translate(globalTransformOrigin.x, globalTransformOrigin.y).multiply(matrix).translate(-globalTransformOrigin.x, -globalTransformOrigin.y);
      totalMatrix.multiplySelf(transformMatrix);
    }
  }
  if (!elementComputedStyle) {
    throw new Error("Element computed style not found");
  }
  const needs3DTransformViaWebGL = !totalMatrix.is2D;
  const needsMaskImage = maskImageInfo !== null;
  return {
    dimensions,
    totalMatrix,
    [Symbol.dispose]: () => {
      for (const reset of toReset) {
        reset();
      }
    },
    nativeTransformOrigin,
    computedStyle: elementComputedStyle,
    opacity,
    maskImageInfo,
    precompositing: {
      needs3DTransformViaWebGL,
      needsMaskImage: maskImageInfo,
      needsPrecompositing: Boolean(needs3DTransformViaWebGL || needsMaskImage)
    }
  };
};

// src/drawing/round-to-expand-rect.ts
var roundToExpandRect = (rect) => {
  const left = Math.floor(rect.left);
  const top = Math.floor(rect.top);
  const right = Math.ceil(rect.right);
  const bottom = Math.ceil(rect.bottom);
  return new DOMRect(left, top, right - left, bottom - top);
};

// src/drawing/clamp-rect-to-parent-bounds.ts
var getNarrowerRect = ({
  firstRect,
  secondRect
}) => {
  const left = Math.max(firstRect.left, secondRect.left);
  const top = Math.max(firstRect.top, secondRect.top);
  const bottom = Math.min(firstRect.bottom, secondRect.bottom);
  const right = Math.min(firstRect.right, secondRect.right);
  return new DOMRect(left, top, right - left, bottom - top);
};
var getWiderRectAndExpand = ({
  firstRect,
  secondRect
}) => {
  if (firstRect === null) {
    return roundToExpandRect(secondRect);
  }
  const left = Math.min(firstRect.left, secondRect.left);
  const top = Math.min(firstRect.top, secondRect.top);
  const bottom = Math.max(firstRect.bottom, secondRect.bottom);
  const right = Math.max(firstRect.right, secondRect.right);
  return roundToExpandRect(new DOMRect(left, top, right - left, bottom - top));
};

// src/drawing/do-rects-intersect.ts
function doRectsIntersect(rect1, rect2) {
  return !(rect1.right <= rect2.left || rect1.left >= rect2.right || rect1.bottom <= rect2.top || rect1.top >= rect2.bottom);
}

// src/drawing/draw-rounded.ts
var drawRoundedRectPath = ({
  ctx,
  x,
  y,
  width,
  height,
  borderRadius
}) => {
  ctx.beginPath();
  ctx.moveTo(x + borderRadius.topLeft.horizontal, y);
  ctx.lineTo(x + width - borderRadius.topRight.horizontal, y);
  if (borderRadius.topRight.horizontal > 0 || borderRadius.topRight.vertical > 0) {
    ctx.ellipse(x + width - borderRadius.topRight.horizontal, y + borderRadius.topRight.vertical, borderRadius.topRight.horizontal, borderRadius.topRight.vertical, 0, -Math.PI / 2, 0);
  }
  ctx.lineTo(x + width, y + height - borderRadius.bottomRight.vertical);
  if (borderRadius.bottomRight.horizontal > 0 || borderRadius.bottomRight.vertical > 0) {
    ctx.ellipse(x + width - borderRadius.bottomRight.horizontal, y + height - borderRadius.bottomRight.vertical, borderRadius.bottomRight.horizontal, borderRadius.bottomRight.vertical, 0, 0, Math.PI / 2);
  }
  ctx.lineTo(x + borderRadius.bottomLeft.horizontal, y + height);
  if (borderRadius.bottomLeft.horizontal > 0 || borderRadius.bottomLeft.vertical > 0) {
    ctx.ellipse(x + borderRadius.bottomLeft.horizontal, y + height - borderRadius.bottomLeft.vertical, borderRadius.bottomLeft.horizontal, borderRadius.bottomLeft.vertical, 0, Math.PI / 2, Math.PI);
  }
  ctx.lineTo(x, y + borderRadius.topLeft.vertical);
  if (borderRadius.topLeft.horizontal > 0 || borderRadius.topLeft.vertical > 0) {
    ctx.ellipse(x + borderRadius.topLeft.horizontal, y + borderRadius.topLeft.vertical, borderRadius.topLeft.horizontal, borderRadius.topLeft.vertical, 0, Math.PI, Math.PI * 3 / 2);
  }
  ctx.closePath();
};

// src/drawing/get-padding-box.ts
var getPaddingBox = (rect, computedStyle) => {
  const borderLeft = parseFloat(computedStyle.borderLeftWidth);
  const borderRight = parseFloat(computedStyle.borderRightWidth);
  const borderTop = parseFloat(computedStyle.borderTopWidth);
  const borderBottom = parseFloat(computedStyle.borderBottomWidth);
  return new DOMRect(rect.left + borderLeft, rect.top + borderTop, rect.width - borderLeft - borderRight, rect.height - borderTop - borderBottom);
};
var getContentBox = (rect, computedStyle) => {
  const paddingBox = getPaddingBox(rect, computedStyle);
  const paddingLeft = parseFloat(computedStyle.paddingLeft);
  const paddingRight = parseFloat(computedStyle.paddingRight);
  const paddingTop = parseFloat(computedStyle.paddingTop);
  const paddingBottom = parseFloat(computedStyle.paddingBottom);
  return new DOMRect(paddingBox.left + paddingLeft, paddingBox.top + paddingTop, paddingBox.width - paddingLeft - paddingRight, paddingBox.height - paddingTop - paddingBottom);
};
var getBoxBasedOnBackgroundClip = (rect, computedStyle, backgroundClip) => {
  if (!backgroundClip) {
    return rect;
  }
  if (backgroundClip.includes("text")) {
    return rect;
  }
  if (backgroundClip.includes("padding-box")) {
    return getPaddingBox(rect, computedStyle);
  }
  if (backgroundClip.includes("content-box")) {
    return getContentBox(rect, computedStyle);
  }
  return rect;
};

// src/drawing/border-radius.ts
function parseValue({
  value,
  reference
}) {
  value = value.trim();
  if (value.endsWith("%")) {
    const percentage = parseFloat(value);
    return percentage / 100 * reference;
  }
  if (value.endsWith("px")) {
    return parseFloat(value);
  }
  return parseFloat(value);
}
function expandShorthand(values) {
  if (values.length === 1) {
    return [values[0], values[0], values[0], values[0]];
  }
  if (values.length === 2) {
    return [values[0], values[1], values[0], values[1]];
  }
  if (values.length === 3) {
    return [values[0], values[1], values[2], values[1]];
  }
  return [values[0], values[1], values[2], values[3]];
}
function clampBorderRadius({
  borderRadius,
  width,
  height
}) {
  const clamped = {
    topLeft: { ...borderRadius.topLeft },
    topRight: { ...borderRadius.topRight },
    bottomRight: { ...borderRadius.bottomRight },
    bottomLeft: { ...borderRadius.bottomLeft }
  };
  const topSum = clamped.topLeft.horizontal + clamped.topRight.horizontal;
  if (topSum > width) {
    const factor = width / topSum;
    clamped.topLeft.horizontal *= factor;
    clamped.topRight.horizontal *= factor;
  }
  const rightSum = clamped.topRight.vertical + clamped.bottomRight.vertical;
  if (rightSum > height) {
    const factor = height / rightSum;
    clamped.topRight.vertical *= factor;
    clamped.bottomRight.vertical *= factor;
  }
  const bottomSum = clamped.bottomRight.horizontal + clamped.bottomLeft.horizontal;
  if (bottomSum > width) {
    const factor = width / bottomSum;
    clamped.bottomRight.horizontal *= factor;
    clamped.bottomLeft.horizontal *= factor;
  }
  const leftSum = clamped.bottomLeft.vertical + clamped.topLeft.vertical;
  if (leftSum > height) {
    const factor = height / leftSum;
    clamped.bottomLeft.vertical *= factor;
    clamped.topLeft.vertical *= factor;
  }
  return clamped;
}
function parseBorderRadius({
  borderRadius,
  width,
  height
}) {
  const parts = borderRadius.split("/").map((part) => part.trim());
  const horizontalPart = parts[0];
  const verticalPart = parts[1];
  const horizontalValues = horizontalPart.split(/\s+/).filter((v) => v);
  const verticalValues = verticalPart ? verticalPart.split(/\s+/).filter((v) => v) : horizontalValues;
  const [hTopLeft, hTopRight, hBottomRight, hBottomLeft] = expandShorthand(horizontalValues);
  const [vTopLeft, vTopRight, vBottomRight, vBottomLeft] = expandShorthand(verticalValues);
  return clampBorderRadius({
    borderRadius: {
      topLeft: {
        horizontal: parseValue({ value: hTopLeft, reference: width }),
        vertical: parseValue({ value: vTopLeft, reference: height })
      },
      topRight: {
        horizontal: parseValue({ value: hTopRight, reference: width }),
        vertical: parseValue({ value: vTopRight, reference: height })
      },
      bottomRight: {
        horizontal: parseValue({ value: hBottomRight, reference: width }),
        vertical: parseValue({ value: vBottomRight, reference: height })
      },
      bottomLeft: {
        horizontal: parseValue({ value: hBottomLeft, reference: width }),
        vertical: parseValue({ value: vBottomLeft, reference: height })
      }
    },
    width,
    height
  });
}
function setBorderRadius({
  ctx,
  rect,
  borderRadius,
  forceClipEvenWhenZero = false,
  computedStyle,
  backgroundClip
}) {
  if (borderRadius.topLeft.horizontal === 0 && borderRadius.topLeft.vertical === 0 && borderRadius.topRight.horizontal === 0 && borderRadius.topRight.vertical === 0 && borderRadius.bottomRight.horizontal === 0 && borderRadius.bottomRight.vertical === 0 && borderRadius.bottomLeft.horizontal === 0 && borderRadius.bottomLeft.vertical === 0 && !forceClipEvenWhenZero) {
    return () => {};
  }
  ctx.save();
  const boundingRect = getBoxBasedOnBackgroundClip(rect, computedStyle, backgroundClip);
  const actualBorderRadius = {
    topLeft: {
      horizontal: Math.max(0, borderRadius.topLeft.horizontal - (boundingRect.left - rect.left)),
      vertical: Math.max(0, borderRadius.topLeft.vertical - (boundingRect.top - rect.top))
    },
    topRight: {
      horizontal: Math.max(0, borderRadius.topRight.horizontal - (rect.right - boundingRect.right)),
      vertical: Math.max(0, borderRadius.topRight.vertical - (boundingRect.top - rect.top))
    },
    bottomRight: {
      horizontal: Math.max(0, borderRadius.bottomRight.horizontal - (rect.right - boundingRect.right)),
      vertical: Math.max(0, borderRadius.bottomRight.vertical - (rect.bottom - boundingRect.bottom))
    },
    bottomLeft: {
      horizontal: Math.max(0, borderRadius.bottomLeft.horizontal - (boundingRect.left - rect.left)),
      vertical: Math.max(0, borderRadius.bottomLeft.vertical - (rect.bottom - boundingRect.bottom))
    }
  };
  drawRoundedRectPath({
    ctx,
    x: boundingRect.left,
    y: boundingRect.top,
    width: boundingRect.width,
    height: boundingRect.height,
    borderRadius: actualBorderRadius
  });
  ctx.clip();
  return () => {
    ctx.restore();
  };
}

// src/drawing/get-background-fill.ts
var isColorTransparent = (color) => {
  return color === "transparent" || color.startsWith("rgba") && (color.endsWith(", 0)") || color.endsWith(",0"));
};
var getBackgroundFill = ({
  backgroundColor,
  backgroundImage,
  contextToDraw,
  boundingRect,
  offsetLeft,
  offsetTop
}) => {
  if (backgroundImage && backgroundImage !== "none") {
    const gradientInfo = parseLinearGradient(backgroundImage);
    if (gradientInfo) {
      const gradient = createCanvasGradient({
        ctx: contextToDraw,
        rect: boundingRect,
        gradientInfo,
        offsetLeft,
        offsetTop
      });
      return gradient;
    }
  }
  if (backgroundColor && backgroundColor !== "transparent" && !isColorTransparent(backgroundColor)) {
    return backgroundColor;
  }
  return null;
};

// src/drawing/draw-background.ts
var drawBackground = async ({
  backgroundImage,
  context,
  rect,
  backgroundColor,
  backgroundClip,
  element,
  logLevel,
  internalState,
  computedStyle,
  offsetLeft: parentOffsetLeft,
  offsetTop: parentOffsetTop,
  scale
}) => {
  let __stack = [];
  try {
    let contextToDraw = context;
    const originalCompositeOperation = context.globalCompositeOperation;
    let offsetLeft = 0;
    let offsetTop = 0;
    const _ = __using(__stack, {
      [Symbol.dispose]: () => {
        context.globalCompositeOperation = originalCompositeOperation;
        if (context !== contextToDraw) {
          context.drawImage(contextToDraw.canvas, offsetLeft, offsetTop, contextToDraw.canvas.width / scale, contextToDraw.canvas.height / scale);
        }
      }
    }, 0);
    const boundingRect = getBoxBasedOnBackgroundClip(rect, computedStyle, backgroundClip);
    if (backgroundClip.includes("text")) {
      offsetLeft = boundingRect.left;
      offsetTop = boundingRect.top;
      const originalBackgroundClip = element.style.backgroundClip;
      const originalWebkitBackgroundClip = element.style.webkitBackgroundClip;
      element.style.backgroundClip = "initial";
      element.style.webkitBackgroundClip = "initial";
      const onlyBackgroundClipText = await createLayer({
        element,
        cutout: new DOMRect(boundingRect.left + parentOffsetLeft, boundingRect.top + parentOffsetTop, boundingRect.width, boundingRect.height),
        logLevel,
        internalState,
        scale,
        onlyBackgroundClipText: true
      });
      onlyBackgroundClipText.setTransform(new DOMMatrix().scale(scale, scale));
      element.style.backgroundClip = originalBackgroundClip;
      element.style.webkitBackgroundClip = originalWebkitBackgroundClip;
      contextToDraw = onlyBackgroundClipText;
      contextToDraw.globalCompositeOperation = "source-in";
    }
    const backgroundFill = getBackgroundFill({
      backgroundImage,
      backgroundColor,
      contextToDraw,
      boundingRect,
      offsetLeft,
      offsetTop
    });
    if (!backgroundFill) {
      return;
    }
    const originalFillStyle = contextToDraw.fillStyle;
    contextToDraw.fillStyle = backgroundFill;
    contextToDraw.fillRect(boundingRect.left - offsetLeft, boundingRect.top - offsetTop, boundingRect.width, boundingRect.height);
    contextToDraw.fillStyle = originalFillStyle;
  } catch (_catch) {
    var _err = _catch, _hasErr = 1;
  } finally {
    __callDispose(__stack, _err, _hasErr);
  }
};

// src/drawing/draw-border.ts
var parseBorderWidth = (value) => {
  return parseFloat(value) || 0;
};
var getBorderSideProperties = (computedStyle) => {
  return {
    top: {
      width: parseBorderWidth(computedStyle.borderTopWidth),
      color: computedStyle.borderTopColor || computedStyle.borderColor || "black",
      style: computedStyle.borderTopStyle || computedStyle.borderStyle || "solid"
    },
    right: {
      width: parseBorderWidth(computedStyle.borderRightWidth),
      color: computedStyle.borderRightColor || computedStyle.borderColor || "black",
      style: computedStyle.borderRightStyle || computedStyle.borderStyle || "solid"
    },
    bottom: {
      width: parseBorderWidth(computedStyle.borderBottomWidth),
      color: computedStyle.borderBottomColor || computedStyle.borderColor || "black",
      style: computedStyle.borderBottomStyle || computedStyle.borderStyle || "solid"
    },
    left: {
      width: parseBorderWidth(computedStyle.borderLeftWidth),
      color: computedStyle.borderLeftColor || computedStyle.borderColor || "black",
      style: computedStyle.borderLeftStyle || computedStyle.borderStyle || "solid"
    }
  };
};
var getLineDashPattern = (style, width) => {
  if (style === "dashed") {
    return [width * 2, width];
  }
  if (style === "dotted") {
    return [width, width];
  }
  return [];
};
var drawBorderSide = ({
  ctx,
  side,
  x,
  y,
  width,
  height,
  borderRadius,
  borderProperties
}) => {
  const { width: borderWidth, color, style } = borderProperties;
  if (borderWidth <= 0 || style === "none" || style === "hidden") {
    return;
  }
  ctx.beginPath();
  ctx.strokeStyle = color;
  ctx.lineWidth = borderWidth;
  ctx.setLineDash(getLineDashPattern(style, borderWidth));
  const halfWidth = borderWidth / 2;
  if (side === "top") {
    const startX = x + borderRadius.topLeft.horizontal;
    const startY = y + halfWidth;
    const endX = x + width - borderRadius.topRight.horizontal;
    const endY = y + halfWidth;
    ctx.moveTo(startX, startY);
    ctx.lineTo(endX, endY);
  } else if (side === "right") {
    const startX = x + width - halfWidth;
    const startY = y + borderRadius.topRight.vertical;
    const endX = x + width - halfWidth;
    const endY = y + height - borderRadius.bottomRight.vertical;
    ctx.moveTo(startX, startY);
    ctx.lineTo(endX, endY);
  } else if (side === "bottom") {
    const startX = x + borderRadius.bottomLeft.horizontal;
    const startY = y + height - halfWidth;
    const endX = x + width - borderRadius.bottomRight.horizontal;
    const endY = y + height - halfWidth;
    ctx.moveTo(startX, startY);
    ctx.lineTo(endX, endY);
  } else if (side === "left") {
    const startX = x + halfWidth;
    const startY = y + borderRadius.topLeft.vertical;
    const endX = x + halfWidth;
    const endY = y + height - borderRadius.bottomLeft.vertical;
    ctx.moveTo(startX, startY);
    ctx.lineTo(endX, endY);
  }
  ctx.stroke();
};
var drawCorner = ({
  ctx,
  corner,
  x,
  y,
  width,
  height,
  borderRadius,
  topBorder,
  rightBorder,
  bottomBorder,
  leftBorder
}) => {
  const radius = borderRadius[corner];
  if (radius.horizontal <= 0 && radius.vertical <= 0) {
    return;
  }
  let border1;
  let border2;
  let centerX;
  let centerY;
  let startAngle;
  let endAngle;
  if (corner === "topLeft") {
    border1 = leftBorder;
    border2 = topBorder;
    centerX = x + radius.horizontal;
    centerY = y + radius.vertical;
    startAngle = Math.PI;
    endAngle = Math.PI * 3 / 2;
  } else if (corner === "topRight") {
    border1 = topBorder;
    border2 = rightBorder;
    centerX = x + width - radius.horizontal;
    centerY = y + radius.vertical;
    startAngle = -Math.PI / 2;
    endAngle = 0;
  } else if (corner === "bottomRight") {
    border1 = rightBorder;
    border2 = bottomBorder;
    centerX = x + width - radius.horizontal;
    centerY = y + height - radius.vertical;
    startAngle = 0;
    endAngle = Math.PI / 2;
  } else {
    border1 = bottomBorder;
    border2 = leftBorder;
    centerX = x + radius.horizontal;
    centerY = y + height - radius.vertical;
    startAngle = Math.PI / 2;
    endAngle = Math.PI;
  }
  const avgWidth = (border1.width + border2.width) / 2;
  const useColor = border1.width >= border2.width ? border1.color : border2.color;
  const useStyle = border1.width >= border2.width ? border1.style : border2.style;
  if (avgWidth > 0 && useStyle !== "none" && useStyle !== "hidden") {
    ctx.beginPath();
    ctx.strokeStyle = useColor;
    ctx.lineWidth = avgWidth;
    ctx.setLineDash(getLineDashPattern(useStyle, avgWidth));
    const adjustedRadiusH = Math.max(0, radius.horizontal - avgWidth / 2);
    const adjustedRadiusV = Math.max(0, radius.vertical - avgWidth / 2);
    ctx.ellipse(centerX, centerY, adjustedRadiusH, adjustedRadiusV, 0, startAngle, endAngle);
    ctx.stroke();
  }
};
var drawUniformBorder = ({
  ctx,
  x,
  y,
  width,
  height,
  borderRadius,
  borderWidth,
  borderColor,
  borderStyle
}) => {
  ctx.beginPath();
  ctx.strokeStyle = borderColor;
  ctx.lineWidth = borderWidth;
  ctx.setLineDash(getLineDashPattern(borderStyle, borderWidth));
  const halfWidth = borderWidth / 2;
  const borderX = x + halfWidth;
  const borderY = y + halfWidth;
  const borderW = width - borderWidth;
  const borderH = height - borderWidth;
  const adjustedBorderRadius = {
    topLeft: {
      horizontal: Math.max(0, borderRadius.topLeft.horizontal - halfWidth),
      vertical: Math.max(0, borderRadius.topLeft.vertical - halfWidth)
    },
    topRight: {
      horizontal: Math.max(0, borderRadius.topRight.horizontal - halfWidth),
      vertical: Math.max(0, borderRadius.topRight.vertical - halfWidth)
    },
    bottomRight: {
      horizontal: Math.max(0, borderRadius.bottomRight.horizontal - halfWidth),
      vertical: Math.max(0, borderRadius.bottomRight.vertical - halfWidth)
    },
    bottomLeft: {
      horizontal: Math.max(0, borderRadius.bottomLeft.horizontal - halfWidth),
      vertical: Math.max(0, borderRadius.bottomLeft.vertical - halfWidth)
    }
  };
  ctx.moveTo(borderX + adjustedBorderRadius.topLeft.horizontal, borderY);
  ctx.lineTo(borderX + borderW - adjustedBorderRadius.topRight.horizontal, borderY);
  if (adjustedBorderRadius.topRight.horizontal > 0 || adjustedBorderRadius.topRight.vertical > 0) {
    ctx.ellipse(borderX + borderW - adjustedBorderRadius.topRight.horizontal, borderY + adjustedBorderRadius.topRight.vertical, adjustedBorderRadius.topRight.horizontal, adjustedBorderRadius.topRight.vertical, 0, -Math.PI / 2, 0);
  }
  ctx.lineTo(borderX + borderW, borderY + borderH - adjustedBorderRadius.bottomRight.vertical);
  if (adjustedBorderRadius.bottomRight.horizontal > 0 || adjustedBorderRadius.bottomRight.vertical > 0) {
    ctx.ellipse(borderX + borderW - adjustedBorderRadius.bottomRight.horizontal, borderY + borderH - adjustedBorderRadius.bottomRight.vertical, adjustedBorderRadius.bottomRight.horizontal, adjustedBorderRadius.bottomRight.vertical, 0, 0, Math.PI / 2);
  }
  ctx.lineTo(borderX + adjustedBorderRadius.bottomLeft.horizontal, borderY + borderH);
  if (adjustedBorderRadius.bottomLeft.horizontal > 0 || adjustedBorderRadius.bottomLeft.vertical > 0) {
    ctx.ellipse(borderX + adjustedBorderRadius.bottomLeft.horizontal, borderY + borderH - adjustedBorderRadius.bottomLeft.vertical, adjustedBorderRadius.bottomLeft.horizontal, adjustedBorderRadius.bottomLeft.vertical, 0, Math.PI / 2, Math.PI);
  }
  ctx.lineTo(borderX, borderY + adjustedBorderRadius.topLeft.vertical);
  if (adjustedBorderRadius.topLeft.horizontal > 0 || adjustedBorderRadius.topLeft.vertical > 0) {
    ctx.ellipse(borderX + adjustedBorderRadius.topLeft.horizontal, borderY + adjustedBorderRadius.topLeft.vertical, adjustedBorderRadius.topLeft.horizontal, adjustedBorderRadius.topLeft.vertical, 0, Math.PI, Math.PI * 3 / 2);
  }
  ctx.closePath();
  ctx.stroke();
};
var drawBorder = ({
  ctx,
  rect,
  borderRadius,
  computedStyle
}) => {
  const borders = getBorderSideProperties(computedStyle);
  const hasBorder = borders.top.width > 0 || borders.right.width > 0 || borders.bottom.width > 0 || borders.left.width > 0;
  if (!hasBorder) {
    return;
  }
  const originalStrokeStyle = ctx.strokeStyle;
  const originalLineWidth = ctx.lineWidth;
  const originalLineDash = ctx.getLineDash();
  const allSidesEqual = borders.top.width === borders.right.width && borders.top.width === borders.bottom.width && borders.top.width === borders.left.width && borders.top.color === borders.right.color && borders.top.color === borders.bottom.color && borders.top.color === borders.left.color && borders.top.style === borders.right.style && borders.top.style === borders.bottom.style && borders.top.style === borders.left.style && borders.top.width > 0;
  if (allSidesEqual) {
    drawUniformBorder({
      ctx,
      x: rect.left,
      y: rect.top,
      width: rect.width,
      height: rect.height,
      borderRadius,
      borderWidth: borders.top.width,
      borderColor: borders.top.color,
      borderStyle: borders.top.style
    });
  } else {
    drawCorner({
      ctx,
      corner: "topLeft",
      x: rect.left,
      y: rect.top,
      width: rect.width,
      height: rect.height,
      borderRadius,
      topBorder: borders.top,
      rightBorder: borders.right,
      bottomBorder: borders.bottom,
      leftBorder: borders.left
    });
    drawCorner({
      ctx,
      corner: "topRight",
      x: rect.left,
      y: rect.top,
      width: rect.width,
      height: rect.height,
      borderRadius,
      topBorder: borders.top,
      rightBorder: borders.right,
      bottomBorder: borders.bottom,
      leftBorder: borders.left
    });
    drawCorner({
      ctx,
      corner: "bottomRight",
      x: rect.left,
      y: rect.top,
      width: rect.width,
      height: rect.height,
      borderRadius,
      topBorder: borders.top,
      rightBorder: borders.right,
      bottomBorder: borders.bottom,
      leftBorder: borders.left
    });
    drawCorner({
      ctx,
      corner: "bottomLeft",
      x: rect.left,
      y: rect.top,
      width: rect.width,
      height: rect.height,
      borderRadius,
      topBorder: borders.top,
      rightBorder: borders.right,
      bottomBorder: borders.bottom,
      leftBorder: borders.left
    });
    drawBorderSide({
      ctx,
      side: "top",
      x: rect.left,
      y: rect.top,
      width: rect.width,
      height: rect.height,
      borderRadius,
      borderProperties: borders.top
    });
    drawBorderSide({
      ctx,
      side: "right",
      x: rect.left,
      y: rect.top,
      width: rect.width,
      height: rect.height,
      borderRadius,
      borderProperties: borders.right
    });
    drawBorderSide({
      ctx,
      side: "bottom",
      x: rect.left,
      y: rect.top,
      width: rect.width,
      height: rect.height,
      borderRadius,
      borderProperties: borders.bottom
    });
    drawBorderSide({
      ctx,
      side: "left",
      x: rect.left,
      y: rect.top,
      width: rect.width,
      height: rect.height,
      borderRadius,
      borderProperties: borders.left
    });
  }
  ctx.strokeStyle = originalStrokeStyle;
  ctx.lineWidth = originalLineWidth;
  ctx.setLineDash(originalLineDash);
};

// src/drawing/draw-box-shadow.ts


// src/drawing/parse-shadow.ts
var parseShadowValues = (shadowValue) => {
  if (!shadowValue || shadowValue === "none") {
    return [];
  }
  const shadows = [];
  const shadowStrings = shadowValue.split(/,(?![^(]*\))/);
  for (const shadowStr of shadowStrings) {
    const trimmed = shadowStr.trim();
    if (!trimmed || trimmed === "none") {
      continue;
    }
    const shadow = {
      offsetX: 0,
      offsetY: 0,
      blurRadius: 0,
      color: "rgba(0, 0, 0, 0.5)"
    };
    let remaining = trimmed.replace(/\binset\b/gi, "").trim();
    const colorMatch = remaining.match(/(rgba?\([^)]+\)|hsla?\([^)]+\)|#[0-9a-f]{3,8}|[a-z]+)/i);
    if (colorMatch) {
      shadow.color = colorMatch[0];
      remaining = remaining.replace(colorMatch[0], "").trim();
    }
    const numbers = remaining.match(/[+-]?\d*\.?\d+(?:px|em|rem|%)?/gi) || [];
    const values = numbers.map((n) => parseFloat(n) || 0);
    if (values.length >= 2) {
      shadow.offsetX = values[0];
      shadow.offsetY = values[1];
      if (values.length >= 3) {
        shadow.blurRadius = Math.max(0, values[2]);
      }
    }
    shadows.push(shadow);
  }
  return shadows;
};

// src/drawing/draw-box-shadow.ts
var parseBoxShadow = (boxShadowValue) => {
  if (!boxShadowValue || boxShadowValue === "none") {
    return [];
  }
  const baseShadows = parseShadowValues(boxShadowValue);
  const shadowStrings = boxShadowValue.split(/,(?![^(]*\))/);
  return baseShadows.map((base, i) => ({
    ...base,
    inset: /\binset\b/i.test(shadowStrings[i] || "")
  }));
};
var drawBorderRadius = ({
  ctx,
  rect,
  borderRadius,
  computedStyle,
  logLevel
}) => {
  const shadows = parseBoxShadow(computedStyle.boxShadow);
  if (shadows.length === 0) {
    return;
  }
  for (let i = shadows.length - 1;i >= 0; i--) {
    const shadow = shadows[i];
    const newLeft = rect.left + Math.min(shadow.offsetX, 0) - shadow.blurRadius;
    const newRight = rect.right + Math.max(shadow.offsetX, 0) + shadow.blurRadius;
    const newTop = rect.top + Math.min(shadow.offsetY, 0) - shadow.blurRadius;
    const newBottom = rect.bottom + Math.max(shadow.offsetY, 0) + shadow.blurRadius;
    const newRect = new DOMRect(newLeft, newTop, newRight - newLeft, newBottom - newTop);
    const leftOffset = rect.left - newLeft;
    const topOffset = rect.top - newTop;
    const newCanvas = new OffscreenCanvas(newRect.width, newRect.height);
    const newCtx = newCanvas.getContext("2d");
    if (!newCtx) {
      throw new Error("Failed to get context");
    }
    if (shadow.inset) {
      esm.Internals.Log.warn({
        logLevel,
        tag: "@remotion/web-renderer"
      }, 'Detected "box-shadow" with "inset". This is not yet supported in @remotion/web-renderer');
      continue;
    }
    newCtx.shadowBlur = shadow.blurRadius;
    newCtx.shadowColor = shadow.color;
    newCtx.shadowOffsetX = shadow.offsetX;
    newCtx.shadowOffsetY = shadow.offsetY;
    newCtx.fillStyle = "black";
    drawRoundedRectPath({
      ctx: newCtx,
      x: leftOffset,
      y: topOffset,
      width: rect.width,
      height: rect.height,
      borderRadius
    });
    newCtx.fill();
    newCtx.shadowColor = "transparent";
    newCtx.globalCompositeOperation = "destination-out";
    drawRoundedRectPath({
      ctx: newCtx,
      x: leftOffset,
      y: topOffset,
      width: rect.width,
      height: rect.height,
      borderRadius
    });
    newCtx.fill();
    ctx.drawImage(newCanvas, rect.left - leftOffset, rect.top - topOffset);
  }
};

// src/drawing/draw-outline.ts
var parseOutlineWidth = (value) => {
  return parseFloat(value) || 0;
};
var parseOutlineOffset = (value) => {
  return parseFloat(value) || 0;
};
var getLineDashPattern2 = (style, width) => {
  if (style === "dashed") {
    return [width * 2, width];
  }
  if (style === "dotted") {
    return [width, width];
  }
  return [];
};
var drawOutline = ({
  ctx,
  rect,
  borderRadius,
  computedStyle
}) => {
  const outlineWidth = parseOutlineWidth(computedStyle.outlineWidth);
  const { outlineStyle } = computedStyle;
  const outlineColor = computedStyle.outlineColor || "black";
  const outlineOffset = parseOutlineOffset(computedStyle.outlineOffset);
  if (outlineWidth <= 0 || outlineStyle === "none" || outlineStyle === "hidden") {
    return;
  }
  const originalStrokeStyle = ctx.strokeStyle;
  const originalLineWidth = ctx.lineWidth;
  const originalLineDash = ctx.getLineDash();
  ctx.strokeStyle = outlineColor;
  ctx.lineWidth = outlineWidth;
  ctx.setLineDash(getLineDashPattern2(outlineStyle, outlineWidth));
  const halfWidth = outlineWidth / 2;
  const offset = outlineOffset + halfWidth;
  const outlineX = rect.left - offset;
  const outlineY = rect.top - offset;
  const outlineW = rect.width + offset * 2;
  const outlineH = rect.height + offset * 2;
  const adjustedBorderRadius = {
    topLeft: {
      horizontal: borderRadius.topLeft.horizontal === 0 ? 0 : Math.max(0, borderRadius.topLeft.horizontal + offset),
      vertical: borderRadius.topLeft.vertical === 0 ? 0 : Math.max(0, borderRadius.topLeft.vertical + offset)
    },
    topRight: {
      horizontal: borderRadius.topRight.horizontal === 0 ? 0 : Math.max(0, borderRadius.topRight.horizontal + offset),
      vertical: borderRadius.topRight.vertical === 0 ? 0 : Math.max(0, borderRadius.topRight.vertical + offset)
    },
    bottomRight: {
      horizontal: borderRadius.bottomRight.horizontal === 0 ? 0 : Math.max(0, borderRadius.bottomRight.horizontal + offset),
      vertical: borderRadius.bottomRight.vertical === 0 ? 0 : Math.max(0, borderRadius.bottomRight.vertical + offset)
    },
    bottomLeft: {
      horizontal: borderRadius.bottomLeft.horizontal === 0 ? 0 : Math.max(0, borderRadius.bottomLeft.horizontal + offset),
      vertical: borderRadius.bottomLeft.vertical === 0 ? 0 : Math.max(0, borderRadius.bottomLeft.vertical + offset)
    }
  };
  drawRoundedRectPath({
    ctx,
    x: outlineX,
    y: outlineY,
    width: outlineW,
    height: outlineH,
    borderRadius: adjustedBorderRadius
  });
  ctx.stroke();
  ctx.strokeStyle = originalStrokeStyle;
  ctx.lineWidth = originalLineWidth;
  ctx.setLineDash(originalLineDash);
};

// src/drawing/opacity.ts
var setOpacity = ({
  ctx,
  opacity
}) => {
  const previousAlpha = ctx.globalAlpha;
  ctx.globalAlpha = previousAlpha * opacity;
  return () => {
    ctx.globalAlpha = previousAlpha;
  };
};

// src/drawing/overflow.ts
var setOverflowHidden = ({
  ctx,
  rect,
  borderRadius,
  overflowHidden,
  computedStyle,
  backgroundClip
}) => {
  if (!overflowHidden) {
    return () => {};
  }
  return setBorderRadius({
    ctx,
    rect,
    borderRadius,
    forceClipEvenWhenZero: true,
    computedStyle,
    backgroundClip
  });
};

// src/drawing/transform.ts
var setTransform = ({
  ctx,
  transform,
  parentRect,
  scale
}) => {
  const offsetMatrix = new DOMMatrix().scale(scale, scale).translate(-parentRect.x, -parentRect.y).multiply(transform).translate(parentRect.x, parentRect.y);
  ctx.setTransform(offsetMatrix);
  return () => {
    ctx.setTransform(new DOMMatrix);
  };
};

// src/drawing/draw-element.ts
var drawElement = async ({
  rect,
  computedStyle,
  context,
  draw,
  opacity,
  totalMatrix,
  parentRect,
  logLevel,
  element,
  internalState,
  scale
}) => {
  const { backgroundImage, backgroundColor, backgroundClip } = computedStyle;
  const borderRadius = parseBorderRadius({
    borderRadius: computedStyle.borderRadius,
    width: rect.width,
    height: rect.height
  });
  const finishTransform = setTransform({
    ctx: context,
    transform: totalMatrix,
    parentRect,
    scale
  });
  const finishOpacity = setOpacity({
    ctx: context,
    opacity
  });
  drawBorderRadius({
    ctx: context,
    computedStyle,
    rect,
    borderRadius,
    logLevel
  });
  const finishBorderRadius = setBorderRadius({
    ctx: context,
    rect,
    borderRadius,
    forceClipEvenWhenZero: false,
    computedStyle,
    backgroundClip
  });
  await drawBackground({
    backgroundImage,
    context,
    rect,
    backgroundColor,
    backgroundClip,
    element,
    logLevel,
    internalState,
    computedStyle,
    offsetLeft: parentRect.left,
    offsetTop: parentRect.top,
    scale
  });
  await draw({ dimensions: rect, computedStyle, contextToDraw: context });
  finishBorderRadius();
  drawBorder({
    ctx: context,
    rect,
    borderRadius,
    computedStyle
  });
  drawOutline({
    ctx: context,
    rect,
    borderRadius,
    computedStyle
  });
  const finishOverflowHidden = setOverflowHidden({
    ctx: context,
    rect,
    borderRadius,
    overflowHidden: computedStyle.overflow === "hidden",
    computedStyle,
    backgroundClip
  });
  finishTransform();
  return {
    cleanupAfterChildren: () => {
      finishOpacity();
      finishOverflowHidden();
    }
  };
};

// src/walk-tree.ts
function skipToNextNonDescendant(treeWalker) {
  if (treeWalker.nextSibling()) {
    return true;
  }
  while (treeWalker.parentNode()) {
    if (treeWalker.nextSibling()) {
      return true;
    }
  }
  return false;
}

// src/get-biggest-bounding-client-rect.ts
var getBiggestBoundingClientRect = (element) => {
  const treeWalker = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT);
  let mostLeft = Infinity;
  let mostTop = Infinity;
  let mostRight = -Infinity;
  let mostBottom = -Infinity;
  while (true) {
    const computedStyle = getComputedStyle(treeWalker.currentNode);
    const outlineWidth = parseOutlineWidth(computedStyle.outlineWidth);
    const outlineOffset = parseOutlineOffset(computedStyle.outlineOffset);
    const rect = treeWalker.currentNode.getBoundingClientRect();
    const shadows = parseBoxShadow(computedStyle.boxShadow);
    let shadowLeft = 0;
    let shadowRight = 0;
    let shadowTop = 0;
    let shadowBottom = 0;
    for (const shadow of shadows) {
      if (!shadow.inset) {
        shadowLeft = Math.max(shadowLeft, Math.abs(Math.min(shadow.offsetX, 0)) + shadow.blurRadius);
        shadowRight = Math.max(shadowRight, Math.max(shadow.offsetX, 0) + shadow.blurRadius);
        shadowTop = Math.max(shadowTop, Math.abs(Math.min(shadow.offsetY, 0)) + shadow.blurRadius);
        shadowBottom = Math.max(shadowBottom, Math.max(shadow.offsetY, 0) + shadow.blurRadius);
      }
    }
    mostLeft = Math.min(mostLeft, rect.left - outlineOffset - outlineWidth - shadowLeft);
    mostTop = Math.min(mostTop, rect.top - outlineOffset - outlineWidth - shadowTop);
    mostRight = Math.max(mostRight, rect.right + outlineOffset + outlineWidth + shadowRight);
    mostBottom = Math.max(mostBottom, rect.bottom + outlineOffset + outlineWidth + shadowBottom);
    if (computedStyle.overflow === "hidden") {
      if (!skipToNextNonDescendant(treeWalker)) {
        break;
      }
    }
    if (!treeWalker.nextNode()) {
      break;
    }
  }
  return new DOMRect(mostLeft, mostTop, mostRight - mostLeft, mostBottom - mostTop);
};

// src/drawing/get-pretransform-rect.ts
var MAX_SCALE_FACTOR = 100;
var isScaleTooBig = (matrix) => {
  const origin = new DOMPoint(0, 0).matrixTransform(matrix);
  const unitX = new DOMPoint(1, 0).matrixTransform(matrix);
  const unitY = new DOMPoint(0, 1).matrixTransform(matrix);
  const basisX = { x: unitX.x - origin.x, y: unitX.y - origin.y };
  const basisY = { x: unitY.x - origin.x, y: unitY.y - origin.y };
  const scaleX = 1 / Math.hypot(basisX.x, basisX.y);
  const scaleY = 1 / Math.hypot(basisY.x, basisY.y);
  const maxScale = Math.max(scaleX, scaleY);
  if (maxScale > MAX_SCALE_FACTOR) {
    return true;
  }
  return false;
};
function invertProjectivePoint(xp, yp, matrix) {
  const A = matrix.m11 - xp * matrix.m14;
  const B = matrix.m21 - xp * matrix.m24;
  const C = xp * matrix.m44 - matrix.m41;
  const D = matrix.m12 - yp * matrix.m14;
  const E = matrix.m22 - yp * matrix.m24;
  const F = yp * matrix.m44 - matrix.m42;
  const det = A * E - B * D;
  if (Math.abs(det) < 0.0000000001) {
    return null;
  }
  const x = (C * E - B * F) / det;
  const y = (A * F - C * D) / det;
  return { x, y };
}
function getPreTransformRect(targetRect, matrix) {
  if (isScaleTooBig(matrix)) {
    return null;
  }
  const corners = [
    { x: targetRect.x, y: targetRect.y },
    { x: targetRect.x + targetRect.width, y: targetRect.y },
    { x: targetRect.x + targetRect.width, y: targetRect.y + targetRect.height },
    { x: targetRect.x, y: targetRect.y + targetRect.height }
  ];
  const invertedCorners = [];
  for (const corner of corners) {
    const inverted = invertProjectivePoint(corner.x, corner.y, matrix);
    if (inverted === null) {
      return null;
    }
    invertedCorners.push(inverted);
  }
  const xCoords = invertedCorners.map((p) => p.x);
  const yCoords = invertedCorners.map((p) => p.y);
  return new DOMRect(Math.min(...xCoords), Math.min(...yCoords), Math.max(...xCoords) - Math.min(...xCoords), Math.max(...yCoords) - Math.min(...yCoords));
}

// src/drawing/transform-in-3d.ts
var vsSource = `
    attribute vec2 aPosition;
    attribute vec2 aTexCoord;
    uniform mat4 uTransform;
    uniform vec2 uResolution;
    uniform vec2 uOffset;
    varying vec2 vTexCoord;

    void main() {
        vec4 pos = uTransform * vec4(aPosition, 0.0, 1.0);
        pos.xy = pos.xy + uOffset * pos.w;

        // Convert homogeneous coords to clip space
        gl_Position = vec4(
            (pos.x / uResolution.x) * 2.0 - pos.w,   // x
            pos.w - (pos.y / uResolution.y) * 2.0,   // y (flipped)
            0.0,
            pos.w
        );

        vTexCoord = aTexCoord;
    }
`;
var fsSource = `
		precision mediump float;
		uniform sampler2D uTexture;
		varying vec2 vTexCoord;

		void main() {
				gl_FragColor = texture2D(uTexture, vTexCoord);
		}
`;
function compileShader(shaderGl, source, type) {
  const shader = shaderGl.createShader(type);
  if (!shader) {
    throw new Error("Could not create shader");
  }
  shaderGl.shaderSource(shader, source);
  shaderGl.compileShader(shader);
  if (!shaderGl.getShaderParameter(shader, shaderGl.COMPILE_STATUS)) {
    const log = shaderGl.getShaderInfoLog(shader);
    shaderGl.deleteShader(shader);
    throw new Error("Shader compile error: " + log);
  }
  return shader;
}
var createHelperCanvas = ({
  canvasWidth,
  canvasHeight,
  helperCanvasState
}) => {
  if (helperCanvasState.current) {
    if (helperCanvasState.current.canvas.width !== canvasWidth || helperCanvasState.current.canvas.height !== canvasHeight) {
      helperCanvasState.current.canvas.width = canvasWidth;
      helperCanvasState.current.canvas.height = canvasHeight;
    }
    helperCanvasState.current.gl.viewport(0, 0, canvasWidth, canvasHeight);
    helperCanvasState.current.gl.clearColor(0, 0, 0, 0);
    helperCanvasState.current.gl.clear(helperCanvasState.current.gl.COLOR_BUFFER_BIT);
    return helperCanvasState.current;
  }
  const canvas = new OffscreenCanvas(canvasWidth, canvasHeight);
  const gl = canvas.getContext("webgl", {
    premultipliedAlpha: true
  }) ?? undefined;
  if (!gl) {
    throw new Error("WebGL not supported");
  }
  const vertexShader = compileShader(gl, vsSource, gl.VERTEX_SHADER);
  const fragmentShader = compileShader(gl, fsSource, gl.FRAGMENT_SHADER);
  const program = gl.createProgram();
  if (!program) {
    throw new Error("Could not create program");
  }
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);
  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    throw new Error("Program link error: " + gl.getProgramInfoLog(program));
  }
  const locations = {
    aPosition: gl.getAttribLocation(program, "aPosition"),
    aTexCoord: gl.getAttribLocation(program, "aTexCoord"),
    uTransform: gl.getUniformLocation(program, "uTransform"),
    uResolution: gl.getUniformLocation(program, "uResolution"),
    uOffset: gl.getUniformLocation(program, "uOffset"),
    uTexture: gl.getUniformLocation(program, "uTexture")
  };
  gl.deleteShader(vertexShader);
  gl.deleteShader(fragmentShader);
  const cleanup = () => {
    gl.deleteProgram(program);
    const loseContext = gl.getExtension("WEBGL_lose_context");
    if (loseContext) {
      loseContext.loseContext();
    }
  };
  helperCanvasState.current = { canvas, gl, program, locations, cleanup };
  return helperCanvasState.current;
};
var transformIn3d = ({
  matrix,
  sourceCanvas,
  sourceRect,
  destRect,
  internalState,
  scale
}) => {
  const { canvas, gl, program, locations } = createHelperCanvas({
    canvasWidth: destRect.width,
    canvasHeight: destRect.height,
    helperCanvasState: internalState.helperCanvasState
  });
  gl.useProgram(program);
  gl.viewport(0, 0, destRect.width, destRect.height);
  gl.clearColor(0, 0, 0, 0);
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.enable(gl.BLEND);
  gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
  gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
  const positionBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
  const positions = new Float32Array([
    sourceRect.x,
    sourceRect.y,
    sourceRect.x + sourceRect.width,
    sourceRect.y,
    sourceRect.x,
    sourceRect.y + sourceRect.height,
    sourceRect.x,
    sourceRect.y + sourceRect.height,
    sourceRect.x + sourceRect.width,
    sourceRect.y,
    sourceRect.x + sourceRect.width,
    sourceRect.y + sourceRect.height
  ]);
  gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
  gl.enableVertexAttribArray(locations.aPosition);
  gl.vertexAttribPointer(locations.aPosition, 2, gl.FLOAT, false, 0, 0);
  const texCoordBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
  const texCoords = new Float32Array([
    0,
    0,
    1,
    0,
    0,
    1,
    0,
    1,
    1,
    0,
    1,
    1
  ]);
  gl.bufferData(gl.ARRAY_BUFFER, texCoords, gl.STATIC_DRAW);
  gl.enableVertexAttribArray(locations.aTexCoord);
  gl.vertexAttribPointer(locations.aTexCoord, 2, gl.FLOAT, false, 0, 0);
  const texture = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, sourceCanvas);
  const actualMatrix = scale !== 1 ? new DOMMatrix().scale(scale, scale).multiply(matrix) : matrix;
  const transformMatrix = actualMatrix.toFloat32Array();
  gl.uniformMatrix4fv(locations.uTransform, false, transformMatrix);
  gl.uniform2f(locations.uResolution, destRect.width, destRect.height);
  gl.uniform2f(locations.uOffset, -destRect.x, -destRect.y);
  gl.uniform1i(locations.uTexture, 0);
  gl.drawArrays(gl.TRIANGLES, 0, 6);
  gl.disableVertexAttribArray(locations.aPosition);
  gl.disableVertexAttribArray(locations.aTexCoord);
  gl.deleteTexture(texture);
  gl.deleteBuffer(positionBuffer);
  gl.deleteBuffer(texCoordBuffer);
  gl.bindTexture(gl.TEXTURE_2D, null);
  gl.bindBuffer(gl.ARRAY_BUFFER, null);
  gl.disable(gl.BLEND);
  gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
  return canvas;
};

// src/drawing/handle-3d-transform.ts
var getPrecomposeRectFor3DTransform = ({
  element,
  parentRect,
  matrix
}) => {
  const unclampedBiggestBoundingClientRect = getBiggestBoundingClientRect(element);
  const biggestPossiblePretransformRect = getPreTransformRect(parentRect, matrix);
  if (!biggestPossiblePretransformRect) {
    return null;
  }
  const preTransformRect = getNarrowerRect({
    firstRect: unclampedBiggestBoundingClientRect,
    secondRect: biggestPossiblePretransformRect
  });
  return preTransformRect;
};
var handle3dTransform = ({
  matrix,
  sourceRect,
  tempCanvas,
  rectAfterTransforms,
  internalState,
  scale
}) => {
  if (rectAfterTransforms.width <= 0 || rectAfterTransforms.height <= 0) {
    return null;
  }
  const transformed = transformIn3d({
    sourceRect,
    matrix,
    sourceCanvas: tempCanvas,
    destRect: rectAfterTransforms,
    internalState,
    scale
  });
  return transformed;
};

// src/drawing/handle-mask.ts
var getPrecomposeRectForMask = (element) => {
  const boundingRect = getBiggestBoundingClientRect(element);
  return boundingRect;
};
var handleMask = ({
  gradientInfo,
  rect,
  precomposeRect,
  tempContext,
  scale
}) => {
  const rectToFill = new DOMRect((rect.left - precomposeRect.left) * scale, (rect.top - precomposeRect.top) * scale, rect.width * scale, rect.height * scale);
  const gradient = createCanvasGradient({
    ctx: tempContext,
    rect: rectToFill,
    gradientInfo,
    offsetLeft: 0,
    offsetTop: 0
  });
  tempContext.globalCompositeOperation = "destination-in";
  tempContext.fillStyle = gradient;
  tempContext.fillRect(rectToFill.left, rectToFill.top, rectToFill.width, rectToFill.height);
};

// src/drawing/scale-rect.ts
var scaleRect = ({
  rect,
  scale
}) => {
  return new DOMRect(rect.x * scale, rect.y * scale, rect.width * scale, rect.height * scale);
};

// src/drawing/transform-rect-with-matrix.ts
function transformDOMRect({
  rect,
  matrix
}) {
  const topLeft = new DOMPointReadOnly(rect.left, rect.top);
  const topRight = new DOMPointReadOnly(rect.right, rect.top);
  const bottomLeft = new DOMPointReadOnly(rect.left, rect.bottom);
  const bottomRight = new DOMPointReadOnly(rect.right, rect.bottom);
  const transformedTopLeft = topLeft.matrixTransform(matrix);
  const transformedTopRight = topRight.matrixTransform(matrix);
  const transformedBottomLeft = bottomLeft.matrixTransform(matrix);
  const transformedBottomRight = bottomRight.matrixTransform(matrix);
  const minX = Math.min(transformedTopLeft.x / transformedTopLeft.w, transformedTopRight.x / transformedTopRight.w, transformedBottomLeft.x / transformedBottomLeft.w, transformedBottomRight.x / transformedBottomRight.w);
  const maxX = Math.max(transformedTopLeft.x / transformedTopLeft.w, transformedTopRight.x / transformedTopRight.w, transformedBottomLeft.x / transformedBottomLeft.w, transformedBottomRight.x / transformedBottomRight.w);
  const minY = Math.min(transformedTopLeft.y / transformedTopLeft.w, transformedTopRight.y / transformedTopRight.w, transformedBottomLeft.y / transformedBottomLeft.w, transformedBottomRight.y / transformedBottomRight.w);
  const maxY = Math.max(transformedTopLeft.y / transformedTopLeft.w, transformedTopRight.y / transformedTopRight.w, transformedBottomLeft.y / transformedBottomLeft.w, transformedBottomRight.y / transformedBottomRight.w);
  return new DOMRect(minX, minY, maxX - minX, maxY - minY);
}

// src/drawing/process-node.ts
var processNode = async ({
  element,
  context,
  draw,
  logLevel,
  parentRect,
  internalState,
  rootElement,
  scale
}) => {
  let __stack = [];
  try {
    const transforms = __using(__stack, calculateTransforms({
      element,
      rootElement
    }), 0);
    const { opacity, computedStyle, totalMatrix, dimensions, precompositing } = transforms;
    if (opacity === 0) {
      return { type: "skip-children" };
    }
    if (computedStyle.backfaceVisibility === "hidden" && totalMatrix.m33 < 0) {
      return { type: "skip-children" };
    }
    if (dimensions.width <= 0 || dimensions.height <= 0) {
      return { type: "continue", cleanupAfterChildren: null };
    }
    const rect = new DOMRect(dimensions.left - parentRect.x, dimensions.top - parentRect.y, dimensions.width, dimensions.height);
    if (precompositing.needsPrecompositing) {
      const start = Date.now();
      let precomposeRect = null;
      if (precompositing.needsMaskImage) {
        precomposeRect = roundToExpandRect(getPrecomposeRectForMask(element));
      }
      if (precompositing.needs3DTransformViaWebGL) {
        const tentativePrecomposeRect = getPrecomposeRectFor3DTransform({
          element,
          parentRect,
          matrix: totalMatrix
        });
        if (!tentativePrecomposeRect) {
          return { type: "continue", cleanupAfterChildren: null };
        }
        precomposeRect = roundToExpandRect(getWiderRectAndExpand({
          firstRect: precomposeRect,
          secondRect: tentativePrecomposeRect
        }));
      }
      if (!precomposeRect) {
        throw new Error("Precompose rect not found");
      }
      if (precomposeRect.width <= 0 || precomposeRect.height <= 0) {
        return { type: "continue", cleanupAfterChildren: null };
      }
      if (!doRectsIntersect(precomposeRect, parentRect)) {
        return { type: "continue", cleanupAfterChildren: null };
      }
      const tempContext = await createLayer({
        cutout: precomposeRect,
        element,
        logLevel,
        internalState,
        scale,
        onlyBackgroundClipText: false
      });
      let drawable = tempContext.canvas;
      const rectAfterTransforms = roundToExpandRect(scaleRect({
        scale,
        rect: transformDOMRect({
          rect: precomposeRect,
          matrix: totalMatrix
        })
      }));
      if (precompositing.needsMaskImage) {
        handleMask({
          gradientInfo: precompositing.needsMaskImage,
          rect,
          precomposeRect,
          tempContext,
          scale
        });
      }
      if (precompositing.needs3DTransformViaWebGL) {
        const t = handle3dTransform({
          matrix: totalMatrix,
          sourceRect: precomposeRect,
          tempCanvas: drawable,
          rectAfterTransforms,
          internalState,
          scale
        });
        if (t) {
          drawable = t;
        }
      }
      const previousTransform = context.getTransform();
      context.setTransform(new DOMMatrix);
      context.drawImage(drawable, 0, drawable.height - rectAfterTransforms.height, rectAfterTransforms.width, rectAfterTransforms.height, rectAfterTransforms.left - parentRect.x, rectAfterTransforms.top - parentRect.y, rectAfterTransforms.width, rectAfterTransforms.height);
      context.setTransform(previousTransform);
      esm.Internals.Log.trace({
        logLevel,
        tag: "@remotion/web-renderer"
      }, `Transforming element in 3D - canvas size: ${precomposeRect.width}x${precomposeRect.height} - compose: ${Date.now() - start}ms - helper canvas: ${drawable.width}x${drawable.height}`);
      internalState.addPrecompose({
        canvasWidth: precomposeRect.width,
        canvasHeight: precomposeRect.height
      });
      return { type: "skip-children" };
    }
    const { cleanupAfterChildren } = await drawElement({
      rect,
      computedStyle,
      context,
      draw,
      opacity,
      totalMatrix,
      parentRect,
      logLevel,
      element,
      internalState,
      scale
    });
    return { type: "continue", cleanupAfterChildren };
  } catch (_catch) {
    var _err = _catch, _hasErr = 1;
  } finally {
    __callDispose(__stack, _err, _hasErr);
  }
};

// src/drawing/text/draw-text.ts


// src/drawing/text/apply-text-transform.ts
var applyTextTransform = (text, transform) => {
  if (transform === "uppercase") {
    return text.toUpperCase();
  }
  if (transform === "lowercase") {
    return text.toLowerCase();
  }
  if (transform === "capitalize") {
    return text.replace(/\b\w/g, (char) => char.toUpperCase());
  }
  return text;
};

// src/drawing/text/find-line-breaks.text.ts
var findWords = (span) => {
  const originalText = span.textContent;
  const segmenter = new Intl.Segmenter("en", { granularity: "word" });
  const segments = segmenter.segment(span.textContent);
  const words = Array.from(segments).map((s) => s.segment);
  const tokens = [];
  for (let i = 0;i < words.length; i++) {
    const wordsBefore = words.slice(0, i);
    const wordsAfter = words.slice(i + 1);
    const word = words[i];
    const wordsBeforeText = wordsBefore.join("");
    const wordsAfterText = wordsAfter.join("");
    const beforeNode = document.createTextNode(wordsBeforeText);
    const afterNode = document.createTextNode(wordsAfterText);
    const interstitialNode = document.createElement("span");
    interstitialNode.textContent = word;
    span.textContent = "";
    span.appendChild(beforeNode);
    span.appendChild(interstitialNode);
    span.appendChild(afterNode);
    const rect = interstitialNode.getBoundingClientRect();
    span.textContent = originalText;
    tokens.push({ text: word, rect });
  }
  return tokens;
};

// src/drawing/text/parse-text-shadow.ts
var parseTextShadow = (textShadowValue) => {
  return parseShadowValues(textShadowValue);
};

// src/drawing/text/draw-text.ts
var drawText = ({
  span,
  logLevel,
  onlyBackgroundClipText,
  parentRect
}) => {
  const drawFn = ({ computedStyle, contextToDraw }) => {
    const {
      fontFamily,
      fontSize,
      fontWeight,
      fontStyle,
      direction,
      writingMode,
      letterSpacing,
      textTransform,
      webkitTextFillColor,
      textShadow: textShadowValue
    } = computedStyle;
    const isVertical = writingMode !== "horizontal-tb";
    if (isVertical) {
      esm.Internals.Log.warn({
        logLevel,
        tag: "@remotion/web-renderer"
      }, 'Detected "writing-mode" CSS property. Vertical text is not yet supported in @remotion/web-renderer');
      return;
    }
    contextToDraw.save();
    const fontSizePx = parseFloat(fontSize);
    contextToDraw.font = `${fontStyle} ${fontWeight} ${fontSizePx}px ${fontFamily}`;
    contextToDraw.fillStyle = onlyBackgroundClipText ? "black" : webkitTextFillColor;
    contextToDraw.letterSpacing = letterSpacing;
    const isRTL = direction === "rtl";
    contextToDraw.textAlign = isRTL ? "right" : "left";
    contextToDraw.textBaseline = "alphabetic";
    const originalText = span.textContent;
    const transformedText = applyTextTransform(originalText, textTransform);
    span.textContent = transformedText;
    const tokens = findWords(span);
    const textShadows = parseTextShadow(textShadowValue);
    for (const token of tokens) {
      const measurements = contextToDraw.measureText(originalText);
      const { fontBoundingBoxDescent, fontBoundingBoxAscent } = measurements;
      const fontHeight = fontBoundingBoxAscent + fontBoundingBoxDescent;
      const leading = token.rect.height - fontHeight;
      const halfLeading = leading / 2;
      const x = (isRTL ? token.rect.right : token.rect.left) - parentRect.x;
      const y = token.rect.top + fontBoundingBoxAscent + halfLeading - parentRect.y;
      for (let i = textShadows.length - 1;i >= 0; i--) {
        const shadow = textShadows[i];
        contextToDraw.shadowColor = shadow.color;
        contextToDraw.shadowBlur = shadow.blurRadius;
        contextToDraw.shadowOffsetX = shadow.offsetX;
        contextToDraw.shadowOffsetY = shadow.offsetY;
        contextToDraw.fillText(token.text, x, y);
      }
      contextToDraw.shadowColor = "transparent";
      contextToDraw.shadowBlur = 0;
      contextToDraw.shadowOffsetX = 0;
      contextToDraw.shadowOffsetY = 0;
      contextToDraw.fillText(token.text, x, y);
    }
    span.textContent = originalText;
    contextToDraw.restore();
  };
  return drawFn;
};

// src/drawing/text/handle-text-node.ts
var handleTextNode = async ({
  node,
  context,
  logLevel,
  parentRect,
  internalState,
  rootElement,
  onlyBackgroundClipText,
  scale
}) => {
  const span = document.createElement("span");
  const parent = node.parentNode;
  if (!parent) {
    throw new Error("Text node has no parent");
  }
  parent.insertBefore(span, node);
  span.appendChild(node);
  const value = await processNode({
    context,
    element: span,
    draw: drawText({ span, logLevel, onlyBackgroundClipText, parentRect }),
    logLevel,
    parentRect,
    internalState,
    rootElement,
    scale
  });
  parent.insertBefore(node, span);
  parent.removeChild(span);
  return value;
};

// src/walk-over-node.ts
var walkOverNode = ({
  node,
  context,
  logLevel,
  parentRect,
  internalState,
  rootElement,
  onlyBackgroundClipText,
  scale
}) => {
  if (node instanceof HTMLElement || node instanceof SVGElement) {
    return processNode({
      element: node,
      context,
      draw: drawDomElement(node),
      logLevel,
      parentRect,
      internalState,
      rootElement,
      scale
    });
  }
  if (node instanceof Text) {
    return handleTextNode({
      node,
      context,
      logLevel,
      parentRect,
      internalState,
      rootElement,
      onlyBackgroundClipText,
      scale
    });
  }
  throw new Error("Unknown node type");
};

// src/compose.ts
var getFilterFunction = (node) => {
  if (!(node instanceof Element)) {
    return NodeFilter.FILTER_ACCEPT;
  }
  if (node.parentElement instanceof SVGSVGElement) {
    return NodeFilter.FILTER_REJECT;
  }
  const computedStyle = getComputedStyle(node);
  if (computedStyle.display === "none") {
    return NodeFilter.FILTER_REJECT;
  }
  return NodeFilter.FILTER_ACCEPT;
};
var compose = async ({
  element,
  context,
  logLevel,
  parentRect,
  internalState,
  onlyBackgroundClipText,
  scale
}) => {
  let __stack = [];
  try {
    const treeWalker = document.createTreeWalker(element, onlyBackgroundClipText ? NodeFilter.SHOW_TEXT : NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT, getFilterFunction);
    if (onlyBackgroundClipText) {
      treeWalker.nextNode();
      if (!treeWalker.currentNode) {
        return;
      }
    }
    const treeWalkerClean = __using(__stack, createTreeWalkerCleanupAfterChildren(treeWalker), 0);
    const { checkCleanUpAtBeginningOfIteration, addCleanup } = treeWalkerClean;
    while (true) {
      checkCleanUpAtBeginningOfIteration();
      const val = await walkOverNode({
        node: treeWalker.currentNode,
        context,
        logLevel,
        parentRect,
        internalState,
        rootElement: element,
        onlyBackgroundClipText,
        scale
      });
      if (val.type === "skip-children") {
        if (!skipToNextNonDescendant(treeWalker)) {
          break;
        }
      } else {
        if (val.cleanupAfterChildren) {
          addCleanup(treeWalker.currentNode, val.cleanupAfterChildren);
        }
        if (!treeWalker.nextNode()) {
          break;
        }
      }
    }
  } catch (_catch) {
    var _err = _catch, _hasErr = 1;
  } finally {
    __callDispose(__stack, _err, _hasErr);
  }
};

// src/take-screenshot.ts
var createLayer = async ({
  element,
  scale,
  logLevel,
  internalState,
  onlyBackgroundClipText,
  cutout
}) => {
  const scaledWidth = Math.ceil(cutout.width * scale);
  const scaledHeight = Math.ceil(cutout.height * scale);
  const canvas = new OffscreenCanvas(scaledWidth, scaledHeight);
  const context = canvas.getContext("2d");
  if (!context) {
    throw new Error("Could not get context");
  }
  await compose({
    element,
    context,
    logLevel,
    parentRect: cutout,
    internalState,
    onlyBackgroundClipText,
    scale
  });
  return context;
};

// src/throttle-progress.ts
var DEFAULT_THROTTLE_MS = 250;
var createThrottledProgressCallback = (callback, throttleMs = DEFAULT_THROTTLE_MS) => {
  if (!callback) {
    return null;
  }
  let lastCallTime = 0;
  let pendingUpdate = null;
  let timeoutId = null;
  const throttled = (progress) => {
    const now = Date.now();
    const timeSinceLastCall = now - lastCallTime;
    pendingUpdate = progress;
    if (timeSinceLastCall >= throttleMs) {
      lastCallTime = now;
      callback(progress);
      pendingUpdate = null;
      if (timeoutId !== null) {
        clearTimeout(timeoutId);
        timeoutId = null;
      }
    } else if (timeoutId === null) {
      const remainingTime = throttleMs - timeSinceLastCall;
      timeoutId = setTimeout(() => {
        if (pendingUpdate !== null) {
          lastCallTime = Date.now();
          callback(pendingUpdate);
          pendingUpdate = null;
        }
        timeoutId = null;
      }, remainingTime);
    }
  };
  const cleanup = () => {
    if (timeoutId !== null) {
      clearTimeout(timeoutId);
      timeoutId = null;
    }
    pendingUpdate = null;
  };
  return { throttled, [Symbol.dispose]: cleanup };
};

// src/validate-scale.ts
var validateScale = (scale) => {
  if (typeof scale === "undefined") {
    return;
  }
  if (typeof scale !== "number") {
    throw new Error('Scale should be a number or undefined, but is "' + JSON.stringify(scale) + '"');
  }
  if (Number.isNaN(scale)) {
    throw new Error("`scale` should not be NaN, but is NaN");
  }
  if (!Number.isFinite(scale)) {
    throw new Error(`"scale" must be finite, but is ${scale}`);
  }
  if (scale <= 0) {
    throw new Error(`"scale" must be bigger than 0, but is ${scale}`);
  }
  if (scale > 16) {
    throw new Error(`"scale" must be smaller or equal than 16, but is ${scale}`);
  }
};

// src/validate-video-frame.ts
var validateVideoFrame = ({
  originalFrame,
  returnedFrame,
  expectedWidth,
  expectedHeight,
  expectedTimestamp
}) => {
  if (!(returnedFrame instanceof VideoFrame)) {
    originalFrame.close();
    throw new Error("onFrame callback must return a VideoFrame or void");
  }
  if (returnedFrame === originalFrame) {
    return returnedFrame;
  }
  if (returnedFrame.displayWidth !== expectedWidth || returnedFrame.displayHeight !== expectedHeight) {
    originalFrame.close();
    returnedFrame.close();
    throw new Error(`VideoFrame dimensions mismatch: expected ${expectedWidth}x${expectedHeight}, got ${returnedFrame.displayWidth}x${returnedFrame.displayHeight}`);
  }
  if (returnedFrame.timestamp !== expectedTimestamp) {
    originalFrame.close();
    returnedFrame.close();
    throw new Error(`VideoFrame timestamp mismatch: expected ${expectedTimestamp}, got ${returnedFrame.timestamp}`);
  }
  originalFrame.close();
  return returnedFrame;
};

// src/with-resolvers.ts
var withResolvers = function() {
  let resolve;
  let reject;
  const promise = new Promise((res, rej) => {
    resolve = res;
    reject = rej;
  });
  return { promise, resolve, reject };
};

// src/wait-for-ready.ts
var waitForReady = ({
  timeoutInMilliseconds,
  scope,
  signal,
  apiName,
  internalState,
  keepalive
}) => {
  const start = performance.now();
  const { promise, resolve, reject } = withResolvers();
  let cancelled = false;
  const check = () => {
    if (cancelled) {
      return;
    }
    if (signal?.aborted) {
      cancelled = true;
      internalState?.addWaitForReadyTime(performance.now() - start);
      reject(new Error(`${apiName}() was cancelled`));
      return;
    }
    if (scope.remotion_renderReady === true) {
      internalState?.addWaitForReadyTime(performance.now() - start);
      resolve();
      return;
    }
    if (scope.remotion_cancelledError !== undefined) {
      cancelled = true;
      internalState?.addWaitForReadyTime(performance.now() - start);
      const stack = scope.remotion_cancelledError;
      const message = stack.split(`
`)[0].replace(/^Error: /, "");
      const error = new Error(message);
      error.stack = stack;
      reject(error);
      return;
    }
    if (performance.now() - start > timeoutInMilliseconds + 3000) {
      cancelled = true;
      internalState?.addWaitForReadyTime(performance.now() - start);
      reject(new Error(Object.values(scope.remotion_delayRenderTimeouts).map((d) => d.label).join(", ")));
      return;
    }
    scheduleNextCheck();
  };
  const scheduleNextCheck = () => {
    const rafTick = new Promise((res) => {
      requestAnimationFrame(() => res());
    });
    const backgroundSafeTick = keepalive ? Promise.race([rafTick, keepalive.waitForTick()]) : rafTick;
    backgroundSafeTick.then(check);
  };
  check();
  return promise;
};

// src/web-fs-target.ts
var sessionId = null;
var getPrefix = () => {
  if (!sessionId) {
    sessionId = crypto.randomUUID();
  }
  return `__remotion_render:${sessionId}:`;
};
var cleanupStaleOpfsFiles = async () => {
  try {
    const root = await navigator.storage.getDirectory();
    for await (const [name] of root.entries()) {
      if (name.startsWith("__remotion_render:") && !name.startsWith(getPrefix())) {
        await root.removeEntry(name);
      }
    }
  } catch {}
};
var createWebFsTarget = async () => {
  const directoryHandle = await navigator.storage.getDirectory();
  const filename = `${getPrefix()}${crypto.randomUUID()}`;
  const fileHandle = await directoryHandle.getFileHandle(filename, {
    create: true
  });
  const writable = await fileHandle.createWritable();
  const stream = new WritableStream({
    async write(chunk) {
      await writable.seek(chunk.position);
      await writable.write(chunk);
    }
  });
  const getBlob = async () => {
    const handle = await directoryHandle.getFileHandle(filename);
    return handle.getFile();
  };
  const close = () => writable.close();
  return { stream, getBlob, close };
};

// src/render-media-on-web.tsx
var internalRenderMediaOnWeb = async ({
  composition,
  inputProps,
  delayRenderTimeoutInMilliseconds,
  logLevel,
  mediaCacheSizeInBytes,
  schema,
  videoCodec: codec,
  audioCodec: unresolvedAudioCodec,
  audioBitrate,
  container,
  signal,
  onProgress,
  hardwareAcceleration,
  keyframeIntervalInSeconds,
  videoBitrate,
  frameRange,
  transparent,
  onArtifact,
  onFrame,
  outputTarget: userDesiredOutputTarget,
  licenseKey,
  muted,
  scale,
  isProduction
}) => {
  let __stack2 = [];
  try {
    validateScale(scale);
    const outputTarget = userDesiredOutputTarget === null ? await canUseWebFsWriter() ? "web-fs" : "arraybuffer" : userDesiredOutputTarget;
    if (outputTarget === "web-fs") {
      await cleanupStaleOpfsFiles();
    }
    const format = containerToMediabunnyContainer(container);
    if (codec && !format.getSupportedCodecs().includes(codecToMediabunnyCodec(codec))) {
      return Promise.reject(new Error(`Codec ${codec} is not supported for container ${container}`));
    }
    const resolvedAudioBitrate = typeof audioBitrate === "number" ? audioBitrate : getQualityForWebRendererQuality(audioBitrate);
    let finalAudioCodec = null;
    if (!muted) {
      const audioResult = await resolveAudioCodec({
        container,
        requestedCodec: unresolvedAudioCodec,
        userSpecifiedAudioCodec: unresolvedAudioCodec !== undefined && unresolvedAudioCodec !== null,
        bitrate: resolvedAudioBitrate
      });
      for (const issue of audioResult.issues) {
        if (issue.severity === "error") {
          return Promise.reject(new Error(issue.message));
        }
        esm.Internals.Log.warn({ logLevel, tag: "@remotion/web-renderer" }, issue.message);
      }
      finalAudioCodec = audioResult.codec;
    }
    const resolved = await esm.Internals.resolveVideoConfig({
      calculateMetadata: composition.calculateMetadata ?? null,
      signal: signal ?? new AbortController().signal,
      defaultProps: composition.defaultProps ?? {},
      inputProps: inputProps ?? {},
      compositionId: composition.id,
      compositionDurationInFrames: composition.durationInFrames ?? null,
      compositionFps: composition.fps ?? null,
      compositionHeight: composition.height ?? null,
      compositionWidth: composition.width ?? null
    });
    const realFrameRange = getRealFrameRange(resolved.durationInFrames, frameRange);
    if (signal?.aborted) {
      return Promise.reject(new Error("renderMediaOnWeb() was cancelled"));
    }
    const scaffold = __using(__stack2, createScaffold({
      width: resolved.width,
      height: resolved.height,
      fps: resolved.fps,
      durationInFrames: resolved.durationInFrames,
      Component: composition.component,
      resolvedProps: resolved.props,
      id: resolved.id,
      delayRenderTimeoutInMilliseconds,
      logLevel,
      mediaCacheSizeInBytes,
      schema: schema ?? null,
      audioEnabled: !muted,
      videoEnabled: true,
      initialFrame: 0,
      defaultCodec: resolved.defaultCodec,
      defaultOutName: resolved.defaultOutName
    }), 0);
    const { delayRenderScope, div, timeUpdater, collectAssets, errorHolder } = scaffold;
    const internalState = __using(__stack2, makeInternalState(), 0);
    const keepalive = __using(__stack2, createBackgroundKeepalive({
      fps: resolved.fps,
      logLevel
    }), 0);
    const artifactsHandler = handleArtifacts();
    const webFsTarget = outputTarget === "web-fs" ? await createWebFsTarget() : null;
    const target = webFsTarget ? new StreamTarget(webFsTarget.stream) : new BufferTarget;
    const outputWithCleanup = __using(__stack2, makeOutputWithCleanup({
      format,
      target
    }), 0);
    outputWithCleanup.output.setMetadataTags({
      comment: `Made with Remotion ${VERSION}`
    });
    const throttledProgress = __using(__stack2, createThrottledProgressCallback(onProgress), 0);
    const throttledOnProgress = throttledProgress?.throttled ?? null;
    try {
      let __stack = [];
      try {
        if (signal?.aborted) {
          throw new Error("renderMediaOnWeb() was cancelled");
        }
        await waitForReady({
          timeoutInMilliseconds: delayRenderTimeoutInMilliseconds,
          scope: delayRenderScope,
          signal,
          apiName: "renderMediaOnWeb",
          internalState,
          keepalive
        });
        checkForError(errorHolder);
        if (signal?.aborted) {
          throw new Error("renderMediaOnWeb() was cancelled");
        }
        const videoSampleSource = __using(__stack, makeVideoSampleSourceCleanup({
          codec: codecToMediabunnyCodec(codec),
          bitrate: typeof videoBitrate === "number" ? videoBitrate : getQualityForWebRendererQuality(videoBitrate),
          sizeChangeBehavior: "deny",
          hardwareAcceleration,
          latencyMode: "quality",
          keyFrameInterval: keyframeIntervalInSeconds,
          alpha: transparent ? "keep" : "discard"
        }), 0);
        outputWithCleanup.output.addVideoTrack(videoSampleSource.videoSampleSource);
        const audioSampleSource = __using(__stack, createAudioSampleSource({
          muted,
          codec: finalAudioCodec ? audioCodecToMediabunnyAudioCodec(finalAudioCodec) : null,
          bitrate: resolvedAudioBitrate
        }), 0);
        if (audioSampleSource) {
          outputWithCleanup.output.addAudioTrack(audioSampleSource.audioSampleSource);
        }
        await outputWithCleanup.output.start();
        if (signal?.aborted) {
          throw new Error("renderMediaOnWeb() was cancelled");
        }
        const progress = {
          renderedFrames: 0,
          encodedFrames: 0
        };
        for (let frame = realFrameRange[0];frame <= realFrameRange[1]; frame++) {
          if (signal?.aborted) {
            throw new Error("renderMediaOnWeb() was cancelled");
          }
          timeUpdater.current?.update(frame);
          await waitForReady({
            timeoutInMilliseconds: delayRenderTimeoutInMilliseconds,
            scope: delayRenderScope,
            signal,
            apiName: "renderMediaOnWeb",
            keepalive,
            internalState
          });
          checkForError(errorHolder);
          if (signal?.aborted) {
            throw new Error("renderMediaOnWeb() was cancelled");
          }
          const createFrameStart = performance.now();
          const layer = await createLayer({
            element: div,
            scale,
            logLevel,
            internalState,
            onlyBackgroundClipText: false,
            cutout: new DOMRect(0, 0, resolved.width, resolved.height)
          });
          internalState.addCreateFrameTime(performance.now() - createFrameStart);
          if (signal?.aborted) {
            throw new Error("renderMediaOnWeb() was cancelled");
          }
          const timestamp = Math.round((frame - realFrameRange[0]) / resolved.fps * 1e6);
          const videoFrame = new VideoFrame(layer.canvas, {
            timestamp
          });
          progress.renderedFrames++;
          throttledOnProgress?.({ ...progress });
          let frameToEncode = videoFrame;
          if (onFrame) {
            const returnedFrame = await onFrame(videoFrame);
            if (signal?.aborted) {
              throw new Error("renderMediaOnWeb() was cancelled");
            }
            frameToEncode = validateVideoFrame({
              originalFrame: videoFrame,
              returnedFrame,
              expectedWidth: Math.round(resolved.width * scale),
              expectedHeight: Math.round(resolved.height * scale),
              expectedTimestamp: timestamp
            });
          }
          const audioCombineStart = performance.now();
          const assets = collectAssets.current.collectAssets();
          if (onArtifact) {
            await artifactsHandler.handle({
              imageData: layer.canvas,
              frame,
              assets,
              onArtifact
            });
          }
          if (signal?.aborted) {
            throw new Error("renderMediaOnWeb() was cancelled");
          }
          const audio = muted ? null : onlyInlineAudio({ assets, fps: resolved.fps, timestamp });
          internalState.addAudioMixingTime(performance.now() - audioCombineStart);
          const addSampleStart = performance.now();
          await Promise.all([
            addVideoSampleAndCloseFrame(frameToEncode, videoSampleSource.videoSampleSource),
            audio && audioSampleSource ? addAudioSample(audio, audioSampleSource.audioSampleSource) : Promise.resolve()
          ]);
          internalState.addAddSampleTime(performance.now() - addSampleStart);
          progress.encodedFrames++;
          throttledOnProgress?.({ ...progress });
          if (signal?.aborted) {
            throw new Error("renderMediaOnWeb() was cancelled");
          }
        }
        onProgress?.({ ...progress });
        videoSampleSource.videoSampleSource.close();
        audioSampleSource?.audioSampleSource.close();
        await outputWithCleanup.output.finalize();
        esm.Internals.Log.verbose({ logLevel, tag: "web-renderer" }, `Render timings: waitForReady=${internalState.getWaitForReadyTime().toFixed(2)}ms, createFrame=${internalState.getCreateFrameTime().toFixed(2)}ms, addSample=${internalState.getAddSampleTime().toFixed(2)}ms, audioMixing=${internalState.getAudioMixingTime().toFixed(2)}ms`);
        if (webFsTarget) {
          sendUsageEvent({
            licenseKey: licenseKey ?? null,
            succeeded: true,
            apiName: "renderMediaOnWeb",
            isStill: false,
            isProduction: isProduction ?? true
          });
          await webFsTarget.close();
          return {
            getBlob: () => {
              return webFsTarget.getBlob();
            },
            internalState
          };
        }
        if (!(target instanceof BufferTarget)) {
          throw new Error("Expected target to be a BufferTarget");
        }
        sendUsageEvent({
          licenseKey: licenseKey ?? null,
          succeeded: true,
          apiName: "renderMediaOnWeb",
          isStill: false,
          isProduction: isProduction ?? true
        });
        return {
          getBlob: () => {
            if (!target.buffer) {
              throw new Error("The resulting buffer is empty");
            }
            return Promise.resolve(new Blob([target.buffer], { type: getMimeType(container) }));
          },
          internalState
        };
      } catch (_catch) {
        var _err = _catch, _hasErr = 1;
      } finally {
        __callDispose(__stack, _err, _hasErr);
      }
    } catch (err) {
      if (!signal?.aborted) {
        sendUsageEvent({
          succeeded: false,
          licenseKey: licenseKey ?? null,
          apiName: "renderMediaOnWeb",
          isStill: false,
          isProduction: isProduction ?? true
        }).catch((err2) => {
          esm.Internals.Log.error({ logLevel: "error", tag: "web-renderer" }, "Failed to send usage event", err2);
        });
      }
      throw err;
    }
  } catch (_catch2) {
    var _err2 = _catch2, _hasErr2 = 1;
  } finally {
    __callDispose(__stack2, _err2, _hasErr2);
  }
};
var renderMediaOnWeb = (options) => {
  const container = options.container ?? "mp4";
  const codec = options.videoCodec ?? getDefaultVideoCodecForContainer(container);
  onlyOneRenderAtATimeQueue.ref = onlyOneRenderAtATimeQueue.ref.catch(() => Promise.resolve()).then(() => internalRenderMediaOnWeb({
    ...options,
    delayRenderTimeoutInMilliseconds: options.delayRenderTimeoutInMilliseconds ?? 30000,
    logLevel: options.logLevel ?? window.remotion_logLevel ?? "info",
    schema: options.schema ?? undefined,
    mediaCacheSizeInBytes: options.mediaCacheSizeInBytes ?? null,
    videoCodec: codec,
    audioCodec: options.audioCodec ?? null,
    audioBitrate: options.audioBitrate ?? "medium",
    container,
    signal: options.signal ?? null,
    onProgress: options.onProgress ?? null,
    hardwareAcceleration: options.hardwareAcceleration ?? "no-preference",
    keyframeIntervalInSeconds: options.keyframeIntervalInSeconds ?? 5,
    videoBitrate: options.videoBitrate ?? "medium",
    frameRange: options.frameRange ?? null,
    transparent: options.transparent ?? false,
    onArtifact: options.onArtifact ?? null,
    onFrame: options.onFrame ?? null,
    outputTarget: options.outputTarget ?? null,
    licenseKey: options.licenseKey ?? null,
    muted: options.muted ?? false,
    scale: options.scale ?? 1,
    isProduction: options.isProduction ?? true
  }));
  return onlyOneRenderAtATimeQueue.ref;
};
// src/render-still-on-web.tsx

async function internalRenderStillOnWeb({
  frame,
  delayRenderTimeoutInMilliseconds,
  logLevel,
  inputProps,
  schema,
  imageFormat,
  mediaCacheSizeInBytes,
  composition,
  signal,
  onArtifact,
  licenseKey,
  scale,
  isProduction
}) {
  let __stack = [];
  try {
    validateScale(scale);
    const resolved = await esm.Internals.resolveVideoConfig({
      calculateMetadata: composition.calculateMetadata ?? null,
      signal: signal ?? new AbortController().signal,
      defaultProps: composition.defaultProps ?? {},
      inputProps: inputProps ?? {},
      compositionId: composition.id,
      compositionDurationInFrames: composition.durationInFrames ?? null,
      compositionFps: composition.fps ?? null,
      compositionHeight: composition.height ?? null,
      compositionWidth: composition.width ?? null
    });
    if (signal?.aborted) {
      return Promise.reject(new Error("renderStillOnWeb() was cancelled"));
    }
    const internalState = __using(__stack, makeInternalState(), 0);
    const scaffold = __using(__stack, createScaffold({
      width: resolved.width,
      height: resolved.height,
      delayRenderTimeoutInMilliseconds,
      logLevel,
      resolvedProps: resolved.props,
      id: resolved.id,
      mediaCacheSizeInBytes,
      audioEnabled: false,
      Component: composition.component,
      videoEnabled: true,
      durationInFrames: resolved.durationInFrames,
      fps: resolved.fps,
      schema: schema ?? null,
      initialFrame: frame,
      defaultCodec: resolved.defaultCodec,
      defaultOutName: resolved.defaultOutName
    }), 0);
    const { delayRenderScope, div, collectAssets, errorHolder } = scaffold;
    const artifactsHandler = handleArtifacts();
    try {
      if (signal?.aborted) {
        throw new Error("renderStillOnWeb() was cancelled");
      }
      await waitForReady({
        timeoutInMilliseconds: delayRenderTimeoutInMilliseconds,
        scope: delayRenderScope,
        signal,
        apiName: "renderStillOnWeb",
        internalState: null,
        keepalive: null
      });
      checkForError(errorHolder);
      if (signal?.aborted) {
        throw new Error("renderStillOnWeb() was cancelled");
      }
      const capturedFrame = await createLayer({
        element: div,
        scale,
        logLevel,
        internalState,
        onlyBackgroundClipText: false,
        cutout: new DOMRect(0, 0, resolved.width, resolved.height)
      });
      const imageData = await capturedFrame.canvas.convertToBlob({
        type: `image/${imageFormat}`
      });
      const assets = collectAssets.current.collectAssets();
      if (onArtifact) {
        await artifactsHandler.handle({ imageData, frame, assets, onArtifact });
      }
      sendUsageEvent({
        licenseKey: licenseKey ?? null,
        succeeded: true,
        apiName: "renderStillOnWeb",
        isStill: true,
        isProduction
      });
      return { blob: imageData, internalState };
    } catch (err) {
      if (!signal?.aborted) {
        sendUsageEvent({
          succeeded: false,
          licenseKey: licenseKey ?? null,
          apiName: "renderStillOnWeb",
          isStill: true,
          isProduction
        }).catch((err2) => {
          esm.Internals.Log.error({ logLevel: "error", tag: "web-renderer" }, "Failed to send usage event", err2);
        });
      }
      throw err;
    }
  } catch (_catch) {
    var _err = _catch, _hasErr = 1;
  } finally {
    __callDispose(__stack, _err, _hasErr);
  }
}
var renderStillOnWeb = (options) => {
  onlyOneRenderAtATimeQueue.ref = onlyOneRenderAtATimeQueue.ref.catch(() => Promise.resolve()).then(() => internalRenderStillOnWeb({
    ...options,
    delayRenderTimeoutInMilliseconds: options.delayRenderTimeoutInMilliseconds ?? 30000,
    logLevel: options.logLevel ?? window.remotion_logLevel ?? "info",
    schema: options.schema ?? undefined,
    mediaCacheSizeInBytes: options.mediaCacheSizeInBytes ?? null,
    signal: options.signal ?? null,
    onArtifact: options.onArtifact ?? null,
    licenseKey: options.licenseKey ?? null,
    scale: options.scale ?? 1,
    isProduction: options.isProduction ?? true
  }));
  return onlyOneRenderAtATimeQueue.ref;
};



/***/ },

/***/ 7553
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   N: () => (/* binding */ AC3_SAMPLE_RATES),
/* harmony export */   P: () => (/* binding */ EAC3_REDUCED_SAMPLE_RATES)
/* harmony export */ });
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */
/** Sample rates indexed by fscod (Table 4.1) */
const AC3_SAMPLE_RATES = [48000, 44100, 32000];
/** E-AC-3 reduced sample rates for fscod2 per ATSC A/52:2018 */
const EAC3_REDUCED_SAMPLE_RATES = [24000, 22050, 16000];


/***/ },

/***/ 2788
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   D0: () => (/* binding */ KILOBIT_RATES),
/* harmony export */   EZ: () => (/* binding */ getXingOffset),
/* harmony export */   Fm: () => (/* binding */ decodeSynchsafe),
/* harmony export */   P8: () => (/* binding */ readMp3FrameHeader),
/* harmony export */   Pj: () => (/* binding */ encodeSynchsafe),
/* harmony export */   Yq: () => (/* binding */ FRAME_HEADER_SIZE),
/* harmony export */   c9: () => (/* binding */ computeMp3FrameSize),
/* harmony export */   hY: () => (/* binding */ XING),
/* harmony export */   rD: () => (/* binding */ INFO)
/* harmony export */ });
/* unused harmony export SAMPLING_RATES */
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */
const FRAME_HEADER_SIZE = 4;
const SAMPLING_RATES = [44100, 48000, 32000];
const KILOBIT_RATES = [
    // lowSamplingFrequency === 0
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // layer = 0
    -1, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1, // layer 1
    -1, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, -1, // layer = 2
    -1, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, -1, // layer = 3
    // lowSamplingFrequency === 1
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // layer = 0
    -1, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1, // layer = 1
    -1, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1, // layer = 2
    -1, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, -1, // layer = 3
];
/** 'Xing' */
const XING = 0x58696e67;
/** 'Info' */
const INFO = 0x496e666f;
const computeMp3FrameSize = (lowSamplingFrequency, layer, bitrate, sampleRate, padding) => {
    if (layer === 0) {
        return 0; // Not expected that this is hit
    }
    else if (layer === 1) {
        return Math.floor(144 * bitrate / (sampleRate << lowSamplingFrequency)) + padding;
    }
    else if (layer === 2) {
        return Math.floor(144 * bitrate / sampleRate) + padding;
    }
    else { // layer === 3
        return (Math.floor(12 * bitrate / sampleRate) + padding) * 4;
    }
};
const getXingOffset = (mpegVersionId, channel) => {
    return mpegVersionId === 3
        ? (channel === 3 ? 21 : 36)
        : (channel === 3 ? 13 : 21);
};
const readMp3FrameHeader = (word, remainingBytes) => {
    const firstByte = word >>> 24;
    const secondByte = (word >>> 16) & 0xff;
    const thirdByte = (word >>> 8) & 0xff;
    const fourthByte = word & 0xff;
    if (firstByte !== 0xff && secondByte !== 0xff && thirdByte !== 0xff && fourthByte !== 0xff) {
        return {
            header: null,
            bytesAdvanced: 4,
        };
    }
    if (firstByte !== 0xff) {
        return { header: null, bytesAdvanced: 1 };
    }
    if ((secondByte & 0xe0) !== 0xe0) {
        return { header: null, bytesAdvanced: 1 };
    }
    let lowSamplingFrequency = 0;
    let mpeg25 = 0;
    if (secondByte & (1 << 4)) {
        lowSamplingFrequency = (secondByte & (1 << 3)) ? 0 : 1;
    }
    else {
        lowSamplingFrequency = 1;
        mpeg25 = 1;
    }
    const mpegVersionId = (secondByte >> 3) & 0x3;
    const layer = (secondByte >> 1) & 0x3;
    const bitrateIndex = (thirdByte >> 4) & 0xf;
    const frequencyIndex = ((thirdByte >> 2) & 0x3) % 3;
    const padding = (thirdByte >> 1) & 0x1;
    const channel = (fourthByte >> 6) & 0x3;
    const modeExtension = (fourthByte >> 4) & 0x3;
    const copyright = (fourthByte >> 3) & 0x1;
    const original = (fourthByte >> 2) & 0x1;
    const emphasis = fourthByte & 0x3;
    const kilobitRate = KILOBIT_RATES[lowSamplingFrequency * 16 * 4 + layer * 16 + bitrateIndex];
    if (kilobitRate === -1) {
        return { header: null, bytesAdvanced: 1 };
    }
    const bitrate = kilobitRate * 1000;
    const sampleRate = SAMPLING_RATES[frequencyIndex] >> (lowSamplingFrequency + mpeg25);
    const frameLength = computeMp3FrameSize(lowSamplingFrequency, layer, bitrate, sampleRate, padding);
    if (remainingBytes !== null && remainingBytes < frameLength) {
        // The frame doesn't fit into the rest of the file
        return { header: null, bytesAdvanced: 1 };
    }
    let audioSamplesInFrame;
    if (mpegVersionId === 3) {
        audioSamplesInFrame = layer === 3 ? 384 : 1152;
    }
    else {
        if (layer === 3) {
            audioSamplesInFrame = 384;
        }
        else if (layer === 2) {
            audioSamplesInFrame = 1152;
        }
        else {
            audioSamplesInFrame = 576;
        }
    }
    return {
        header: {
            totalSize: frameLength,
            mpegVersionId,
            layer,
            bitrate,
            frequencyIndex,
            sampleRate,
            channel,
            modeExtension,
            copyright,
            original,
            emphasis,
            audioSamplesInFrame,
        },
        bytesAdvanced: 1,
    };
};
const encodeSynchsafe = (unsynchsafed) => {
    let mask = 0x7f;
    let synchsafed = 0;
    let unsynchsafedRest = unsynchsafed;
    while ((mask ^ 0x7fffffff) !== 0) {
        synchsafed = unsynchsafedRest & ~mask;
        synchsafed <<= 1;
        synchsafed |= unsynchsafedRest & mask;
        mask = ((mask + 1) << 8) - 1;
        unsynchsafedRest = synchsafed;
    }
    return synchsafed;
};
const decodeSynchsafe = (synchsafed) => {
    let mask = 0x7f000000;
    let unsynchsafed = 0;
    while (mask !== 0) {
        unsynchsafed >>= 1;
        unsynchsafed |= synchsafed & mask;
        mask >>= 8;
    }
    return unsynchsafed;
};


/***/ },

/***/ 8475
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Y$: () => (/* binding */ MAX_ADTS_FRAME_HEADER_SIZE),
/* harmony export */   gc: () => (/* binding */ MIN_ADTS_FRAME_HEADER_SIZE),
/* harmony export */   lh: () => (/* binding */ readAdtsFrameHeader)
/* harmony export */ });
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3912);
/* harmony import */ var _reader_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7735);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */


const MIN_ADTS_FRAME_HEADER_SIZE = 7;
const MAX_ADTS_FRAME_HEADER_SIZE = 9;
const readAdtsFrameHeader = (slice) => {
    // https://wiki.multimedia.cx/index.php/ADTS (last visited: 2025/08/17)
    const startPos = slice.filePos;
    const bytes = (0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readBytes */ .io)(slice, 9); // 9 with CRC, 7 without CRC
    const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_0__/* .Bitstream */ ._c(bytes);
    const syncword = bitstream.readBits(12);
    if (syncword !== 0b1111_11111111) {
        return null;
    }
    bitstream.skipBits(1); // MPEG version
    const layer = bitstream.readBits(2);
    if (layer !== 0) {
        return null;
    }
    const protectionAbsence = bitstream.readBits(1);
    const objectType = bitstream.readBits(2) + 1;
    const samplingFrequencyIndex = bitstream.readBits(4);
    if (samplingFrequencyIndex === 15) {
        return null;
    }
    bitstream.skipBits(1); // Private bit
    const channelConfiguration = bitstream.readBits(3);
    if (channelConfiguration === 0) {
        throw new Error('ADTS frames with channel configuration 0 are not supported.');
    }
    bitstream.skipBits(1); // Originality
    bitstream.skipBits(1); // Home
    bitstream.skipBits(1); // Copyright ID bit
    bitstream.skipBits(1); // Copyright ID start
    const frameLength = bitstream.readBits(13);
    bitstream.skipBits(11); // Buffer fullness
    const numberOfAacFrames = bitstream.readBits(2) + 1;
    if (numberOfAacFrames !== 1) {
        throw new Error('ADTS frames with more than one AAC frame are not supported.');
    }
    let crcCheck = null;
    if (protectionAbsence === 1) { // No CRC
        slice.filePos -= 2;
    }
    else { // CRC
        crcCheck = bitstream.readBits(16);
    }
    return {
        objectType,
        samplingFrequencyIndex,
        channelConfiguration,
        frameLength,
        numberOfAacFrames,
        crcCheck,
        startPos,
    };
};


/***/ },

/***/ 6297
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   A3: () => (/* binding */ FlacBlockType),
/* harmony export */   BP: () => (/* binding */ deserializeAvcDecoderConfigurationRecord),
/* harmony export */   Co: () => (/* binding */ parseModesFromVorbisSetupPacket),
/* harmony export */   D5: () => (/* binding */ extractHevcDecoderConfigurationRecord),
/* harmony export */   FY: () => (/* binding */ EAC3_NUMBLKS_TABLE),
/* harmony export */   GE: () => (/* binding */ concatNalUnitsInAnnexB),
/* harmony export */   HR: () => (/* binding */ iterateNalUnitsInLengthPrefixed),
/* harmony export */   Ir: () => (/* binding */ AC3_SAMPLES_PER_FRAME),
/* harmony export */   KU: () => (/* binding */ serializeAvcDecoderConfigurationRecord),
/* harmony export */   LM: () => (/* binding */ parseAc3SyncFrame),
/* harmony export */   O9: () => (/* binding */ extractNalUnitTypeForHevc),
/* harmony export */   Oc: () => (/* binding */ readVorbisComments),
/* harmony export */   PK: () => (/* binding */ getEac3SampleRate),
/* harmony export */   PR: () => (/* binding */ determineVideoPacketType),
/* harmony export */   Pl: () => (/* binding */ AC3_FRAME_SIZES),
/* harmony export */   Qf: () => (/* binding */ parseOpusIdentificationHeader),
/* harmony export */   RF: () => (/* binding */ iterateHevcNalUnits),
/* harmony export */   RO: () => (/* binding */ iterateAvcNalUnits),
/* harmony export */   Sd: () => (/* binding */ parseEac3Config),
/* harmony export */   UU: () => (/* binding */ extractAv1CodecInfoFromPacket),
/* harmony export */   Us: () => (/* binding */ serializeHevcDecoderConfigurationRecord),
/* harmony export */   WY: () => (/* binding */ createVorbisComments),
/* harmony export */   Zi: () => (/* binding */ concatAvcNalUnits),
/* harmony export */   _b: () => (/* binding */ AC3_REGISTRATION_DESCRIPTOR),
/* harmony export */   _u: () => (/* binding */ iterateNalUnitsInAnnexB),
/* harmony export */   bs: () => (/* binding */ extractVp9CodecInfoFromPacket),
/* harmony export */   eM: () => (/* binding */ parseAvcSps),
/* harmony export */   fH: () => (/* binding */ extractAvcDecoderConfigurationRecord),
/* harmony export */   gT: () => (/* binding */ parseHevcSps),
/* harmony export */   hf: () => (/* binding */ deserializeHevcDecoderConfigurationRecord),
/* harmony export */   iJ: () => (/* binding */ HevcNalUnitType),
/* harmony export */   ls: () => (/* binding */ parseOpusTocByte),
/* harmony export */   mY: () => (/* binding */ AvcNalUnitType),
/* harmony export */   nV: () => (/* binding */ EAC3_REGISTRATION_DESCRIPTOR),
/* harmony export */   oL: () => (/* binding */ parseEac3SyncFrame),
/* harmony export */   pc: () => (/* binding */ concatNalUnitsInLengthPrefixed),
/* harmony export */   uN: () => (/* binding */ extractNalUnitTypeForAvc),
/* harmony export */   ux: () => (/* binding */ AC3_ACMOD_CHANNEL_COUNTS),
/* harmony export */   zV: () => (/* binding */ getEac3ChannelCount)
/* harmony export */ });
/* unused harmony export iterateAv1PacketObus */
/* harmony import */ var _codec_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1188);
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3912);
/* harmony import */ var _shared_ac3_misc_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7553);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */



// References for AVC/HEVC code:
// ISO 14496-15
// Rec. ITU-T H.264
// Rec. ITU-T H.265
// https://stackoverflow.com/questions/24884827
var AvcNalUnitType;
(function (AvcNalUnitType) {
    AvcNalUnitType[AvcNalUnitType["NON_IDR_SLICE"] = 1] = "NON_IDR_SLICE";
    AvcNalUnitType[AvcNalUnitType["SLICE_DPA"] = 2] = "SLICE_DPA";
    AvcNalUnitType[AvcNalUnitType["SLICE_DPB"] = 3] = "SLICE_DPB";
    AvcNalUnitType[AvcNalUnitType["SLICE_DPC"] = 4] = "SLICE_DPC";
    AvcNalUnitType[AvcNalUnitType["IDR"] = 5] = "IDR";
    AvcNalUnitType[AvcNalUnitType["SEI"] = 6] = "SEI";
    AvcNalUnitType[AvcNalUnitType["SPS"] = 7] = "SPS";
    AvcNalUnitType[AvcNalUnitType["PPS"] = 8] = "PPS";
    AvcNalUnitType[AvcNalUnitType["AUD"] = 9] = "AUD";
    AvcNalUnitType[AvcNalUnitType["SPS_EXT"] = 13] = "SPS_EXT";
})(AvcNalUnitType || (AvcNalUnitType = {}));
var HevcNalUnitType;
(function (HevcNalUnitType) {
    HevcNalUnitType[HevcNalUnitType["RASL_N"] = 8] = "RASL_N";
    HevcNalUnitType[HevcNalUnitType["RASL_R"] = 9] = "RASL_R";
    HevcNalUnitType[HevcNalUnitType["BLA_W_LP"] = 16] = "BLA_W_LP";
    HevcNalUnitType[HevcNalUnitType["RSV_IRAP_VCL23"] = 23] = "RSV_IRAP_VCL23";
    HevcNalUnitType[HevcNalUnitType["VPS_NUT"] = 32] = "VPS_NUT";
    HevcNalUnitType[HevcNalUnitType["SPS_NUT"] = 33] = "SPS_NUT";
    HevcNalUnitType[HevcNalUnitType["PPS_NUT"] = 34] = "PPS_NUT";
    HevcNalUnitType[HevcNalUnitType["AUD_NUT"] = 35] = "AUD_NUT";
    HevcNalUnitType[HevcNalUnitType["PREFIX_SEI_NUT"] = 39] = "PREFIX_SEI_NUT";
    HevcNalUnitType[HevcNalUnitType["SUFFIX_SEI_NUT"] = 40] = "SUFFIX_SEI_NUT";
})(HevcNalUnitType || (HevcNalUnitType = {}));
const iterateNalUnitsInAnnexB = function* (packetData) {
    let i = 0;
    let nalStart = -1;
    while (i < packetData.length - 2) {
        const zeroIndex = packetData.indexOf(0, i);
        if (zeroIndex === -1 || zeroIndex >= packetData.length - 2) {
            break;
        }
        i = zeroIndex;
        let startCodeLength = 0;
        // Check for 4-byte start code (0x00000001)
        if (i + 3 < packetData.length
            && packetData[i + 1] === 0
            && packetData[i + 2] === 0
            && packetData[i + 3] === 1) {
            startCodeLength = 4;
        }
        else if (packetData[i + 1] === 0 && packetData[i + 2] === 1) {
            // Check for 3-byte start code (0x000001)
            startCodeLength = 3;
        }
        if (startCodeLength === 0) {
            i++;
            continue;
        }
        // If we had a previous NAL unit, yield it
        if (nalStart !== -1 && i > nalStart) {
            yield {
                offset: nalStart,
                length: i - nalStart,
            };
        }
        nalStart = i + startCodeLength;
        i = nalStart;
    }
    // Yield the last NAL unit if there is one
    if (nalStart !== -1 && nalStart < packetData.length) {
        yield {
            offset: nalStart,
            length: packetData.length - nalStart,
        };
    }
};
const iterateNalUnitsInLengthPrefixed = function* (packetData, lengthSize) {
    let offset = 0;
    const dataView = new DataView(packetData.buffer, packetData.byteOffset, packetData.byteLength);
    while (offset + lengthSize <= packetData.length) {
        let nalUnitLength;
        if (lengthSize === 1) {
            nalUnitLength = dataView.getUint8(offset);
        }
        else if (lengthSize === 2) {
            nalUnitLength = dataView.getUint16(offset, false);
        }
        else if (lengthSize === 3) {
            nalUnitLength = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .getUint24 */ .dq)(dataView, offset, false);
        }
        else {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assert */ .vA)(lengthSize === 4);
            nalUnitLength = dataView.getUint32(offset, false);
        }
        offset += lengthSize;
        yield {
            offset,
            length: nalUnitLength,
        };
        offset += nalUnitLength;
    }
};
const iterateAvcNalUnits = (packetData, decoderConfig) => {
    if (decoderConfig.description) {
        const bytes = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .toUint8Array */ .Fo)(decoderConfig.description);
        const lengthSizeMinusOne = bytes[4] & 0b11;
        const lengthSize = (lengthSizeMinusOne + 1);
        return iterateNalUnitsInLengthPrefixed(packetData, lengthSize);
    }
    else {
        return iterateNalUnitsInAnnexB(packetData);
    }
};
const extractNalUnitTypeForAvc = (byte) => {
    return byte & 0x1F;
};
const removeEmulationPreventionBytes = (data) => {
    const result = [];
    const len = data.length;
    for (let i = 0; i < len; i++) {
        // Look for the 0x000003 pattern
        if (i + 2 < len && data[i] === 0x00 && data[i + 1] === 0x00 && data[i + 2] === 0x03) {
            result.push(0x00, 0x00); // Push the first two bytes
            i += 2; // Skip the 0x03 byte
        }
        else {
            result.push(data[i]);
        }
    }
    return new Uint8Array(result);
};
const ANNEX_B_START_CODE = new Uint8Array([0, 0, 0, 1]);
const concatNalUnitsInAnnexB = (nalUnits) => {
    const totalLength = nalUnits.reduce((a, b) => a + ANNEX_B_START_CODE.byteLength + b.byteLength, 0);
    const result = new Uint8Array(totalLength);
    let offset = 0;
    for (const nalUnit of nalUnits) {
        result.set(ANNEX_B_START_CODE, offset);
        offset += ANNEX_B_START_CODE.byteLength;
        result.set(nalUnit, offset);
        offset += nalUnit.byteLength;
    }
    return result;
};
const concatNalUnitsInLengthPrefixed = (nalUnits, lengthSize) => {
    const totalLength = nalUnits.reduce((a, b) => a + lengthSize + b.byteLength, 0);
    const result = new Uint8Array(totalLength);
    let offset = 0;
    for (const nalUnit of nalUnits) {
        const dataView = new DataView(result.buffer, result.byteOffset, result.byteLength);
        switch (lengthSize) {
            case 1:
                dataView.setUint8(offset, nalUnit.byteLength);
                break;
            case 2:
                dataView.setUint16(offset, nalUnit.byteLength, false);
                break;
            case 3:
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .setUint24 */ .jD)(dataView, offset, nalUnit.byteLength, false);
                break;
            case 4:
                dataView.setUint32(offset, nalUnit.byteLength, false);
                break;
        }
        offset += lengthSize;
        result.set(nalUnit, offset);
        offset += nalUnit.byteLength;
    }
    return result;
};
const concatAvcNalUnits = (nalUnits, decoderConfig) => {
    if (decoderConfig.description) {
        // Stream is length-prefixed. Let's extract the size of the length prefix from the decoder config
        const bytes = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .toUint8Array */ .Fo)(decoderConfig.description);
        const lengthSizeMinusOne = bytes[4] & 0b11;
        const lengthSize = (lengthSizeMinusOne + 1);
        return concatNalUnitsInLengthPrefixed(nalUnits, lengthSize);
    }
    else {
        // Stream is in Annex B format
        return concatNalUnitsInAnnexB(nalUnits);
    }
};
/** Builds an AvcDecoderConfigurationRecord from an AVC packet in Annex B format. */
const extractAvcDecoderConfigurationRecord = (packetData) => {
    try {
        const spsUnits = [];
        const ppsUnits = [];
        const spsExtUnits = [];
        for (const loc of iterateNalUnitsInAnnexB(packetData)) {
            const nalUnit = packetData.subarray(loc.offset, loc.offset + loc.length);
            const type = extractNalUnitTypeForAvc(nalUnit[0]);
            if (type === AvcNalUnitType.SPS) {
                spsUnits.push(nalUnit);
            }
            else if (type === AvcNalUnitType.PPS) {
                ppsUnits.push(nalUnit);
            }
            else if (type === AvcNalUnitType.SPS_EXT) {
                spsExtUnits.push(nalUnit);
            }
        }
        if (spsUnits.length === 0) {
            return null;
        }
        if (ppsUnits.length === 0) {
            return null;
        }
        // Let's get the first SPS for profile and level information
        const spsData = spsUnits[0];
        const spsInfo = parseAvcSps(spsData);
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assert */ .vA)(spsInfo !== null);
        const hasExtendedData = spsInfo.profileIdc === 100
            || spsInfo.profileIdc === 110
            || spsInfo.profileIdc === 122
            || spsInfo.profileIdc === 144;
        return {
            configurationVersion: 1,
            avcProfileIndication: spsInfo.profileIdc,
            profileCompatibility: spsInfo.constraintFlags,
            avcLevelIndication: spsInfo.levelIdc,
            lengthSizeMinusOne: 3, // Typically 4 bytes for length field
            sequenceParameterSets: spsUnits,
            pictureParameterSets: ppsUnits,
            chromaFormat: hasExtendedData ? spsInfo.chromaFormatIdc : null,
            bitDepthLumaMinus8: hasExtendedData ? spsInfo.bitDepthLumaMinus8 : null,
            bitDepthChromaMinus8: hasExtendedData ? spsInfo.bitDepthChromaMinus8 : null,
            sequenceParameterSetExt: hasExtendedData ? spsExtUnits : null,
        };
    }
    catch (error) {
        console.error('Error building AVC Decoder Configuration Record:', error);
        return null;
    }
};
/** Serializes an AvcDecoderConfigurationRecord into the format specified in Section 5.3.3.1 of ISO 14496-15. */
const serializeAvcDecoderConfigurationRecord = (record) => {
    const bytes = [];
    // Write header
    bytes.push(record.configurationVersion);
    bytes.push(record.avcProfileIndication);
    bytes.push(record.profileCompatibility);
    bytes.push(record.avcLevelIndication);
    bytes.push(0xFC | (record.lengthSizeMinusOne & 0x03)); // Reserved bits (6) + lengthSizeMinusOne (2)
    // Reserved bits (3) + numOfSequenceParameterSets (5)
    bytes.push(0xE0 | (record.sequenceParameterSets.length & 0x1F));
    // Write SPS
    for (const sps of record.sequenceParameterSets) {
        const length = sps.byteLength;
        bytes.push(length >> 8); // High byte
        bytes.push(length & 0xFF); // Low byte
        for (let i = 0; i < length; i++) {
            bytes.push(sps[i]);
        }
    }
    bytes.push(record.pictureParameterSets.length);
    // Write PPS
    for (const pps of record.pictureParameterSets) {
        const length = pps.byteLength;
        bytes.push(length >> 8); // High byte
        bytes.push(length & 0xFF); // Low byte
        for (let i = 0; i < length; i++) {
            bytes.push(pps[i]);
        }
    }
    if (record.avcProfileIndication === 100
        || record.avcProfileIndication === 110
        || record.avcProfileIndication === 122
        || record.avcProfileIndication === 144) {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assert */ .vA)(record.chromaFormat !== null);
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assert */ .vA)(record.bitDepthLumaMinus8 !== null);
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assert */ .vA)(record.bitDepthChromaMinus8 !== null);
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assert */ .vA)(record.sequenceParameterSetExt !== null);
        bytes.push(0xFC | (record.chromaFormat & 0x03)); // Reserved bits + chroma_format
        bytes.push(0xF8 | (record.bitDepthLumaMinus8 & 0x07)); // Reserved bits + bit_depth_luma_minus8
        bytes.push(0xF8 | (record.bitDepthChromaMinus8 & 0x07)); // Reserved bits + bit_depth_chroma_minus8
        bytes.push(record.sequenceParameterSetExt.length);
        // Write SPS Ext
        for (const spsExt of record.sequenceParameterSetExt) {
            const length = spsExt.byteLength;
            bytes.push(length >> 8); // High byte
            bytes.push(length & 0xFF); // Low byte
            for (let i = 0; i < length; i++) {
                bytes.push(spsExt[i]);
            }
        }
    }
    return new Uint8Array(bytes);
};
/** Deserializes an AvcDecoderConfigurationRecord from the format specified in Section 5.3.3.1 of ISO 14496-15. */
const deserializeAvcDecoderConfigurationRecord = (data) => {
    try {
        const view = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .toDataView */ .Zc)(data);
        let offset = 0;
        // Read header
        const configurationVersion = view.getUint8(offset++);
        const avcProfileIndication = view.getUint8(offset++);
        const profileCompatibility = view.getUint8(offset++);
        const avcLevelIndication = view.getUint8(offset++);
        const lengthSizeMinusOne = view.getUint8(offset++) & 0x03;
        const numOfSequenceParameterSets = view.getUint8(offset++) & 0x1F;
        // Read SPS
        const sequenceParameterSets = [];
        for (let i = 0; i < numOfSequenceParameterSets; i++) {
            const length = view.getUint16(offset, false);
            offset += 2;
            sequenceParameterSets.push(data.subarray(offset, offset + length));
            offset += length;
        }
        const numOfPictureParameterSets = view.getUint8(offset++);
        // Read PPS
        const pictureParameterSets = [];
        for (let i = 0; i < numOfPictureParameterSets; i++) {
            const length = view.getUint16(offset, false);
            offset += 2;
            pictureParameterSets.push(data.subarray(offset, offset + length));
            offset += length;
        }
        const record = {
            configurationVersion,
            avcProfileIndication,
            profileCompatibility,
            avcLevelIndication,
            lengthSizeMinusOne,
            sequenceParameterSets,
            pictureParameterSets,
            chromaFormat: null,
            bitDepthLumaMinus8: null,
            bitDepthChromaMinus8: null,
            sequenceParameterSetExt: null,
        };
        // Check if there are extended profile fields
        if ((avcProfileIndication === 100
            || avcProfileIndication === 110
            || avcProfileIndication === 122
            || avcProfileIndication === 144)
            && offset + 4 <= data.length) {
            const chromaFormat = view.getUint8(offset++) & 0x03;
            const bitDepthLumaMinus8 = view.getUint8(offset++) & 0x07;
            const bitDepthChromaMinus8 = view.getUint8(offset++) & 0x07;
            const numOfSequenceParameterSetExt = view.getUint8(offset++);
            record.chromaFormat = chromaFormat;
            record.bitDepthLumaMinus8 = bitDepthLumaMinus8;
            record.bitDepthChromaMinus8 = bitDepthChromaMinus8;
            // Read SPS Ext
            const sequenceParameterSetExt = [];
            for (let i = 0; i < numOfSequenceParameterSetExt; i++) {
                const length = view.getUint16(offset, false);
                offset += 2;
                sequenceParameterSetExt.push(data.subarray(offset, offset + length));
                offset += length;
            }
            record.sequenceParameterSetExt = sequenceParameterSetExt;
        }
        return record;
    }
    catch (error) {
        console.error('Error deserializing AVC Decoder Configuration Record:', error);
        return null;
    }
};
/** Parses an AVC SPS (Sequence Parameter Set) to extract basic information. */
const parseAvcSps = (sps) => {
    try {
        const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .Bitstream */ ._c(removeEmulationPreventionBytes(sps));
        bitstream.skipBits(1); // forbidden_zero_bit
        bitstream.skipBits(2); // nal_ref_idc
        const nalUnitType = bitstream.readBits(5);
        if (nalUnitType !== 7) { // SPS NAL unit type is 7
            return null;
        }
        const profileIdc = bitstream.readAlignedByte();
        const constraintFlags = bitstream.readAlignedByte();
        const levelIdc = bitstream.readAlignedByte();
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // seq_parameter_set_id
        // "When chroma_format_idc is not present, it shall be inferred to be equal to 1 (4:2:0 chroma format)."
        let chromaFormatIdc = 1;
        // "When bit_depth_luma_minus8 is not present, it shall be inferred to be equal to 0.""
        let bitDepthLumaMinus8 = 0;
        // "When bit_depth_chroma_minus8 is not present, it shall be inferred to be equal to 0."
        let bitDepthChromaMinus8 = 0;
        // "When separate_colour_plane_flag is not present, it shall be inferred to be equal to 0."
        let separateColourPlaneFlag = 0;
        // Handle high profile chroma_format_idc
        if (profileIdc === 100
            || profileIdc === 110
            || profileIdc === 122
            || profileIdc === 244
            || profileIdc === 44
            || profileIdc === 83
            || profileIdc === 86
            || profileIdc === 118
            || profileIdc === 128) {
            chromaFormatIdc = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
            if (chromaFormatIdc === 3) {
                separateColourPlaneFlag = bitstream.readBits(1);
            }
            bitDepthLumaMinus8 = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
            bitDepthChromaMinus8 = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
            bitstream.skipBits(1); // qpprime_y_zero_transform_bypass_flag
            const seqScalingMatrixPresentFlag = bitstream.readBits(1);
            if (seqScalingMatrixPresentFlag) {
                for (let i = 0; i < (chromaFormatIdc !== 3 ? 8 : 12); i++) {
                    const seqScalingListPresentFlag = bitstream.readBits(1);
                    if (seqScalingListPresentFlag) {
                        const sizeOfScalingList = i < 6 ? 16 : 64;
                        let lastScale = 8;
                        let nextScale = 8;
                        for (let j = 0; j < sizeOfScalingList; j++) {
                            if (nextScale !== 0) {
                                const deltaScale = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readSignedExpGolomb */ .OO)(bitstream);
                                nextScale = (lastScale + deltaScale + 256) % 256;
                            }
                            lastScale = nextScale === 0 ? lastScale : nextScale;
                        }
                    }
                }
            }
        }
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // log2_max_frame_num_minus4
        const picOrderCntType = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
        if (picOrderCntType === 0) {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // log2_max_pic_order_cnt_lsb_minus4
        }
        else if (picOrderCntType === 1) {
            bitstream.skipBits(1); // delta_pic_order_always_zero_flag
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readSignedExpGolomb */ .OO)(bitstream); // offset_for_non_ref_pic
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readSignedExpGolomb */ .OO)(bitstream); // offset_for_top_to_bottom_field
            const numRefFramesInPicOrderCntCycle = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
            for (let i = 0; i < numRefFramesInPicOrderCntCycle; i++) {
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readSignedExpGolomb */ .OO)(bitstream); // offset_for_ref_frame[i]
            }
        }
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // max_num_ref_frames
        bitstream.skipBits(1); // gaps_in_frame_num_value_allowed_flag
        const picWidthInMbsMinus1 = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
        const picHeightInMapUnitsMinus1 = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
        const codedWidth = 16 * (picWidthInMbsMinus1 + 1);
        const codedHeight = 16 * (picHeightInMapUnitsMinus1 + 1);
        let displayWidth = codedWidth;
        let displayHeight = codedHeight;
        const frameMbsOnlyFlag = bitstream.readBits(1);
        if (!frameMbsOnlyFlag) {
            bitstream.skipBits(1); // mb_adaptive_frame_field_flag
        }
        bitstream.skipBits(1); // direct_8x8_inference_flag
        const frameCroppingFlag = bitstream.readBits(1);
        if (frameCroppingFlag) {
            const frameCropLeftOffset = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
            const frameCropRightOffset = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
            const frameCropTopOffset = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
            const frameCropBottomOffset = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
            let cropUnitX;
            let cropUnitY;
            const chromaArrayType = separateColourPlaneFlag === 0 ? chromaFormatIdc : 0;
            if (chromaArrayType === 0) {
                // "If ChromaArrayType is equal to 0, CropUnitX and CropUnitY are derived as:"
                cropUnitX = 1;
                cropUnitY = 2 - frameMbsOnlyFlag;
            }
            else {
                // "Otherwise (ChromaArrayType is equal to 1, 2, or 3), CropUnitX and CropUnitY are derived as:"
                const subWidthC = chromaFormatIdc === 3 ? 1 : 2;
                const subHeightC = chromaFormatIdc === 1 ? 2 : 1;
                cropUnitX = subWidthC;
                cropUnitY = subHeightC * (2 - frameMbsOnlyFlag);
            }
            displayWidth -= (cropUnitX * (frameCropLeftOffset + frameCropRightOffset));
            displayHeight -= (cropUnitY * (frameCropTopOffset + frameCropBottomOffset));
        }
        // 2 = unspecified
        let colourPrimaries = 2;
        let transferCharacteristics = 2;
        let matrixCoefficients = 2;
        let fullRangeFlag = 0;
        let numReorderFrames = null;
        let maxDecFrameBuffering = null;
        const vuiParametersPresentFlag = bitstream.readBits(1);
        if (vuiParametersPresentFlag) {
            const aspectRatioInfoPresentFlag = bitstream.readBits(1);
            if (aspectRatioInfoPresentFlag) {
                const aspectRatioIdc = bitstream.readBits(8);
                if (aspectRatioIdc === 255) { // Extended_SAR
                    bitstream.skipBits(16); // sar_width
                    bitstream.skipBits(16); // sar_height
                }
            }
            const overscanInfoPresentFlag = bitstream.readBits(1);
            if (overscanInfoPresentFlag) {
                bitstream.skipBits(1); // overscan_appropriate_flag
            }
            const videoSignalTypePresentFlag = bitstream.readBits(1);
            if (videoSignalTypePresentFlag) {
                bitstream.skipBits(3); // video_format
                fullRangeFlag = bitstream.readBits(1);
                const colourDescriptionPresentFlag = bitstream.readBits(1);
                if (colourDescriptionPresentFlag) {
                    colourPrimaries = bitstream.readBits(8);
                    transferCharacteristics = bitstream.readBits(8);
                    matrixCoefficients = bitstream.readBits(8);
                }
            }
            const chromaLocInfoPresentFlag = bitstream.readBits(1);
            if (chromaLocInfoPresentFlag) {
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // chroma_sample_loc_type_top_field
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // chroma_sample_loc_type_bottom_field
            }
            const timingInfoPresentFlag = bitstream.readBits(1);
            if (timingInfoPresentFlag) {
                bitstream.skipBits(32); // num_units_in_tick
                bitstream.skipBits(32); // time_scale
                bitstream.skipBits(1); // fixed_frame_rate_flag
            }
            const nalHrdParametersPresentFlag = bitstream.readBits(1);
            if (nalHrdParametersPresentFlag) {
                skipAvcHrdParameters(bitstream);
            }
            const vclHrdParametersPresentFlag = bitstream.readBits(1);
            if (vclHrdParametersPresentFlag) {
                skipAvcHrdParameters(bitstream);
            }
            if (nalHrdParametersPresentFlag || vclHrdParametersPresentFlag) {
                bitstream.skipBits(1); // low_delay_hrd_flag
            }
            bitstream.skipBits(1); // pic_struct_present_flag
            const bitstreamRestrictionFlag = bitstream.readBits(1);
            if (bitstreamRestrictionFlag) {
                bitstream.skipBits(1); // motion_vectors_over_pic_boundaries_flag
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // max_bytes_per_pic_denom
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // max_bits_per_mb_denom
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // log2_max_mv_length_horizontal
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // log2_max_mv_length_vertical
                numReorderFrames = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
                maxDecFrameBuffering = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
            }
        }
        if (numReorderFrames === null) {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assert */ .vA)(maxDecFrameBuffering === null);
            const constraintSet3Flag = constraintFlags & 0b00010000;
            if ((profileIdc === 44 || profileIdc === 86 || profileIdc === 100
                || profileIdc === 110 || profileIdc === 122 || profileIdc === 244) && constraintSet3Flag) {
                // "If profile_idc is equal to 44, 86, 100, 110, 122, or 244 and constraint_set3_flag is equal to 1, the
                // value of num_reorder_frames shall be inferred to be equal to 0."
                numReorderFrames = 0;
                maxDecFrameBuffering = 0;
            }
            else {
                const picWidthInMbs = picWidthInMbsMinus1 + 1;
                const picHeightInMapUnits = picHeightInMapUnitsMinus1 + 1;
                const frameHeightInMbs = (2 - frameMbsOnlyFlag) * picHeightInMapUnits;
                const levelInfo = _codec_js__WEBPACK_IMPORTED_MODULE_0__/* .AVC_LEVEL_TABLE */ .$3.find(x => x.level >= levelIdc) ?? (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .last */ ._g)(_codec_js__WEBPACK_IMPORTED_MODULE_0__/* .AVC_LEVEL_TABLE */ .$3);
                // "MaxDpbFrames is equal to
                // Min( MaxDpbMbs / ( picWidthInMbs * frameHeightInMbs ), 16 ) and MaxDpbMbs is given in Table A-1."
                const maxDpbFrames = Math.min(Math.floor(levelInfo.maxDpbMbs / (picWidthInMbs * frameHeightInMbs)), 16);
                // "Otherwise, [...] the value of num_reorder_frames shall be inferred to be equal to MaxDpbFrames."
                numReorderFrames = maxDpbFrames;
                maxDecFrameBuffering = maxDpbFrames;
            }
        }
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assert */ .vA)(maxDecFrameBuffering !== null);
        return {
            profileIdc,
            constraintFlags,
            levelIdc,
            frameMbsOnlyFlag,
            chromaFormatIdc,
            bitDepthLumaMinus8,
            bitDepthChromaMinus8,
            codedWidth,
            codedHeight,
            displayWidth,
            displayHeight,
            colourPrimaries,
            matrixCoefficients,
            transferCharacteristics,
            fullRangeFlag,
            numReorderFrames,
            maxDecFrameBuffering,
        };
    }
    catch (error) {
        console.error('Error parsing AVC SPS:', error);
        return null;
    }
};
const skipAvcHrdParameters = (bitstream) => {
    const cpb_cnt_minus1 = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
    bitstream.skipBits(4); // bit_rate_scale
    bitstream.skipBits(4); // cpb_size_scale
    for (let i = 0; i <= cpb_cnt_minus1; i++) {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // bit_rate_value_minus1[i]
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // cpb_size_value_minus1[i]
        bitstream.skipBits(1); // cbr_flag[i]
    }
    bitstream.skipBits(5); // initial_cpb_removal_delay_length_minus1
    bitstream.skipBits(5); // cpb_removal_delay_length_minus1
    bitstream.skipBits(5); // dpb_output_delay_length_minus1
    bitstream.skipBits(5); // time_offset_length
};
const iterateHevcNalUnits = (packetData, decoderConfig) => {
    if (decoderConfig.description) {
        const bytes = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .toUint8Array */ .Fo)(decoderConfig.description);
        const lengthSizeMinusOne = bytes[21] & 0b11;
        const lengthSize = (lengthSizeMinusOne + 1);
        return iterateNalUnitsInLengthPrefixed(packetData, lengthSize);
    }
    else {
        return iterateNalUnitsInAnnexB(packetData);
    }
};
const extractNalUnitTypeForHevc = (byte) => {
    return (byte >> 1) & 0x3F;
};
/** Parses an HEVC SPS (Sequence Parameter Set) to extract video information. */
const parseHevcSps = (sps) => {
    try {
        const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .Bitstream */ ._c(removeEmulationPreventionBytes(sps));
        bitstream.skipBits(16); // NAL header
        bitstream.readBits(4); // sps_video_parameter_set_id
        const spsMaxSubLayersMinus1 = bitstream.readBits(3);
        const spsTemporalIdNestingFlag = bitstream.readBits(1);
        const { general_profile_space, general_tier_flag, general_profile_idc, general_profile_compatibility_flags, general_constraint_indicator_flags, general_level_idc, } = parseProfileTierLevel(bitstream, spsMaxSubLayersMinus1);
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // sps_seq_parameter_set_id
        const chromaFormatIdc = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
        let separateColourPlaneFlag = 0;
        if (chromaFormatIdc === 3) {
            separateColourPlaneFlag = bitstream.readBits(1);
        }
        const picWidthInLumaSamples = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
        const picHeightInLumaSamples = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
        let displayWidth = picWidthInLumaSamples;
        let displayHeight = picHeightInLumaSamples;
        if (bitstream.readBits(1)) { // conformance_window_flag
            const confWinLeftOffset = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
            const confWinRightOffset = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
            const confWinTopOffset = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
            const confWinBottomOffset = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
            // SubWidthC and SubHeightC depend on chroma_format_idc and separate_colour_plane_flag
            let subWidthC = 1;
            let subHeightC = 1;
            const chromaArrayType = separateColourPlaneFlag === 0 ? chromaFormatIdc : 0;
            if (chromaArrayType === 1) {
                subWidthC = 2;
                subHeightC = 2;
            }
            else if (chromaArrayType === 2) {
                subWidthC = 2;
                subHeightC = 1;
            }
            displayWidth -= (confWinLeftOffset + confWinRightOffset) * subWidthC;
            displayHeight -= (confWinTopOffset + confWinBottomOffset) * subHeightC;
        }
        const bitDepthLumaMinus8 = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
        const bitDepthChromaMinus8 = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // log2_max_pic_order_cnt_lsb_minus4
        const spsSubLayerOrderingInfoPresentFlag = bitstream.readBits(1);
        const startI = spsSubLayerOrderingInfoPresentFlag ? 0 : spsMaxSubLayersMinus1;
        let spsMaxNumReorderPics = 0;
        for (let i = startI; i <= spsMaxSubLayersMinus1; i++) {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // sps_max_dec_pic_buffering_minus1[i]
            spsMaxNumReorderPics = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // sps_max_num_reorder_pics[i]
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // sps_max_latency_increase_plus1[i]
        }
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // log2_min_luma_coding_block_size_minus3
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // log2_diff_max_min_luma_coding_block_size
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // log2_min_luma_transform_block_size_minus2
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // log2_diff_max_min_luma_transform_block_size
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // max_transform_hierarchy_depth_inter
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // max_transform_hierarchy_depth_intra
        if (bitstream.readBits(1)) { // scaling_list_enabled_flag
            if (bitstream.readBits(1)) {
                skipScalingListData(bitstream);
            }
        }
        bitstream.skipBits(1); // amp_enabled_flag
        bitstream.skipBits(1); // sample_adaptive_offset_enabled_flag
        if (bitstream.readBits(1)) { // pcm_enabled_flag
            bitstream.skipBits(4); // pcm_sample_bit_depth_luma_minus1
            bitstream.skipBits(4); // pcm_sample_bit_depth_chroma_minus1
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // log2_min_pcm_luma_coding_block_size_minus3
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // log2_diff_max_min_pcm_luma_coding_block_size
            bitstream.skipBits(1); // pcm_loop_filter_disabled_flag
        }
        const numShortTermRefPicSets = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
        skipAllStRefPicSets(bitstream, numShortTermRefPicSets);
        if (bitstream.readBits(1)) { // long_term_ref_pics_present_flag
            const numLongTermRefPicsSps = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
            for (let i = 0; i < numLongTermRefPicsSps; i++) {
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // lt_ref_pic_poc_lsb_sps[i]
                bitstream.skipBits(1); // used_by_curr_pic_lt_sps_flag[i]
            }
        }
        bitstream.skipBits(1); // sps_temporal_mvp_enabled_flag
        bitstream.skipBits(1); // strong_intra_smoothing_enabled_flag
        let colourPrimaries = 2;
        let transferCharacteristics = 2;
        let matrixCoefficients = 2;
        let fullRangeFlag = 0;
        let minSpatialSegmentationIdc = 0;
        if (bitstream.readBits(1)) { // vui_parameters_present_flag
            const vui = parseHevcVui(bitstream, spsMaxSubLayersMinus1);
            colourPrimaries = vui.colourPrimaries;
            transferCharacteristics = vui.transferCharacteristics;
            matrixCoefficients = vui.matrixCoefficients;
            fullRangeFlag = vui.fullRangeFlag;
            minSpatialSegmentationIdc = vui.minSpatialSegmentationIdc;
        }
        return {
            displayWidth,
            displayHeight,
            colourPrimaries,
            transferCharacteristics,
            matrixCoefficients,
            fullRangeFlag,
            maxDecFrameBuffering: spsMaxNumReorderPics + 1,
            spsMaxSubLayersMinus1,
            spsTemporalIdNestingFlag,
            generalProfileSpace: general_profile_space,
            generalTierFlag: general_tier_flag,
            generalProfileIdc: general_profile_idc,
            generalProfileCompatibilityFlags: general_profile_compatibility_flags,
            generalConstraintIndicatorFlags: general_constraint_indicator_flags,
            generalLevelIdc: general_level_idc,
            chromaFormatIdc,
            bitDepthLumaMinus8,
            bitDepthChromaMinus8,
            minSpatialSegmentationIdc,
        };
    }
    catch (error) {
        console.error('Error parsing HEVC SPS:', error);
        return null;
    }
};
/** Builds a HevcDecoderConfigurationRecord from an HEVC packet in Annex B format. */
const extractHevcDecoderConfigurationRecord = (packetData) => {
    try {
        const vpsUnits = [];
        const spsUnits = [];
        const ppsUnits = [];
        const seiUnits = [];
        for (const loc of iterateNalUnitsInAnnexB(packetData)) {
            const nalUnit = packetData.subarray(loc.offset, loc.offset + loc.length);
            const type = extractNalUnitTypeForHevc(nalUnit[0]);
            if (type === HevcNalUnitType.VPS_NUT) {
                vpsUnits.push(nalUnit);
            }
            else if (type === HevcNalUnitType.SPS_NUT) {
                spsUnits.push(nalUnit);
            }
            else if (type === HevcNalUnitType.PPS_NUT) {
                ppsUnits.push(nalUnit);
            }
            else if (type === HevcNalUnitType.PREFIX_SEI_NUT || type === HevcNalUnitType.SUFFIX_SEI_NUT) {
                seiUnits.push(nalUnit);
            }
        }
        if (spsUnits.length === 0 || ppsUnits.length === 0)
            return null;
        const spsInfo = parseHevcSps(spsUnits[0]);
        if (!spsInfo)
            return null;
        // Parse PPS for parallelismType
        let parallelismType = 0;
        if (ppsUnits.length > 0) {
            const pps = ppsUnits[0];
            const ppsBitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .Bitstream */ ._c(removeEmulationPreventionBytes(pps));
            ppsBitstream.skipBits(16); // NAL header
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(ppsBitstream); // pps_pic_parameter_set_id
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(ppsBitstream); // pps_seq_parameter_set_id
            ppsBitstream.skipBits(1); // dependent_slice_segments_enabled_flag
            ppsBitstream.skipBits(1); // output_flag_present_flag
            ppsBitstream.skipBits(3); // num_extra_slice_header_bits
            ppsBitstream.skipBits(1); // sign_data_hiding_enabled_flag
            ppsBitstream.skipBits(1); // cabac_init_present_flag
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(ppsBitstream); // num_ref_idx_l0_default_active_minus1
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(ppsBitstream); // num_ref_idx_l1_default_active_minus1
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readSignedExpGolomb */ .OO)(ppsBitstream); // init_qp_minus26
            ppsBitstream.skipBits(1); // constrained_intra_pred_flag
            ppsBitstream.skipBits(1); // transform_skip_enabled_flag
            if (ppsBitstream.readBits(1)) { // cu_qp_delta_enabled_flag
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(ppsBitstream); // diff_cu_qp_delta_depth
            }
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readSignedExpGolomb */ .OO)(ppsBitstream); // pps_cb_qp_offset
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readSignedExpGolomb */ .OO)(ppsBitstream); // pps_cr_qp_offset
            ppsBitstream.skipBits(1); // pps_slice_chroma_qp_offsets_present_flag
            ppsBitstream.skipBits(1); // weighted_pred_flag
            ppsBitstream.skipBits(1); // weighted_bipred_flag
            ppsBitstream.skipBits(1); // transquant_bypass_enabled_flag
            const tiles_enabled_flag = ppsBitstream.readBits(1);
            const entropy_coding_sync_enabled_flag = ppsBitstream.readBits(1);
            if (!tiles_enabled_flag && !entropy_coding_sync_enabled_flag)
                parallelismType = 0;
            else if (tiles_enabled_flag && !entropy_coding_sync_enabled_flag)
                parallelismType = 2;
            else if (!tiles_enabled_flag && entropy_coding_sync_enabled_flag)
                parallelismType = 3;
            else
                parallelismType = 0;
        }
        const arrays = [
            ...(vpsUnits.length
                ? [
                    {
                        arrayCompleteness: 1,
                        nalUnitType: HevcNalUnitType.VPS_NUT,
                        nalUnits: vpsUnits,
                    },
                ]
                : []),
            ...(spsUnits.length
                ? [
                    {
                        arrayCompleteness: 1,
                        nalUnitType: HevcNalUnitType.SPS_NUT,
                        nalUnits: spsUnits,
                    },
                ]
                : []),
            ...(ppsUnits.length
                ? [
                    {
                        arrayCompleteness: 1,
                        nalUnitType: HevcNalUnitType.PPS_NUT,
                        nalUnits: ppsUnits,
                    },
                ]
                : []),
            ...(seiUnits.length
                ? [
                    {
                        arrayCompleteness: 1,
                        nalUnitType: extractNalUnitTypeForHevc(seiUnits[0][0]),
                        nalUnits: seiUnits,
                    },
                ]
                : []),
        ];
        const record = {
            configurationVersion: 1,
            generalProfileSpace: spsInfo.generalProfileSpace,
            generalTierFlag: spsInfo.generalTierFlag,
            generalProfileIdc: spsInfo.generalProfileIdc,
            generalProfileCompatibilityFlags: spsInfo.generalProfileCompatibilityFlags,
            generalConstraintIndicatorFlags: spsInfo.generalConstraintIndicatorFlags,
            generalLevelIdc: spsInfo.generalLevelIdc,
            minSpatialSegmentationIdc: spsInfo.minSpatialSegmentationIdc,
            parallelismType,
            chromaFormatIdc: spsInfo.chromaFormatIdc,
            bitDepthLumaMinus8: spsInfo.bitDepthLumaMinus8,
            bitDepthChromaMinus8: spsInfo.bitDepthChromaMinus8,
            avgFrameRate: 0,
            constantFrameRate: 0,
            numTemporalLayers: spsInfo.spsMaxSubLayersMinus1 + 1,
            temporalIdNested: spsInfo.spsTemporalIdNestingFlag,
            lengthSizeMinusOne: 3,
            arrays,
        };
        return record;
    }
    catch (error) {
        console.error('Error building HEVC Decoder Configuration Record:', error);
        return null;
    }
};
const parseProfileTierLevel = (bitstream, maxNumSubLayersMinus1) => {
    const general_profile_space = bitstream.readBits(2);
    const general_tier_flag = bitstream.readBits(1);
    const general_profile_idc = bitstream.readBits(5);
    let general_profile_compatibility_flags = 0;
    for (let i = 0; i < 32; i++) {
        general_profile_compatibility_flags = (general_profile_compatibility_flags << 1) | bitstream.readBits(1);
    }
    const general_constraint_indicator_flags = new Uint8Array(6);
    for (let i = 0; i < 6; i++) {
        general_constraint_indicator_flags[i] = bitstream.readBits(8);
    }
    const general_level_idc = bitstream.readBits(8);
    const sub_layer_profile_present_flag = [];
    const sub_layer_level_present_flag = [];
    for (let i = 0; i < maxNumSubLayersMinus1; i++) {
        sub_layer_profile_present_flag.push(bitstream.readBits(1));
        sub_layer_level_present_flag.push(bitstream.readBits(1));
    }
    if (maxNumSubLayersMinus1 > 0) {
        for (let i = maxNumSubLayersMinus1; i < 8; i++) {
            bitstream.skipBits(2); // reserved_zero_2bits
        }
    }
    for (let i = 0; i < maxNumSubLayersMinus1; i++) {
        if (sub_layer_profile_present_flag[i])
            bitstream.skipBits(88);
        if (sub_layer_level_present_flag[i])
            bitstream.skipBits(8);
    }
    return {
        general_profile_space,
        general_tier_flag,
        general_profile_idc,
        general_profile_compatibility_flags,
        general_constraint_indicator_flags,
        general_level_idc,
    };
};
const skipScalingListData = (bitstream) => {
    for (let sizeId = 0; sizeId < 4; sizeId++) {
        for (let matrixId = 0; matrixId < (sizeId === 3 ? 2 : 6); matrixId++) {
            const scaling_list_pred_mode_flag = bitstream.readBits(1);
            if (!scaling_list_pred_mode_flag) {
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // scaling_list_pred_matrix_id_delta
            }
            else {
                const coefNum = Math.min(64, 1 << (4 + (sizeId << 1)));
                if (sizeId > 1) {
                    (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readSignedExpGolomb */ .OO)(bitstream); // scaling_list_dc_coef_minus8
                }
                for (let i = 0; i < coefNum; i++) {
                    (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readSignedExpGolomb */ .OO)(bitstream); // scaling_list_delta_coef
                }
            }
        }
    }
};
const skipAllStRefPicSets = (bitstream, num_short_term_ref_pic_sets) => {
    const NumDeltaPocs = [];
    for (let stRpsIdx = 0; stRpsIdx < num_short_term_ref_pic_sets; stRpsIdx++) {
        NumDeltaPocs[stRpsIdx] = skipStRefPicSet(bitstream, stRpsIdx, num_short_term_ref_pic_sets, NumDeltaPocs);
    }
};
const skipStRefPicSet = (bitstream, stRpsIdx, num_short_term_ref_pic_sets, NumDeltaPocs) => {
    let NumDeltaPocsThis = 0;
    let inter_ref_pic_set_prediction_flag = 0;
    let RefRpsIdx = 0;
    if (stRpsIdx !== 0) {
        inter_ref_pic_set_prediction_flag = bitstream.readBits(1);
    }
    if (inter_ref_pic_set_prediction_flag) {
        if (stRpsIdx === num_short_term_ref_pic_sets) {
            const delta_idx_minus1 = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
            RefRpsIdx = stRpsIdx - (delta_idx_minus1 + 1);
        }
        else {
            RefRpsIdx = stRpsIdx - 1;
        }
        bitstream.readBits(1); // delta_rps_sign
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // abs_delta_rps_minus1
        // The number of iterations is NumDeltaPocs[RefRpsIdx] + 1
        const numDelta = NumDeltaPocs[RefRpsIdx] ?? 0;
        for (let j = 0; j <= numDelta; j++) {
            const used_by_curr_pic_flag = bitstream.readBits(1);
            if (!used_by_curr_pic_flag) {
                bitstream.readBits(1); // use_delta_flag
            }
        }
        NumDeltaPocsThis = NumDeltaPocs[RefRpsIdx];
    }
    else {
        const num_negative_pics = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
        const num_positive_pics = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
        for (let i = 0; i < num_negative_pics; i++) {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // delta_poc_s0_minus1[i]
            bitstream.readBits(1); // used_by_curr_pic_s0_flag[i]
        }
        for (let i = 0; i < num_positive_pics; i++) {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // delta_poc_s1_minus1[i]
            bitstream.readBits(1); // used_by_curr_pic_s1_flag[i]
        }
        NumDeltaPocsThis = num_negative_pics + num_positive_pics;
    }
    return NumDeltaPocsThis;
};
const parseHevcVui = (bitstream, sps_max_sub_layers_minus1) => {
    // Defaults: 2 = unspecified
    let colourPrimaries = 2;
    let transferCharacteristics = 2;
    let matrixCoefficients = 2;
    let fullRangeFlag = 0;
    let minSpatialSegmentationIdc = 0;
    if (bitstream.readBits(1)) { // aspect_ratio_info_present_flag
        const aspect_ratio_idc = bitstream.readBits(8);
        if (aspect_ratio_idc === 255) {
            bitstream.readBits(16); // sar_width
            bitstream.readBits(16); // sar_height
        }
    }
    if (bitstream.readBits(1)) { // overscan_info_present_flag
        bitstream.readBits(1); // overscan_appropriate_flag
    }
    if (bitstream.readBits(1)) { // video_signal_type_present_flag
        bitstream.readBits(3); // video_format
        fullRangeFlag = bitstream.readBits(1);
        if (bitstream.readBits(1)) { // colour_description_present_flag
            colourPrimaries = bitstream.readBits(8);
            transferCharacteristics = bitstream.readBits(8);
            matrixCoefficients = bitstream.readBits(8);
        }
    }
    if (bitstream.readBits(1)) { // chroma_loc_info_present_flag
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // chroma_sample_loc_type_top_field
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // chroma_sample_loc_type_bottom_field
    }
    bitstream.readBits(1); // neutral_chroma_indication_flag
    bitstream.readBits(1); // field_seq_flag
    bitstream.readBits(1); // frame_field_info_present_flag
    if (bitstream.readBits(1)) { // default_display_window_flag
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // def_disp_win_left_offset
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // def_disp_win_right_offset
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // def_disp_win_top_offset
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // def_disp_win_bottom_offset
    }
    if (bitstream.readBits(1)) { // vui_timing_info_present_flag
        bitstream.readBits(32); // vui_num_units_in_tick
        bitstream.readBits(32); // vui_time_scale
        if (bitstream.readBits(1)) { // vui_poc_proportional_to_timing_flag
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // vui_num_ticks_poc_diff_one_minus1
        }
        if (bitstream.readBits(1)) {
            skipHevcHrdParameters(bitstream, true, sps_max_sub_layers_minus1);
        }
    }
    if (bitstream.readBits(1)) { // bitstream_restriction_flag
        bitstream.readBits(1); // tiles_fixed_structure_flag
        bitstream.readBits(1); // motion_vectors_over_pic_boundaries_flag
        bitstream.readBits(1); // restricted_ref_pic_lists_flag
        minSpatialSegmentationIdc = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // max_bytes_per_pic_denom
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // max_bits_per_min_cu_denom
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // log2_max_mv_length_horizontal
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // log2_max_mv_length_vertical
    }
    return {
        colourPrimaries,
        transferCharacteristics,
        matrixCoefficients,
        fullRangeFlag,
        minSpatialSegmentationIdc,
    };
};
const skipHevcHrdParameters = (bitstream, commonInfPresentFlag, maxNumSubLayersMinus1) => {
    let nal_hrd_parameters_present_flag = false;
    let vcl_hrd_parameters_present_flag = false;
    let sub_pic_hrd_params_present_flag = false;
    if (commonInfPresentFlag) {
        nal_hrd_parameters_present_flag = bitstream.readBits(1) === 1;
        vcl_hrd_parameters_present_flag = bitstream.readBits(1) === 1;
        if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) {
            sub_pic_hrd_params_present_flag = bitstream.readBits(1) === 1;
            if (sub_pic_hrd_params_present_flag) {
                bitstream.readBits(8); // tick_divisor_minus2
                bitstream.readBits(5); // du_cpb_removal_delay_increment_length_minus1
                bitstream.readBits(1); // sub_pic_cpb_params_in_pic_timing_sei_flag
                bitstream.readBits(5); // dpb_output_delay_du_length_minus1
            }
            bitstream.readBits(4); // bit_rate_scale
            bitstream.readBits(4); // cpb_size_scale
            if (sub_pic_hrd_params_present_flag) {
                bitstream.readBits(4); // cpb_size_du_scale
            }
            bitstream.readBits(5); // initial_cpb_removal_delay_length_minus1
            bitstream.readBits(5); // au_cpb_removal_delay_length_minus1
            bitstream.readBits(5); // dpb_output_delay_length_minus1
        }
    }
    for (let i = 0; i <= maxNumSubLayersMinus1; i++) {
        const fixed_pic_rate_general_flag = bitstream.readBits(1) === 1;
        let fixed_pic_rate_within_cvs_flag = true; // Default assumption if general is true
        if (!fixed_pic_rate_general_flag) {
            fixed_pic_rate_within_cvs_flag = bitstream.readBits(1) === 1;
        }
        let low_delay_hrd_flag = false; // Default assumption
        if (fixed_pic_rate_within_cvs_flag) {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // elemental_duration_in_tc_minus1[i]
        }
        else {
            low_delay_hrd_flag = bitstream.readBits(1) === 1;
        }
        let CpbCnt = 1; // Default if low_delay is true
        if (!low_delay_hrd_flag) {
            const cpb_cnt_minus1 = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // cpb_cnt_minus1[i]
            CpbCnt = cpb_cnt_minus1 + 1;
        }
        if (nal_hrd_parameters_present_flag) {
            skipSubLayerHrdParameters(bitstream, CpbCnt, sub_pic_hrd_params_present_flag);
        }
        if (vcl_hrd_parameters_present_flag) {
            skipSubLayerHrdParameters(bitstream, CpbCnt, sub_pic_hrd_params_present_flag);
        }
    }
};
const skipSubLayerHrdParameters = (bitstream, CpbCnt, sub_pic_hrd_params_present_flag) => {
    for (let i = 0; i < CpbCnt; i++) {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // bit_rate_value_minus1[i]
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // cpb_size_value_minus1[i]
        if (sub_pic_hrd_params_present_flag) {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // cpb_size_du_value_minus1[i]
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream); // bit_rate_du_value_minus1[i]
        }
        bitstream.readBits(1); // cbr_flag[i]
    }
};
/** Serializes an HevcDecoderConfigurationRecord into the format specified in Section 8.3.3.1 of ISO 14496-15. */
const serializeHevcDecoderConfigurationRecord = (record) => {
    const bytes = [];
    bytes.push(record.configurationVersion);
    bytes.push(((record.generalProfileSpace & 0x3) << 6)
        | ((record.generalTierFlag & 0x1) << 5)
        | (record.generalProfileIdc & 0x1F));
    bytes.push((record.generalProfileCompatibilityFlags >>> 24) & 0xFF);
    bytes.push((record.generalProfileCompatibilityFlags >>> 16) & 0xFF);
    bytes.push((record.generalProfileCompatibilityFlags >>> 8) & 0xFF);
    bytes.push(record.generalProfileCompatibilityFlags & 0xFF);
    bytes.push(...record.generalConstraintIndicatorFlags);
    bytes.push(record.generalLevelIdc & 0xFF);
    bytes.push(0xF0 | ((record.minSpatialSegmentationIdc >> 8) & 0x0F)); // Reserved + high nibble
    bytes.push(record.minSpatialSegmentationIdc & 0xFF); // Low byte
    bytes.push(0xFC | (record.parallelismType & 0x03));
    bytes.push(0xFC | (record.chromaFormatIdc & 0x03));
    bytes.push(0xF8 | (record.bitDepthLumaMinus8 & 0x07));
    bytes.push(0xF8 | (record.bitDepthChromaMinus8 & 0x07));
    bytes.push((record.avgFrameRate >> 8) & 0xFF); // High byte
    bytes.push(record.avgFrameRate & 0xFF); // Low byte
    bytes.push(((record.constantFrameRate & 0x03) << 6)
        | ((record.numTemporalLayers & 0x07) << 3)
        | ((record.temporalIdNested & 0x01) << 2)
        | (record.lengthSizeMinusOne & 0x03));
    bytes.push(record.arrays.length & 0xFF);
    for (const arr of record.arrays) {
        bytes.push(((arr.arrayCompleteness & 0x01) << 7)
            | (0 << 6)
            | (arr.nalUnitType & 0x3F));
        bytes.push((arr.nalUnits.length >> 8) & 0xFF); // High byte
        bytes.push(arr.nalUnits.length & 0xFF); // Low byte
        for (const nal of arr.nalUnits) {
            bytes.push((nal.length >> 8) & 0xFF); // High byte
            bytes.push(nal.length & 0xFF); // Low byte
            for (let i = 0; i < nal.length; i++) {
                bytes.push(nal[i]);
            }
        }
    }
    return new Uint8Array(bytes);
};
/** Deserializes an HevcDecoderConfigurationRecord from the format specified in Section 8.3.3.1 of ISO 14496-15. */
const deserializeHevcDecoderConfigurationRecord = (data) => {
    try {
        const view = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .toDataView */ .Zc)(data);
        let offset = 0;
        const configurationVersion = view.getUint8(offset++);
        const byte1 = view.getUint8(offset++);
        const generalProfileSpace = (byte1 >> 6) & 0x3;
        const generalTierFlag = (byte1 >> 5) & 0x1;
        const generalProfileIdc = byte1 & 0x1F;
        const generalProfileCompatibilityFlags = view.getUint32(offset, false);
        offset += 4;
        const generalConstraintIndicatorFlags = data.subarray(offset, offset + 6);
        offset += 6;
        const generalLevelIdc = view.getUint8(offset++);
        const minSpatialSegmentationIdc = ((view.getUint8(offset++) & 0x0F) << 8) | view.getUint8(offset++);
        const parallelismType = view.getUint8(offset++) & 0x03;
        const chromaFormatIdc = view.getUint8(offset++) & 0x03;
        const bitDepthLumaMinus8 = view.getUint8(offset++) & 0x07;
        const bitDepthChromaMinus8 = view.getUint8(offset++) & 0x07;
        const avgFrameRate = view.getUint16(offset, false);
        offset += 2;
        const byte21 = view.getUint8(offset++);
        const constantFrameRate = (byte21 >> 6) & 0x03;
        const numTemporalLayers = (byte21 >> 3) & 0x07;
        const temporalIdNested = (byte21 >> 2) & 0x01;
        const lengthSizeMinusOne = byte21 & 0x03;
        const numOfArrays = view.getUint8(offset++);
        const arrays = [];
        for (let i = 0; i < numOfArrays; i++) {
            const arrByte = view.getUint8(offset++);
            const arrayCompleteness = (arrByte >> 7) & 0x01;
            const nalUnitType = arrByte & 0x3F;
            const numNalus = view.getUint16(offset, false);
            offset += 2;
            const nalUnits = [];
            for (let j = 0; j < numNalus; j++) {
                const nalUnitLength = view.getUint16(offset, false);
                offset += 2;
                nalUnits.push(data.subarray(offset, offset + nalUnitLength));
                offset += nalUnitLength;
            }
            arrays.push({
                arrayCompleteness,
                nalUnitType,
                nalUnits,
            });
        }
        return {
            configurationVersion,
            generalProfileSpace,
            generalTierFlag,
            generalProfileIdc,
            generalProfileCompatibilityFlags,
            generalConstraintIndicatorFlags,
            generalLevelIdc,
            minSpatialSegmentationIdc,
            parallelismType,
            chromaFormatIdc,
            bitDepthLumaMinus8,
            bitDepthChromaMinus8,
            avgFrameRate,
            constantFrameRate,
            numTemporalLayers,
            temporalIdNested,
            lengthSizeMinusOne,
            arrays,
        };
    }
    catch (error) {
        console.error('Error deserializing HEVC Decoder Configuration Record:', error);
        return null;
    }
};
const extractVp9CodecInfoFromPacket = (packet) => {
    // eslint-disable-next-line @stylistic/max-len
    // https://storage.googleapis.com/downloads.webmproject.org/docs/vp9/vp9-bitstream-specification-v0.7-20170222-draft.pdf
    // http://downloads.webmproject.org/docs/vp9/vp9-bitstream_superframe-and-uncompressed-header_v1.0.pdf
    const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .Bitstream */ ._c(packet);
    // Frame marker (0b10)
    const frameMarker = bitstream.readBits(2);
    if (frameMarker !== 2) {
        return null;
    }
    // Profile
    const profileLowBit = bitstream.readBits(1);
    const profileHighBit = bitstream.readBits(1);
    const profile = (profileHighBit << 1) + profileLowBit;
    // Skip reserved bit for profile 3
    if (profile === 3) {
        bitstream.skipBits(1);
    }
    // show_existing_frame
    const showExistingFrame = bitstream.readBits(1);
    if (showExistingFrame === 1) {
        return null;
    }
    // frame_type (0 = key frame)
    const frameType = bitstream.readBits(1);
    if (frameType !== 0) {
        return null;
    }
    // Skip show_frame and error_resilient_mode
    bitstream.skipBits(2);
    // Sync code (0x498342)
    const syncCode = bitstream.readBits(24);
    if (syncCode !== 0x498342) {
        return null;
    }
    // Color config
    let bitDepth = 8;
    if (profile >= 2) {
        const tenOrTwelveBit = bitstream.readBits(1);
        bitDepth = tenOrTwelveBit ? 12 : 10;
    }
    // Color space
    const colorSpace = bitstream.readBits(3);
    let chromaSubsampling = 0;
    let videoFullRangeFlag = 0;
    if (colorSpace !== 7) { // 7 is CS_RGB
        const colorRange = bitstream.readBits(1);
        videoFullRangeFlag = colorRange;
        if (profile === 1 || profile === 3) {
            const subsamplingX = bitstream.readBits(1);
            const subsamplingY = bitstream.readBits(1);
            // 0 = 4:2:0 vertical
            // 1 = 4:2:0 colocated
            // 2 = 4:2:2
            // 3 = 4:4:4
            chromaSubsampling = !subsamplingX && !subsamplingY
                ? 3 // 0,0 = 4:4:4
                : subsamplingX && !subsamplingY
                    ? 2 // 1,0 = 4:2:2
                    : 1; // 1,1 = 4:2:0 colocated (default)
            // Skip reserved bit
            bitstream.skipBits(1);
        }
        else {
            // For profile 0 and 2, always 4:2:0
            chromaSubsampling = 1; // Using colocated as default
        }
    }
    else {
        // RGB is always 4:4:4
        chromaSubsampling = 3;
        videoFullRangeFlag = 1;
    }
    // Parse frame size
    const widthMinusOne = bitstream.readBits(16);
    const heightMinusOne = bitstream.readBits(16);
    const width = widthMinusOne + 1;
    const height = heightMinusOne + 1;
    // Calculate level based on dimensions
    const pictureSize = width * height;
    let level = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .last */ ._g)(_codec_js__WEBPACK_IMPORTED_MODULE_0__/* .VP9_LEVEL_TABLE */ .ye).level; // Default to highest level
    for (const entry of _codec_js__WEBPACK_IMPORTED_MODULE_0__/* .VP9_LEVEL_TABLE */ .ye) {
        if (pictureSize <= entry.maxPictureSize) {
            level = entry.level;
            break;
        }
    }
    // Map color_space to standard values
    const matrixCoefficients = colorSpace === 7
        ? 0
        : colorSpace === 2
            ? 1
            : colorSpace === 1
                ? 6
                : 2;
    const colourPrimaries = colorSpace === 2
        ? 1
        : colorSpace === 1
            ? 6
            : 2;
    const transferCharacteristics = colorSpace === 2
        ? 1
        : colorSpace === 1
            ? 6
            : 2;
    return {
        profile,
        level,
        bitDepth,
        chromaSubsampling,
        videoFullRangeFlag,
        colourPrimaries,
        transferCharacteristics,
        matrixCoefficients,
    };
};
/** Iterates over all OBUs in an AV1 packet bistream. */
const iterateAv1PacketObus = function* (packet) {
    // https://aomediacodec.github.io/av1-spec/av1-spec.pdf
    const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .Bitstream */ ._c(packet);
    const readLeb128 = () => {
        let value = 0;
        for (let i = 0; i < 8; i++) {
            const byte = bitstream.readAlignedByte();
            value |= ((byte & 0x7f) << (i * 7));
            if (!(byte & 0x80)) {
                break;
            }
            // Spec requirement
            if (i === 7 && (byte & 0x80)) {
                return null;
            }
        }
        // Spec requirement
        if (value >= 2 ** 32 - 1) {
            return null;
        }
        return value;
    };
    while (bitstream.getBitsLeft() >= 8) {
        // Parse OBU header
        bitstream.skipBits(1);
        const obuType = bitstream.readBits(4);
        const obuExtension = bitstream.readBits(1);
        const obuHasSizeField = bitstream.readBits(1);
        bitstream.skipBits(1);
        // Skip extension header if present
        if (obuExtension) {
            bitstream.skipBits(8);
        }
        // Read OBU size if present
        let obuSize;
        if (obuHasSizeField) {
            const obuSizeValue = readLeb128();
            if (obuSizeValue === null)
                return; // It was invalid
            obuSize = obuSizeValue;
        }
        else {
            // Calculate remaining bits and convert to bytes, rounding down
            obuSize = Math.floor(bitstream.getBitsLeft() / 8);
        }
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assert */ .vA)(bitstream.pos % 8 === 0);
        yield {
            type: obuType,
            data: packet.subarray(bitstream.pos / 8, bitstream.pos / 8 + obuSize),
        };
        // Move to next OBU
        bitstream.skipBits(obuSize * 8);
    }
};
/**
 * When AV1 codec information is not provided by the container, we can still try to extract the information by digging
 * into the AV1 bitstream.
 */
const extractAv1CodecInfoFromPacket = (packet) => {
    // https://aomediacodec.github.io/av1-spec/av1-spec.pdf
    for (const { type, data } of iterateAv1PacketObus(packet)) {
        if (type !== 1) {
            continue; // 1 == OBU_SEQUENCE_HEADER
        }
        const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .Bitstream */ ._c(data);
        // Read sequence header fields
        const seqProfile = bitstream.readBits(3);
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const stillPicture = bitstream.readBits(1);
        const reducedStillPictureHeader = bitstream.readBits(1);
        let seqLevel = 0;
        let seqTier = 0;
        let bufferDelayLengthMinus1 = 0;
        if (reducedStillPictureHeader) {
            seqLevel = bitstream.readBits(5);
        }
        else {
            // Parse timing_info_present_flag
            const timingInfoPresentFlag = bitstream.readBits(1);
            if (timingInfoPresentFlag) {
                // Skip timing info (num_units_in_display_tick, time_scale, equal_picture_interval)
                bitstream.skipBits(32); // num_units_in_display_tick
                bitstream.skipBits(32); // time_scale
                const equalPictureInterval = bitstream.readBits(1);
                if (equalPictureInterval) {
                    // Skip num_ticks_per_picture_minus_1 (uvlc)
                    // Since this is variable length, we'd need to implement uvlc reading
                    // For now, we'll return null as this is rare
                    return null;
                }
            }
            // Parse decoder_model_info_present_flag
            const decoderModelInfoPresentFlag = bitstream.readBits(1);
            if (decoderModelInfoPresentFlag) {
                // Store buffer_delay_length_minus_1 instead of just skipping
                bufferDelayLengthMinus1 = bitstream.readBits(5);
                bitstream.skipBits(32); // num_units_in_decoding_tick
                bitstream.skipBits(5); // buffer_removal_time_length_minus_1
                bitstream.skipBits(5); // frame_presentation_time_length_minus_1
            }
            // Parse operating_points_cnt_minus_1
            const operatingPointsCntMinus1 = bitstream.readBits(5);
            // For each operating point
            for (let i = 0; i <= operatingPointsCntMinus1; i++) {
                // operating_point_idc[i]
                bitstream.skipBits(12);
                // seq_level_idx[i]
                const seqLevelIdx = bitstream.readBits(5);
                if (i === 0) {
                    seqLevel = seqLevelIdx;
                }
                if (seqLevelIdx > 7) {
                    // seq_tier[i]
                    const seqTierTemp = bitstream.readBits(1);
                    if (i === 0) {
                        seqTier = seqTierTemp;
                    }
                }
                if (decoderModelInfoPresentFlag) {
                    // decoder_model_present_for_this_op[i]
                    const decoderModelPresentForThisOp = bitstream.readBits(1);
                    if (decoderModelPresentForThisOp) {
                        const n = bufferDelayLengthMinus1 + 1;
                        bitstream.skipBits(n); // decoder_buffer_delay[op]
                        bitstream.skipBits(n); // encoder_buffer_delay[op]
                        bitstream.skipBits(1); // low_delay_mode_flag[op]
                    }
                }
                // initial_display_delay_present_flag
                const initialDisplayDelayPresentFlag = bitstream.readBits(1);
                if (initialDisplayDelayPresentFlag) {
                    // initial_display_delay_minus_1[i]
                    bitstream.skipBits(4);
                }
            }
        }
        // Frame size
        const frameWidthBitsMinus1 = bitstream.readBits(4);
        const frameHeightBitsMinus1 = bitstream.readBits(4);
        const n1 = frameWidthBitsMinus1 + 1;
        bitstream.skipBits(n1); // max_frame_width_minus_1
        const n2 = frameHeightBitsMinus1 + 1;
        bitstream.skipBits(n2); // max_frame_height_minus_1
        // Frame IDs
        let frameIdNumbersPresentFlag = 0;
        if (reducedStillPictureHeader) {
            frameIdNumbersPresentFlag = 0;
        }
        else {
            frameIdNumbersPresentFlag = bitstream.readBits(1);
        }
        if (frameIdNumbersPresentFlag) {
            bitstream.skipBits(4); // delta_frame_id_length_minus_2
            bitstream.skipBits(3); // additional_frame_id_length_minus_1
        }
        bitstream.skipBits(1); // use_128x128_superblock
        bitstream.skipBits(1); // enable_filter_intra
        bitstream.skipBits(1); // enable_intra_edge_filter
        if (!reducedStillPictureHeader) {
            bitstream.skipBits(1); // enable_interintra_compound
            bitstream.skipBits(1); // enable_masked_compound
            bitstream.skipBits(1); // enable_warped_motion
            bitstream.skipBits(1); // enable_dual_filter
            const enableOrderHint = bitstream.readBits(1);
            if (enableOrderHint) {
                bitstream.skipBits(1); // enable_jnt_comp
                bitstream.skipBits(1); // enable_ref_frame_mvs
            }
            const seqChooseScreenContentTools = bitstream.readBits(1);
            let seqForceScreenContentTools = 0;
            if (seqChooseScreenContentTools) {
                seqForceScreenContentTools = 2; // SELECT_SCREEN_CONTENT_TOOLS
            }
            else {
                seqForceScreenContentTools = bitstream.readBits(1);
            }
            if (seqForceScreenContentTools > 0) {
                const seqChooseIntegerMv = bitstream.readBits(1);
                if (!seqChooseIntegerMv) {
                    bitstream.skipBits(1); // seq_force_integer_mv
                }
            }
            if (enableOrderHint) {
                bitstream.skipBits(3); // order_hint_bits_minus_1
            }
        }
        bitstream.skipBits(1); // enable_superres
        bitstream.skipBits(1); // enable_cdef
        bitstream.skipBits(1); // enable_restoration
        // color_config()
        const highBitdepth = bitstream.readBits(1);
        let bitDepth = 8;
        if (seqProfile === 2 && highBitdepth) {
            const twelveBit = bitstream.readBits(1);
            bitDepth = twelveBit ? 12 : 10;
        }
        else if (seqProfile <= 2) {
            bitDepth = highBitdepth ? 10 : 8;
        }
        let monochrome = 0;
        if (seqProfile !== 1) {
            monochrome = bitstream.readBits(1);
        }
        let chromaSubsamplingX = 1;
        let chromaSubsamplingY = 1;
        let chromaSamplePosition = 0;
        if (!monochrome) {
            if (seqProfile === 0) {
                chromaSubsamplingX = 1;
                chromaSubsamplingY = 1;
            }
            else if (seqProfile === 1) {
                chromaSubsamplingX = 0;
                chromaSubsamplingY = 0;
            }
            else {
                if (bitDepth === 12) {
                    chromaSubsamplingX = bitstream.readBits(1);
                    if (chromaSubsamplingX) {
                        chromaSubsamplingY = bitstream.readBits(1);
                    }
                }
            }
            if (chromaSubsamplingX && chromaSubsamplingY) {
                chromaSamplePosition = bitstream.readBits(2);
            }
        }
        return {
            profile: seqProfile,
            level: seqLevel,
            tier: seqTier,
            bitDepth,
            monochrome,
            chromaSubsamplingX,
            chromaSubsamplingY,
            chromaSamplePosition,
        };
    }
    return null;
};
const parseOpusIdentificationHeader = (bytes) => {
    const view = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .toDataView */ .Zc)(bytes);
    const outputChannelCount = view.getUint8(9);
    const preSkip = view.getUint16(10, true);
    const inputSampleRate = view.getUint32(12, true);
    const outputGain = view.getInt16(16, true);
    const channelMappingFamily = view.getUint8(18);
    let channelMappingTable = null;
    if (channelMappingFamily) {
        channelMappingTable = bytes.subarray(19, 19 + 2 + outputChannelCount);
    }
    return {
        outputChannelCount,
        preSkip,
        inputSampleRate,
        outputGain,
        channelMappingFamily,
        channelMappingTable,
    };
};
// From https://datatracker.ietf.org/doc/html/rfc6716, in 48 kHz samples
const OPUS_FRAME_DURATION_TABLE = [
    480, 960, 1920, 2880,
    480, 960, 1920, 2880,
    480, 960, 1920, 2880,
    480, 960,
    480, 960,
    120, 240, 480, 960,
    120, 240, 480, 960,
    120, 240, 480, 960,
    120, 240, 480, 960,
];
const parseOpusTocByte = (packet) => {
    const config = packet[0] >> 3;
    return {
        durationInSamples: OPUS_FRAME_DURATION_TABLE[config],
    };
};
// Based on vorbis_parser.c from FFmpeg.
const parseModesFromVorbisSetupPacket = (setupHeader) => {
    // Verify that this is a Setup header.
    if (setupHeader.length < 7) {
        throw new Error('Setup header is too short.');
    }
    if (setupHeader[0] !== 5) {
        throw new Error('Wrong packet type in Setup header.');
    }
    const signature = String.fromCharCode(...setupHeader.slice(1, 7));
    if (signature !== 'vorbis') {
        throw new Error('Invalid packet signature in Setup header.');
    }
    // Reverse the entire buffer.
    const bufSize = setupHeader.length;
    const revBuffer = new Uint8Array(bufSize);
    for (let i = 0; i < bufSize; i++) {
        revBuffer[i] = setupHeader[bufSize - 1 - i];
    }
    // Initialize a Bitstream on the reversed buffer.
    const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .Bitstream */ ._c(revBuffer);
    // --- Find the framing bit.
    // In FFmpeg code, we scan until get_bits1() returns 1.
    let gotFramingBit = 0;
    while (bitstream.getBitsLeft() > 97) {
        if (bitstream.readBits(1) === 1) {
            gotFramingBit = bitstream.pos;
            break;
        }
    }
    if (gotFramingBit === 0) {
        throw new Error('Invalid Setup header: framing bit not found.');
    }
    // --- Search backwards for a valid mode header.
    // We try to “guess” the number of modes by reading a fixed pattern.
    let modeCount = 0;
    let gotModeHeader = false;
    let lastModeCount = 0;
    while (bitstream.getBitsLeft() >= 97) {
        const tempPos = bitstream.pos;
        const a = bitstream.readBits(8);
        const b = bitstream.readBits(16);
        const c = bitstream.readBits(16);
        // If a > 63 or b or c nonzero, assume we’ve gone too far.
        if (a > 63 || b !== 0 || c !== 0) {
            bitstream.pos = tempPos;
            break;
        }
        bitstream.skipBits(1);
        modeCount++;
        if (modeCount > 64) {
            break;
        }
        const bsClone = bitstream.clone();
        const candidate = bsClone.readBits(6) + 1;
        if (candidate === modeCount) {
            gotModeHeader = true;
            lastModeCount = modeCount;
        }
    }
    if (!gotModeHeader) {
        throw new Error('Invalid Setup header: mode header not found.');
    }
    if (lastModeCount > 63) {
        throw new Error(`Unsupported mode count: ${lastModeCount}.`);
    }
    const finalModeCount = lastModeCount;
    // --- Reinitialize the bitstream.
    bitstream.pos = 0;
    // Skip the bits up to the found framing bit.
    bitstream.skipBits(gotFramingBit);
    // --- Now read, for each mode (in reverse order), 40 bits then one bit.
    // That one bit is the mode blockflag.
    const modeBlockflags = Array(finalModeCount).fill(0);
    for (let i = finalModeCount - 1; i >= 0; i--) {
        bitstream.skipBits(40);
        modeBlockflags[i] = bitstream.readBits(1);
    }
    return { modeBlockflags };
};
/** Determines a packet's type (key or delta) by digging into the packet bitstream. */
const determineVideoPacketType = (codec, decoderConfig, packetData) => {
    switch (codec) {
        case 'avc':
            {
                for (const loc of iterateAvcNalUnits(packetData, decoderConfig)) {
                    const nalTypeByte = packetData[loc.offset];
                    const type = extractNalUnitTypeForAvc(nalTypeByte);
                    if (type >= AvcNalUnitType.NON_IDR_SLICE && type <= AvcNalUnitType.SLICE_DPC) {
                        return 'delta';
                    }
                    if (type === AvcNalUnitType.IDR) {
                        return 'key';
                    }
                    // In addition to IDR, Recovery Point SEI also counts as a valid H.264 keyframe by current consensus.
                    // See https://github.com/w3c/webcodecs/issues/650 for the relevant discussion. WebKit and Firefox have
                    // always supported them, but Chromium hasn't, therefore the (admittedly dirty) version check.
                    if (type === AvcNalUnitType.SEI && (!(0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .isChromium */ .F2)() || (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .getChromiumVersion */ .zp)() >= 144)) {
                        const nalUnit = packetData.subarray(loc.offset, loc.offset + loc.length);
                        const bytes = removeEmulationPreventionBytes(nalUnit);
                        let pos = 1; // Skip NALU header
                        // sei_rbsp()
                        do {
                            // sei_message()
                            let payloadType = 0;
                            while (true) {
                                const nextByte = bytes[pos++];
                                if (nextByte === undefined)
                                    break;
                                payloadType += nextByte;
                                if (nextByte < 255) {
                                    break;
                                }
                            }
                            let payloadSize = 0;
                            while (true) {
                                const nextByte = bytes[pos++];
                                if (nextByte === undefined)
                                    break;
                                payloadSize += nextByte;
                                if (nextByte < 255) {
                                    break;
                                }
                            }
                            // sei_payload()
                            const PAYLOAD_TYPE_RECOVERY_POINT = 6;
                            if (payloadType === PAYLOAD_TYPE_RECOVERY_POINT) {
                                const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .Bitstream */ ._c(bytes);
                                bitstream.pos = 8 * pos;
                                const recoveryFrameCount = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .readExpGolomb */ .IP)(bitstream);
                                const exactMatchFlag = bitstream.readBits(1);
                                if (recoveryFrameCount === 0 && exactMatchFlag === 1) {
                                    // https://github.com/w3c/webcodecs/pull/910
                                    // "recovery_frame_cnt == 0 and exact_match_flag=1 in the SEI recovery payload"
                                    return 'key';
                                }
                            }
                            pos += payloadSize;
                        } while (pos < bytes.length - 1);
                    }
                }
                return 'delta';
            }
            // removed by dead control flow

        case 'hevc':
            {
                for (const loc of iterateHevcNalUnits(packetData, decoderConfig)) {
                    const type = extractNalUnitTypeForHevc(packetData[loc.offset]);
                    if (type < HevcNalUnitType.BLA_W_LP) {
                        return 'delta';
                    }
                    if (type <= HevcNalUnitType.RSV_IRAP_VCL23) {
                        return 'key';
                    }
                }
                return 'delta';
            }
            // removed by dead control flow

        case 'vp8':
            {
                // VP8, once again, by far the easiest to deal with.
                const frameType = packetData[0] & 0b1;
                return frameType === 0 ? 'key' : 'delta';
            }
            // removed by dead control flow

        case 'vp9':
            {
                const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .Bitstream */ ._c(packetData);
                if (bitstream.readBits(2) !== 2) {
                    return null;
                }
                ;
                const profileLowBit = bitstream.readBits(1);
                const profileHighBit = bitstream.readBits(1);
                const profile = (profileHighBit << 1) + profileLowBit;
                // Skip reserved bit for profile 3
                if (profile === 3) {
                    bitstream.skipBits(1);
                }
                const showExistingFrame = bitstream.readBits(1);
                if (showExistingFrame) {
                    return null;
                }
                const frameType = bitstream.readBits(1);
                return frameType === 0 ? 'key' : 'delta';
            }
            // removed by dead control flow

        case 'av1':
            {
                let reducedStillPictureHeader = false;
                for (const { type, data } of iterateAv1PacketObus(packetData)) {
                    if (type === 1) { // OBU_SEQUENCE_HEADER
                        const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .Bitstream */ ._c(data);
                        bitstream.skipBits(4);
                        reducedStillPictureHeader = !!bitstream.readBits(1);
                    }
                    else if (type === 3 // OBU_FRAME_HEADER
                        || type === 6 // OBU_FRAME
                        || type === 7 // OBU_REDUNDANT_FRAME_HEADER
                    ) {
                        if (reducedStillPictureHeader) {
                            return 'key';
                        }
                        const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .Bitstream */ ._c(data);
                        const showExistingFrame = bitstream.readBits(1);
                        if (showExistingFrame) {
                            return null;
                        }
                        const frameType = bitstream.readBits(2);
                        return frameType === 0 ? 'key' : 'delta';
                    }
                }
                return null;
            }
            // removed by dead control flow

        default:
            {
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assertNever */ .xb)(codec);
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assert */ .vA)(false);
            }
            ;
    }
};
var FlacBlockType;
(function (FlacBlockType) {
    FlacBlockType[FlacBlockType["STREAMINFO"] = 0] = "STREAMINFO";
    FlacBlockType[FlacBlockType["VORBIS_COMMENT"] = 4] = "VORBIS_COMMENT";
    FlacBlockType[FlacBlockType["PICTURE"] = 6] = "PICTURE";
})(FlacBlockType || (FlacBlockType = {}));
const readVorbisComments = (bytes, metadataTags) => {
    // https://datatracker.ietf.org/doc/html/rfc7845#section-5.2
    const commentView = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .toDataView */ .Zc)(bytes);
    let commentPos = 0;
    const vendorStringLength = commentView.getUint32(commentPos, true);
    commentPos += 4;
    const vendorString = _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .textDecoder */ .su.decode(bytes.subarray(commentPos, commentPos + vendorStringLength));
    commentPos += vendorStringLength;
    if (vendorStringLength > 0) {
        // Expose the vendor string in the raw metadata
        metadataTags.raw ??= {};
        metadataTags.raw['vendor'] ??= vendorString;
    }
    const listLength = commentView.getUint32(commentPos, true);
    commentPos += 4;
    // Loop over all metadata tags
    for (let i = 0; i < listLength; i++) {
        const stringLength = commentView.getUint32(commentPos, true);
        commentPos += 4;
        const string = _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .textDecoder */ .su.decode(bytes.subarray(commentPos, commentPos + stringLength));
        commentPos += stringLength;
        const separatorIndex = string.indexOf('=');
        if (separatorIndex === -1) {
            continue;
        }
        const key = string.slice(0, separatorIndex).toUpperCase();
        const value = string.slice(separatorIndex + 1);
        metadataTags.raw ??= {};
        metadataTags.raw[key] ??= value;
        switch (key) {
            case 'TITLE':
                {
                    metadataTags.title ??= value;
                }
                ;
                break;
            case 'DESCRIPTION':
                {
                    metadataTags.description ??= value;
                }
                ;
                break;
            case 'ARTIST':
                {
                    metadataTags.artist ??= value;
                }
                ;
                break;
            case 'ALBUM':
                {
                    metadataTags.album ??= value;
                }
                ;
                break;
            case 'ALBUMARTIST':
                {
                    metadataTags.albumArtist ??= value;
                }
                ;
                break;
            case 'COMMENT':
                {
                    metadataTags.comment ??= value;
                }
                ;
                break;
            case 'LYRICS':
                {
                    metadataTags.lyrics ??= value;
                }
                ;
                break;
            case 'TRACKNUMBER':
                {
                    const parts = value.split('/');
                    const trackNum = Number.parseInt(parts[0], 10);
                    const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);
                    if (Number.isInteger(trackNum) && trackNum > 0) {
                        metadataTags.trackNumber ??= trackNum;
                    }
                    if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {
                        metadataTags.tracksTotal ??= tracksTotal;
                    }
                }
                ;
                break;
            case 'TRACKTOTAL':
                {
                    const tracksTotal = Number.parseInt(value, 10);
                    if (Number.isInteger(tracksTotal) && tracksTotal > 0) {
                        metadataTags.tracksTotal ??= tracksTotal;
                    }
                }
                ;
                break;
            case 'DISCNUMBER':
                {
                    const parts = value.split('/');
                    const discNum = Number.parseInt(parts[0], 10);
                    const discsTotal = parts[1] && Number.parseInt(parts[1], 10);
                    if (Number.isInteger(discNum) && discNum > 0) {
                        metadataTags.discNumber ??= discNum;
                    }
                    if (discsTotal && Number.isInteger(discsTotal) && discsTotal > 0) {
                        metadataTags.discsTotal ??= discsTotal;
                    }
                }
                ;
                break;
            case 'DISCTOTAL':
                {
                    const discsTotal = Number.parseInt(value, 10);
                    if (Number.isInteger(discsTotal) && discsTotal > 0) {
                        metadataTags.discsTotal ??= discsTotal;
                    }
                }
                ;
                break;
            case 'DATE':
                {
                    const date = new Date(value);
                    if (!Number.isNaN(date.getTime())) {
                        metadataTags.date ??= date;
                    }
                }
                ;
                break;
            case 'GENRE':
                {
                    metadataTags.genre ??= value;
                }
                ;
                break;
            case 'METADATA_BLOCK_PICTURE':
                {
                    // https://datatracker.ietf.org/doc/rfc9639/ Section 8.8
                    const decoded = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .base64ToBytes */ .Kp)(value);
                    const view = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .toDataView */ .Zc)(decoded);
                    const pictureType = view.getUint32(0, false);
                    const mediaTypeLength = view.getUint32(4, false);
                    const mediaType = String.fromCharCode(...decoded.subarray(8, 8 + mediaTypeLength)); // ASCII
                    const descriptionLength = view.getUint32(8 + mediaTypeLength, false);
                    const description = _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .textDecoder */ .su.decode(decoded.subarray(12 + mediaTypeLength, 12 + mediaTypeLength + descriptionLength));
                    const dataLength = view.getUint32(mediaTypeLength + descriptionLength + 28);
                    const data = decoded.subarray(mediaTypeLength + descriptionLength + 32, mediaTypeLength + descriptionLength + 32 + dataLength);
                    metadataTags.images ??= [];
                    metadataTags.images.push({
                        data,
                        mimeType: mediaType,
                        kind: pictureType === 3 ? 'coverFront' : pictureType === 4 ? 'coverBack' : 'unknown',
                        name: undefined,
                        description: description || undefined,
                    });
                }
                ;
                break;
        }
    }
};
const createVorbisComments = (headerBytes, tags, writeImages) => {
    // https://datatracker.ietf.org/doc/html/rfc7845#section-5.2
    const commentHeaderParts = [
        headerBytes,
    ];
    const vendorString = 'Mediabunny';
    const encodedVendorString = _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .textEncoder */ .UG.encode(vendorString);
    let currentBuffer = new Uint8Array(4 + encodedVendorString.length);
    let currentView = new DataView(currentBuffer.buffer);
    currentView.setUint32(0, encodedVendorString.length, true);
    currentBuffer.set(encodedVendorString, 4);
    commentHeaderParts.push(currentBuffer);
    const writtenTags = new Set();
    const addCommentTag = (key, value) => {
        const joined = `${key}=${value}`;
        const encoded = _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .textEncoder */ .UG.encode(joined);
        currentBuffer = new Uint8Array(4 + encoded.length);
        currentView = new DataView(currentBuffer.buffer);
        currentView.setUint32(0, encoded.length, true);
        currentBuffer.set(encoded, 4);
        commentHeaderParts.push(currentBuffer);
        writtenTags.add(key);
    };
    for (const { key, value } of (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .keyValueIterator */ .rk)(tags)) {
        switch (key) {
            case 'title':
                {
                    addCommentTag('TITLE', value);
                }
                ;
                break;
            case 'description':
                {
                    addCommentTag('DESCRIPTION', value);
                }
                ;
                break;
            case 'artist':
                {
                    addCommentTag('ARTIST', value);
                }
                ;
                break;
            case 'album':
                {
                    addCommentTag('ALBUM', value);
                }
                ;
                break;
            case 'albumArtist':
                {
                    addCommentTag('ALBUMARTIST', value);
                }
                ;
                break;
            case 'genre':
                {
                    addCommentTag('GENRE', value);
                }
                ;
                break;
            case 'date':
                {
                    const rawVersion = tags.raw?.['DATE'] ?? tags.raw?.['date'];
                    if (rawVersion && typeof rawVersion === 'string') {
                        addCommentTag('DATE', rawVersion);
                    }
                    else {
                        addCommentTag('DATE', value.toISOString().slice(0, 10));
                    }
                }
                ;
                break;
            case 'comment':
                {
                    addCommentTag('COMMENT', value);
                }
                ;
                break;
            case 'lyrics':
                {
                    addCommentTag('LYRICS', value);
                }
                ;
                break;
            case 'trackNumber':
                {
                    addCommentTag('TRACKNUMBER', value.toString());
                }
                ;
                break;
            case 'tracksTotal':
                {
                    addCommentTag('TRACKTOTAL', value.toString());
                }
                ;
                break;
            case 'discNumber':
                {
                    addCommentTag('DISCNUMBER', value.toString());
                }
                ;
                break;
            case 'discsTotal':
                {
                    addCommentTag('DISCTOTAL', value.toString());
                }
                ;
                break;
            case 'images':
                {
                    // For example, in .flac, we put the pictures in a different section,
                    // not in the Vorbis comment header.
                    if (!writeImages) {
                        break;
                    }
                    for (const image of value) {
                        // https://datatracker.ietf.org/doc/rfc9639/ Section 8.8
                        const pictureType = image.kind === 'coverFront' ? 3 : image.kind === 'coverBack' ? 4 : 0;
                        const encodedMediaType = new Uint8Array(image.mimeType.length);
                        for (let i = 0; i < image.mimeType.length; i++) {
                            encodedMediaType[i] = image.mimeType.charCodeAt(i);
                        }
                        const encodedDescription = _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .textEncoder */ .UG.encode(image.description ?? '');
                        const buffer = new Uint8Array(4 // Picture type
                            + 4 // MIME type length
                            + encodedMediaType.length // MIME type
                            + 4 // Description length
                            + encodedDescription.length // Description
                            + 16 // Width, height, color depth, number of colors
                            + 4 // Picture data length
                            + image.data.length);
                        const view = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .toDataView */ .Zc)(buffer);
                        view.setUint32(0, pictureType, false);
                        view.setUint32(4, encodedMediaType.length, false);
                        buffer.set(encodedMediaType, 8);
                        view.setUint32(8 + encodedMediaType.length, encodedDescription.length, false);
                        buffer.set(encodedDescription, 12 + encodedMediaType.length);
                        // Skip a bunch of fields (width, height, color depth, number of colors)
                        view.setUint32(28 + encodedMediaType.length + encodedDescription.length, image.data.length, false);
                        buffer.set(image.data, 32 + encodedMediaType.length + encodedDescription.length);
                        const encoded = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .bytesToBase64 */ ["if"])(buffer);
                        addCommentTag('METADATA_BLOCK_PICTURE', encoded);
                    }
                }
                ;
                break;
            case 'raw':
                {
                    // Handled later
                }
                ;
                break;
            default: (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assertNever */ .xb)(key);
        }
    }
    if (tags.raw) {
        for (const key in tags.raw) {
            const value = tags.raw[key] ?? tags.raw[key.toLowerCase()];
            if (key === 'vendor' || value == null || writtenTags.has(key)) {
                continue;
            }
            if (typeof value === 'string') {
                addCommentTag(key, value);
            }
        }
    }
    const listLengthBuffer = new Uint8Array(4);
    (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .toDataView */ .Zc)(listLengthBuffer).setUint32(0, writtenTags.size, true);
    commentHeaderParts.splice(2, 0, listLengthBuffer); // Insert after the header and vendor section
    // Merge all comment header parts into a single buffer
    const commentHeaderLength = commentHeaderParts.reduce((a, b) => a + b.length, 0);
    const commentHeader = new Uint8Array(commentHeaderLength);
    let pos = 0;
    for (const part of commentHeaderParts) {
        commentHeader.set(part, pos);
        pos += part.length;
    }
    return commentHeader;
};
// ============================================================================
// AC-3 / E-AC-3 Parsing
// Reference: ETSI TS 102 366 V1.4.1
// ============================================================================
/**
 * Channel counts indexed by acmod (Table 4.3).
 * Does NOT include LFE - add lfeon to get total channel count.
 */
const AC3_ACMOD_CHANNEL_COUNTS = [2, 1, 2, 3, 3, 4, 4, 5];
/**
 * Parse an AC-3 syncframe to extract BSI (Bit Stream Information) fields.
 * Section 4.3
 */
const parseAc3SyncFrame = (data) => {
    if (data.length < 7) {
        return null;
    }
    // Check sync word (0x0B77)
    if (data[0] !== 0x0B || data[1] !== 0x77) {
        return null;
    }
    const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .Bitstream */ ._c(data);
    bitstream.skipBits(16); // sync word
    bitstream.skipBits(16); // crc1
    const fscod = bitstream.readBits(2);
    if (fscod === 3) {
        return null; // Reserved, invalid
    }
    const frmsizecod = bitstream.readBits(6);
    const bsid = bitstream.readBits(5);
    // Verify this is AC-3
    if (bsid > 8) {
        return null;
    }
    const bsmod = bitstream.readBits(3);
    const acmod = bitstream.readBits(3);
    // Skip cmixlev (center downmix level) if three front channels are in use (L, C, R).
    if ((acmod & 0x1) !== 0 && acmod !== 0x1) {
        bitstream.skipBits(2);
    }
    // Skip surmixlev (surround downmix level) if surround channels are in use.
    if ((acmod & 0x4) !== 0) {
        bitstream.skipBits(2);
    }
    // Skip dsurmod if stereo (acmod === 2)
    if (acmod === 0x2) {
        bitstream.skipBits(2);
    }
    const lfeon = bitstream.readBits(1);
    const bitRateCode = Math.floor(frmsizecod / 2);
    return { fscod, bsid, bsmod, acmod, lfeon, bitRateCode };
};
/**
 * AC-3 frame sizes in bytes, indexed by [3 * frmsizecod + fscod].
 * fscod: 0=48kHz, 1=44.1kHz, 2=32kHz
 * Values are 16-bit words * 2 (to convert to bytes).
 * Table 4.13
 */
const AC3_FRAME_SIZES = [
    // frmsizecod, [48kHz, 44.1kHz, 32kHz] in bytes
    64 * 2, 69 * 2, 96 * 2,
    64 * 2, 70 * 2, 96 * 2,
    80 * 2, 87 * 2, 120 * 2,
    80 * 2, 88 * 2, 120 * 2,
    96 * 2, 104 * 2, 144 * 2,
    96 * 2, 105 * 2, 144 * 2,
    112 * 2, 121 * 2, 168 * 2,
    112 * 2, 122 * 2, 168 * 2,
    128 * 2, 139 * 2, 192 * 2,
    128 * 2, 140 * 2, 192 * 2,
    160 * 2, 174 * 2, 240 * 2,
    160 * 2, 175 * 2, 240 * 2,
    192 * 2, 208 * 2, 288 * 2,
    192 * 2, 209 * 2, 288 * 2,
    224 * 2, 243 * 2, 336 * 2,
    224 * 2, 244 * 2, 336 * 2,
    256 * 2, 278 * 2, 384 * 2,
    256 * 2, 279 * 2, 384 * 2,
    320 * 2, 348 * 2, 480 * 2,
    320 * 2, 349 * 2, 480 * 2,
    384 * 2, 417 * 2, 576 * 2,
    384 * 2, 418 * 2, 576 * 2,
    448 * 2, 487 * 2, 672 * 2,
    448 * 2, 488 * 2, 672 * 2,
    512 * 2, 557 * 2, 768 * 2,
    512 * 2, 558 * 2, 768 * 2,
    640 * 2, 696 * 2, 960 * 2,
    640 * 2, 697 * 2, 960 * 2,
    768 * 2, 835 * 2, 1152 * 2,
    768 * 2, 836 * 2, 1152 * 2,
    896 * 2, 975 * 2, 1344 * 2,
    896 * 2, 976 * 2, 1344 * 2,
    1024 * 2, 1114 * 2, 1536 * 2,
    1024 * 2, 1115 * 2, 1536 * 2,
    1152 * 2, 1253 * 2, 1728 * 2,
    1152 * 2, 1254 * 2, 1728 * 2,
    1280 * 2, 1393 * 2, 1920 * 2,
    1280 * 2, 1394 * 2, 1920 * 2,
];
/** Number of samples per AC-3 syncframe (always 1536) */
const AC3_SAMPLES_PER_FRAME = 1536;
/**
 * AC-3 registration_descriptor for MPEG-TS.
 * Section A.2.3
 */
const AC3_REGISTRATION_DESCRIPTOR = new Uint8Array([0x05, 0x04, 0x41, 0x43, 0x2d, 0x33]);
/** E-AC-3 registration_descriptor for MPEG-TS/ */
const EAC3_REGISTRATION_DESCRIPTOR = new Uint8Array([0x05, 0x04, 0x45, 0x41, 0x43, 0x33]);
/** Number of audio blocks per syncframe, indexed by numblkscod */
const EAC3_NUMBLKS_TABLE = [1, 2, 3, 6];
/**
 * Parse an E-AC-3 syncframe to extract BSI fields.
 * Section E.1.2
 */
const parseEac3SyncFrame = (data) => {
    if (data.length < 6) {
        return null;
    }
    // Check sync word (0x0B77)
    if (data[0] !== 0x0B || data[1] !== 0x77) {
        return null;
    }
    const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .Bitstream */ ._c(data);
    bitstream.skipBits(16); // sync word
    const strmtyp = bitstream.readBits(2);
    bitstream.skipBits(3); // substreamid
    // Only parse independent substreams (strmtyp 0 or 2)
    if (strmtyp !== 0 && strmtyp !== 2) {
        return null;
    }
    const frmsiz = bitstream.readBits(11);
    const fscod = bitstream.readBits(2);
    let fscod2 = 0;
    let numblkscod;
    if (fscod === 3) {
        // fscod2 enables reduced sample rates (24/22.05/16 kHz) per ATSC A/52:2018
        fscod2 = bitstream.readBits(2);
        numblkscod = 3; // Implicitly 6 blocks when fscod=3
    }
    else {
        numblkscod = bitstream.readBits(2);
    }
    const acmod = bitstream.readBits(3);
    const lfeon = bitstream.readBits(1);
    const bsid = bitstream.readBits(5);
    // Verify this is E-AC-3
    if (bsid < 11 || bsid > 16) {
        return null;
    }
    // Calculate data rate: ((frmsiz + 1) * fs) / (numblks * 16)
    const numblks = EAC3_NUMBLKS_TABLE[numblkscod];
    let fs;
    if (fscod < 3) {
        fs = _shared_ac3_misc_js__WEBPACK_IMPORTED_MODULE_2__/* .AC3_SAMPLE_RATES */ .N[fscod] / 1000;
    }
    else {
        fs = _shared_ac3_misc_js__WEBPACK_IMPORTED_MODULE_2__/* .EAC3_REDUCED_SAMPLE_RATES */ .P[fscod2] / 1000;
    }
    const dataRate = Math.round(((frmsiz + 1) * fs) / (numblks * 16));
    // These fields require parsing beyond the first frame.
    // Defaults are correct for almost all content.
    const bsmod = 0;
    const numDepSub = 0;
    const chanLoc = 0;
    const substream = {
        fscod,
        fscod2,
        bsid,
        bsmod,
        acmod,
        lfeon,
        numDepSub,
        chanLoc,
    };
    return {
        dataRate,
        substreams: [substream],
    };
};
/**
 * Parse a dec3 box to extract E-AC-3 parameters.
 * Section F.6
 */
const parseEac3Config = (data) => {
    if (data.length < 2) {
        return null;
    }
    const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .Bitstream */ ._c(data);
    const dataRate = bitstream.readBits(13);
    const numIndSub = bitstream.readBits(3);
    const substreams = [];
    for (let i = 0; i <= numIndSub; i++) {
        // Check we have enough data for this substream
        // Each substream needs at least 24 bits (3 bytes) without dependent subs
        if (Math.ceil(bitstream.pos / 8) + 3 > data.length) {
            break;
        }
        const fscod = bitstream.readBits(2);
        const bsid = bitstream.readBits(5);
        bitstream.skipBits(1); // reserved
        bitstream.skipBits(1); // asvc
        const bsmod = bitstream.readBits(3);
        const acmod = bitstream.readBits(3);
        const lfeon = bitstream.readBits(1);
        bitstream.skipBits(3); // reserved
        const numDepSub = bitstream.readBits(4);
        let chanLoc = 0;
        if (numDepSub > 0) {
            chanLoc = bitstream.readBits(9);
        }
        else {
            bitstream.skipBits(1); // reserved
        }
        substreams.push({
            fscod,
            fscod2: null,
            bsid,
            bsmod,
            acmod,
            lfeon,
            numDepSub,
            chanLoc,
        });
    }
    if (substreams.length === 0) {
        return null;
    }
    return { dataRate, substreams };
};
/**
 * Get sample rate from E-AC-3 config.
 * See ATSC A/52:2018 for handling fscod2.
 */
const getEac3SampleRate = (config) => {
    const sub = config.substreams[0];
    (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assert */ .vA)(sub);
    if (sub.fscod < 3) {
        return _shared_ac3_misc_js__WEBPACK_IMPORTED_MODULE_2__/* .AC3_SAMPLE_RATES */ .N[sub.fscod];
    }
    else if (sub.fscod2 !== null && sub.fscod2 < 3) {
        return _shared_ac3_misc_js__WEBPACK_IMPORTED_MODULE_2__/* .EAC3_REDUCED_SAMPLE_RATES */ .P[sub.fscod2];
    }
    return null;
};
/**
 * Get channel count from E-AC-3 config (first independent substream only).
 */
const getEac3ChannelCount = (config) => {
    const sub = config.substreams[0];
    (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assert */ .vA)(sub);
    let channels = AC3_ACMOD_CHANNEL_COUNTS[sub.acmod] + sub.lfeon;
    // Add channels from dependent substreams
    if (sub.numDepSub > 0) {
        const CHAN_LOC_COUNTS = [2, 2, 1, 1, 2, 2, 2, 1, 1];
        for (let bit = 0; bit < 9; bit++) {
            if (sub.chanLoc & (1 << (8 - bit))) {
                channels += CHAN_LOC_COUNTS[bit];
            }
        }
    }
    return channels;
};


/***/ },

/***/ 1188
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   $3: () => (/* binding */ AVC_LEVEL_TABLE),
/* harmony export */   DC: () => (/* binding */ generateAv1CodecConfigurationFromCodecString),
/* harmony export */   Ei: () => (/* binding */ parsePcmCodec),
/* harmony export */   GL: () => (/* binding */ validateSubtitleMetadata),
/* harmony export */   IJ: () => (/* binding */ getAudioEncoderConfigExtension),
/* harmony export */   Im: () => (/* binding */ aacFrequencyTable),
/* harmony export */   KZ: () => (/* binding */ buildAudioCodecString),
/* harmony export */   P7: () => (/* binding */ validateAudioChunkMetadata),
/* harmony export */   PP: () => (/* binding */ AUDIO_CODECS),
/* harmony export */   QP: () => (/* binding */ extractVideoCodecString),
/* harmony export */   Rc: () => (/* binding */ getVideoEncoderConfigExtension),
/* harmony export */   Ti: () => (/* binding */ aacChannelMap),
/* harmony export */   VW: () => (/* binding */ SUBTITLE_CODECS),
/* harmony export */   WN: () => (/* binding */ VIDEO_CODECS),
/* harmony export */   Wq: () => (/* binding */ PCM_AUDIO_CODECS),
/* harmony export */   Wz: () => (/* binding */ buildAacAudioSpecificConfig),
/* harmony export */   X0: () => (/* binding */ extractAudioCodecString),
/* harmony export */   YB: () => (/* binding */ NON_PCM_AUDIO_CODECS),
/* harmony export */   aF: () => (/* binding */ validateVideoChunkMetadata),
/* harmony export */   j7: () => (/* binding */ buildVideoCodecString),
/* harmony export */   mD: () => (/* binding */ generateVp9CodecConfigurationFromCodecString),
/* harmony export */   oU: () => (/* binding */ inferCodecFromCodecString),
/* harmony export */   ye: () => (/* binding */ VP9_LEVEL_TABLE),
/* harmony export */   yo: () => (/* binding */ OPUS_SAMPLE_RATE),
/* harmony export */   zF: () => (/* binding */ parseAacAudioSpecificConfig)
/* harmony export */ });
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3912);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

/**
 * List of known video codecs, ordered by encoding preference.
 * @group Codecs
 * @public
 */
const VIDEO_CODECS = [
    'avc',
    'hevc',
    'vp9',
    'av1',
    'vp8',
];
/**
 * List of known PCM (uncompressed) audio codecs, ordered by encoding preference.
 * @group Codecs
 * @public
 */
const PCM_AUDIO_CODECS = [
    'pcm-s16', // We don't prefix 'le' so we're compatible with the WebCodecs-registered PCM codec strings
    'pcm-s16be',
    'pcm-s24',
    'pcm-s24be',
    'pcm-s32',
    'pcm-s32be',
    'pcm-f32',
    'pcm-f32be',
    'pcm-f64',
    'pcm-f64be',
    'pcm-u8',
    'pcm-s8',
    'ulaw',
    'alaw',
];
/**
 * List of known compressed audio codecs, ordered by encoding preference.
 * @group Codecs
 * @public
 */
const NON_PCM_AUDIO_CODECS = [
    'aac',
    'opus',
    'mp3',
    'vorbis',
    'flac',
    'ac3',
    'eac3',
];
/**
 * List of known audio codecs, ordered by encoding preference.
 * @group Codecs
 * @public
 */
const AUDIO_CODECS = [
    ...NON_PCM_AUDIO_CODECS,
    ...PCM_AUDIO_CODECS,
];
/**
 * List of known subtitle codecs, ordered by encoding preference.
 * @group Codecs
 * @public
 */
const SUBTITLE_CODECS = [
    'webvtt',
]; // TODO add the rest
// https://en.wikipedia.org/wiki/Advanced_Video_Coding
const AVC_LEVEL_TABLE = [
    { maxMacroblocks: 99, maxBitrate: 64000, maxDpbMbs: 396, level: 0x0A }, // Level 1
    { maxMacroblocks: 396, maxBitrate: 192000, maxDpbMbs: 900, level: 0x0B }, // Level 1.1
    { maxMacroblocks: 396, maxBitrate: 384000, maxDpbMbs: 2376, level: 0x0C }, // Level 1.2
    { maxMacroblocks: 396, maxBitrate: 768000, maxDpbMbs: 2376, level: 0x0D }, // Level 1.3
    { maxMacroblocks: 396, maxBitrate: 2000000, maxDpbMbs: 2376, level: 0x14 }, // Level 2
    { maxMacroblocks: 792, maxBitrate: 4000000, maxDpbMbs: 4752, level: 0x15 }, // Level 2.1
    { maxMacroblocks: 1620, maxBitrate: 4000000, maxDpbMbs: 8100, level: 0x16 }, // Level 2.2
    { maxMacroblocks: 1620, maxBitrate: 10000000, maxDpbMbs: 8100, level: 0x1E }, // Level 3
    { maxMacroblocks: 3600, maxBitrate: 14000000, maxDpbMbs: 18000, level: 0x1F }, // Level 3.1
    { maxMacroblocks: 5120, maxBitrate: 20000000, maxDpbMbs: 20480, level: 0x20 }, // Level 3.2
    { maxMacroblocks: 8192, maxBitrate: 20000000, maxDpbMbs: 32768, level: 0x28 }, // Level 4
    { maxMacroblocks: 8192, maxBitrate: 50000000, maxDpbMbs: 32768, level: 0x29 }, // Level 4.1
    { maxMacroblocks: 8704, maxBitrate: 50000000, maxDpbMbs: 34816, level: 0x2A }, // Level 4.2
    { maxMacroblocks: 22080, maxBitrate: 135000000, maxDpbMbs: 110400, level: 0x32 }, // Level 5
    { maxMacroblocks: 36864, maxBitrate: 240000000, maxDpbMbs: 184320, level: 0x33 }, // Level 5.1
    { maxMacroblocks: 36864, maxBitrate: 240000000, maxDpbMbs: 184320, level: 0x34 }, // Level 5.2
    { maxMacroblocks: 139264, maxBitrate: 240000000, maxDpbMbs: 696320, level: 0x3C }, // Level 6
    { maxMacroblocks: 139264, maxBitrate: 480000000, maxDpbMbs: 696320, level: 0x3D }, // Level 6.1
    { maxMacroblocks: 139264, maxBitrate: 800000000, maxDpbMbs: 696320, level: 0x3E }, // Level 6.2
];
// https://en.wikipedia.org/wiki/High_Efficiency_Video_Coding
const HEVC_LEVEL_TABLE = [
    { maxPictureSize: 36864, maxBitrate: 128000, tier: 'L', level: 30 }, // Level 1 (Low Tier)
    { maxPictureSize: 122880, maxBitrate: 1500000, tier: 'L', level: 60 }, // Level 2 (Low Tier)
    { maxPictureSize: 245760, maxBitrate: 3000000, tier: 'L', level: 63 }, // Level 2.1 (Low Tier)
    { maxPictureSize: 552960, maxBitrate: 6000000, tier: 'L', level: 90 }, // Level 3 (Low Tier)
    { maxPictureSize: 983040, maxBitrate: 10000000, tier: 'L', level: 93 }, // Level 3.1 (Low Tier)
    { maxPictureSize: 2228224, maxBitrate: 12000000, tier: 'L', level: 120 }, // Level 4 (Low Tier)
    { maxPictureSize: 2228224, maxBitrate: 30000000, tier: 'H', level: 120 }, // Level 4 (High Tier)
    { maxPictureSize: 2228224, maxBitrate: 20000000, tier: 'L', level: 123 }, // Level 4.1 (Low Tier)
    { maxPictureSize: 2228224, maxBitrate: 50000000, tier: 'H', level: 123 }, // Level 4.1 (High Tier)
    { maxPictureSize: 8912896, maxBitrate: 25000000, tier: 'L', level: 150 }, // Level 5 (Low Tier)
    { maxPictureSize: 8912896, maxBitrate: 100000000, tier: 'H', level: 150 }, // Level 5 (High Tier)
    { maxPictureSize: 8912896, maxBitrate: 40000000, tier: 'L', level: 153 }, // Level 5.1 (Low Tier)
    { maxPictureSize: 8912896, maxBitrate: 160000000, tier: 'H', level: 153 }, // Level 5.1 (High Tier)
    { maxPictureSize: 8912896, maxBitrate: 60000000, tier: 'L', level: 156 }, // Level 5.2 (Low Tier)
    { maxPictureSize: 8912896, maxBitrate: 240000000, tier: 'H', level: 156 }, // Level 5.2 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 60000000, tier: 'L', level: 180 }, // Level 6 (Low Tier)
    { maxPictureSize: 35651584, maxBitrate: 240000000, tier: 'H', level: 180 }, // Level 6 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 120000000, tier: 'L', level: 183 }, // Level 6.1 (Low Tier)
    { maxPictureSize: 35651584, maxBitrate: 480000000, tier: 'H', level: 183 }, // Level 6.1 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 240000000, tier: 'L', level: 186 }, // Level 6.2 (Low Tier)
    { maxPictureSize: 35651584, maxBitrate: 800000000, tier: 'H', level: 186 }, // Level 6.2 (High Tier)
];
// https://en.wikipedia.org/wiki/VP9
const VP9_LEVEL_TABLE = [
    { maxPictureSize: 36864, maxBitrate: 200000, level: 10 }, // Level 1
    { maxPictureSize: 73728, maxBitrate: 800000, level: 11 }, // Level 1.1
    { maxPictureSize: 122880, maxBitrate: 1800000, level: 20 }, // Level 2
    { maxPictureSize: 245760, maxBitrate: 3600000, level: 21 }, // Level 2.1
    { maxPictureSize: 552960, maxBitrate: 7200000, level: 30 }, // Level 3
    { maxPictureSize: 983040, maxBitrate: 12000000, level: 31 }, // Level 3.1
    { maxPictureSize: 2228224, maxBitrate: 18000000, level: 40 }, // Level 4
    { maxPictureSize: 2228224, maxBitrate: 30000000, level: 41 }, // Level 4.1
    { maxPictureSize: 8912896, maxBitrate: 60000000, level: 50 }, // Level 5
    { maxPictureSize: 8912896, maxBitrate: 120000000, level: 51 }, // Level 5.1
    { maxPictureSize: 8912896, maxBitrate: 180000000, level: 52 }, // Level 5.2
    { maxPictureSize: 35651584, maxBitrate: 180000000, level: 60 }, // Level 6
    { maxPictureSize: 35651584, maxBitrate: 240000000, level: 61 }, // Level 6.1
    { maxPictureSize: 35651584, maxBitrate: 480000000, level: 62 }, // Level 6.2
];
// https://en.wikipedia.org/wiki/AV1
const AV1_LEVEL_TABLE = [
    { maxPictureSize: 147456, maxBitrate: 1500000, tier: 'M', level: 0 }, // Level 2.0 (Main Tier)
    { maxPictureSize: 278784, maxBitrate: 3000000, tier: 'M', level: 1 }, // Level 2.1 (Main Tier)
    { maxPictureSize: 665856, maxBitrate: 6000000, tier: 'M', level: 4 }, // Level 3.0 (Main Tier)
    { maxPictureSize: 1065024, maxBitrate: 10000000, tier: 'M', level: 5 }, // Level 3.1 (Main Tier)
    { maxPictureSize: 2359296, maxBitrate: 12000000, tier: 'M', level: 8 }, // Level 4.0 (Main Tier)
    { maxPictureSize: 2359296, maxBitrate: 30000000, tier: 'H', level: 8 }, // Level 4.0 (High Tier)
    { maxPictureSize: 2359296, maxBitrate: 20000000, tier: 'M', level: 9 }, // Level 4.1 (Main Tier)
    { maxPictureSize: 2359296, maxBitrate: 50000000, tier: 'H', level: 9 }, // Level 4.1 (High Tier)
    { maxPictureSize: 8912896, maxBitrate: 30000000, tier: 'M', level: 12 }, // Level 5.0 (Main Tier)
    { maxPictureSize: 8912896, maxBitrate: 100000000, tier: 'H', level: 12 }, // Level 5.0 (High Tier)
    { maxPictureSize: 8912896, maxBitrate: 40000000, tier: 'M', level: 13 }, // Level 5.1 (Main Tier)
    { maxPictureSize: 8912896, maxBitrate: 160000000, tier: 'H', level: 13 }, // Level 5.1 (High Tier)
    { maxPictureSize: 8912896, maxBitrate: 60000000, tier: 'M', level: 14 }, // Level 5.2 (Main Tier)
    { maxPictureSize: 8912896, maxBitrate: 240000000, tier: 'H', level: 14 }, // Level 5.2 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 60000000, tier: 'M', level: 15 }, // Level 5.3 (Main Tier)
    { maxPictureSize: 35651584, maxBitrate: 240000000, tier: 'H', level: 15 }, // Level 5.3 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 60000000, tier: 'M', level: 16 }, // Level 6.0 (Main Tier)
    { maxPictureSize: 35651584, maxBitrate: 240000000, tier: 'H', level: 16 }, // Level 6.0 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 100000000, tier: 'M', level: 17 }, // Level 6.1 (Main Tier)
    { maxPictureSize: 35651584, maxBitrate: 480000000, tier: 'H', level: 17 }, // Level 6.1 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 160000000, tier: 'M', level: 18 }, // Level 6.2 (Main Tier)
    { maxPictureSize: 35651584, maxBitrate: 800000000, tier: 'H', level: 18 }, // Level 6.2 (High Tier)
    { maxPictureSize: 35651584, maxBitrate: 160000000, tier: 'M', level: 19 }, // Level 6.3 (Main Tier)
    { maxPictureSize: 35651584, maxBitrate: 800000000, tier: 'H', level: 19 }, // Level 6.3 (High Tier)
];
const VP9_DEFAULT_SUFFIX = '.01.01.01.01.00';
const AV1_DEFAULT_SUFFIX = '.0.110.01.01.01.0';
const buildVideoCodecString = (codec, width, height, bitrate) => {
    if (codec === 'avc') {
        const profileIndication = 0x64; // High Profile
        const totalMacroblocks = Math.ceil(width / 16) * Math.ceil(height / 16);
        // Determine the level based on the table
        const levelInfo = AVC_LEVEL_TABLE.find(level => totalMacroblocks <= level.maxMacroblocks && bitrate <= level.maxBitrate) ?? (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .last */ ._g)(AVC_LEVEL_TABLE);
        const levelIndication = levelInfo ? levelInfo.level : 0;
        const hexProfileIndication = profileIndication.toString(16).padStart(2, '0');
        const hexProfileCompatibility = '00';
        const hexLevelIndication = levelIndication.toString(16).padStart(2, '0');
        return `avc1.${hexProfileIndication}${hexProfileCompatibility}${hexLevelIndication}`;
    }
    else if (codec === 'hevc') {
        const profilePrefix = ''; // Profile space 0
        const profileIdc = 1; // Main Profile
        const compatibilityFlags = '6'; // Taken from the example in ISO 14496-15
        const pictureSize = width * height;
        const levelInfo = HEVC_LEVEL_TABLE.find(level => pictureSize <= level.maxPictureSize && bitrate <= level.maxBitrate) ?? (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .last */ ._g)(HEVC_LEVEL_TABLE);
        const constraintFlags = 'B0'; // Progressive source flag
        return 'hev1.'
            + `${profilePrefix}${profileIdc}.`
            + `${compatibilityFlags}.`
            + `${levelInfo.tier}${levelInfo.level}.`
            + `${constraintFlags}`;
    }
    else if (codec === 'vp8') {
        return 'vp8'; // Easy, this one
    }
    else if (codec === 'vp9') {
        const profile = '00'; // Profile 0
        const pictureSize = width * height;
        const levelInfo = VP9_LEVEL_TABLE.find(level => pictureSize <= level.maxPictureSize && bitrate <= level.maxBitrate) ?? (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .last */ ._g)(VP9_LEVEL_TABLE);
        const bitDepth = '08'; // 8-bit
        return `vp09.${profile}.${levelInfo.level.toString().padStart(2, '0')}.${bitDepth}`;
    }
    else if (codec === 'av1') {
        const profile = 0; // Main Profile, single digit
        const pictureSize = width * height;
        const levelInfo = AV1_LEVEL_TABLE.find(level => pictureSize <= level.maxPictureSize && bitrate <= level.maxBitrate) ?? (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .last */ ._g)(AV1_LEVEL_TABLE);
        const level = levelInfo.level.toString().padStart(2, '0');
        const bitDepth = '08'; // 8-bit
        return `av01.${profile}.${level}${levelInfo.tier}.${bitDepth}`;
    }
    // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
    throw new TypeError(`Unhandled codec '${codec}'.`);
};
const generateVp9CodecConfigurationFromCodecString = (codecString) => {
    // Reference: https://www.webmproject.org/docs/container/#vp9-codec-feature-metadata-codecprivate
    const parts = codecString.split('.'); // We can derive the required values from the codec string
    const profile = Number(parts[1]);
    const level = Number(parts[2]);
    const bitDepth = Number(parts[3]);
    const chromaSubsampling = parts[4] ? Number(parts[4]) : 1;
    return [
        1, 1, profile,
        2, 1, level,
        3, 1, bitDepth,
        4, 1, chromaSubsampling,
    ];
};
const generateAv1CodecConfigurationFromCodecString = (codecString) => {
    // Reference: https://aomediacodec.github.io/av1-isobmff/
    const parts = codecString.split('.'); // We can derive the required values from the codec string
    const marker = 1;
    const version = 1;
    const firstByte = (marker << 7) + version;
    const profile = Number(parts[1]);
    const levelAndTier = parts[2];
    const level = Number(levelAndTier.slice(0, -1));
    const secondByte = (profile << 5) + level;
    const tier = levelAndTier.slice(-1) === 'H' ? 1 : 0;
    const bitDepth = Number(parts[3]);
    const highBitDepth = bitDepth === 8 ? 0 : 1;
    const twelveBit = 0;
    const monochrome = parts[4] ? Number(parts[4]) : 0;
    const chromaSubsamplingX = parts[5] ? Number(parts[5][0]) : 1;
    const chromaSubsamplingY = parts[5] ? Number(parts[5][1]) : 1;
    const chromaSamplePosition = parts[5] ? Number(parts[5][2]) : 0; // CSP_UNKNOWN
    const thirdByte = (tier << 7)
        + (highBitDepth << 6)
        + (twelveBit << 5)
        + (monochrome << 4)
        + (chromaSubsamplingX << 3)
        + (chromaSubsamplingY << 2)
        + chromaSamplePosition;
    const initialPresentationDelayPresent = 0; // Should be fine
    const fourthByte = initialPresentationDelayPresent;
    return [firstByte, secondByte, thirdByte, fourthByte];
};
const extractVideoCodecString = (trackInfo) => {
    const { codec, codecDescription, colorSpace, avcCodecInfo, hevcCodecInfo, vp9CodecInfo, av1CodecInfo } = trackInfo;
    if (codec === 'avc') {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(trackInfo.avcType !== null);
        if (avcCodecInfo) {
            const bytes = new Uint8Array([
                avcCodecInfo.avcProfileIndication,
                avcCodecInfo.profileCompatibility,
                avcCodecInfo.avcLevelIndication,
            ]);
            return `avc${trackInfo.avcType}.${(0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .bytesToHexString */ .Br)(bytes)}`;
        }
        if (!codecDescription || codecDescription.byteLength < 4) {
            throw new TypeError('AVC decoder description is not provided or is not at least 4 bytes long.');
        }
        return `avc${trackInfo.avcType}.${(0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .bytesToHexString */ .Br)(codecDescription.subarray(1, 4))}`;
    }
    else if (codec === 'hevc') {
        let generalProfileSpace;
        let generalProfileIdc;
        let compatibilityFlags;
        let generalTierFlag;
        let generalLevelIdc;
        let constraintFlags;
        if (hevcCodecInfo) {
            generalProfileSpace = hevcCodecInfo.generalProfileSpace;
            generalProfileIdc = hevcCodecInfo.generalProfileIdc;
            compatibilityFlags = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .reverseBitsU32 */ .P5)(hevcCodecInfo.generalProfileCompatibilityFlags);
            generalTierFlag = hevcCodecInfo.generalTierFlag;
            generalLevelIdc = hevcCodecInfo.generalLevelIdc;
            constraintFlags = [...hevcCodecInfo.generalConstraintIndicatorFlags];
        }
        else {
            if (!codecDescription || codecDescription.byteLength < 23) {
                throw new TypeError('HEVC decoder description is not provided or is not at least 23 bytes long.');
            }
            const view = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(codecDescription);
            const profileByte = view.getUint8(1);
            generalProfileSpace = (profileByte >> 6) & 0x03;
            generalProfileIdc = profileByte & 0x1F;
            compatibilityFlags = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .reverseBitsU32 */ .P5)(view.getUint32(2));
            generalTierFlag = (profileByte >> 5) & 0x01;
            generalLevelIdc = view.getUint8(12);
            constraintFlags = [];
            for (let i = 0; i < 6; i++) {
                constraintFlags.push(view.getUint8(6 + i));
            }
        }
        let codecString = 'hev1.';
        codecString += ['', 'A', 'B', 'C'][generalProfileSpace] + generalProfileIdc;
        codecString += '.';
        codecString += compatibilityFlags.toString(16).toUpperCase();
        codecString += '.';
        codecString += generalTierFlag === 0 ? 'L' : 'H';
        codecString += generalLevelIdc;
        while (constraintFlags.length > 0 && constraintFlags[constraintFlags.length - 1] === 0) {
            constraintFlags.pop();
        }
        if (constraintFlags.length > 0) {
            codecString += '.';
            codecString += constraintFlags.map(x => x.toString(16).toUpperCase()).join('.');
        }
        return codecString;
    }
    else if (codec === 'vp8') {
        return 'vp8'; // Easy, this one
    }
    else if (codec === 'vp9') {
        if (!vp9CodecInfo) {
            // Calculate level based on dimensions
            const pictureSize = trackInfo.width * trackInfo.height;
            let level = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .last */ ._g)(VP9_LEVEL_TABLE).level; // Default to highest level
            for (const entry of VP9_LEVEL_TABLE) {
                if (pictureSize <= entry.maxPictureSize) {
                    level = entry.level;
                    break;
                }
            }
            // We don't really know better, so let's return a general-purpose, common codec string and hope for the best
            return `vp09.00.${level.toString().padStart(2, '0')}.08`;
        }
        const profile = vp9CodecInfo.profile.toString().padStart(2, '0');
        const level = vp9CodecInfo.level.toString().padStart(2, '0');
        const bitDepth = vp9CodecInfo.bitDepth.toString().padStart(2, '0');
        const chromaSubsampling = vp9CodecInfo.chromaSubsampling.toString().padStart(2, '0');
        const colourPrimaries = vp9CodecInfo.colourPrimaries.toString().padStart(2, '0');
        const transferCharacteristics = vp9CodecInfo.transferCharacteristics.toString().padStart(2, '0');
        const matrixCoefficients = vp9CodecInfo.matrixCoefficients.toString().padStart(2, '0');
        const videoFullRangeFlag = vp9CodecInfo.videoFullRangeFlag.toString().padStart(2, '0');
        let string = `vp09.${profile}.${level}.${bitDepth}.${chromaSubsampling}`;
        string += `.${colourPrimaries}.${transferCharacteristics}.${matrixCoefficients}.${videoFullRangeFlag}`;
        if (string.endsWith(VP9_DEFAULT_SUFFIX)) {
            string = string.slice(0, -VP9_DEFAULT_SUFFIX.length);
        }
        return string;
    }
    else if (codec === 'av1') {
        if (!av1CodecInfo) {
            // Calculate level based on dimensions
            const pictureSize = trackInfo.width * trackInfo.height;
            let level = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .last */ ._g)(VP9_LEVEL_TABLE).level; // Default to highest level
            for (const entry of VP9_LEVEL_TABLE) {
                if (pictureSize <= entry.maxPictureSize) {
                    level = entry.level;
                    break;
                }
            }
            // We don't really know better, so let's return a general-purpose, common codec string and hope for the best
            return `av01.0.${level.toString().padStart(2, '0')}M.08`;
        }
        // https://aomediacodec.github.io/av1-isobmff/#codecsparam
        const profile = av1CodecInfo.profile; // Single digit
        const level = av1CodecInfo.level.toString().padStart(2, '0');
        const tier = av1CodecInfo.tier ? 'H' : 'M';
        const bitDepth = av1CodecInfo.bitDepth.toString().padStart(2, '0');
        const monochrome = av1CodecInfo.monochrome ? '1' : '0';
        const chromaSubsampling = 100 * av1CodecInfo.chromaSubsamplingX
            + 10 * av1CodecInfo.chromaSubsamplingY
            + 1 * (av1CodecInfo.chromaSubsamplingX && av1CodecInfo.chromaSubsamplingY
                ? av1CodecInfo.chromaSamplePosition
                : 0);
        // The defaults are 1 (ITU-R BT.709)
        const colorPrimaries = colorSpace?.primaries ? _misc_js__WEBPACK_IMPORTED_MODULE_0__/* .COLOR_PRIMARIES_MAP */ .wd[colorSpace.primaries] : 1;
        const transferCharacteristics = colorSpace?.transfer ? _misc_js__WEBPACK_IMPORTED_MODULE_0__/* .TRANSFER_CHARACTERISTICS_MAP */ .uN[colorSpace.transfer] : 1;
        const matrixCoefficients = colorSpace?.matrix ? _misc_js__WEBPACK_IMPORTED_MODULE_0__/* .MATRIX_COEFFICIENTS_MAP */ .Au[colorSpace.matrix] : 1;
        const videoFullRangeFlag = colorSpace?.fullRange ? 1 : 0;
        let string = `av01.${profile}.${level}${tier}.${bitDepth}`;
        string += `.${monochrome}.${chromaSubsampling.toString().padStart(3, '0')}`;
        string += `.${colorPrimaries.toString().padStart(2, '0')}`;
        string += `.${transferCharacteristics.toString().padStart(2, '0')}`;
        string += `.${matrixCoefficients.toString().padStart(2, '0')}`;
        string += `.${videoFullRangeFlag}`;
        if (string.endsWith(AV1_DEFAULT_SUFFIX)) {
            string = string.slice(0, -AV1_DEFAULT_SUFFIX.length);
        }
        return string;
    }
    throw new TypeError(`Unhandled codec '${codec}'.`);
};
const buildAudioCodecString = (codec, numberOfChannels, sampleRate) => {
    if (codec === 'aac') {
        // If stereo or higher channels and lower sample rate, likely using HE-AAC v2 with PS
        if (numberOfChannels >= 2 && sampleRate <= 24000) {
            return 'mp4a.40.29'; // HE-AAC v2 (AAC LC + SBR + PS)
        }
        // If sample rate is low, likely using HE-AAC v1 with SBR
        if (sampleRate <= 24000) {
            return 'mp4a.40.5'; // HE-AAC v1 (AAC LC + SBR)
        }
        // Default to standard AAC-LC for higher sample rates
        return 'mp4a.40.2'; // AAC-LC
    }
    else if (codec === 'mp3') {
        return 'mp3';
    }
    else if (codec === 'opus') {
        return 'opus';
    }
    else if (codec === 'vorbis') {
        return 'vorbis';
    }
    else if (codec === 'flac') {
        return 'flac';
    }
    else if (codec === 'ac3') {
        return 'ac-3';
    }
    else if (codec === 'eac3') {
        return 'ec-3';
    }
    else if (PCM_AUDIO_CODECS.includes(codec)) {
        return codec;
    }
    throw new TypeError(`Unhandled codec '${codec}'.`);
};
const extractAudioCodecString = (trackInfo) => {
    const { codec, codecDescription, aacCodecInfo } = trackInfo;
    if (codec === 'aac') {
        if (!aacCodecInfo) {
            throw new TypeError('AAC codec info must be provided.');
        }
        if (aacCodecInfo.isMpeg2) {
            return 'mp4a.67';
        }
        else {
            let objectType;
            if (aacCodecInfo.objectType !== null) {
                objectType = aacCodecInfo.objectType;
            }
            else {
                const audioSpecificConfig = parseAacAudioSpecificConfig(codecDescription);
                objectType = audioSpecificConfig.objectType;
            }
            return `mp4a.40.${objectType}`;
        }
    }
    else if (codec === 'mp3') {
        return 'mp3';
    }
    else if (codec === 'opus') {
        return 'opus';
    }
    else if (codec === 'vorbis') {
        return 'vorbis';
    }
    else if (codec === 'flac') {
        return 'flac';
    }
    else if (codec === 'ac3') {
        return 'ac-3';
    }
    else if (codec === 'eac3') {
        return 'ec-3';
    }
    else if (codec && PCM_AUDIO_CODECS.includes(codec)) {
        return codec;
    }
    throw new TypeError(`Unhandled codec '${codec}'.`);
};
const aacFrequencyTable = [
    96000, 88200, 64000, 48000, 44100, 32000,
    24000, 22050, 16000, 12000, 11025, 8000, 7350,
];
const aacChannelMap = [-1, 1, 2, 3, 4, 5, 6, 8];
const parseAacAudioSpecificConfig = (bytes) => {
    if (!bytes || bytes.byteLength < 2) {
        throw new TypeError('AAC description must be at least 2 bytes long.');
    }
    const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_0__/* .Bitstream */ ._c(bytes);
    let objectType = bitstream.readBits(5);
    if (objectType === 31) {
        objectType = 32 + bitstream.readBits(6);
    }
    const frequencyIndex = bitstream.readBits(4);
    let sampleRate = null;
    if (frequencyIndex === 15) {
        sampleRate = bitstream.readBits(24);
    }
    else {
        if (frequencyIndex < aacFrequencyTable.length) {
            sampleRate = aacFrequencyTable[frequencyIndex];
        }
    }
    const channelConfiguration = bitstream.readBits(4);
    let numberOfChannels = null;
    if (channelConfiguration >= 1 && channelConfiguration <= 7) {
        numberOfChannels = aacChannelMap[channelConfiguration];
    }
    return {
        objectType,
        frequencyIndex,
        sampleRate,
        channelConfiguration,
        numberOfChannels,
    };
};
const buildAacAudioSpecificConfig = (config) => {
    let frequencyIndex = aacFrequencyTable.indexOf(config.sampleRate);
    let customSampleRate = null;
    if (frequencyIndex === -1) {
        frequencyIndex = 15;
        customSampleRate = config.sampleRate;
    }
    const channelConfiguration = aacChannelMap.indexOf(config.numberOfChannels);
    if (channelConfiguration === -1) {
        throw new TypeError(`Unsupported number of channels: ${config.numberOfChannels}`);
    }
    let bitCount = 5 + 4 + 4;
    if (config.objectType >= 32) {
        bitCount += 6;
    }
    if (frequencyIndex === 15) {
        bitCount += 24;
    }
    const byteCount = Math.ceil(bitCount / 8);
    const bytes = new Uint8Array(byteCount);
    const bitstream = new _misc_js__WEBPACK_IMPORTED_MODULE_0__/* .Bitstream */ ._c(bytes);
    if (config.objectType < 32) {
        bitstream.writeBits(5, config.objectType);
    }
    else {
        bitstream.writeBits(5, 31);
        bitstream.writeBits(6, config.objectType - 32);
    }
    bitstream.writeBits(4, frequencyIndex);
    if (frequencyIndex === 15) {
        bitstream.writeBits(24, customSampleRate);
    }
    bitstream.writeBits(4, channelConfiguration);
    return bytes;
};
const OPUS_SAMPLE_RATE = 48_000;
const PCM_CODEC_REGEX = /^pcm-([usf])(\d+)+(be)?$/;
const parsePcmCodec = (codec) => {
    (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(PCM_AUDIO_CODECS.includes(codec));
    if (codec === 'ulaw') {
        return { dataType: 'ulaw', sampleSize: 1, littleEndian: true, silentValue: 255 };
    }
    else if (codec === 'alaw') {
        return { dataType: 'alaw', sampleSize: 1, littleEndian: true, silentValue: 213 };
    }
    const match = PCM_CODEC_REGEX.exec(codec);
    (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(match);
    let dataType;
    if (match[1] === 'u') {
        dataType = 'unsigned';
    }
    else if (match[1] === 's') {
        dataType = 'signed';
    }
    else {
        dataType = 'float';
    }
    const sampleSize = (Number(match[2]) / 8);
    const littleEndian = match[3] !== 'be';
    const silentValue = codec === 'pcm-u8' ? 2 ** 7 : 0;
    return { dataType, sampleSize, littleEndian, silentValue };
};
const inferCodecFromCodecString = (codecString) => {
    // Video codecs
    if (codecString.startsWith('avc1') || codecString.startsWith('avc3')) {
        return 'avc';
    }
    else if (codecString.startsWith('hev1') || codecString.startsWith('hvc1')) {
        return 'hevc';
    }
    else if (codecString === 'vp8') {
        return 'vp8';
    }
    else if (codecString.startsWith('vp09')) {
        return 'vp9';
    }
    else if (codecString.startsWith('av01')) {
        return 'av1';
    }
    // Audio codecs
    if (codecString.startsWith('mp4a.40') || codecString === 'mp4a.67') {
        return 'aac';
    }
    else if (codecString === 'mp3'
        || codecString === 'mp4a.69'
        || codecString === 'mp4a.6B'
        || codecString === 'mp4a.6b') {
        return 'mp3';
    }
    else if (codecString === 'opus') {
        return 'opus';
    }
    else if (codecString === 'vorbis') {
        return 'vorbis';
    }
    else if (codecString === 'flac') {
        return 'flac';
    }
    else if (codecString === 'ac-3' || codecString === 'ac3') {
        return 'ac3';
    }
    else if (codecString === 'ec-3' || codecString === 'eac3') {
        return 'eac3';
    }
    else if (codecString === 'ulaw') {
        return 'ulaw';
    }
    else if (codecString === 'alaw') {
        return 'alaw';
    }
    else if (PCM_CODEC_REGEX.test(codecString)) {
        return codecString;
    }
    // Subtitle codecs
    if (codecString === 'webvtt') {
        return 'webvtt';
    }
    return null;
};
const getVideoEncoderConfigExtension = (codec) => {
    if (codec === 'avc') {
        return {
            avc: {
                format: 'avc', // Ensure the format is not Annex B
            },
        };
    }
    else if (codec === 'hevc') {
        return {
            hevc: {
                format: 'hevc', // Ensure the format is not Annex B
            },
        };
    }
    return {};
};
const getAudioEncoderConfigExtension = (codec) => {
    if (codec === 'aac') {
        return {
            aac: {
                format: 'aac', // Ensure the format is not ADTS
            },
        };
    }
    else if (codec === 'opus') {
        return {
            opus: {
                format: 'opus',
            },
        };
    }
    return {};
};
const VALID_VIDEO_CODEC_STRING_PREFIXES = ['avc1', 'avc3', 'hev1', 'hvc1', 'vp8', 'vp09', 'av01'];
const AVC_CODEC_STRING_REGEX = /^(avc1|avc3)\.[0-9a-fA-F]{6}$/;
const HEVC_CODEC_STRING_REGEX = /^(hev1|hvc1)\.(?:[ABC]?\d+)\.[0-9a-fA-F]{1,8}\.[LH]\d+(?:\.[0-9a-fA-F]{1,2}){0,6}$/;
const VP9_CODEC_STRING_REGEX = /^vp09(?:\.\d{2}){3}(?:(?:\.\d{2}){5})?$/;
const AV1_CODEC_STRING_REGEX = /^av01\.\d\.\d{2}[MH]\.\d{2}(?:\.\d\.\d{3}\.\d{2}\.\d{2}\.\d{2}\.\d)?$/;
const validateVideoChunkMetadata = (metadata) => {
    if (!metadata) {
        throw new TypeError('Video chunk metadata must be provided.');
    }
    if (typeof metadata !== 'object') {
        throw new TypeError('Video chunk metadata must be an object.');
    }
    if (!metadata.decoderConfig) {
        throw new TypeError('Video chunk metadata must include a decoder configuration.');
    }
    if (typeof metadata.decoderConfig !== 'object') {
        throw new TypeError('Video chunk metadata decoder configuration must be an object.');
    }
    if (typeof metadata.decoderConfig.codec !== 'string') {
        throw new TypeError('Video chunk metadata decoder configuration must specify a codec string.');
    }
    if (!VALID_VIDEO_CODEC_STRING_PREFIXES.some(prefix => metadata.decoderConfig.codec.startsWith(prefix))) {
        throw new TypeError('Video chunk metadata decoder configuration codec string must be a valid video codec string as specified in'
            + ' the Mediabunny Codec Registry.');
    }
    if (!Number.isInteger(metadata.decoderConfig.codedWidth) || metadata.decoderConfig.codedWidth <= 0) {
        throw new TypeError('Video chunk metadata decoder configuration must specify a valid codedWidth (positive integer).');
    }
    if (!Number.isInteger(metadata.decoderConfig.codedHeight) || metadata.decoderConfig.codedHeight <= 0) {
        throw new TypeError('Video chunk metadata decoder configuration must specify a valid codedHeight (positive integer).');
    }
    if (metadata.decoderConfig.description !== undefined) {
        if (!(0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .isAllowSharedBufferSource */ .SM)(metadata.decoderConfig.description)) {
            throw new TypeError('Video chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an'
                + ' ArrayBuffer view.');
        }
    }
    if (metadata.decoderConfig.colorSpace !== undefined) {
        const { colorSpace } = metadata.decoderConfig;
        if (typeof colorSpace !== 'object') {
            throw new TypeError('Video chunk metadata decoder configuration colorSpace, when provided, must be an object.');
        }
        const primariesValues = Object.keys(_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .COLOR_PRIMARIES_MAP */ .wd);
        if (colorSpace.primaries != null && !primariesValues.includes(colorSpace.primaries)) {
            throw new TypeError(`Video chunk metadata decoder configuration colorSpace primaries, when defined, must be one of`
                + ` ${primariesValues.join(', ')}.`);
        }
        const transferValues = Object.keys(_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .TRANSFER_CHARACTERISTICS_MAP */ .uN);
        if (colorSpace.transfer != null && !transferValues.includes(colorSpace.transfer)) {
            throw new TypeError(`Video chunk metadata decoder configuration colorSpace transfer, when defined, must be one of`
                + ` ${transferValues.join(', ')}.`);
        }
        const matrixValues = Object.keys(_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .MATRIX_COEFFICIENTS_MAP */ .Au);
        if (colorSpace.matrix != null && !matrixValues.includes(colorSpace.matrix)) {
            throw new TypeError(`Video chunk metadata decoder configuration colorSpace matrix, when defined, must be one of`
                + ` ${matrixValues.join(', ')}.`);
        }
        if (colorSpace.fullRange != null && typeof colorSpace.fullRange !== 'boolean') {
            throw new TypeError('Video chunk metadata decoder configuration colorSpace fullRange, when defined, must be a boolean.');
        }
    }
    if (metadata.decoderConfig.codec.startsWith('avc1') || metadata.decoderConfig.codec.startsWith('avc3')) {
        // AVC-specific validation
        if (!AVC_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {
            throw new TypeError('Video chunk metadata decoder configuration codec string for AVC must be a valid AVC codec string as'
                + ' specified in Section 3.4 of RFC 6381.');
        }
        // `description` may or may not be set, depending on if the format is AVCC or Annex B, so don't perform any
        // validation for it.
        // https://www.w3.org/TR/webcodecs-avc-codec-registration
    }
    else if (metadata.decoderConfig.codec.startsWith('hev1') || metadata.decoderConfig.codec.startsWith('hvc1')) {
        // HEVC-specific validation
        if (!HEVC_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {
            throw new TypeError('Video chunk metadata decoder configuration codec string for HEVC must be a valid HEVC codec string as'
                + ' specified in Section E.3 of ISO 14496-15.');
        }
        // `description` may or may not be set, depending on if the format is HEVC or Annex B, so don't perform any
        // validation for it.
        // https://www.w3.org/TR/webcodecs-hevc-codec-registration
    }
    else if (metadata.decoderConfig.codec.startsWith('vp8')) {
        // VP8-specific validation
        if (metadata.decoderConfig.codec !== 'vp8') {
            throw new TypeError('Video chunk metadata decoder configuration codec string for VP8 must be "vp8".');
        }
    }
    else if (metadata.decoderConfig.codec.startsWith('vp09')) {
        // VP9-specific validation
        if (!VP9_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {
            throw new TypeError('Video chunk metadata decoder configuration codec string for VP9 must be a valid VP9 codec string as'
                + ' specified in Section "Codecs Parameter String" of https://www.webmproject.org/vp9/mp4/.');
        }
    }
    else if (metadata.decoderConfig.codec.startsWith('av01')) {
        // AV1-specific validation
        if (!AV1_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {
            throw new TypeError('Video chunk metadata decoder configuration codec string for AV1 must be a valid AV1 codec string as'
                + ' specified in Section "Codecs Parameter String" of https://aomediacodec.github.io/av1-isobmff/.');
        }
    }
};
const VALID_AUDIO_CODEC_STRING_PREFIXES = [
    'mp4a', 'mp3', 'opus', 'vorbis', 'flac', 'ulaw', 'alaw', 'pcm', 'ac-3', 'ec-3',
];
const validateAudioChunkMetadata = (metadata) => {
    if (!metadata) {
        throw new TypeError('Audio chunk metadata must be provided.');
    }
    if (typeof metadata !== 'object') {
        throw new TypeError('Audio chunk metadata must be an object.');
    }
    if (!metadata.decoderConfig) {
        throw new TypeError('Audio chunk metadata must include a decoder configuration.');
    }
    if (typeof metadata.decoderConfig !== 'object') {
        throw new TypeError('Audio chunk metadata decoder configuration must be an object.');
    }
    if (typeof metadata.decoderConfig.codec !== 'string') {
        throw new TypeError('Audio chunk metadata decoder configuration must specify a codec string.');
    }
    if (!VALID_AUDIO_CODEC_STRING_PREFIXES.some(prefix => metadata.decoderConfig.codec.startsWith(prefix))) {
        throw new TypeError('Audio chunk metadata decoder configuration codec string must be a valid audio codec string as specified in'
            + ' the Mediabunny Codec Registry.');
    }
    if (!Number.isInteger(metadata.decoderConfig.sampleRate) || metadata.decoderConfig.sampleRate <= 0) {
        throw new TypeError('Audio chunk metadata decoder configuration must specify a valid sampleRate (positive integer).');
    }
    if (!Number.isInteger(metadata.decoderConfig.numberOfChannels) || metadata.decoderConfig.numberOfChannels <= 0) {
        throw new TypeError('Audio chunk metadata decoder configuration must specify a valid numberOfChannels (positive integer).');
    }
    if (metadata.decoderConfig.description !== undefined) {
        if (!(0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .isAllowSharedBufferSource */ .SM)(metadata.decoderConfig.description)) {
            throw new TypeError('Audio chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an'
                + ' ArrayBuffer view.');
        }
    }
    if (metadata.decoderConfig.codec.startsWith('mp4a')
        // These three refer to MP3:
        && metadata.decoderConfig.codec !== 'mp4a.69'
        && metadata.decoderConfig.codec !== 'mp4a.6B'
        && metadata.decoderConfig.codec !== 'mp4a.6b') {
        // AAC-specific validation
        const validStrings = ['mp4a.40.2', 'mp4a.40.02', 'mp4a.40.5', 'mp4a.40.05', 'mp4a.40.29', 'mp4a.67'];
        if (!validStrings.includes(metadata.decoderConfig.codec)) {
            throw new TypeError('Audio chunk metadata decoder configuration codec string for AAC must be a valid AAC codec string as'
                + ' specified in https://www.w3.org/TR/webcodecs-aac-codec-registration/.');
        }
        // `description` may or may not be set, depending on if the format is AAC or ADTS, so don't perform any
        // validation for it.
        // https://www.w3.org/TR/webcodecs-aac-codec-registration
    }
    else if (metadata.decoderConfig.codec.startsWith('mp3') || metadata.decoderConfig.codec.startsWith('mp4a')) {
        // MP3-specific validation
        if (metadata.decoderConfig.codec !== 'mp3'
            && metadata.decoderConfig.codec !== 'mp4a.69'
            && metadata.decoderConfig.codec !== 'mp4a.6B'
            && metadata.decoderConfig.codec !== 'mp4a.6b') {
            throw new TypeError('Audio chunk metadata decoder configuration codec string for MP3 must be "mp3", "mp4a.69" or'
                + ' "mp4a.6B".');
        }
    }
    else if (metadata.decoderConfig.codec.startsWith('opus')) {
        // Opus-specific validation
        if (metadata.decoderConfig.codec !== 'opus') {
            throw new TypeError('Audio chunk metadata decoder configuration codec string for Opus must be "opus".');
        }
        if (metadata.decoderConfig.description && metadata.decoderConfig.description.byteLength < 18) {
            // Description is optional for Opus per-spec, so we shouldn't enforce it
            throw new TypeError('Audio chunk metadata decoder configuration description, when specified, is expected to be an'
                + ' Identification Header as specified in Section 5.1 of RFC 7845.');
        }
    }
    else if (metadata.decoderConfig.codec.startsWith('vorbis')) {
        // Vorbis-specific validation
        if (metadata.decoderConfig.codec !== 'vorbis') {
            throw new TypeError('Audio chunk metadata decoder configuration codec string for Vorbis must be "vorbis".');
        }
        if (!metadata.decoderConfig.description) {
            throw new TypeError('Audio chunk metadata decoder configuration for Vorbis must include a description, which is expected to'
                + ' adhere to the format described in https://www.w3.org/TR/webcodecs-vorbis-codec-registration/.');
        }
    }
    else if (metadata.decoderConfig.codec.startsWith('flac')) {
        // FLAC-specific validation
        if (metadata.decoderConfig.codec !== 'flac') {
            throw new TypeError('Audio chunk metadata decoder configuration codec string for FLAC must be "flac".');
        }
        const minDescriptionSize = 4 + 4 + 34; // 'fLaC' + metadata block header + STREAMINFO block
        if (!metadata.decoderConfig.description || metadata.decoderConfig.description.byteLength < minDescriptionSize) {
            throw new TypeError('Audio chunk metadata decoder configuration for FLAC must include a description, which is expected to'
                + ' adhere to the format described in https://www.w3.org/TR/webcodecs-flac-codec-registration/.');
        }
    }
    else if (metadata.decoderConfig.codec.startsWith('ac-3') || metadata.decoderConfig.codec.startsWith('ac3')) {
        // AC3-specific validation
        if (metadata.decoderConfig.codec !== 'ac-3') {
            throw new TypeError('Audio chunk metadata decoder configuration codec string for AC-3 must be "ac-3".');
        }
    }
    else if (metadata.decoderConfig.codec.startsWith('ec-3') || metadata.decoderConfig.codec.startsWith('eac3')) {
        // EAC3-specific validation
        if (metadata.decoderConfig.codec !== 'ec-3') {
            throw new TypeError('Audio chunk metadata decoder configuration codec string for EC-3 must be "ec-3".');
        }
    }
    else if (metadata.decoderConfig.codec.startsWith('pcm')
        || metadata.decoderConfig.codec.startsWith('ulaw')
        || metadata.decoderConfig.codec.startsWith('alaw')) {
        // PCM-specific validation
        if (!PCM_AUDIO_CODECS.includes(metadata.decoderConfig.codec)) {
            throw new TypeError('Audio chunk metadata decoder configuration codec string for PCM must be one of the supported PCM'
                + ` codecs (${PCM_AUDIO_CODECS.join(', ')}).`);
        }
    }
};
const validateSubtitleMetadata = (metadata) => {
    if (!metadata) {
        throw new TypeError('Subtitle metadata must be provided.');
    }
    if (typeof metadata !== 'object') {
        throw new TypeError('Subtitle metadata must be an object.');
    }
    if (!metadata.config) {
        throw new TypeError('Subtitle metadata must include a config object.');
    }
    if (typeof metadata.config !== 'object') {
        throw new TypeError('Subtitle metadata config must be an object.');
    }
    if (typeof metadata.config.description !== 'string') {
        throw new TypeError('Subtitle metadata config description must be a string.');
    }
};


/***/ },

/***/ 8647
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Lr: () => (/* binding */ customAudioEncoders),
/* harmony export */   WE: () => (/* binding */ customVideoEncoders),
/* harmony export */   wb: () => (/* binding */ customVideoDecoders),
/* harmony export */   zx: () => (/* binding */ customAudioDecoders)
/* harmony export */ });
/* unused harmony exports CustomVideoDecoder, CustomAudioDecoder, CustomVideoEncoder, CustomAudioEncoder, registerDecoder, registerEncoder */
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */
/**
 * Base class for custom video decoders. To add your own custom video decoder, extend this class, implement the
 * abstract methods and static `supports` method, and register the decoder using {@link registerDecoder}.
 * @group Custom coders
 * @public
 */
class CustomVideoDecoder {
    /** Returns true if and only if the decoder can decode the given codec configuration. */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    static supports(codec, config) {
        return false;
    }
}
/**
 * Base class for custom audio decoders. To add your own custom audio decoder, extend this class, implement the
 * abstract methods and static `supports` method, and register the decoder using {@link registerDecoder}.
 * @group Custom coders
 * @public
 */
class CustomAudioDecoder {
    /** Returns true if and only if the decoder can decode the given codec configuration. */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    static supports(codec, config) {
        return false;
    }
}
/**
 * Base class for custom video encoders. To add your own custom video encoder, extend this class, implement the
 * abstract methods and static `supports` method, and register the encoder using {@link registerEncoder}.
 * @group Custom coders
 * @public
 */
class CustomVideoEncoder {
    /** Returns true if and only if the encoder can encode the given codec configuration. */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    static supports(codec, config) {
        return false;
    }
}
/**
 * Base class for custom audio encoders. To add your own custom audio encoder, extend this class, implement the
 * abstract methods and static `supports` method, and register the encoder using {@link registerEncoder}.
 * @group Custom coders
 * @public
 */
class CustomAudioEncoder {
    /** Returns true if and only if the encoder can encode the given codec configuration. */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    static supports(codec, config) {
        return false;
    }
}
const customVideoDecoders = [];
const customAudioDecoders = [];
const customVideoEncoders = [];
const customAudioEncoders = [];
/**
 * Registers a custom video or audio decoder. Registered decoders will automatically be used for decoding whenever
 * possible.
 * @group Custom coders
 * @public
 */
const registerDecoder = (decoder) => {
    if (decoder.prototype instanceof CustomVideoDecoder) {
        const casted = decoder;
        if (customVideoDecoders.includes(casted)) {
            console.warn('Video decoder already registered.');
            return;
        }
        customVideoDecoders.push(casted);
    }
    else if (decoder.prototype instanceof CustomAudioDecoder) {
        const casted = decoder;
        if (customAudioDecoders.includes(casted)) {
            console.warn('Audio decoder already registered.');
            return;
        }
        customAudioDecoders.push(casted);
    }
    else {
        throw new TypeError('Decoder must be a CustomVideoDecoder or CustomAudioDecoder.');
    }
};
/**
 * Registers a custom video or audio encoder. Registered encoders will automatically be used for encoding whenever
 * possible.
 * @group Custom coders
 * @public
 */
const registerEncoder = (encoder) => {
    if (encoder.prototype instanceof CustomVideoEncoder) {
        const casted = encoder;
        if (customVideoEncoders.includes(casted)) {
            console.warn('Video encoder already registered.');
            return;
        }
        customVideoEncoders.push(casted);
    }
    else if (encoder.prototype instanceof CustomAudioEncoder) {
        const casted = encoder;
        if (customAudioEncoders.includes(casted)) {
            console.warn('Audio encoder already registered.');
            return;
        }
        customAudioEncoders.push(casted);
    }
    else {
        throw new TypeError('Encoder must be a CustomVideoEncoder or CustomAudioEncoder.');
    }
};


/***/ },

/***/ 7202
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   B: () => (/* binding */ Demuxer)
/* harmony export */ });
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */
class Demuxer {
    constructor(input) {
        this.input = input;
    }
}


/***/ },

/***/ 5828
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Be: () => (/* binding */ calculateCrc8),
/* harmony export */   Ld: () => (/* binding */ readSampleRate),
/* harmony export */   X7: () => (/* binding */ readCodedNumber),
/* harmony export */   f6: () => (/* binding */ readBlockSize),
/* harmony export */   iv: () => (/* binding */ getBlockSizeOrUncommon),
/* harmony export */   oP: () => (/* binding */ getSampleRateOrUncommon)
/* harmony export */ });
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3912);
/* harmony import */ var _reader_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7735);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */


// https://www.rfc-editor.org/rfc/rfc9639.html#name-block-size-bits
const getBlockSizeOrUncommon = (bits) => {
    if (bits === 0b0000) {
        return null;
    }
    else if (bits === 0b0001) {
        return 192;
    }
    else if (bits >= 0b0010 && bits <= 0b0101) {
        return 144 * 2 ** bits;
    }
    else if (bits === 0b0110) {
        return 'uncommon-u8';
    }
    else if (bits === 0b0111) {
        return 'uncommon-u16';
    }
    else if (bits >= 0b1000 && bits <= 0b1111) {
        return 2 ** bits;
    }
    else {
        return null;
    }
};
// https://www.rfc-editor.org/rfc/rfc9639.html#name-sample-rate-bits
const getSampleRateOrUncommon = (sampleRateBits, streamInfoSampleRate) => {
    switch (sampleRateBits) {
        case 0b0000: return streamInfoSampleRate;
        case 0b0001: return 88200;
        case 0b0010: return 176400;
        case 0b0011: return 192000;
        case 0b0100: return 8000;
        case 0b0101: return 16000;
        case 0b0110: return 22050;
        case 0b0111: return 24000;
        case 0b1000: return 32000;
        case 0b1001: return 44100;
        case 0b1010: return 48000;
        case 0b1011: return 96000;
        case 0b1100: return 'uncommon-u8';
        case 0b1101: return 'uncommon-u16';
        case 0b1110: return 'uncommon-u16-10';
        default: return null;
    }
};
// https://www.rfc-editor.org/rfc/rfc9639.html#name-coded-number
const readCodedNumber = (fileSlice) => {
    let ones = 0;
    const bitstream1 = new _misc_js__WEBPACK_IMPORTED_MODULE_0__/* .Bitstream */ ._c((0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readBytes */ .io)(fileSlice, 1));
    while (bitstream1.readBits(1) === 1) {
        ones++;
    }
    if (ones === 0) {
        return bitstream1.readBits(7);
    }
    const bitArray = [];
    const extraBytes = ones - 1;
    const bitstream2 = new _misc_js__WEBPACK_IMPORTED_MODULE_0__/* .Bitstream */ ._c((0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readBytes */ .io)(fileSlice, extraBytes));
    const firstByteBits = 8 - ones - 1;
    for (let i = 0; i < firstByteBits; i++) {
        bitArray.unshift(bitstream1.readBits(1));
    }
    for (let i = 0; i < extraBytes; i++) {
        for (let j = 0; j < 8; j++) {
            const val = bitstream2.readBits(1);
            if (j < 2) {
                continue;
            }
            bitArray.unshift(val);
        }
    }
    const encoded = bitArray.reduce((acc, bit, index) => {
        return acc | (bit << index);
    }, 0);
    return encoded;
};
const readBlockSize = (slice, blockSizeBits) => {
    if (blockSizeBits === 'uncommon-u16') {
        return (0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readU16Be */ .mH)(slice) + 1;
    }
    else if (blockSizeBits === 'uncommon-u8') {
        return (0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readU8 */ .eo)(slice) + 1;
    }
    else if (typeof blockSizeBits === 'number') {
        return blockSizeBits;
    }
    else {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assertNever */ .xb)(blockSizeBits);
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(false);
    }
};
const readSampleRate = (slice, sampleRateOrUncommon) => {
    if (sampleRateOrUncommon === 'uncommon-u16') {
        return (0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readU16Be */ .mH)(slice);
    }
    if (sampleRateOrUncommon === 'uncommon-u16-10') {
        return (0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readU16Be */ .mH)(slice) * 10;
    }
    if (sampleRateOrUncommon === 'uncommon-u8') {
        return (0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readU8 */ .eo)(slice);
    }
    if (typeof sampleRateOrUncommon === 'number') {
        return sampleRateOrUncommon;
    }
    return null;
};
// https://www.rfc-editor.org/rfc/rfc9639.html#section-9.1.1
const calculateCrc8 = (data) => {
    const polynomial = 0x07; // x^8 + x^2 + x^1 + x^0
    let crc = 0x00; // Initialize CRC to 0
    for (const byte of data) {
        crc ^= byte; // XOR byte into least significant byte of crc
        for (let i = 0; i < 8; i++) {
            // For each bit in the byte
            if ((crc & 0x80) !== 0) {
                // If the leftmost bit (MSB) is set
                crc = (crc << 1) ^ polynomial; // Shift left and XOR with polynomial
            }
            else {
                crc <<= 1; // Just shift left
            }
            crc &= 0xff; // Ensure CRC remains 8-bit
        }
    }
    return crc;
};


/***/ },

/***/ 7576
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   IX: () => (/* binding */ readId3V2Header),
/* harmony export */   Ov: () => (/* binding */ Id3V2Writer),
/* harmony export */   aU: () => (/* binding */ ID3_V1_TAG_SIZE),
/* harmony export */   cG: () => (/* binding */ parseId3V2Tag),
/* harmony export */   p_: () => (/* binding */ parseId3V1Tag),
/* harmony export */   sY: () => (/* binding */ ID3_V2_HEADER_SIZE)
/* harmony export */ });
/* unused harmony exports Id3V2HeaderFlags, Id3V2TextEncoding, ID3_V1_GENRES, readId3V1String, Id3V2Reader */
/* harmony import */ var _shared_mp3_misc_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2788);
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3912);
/* harmony import */ var _reader_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7735);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */



var Id3V2HeaderFlags;
(function (Id3V2HeaderFlags) {
    Id3V2HeaderFlags[Id3V2HeaderFlags["Unsynchronisation"] = 128] = "Unsynchronisation";
    Id3V2HeaderFlags[Id3V2HeaderFlags["ExtendedHeader"] = 64] = "ExtendedHeader";
    Id3V2HeaderFlags[Id3V2HeaderFlags["ExperimentalIndicator"] = 32] = "ExperimentalIndicator";
    Id3V2HeaderFlags[Id3V2HeaderFlags["Footer"] = 16] = "Footer";
})(Id3V2HeaderFlags || (Id3V2HeaderFlags = {}));
var Id3V2TextEncoding;
(function (Id3V2TextEncoding) {
    Id3V2TextEncoding[Id3V2TextEncoding["ISO_8859_1"] = 0] = "ISO_8859_1";
    Id3V2TextEncoding[Id3V2TextEncoding["UTF_16_WITH_BOM"] = 1] = "UTF_16_WITH_BOM";
    Id3V2TextEncoding[Id3V2TextEncoding["UTF_16_BE_NO_BOM"] = 2] = "UTF_16_BE_NO_BOM";
    Id3V2TextEncoding[Id3V2TextEncoding["UTF_8"] = 3] = "UTF_8";
})(Id3V2TextEncoding || (Id3V2TextEncoding = {}));
const ID3_V1_TAG_SIZE = 128;
const ID3_V2_HEADER_SIZE = 10;
const ID3_V1_GENRES = [
    'Blues', 'Classic rock', 'Country', 'Dance', 'Disco', 'Funk', 'Grunge', 'Hip-hop', 'Jazz',
    'Metal', 'New age', 'Oldies', 'Other', 'Pop', 'Rhythm and blues', 'Rap', 'Reggae', 'Rock',
    'Techno', 'Industrial', 'Alternative', 'Ska', 'Death metal', 'Pranks', 'Soundtrack',
    'Euro-techno', 'Ambient', 'Trip-hop', 'Vocal', 'Jazz & funk', 'Fusion', 'Trance', 'Classical',
    'Instrumental', 'Acid', 'House', 'Game', 'Sound clip', 'Gospel', 'Noise', 'Alternative rock',
    'Bass', 'Soul', 'Punk', 'Space', 'Meditative', 'Instrumental pop', 'Instrumental rock',
    'Ethnic', 'Gothic', 'Darkwave', 'Techno-industrial', 'Electronic', 'Pop-folk', 'Eurodance',
    'Dream', 'Southern rock', 'Comedy', 'Cult', 'Gangsta', 'Top 40', 'Christian rap', 'Pop/funk',
    'Jungle music', 'Native US', 'Cabaret', 'New wave', 'Psychedelic', 'Rave', 'Showtunes',
    'Trailer', 'Lo-fi', 'Tribal', 'Acid punk', 'Acid jazz', 'Polka', 'Retro', 'Musical',
    'Rock \'n\' roll', 'Hard rock', 'Folk', 'Folk rock', 'National folk', 'Swing', 'Fast fusion',
    'Bebop', 'Latin', 'Revival', 'Celtic', 'Bluegrass', 'Avantgarde', 'Gothic rock',
    'Progressive rock', 'Psychedelic rock', 'Symphonic rock', 'Slow rock', 'Big band', 'Chorus',
    'Easy listening', 'Acoustic', 'Humour', 'Speech', 'Chanson', 'Opera', 'Chamber music',
    'Sonata', 'Symphony', 'Booty bass', 'Primus', 'Porn groove', 'Satire', 'Slow jam', 'Club',
    'Tango', 'Samba', 'Folklore', 'Ballad', 'Power ballad', 'Rhythmic Soul', 'Freestyle', 'Duet',
    'Punk rock', 'Drum solo', 'A cappella', 'Euro-house', 'Dance hall', 'Goa music', 'Drum & bass',
    'Club-house', 'Hardcore techno', 'Terror', 'Indie', 'Britpop', 'Negerpunk', 'Polsk punk',
    'Beat', 'Christian gangsta rap', 'Heavy metal', 'Black metal', 'Crossover',
    'Contemporary Christian', 'Christian rock', 'Merengue', 'Salsa', 'Thrash metal', 'Anime',
    'Jpop', 'Synthpop', 'Christmas', 'Art rock', 'Baroque', 'Bhangra', 'Big beat', 'Breakbeat',
    'Chillout', 'Downtempo', 'Dub', 'EBM', 'Eclectic', 'Electro', 'Electroclash', 'Emo',
    'Experimental', 'Garage', 'Global', 'IDM', 'Illbient', 'Industro-Goth', 'Jam Band',
    'Krautrock', 'Leftfield', 'Lounge', 'Math rock', 'New romantic', 'Nu-breakz', 'Post-punk',
    'Post-rock', 'Psytrance', 'Shoegaze', 'Space rock', 'Trop rock', 'World music', 'Neoclassical',
    'Audiobook', 'Audio theatre', 'Neue Deutsche Welle', 'Podcast', 'Indie rock', 'G-Funk',
    'Dubstep', 'Garage rock', 'Psybient',
];
const parseId3V1Tag = (slice, tags) => {
    const startPos = slice.filePos;
    tags.raw ??= {};
    tags.raw['TAG'] ??= (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readBytes */ .io)(slice, ID3_V1_TAG_SIZE - 3); // Dump the whole tag into the raw metadata
    slice.filePos = startPos;
    const title = readId3V1String(slice, 30);
    if (title)
        tags.title ??= title;
    const artist = readId3V1String(slice, 30);
    if (artist)
        tags.artist ??= artist;
    const album = readId3V1String(slice, 30);
    if (album)
        tags.album ??= album;
    const yearText = readId3V1String(slice, 4);
    const year = Number.parseInt(yearText, 10);
    if (Number.isInteger(year) && year > 0) {
        tags.date ??= new Date(year, 0, 1);
    }
    const commentBytes = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readBytes */ .io)(slice, 30);
    let comment;
    // Check for the ID3v1.1 track number format:
    // The 29th byte (index 28) is a null terminator, and the 30th byte is the track number.
    if (commentBytes[28] === 0 && commentBytes[29] !== 0) {
        const trackNum = commentBytes[29];
        if (trackNum > 0) {
            tags.trackNumber ??= trackNum;
        }
        slice.skip(-30);
        comment = readId3V1String(slice, 28);
        slice.skip(2);
    }
    else {
        slice.skip(-30);
        comment = readId3V1String(slice, 30);
    }
    if (comment)
        tags.comment ??= comment;
    const genreIndex = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readU8 */ .eo)(slice);
    if (genreIndex < ID3_V1_GENRES.length) {
        tags.genre ??= ID3_V1_GENRES[genreIndex];
    }
};
const readId3V1String = (slice, length) => {
    const bytes = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readBytes */ .io)(slice, length);
    const endIndex = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .coalesceIndex */ .Sf)(bytes.indexOf(0), bytes.length);
    const relevantBytes = bytes.subarray(0, endIndex);
    // Decode as ISO-8859-1
    let str = '';
    for (let i = 0; i < relevantBytes.length; i++) {
        str += String.fromCharCode(relevantBytes[i]);
    }
    return str.trimEnd(); // String also may be padded with spaces
};
const readId3V2Header = (slice) => {
    const startPos = slice.filePos;
    const tag = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readAscii */ .IT)(slice, 3);
    const majorVersion = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readU8 */ .eo)(slice);
    const revision = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readU8 */ .eo)(slice);
    const flags = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readU8 */ .eo)(slice);
    const sizeRaw = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readU32Be */ .cN)(slice);
    if (tag !== 'ID3' || majorVersion === 0xff || revision === 0xff || (sizeRaw & 0x80808080) !== 0) {
        slice.filePos = startPos;
        return null;
    }
    const size = (0,_shared_mp3_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .decodeSynchsafe */ .Fm)(sizeRaw);
    return { majorVersion, revision, flags, size };
};
const parseId3V2Tag = (slice, header, tags) => {
    // https://id3.org/id3v2.3.0
    if (![2, 3, 4].includes(header.majorVersion)) {
        console.warn(`Unsupported ID3v2 major version: ${header.majorVersion}`);
        return;
    }
    const bytes = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readBytes */ .io)(slice, header.size);
    const reader = new Id3V2Reader(header, bytes);
    if (header.flags & Id3V2HeaderFlags.Footer) {
        reader.removeFooter();
    }
    if ((header.flags & Id3V2HeaderFlags.Unsynchronisation) && header.majorVersion === 3) {
        reader.ununsynchronizeAll();
    }
    if (header.flags & Id3V2HeaderFlags.ExtendedHeader) {
        const extendedHeaderSize = reader.readU32();
        if (header.majorVersion === 3) {
            reader.pos += extendedHeaderSize; // The extended header size excludes itself
        }
        else {
            reader.pos += extendedHeaderSize - 4; // The extended header size includes itself
        }
    }
    while (reader.pos <= reader.bytes.length - reader.frameHeaderSize()) {
        const frame = reader.readId3V2Frame();
        if (!frame) {
            break;
        }
        const frameStartPos = reader.pos;
        const frameEndPos = reader.pos + frame.size;
        let frameEncrypted = false;
        let frameCompressed = false;
        let frameUnsynchronized = false;
        if (header.majorVersion === 3) {
            frameEncrypted = !!(frame.flags & (1 << 6));
            frameCompressed = !!(frame.flags & (1 << 7));
        }
        else if (header.majorVersion === 4) {
            frameEncrypted = !!(frame.flags & (1 << 2));
            frameCompressed = !!(frame.flags & (1 << 3));
            frameUnsynchronized = !!(frame.flags & (1 << 1))
                || !!(header.flags & Id3V2HeaderFlags.Unsynchronisation);
        }
        if (frameEncrypted) {
            console.warn(`Skipping encrypted ID3v2 frame ${frame.id}`);
            reader.pos = frameEndPos;
            continue;
        }
        if (frameCompressed) {
            console.warn(`Skipping compressed ID3v2 frame ${frame.id}`); // Maybe someday? Idk
            reader.pos = frameEndPos;
            continue;
        }
        if (frameUnsynchronized) {
            reader.ununsynchronizeRegion(reader.pos, frameEndPos);
        }
        tags.raw ??= {};
        if (frame.id[0] === 'T') {
            // It's a text frame, let's decode as text
            tags.raw[frame.id] ??= reader.readId3V2EncodingAndText(frameEndPos);
        }
        else {
            // For the others, let's just get the bytes
            tags.raw[frame.id] ??= reader.readBytes(frame.size);
        }
        reader.pos = frameStartPos;
        switch (frame.id) {
            case 'TIT2':
            case 'TT2':
                {
                    tags.title ??= reader.readId3V2EncodingAndText(frameEndPos);
                }
                ;
                break;
            case 'TIT3':
            case 'TT3':
                {
                    tags.description ??= reader.readId3V2EncodingAndText(frameEndPos);
                }
                ;
                break;
            case 'TPE1':
            case 'TP1':
                {
                    tags.artist ??= reader.readId3V2EncodingAndText(frameEndPos);
                }
                ;
                break;
            case 'TALB':
            case 'TAL':
                {
                    tags.album ??= reader.readId3V2EncodingAndText(frameEndPos);
                }
                ;
                break;
            case 'TPE2':
            case 'TP2':
                {
                    tags.albumArtist ??= reader.readId3V2EncodingAndText(frameEndPos);
                }
                ;
                break;
            case 'TRCK':
            case 'TRK':
                {
                    const trackText = reader.readId3V2EncodingAndText(frameEndPos);
                    const parts = trackText.split('/');
                    const trackNum = Number.parseInt(parts[0], 10);
                    const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);
                    if (Number.isInteger(trackNum) && trackNum > 0) {
                        tags.trackNumber ??= trackNum;
                    }
                    if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {
                        tags.tracksTotal ??= tracksTotal;
                    }
                }
                ;
                break;
            case 'TPOS':
            case 'TPA':
                {
                    const discText = reader.readId3V2EncodingAndText(frameEndPos);
                    const parts = discText.split('/');
                    const discNum = Number.parseInt(parts[0], 10);
                    const discsTotal = parts[1] && Number.parseInt(parts[1], 10);
                    if (Number.isInteger(discNum) && discNum > 0) {
                        tags.discNumber ??= discNum;
                    }
                    if (discsTotal && Number.isInteger(discsTotal) && discsTotal > 0) {
                        tags.discsTotal ??= discsTotal;
                    }
                }
                ;
                break;
            case 'TCON':
            case 'TCO':
                {
                    const genreText = reader.readId3V2EncodingAndText(frameEndPos);
                    let match = /^\((\d+)\)/.exec(genreText);
                    if (match) {
                        const genreNumber = Number.parseInt(match[1]);
                        if (ID3_V1_GENRES[genreNumber] !== undefined) {
                            tags.genre ??= ID3_V1_GENRES[genreNumber];
                            break;
                        }
                    }
                    match = /^\d+$/.exec(genreText);
                    if (match) {
                        const genreNumber = Number.parseInt(match[0]);
                        if (ID3_V1_GENRES[genreNumber] !== undefined) {
                            tags.genre ??= ID3_V1_GENRES[genreNumber];
                            break;
                        }
                    }
                    tags.genre ??= genreText;
                }
                ;
                break;
            case 'TDRC':
            case 'TDAT':
                {
                    const dateText = reader.readId3V2EncodingAndText(frameEndPos);
                    const date = new Date(dateText);
                    if (!Number.isNaN(date.getTime())) {
                        tags.date ??= date;
                    }
                }
                ;
                break;
            case 'TYER':
            case 'TYE':
                {
                    const yearText = reader.readId3V2EncodingAndText(frameEndPos);
                    const year = Number.parseInt(yearText, 10);
                    if (Number.isInteger(year)) {
                        tags.date ??= new Date(year, 0, 1);
                    }
                }
                ;
                break;
            case 'USLT':
            case 'ULT':
                {
                    const encoding = reader.readU8();
                    reader.pos += 3; // Skip language
                    reader.readId3V2Text(encoding, frameEndPos); // Short content description
                    tags.lyrics ??= reader.readId3V2Text(encoding, frameEndPos);
                }
                ;
                break;
            case 'COMM':
            case 'COM':
                {
                    const encoding = reader.readU8();
                    reader.pos += 3; // Skip language
                    reader.readId3V2Text(encoding, frameEndPos); // Short content description
                    tags.comment ??= reader.readId3V2Text(encoding, frameEndPos);
                }
                ;
                break;
            case 'APIC':
            case 'PIC':
                {
                    const encoding = reader.readId3V2TextEncoding();
                    let mimeType;
                    if (header.majorVersion === 2) {
                        const imageFormat = reader.readAscii(3);
                        mimeType = imageFormat === 'PNG'
                            ? 'image/png'
                            : imageFormat === 'JPG'
                                ? 'image/jpeg'
                                : 'image/*';
                    }
                    else {
                        mimeType = reader.readId3V2Text(encoding, frameEndPos);
                    }
                    const pictureType = reader.readU8();
                    const description = reader.readId3V2Text(encoding, frameEndPos).trimEnd(); // Trim ending spaces
                    const imageDataSize = frameEndPos - reader.pos;
                    if (imageDataSize >= 0) {
                        const imageData = reader.readBytes(imageDataSize);
                        if (!tags.images)
                            tags.images = [];
                        tags.images.push({
                            data: imageData,
                            mimeType,
                            kind: pictureType === 3
                                ? 'coverFront'
                                : pictureType === 4
                                    ? 'coverBack'
                                    : 'unknown',
                            description,
                        });
                    }
                }
                ;
                break;
            default:
                {
                    reader.pos += frame.size;
                }
                ;
                break;
        }
        reader.pos = frameEndPos;
    }
};
// https://id3.org/id3v2.3.0
class Id3V2Reader {
    constructor(header, bytes) {
        this.header = header;
        this.bytes = bytes;
        this.pos = 0;
        this.view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
    }
    frameHeaderSize() {
        return this.header.majorVersion === 2 ? 6 : 10;
    }
    ununsynchronizeAll() {
        const newBytes = [];
        for (let i = 0; i < this.bytes.length; i++) {
            const value1 = this.bytes[i];
            newBytes.push(value1);
            if (value1 === 0xff && i !== this.bytes.length - 1) {
                const value2 = this.bytes[i];
                if (value2 === 0x00) {
                    i++;
                }
            }
        }
        this.bytes = new Uint8Array(newBytes);
        this.view = new DataView(this.bytes.buffer);
    }
    ununsynchronizeRegion(start, end) {
        const newBytes = [];
        for (let i = start; i < end; i++) {
            const value1 = this.bytes[i];
            newBytes.push(value1);
            if (value1 === 0xff && i !== end - 1) {
                const value2 = this.bytes[i + 1];
                if (value2 === 0x00) {
                    i++;
                }
            }
        }
        const before = this.bytes.subarray(0, start);
        const after = this.bytes.subarray(end);
        this.bytes = new Uint8Array(before.length + newBytes.length + after.length);
        this.bytes.set(before, 0);
        this.bytes.set(newBytes, before.length);
        this.bytes.set(after, before.length + newBytes.length);
        this.view = new DataView(this.bytes.buffer);
    }
    removeFooter() {
        this.bytes = this.bytes.subarray(0, this.bytes.length - ID3_V2_HEADER_SIZE);
        this.view = new DataView(this.bytes.buffer);
    }
    readBytes(length) {
        const slice = this.bytes.subarray(this.pos, this.pos + length);
        this.pos += length;
        return slice;
    }
    readU8() {
        const value = this.view.getUint8(this.pos);
        this.pos += 1;
        return value;
    }
    readU16() {
        const value = this.view.getUint16(this.pos, false);
        this.pos += 2;
        return value;
    }
    readU24() {
        const high = this.view.getUint16(this.pos, false);
        const low = this.view.getUint8(this.pos + 1);
        this.pos += 3;
        return high * 0x100 + low;
    }
    readU32() {
        const value = this.view.getUint32(this.pos, false);
        this.pos += 4;
        return value;
    }
    readAscii(length) {
        let str = '';
        for (let i = 0; i < length; i++) {
            str += String.fromCharCode(this.view.getUint8(this.pos + i));
        }
        this.pos += length;
        return str;
    }
    readId3V2Frame() {
        if (this.header.majorVersion === 2) {
            const id = this.readAscii(3);
            if (id === '\x00\x00\x00') {
                return null;
            }
            const size = this.readU24();
            return { id, size, flags: 0 };
        }
        else {
            const id = this.readAscii(4);
            if (id === '\x00\x00\x00\x00') {
                // We've landed in the padding section
                return null;
            }
            const sizeRaw = this.readU32();
            let size = this.header.majorVersion === 4
                ? (0,_shared_mp3_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .decodeSynchsafe */ .Fm)(sizeRaw)
                : sizeRaw;
            const flags = this.readU16();
            const headerEndPos = this.pos;
            // Some files may have incorrectly synchsafed/unsynchsafed sizes. To validate which interpretation is valid,
            // we validate a size by skipping ahead and seeing if we land at a valid frame header (or at the end of the
            // tag.
            const isSizeValid = (size) => {
                const nextPos = this.pos + size;
                if (nextPos > this.bytes.length) {
                    return false;
                }
                if (nextPos <= this.bytes.length - this.frameHeaderSize()) {
                    this.pos += size;
                    const nextId = this.readAscii(4);
                    if (nextId !== '\x00\x00\x00\x00' && !/[0-9A-Z]{4}/.test(nextId)) {
                        return false;
                    }
                }
                return true;
            };
            if (!isSizeValid(size)) {
                // Flip the synchsafing, and try if this one makes more sense
                const otherSize = this.header.majorVersion === 4
                    ? sizeRaw
                    : (0,_shared_mp3_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .decodeSynchsafe */ .Fm)(sizeRaw);
                if (isSizeValid(otherSize)) {
                    size = otherSize;
                }
            }
            this.pos = headerEndPos;
            return { id, size, flags };
        }
    }
    readId3V2TextEncoding() {
        const number = this.readU8();
        if (number > 3) {
            throw new Error(`Unsupported text encoding: ${number}`);
        }
        return number;
    }
    readId3V2Text(encoding, until) {
        const startPos = this.pos;
        const data = this.readBytes(until - this.pos);
        switch (encoding) {
            case Id3V2TextEncoding.ISO_8859_1: {
                let str = '';
                for (let i = 0; i < data.length; i++) {
                    const value = data[i];
                    if (value === 0) {
                        this.pos = startPos + i + 1;
                        break;
                    }
                    str += String.fromCharCode(value);
                }
                return str;
            }
            case Id3V2TextEncoding.UTF_16_WITH_BOM: {
                if (data[0] === 0xff && data[1] === 0xfe) {
                    const decoder = new TextDecoder('utf-16le');
                    const endIndex = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .coalesceIndex */ .Sf)(data.findIndex((x, i) => x === 0 && data[i + 1] === 0 && i % 2 === 0), data.length);
                    this.pos = startPos + Math.min(endIndex + 2, data.length);
                    return decoder.decode(data.subarray(2, endIndex));
                }
                else if (data[0] === 0xfe && data[1] === 0xff) {
                    const decoder = new TextDecoder('utf-16be');
                    const endIndex = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .coalesceIndex */ .Sf)(data.findIndex((x, i) => x === 0 && data[i + 1] === 0 && i % 2 === 0), data.length);
                    this.pos = startPos + Math.min(endIndex + 2, data.length);
                    return decoder.decode(data.subarray(2, endIndex));
                }
                else {
                    // Treat it like UTF-8, some files do this
                    const endIndex = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .coalesceIndex */ .Sf)(data.findIndex(x => x === 0), data.length);
                    this.pos = startPos + Math.min(endIndex + 1, data.length);
                    return _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .textDecoder */ .su.decode(data.subarray(0, endIndex));
                }
            }
            case Id3V2TextEncoding.UTF_16_BE_NO_BOM: {
                const decoder = new TextDecoder('utf-16be');
                const endIndex = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .coalesceIndex */ .Sf)(data.findIndex((x, i) => x === 0 && data[i + 1] === 0 && i % 2 === 0), data.length);
                this.pos = startPos + Math.min(endIndex + 2, data.length);
                return decoder.decode(data.subarray(0, endIndex));
            }
            case Id3V2TextEncoding.UTF_8: {
                const endIndex = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .coalesceIndex */ .Sf)(data.findIndex(x => x === 0), data.length);
                this.pos = startPos + Math.min(endIndex + 1, data.length);
                return _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .textDecoder */ .su.decode(data.subarray(0, endIndex));
            }
        }
    }
    readId3V2EncodingAndText(until) {
        if (this.pos >= until) {
            return '';
        }
        const encoding = this.readId3V2TextEncoding();
        return this.readId3V2Text(encoding, until);
    }
}
class Id3V2Writer {
    constructor(writer) {
        this.helper = new Uint8Array(8);
        this.helperView = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .toDataView */ .Zc)(this.helper);
        this.writer = writer;
    }
    writeId3V2Tag(metadata) {
        const tagStartPos = this.writer.getPos();
        // Write ID3v2.4 header
        this.writeAscii('ID3');
        this.writeU8(0x04); // Version 2.4
        this.writeU8(0x00); // Revision 0
        this.writeU8(0x00); // Flags
        this.writeSynchsafeU32(0); // Size placeholder
        const framesStartPos = this.writer.getPos();
        const writtenTags = new Set();
        // Write all metadata frames
        for (const { key, value } of (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .keyValueIterator */ .rk)(metadata)) {
            switch (key) {
                case 'title':
                    {
                        this.writeId3V2TextFrame('TIT2', value);
                        writtenTags.add('TIT2');
                    }
                    ;
                    break;
                case 'description':
                    {
                        this.writeId3V2TextFrame('TIT3', value);
                        writtenTags.add('TIT3');
                    }
                    ;
                    break;
                case 'artist':
                    {
                        this.writeId3V2TextFrame('TPE1', value);
                        writtenTags.add('TPE1');
                    }
                    ;
                    break;
                case 'album':
                    {
                        this.writeId3V2TextFrame('TALB', value);
                        writtenTags.add('TALB');
                    }
                    ;
                    break;
                case 'albumArtist':
                    {
                        this.writeId3V2TextFrame('TPE2', value);
                        writtenTags.add('TPE2');
                    }
                    ;
                    break;
                case 'trackNumber':
                    {
                        const string = metadata.tracksTotal !== undefined
                            ? `${value}/${metadata.tracksTotal}`
                            : value.toString();
                        this.writeId3V2TextFrame('TRCK', string);
                        writtenTags.add('TRCK');
                    }
                    ;
                    break;
                case 'discNumber':
                    {
                        const string = metadata.discsTotal !== undefined
                            ? `${value}/${metadata.discsTotal}`
                            : value.toString();
                        this.writeId3V2TextFrame('TPOS', string);
                        writtenTags.add('TPOS');
                    }
                    ;
                    break;
                case 'genre':
                    {
                        this.writeId3V2TextFrame('TCON', value);
                        writtenTags.add('TCON');
                    }
                    ;
                    break;
                case 'date':
                    {
                        this.writeId3V2TextFrame('TDRC', value.toISOString().slice(0, 10));
                        writtenTags.add('TDRC');
                    }
                    ;
                    break;
                case 'lyrics':
                    {
                        this.writeId3V2LyricsFrame(value);
                        writtenTags.add('USLT');
                    }
                    ;
                    break;
                case 'comment':
                    {
                        this.writeId3V2CommentFrame(value);
                        writtenTags.add('COMM');
                    }
                    ;
                    break;
                case 'images':
                    {
                        const pictureTypeMap = { coverFront: 0x03, coverBack: 0x04, unknown: 0x00 };
                        for (const image of value) {
                            const pictureType = pictureTypeMap[image.kind] ?? 0x00;
                            const description = image.description ?? '';
                            this.writeId3V2ApicFrame(image.mimeType, pictureType, description, image.data);
                        }
                    }
                    ;
                    break;
                case 'tracksTotal':
                case 'discsTotal':
                    {
                        // Handled with trackNumber and discNumber respectively
                    }
                    ;
                    break;
                case 'raw':
                    {
                        // Handled later
                    }
                    ;
                    break;
                default: {
                    (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assertNever */ .xb)(key);
                }
            }
        }
        if (metadata.raw) {
            for (const key in metadata.raw) {
                const value = metadata.raw[key];
                if (value == null || key.length !== 4 || writtenTags.has(key)) {
                    continue;
                }
                let bytes;
                if (typeof value === 'string') {
                    const encoded = _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .textEncoder */ .UG.encode(value);
                    bytes = new Uint8Array(encoded.byteLength + 2);
                    bytes[0] = Id3V2TextEncoding.UTF_8;
                    bytes.set(encoded, 1);
                    // Last byte is the null terminator
                }
                else if (value instanceof Uint8Array) {
                    bytes = value;
                }
                else {
                    continue;
                }
                this.writeAscii(key);
                this.writeSynchsafeU32(bytes.byteLength);
                this.writeU16(0x0000);
                this.writer.write(bytes);
            }
        }
        const framesEndPos = this.writer.getPos();
        const framesSize = framesEndPos - framesStartPos;
        // Update the size field in the header (synchsafe)
        this.writer.seek(tagStartPos + 6); // Skip 'ID3' + version + revision + flags
        this.writeSynchsafeU32(framesSize);
        this.writer.seek(framesEndPos);
        return framesSize + 10; // +10 for the header size
    }
    writeU8(value) {
        this.helper[0] = value;
        this.writer.write(this.helper.subarray(0, 1));
    }
    writeU16(value) {
        this.helperView.setUint16(0, value, false);
        this.writer.write(this.helper.subarray(0, 2));
    }
    writeU32(value) {
        this.helperView.setUint32(0, value, false);
        this.writer.write(this.helper.subarray(0, 4));
    }
    writeAscii(text) {
        for (let i = 0; i < text.length; i++) {
            this.helper[i] = text.charCodeAt(i);
        }
        this.writer.write(this.helper.subarray(0, text.length));
    }
    writeSynchsafeU32(value) {
        this.writeU32((0,_shared_mp3_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .encodeSynchsafe */ .Pj)(value));
    }
    writeIsoString(text) {
        const bytes = new Uint8Array(text.length + 1);
        for (let i = 0; i < text.length; i++) {
            bytes[i] = text.charCodeAt(i);
        }
        bytes[text.length] = 0x00;
        this.writer.write(bytes);
    }
    writeUtf8String(text) {
        const utf8Data = _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .textEncoder */ .UG.encode(text);
        this.writer.write(utf8Data);
        this.writeU8(0x00);
    }
    writeId3V2TextFrame(frameId, text) {
        const useIso88591 = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .isIso88591Compatible */ .H9)(text);
        const textDataLength = useIso88591 ? text.length : _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .textEncoder */ .UG.encode(text).byteLength;
        const frameSize = 1 + textDataLength + 1;
        this.writeAscii(frameId);
        this.writeSynchsafeU32(frameSize);
        this.writeU16(0x0000);
        this.writeU8(useIso88591 ? Id3V2TextEncoding.ISO_8859_1 : Id3V2TextEncoding.UTF_8);
        if (useIso88591) {
            this.writeIsoString(text);
        }
        else {
            this.writeUtf8String(text);
        }
    }
    writeId3V2LyricsFrame(lyrics) {
        const useIso88591 = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .isIso88591Compatible */ .H9)(lyrics);
        const shortDescription = '';
        const frameSize = 1 + 3 + shortDescription.length + 1 + lyrics.length + 1;
        this.writeAscii('USLT');
        this.writeSynchsafeU32(frameSize);
        this.writeU16(0x0000);
        this.writeU8(useIso88591 ? Id3V2TextEncoding.ISO_8859_1 : Id3V2TextEncoding.UTF_8);
        this.writeAscii('und');
        if (useIso88591) {
            this.writeIsoString(shortDescription);
            this.writeIsoString(lyrics);
        }
        else {
            this.writeUtf8String(shortDescription);
            this.writeUtf8String(lyrics);
        }
    }
    writeId3V2CommentFrame(comment) {
        const useIso88591 = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .isIso88591Compatible */ .H9)(comment);
        const textDataLength = useIso88591 ? comment.length : _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .textEncoder */ .UG.encode(comment).byteLength;
        const shortDescription = '';
        const frameSize = 1 + 3 + shortDescription.length + 1 + textDataLength + 1;
        this.writeAscii('COMM');
        this.writeSynchsafeU32(frameSize);
        this.writeU16(0x0000);
        this.writeU8(useIso88591 ? Id3V2TextEncoding.ISO_8859_1 : Id3V2TextEncoding.UTF_8);
        this.writeU8(0x75); // 'u'
        this.writeU8(0x6E); // 'n'
        this.writeU8(0x64); // 'd'
        if (useIso88591) {
            this.writeIsoString(shortDescription);
            this.writeIsoString(comment);
        }
        else {
            this.writeUtf8String(shortDescription);
            this.writeUtf8String(comment);
        }
    }
    writeId3V2ApicFrame(mimeType, pictureType, description, imageData) {
        const useIso88591 = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .isIso88591Compatible */ .H9)(mimeType) && (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .isIso88591Compatible */ .H9)(description);
        const descriptionDataLength = useIso88591
            ? description.length
            : _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .textEncoder */ .UG.encode(description).byteLength;
        const frameSize = 1 + mimeType.length + 1 + 1 + descriptionDataLength + 1 + imageData.byteLength;
        this.writeAscii('APIC');
        this.writeSynchsafeU32(frameSize);
        this.writeU16(0x0000);
        this.writeU8(useIso88591 ? Id3V2TextEncoding.ISO_8859_1 : Id3V2TextEncoding.UTF_8);
        if (useIso88591) {
            this.writeIsoString(mimeType);
        }
        else {
            this.writeUtf8String(mimeType);
        }
        this.writeU8(pictureType);
        if (useIso88591) {
            this.writeIsoString(description);
        }
        else {
            this.writeUtf8String(description);
        }
        this.writer.write(imageData);
    }
}


/***/ },

/***/ 2912
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";

// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  XE: () => (/* binding */ ALL_FORMATS),
  CW: () => (/* binding */ InputFormat)
});

// UNUSED EXPORTS: ADTS, AdtsInputFormat, FLAC, FlacInputFormat, IsobmffInputFormat, MATROSKA, MP3, MP4, MPEG_TS, MatroskaInputFormat, Mp3InputFormat, Mp4InputFormat, MpegTsInputFormat, OGG, OggInputFormat, QTFF, QuickTimeInputFormat, WAVE, WEBM, WaveInputFormat, WebMInputFormat

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/codec.js
var codec = __webpack_require__(1188);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/codec-data.js
var codec_data = __webpack_require__(6297);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/demuxer.js
var demuxer = __webpack_require__(7202);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/input-track.js
var input_track = __webpack_require__(6244);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/misc.js
var misc = __webpack_require__(3912);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/packet.js
var src_packet = __webpack_require__(3936);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/isobmff/isobmff-misc.js
var isobmff_misc = __webpack_require__(1826);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/isobmff/isobmff-reader.js
var isobmff_reader = __webpack_require__(8561);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/reader.js
var src_reader = __webpack_require__(7735);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/metadata.js
var metadata = __webpack_require__(5165);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/shared/ac3-misc.js
var ac3_misc = __webpack_require__(7553);
;// ./node_modules/mediabunny/dist/modules/src/isobmff/isobmff-demuxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */











class IsobmffDemuxer extends demuxer/* Demuxer */.B {
    constructor(input) {
        super(input);
        this.moovSlice = null;
        this.currentTrack = null;
        this.tracks = [];
        this.metadataPromise = null;
        this.movieTimescale = -1;
        this.movieDurationInTimescale = -1;
        this.isQuickTime = false;
        this.metadataTags = {};
        this.currentMetadataKeys = null;
        this.isFragmented = false;
        this.fragmentTrackDefaults = [];
        this.currentFragment = null;
        /**
         * Caches the last fragment that was read. Based on the assumption that there will be multiple reads to the
         * same fragment in quick succession.
         */
        this.lastReadFragment = null;
        this.reader = input._reader;
    }
    async computeDuration() {
        const tracks = await this.getTracks();
        const trackDurations = await Promise.all(tracks.map(x => x.computeDuration()));
        return Math.max(0, ...trackDurations);
    }
    async getTracks() {
        await this.readMetadata();
        return this.tracks.map(track => track.inputTrack);
    }
    async getMimeType() {
        await this.readMetadata();
        const codecStrings = await Promise.all(this.tracks.map(x => x.inputTrack.getCodecParameterString()));
        return (0,isobmff_misc/* buildIsobmffMimeType */.X)({
            isQuickTime: this.isQuickTime,
            hasVideo: this.tracks.some(x => x.info?.type === 'video'),
            hasAudio: this.tracks.some(x => x.info?.type === 'audio'),
            codecStrings: codecStrings.filter(Boolean),
        });
    }
    async getMetadataTags() {
        await this.readMetadata();
        return this.metadataTags;
    }
    readMetadata() {
        return this.metadataPromise ??= (async () => {
            let currentPos = 0;
            while (true) {
                let slice = this.reader.requestSliceRange(currentPos, isobmff_reader/* MIN_BOX_HEADER_SIZE */.ZM, isobmff_reader/* MAX_BOX_HEADER_SIZE */.Xk);
                if (slice instanceof Promise)
                    slice = await slice;
                if (!slice)
                    break;
                const startPos = currentPos;
                const boxInfo = (0,isobmff_reader/* readBoxHeader */.Vl)(slice);
                if (!boxInfo) {
                    break;
                }
                if (boxInfo.name === 'ftyp') {
                    const majorBrand = (0,src_reader/* readAscii */.IT)(slice, 4);
                    this.isQuickTime = majorBrand === 'qt  ';
                }
                else if (boxInfo.name === 'moov') {
                    // Found moov, load it
                    let moovSlice = this.reader.requestSlice(slice.filePos, boxInfo.contentSize);
                    if (moovSlice instanceof Promise)
                        moovSlice = await moovSlice;
                    if (!moovSlice)
                        break;
                    this.moovSlice = moovSlice;
                    this.readContiguousBoxes(this.moovSlice);
                    // Put default tracks first
                    this.tracks.sort((a, b) => Number(b.disposition.default) - Number(a.disposition.default));
                    for (const track of this.tracks) {
                        // Modify the edit list offset based on the previous segment durations. They are in different
                        // timescales, so we first convert to seconds and then into the track timescale.
                        const previousSegmentDurationsInSeconds = track.editListPreviousSegmentDurations / this.movieTimescale;
                        track.editListOffset -= Math.round(previousSegmentDurationsInSeconds * track.timescale);
                    }
                    break;
                }
                currentPos = startPos + boxInfo.totalSize;
            }
            if (this.isFragmented && this.reader.fileSize !== null) {
                // The last 4 bytes may contain the size of the mfra box at the end of the file
                let lastWordSlice = this.reader.requestSlice(this.reader.fileSize - 4, 4);
                if (lastWordSlice instanceof Promise)
                    lastWordSlice = await lastWordSlice;
                (0,misc/* assert */.vA)(lastWordSlice);
                const lastWord = (0,src_reader/* readU32Be */.cN)(lastWordSlice);
                const potentialMfraPos = this.reader.fileSize - lastWord;
                if (potentialMfraPos >= 0 && potentialMfraPos <= this.reader.fileSize - isobmff_reader/* MAX_BOX_HEADER_SIZE */.Xk) {
                    let mfraHeaderSlice = this.reader.requestSliceRange(potentialMfraPos, isobmff_reader/* MIN_BOX_HEADER_SIZE */.ZM, isobmff_reader/* MAX_BOX_HEADER_SIZE */.Xk);
                    if (mfraHeaderSlice instanceof Promise)
                        mfraHeaderSlice = await mfraHeaderSlice;
                    if (mfraHeaderSlice) {
                        const boxInfo = (0,isobmff_reader/* readBoxHeader */.Vl)(mfraHeaderSlice);
                        if (boxInfo && boxInfo.name === 'mfra') {
                            // We found the mfra box, allowing for much better random access. Let's parse it.
                            let mfraSlice = this.reader.requestSlice(mfraHeaderSlice.filePos, boxInfo.contentSize);
                            if (mfraSlice instanceof Promise)
                                mfraSlice = await mfraSlice;
                            if (mfraSlice) {
                                this.readContiguousBoxes(mfraSlice);
                            }
                        }
                    }
                }
            }
        })();
    }
    getSampleTableForTrack(internalTrack) {
        if (internalTrack.sampleTable) {
            return internalTrack.sampleTable;
        }
        const sampleTable = {
            sampleTimingEntries: [],
            sampleCompositionTimeOffsets: [],
            sampleSizes: [],
            keySampleIndices: null,
            chunkOffsets: [],
            sampleToChunk: [],
            presentationTimestamps: null,
            presentationTimestampIndexMap: null,
        };
        internalTrack.sampleTable = sampleTable;
        (0,misc/* assert */.vA)(this.moovSlice);
        const stblContainerSlice = this.moovSlice.slice(internalTrack.sampleTableByteOffset);
        this.currentTrack = internalTrack;
        this.traverseBox(stblContainerSlice);
        this.currentTrack = null;
        const isPcmCodec = internalTrack.info?.type === 'audio'
            && internalTrack.info.codec
            && codec/* PCM_AUDIO_CODECS */.Wq.includes(internalTrack.info.codec);
        if (isPcmCodec && sampleTable.sampleCompositionTimeOffsets.length === 0) {
            // If the audio has PCM samples, the way the samples are defined in the sample table is somewhat
            // suboptimal: Each individual audio sample is its own sample, meaning we can have 48000 samples per second.
            // Because we treat each sample as its own atomic unit that can be decoded, this would lead to a huge
            // amount of very short samples for PCM audio. So instead, we make a transformation: If the audio is in PCM,
            // we say that each chunk (that normally holds many samples) now is one big sample. We can this because
            // the samples in the chunk are contiguous and the format is PCM, so the entire chunk as one thing still
            // encodes valid audio information.
            (0,misc/* assert */.vA)(internalTrack.info?.type === 'audio');
            const pcmInfo = (0,codec/* parsePcmCodec */.Ei)(internalTrack.info.codec);
            const newSampleTimingEntries = [];
            const newSampleSizes = [];
            for (let i = 0; i < sampleTable.sampleToChunk.length; i++) {
                const chunkEntry = sampleTable.sampleToChunk[i];
                const nextEntry = sampleTable.sampleToChunk[i + 1];
                const chunkCount = (nextEntry ? nextEntry.startChunkIndex : sampleTable.chunkOffsets.length)
                    - chunkEntry.startChunkIndex;
                for (let j = 0; j < chunkCount; j++) {
                    const startSampleIndex = chunkEntry.startSampleIndex + j * chunkEntry.samplesPerChunk;
                    const endSampleIndex = startSampleIndex + chunkEntry.samplesPerChunk; // Exclusive, outside of chunk
                    const startTimingEntryIndex = (0,misc/* binarySearchLessOrEqual */.eE)(sampleTable.sampleTimingEntries, startSampleIndex, x => x.startIndex);
                    const startTimingEntry = sampleTable.sampleTimingEntries[startTimingEntryIndex];
                    const endTimingEntryIndex = (0,misc/* binarySearchLessOrEqual */.eE)(sampleTable.sampleTimingEntries, endSampleIndex, x => x.startIndex);
                    const endTimingEntry = sampleTable.sampleTimingEntries[endTimingEntryIndex];
                    const firstSampleTimestamp = startTimingEntry.startDecodeTimestamp
                        + (startSampleIndex - startTimingEntry.startIndex) * startTimingEntry.delta;
                    const lastSampleTimestamp = endTimingEntry.startDecodeTimestamp
                        + (endSampleIndex - endTimingEntry.startIndex) * endTimingEntry.delta;
                    const delta = lastSampleTimestamp - firstSampleTimestamp;
                    const lastSampleTimingEntry = (0,misc/* last */._g)(newSampleTimingEntries);
                    if (lastSampleTimingEntry && lastSampleTimingEntry.delta === delta) {
                        lastSampleTimingEntry.count++;
                    }
                    else {
                        // One sample for the entire chunk
                        newSampleTimingEntries.push({
                            startIndex: chunkEntry.startChunkIndex + j,
                            startDecodeTimestamp: firstSampleTimestamp,
                            count: 1,
                            delta,
                        });
                    }
                    // Instead of determining the chunk's size by looping over the samples sizes in the sample table, we
                    // can directly compute it as we know how many PCM frames are in this chunk, and the size of each
                    // PCM frame. This also improves compatibility with some files which fail to write proper sample
                    // size values into their sample tables in the PCM case.
                    const chunkSize = chunkEntry.samplesPerChunk
                        * pcmInfo.sampleSize
                        * internalTrack.info.numberOfChannels;
                    newSampleSizes.push(chunkSize);
                }
                chunkEntry.startSampleIndex = chunkEntry.startChunkIndex;
                chunkEntry.samplesPerChunk = 1;
            }
            sampleTable.sampleTimingEntries = newSampleTimingEntries;
            sampleTable.sampleSizes = newSampleSizes;
        }
        if (sampleTable.sampleCompositionTimeOffsets.length > 0) {
            // If composition time offsets are defined, we must build a list of all presentation timestamps and then
            // sort them
            sampleTable.presentationTimestamps = [];
            for (const entry of sampleTable.sampleTimingEntries) {
                for (let i = 0; i < entry.count; i++) {
                    sampleTable.presentationTimestamps.push({
                        presentationTimestamp: entry.startDecodeTimestamp + i * entry.delta,
                        sampleIndex: entry.startIndex + i,
                    });
                }
            }
            for (const entry of sampleTable.sampleCompositionTimeOffsets) {
                for (let i = 0; i < entry.count; i++) {
                    const sampleIndex = entry.startIndex + i;
                    const sample = sampleTable.presentationTimestamps[sampleIndex];
                    if (!sample) {
                        continue;
                    }
                    sample.presentationTimestamp += entry.offset;
                }
            }
            sampleTable.presentationTimestamps.sort((a, b) => a.presentationTimestamp - b.presentationTimestamp);
            sampleTable.presentationTimestampIndexMap = Array(sampleTable.presentationTimestamps.length).fill(-1);
            for (let i = 0; i < sampleTable.presentationTimestamps.length; i++) {
                sampleTable.presentationTimestampIndexMap[sampleTable.presentationTimestamps[i].sampleIndex] = i;
            }
        }
        else {
            // If they're not defined, we can simply use the decode timestamps as presentation timestamps
        }
        return sampleTable;
    }
    async readFragment(startPos) {
        if (this.lastReadFragment?.moofOffset === startPos) {
            return this.lastReadFragment;
        }
        let headerSlice = this.reader.requestSliceRange(startPos, isobmff_reader/* MIN_BOX_HEADER_SIZE */.ZM, isobmff_reader/* MAX_BOX_HEADER_SIZE */.Xk);
        if (headerSlice instanceof Promise)
            headerSlice = await headerSlice;
        (0,misc/* assert */.vA)(headerSlice);
        const moofBoxInfo = (0,isobmff_reader/* readBoxHeader */.Vl)(headerSlice);
        (0,misc/* assert */.vA)(moofBoxInfo?.name === 'moof');
        let entireSlice = this.reader.requestSlice(startPos, moofBoxInfo.totalSize);
        if (entireSlice instanceof Promise)
            entireSlice = await entireSlice;
        (0,misc/* assert */.vA)(entireSlice);
        this.traverseBox(entireSlice);
        const fragment = this.lastReadFragment;
        (0,misc/* assert */.vA)(fragment && fragment.moofOffset === startPos);
        for (const [, trackData] of fragment.trackData) {
            const track = trackData.track;
            const { fragmentPositionCache } = track;
            if (!trackData.startTimestampIsFinal) {
                // It may be that some tracks don't define the base decode time, i.e. when the fragment begins. This
                // we'll need to figure out the start timestamp another way. We'll compute the timestamp by accessing
                // the lookup entries and fragment cache, which works out nicely with the lookup algorithm: If these
                // exist, then the lookup will automatically start at the furthest possible point. If they don't, the
                // lookup starts sequentially from the start, incrementally summing up all fragment durations. It's sort
                // of implicit, but it ends up working nicely.
                const lookupEntry = track.fragmentLookupTable.find(x => x.moofOffset === fragment.moofOffset);
                if (lookupEntry) {
                    // There's a lookup entry, let's use its timestamp
                    offsetFragmentTrackDataByTimestamp(trackData, lookupEntry.timestamp);
                }
                else {
                    const lastCacheIndex = (0,misc/* binarySearchLessOrEqual */.eE)(fragmentPositionCache, fragment.moofOffset - 1, x => x.moofOffset);
                    if (lastCacheIndex !== -1) {
                        // Let's use the timestamp of the previous fragment in the cache
                        const lastCache = fragmentPositionCache[lastCacheIndex];
                        offsetFragmentTrackDataByTimestamp(trackData, lastCache.endTimestamp);
                    }
                    else {
                        // We're the first fragment I guess, "offset by 0"
                    }
                }
                trackData.startTimestampIsFinal = true;
            }
            // Let's remember that a fragment with a given timestamp is here, speeding up future lookups if no
            // lookup table exists
            const insertionIndex = (0,misc/* binarySearchLessOrEqual */.eE)(fragmentPositionCache, trackData.startTimestamp, x => x.startTimestamp);
            if (insertionIndex === -1
                || fragmentPositionCache[insertionIndex].moofOffset !== fragment.moofOffset) {
                fragmentPositionCache.splice(insertionIndex + 1, 0, {
                    moofOffset: fragment.moofOffset,
                    startTimestamp: trackData.startTimestamp,
                    endTimestamp: trackData.endTimestamp,
                });
            }
        }
        return fragment;
    }
    readContiguousBoxes(slice) {
        const startIndex = slice.filePos;
        while (slice.filePos - startIndex <= slice.length - isobmff_reader/* MIN_BOX_HEADER_SIZE */.ZM) {
            const foundBox = this.traverseBox(slice);
            if (!foundBox) {
                break;
            }
        }
    }
    // eslint-disable-next-line @stylistic/generator-star-spacing
    *iterateContiguousBoxes(slice) {
        const startIndex = slice.filePos;
        while (slice.filePos - startIndex <= slice.length - isobmff_reader/* MIN_BOX_HEADER_SIZE */.ZM) {
            const startPos = slice.filePos;
            const boxInfo = (0,isobmff_reader/* readBoxHeader */.Vl)(slice);
            if (!boxInfo) {
                break;
            }
            yield { boxInfo, slice };
            slice.filePos = startPos + boxInfo.totalSize;
        }
    }
    traverseBox(slice) {
        const startPos = slice.filePos;
        const boxInfo = (0,isobmff_reader/* readBoxHeader */.Vl)(slice);
        if (!boxInfo) {
            return false;
        }
        const contentStartPos = slice.filePos;
        const boxEndPos = startPos + boxInfo.totalSize;
        switch (boxInfo.name) {
            case 'mdia':
            case 'minf':
            case 'dinf':
            case 'mfra':
            case 'edts':
                {
                    this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
                }
                ;
                break;
            case 'mvhd':
                {
                    const version = (0,src_reader/* readU8 */.eo)(slice);
                    slice.skip(3); // Flags
                    if (version === 1) {
                        slice.skip(8 + 8);
                        this.movieTimescale = (0,src_reader/* readU32Be */.cN)(slice);
                        this.movieDurationInTimescale = (0,src_reader/* readU64Be */.th)(slice);
                    }
                    else {
                        slice.skip(4 + 4);
                        this.movieTimescale = (0,src_reader/* readU32Be */.cN)(slice);
                        this.movieDurationInTimescale = (0,src_reader/* readU32Be */.cN)(slice);
                    }
                }
                ;
                break;
            case 'trak':
                {
                    const track = {
                        id: -1,
                        demuxer: this,
                        inputTrack: null,
                        disposition: {
                            ...metadata/* DEFAULT_TRACK_DISPOSITION */.gM,
                        },
                        info: null,
                        timescale: -1,
                        durationInMovieTimescale: -1,
                        durationInMediaTimescale: -1,
                        rotation: 0,
                        internalCodecId: null,
                        name: null,
                        languageCode: misc/* UNDETERMINED_LANGUAGE */.IR,
                        sampleTableByteOffset: -1,
                        sampleTable: null,
                        fragmentLookupTable: [],
                        currentFragmentState: null,
                        fragmentPositionCache: [],
                        editListPreviousSegmentDurations: 0,
                        editListOffset: 0,
                    };
                    this.currentTrack = track;
                    this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
                    if (track.id !== -1 && track.timescale !== -1 && track.info !== null) {
                        if (track.info.type === 'video' && track.info.width !== -1) {
                            const videoTrack = track;
                            track.inputTrack = new input_track/* InputVideoTrack */.N0(this.input, new IsobmffVideoTrackBacking(videoTrack));
                            this.tracks.push(track);
                        }
                        else if (track.info.type === 'audio' && track.info.numberOfChannels !== -1) {
                            const audioTrack = track;
                            track.inputTrack = new input_track/* InputAudioTrack */.Yi(this.input, new IsobmffAudioTrackBacking(audioTrack));
                            this.tracks.push(track);
                        }
                    }
                    this.currentTrack = null;
                }
                ;
                break;
            case 'tkhd':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    const version = (0,src_reader/* readU8 */.eo)(slice);
                    const flags = (0,src_reader/* readU24Be */.n2)(slice);
                    // Spec says disabled tracks are to be treated like they don't exist, but in practice, they are treated
                    // more like non-default tracks.
                    const trackEnabled = !!(flags & 0x1);
                    track.disposition.default = trackEnabled;
                    // Skip over creation & modification time to reach the track ID
                    if (version === 0) {
                        slice.skip(8);
                        track.id = (0,src_reader/* readU32Be */.cN)(slice);
                        slice.skip(4);
                        track.durationInMovieTimescale = (0,src_reader/* readU32Be */.cN)(slice);
                    }
                    else if (version === 1) {
                        slice.skip(16);
                        track.id = (0,src_reader/* readU32Be */.cN)(slice);
                        slice.skip(4);
                        track.durationInMovieTimescale = (0,src_reader/* readU64Be */.th)(slice);
                    }
                    else {
                        throw new Error(`Incorrect track header version ${version}.`);
                    }
                    slice.skip(2 * 4 + 2 + 2 + 2 + 2);
                    const matrix = [
                        (0,isobmff_reader/* readFixed_16_16 */.vX)(slice),
                        (0,isobmff_reader/* readFixed_16_16 */.vX)(slice),
                        (0,isobmff_reader/* readFixed_2_30 */.IS)(slice),
                        (0,isobmff_reader/* readFixed_16_16 */.vX)(slice),
                        (0,isobmff_reader/* readFixed_16_16 */.vX)(slice),
                        (0,isobmff_reader/* readFixed_2_30 */.IS)(slice),
                        (0,isobmff_reader/* readFixed_16_16 */.vX)(slice),
                        (0,isobmff_reader/* readFixed_16_16 */.vX)(slice),
                        (0,isobmff_reader/* readFixed_2_30 */.IS)(slice),
                    ];
                    const rotation = (0,misc/* normalizeRotation */.qT)((0,misc/* roundToMultiple */["in"])(extractRotationFromMatrix(matrix), 90));
                    (0,misc/* assert */.vA)(rotation === 0 || rotation === 90 || rotation === 180 || rotation === 270);
                    track.rotation = rotation;
                }
                ;
                break;
            case 'elst':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    const version = (0,src_reader/* readU8 */.eo)(slice);
                    slice.skip(3); // Flags
                    let relevantEntryFound = false;
                    let previousSegmentDurations = 0;
                    const entryCount = (0,src_reader/* readU32Be */.cN)(slice);
                    for (let i = 0; i < entryCount; i++) {
                        const segmentDuration = version === 1
                            ? (0,src_reader/* readU64Be */.th)(slice)
                            : (0,src_reader/* readU32Be */.cN)(slice);
                        const mediaTime = version === 1
                            ? (0,src_reader/* readI64Be */.B5)(slice)
                            : (0,src_reader/* readI32Be */.Ar)(slice);
                        const mediaRate = (0,isobmff_reader/* readFixed_16_16 */.vX)(slice);
                        if (segmentDuration === 0) {
                            // Don't care
                            continue;
                        }
                        if (relevantEntryFound) {
                            console.warn('Unsupported edit list: multiple edits are not currently supported. Only using first edit.');
                            break;
                        }
                        if (mediaTime === -1) {
                            previousSegmentDurations += segmentDuration;
                            continue;
                        }
                        if (mediaRate !== 1) {
                            console.warn('Unsupported edit list entry: media rate must be 1.');
                            break;
                        }
                        track.editListPreviousSegmentDurations = previousSegmentDurations;
                        track.editListOffset = mediaTime;
                        relevantEntryFound = true;
                    }
                }
                ;
                break;
            case 'mdhd':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    const version = (0,src_reader/* readU8 */.eo)(slice);
                    slice.skip(3); // Flags
                    if (version === 0) {
                        slice.skip(8);
                        track.timescale = (0,src_reader/* readU32Be */.cN)(slice);
                        track.durationInMediaTimescale = (0,src_reader/* readU32Be */.cN)(slice);
                    }
                    else if (version === 1) {
                        slice.skip(16);
                        track.timescale = (0,src_reader/* readU32Be */.cN)(slice);
                        track.durationInMediaTimescale = (0,src_reader/* readU64Be */.th)(slice);
                    }
                    let language = (0,src_reader/* readU16Be */.mH)(slice);
                    if (language > 0) {
                        track.languageCode = '';
                        for (let i = 0; i < 3; i++) {
                            track.languageCode = String.fromCharCode(0x60 + (language & 0b11111)) + track.languageCode;
                            language >>= 5;
                        }
                        if (!(0,misc/* isIso639Dash2LanguageCode */.Nu)(track.languageCode)) {
                            // Sometimes the bytes are garbage
                            track.languageCode = misc/* UNDETERMINED_LANGUAGE */.IR;
                        }
                    }
                }
                ;
                break;
            case 'hdlr':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    slice.skip(8); // Version + flags + pre-defined
                    const handlerType = (0,src_reader/* readAscii */.IT)(slice, 4);
                    if (handlerType === 'vide') {
                        track.info = {
                            type: 'video',
                            width: -1,
                            height: -1,
                            codec: null,
                            codecDescription: null,
                            colorSpace: null,
                            avcType: null,
                            avcCodecInfo: null,
                            hevcCodecInfo: null,
                            vp9CodecInfo: null,
                            av1CodecInfo: null,
                        };
                    }
                    else if (handlerType === 'soun') {
                        track.info = {
                            type: 'audio',
                            numberOfChannels: -1,
                            sampleRate: -1,
                            codec: null,
                            codecDescription: null,
                            aacCodecInfo: null,
                        };
                    }
                }
                ;
                break;
            case 'stbl':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    track.sampleTableByteOffset = startPos;
                    this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
                }
                ;
                break;
            case 'stsd':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    if (track.info === null || track.sampleTable) {
                        break;
                    }
                    const stsdVersion = (0,src_reader/* readU8 */.eo)(slice);
                    slice.skip(3); // Flags
                    const entries = (0,src_reader/* readU32Be */.cN)(slice);
                    for (let i = 0; i < entries; i++) {
                        const sampleBoxStartPos = slice.filePos;
                        const sampleBoxInfo = (0,isobmff_reader/* readBoxHeader */.Vl)(slice);
                        if (!sampleBoxInfo) {
                            break;
                        }
                        track.internalCodecId = sampleBoxInfo.name;
                        const lowercaseBoxName = sampleBoxInfo.name.toLowerCase();
                        if (track.info.type === 'video') {
                            if (lowercaseBoxName === 'avc1' || lowercaseBoxName === 'avc3') {
                                track.info.codec = 'avc';
                                track.info.avcType = lowercaseBoxName === 'avc1' ? 1 : 3;
                            }
                            else if (lowercaseBoxName === 'hvc1' || lowercaseBoxName === 'hev1') {
                                track.info.codec = 'hevc';
                            }
                            else if (lowercaseBoxName === 'vp08') {
                                track.info.codec = 'vp8';
                            }
                            else if (lowercaseBoxName === 'vp09') {
                                track.info.codec = 'vp9';
                            }
                            else if (lowercaseBoxName === 'av01') {
                                track.info.codec = 'av1';
                            }
                            else {
                                console.warn(`Unsupported video codec (sample entry type '${sampleBoxInfo.name}').`);
                            }
                            slice.skip(6 * 1 + 2 + 2 + 2 + 3 * 4);
                            track.info.width = (0,src_reader/* readU16Be */.mH)(slice);
                            track.info.height = (0,src_reader/* readU16Be */.mH)(slice);
                            slice.skip(4 + 4 + 4 + 2 + 32 + 2 + 2);
                            this.readContiguousBoxes(slice.slice(slice.filePos, (sampleBoxStartPos + sampleBoxInfo.totalSize) - slice.filePos));
                        }
                        else {
                            if (lowercaseBoxName === 'mp4a') {
                                // We don't know the codec yet (might be AAC, might be MP3), need to read the esds box
                            }
                            else if (lowercaseBoxName === 'opus') {
                                track.info.codec = 'opus';
                            }
                            else if (lowercaseBoxName === 'flac') {
                                track.info.codec = 'flac';
                            }
                            else if (lowercaseBoxName === 'twos'
                                || lowercaseBoxName === 'sowt'
                                || lowercaseBoxName === 'raw '
                                || lowercaseBoxName === 'in24'
                                || lowercaseBoxName === 'in32'
                                || lowercaseBoxName === 'fl32'
                                || lowercaseBoxName === 'fl64'
                                || lowercaseBoxName === 'lpcm'
                                || lowercaseBoxName === 'ipcm' // ISO/IEC 23003-5
                                || lowercaseBoxName === 'fpcm' // "
                            ) {
                                // It's PCM
                                // developer.apple.com/documentation/quicktime-file-format/sound_sample_descriptions/
                            }
                            else if (lowercaseBoxName === 'ulaw') {
                                track.info.codec = 'ulaw';
                            }
                            else if (lowercaseBoxName === 'alaw') {
                                track.info.codec = 'alaw';
                            }
                            else if (lowercaseBoxName === 'ac-3') {
                                track.info.codec = 'ac3';
                            }
                            else if (lowercaseBoxName === 'ec-3') {
                                track.info.codec = 'eac3';
                            }
                            else {
                                console.warn(`Unsupported audio codec (sample entry type '${sampleBoxInfo.name}').`);
                            }
                            slice.skip(6 * 1 + 2);
                            const version = (0,src_reader/* readU16Be */.mH)(slice);
                            slice.skip(3 * 2);
                            let channelCount = (0,src_reader/* readU16Be */.mH)(slice);
                            let sampleSize = (0,src_reader/* readU16Be */.mH)(slice);
                            slice.skip(2 * 2);
                            // Can't use fixed16_16 as that's signed
                            let sampleRate = (0,src_reader/* readU32Be */.cN)(slice) / 0x10000;
                            if (stsdVersion === 0 && version > 0) {
                                // Additional QuickTime fields
                                if (version === 1) {
                                    slice.skip(4);
                                    sampleSize = 8 * (0,src_reader/* readU32Be */.cN)(slice);
                                    slice.skip(2 * 4);
                                }
                                else if (version === 2) {
                                    slice.skip(4);
                                    sampleRate = (0,src_reader/* readF64Be */._3)(slice);
                                    channelCount = (0,src_reader/* readU32Be */.cN)(slice);
                                    slice.skip(4); // Always 0x7f000000
                                    sampleSize = (0,src_reader/* readU32Be */.cN)(slice);
                                    const flags = (0,src_reader/* readU32Be */.cN)(slice);
                                    slice.skip(2 * 4);
                                    if (lowercaseBoxName === 'lpcm') {
                                        const bytesPerSample = (sampleSize + 7) >> 3;
                                        const isFloat = Boolean(flags & 1);
                                        const isBigEndian = Boolean(flags & 2);
                                        const sFlags = flags & 4 ? -1 : 0; // I guess it means "signed flags" or something?
                                        if (sampleSize > 0 && sampleSize <= 64) {
                                            if (isFloat) {
                                                if (sampleSize === 32) {
                                                    track.info.codec = isBigEndian ? 'pcm-f32be' : 'pcm-f32';
                                                }
                                            }
                                            else {
                                                if (sFlags & (1 << (bytesPerSample - 1))) {
                                                    if (bytesPerSample === 1) {
                                                        track.info.codec = 'pcm-s8';
                                                    }
                                                    else if (bytesPerSample === 2) {
                                                        track.info.codec = isBigEndian ? 'pcm-s16be' : 'pcm-s16';
                                                    }
                                                    else if (bytesPerSample === 3) {
                                                        track.info.codec = isBigEndian ? 'pcm-s24be' : 'pcm-s24';
                                                    }
                                                    else if (bytesPerSample === 4) {
                                                        track.info.codec = isBigEndian ? 'pcm-s32be' : 'pcm-s32';
                                                    }
                                                }
                                                else {
                                                    if (bytesPerSample === 1) {
                                                        track.info.codec = 'pcm-u8';
                                                    }
                                                }
                                            }
                                        }
                                        if (track.info.codec === null) {
                                            console.warn('Unsupported PCM format.');
                                        }
                                    }
                                }
                            }
                            if (track.info.codec === 'opus') {
                                sampleRate = codec/* OPUS_SAMPLE_RATE */.yo; // Always the same
                            }
                            track.info.numberOfChannels = channelCount;
                            track.info.sampleRate = sampleRate;
                            // PCM codec assignments
                            if (lowercaseBoxName === 'twos') {
                                if (sampleSize === 8) {
                                    track.info.codec = 'pcm-s8';
                                }
                                else if (sampleSize === 16) {
                                    track.info.codec = 'pcm-s16be';
                                }
                                else {
                                    console.warn(`Unsupported sample size ${sampleSize} for codec 'twos'.`);
                                    track.info.codec = null;
                                }
                            }
                            else if (lowercaseBoxName === 'sowt') {
                                if (sampleSize === 8) {
                                    track.info.codec = 'pcm-s8';
                                }
                                else if (sampleSize === 16) {
                                    track.info.codec = 'pcm-s16';
                                }
                                else {
                                    console.warn(`Unsupported sample size ${sampleSize} for codec 'sowt'.`);
                                    track.info.codec = null;
                                }
                            }
                            else if (lowercaseBoxName === 'raw ') {
                                track.info.codec = 'pcm-u8';
                            }
                            else if (lowercaseBoxName === 'in24') {
                                track.info.codec = 'pcm-s24be';
                            }
                            else if (lowercaseBoxName === 'in32') {
                                track.info.codec = 'pcm-s32be';
                            }
                            else if (lowercaseBoxName === 'fl32') {
                                track.info.codec = 'pcm-f32be';
                            }
                            else if (lowercaseBoxName === 'fl64') {
                                track.info.codec = 'pcm-f64be';
                            }
                            else if (lowercaseBoxName === 'ipcm') {
                                track.info.codec = 'pcm-s16be'; // Placeholder, will be adjusted by the pcmC box
                            }
                            else if (lowercaseBoxName === 'fpcm') {
                                track.info.codec = 'pcm-f32be'; // Placeholder, will be adjusted by the pcmC box
                            }
                            this.readContiguousBoxes(slice.slice(slice.filePos, (sampleBoxStartPos + sampleBoxInfo.totalSize) - slice.filePos));
                        }
                    }
                }
                ;
                break;
            case 'avcC':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    (0,misc/* assert */.vA)(track.info);
                    track.info.codecDescription = (0,src_reader/* readBytes */.io)(slice, boxInfo.contentSize);
                }
                ;
                break;
            case 'hvcC':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    (0,misc/* assert */.vA)(track.info);
                    track.info.codecDescription = (0,src_reader/* readBytes */.io)(slice, boxInfo.contentSize);
                }
                ;
                break;
            case 'vpcC':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    (0,misc/* assert */.vA)(track.info?.type === 'video');
                    slice.skip(4); // Version + flags
                    const profile = (0,src_reader/* readU8 */.eo)(slice);
                    const level = (0,src_reader/* readU8 */.eo)(slice);
                    const thirdByte = (0,src_reader/* readU8 */.eo)(slice);
                    const bitDepth = thirdByte >> 4;
                    const chromaSubsampling = (thirdByte >> 1) & 0b111;
                    const videoFullRangeFlag = thirdByte & 1;
                    const colourPrimaries = (0,src_reader/* readU8 */.eo)(slice);
                    const transferCharacteristics = (0,src_reader/* readU8 */.eo)(slice);
                    const matrixCoefficients = (0,src_reader/* readU8 */.eo)(slice);
                    track.info.vp9CodecInfo = {
                        profile,
                        level,
                        bitDepth,
                        chromaSubsampling,
                        videoFullRangeFlag,
                        colourPrimaries,
                        transferCharacteristics,
                        matrixCoefficients,
                    };
                }
                ;
                break;
            case 'av1C':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    (0,misc/* assert */.vA)(track.info?.type === 'video');
                    slice.skip(1); // Marker + version
                    const secondByte = (0,src_reader/* readU8 */.eo)(slice);
                    const profile = secondByte >> 5;
                    const level = secondByte & 0b11111;
                    const thirdByte = (0,src_reader/* readU8 */.eo)(slice);
                    const tier = thirdByte >> 7;
                    const highBitDepth = (thirdByte >> 6) & 1;
                    const twelveBit = (thirdByte >> 5) & 1;
                    const monochrome = (thirdByte >> 4) & 1;
                    const chromaSubsamplingX = (thirdByte >> 3) & 1;
                    const chromaSubsamplingY = (thirdByte >> 2) & 1;
                    const chromaSamplePosition = thirdByte & 0b11;
                    // Logic from https://aomediacodec.github.io/av1-spec/av1-spec.pdf
                    const bitDepth = profile === 2 && highBitDepth ? (twelveBit ? 12 : 10) : (highBitDepth ? 10 : 8);
                    track.info.av1CodecInfo = {
                        profile,
                        level,
                        tier,
                        bitDepth,
                        monochrome,
                        chromaSubsamplingX,
                        chromaSubsamplingY,
                        chromaSamplePosition,
                    };
                }
                ;
                break;
            case 'colr':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    (0,misc/* assert */.vA)(track.info?.type === 'video');
                    const colourType = (0,src_reader/* readAscii */.IT)(slice, 4);
                    if (colourType !== 'nclx') {
                        break;
                    }
                    const colourPrimaries = (0,src_reader/* readU16Be */.mH)(slice);
                    const transferCharacteristics = (0,src_reader/* readU16Be */.mH)(slice);
                    const matrixCoefficients = (0,src_reader/* readU16Be */.mH)(slice);
                    const fullRangeFlag = Boolean((0,src_reader/* readU8 */.eo)(slice) & 0x80);
                    track.info.colorSpace = {
                        primaries: misc/* COLOR_PRIMARIES_MAP_INVERSE */.BL[colourPrimaries],
                        transfer: misc/* TRANSFER_CHARACTERISTICS_MAP_INVERSE */.x_[transferCharacteristics],
                        matrix: misc/* MATRIX_COEFFICIENTS_MAP_INVERSE */.fl[matrixCoefficients],
                        fullRange: fullRangeFlag,
                    };
                }
                ;
                break;
            case 'wave':
                {
                    this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
                }
                ;
                break;
            case 'esds':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    (0,misc/* assert */.vA)(track.info?.type === 'audio');
                    slice.skip(4); // Version + flags
                    const tag = (0,src_reader/* readU8 */.eo)(slice);
                    (0,misc/* assert */.vA)(tag === 0x03); // ES Descriptor
                    (0,isobmff_reader/* readIsomVariableInteger */.hs)(slice); // Length
                    slice.skip(2); // ES ID
                    const mixed = (0,src_reader/* readU8 */.eo)(slice);
                    const streamDependenceFlag = (mixed & 0x80) !== 0;
                    const urlFlag = (mixed & 0x40) !== 0;
                    const ocrStreamFlag = (mixed & 0x20) !== 0;
                    if (streamDependenceFlag) {
                        slice.skip(2);
                    }
                    if (urlFlag) {
                        const urlLength = (0,src_reader/* readU8 */.eo)(slice);
                        slice.skip(urlLength);
                    }
                    if (ocrStreamFlag) {
                        slice.skip(2);
                    }
                    const decoderConfigTag = (0,src_reader/* readU8 */.eo)(slice);
                    (0,misc/* assert */.vA)(decoderConfigTag === 0x04); // DecoderConfigDescriptor
                    const decoderConfigDescriptorLength = (0,isobmff_reader/* readIsomVariableInteger */.hs)(slice); // Length
                    const payloadStart = slice.filePos;
                    const objectTypeIndication = (0,src_reader/* readU8 */.eo)(slice);
                    if (objectTypeIndication === 0x40 || objectTypeIndication === 0x67) {
                        track.info.codec = 'aac';
                        track.info.aacCodecInfo = {
                            isMpeg2: objectTypeIndication === 0x67,
                            objectType: null,
                        };
                    }
                    else if (objectTypeIndication === 0x69 || objectTypeIndication === 0x6b) {
                        track.info.codec = 'mp3';
                    }
                    else if (objectTypeIndication === 0xdd) {
                        track.info.codec = 'vorbis'; // "nonstandard, gpac uses it" - FFmpeg
                    }
                    else {
                        console.warn(`Unsupported audio codec (objectTypeIndication ${objectTypeIndication}) - discarding track.`);
                    }
                    slice.skip(1 + 3 + 4 + 4);
                    if (decoderConfigDescriptorLength > slice.filePos - payloadStart) {
                        // There's a DecoderSpecificInfo at the end, let's read it
                        const decoderSpecificInfoTag = (0,src_reader/* readU8 */.eo)(slice);
                        (0,misc/* assert */.vA)(decoderSpecificInfoTag === 0x05); // DecoderSpecificInfo
                        const decoderSpecificInfoLength = (0,isobmff_reader/* readIsomVariableInteger */.hs)(slice);
                        track.info.codecDescription = (0,src_reader/* readBytes */.io)(slice, decoderSpecificInfoLength);
                        if (track.info.codec === 'aac') {
                            // Let's try to deduce more accurate values directly from the AudioSpecificConfig:
                            const audioSpecificConfig = (0,codec/* parseAacAudioSpecificConfig */.zF)(track.info.codecDescription);
                            if (audioSpecificConfig.numberOfChannels !== null) {
                                track.info.numberOfChannels = audioSpecificConfig.numberOfChannels;
                            }
                            if (audioSpecificConfig.sampleRate !== null) {
                                track.info.sampleRate = audioSpecificConfig.sampleRate;
                            }
                        }
                    }
                }
                ;
                break;
            case 'enda':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    (0,misc/* assert */.vA)(track.info?.type === 'audio');
                    const littleEndian = (0,src_reader/* readU16Be */.mH)(slice) & 0xff; // 0xff is from FFmpeg
                    if (littleEndian) {
                        if (track.info.codec === 'pcm-s16be') {
                            track.info.codec = 'pcm-s16';
                        }
                        else if (track.info.codec === 'pcm-s24be') {
                            track.info.codec = 'pcm-s24';
                        }
                        else if (track.info.codec === 'pcm-s32be') {
                            track.info.codec = 'pcm-s32';
                        }
                        else if (track.info.codec === 'pcm-f32be') {
                            track.info.codec = 'pcm-f32';
                        }
                        else if (track.info.codec === 'pcm-f64be') {
                            track.info.codec = 'pcm-f64';
                        }
                    }
                }
                ;
                break;
            case 'pcmC':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    (0,misc/* assert */.vA)(track.info?.type === 'audio');
                    slice.skip(1 + 3); // Version + flags
                    // ISO/IEC 23003-5
                    const formatFlags = (0,src_reader/* readU8 */.eo)(slice);
                    const isLittleEndian = Boolean(formatFlags & 0x01);
                    const pcmSampleSize = (0,src_reader/* readU8 */.eo)(slice);
                    if (track.info.codec === 'pcm-s16be') {
                        // ipcm
                        if (isLittleEndian) {
                            if (pcmSampleSize === 16) {
                                track.info.codec = 'pcm-s16';
                            }
                            else if (pcmSampleSize === 24) {
                                track.info.codec = 'pcm-s24';
                            }
                            else if (pcmSampleSize === 32) {
                                track.info.codec = 'pcm-s32';
                            }
                            else {
                                console.warn(`Invalid ipcm sample size ${pcmSampleSize}.`);
                                track.info.codec = null;
                            }
                        }
                        else {
                            if (pcmSampleSize === 16) {
                                track.info.codec = 'pcm-s16be';
                            }
                            else if (pcmSampleSize === 24) {
                                track.info.codec = 'pcm-s24be';
                            }
                            else if (pcmSampleSize === 32) {
                                track.info.codec = 'pcm-s32be';
                            }
                            else {
                                console.warn(`Invalid ipcm sample size ${pcmSampleSize}.`);
                                track.info.codec = null;
                            }
                        }
                    }
                    else if (track.info.codec === 'pcm-f32be') {
                        // fpcm
                        if (isLittleEndian) {
                            if (pcmSampleSize === 32) {
                                track.info.codec = 'pcm-f32';
                            }
                            else if (pcmSampleSize === 64) {
                                track.info.codec = 'pcm-f64';
                            }
                            else {
                                console.warn(`Invalid fpcm sample size ${pcmSampleSize}.`);
                                track.info.codec = null;
                            }
                        }
                        else {
                            if (pcmSampleSize === 32) {
                                track.info.codec = 'pcm-f32be';
                            }
                            else if (pcmSampleSize === 64) {
                                track.info.codec = 'pcm-f64be';
                            }
                            else {
                                console.warn(`Invalid fpcm sample size ${pcmSampleSize}.`);
                                track.info.codec = null;
                            }
                        }
                    }
                    break;
                }
                ;
            case 'dOps':
                { // Used for Opus audio
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    (0,misc/* assert */.vA)(track.info?.type === 'audio');
                    slice.skip(1); // Version
                    // https://www.opus-codec.org/docs/opus_in_isobmff.html
                    const outputChannelCount = (0,src_reader/* readU8 */.eo)(slice);
                    const preSkip = (0,src_reader/* readU16Be */.mH)(slice);
                    const inputSampleRate = (0,src_reader/* readU32Be */.cN)(slice);
                    const outputGain = (0,src_reader/* readI16Be */.iH)(slice);
                    const channelMappingFamily = (0,src_reader/* readU8 */.eo)(slice);
                    let channelMappingTable;
                    if (channelMappingFamily !== 0) {
                        channelMappingTable = (0,src_reader/* readBytes */.io)(slice, 2 + outputChannelCount);
                    }
                    else {
                        channelMappingTable = new Uint8Array(0);
                    }
                    // https://datatracker.ietf.org/doc/html/draft-ietf-codec-oggopus-06
                    const description = new Uint8Array(8 + 1 + 1 + 2 + 4 + 2 + 1 + channelMappingTable.byteLength);
                    const view = new DataView(description.buffer);
                    view.setUint32(0, 0x4f707573, false); // 'Opus'
                    view.setUint32(4, 0x48656164, false); // 'Head'
                    view.setUint8(8, 1); // Version
                    view.setUint8(9, outputChannelCount);
                    view.setUint16(10, preSkip, true);
                    view.setUint32(12, inputSampleRate, true);
                    view.setInt16(16, outputGain, true);
                    view.setUint8(18, channelMappingFamily);
                    description.set(channelMappingTable, 19);
                    track.info.codecDescription = description;
                    track.info.numberOfChannels = outputChannelCount;
                    // Don't copy the input sample rate, irrelevant, and output sample rate is fixed
                }
                ;
                break;
            case 'dfLa':
                { // Used for FLAC audio
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    (0,misc/* assert */.vA)(track.info?.type === 'audio');
                    slice.skip(4); // Version + flags
                    // https://datatracker.ietf.org/doc/rfc9639/
                    const BLOCK_TYPE_MASK = 0x7f;
                    const LAST_METADATA_BLOCK_FLAG_MASK = 0x80;
                    const startPos = slice.filePos;
                    while (slice.filePos < boxEndPos) {
                        const flagAndType = (0,src_reader/* readU8 */.eo)(slice);
                        const metadataBlockLength = (0,src_reader/* readU24Be */.n2)(slice);
                        const type = flagAndType & BLOCK_TYPE_MASK;
                        // It's a STREAMINFO block; let's extract the actual sample rate and channel count
                        if (type === codec_data/* FlacBlockType */.A3.STREAMINFO) {
                            slice.skip(10);
                            // Extract sample rate and channel count
                            const word = (0,src_reader/* readU32Be */.cN)(slice);
                            const sampleRate = word >>> 12;
                            const numberOfChannels = ((word >> 9) & 0b111) + 1;
                            track.info.sampleRate = sampleRate;
                            track.info.numberOfChannels = numberOfChannels;
                            slice.skip(20);
                        }
                        else {
                            // Simply skip ahead to the next block
                            slice.skip(metadataBlockLength);
                        }
                        if (flagAndType & LAST_METADATA_BLOCK_FLAG_MASK) {
                            break;
                        }
                    }
                    const endPos = slice.filePos;
                    slice.filePos = startPos;
                    const bytes = (0,src_reader/* readBytes */.io)(slice, endPos - startPos);
                    const description = new Uint8Array(4 + bytes.byteLength);
                    const view = new DataView(description.buffer);
                    view.setUint32(0, 0x664c6143, false); // 'fLaC'
                    description.set(bytes, 4);
                    // Set the codec description to be 'fLaC' + all metadata blocks
                    track.info.codecDescription = description;
                }
                ;
                break;
            case 'dac3':
                { // AC3SpecificBox
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    (0,misc/* assert */.vA)(track.info?.type === 'audio');
                    const bytes = (0,src_reader/* readBytes */.io)(slice, 3);
                    const bitstream = new misc/* Bitstream */._c(bytes);
                    const fscod = bitstream.readBits(2);
                    bitstream.skipBits(5 + 3); // Skip bsid and bsmod
                    const acmod = bitstream.readBits(3);
                    const lfeon = bitstream.readBits(1);
                    if (fscod < 3) {
                        track.info.sampleRate = ac3_misc/* AC3_SAMPLE_RATES */.N[fscod];
                    }
                    track.info.numberOfChannels = codec_data/* AC3_ACMOD_CHANNEL_COUNTS */.ux[acmod] + lfeon;
                }
                ;
                break;
            case 'dec3':
                { // EC3SpecificBox
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    (0,misc/* assert */.vA)(track.info?.type === 'audio');
                    const bytes = (0,src_reader/* readBytes */.io)(slice, boxInfo.contentSize);
                    const config = (0,codec_data/* parseEac3Config */.Sd)(bytes);
                    if (!config) {
                        console.warn('Invalid dec3 box contents, ignoring.');
                        break;
                    }
                    const sampleRate = (0,codec_data/* getEac3SampleRate */.PK)(config);
                    if (sampleRate !== null) {
                        track.info.sampleRate = sampleRate;
                    }
                    track.info.numberOfChannels = (0,codec_data/* getEac3ChannelCount */.zV)(config);
                }
                ;
                break;
            case 'stts':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    if (!track.sampleTable) {
                        break;
                    }
                    slice.skip(4); // Version + flags
                    const entryCount = (0,src_reader/* readU32Be */.cN)(slice);
                    let currentIndex = 0;
                    let currentTimestamp = 0;
                    for (let i = 0; i < entryCount; i++) {
                        const sampleCount = (0,src_reader/* readU32Be */.cN)(slice);
                        const sampleDelta = (0,src_reader/* readU32Be */.cN)(slice);
                        track.sampleTable.sampleTimingEntries.push({
                            startIndex: currentIndex,
                            startDecodeTimestamp: currentTimestamp,
                            count: sampleCount,
                            delta: sampleDelta,
                        });
                        currentIndex += sampleCount;
                        currentTimestamp += sampleCount * sampleDelta;
                    }
                }
                ;
                break;
            case 'ctts':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    if (!track.sampleTable) {
                        break;
                    }
                    slice.skip(1 + 3); // Version + flags
                    const entryCount = (0,src_reader/* readU32Be */.cN)(slice);
                    let sampleIndex = 0;
                    for (let i = 0; i < entryCount; i++) {
                        const sampleCount = (0,src_reader/* readU32Be */.cN)(slice);
                        const sampleOffset = (0,src_reader/* readI32Be */.Ar)(slice);
                        track.sampleTable.sampleCompositionTimeOffsets.push({
                            startIndex: sampleIndex,
                            count: sampleCount,
                            offset: sampleOffset,
                        });
                        sampleIndex += sampleCount;
                    }
                }
                ;
                break;
            case 'stsz':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    if (!track.sampleTable) {
                        break;
                    }
                    slice.skip(4); // Version + flags
                    const sampleSize = (0,src_reader/* readU32Be */.cN)(slice);
                    const sampleCount = (0,src_reader/* readU32Be */.cN)(slice);
                    if (sampleSize === 0) {
                        for (let i = 0; i < sampleCount; i++) {
                            const sampleSize = (0,src_reader/* readU32Be */.cN)(slice);
                            track.sampleTable.sampleSizes.push(sampleSize);
                        }
                    }
                    else {
                        track.sampleTable.sampleSizes.push(sampleSize);
                    }
                }
                ;
                break;
            case 'stz2':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    if (!track.sampleTable) {
                        break;
                    }
                    slice.skip(4); // Version + flags
                    slice.skip(3); // Reserved
                    const fieldSize = (0,src_reader/* readU8 */.eo)(slice); // in bits
                    const sampleCount = (0,src_reader/* readU32Be */.cN)(slice);
                    const bytes = (0,src_reader/* readBytes */.io)(slice, Math.ceil(sampleCount * fieldSize / 8));
                    const bitstream = new misc/* Bitstream */._c(bytes);
                    for (let i = 0; i < sampleCount; i++) {
                        const sampleSize = bitstream.readBits(fieldSize);
                        track.sampleTable.sampleSizes.push(sampleSize);
                    }
                }
                ;
                break;
            case 'stss':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    if (!track.sampleTable) {
                        break;
                    }
                    slice.skip(4); // Version + flags
                    track.sampleTable.keySampleIndices = [];
                    const entryCount = (0,src_reader/* readU32Be */.cN)(slice);
                    for (let i = 0; i < entryCount; i++) {
                        const sampleIndex = (0,src_reader/* readU32Be */.cN)(slice) - 1; // Convert to 0-indexed
                        track.sampleTable.keySampleIndices.push(sampleIndex);
                    }
                    if (track.sampleTable.keySampleIndices[0] !== 0) {
                        // Some files don't mark the first sample a key sample, which is basically almost always incorrect.
                        // Here, we correct for that mistake:
                        track.sampleTable.keySampleIndices.unshift(0);
                    }
                }
                ;
                break;
            case 'stsc':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    if (!track.sampleTable) {
                        break;
                    }
                    slice.skip(4);
                    const entryCount = (0,src_reader/* readU32Be */.cN)(slice);
                    for (let i = 0; i < entryCount; i++) {
                        const startChunkIndex = (0,src_reader/* readU32Be */.cN)(slice) - 1; // Convert to 0-indexed
                        const samplesPerChunk = (0,src_reader/* readU32Be */.cN)(slice);
                        const sampleDescriptionIndex = (0,src_reader/* readU32Be */.cN)(slice);
                        track.sampleTable.sampleToChunk.push({
                            startSampleIndex: -1,
                            startChunkIndex,
                            samplesPerChunk,
                            sampleDescriptionIndex,
                        });
                    }
                    let startSampleIndex = 0;
                    for (let i = 0; i < track.sampleTable.sampleToChunk.length; i++) {
                        track.sampleTable.sampleToChunk[i].startSampleIndex = startSampleIndex;
                        if (i < track.sampleTable.sampleToChunk.length - 1) {
                            const nextChunk = track.sampleTable.sampleToChunk[i + 1];
                            const chunkCount = nextChunk.startChunkIndex
                                - track.sampleTable.sampleToChunk[i].startChunkIndex;
                            startSampleIndex += chunkCount * track.sampleTable.sampleToChunk[i].samplesPerChunk;
                        }
                    }
                }
                ;
                break;
            case 'stco':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    if (!track.sampleTable) {
                        break;
                    }
                    slice.skip(4); // Version + flags
                    const entryCount = (0,src_reader/* readU32Be */.cN)(slice);
                    for (let i = 0; i < entryCount; i++) {
                        const chunkOffset = (0,src_reader/* readU32Be */.cN)(slice);
                        track.sampleTable.chunkOffsets.push(chunkOffset);
                    }
                }
                ;
                break;
            case 'co64':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    if (!track.sampleTable) {
                        break;
                    }
                    slice.skip(4); // Version + flags
                    const entryCount = (0,src_reader/* readU32Be */.cN)(slice);
                    for (let i = 0; i < entryCount; i++) {
                        const chunkOffset = (0,src_reader/* readU64Be */.th)(slice);
                        track.sampleTable.chunkOffsets.push(chunkOffset);
                    }
                }
                ;
                break;
            case 'mvex':
                {
                    this.isFragmented = true;
                    this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
                }
                ;
                break;
            case 'mehd':
                {
                    const version = (0,src_reader/* readU8 */.eo)(slice);
                    slice.skip(3); // Flags
                    const fragmentDuration = version === 1 ? (0,src_reader/* readU64Be */.th)(slice) : (0,src_reader/* readU32Be */.cN)(slice);
                    this.movieDurationInTimescale = fragmentDuration;
                }
                ;
                break;
            case 'trex':
                {
                    slice.skip(4); // Version + flags
                    const trackId = (0,src_reader/* readU32Be */.cN)(slice);
                    const defaultSampleDescriptionIndex = (0,src_reader/* readU32Be */.cN)(slice);
                    const defaultSampleDuration = (0,src_reader/* readU32Be */.cN)(slice);
                    const defaultSampleSize = (0,src_reader/* readU32Be */.cN)(slice);
                    const defaultSampleFlags = (0,src_reader/* readU32Be */.cN)(slice);
                    // We store these separately rather than in the tracks since the tracks may not exist yet
                    this.fragmentTrackDefaults.push({
                        trackId,
                        defaultSampleDescriptionIndex,
                        defaultSampleDuration,
                        defaultSampleSize,
                        defaultSampleFlags,
                    });
                }
                ;
                break;
            case 'tfra':
                {
                    const version = (0,src_reader/* readU8 */.eo)(slice);
                    slice.skip(3); // Flags
                    const trackId = (0,src_reader/* readU32Be */.cN)(slice);
                    const track = this.tracks.find(x => x.id === trackId);
                    if (!track) {
                        break;
                    }
                    const word = (0,src_reader/* readU32Be */.cN)(slice);
                    const lengthSizeOfTrafNum = (word & 0b110000) >> 4;
                    const lengthSizeOfTrunNum = (word & 0b001100) >> 2;
                    const lengthSizeOfSampleNum = word & 0b000011;
                    const functions = [src_reader/* readU8 */.eo, src_reader/* readU16Be */.mH, src_reader/* readU24Be */.n2, src_reader/* readU32Be */.cN];
                    const readTrafNum = functions[lengthSizeOfTrafNum];
                    const readTrunNum = functions[lengthSizeOfTrunNum];
                    const readSampleNum = functions[lengthSizeOfSampleNum];
                    const numberOfEntries = (0,src_reader/* readU32Be */.cN)(slice);
                    for (let i = 0; i < numberOfEntries; i++) {
                        const time = version === 1 ? (0,src_reader/* readU64Be */.th)(slice) : (0,src_reader/* readU32Be */.cN)(slice);
                        const moofOffset = version === 1 ? (0,src_reader/* readU64Be */.th)(slice) : (0,src_reader/* readU32Be */.cN)(slice);
                        readTrafNum(slice);
                        readTrunNum(slice);
                        readSampleNum(slice);
                        track.fragmentLookupTable.push({
                            timestamp: time,
                            moofOffset,
                        });
                    }
                    // Sort by timestamp in case it's not naturally sorted
                    track.fragmentLookupTable.sort((a, b) => a.timestamp - b.timestamp);
                    // Remove multiple entries for the same time
                    for (let i = 0; i < track.fragmentLookupTable.length - 1; i++) {
                        const entry1 = track.fragmentLookupTable[i];
                        const entry2 = track.fragmentLookupTable[i + 1];
                        if (entry1.timestamp === entry2.timestamp) {
                            track.fragmentLookupTable.splice(i + 1, 1);
                            i--;
                        }
                    }
                }
                ;
                break;
            case 'moof':
                {
                    this.currentFragment = {
                        moofOffset: startPos,
                        moofSize: boxInfo.totalSize,
                        implicitBaseDataOffset: startPos,
                        trackData: new Map(),
                    };
                    this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
                    this.lastReadFragment = this.currentFragment;
                    this.currentFragment = null;
                }
                ;
                break;
            case 'traf':
                {
                    (0,misc/* assert */.vA)(this.currentFragment);
                    this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
                    // It is possible that there is no current track, for example when we don't care about the track
                    // referenced in the track fragment header.
                    if (this.currentTrack) {
                        const trackData = this.currentFragment.trackData.get(this.currentTrack.id);
                        if (trackData) {
                            const { currentFragmentState } = this.currentTrack;
                            (0,misc/* assert */.vA)(currentFragmentState);
                            if (currentFragmentState.startTimestamp !== null) {
                                offsetFragmentTrackDataByTimestamp(trackData, currentFragmentState.startTimestamp);
                                trackData.startTimestampIsFinal = true;
                            }
                        }
                        this.currentTrack.currentFragmentState = null;
                        this.currentTrack = null;
                    }
                }
                ;
                break;
            case 'tfhd':
                {
                    (0,misc/* assert */.vA)(this.currentFragment);
                    slice.skip(1); // Version
                    const flags = (0,src_reader/* readU24Be */.n2)(slice);
                    const baseDataOffsetPresent = Boolean(flags & 0x000001);
                    const sampleDescriptionIndexPresent = Boolean(flags & 0x000002);
                    const defaultSampleDurationPresent = Boolean(flags & 0x000008);
                    const defaultSampleSizePresent = Boolean(flags & 0x000010);
                    const defaultSampleFlagsPresent = Boolean(flags & 0x000020);
                    const durationIsEmpty = Boolean(flags & 0x010000);
                    const defaultBaseIsMoof = Boolean(flags & 0x020000);
                    const trackId = (0,src_reader/* readU32Be */.cN)(slice);
                    const track = this.tracks.find(x => x.id === trackId);
                    if (!track) {
                        // We don't care about this track
                        break;
                    }
                    const defaults = this.fragmentTrackDefaults.find(x => x.trackId === trackId);
                    this.currentTrack = track;
                    track.currentFragmentState = {
                        baseDataOffset: this.currentFragment.implicitBaseDataOffset,
                        sampleDescriptionIndex: defaults?.defaultSampleDescriptionIndex ?? null,
                        defaultSampleDuration: defaults?.defaultSampleDuration ?? null,
                        defaultSampleSize: defaults?.defaultSampleSize ?? null,
                        defaultSampleFlags: defaults?.defaultSampleFlags ?? null,
                        startTimestamp: null,
                    };
                    if (baseDataOffsetPresent) {
                        track.currentFragmentState.baseDataOffset = (0,src_reader/* readU64Be */.th)(slice);
                    }
                    else if (defaultBaseIsMoof) {
                        track.currentFragmentState.baseDataOffset = this.currentFragment.moofOffset;
                    }
                    if (sampleDescriptionIndexPresent) {
                        track.currentFragmentState.sampleDescriptionIndex = (0,src_reader/* readU32Be */.cN)(slice);
                    }
                    if (defaultSampleDurationPresent) {
                        track.currentFragmentState.defaultSampleDuration = (0,src_reader/* readU32Be */.cN)(slice);
                    }
                    if (defaultSampleSizePresent) {
                        track.currentFragmentState.defaultSampleSize = (0,src_reader/* readU32Be */.cN)(slice);
                    }
                    if (defaultSampleFlagsPresent) {
                        track.currentFragmentState.defaultSampleFlags = (0,src_reader/* readU32Be */.cN)(slice);
                    }
                    if (durationIsEmpty) {
                        track.currentFragmentState.defaultSampleDuration = 0;
                    }
                }
                ;
                break;
            case 'tfdt':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    (0,misc/* assert */.vA)(track.currentFragmentState);
                    const version = (0,src_reader/* readU8 */.eo)(slice);
                    slice.skip(3); // Flags
                    const baseMediaDecodeTime = version === 0 ? (0,src_reader/* readU32Be */.cN)(slice) : (0,src_reader/* readU64Be */.th)(slice);
                    track.currentFragmentState.startTimestamp = baseMediaDecodeTime;
                }
                ;
                break;
            case 'trun':
                {
                    const track = this.currentTrack;
                    if (!track) {
                        break;
                    }
                    (0,misc/* assert */.vA)(this.currentFragment);
                    (0,misc/* assert */.vA)(track.currentFragmentState);
                    if (this.currentFragment.trackData.has(track.id)) {
                        console.warn('Can\'t have two trun boxes for the same track in one fragment. Ignoring...');
                        break;
                    }
                    const version = (0,src_reader/* readU8 */.eo)(slice);
                    const flags = (0,src_reader/* readU24Be */.n2)(slice);
                    const dataOffsetPresent = Boolean(flags & 0x000001);
                    const firstSampleFlagsPresent = Boolean(flags & 0x000004);
                    const sampleDurationPresent = Boolean(flags & 0x000100);
                    const sampleSizePresent = Boolean(flags & 0x000200);
                    const sampleFlagsPresent = Boolean(flags & 0x000400);
                    const sampleCompositionTimeOffsetsPresent = Boolean(flags & 0x000800);
                    const sampleCount = (0,src_reader/* readU32Be */.cN)(slice);
                    let dataOffset = track.currentFragmentState.baseDataOffset;
                    if (dataOffsetPresent) {
                        dataOffset += (0,src_reader/* readI32Be */.Ar)(slice);
                    }
                    let firstSampleFlags = null;
                    if (firstSampleFlagsPresent) {
                        firstSampleFlags = (0,src_reader/* readU32Be */.cN)(slice);
                    }
                    let currentOffset = dataOffset;
                    if (sampleCount === 0) {
                        // Don't associate the fragment with the track if it has no samples, this simplifies other code
                        this.currentFragment.implicitBaseDataOffset = currentOffset;
                        break;
                    }
                    let currentTimestamp = 0;
                    const trackData = {
                        track,
                        startTimestamp: 0,
                        endTimestamp: 0,
                        firstKeyFrameTimestamp: null,
                        samples: [],
                        presentationTimestamps: [],
                        startTimestampIsFinal: false,
                    };
                    this.currentFragment.trackData.set(track.id, trackData);
                    for (let i = 0; i < sampleCount; i++) {
                        let sampleDuration;
                        if (sampleDurationPresent) {
                            sampleDuration = (0,src_reader/* readU32Be */.cN)(slice);
                        }
                        else {
                            (0,misc/* assert */.vA)(track.currentFragmentState.defaultSampleDuration !== null);
                            sampleDuration = track.currentFragmentState.defaultSampleDuration;
                        }
                        let sampleSize;
                        if (sampleSizePresent) {
                            sampleSize = (0,src_reader/* readU32Be */.cN)(slice);
                        }
                        else {
                            (0,misc/* assert */.vA)(track.currentFragmentState.defaultSampleSize !== null);
                            sampleSize = track.currentFragmentState.defaultSampleSize;
                        }
                        let sampleFlags;
                        if (sampleFlagsPresent) {
                            sampleFlags = (0,src_reader/* readU32Be */.cN)(slice);
                        }
                        else {
                            (0,misc/* assert */.vA)(track.currentFragmentState.defaultSampleFlags !== null);
                            sampleFlags = track.currentFragmentState.defaultSampleFlags;
                        }
                        if (i === 0 && firstSampleFlags !== null) {
                            sampleFlags = firstSampleFlags;
                        }
                        let sampleCompositionTimeOffset = 0;
                        if (sampleCompositionTimeOffsetsPresent) {
                            if (version === 0) {
                                sampleCompositionTimeOffset = (0,src_reader/* readU32Be */.cN)(slice);
                            }
                            else {
                                sampleCompositionTimeOffset = (0,src_reader/* readI32Be */.Ar)(slice);
                            }
                        }
                        const isKeyFrame = !(sampleFlags & 0x00010000);
                        trackData.samples.push({
                            presentationTimestamp: currentTimestamp + sampleCompositionTimeOffset,
                            duration: sampleDuration,
                            byteOffset: currentOffset,
                            byteSize: sampleSize,
                            isKeyFrame,
                        });
                        currentOffset += sampleSize;
                        currentTimestamp += sampleDuration;
                    }
                    trackData.presentationTimestamps = trackData.samples
                        .map((x, i) => ({ presentationTimestamp: x.presentationTimestamp, sampleIndex: i }))
                        .sort((a, b) => a.presentationTimestamp - b.presentationTimestamp);
                    for (let i = 0; i < trackData.presentationTimestamps.length; i++) {
                        const currentEntry = trackData.presentationTimestamps[i];
                        const currentSample = trackData.samples[currentEntry.sampleIndex];
                        if (trackData.firstKeyFrameTimestamp === null && currentSample.isKeyFrame) {
                            trackData.firstKeyFrameTimestamp = currentSample.presentationTimestamp;
                        }
                        if (i < trackData.presentationTimestamps.length - 1) {
                            // Update sample durations based on presentation order
                            const nextEntry = trackData.presentationTimestamps[i + 1];
                            currentSample.duration = nextEntry.presentationTimestamp - currentEntry.presentationTimestamp;
                        }
                    }
                    const firstSample = trackData.samples[trackData.presentationTimestamps[0].sampleIndex];
                    const lastSample = trackData.samples[(0,misc/* last */._g)(trackData.presentationTimestamps).sampleIndex];
                    trackData.startTimestamp = firstSample.presentationTimestamp;
                    trackData.endTimestamp = lastSample.presentationTimestamp + lastSample.duration;
                    this.currentFragment.implicitBaseDataOffset = currentOffset;
                }
                ;
                break;
            // Metadata section
            // https://exiftool.org/TagNames/QuickTime.html
            // https://mp4workshop.com/about
            case 'udta':
                { // Contains either movie metadata or track metadata
                    const iterator = this.iterateContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
                    for (const { boxInfo, slice } of iterator) {
                        if (boxInfo.name !== 'meta' && !this.currentTrack) {
                            const startPos = slice.filePos;
                            this.metadataTags.raw ??= {};
                            if (boxInfo.name[0] === '©') {
                                // https://mp4workshop.com/about
                                // Box name starting with © indicates "international text"
                                this.metadataTags.raw[boxInfo.name] ??= (0,isobmff_reader/* readMetadataStringShort */.$L)(slice);
                            }
                            else {
                                this.metadataTags.raw[boxInfo.name] ??= (0,src_reader/* readBytes */.io)(slice, boxInfo.contentSize);
                            }
                            slice.filePos = startPos;
                        }
                        switch (boxInfo.name) {
                            case 'meta':
                                {
                                    slice.skip(-boxInfo.headerSize);
                                    this.traverseBox(slice);
                                }
                                ;
                                break;
                            case '©nam':
                            case 'name':
                                {
                                    if (this.currentTrack) {
                                        this.currentTrack.name = misc/* textDecoder */.su.decode((0,src_reader/* readBytes */.io)(slice, boxInfo.contentSize));
                                    }
                                    else {
                                        this.metadataTags.title ??= (0,isobmff_reader/* readMetadataStringShort */.$L)(slice);
                                    }
                                }
                                ;
                                break;
                            case '©des':
                                {
                                    if (!this.currentTrack) {
                                        this.metadataTags.description ??= (0,isobmff_reader/* readMetadataStringShort */.$L)(slice);
                                    }
                                }
                                ;
                                break;
                            case '©ART':
                                {
                                    if (!this.currentTrack) {
                                        this.metadataTags.artist ??= (0,isobmff_reader/* readMetadataStringShort */.$L)(slice);
                                    }
                                }
                                ;
                                break;
                            case '©alb':
                                {
                                    if (!this.currentTrack) {
                                        this.metadataTags.album ??= (0,isobmff_reader/* readMetadataStringShort */.$L)(slice);
                                    }
                                }
                                ;
                                break;
                            case 'albr':
                                {
                                    if (!this.currentTrack) {
                                        this.metadataTags.albumArtist ??= (0,isobmff_reader/* readMetadataStringShort */.$L)(slice);
                                    }
                                }
                                ;
                                break;
                            case '©gen':
                                {
                                    if (!this.currentTrack) {
                                        this.metadataTags.genre ??= (0,isobmff_reader/* readMetadataStringShort */.$L)(slice);
                                    }
                                }
                                ;
                                break;
                            case '©day':
                                {
                                    if (!this.currentTrack) {
                                        const date = new Date((0,isobmff_reader/* readMetadataStringShort */.$L)(slice));
                                        if (!Number.isNaN(date.getTime())) {
                                            this.metadataTags.date ??= date;
                                        }
                                    }
                                }
                                ;
                                break;
                            case '©cmt':
                                {
                                    if (!this.currentTrack) {
                                        this.metadataTags.comment ??= (0,isobmff_reader/* readMetadataStringShort */.$L)(slice);
                                    }
                                }
                                ;
                                break;
                            case '©lyr':
                                {
                                    if (!this.currentTrack) {
                                        this.metadataTags.lyrics ??= (0,isobmff_reader/* readMetadataStringShort */.$L)(slice);
                                    }
                                }
                                ;
                                break;
                        }
                    }
                }
                ;
                break;
            case 'meta':
                {
                    if (this.currentTrack) {
                        break; // Only care about movie-level metadata for now
                    }
                    // The 'meta' box comes in two flavors, one with flags/version and one without. To know which is which,
                    // let's read the next 4 bytes, which are either the version or the size of the first subbox.
                    const word = (0,src_reader/* readU32Be */.cN)(slice);
                    const isQuickTime = word !== 0;
                    this.currentMetadataKeys = new Map();
                    if (isQuickTime) {
                        this.readContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
                    }
                    else {
                        this.readContiguousBoxes(slice.slice(contentStartPos + 4, boxInfo.contentSize - 4));
                    }
                    this.currentMetadataKeys = null;
                }
                ;
                break;
            case 'keys':
                {
                    if (!this.currentMetadataKeys) {
                        break;
                    }
                    slice.skip(4); // Version + flags
                    const entryCount = (0,src_reader/* readU32Be */.cN)(slice);
                    for (let i = 0; i < entryCount; i++) {
                        const keySize = (0,src_reader/* readU32Be */.cN)(slice);
                        slice.skip(4); // Key namespace
                        const keyName = misc/* textDecoder */.su.decode((0,src_reader/* readBytes */.io)(slice, keySize - 8));
                        this.currentMetadataKeys.set(i + 1, keyName);
                    }
                }
                ;
                break;
            case 'ilst':
                {
                    if (!this.currentMetadataKeys) {
                        break;
                    }
                    const iterator = this.iterateContiguousBoxes(slice.slice(contentStartPos, boxInfo.contentSize));
                    for (const { boxInfo, slice } of iterator) {
                        let metadataKey = boxInfo.name;
                        // Interpret the box name as a u32be
                        const nameAsNumber = (metadataKey.charCodeAt(0) << 24)
                            + (metadataKey.charCodeAt(1) << 16)
                            + (metadataKey.charCodeAt(2) << 8)
                            + metadataKey.charCodeAt(3);
                        if (this.currentMetadataKeys.has(nameAsNumber)) {
                            // An entry exists for this number
                            metadataKey = this.currentMetadataKeys.get(nameAsNumber);
                        }
                        const data = (0,isobmff_reader/* readDataBox */.Cp)(slice);
                        this.metadataTags.raw ??= {};
                        this.metadataTags.raw[metadataKey] ??= data;
                        switch (metadataKey) {
                            case '©nam':
                            case 'titl':
                            case 'com.apple.quicktime.title':
                            case 'title':
                                {
                                    if (typeof data === 'string') {
                                        this.metadataTags.title ??= data;
                                    }
                                }
                                ;
                                break;
                            case '©des':
                            case 'desc':
                            case 'dscp':
                            case 'com.apple.quicktime.description':
                            case 'description':
                                {
                                    if (typeof data === 'string') {
                                        this.metadataTags.description ??= data;
                                    }
                                }
                                ;
                                break;
                            case '©ART':
                            case 'com.apple.quicktime.artist':
                            case 'artist':
                                {
                                    if (typeof data === 'string') {
                                        this.metadataTags.artist ??= data;
                                    }
                                }
                                ;
                                break;
                            case '©alb':
                            case 'albm':
                            case 'com.apple.quicktime.album':
                            case 'album':
                                {
                                    if (typeof data === 'string') {
                                        this.metadataTags.album ??= data;
                                    }
                                }
                                ;
                                break;
                            case 'aART':
                            case 'album_artist':
                                {
                                    if (typeof data === 'string') {
                                        this.metadataTags.albumArtist ??= data;
                                    }
                                }
                                ;
                                break;
                            case '©cmt':
                            case 'com.apple.quicktime.comment':
                            case 'comment':
                                {
                                    if (typeof data === 'string') {
                                        this.metadataTags.comment ??= data;
                                    }
                                }
                                ;
                                break;
                            case '©gen':
                            case 'gnre':
                            case 'com.apple.quicktime.genre':
                            case 'genre':
                                {
                                    if (typeof data === 'string') {
                                        this.metadataTags.genre ??= data;
                                    }
                                }
                                ;
                                break;
                            case '©lyr':
                            case 'lyrics':
                                {
                                    if (typeof data === 'string') {
                                        this.metadataTags.lyrics ??= data;
                                    }
                                }
                                ;
                                break;
                            case '©day':
                            case 'rldt':
                            case 'com.apple.quicktime.creationdate':
                            case 'date':
                                {
                                    if (typeof data === 'string') {
                                        const date = new Date(data);
                                        if (!Number.isNaN(date.getTime())) {
                                            this.metadataTags.date ??= date;
                                        }
                                    }
                                }
                                ;
                                break;
                            case 'covr':
                            case 'com.apple.quicktime.artwork':
                                {
                                    if (data instanceof metadata/* RichImageData */.sF) {
                                        this.metadataTags.images ??= [];
                                        this.metadataTags.images.push({
                                            data: data.data,
                                            kind: 'coverFront',
                                            mimeType: data.mimeType,
                                        });
                                    }
                                    else if (data instanceof Uint8Array) {
                                        this.metadataTags.images ??= [];
                                        this.metadataTags.images.push({
                                            data,
                                            kind: 'coverFront',
                                            mimeType: 'image/*',
                                        });
                                    }
                                }
                                ;
                                break;
                            case 'track':
                                {
                                    if (typeof data === 'string') {
                                        const parts = data.split('/');
                                        const trackNum = Number.parseInt(parts[0], 10);
                                        const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);
                                        if (Number.isInteger(trackNum) && trackNum > 0) {
                                            this.metadataTags.trackNumber ??= trackNum;
                                        }
                                        if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {
                                            this.metadataTags.tracksTotal ??= tracksTotal;
                                        }
                                    }
                                }
                                ;
                                break;
                            case 'trkn':
                                {
                                    if (data instanceof Uint8Array && data.length >= 6) {
                                        const view = (0,misc/* toDataView */.Zc)(data);
                                        const trackNumber = view.getUint16(2, false);
                                        const tracksTotal = view.getUint16(4, false);
                                        if (trackNumber > 0) {
                                            this.metadataTags.trackNumber ??= trackNumber;
                                        }
                                        if (tracksTotal > 0) {
                                            this.metadataTags.tracksTotal ??= tracksTotal;
                                        }
                                    }
                                }
                                ;
                                break;
                            case 'disc':
                            case 'disk':
                                {
                                    if (data instanceof Uint8Array && data.length >= 6) {
                                        const view = (0,misc/* toDataView */.Zc)(data);
                                        const discNumber = view.getUint16(2, false);
                                        const discNumberMax = view.getUint16(4, false);
                                        if (discNumber > 0) {
                                            this.metadataTags.discNumber ??= discNumber;
                                        }
                                        if (discNumberMax > 0) {
                                            this.metadataTags.discsTotal ??= discNumberMax;
                                        }
                                    }
                                }
                                ;
                                break;
                        }
                    }
                }
                ;
                break;
        }
        slice.filePos = boxEndPos;
        return true;
    }
}
class IsobmffTrackBacking {
    constructor(internalTrack) {
        this.internalTrack = internalTrack;
        this.packetToSampleIndex = new WeakMap();
        this.packetToFragmentLocation = new WeakMap();
    }
    getId() {
        return this.internalTrack.id;
    }
    getNumber() {
        const demuxer = this.internalTrack.demuxer;
        const inputTrack = this.internalTrack.inputTrack;
        const trackType = inputTrack.type;
        let number = 0;
        for (const track of demuxer.tracks) {
            if (track.inputTrack.type === trackType) {
                number++;
            }
            if (track === this.internalTrack) {
                break;
            }
        }
        return number;
    }
    getCodec() {
        throw new Error('Not implemented on base class.');
    }
    getInternalCodecId() {
        return this.internalTrack.internalCodecId;
    }
    getName() {
        return this.internalTrack.name;
    }
    getLanguageCode() {
        return this.internalTrack.languageCode;
    }
    getTimeResolution() {
        return this.internalTrack.timescale;
    }
    getDisposition() {
        return this.internalTrack.disposition;
    }
    async computeDuration() {
        const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
        return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    async getFirstTimestamp() {
        const firstPacket = await this.getFirstPacket({ metadataOnly: true });
        return firstPacket?.timestamp ?? 0;
    }
    async getFirstPacket(options) {
        const regularPacket = await this.fetchPacketForSampleIndex(0, options);
        if (regularPacket || !this.internalTrack.demuxer.isFragmented) {
            // If there's a non-fragmented packet, always prefer that
            return regularPacket;
        }
        return this.performFragmentedLookup(null, (fragment) => {
            const trackData = fragment.trackData.get(this.internalTrack.id);
            if (trackData) {
                return {
                    sampleIndex: 0,
                    correctSampleFound: true,
                };
            }
            return {
                sampleIndex: -1,
                correctSampleFound: false,
            };
        }, -Infinity, // Use -Infinity as a search timestamp to avoid using the lookup entries
        Infinity, options);
    }
    mapTimestampIntoTimescale(timestamp) {
        // Do a little rounding to catch cases where the result is very close to an integer. If it is, it's likely
        // that the number was originally an integer divided by the timescale. For stability, it's best
        // to return the integer in this case.
        return (0,misc/* roundIfAlmostInteger */.aI)(timestamp * this.internalTrack.timescale) + this.internalTrack.editListOffset;
    }
    async getPacket(timestamp, options) {
        const timestampInTimescale = this.mapTimestampIntoTimescale(timestamp);
        const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);
        const sampleIndex = getSampleIndexForTimestamp(sampleTable, timestampInTimescale);
        const regularPacket = await this.fetchPacketForSampleIndex(sampleIndex, options);
        if (!sampleTableIsEmpty(sampleTable) || !this.internalTrack.demuxer.isFragmented) {
            // Prefer the non-fragmented packet
            return regularPacket;
        }
        return this.performFragmentedLookup(null, (fragment) => {
            const trackData = fragment.trackData.get(this.internalTrack.id);
            if (!trackData) {
                return { sampleIndex: -1, correctSampleFound: false };
            }
            const index = (0,misc/* binarySearchLessOrEqual */.eE)(trackData.presentationTimestamps, timestampInTimescale, x => x.presentationTimestamp);
            const sampleIndex = index !== -1 ? trackData.presentationTimestamps[index].sampleIndex : -1;
            const correctSampleFound = index !== -1 && timestampInTimescale < trackData.endTimestamp;
            return { sampleIndex, correctSampleFound };
        }, timestampInTimescale, timestampInTimescale, options);
    }
    async getNextPacket(packet, options) {
        const regularSampleIndex = this.packetToSampleIndex.get(packet);
        if (regularSampleIndex !== undefined) {
            // Prefer the non-fragmented packet
            return this.fetchPacketForSampleIndex(regularSampleIndex + 1, options);
        }
        const locationInFragment = this.packetToFragmentLocation.get(packet);
        if (locationInFragment === undefined) {
            throw new Error('Packet was not created from this track.');
        }
        return this.performFragmentedLookup(locationInFragment.fragment, (fragment) => {
            if (fragment === locationInFragment.fragment) {
                const trackData = fragment.trackData.get(this.internalTrack.id);
                if (locationInFragment.sampleIndex + 1 < trackData.samples.length) {
                    // We can simply take the next sample in the fragment
                    return {
                        sampleIndex: locationInFragment.sampleIndex + 1,
                        correctSampleFound: true,
                    };
                }
            }
            else {
                const trackData = fragment.trackData.get(this.internalTrack.id);
                if (trackData) {
                    return {
                        sampleIndex: 0,
                        correctSampleFound: true,
                    };
                }
            }
            return {
                sampleIndex: -1,
                correctSampleFound: false,
            };
        }, -Infinity, // Use -Infinity as a search timestamp to avoid using the lookup entries
        Infinity, options);
    }
    async getKeyPacket(timestamp, options) {
        const timestampInTimescale = this.mapTimestampIntoTimescale(timestamp);
        const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);
        const sampleIndex = getKeyframeSampleIndexForTimestamp(sampleTable, timestampInTimescale);
        const regularPacket = await this.fetchPacketForSampleIndex(sampleIndex, options);
        if (!sampleTableIsEmpty(sampleTable) || !this.internalTrack.demuxer.isFragmented) {
            // Prefer the non-fragmented packet
            return regularPacket;
        }
        return this.performFragmentedLookup(null, (fragment) => {
            const trackData = fragment.trackData.get(this.internalTrack.id);
            if (!trackData) {
                return { sampleIndex: -1, correctSampleFound: false };
            }
            const index = (0,misc/* findLastIndex */.Kl)(trackData.presentationTimestamps, (x) => {
                const sample = trackData.samples[x.sampleIndex];
                return sample.isKeyFrame && x.presentationTimestamp <= timestampInTimescale;
            });
            const sampleIndex = index !== -1 ? trackData.presentationTimestamps[index].sampleIndex : -1;
            const correctSampleFound = index !== -1 && timestampInTimescale < trackData.endTimestamp;
            return { sampleIndex, correctSampleFound };
        }, timestampInTimescale, timestampInTimescale, options);
    }
    async getNextKeyPacket(packet, options) {
        const regularSampleIndex = this.packetToSampleIndex.get(packet);
        if (regularSampleIndex !== undefined) {
            // Prefer the non-fragmented packet
            const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);
            const nextKeyFrameSampleIndex = getNextKeyframeIndexForSample(sampleTable, regularSampleIndex);
            return this.fetchPacketForSampleIndex(nextKeyFrameSampleIndex, options);
        }
        const locationInFragment = this.packetToFragmentLocation.get(packet);
        if (locationInFragment === undefined) {
            throw new Error('Packet was not created from this track.');
        }
        return this.performFragmentedLookup(locationInFragment.fragment, (fragment) => {
            if (fragment === locationInFragment.fragment) {
                const trackData = fragment.trackData.get(this.internalTrack.id);
                const nextKeyFrameIndex = trackData.samples.findIndex((x, i) => x.isKeyFrame && i > locationInFragment.sampleIndex);
                if (nextKeyFrameIndex !== -1) {
                    // We can simply take the next key frame in the fragment
                    return {
                        sampleIndex: nextKeyFrameIndex,
                        correctSampleFound: true,
                    };
                }
            }
            else {
                const trackData = fragment.trackData.get(this.internalTrack.id);
                if (trackData && trackData.firstKeyFrameTimestamp !== null) {
                    const keyFrameIndex = trackData.samples.findIndex(x => x.isKeyFrame);
                    (0,misc/* assert */.vA)(keyFrameIndex !== -1); // There must be one
                    return {
                        sampleIndex: keyFrameIndex,
                        correctSampleFound: true,
                    };
                }
            }
            return {
                sampleIndex: -1,
                correctSampleFound: false,
            };
        }, -Infinity, // Use -Infinity as a search timestamp to avoid using the lookup entries
        Infinity, options);
    }
    async fetchPacketForSampleIndex(sampleIndex, options) {
        if (sampleIndex === -1) {
            return null;
        }
        const sampleTable = this.internalTrack.demuxer.getSampleTableForTrack(this.internalTrack);
        const sampleInfo = getSampleInfo(sampleTable, sampleIndex);
        if (!sampleInfo) {
            return null;
        }
        let data;
        if (options.metadataOnly) {
            data = src_packet/* PLACEHOLDER_DATA */.T;
        }
        else {
            let slice = this.internalTrack.demuxer.reader.requestSlice(sampleInfo.sampleOffset, sampleInfo.sampleSize);
            if (slice instanceof Promise)
                slice = await slice;
            (0,misc/* assert */.vA)(slice);
            data = (0,src_reader/* readBytes */.io)(slice, sampleInfo.sampleSize);
        }
        const timestamp = (sampleInfo.presentationTimestamp - this.internalTrack.editListOffset)
            / this.internalTrack.timescale;
        const duration = sampleInfo.duration / this.internalTrack.timescale;
        const packet = new src_packet/* EncodedPacket */.Z(data, sampleInfo.isKeyFrame ? 'key' : 'delta', timestamp, duration, sampleIndex, sampleInfo.sampleSize);
        this.packetToSampleIndex.set(packet, sampleIndex);
        return packet;
    }
    async fetchPacketInFragment(fragment, sampleIndex, options) {
        if (sampleIndex === -1) {
            return null;
        }
        const trackData = fragment.trackData.get(this.internalTrack.id);
        const fragmentSample = trackData.samples[sampleIndex];
        (0,misc/* assert */.vA)(fragmentSample);
        let data;
        if (options.metadataOnly) {
            data = src_packet/* PLACEHOLDER_DATA */.T;
        }
        else {
            let slice = this.internalTrack.demuxer.reader.requestSlice(fragmentSample.byteOffset, fragmentSample.byteSize);
            if (slice instanceof Promise)
                slice = await slice;
            (0,misc/* assert */.vA)(slice);
            data = (0,src_reader/* readBytes */.io)(slice, fragmentSample.byteSize);
        }
        const timestamp = (fragmentSample.presentationTimestamp - this.internalTrack.editListOffset)
            / this.internalTrack.timescale;
        const duration = fragmentSample.duration / this.internalTrack.timescale;
        const packet = new src_packet/* EncodedPacket */.Z(data, fragmentSample.isKeyFrame ? 'key' : 'delta', timestamp, duration, fragment.moofOffset + sampleIndex, fragmentSample.byteSize);
        this.packetToFragmentLocation.set(packet, { fragment, sampleIndex });
        return packet;
    }
    /** Looks for a packet in the fragments while trying to load as few fragments as possible to retrieve it. */
    async performFragmentedLookup(
    // The fragment where we start looking
    startFragment, 
    // This function returns the best-matching sample in a given fragment
    getMatchInFragment, 
    // The timestamp with which we can search the lookup table
    searchTimestamp, 
    // The timestamp for which we know the correct sample will not come after it
    latestTimestamp, options) {
        const demuxer = this.internalTrack.demuxer;
        let currentFragment = null;
        let bestFragment = null;
        let bestSampleIndex = -1;
        if (startFragment) {
            const { sampleIndex, correctSampleFound } = getMatchInFragment(startFragment);
            if (correctSampleFound) {
                return this.fetchPacketInFragment(startFragment, sampleIndex, options);
            }
            if (sampleIndex !== -1) {
                bestFragment = startFragment;
                bestSampleIndex = sampleIndex;
            }
        }
        // Search for a lookup entry; this way, we won't need to start searching from the start of the file
        // but can jump right into the correct fragment (or at least nearby).
        const lookupEntryIndex = (0,misc/* binarySearchLessOrEqual */.eE)(this.internalTrack.fragmentLookupTable, searchTimestamp, x => x.timestamp);
        const lookupEntry = lookupEntryIndex !== -1
            ? this.internalTrack.fragmentLookupTable[lookupEntryIndex]
            : null;
        const positionCacheIndex = (0,misc/* binarySearchLessOrEqual */.eE)(this.internalTrack.fragmentPositionCache, searchTimestamp, x => x.startTimestamp);
        const positionCacheEntry = positionCacheIndex !== -1
            ? this.internalTrack.fragmentPositionCache[positionCacheIndex]
            : null;
        const lookupEntryPosition = Math.max(lookupEntry?.moofOffset ?? 0, positionCacheEntry?.moofOffset ?? 0) || null;
        let currentPos;
        if (!startFragment) {
            currentPos = lookupEntryPosition ?? 0;
        }
        else {
            if (lookupEntryPosition === null || startFragment.moofOffset >= lookupEntryPosition) {
                currentPos = startFragment.moofOffset + startFragment.moofSize;
                currentFragment = startFragment;
            }
            else {
                // Use the lookup entry
                currentPos = lookupEntryPosition;
            }
        }
        while (true) {
            if (currentFragment) {
                const trackData = currentFragment.trackData.get(this.internalTrack.id);
                if (trackData && trackData.startTimestamp > latestTimestamp) {
                    // We're already past the upper bound, no need to keep searching
                    break;
                }
            }
            // Load the header
            let slice = demuxer.reader.requestSliceRange(currentPos, isobmff_reader/* MIN_BOX_HEADER_SIZE */.ZM, isobmff_reader/* MAX_BOX_HEADER_SIZE */.Xk);
            if (slice instanceof Promise)
                slice = await slice;
            if (!slice)
                break;
            const boxStartPos = currentPos;
            const boxInfo = (0,isobmff_reader/* readBoxHeader */.Vl)(slice);
            if (!boxInfo) {
                break;
            }
            if (boxInfo.name === 'moof') {
                currentFragment = await demuxer.readFragment(boxStartPos);
                const { sampleIndex, correctSampleFound } = getMatchInFragment(currentFragment);
                if (correctSampleFound) {
                    return this.fetchPacketInFragment(currentFragment, sampleIndex, options);
                }
                if (sampleIndex !== -1) {
                    bestFragment = currentFragment;
                    bestSampleIndex = sampleIndex;
                }
            }
            currentPos = boxStartPos + boxInfo.totalSize;
        }
        // Catch faulty lookup table entries
        if (lookupEntry && (!bestFragment || bestFragment.moofOffset < lookupEntry.moofOffset)) {
            // The lookup table entry lied to us! We found a lookup entry but no fragment there that satisfied
            // the match. In this case, let's search again but using the lookup entry before that.
            const previousLookupEntry = this.internalTrack.fragmentLookupTable[lookupEntryIndex - 1];
            (0,misc/* assert */.vA)(!previousLookupEntry || previousLookupEntry.timestamp < lookupEntry.timestamp);
            const newSearchTimestamp = previousLookupEntry?.timestamp ?? -Infinity;
            return this.performFragmentedLookup(null, getMatchInFragment, newSearchTimestamp, latestTimestamp, options);
        }
        if (bestFragment) {
            // If we finished looping but didn't find a perfect match, still return the best match we found
            return this.fetchPacketInFragment(bestFragment, bestSampleIndex, options);
        }
        return null;
    }
}
class IsobmffVideoTrackBacking extends IsobmffTrackBacking {
    constructor(internalTrack) {
        super(internalTrack);
        this.decoderConfigPromise = null;
        this.internalTrack = internalTrack;
    }
    getCodec() {
        return this.internalTrack.info.codec;
    }
    getCodedWidth() {
        return this.internalTrack.info.width;
    }
    getCodedHeight() {
        return this.internalTrack.info.height;
    }
    getRotation() {
        return this.internalTrack.rotation;
    }
    async getColorSpace() {
        return {
            primaries: this.internalTrack.info.colorSpace?.primaries,
            transfer: this.internalTrack.info.colorSpace?.transfer,
            matrix: this.internalTrack.info.colorSpace?.matrix,
            fullRange: this.internalTrack.info.colorSpace?.fullRange,
        };
    }
    async canBeTransparent() {
        return false;
    }
    async getDecoderConfig() {
        if (!this.internalTrack.info.codec) {
            return null;
        }
        return this.decoderConfigPromise ??= (async () => {
            if (this.internalTrack.info.codec === 'vp9' && !this.internalTrack.info.vp9CodecInfo) {
                const firstPacket = await this.getFirstPacket({});
                this.internalTrack.info.vp9CodecInfo = firstPacket && (0,codec_data/* extractVp9CodecInfoFromPacket */.bs)(firstPacket.data);
            }
            else if (this.internalTrack.info.codec === 'av1' && !this.internalTrack.info.av1CodecInfo) {
                const firstPacket = await this.getFirstPacket({});
                this.internalTrack.info.av1CodecInfo = firstPacket && (0,codec_data/* extractAv1CodecInfoFromPacket */.UU)(firstPacket.data);
            }
            return {
                codec: (0,codec/* extractVideoCodecString */.QP)(this.internalTrack.info),
                codedWidth: this.internalTrack.info.width,
                codedHeight: this.internalTrack.info.height,
                description: this.internalTrack.info.codecDescription ?? undefined,
                colorSpace: this.internalTrack.info.colorSpace ?? undefined,
            };
        })();
    }
}
class IsobmffAudioTrackBacking extends IsobmffTrackBacking {
    constructor(internalTrack) {
        super(internalTrack);
        this.decoderConfig = null;
        this.internalTrack = internalTrack;
    }
    getCodec() {
        return this.internalTrack.info.codec;
    }
    getNumberOfChannels() {
        return this.internalTrack.info.numberOfChannels;
    }
    getSampleRate() {
        return this.internalTrack.info.sampleRate;
    }
    async getDecoderConfig() {
        if (!this.internalTrack.info.codec) {
            return null;
        }
        return this.decoderConfig ??= {
            codec: (0,codec/* extractAudioCodecString */.X0)(this.internalTrack.info),
            numberOfChannels: this.internalTrack.info.numberOfChannels,
            sampleRate: this.internalTrack.info.sampleRate,
            description: this.internalTrack.info.codecDescription ?? undefined,
        };
    }
}
const getSampleIndexForTimestamp = (sampleTable, timescaleUnits) => {
    if (sampleTable.presentationTimestamps) {
        const index = (0,misc/* binarySearchLessOrEqual */.eE)(sampleTable.presentationTimestamps, timescaleUnits, x => x.presentationTimestamp);
        if (index === -1) {
            return -1;
        }
        return sampleTable.presentationTimestamps[index].sampleIndex;
    }
    else {
        const index = (0,misc/* binarySearchLessOrEqual */.eE)(sampleTable.sampleTimingEntries, timescaleUnits, x => x.startDecodeTimestamp);
        if (index === -1) {
            return -1;
        }
        const entry = sampleTable.sampleTimingEntries[index];
        return entry.startIndex
            + Math.min(Math.floor((timescaleUnits - entry.startDecodeTimestamp) / entry.delta), entry.count - 1);
    }
};
const getKeyframeSampleIndexForTimestamp = (sampleTable, timescaleUnits) => {
    if (!sampleTable.keySampleIndices) {
        // Every sample is a keyframe
        return getSampleIndexForTimestamp(sampleTable, timescaleUnits);
    }
    if (sampleTable.presentationTimestamps) {
        const index = (0,misc/* binarySearchLessOrEqual */.eE)(sampleTable.presentationTimestamps, timescaleUnits, x => x.presentationTimestamp);
        if (index === -1) {
            return -1;
        }
        // Walk the samples in presentation order until we find one that's a keyframe
        for (let i = index; i >= 0; i--) {
            const sampleIndex = sampleTable.presentationTimestamps[i].sampleIndex;
            const isKeyFrame = (0,misc/* binarySearchExact */.pl)(sampleTable.keySampleIndices, sampleIndex, x => x) !== -1;
            if (isKeyFrame) {
                return sampleIndex;
            }
        }
        return -1;
    }
    else {
        const sampleIndex = getSampleIndexForTimestamp(sampleTable, timescaleUnits);
        const index = (0,misc/* binarySearchLessOrEqual */.eE)(sampleTable.keySampleIndices, sampleIndex, x => x);
        return sampleTable.keySampleIndices[index] ?? -1;
    }
};
const getSampleInfo = (sampleTable, sampleIndex) => {
    const timingEntryIndex = (0,misc/* binarySearchLessOrEqual */.eE)(sampleTable.sampleTimingEntries, sampleIndex, x => x.startIndex);
    const timingEntry = sampleTable.sampleTimingEntries[timingEntryIndex];
    if (!timingEntry || timingEntry.startIndex + timingEntry.count <= sampleIndex) {
        return null;
    }
    const decodeTimestamp = timingEntry.startDecodeTimestamp
        + (sampleIndex - timingEntry.startIndex) * timingEntry.delta;
    let presentationTimestamp = decodeTimestamp;
    const offsetEntryIndex = (0,misc/* binarySearchLessOrEqual */.eE)(sampleTable.sampleCompositionTimeOffsets, sampleIndex, x => x.startIndex);
    const offsetEntry = sampleTable.sampleCompositionTimeOffsets[offsetEntryIndex];
    if (offsetEntry && sampleIndex - offsetEntry.startIndex < offsetEntry.count) {
        presentationTimestamp += offsetEntry.offset;
    }
    const sampleSize = sampleTable.sampleSizes[Math.min(sampleIndex, sampleTable.sampleSizes.length - 1)];
    const chunkEntryIndex = (0,misc/* binarySearchLessOrEqual */.eE)(sampleTable.sampleToChunk, sampleIndex, x => x.startSampleIndex);
    const chunkEntry = sampleTable.sampleToChunk[chunkEntryIndex];
    (0,misc/* assert */.vA)(chunkEntry);
    const chunkIndex = chunkEntry.startChunkIndex
        + Math.floor((sampleIndex - chunkEntry.startSampleIndex) / chunkEntry.samplesPerChunk);
    const chunkOffset = sampleTable.chunkOffsets[chunkIndex];
    const startSampleIndexOfChunk = chunkEntry.startSampleIndex
        + (chunkIndex - chunkEntry.startChunkIndex) * chunkEntry.samplesPerChunk;
    let chunkSize = 0;
    let sampleOffset = chunkOffset;
    if (sampleTable.sampleSizes.length === 1) {
        sampleOffset += sampleSize * (sampleIndex - startSampleIndexOfChunk);
        chunkSize += sampleSize * chunkEntry.samplesPerChunk;
    }
    else {
        for (let i = startSampleIndexOfChunk; i < startSampleIndexOfChunk + chunkEntry.samplesPerChunk; i++) {
            const sampleSize = sampleTable.sampleSizes[i];
            if (i < sampleIndex) {
                sampleOffset += sampleSize;
            }
            chunkSize += sampleSize;
        }
    }
    let duration = timingEntry.delta;
    if (sampleTable.presentationTimestamps) {
        // In order to accurately compute the duration, we need to take the duration to the next sample in presentation
        // order, not in decode order
        const presentationIndex = sampleTable.presentationTimestampIndexMap[sampleIndex];
        (0,misc/* assert */.vA)(presentationIndex !== undefined);
        if (presentationIndex < sampleTable.presentationTimestamps.length - 1) {
            const nextEntry = sampleTable.presentationTimestamps[presentationIndex + 1];
            const nextPresentationTimestamp = nextEntry.presentationTimestamp;
            duration = nextPresentationTimestamp - presentationTimestamp;
        }
    }
    return {
        presentationTimestamp,
        duration,
        sampleOffset,
        sampleSize,
        chunkOffset,
        chunkSize,
        isKeyFrame: sampleTable.keySampleIndices
            ? (0,misc/* binarySearchExact */.pl)(sampleTable.keySampleIndices, sampleIndex, x => x) !== -1
            : true,
    };
};
const getNextKeyframeIndexForSample = (sampleTable, sampleIndex) => {
    if (!sampleTable.keySampleIndices) {
        return sampleIndex + 1;
    }
    const index = (0,misc/* binarySearchLessOrEqual */.eE)(sampleTable.keySampleIndices, sampleIndex, x => x);
    return sampleTable.keySampleIndices[index + 1] ?? -1;
};
const offsetFragmentTrackDataByTimestamp = (trackData, timestamp) => {
    trackData.startTimestamp += timestamp;
    trackData.endTimestamp += timestamp;
    for (const sample of trackData.samples) {
        sample.presentationTimestamp += timestamp;
    }
    for (const entry of trackData.presentationTimestamps) {
        entry.presentationTimestamp += timestamp;
    }
};
/** Extracts the rotation component from a transformation matrix, in degrees. */
const extractRotationFromMatrix = (matrix) => {
    const [m11, , , m21] = matrix;
    const scaleX = Math.hypot(m11, m21);
    const cosTheta = m11 / scaleX;
    const sinTheta = m21 / scaleX;
    // Invert the rotation because matrices are post-multiplied in ISOBMFF
    const result = -Math.atan2(sinTheta, cosTheta) * (180 / Math.PI);
    if (!Number.isFinite(result)) {
        // Can happen if the entire matrix is 0, for example
        return 0;
    }
    return result;
};
const sampleTableIsEmpty = (sampleTable) => {
    return sampleTable.sampleSizes.length === 0;
};

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/matroska/ebml.js
var ebml = __webpack_require__(6411);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/matroska/matroska-misc.js
var matroska_misc = __webpack_require__(3616);
;// ./node_modules/mediabunny/dist/modules/src/matroska/matroska-demuxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */










var BlockLacing;
(function (BlockLacing) {
    BlockLacing[BlockLacing["None"] = 0] = "None";
    BlockLacing[BlockLacing["Xiph"] = 1] = "Xiph";
    BlockLacing[BlockLacing["FixedSize"] = 2] = "FixedSize";
    BlockLacing[BlockLacing["Ebml"] = 3] = "Ebml";
})(BlockLacing || (BlockLacing = {}));
var ContentEncodingScope;
(function (ContentEncodingScope) {
    ContentEncodingScope[ContentEncodingScope["Block"] = 1] = "Block";
    ContentEncodingScope[ContentEncodingScope["Private"] = 2] = "Private";
    ContentEncodingScope[ContentEncodingScope["Next"] = 4] = "Next";
})(ContentEncodingScope || (ContentEncodingScope = {}));
var ContentCompAlgo;
(function (ContentCompAlgo) {
    ContentCompAlgo[ContentCompAlgo["Zlib"] = 0] = "Zlib";
    ContentCompAlgo[ContentCompAlgo["Bzlib"] = 1] = "Bzlib";
    ContentCompAlgo[ContentCompAlgo["lzo1x"] = 2] = "lzo1x";
    ContentCompAlgo[ContentCompAlgo["HeaderStripping"] = 3] = "HeaderStripping";
})(ContentCompAlgo || (ContentCompAlgo = {}));
const METADATA_ELEMENTS = [
    { id: ebml/* EBMLId */.Cl.SeekHead, flag: 'seekHeadSeen' },
    { id: ebml/* EBMLId */.Cl.Info, flag: 'infoSeen' },
    { id: ebml/* EBMLId */.Cl.Tracks, flag: 'tracksSeen' },
    { id: ebml/* EBMLId */.Cl.Cues, flag: 'cuesSeen' },
];
const MAX_RESYNC_LENGTH = 10 * 2 ** 20; // 10 MiB
class MatroskaDemuxer extends demuxer/* Demuxer */.B {
    constructor(input) {
        super(input);
        this.readMetadataPromise = null;
        this.segments = [];
        this.currentSegment = null;
        this.currentTrack = null;
        this.currentCluster = null;
        this.currentBlock = null;
        this.currentBlockAdditional = null;
        this.currentCueTime = null;
        this.currentDecodingInstruction = null;
        this.currentTagTargetIsMovie = true;
        this.currentSimpleTagName = null;
        this.currentAttachedFile = null;
        this.isWebM = false;
        this.reader = input._reader;
    }
    async computeDuration() {
        const tracks = await this.getTracks();
        const trackDurations = await Promise.all(tracks.map(x => x.computeDuration()));
        return Math.max(0, ...trackDurations);
    }
    async getTracks() {
        await this.readMetadata();
        return this.segments.flatMap(segment => segment.tracks.map(track => track.inputTrack));
    }
    async getMimeType() {
        await this.readMetadata();
        const tracks = await this.getTracks();
        const codecStrings = await Promise.all(tracks.map(x => x.getCodecParameterString()));
        return (0,matroska_misc/* buildMatroskaMimeType */.V)({
            isWebM: this.isWebM,
            hasVideo: this.segments.some(segment => segment.tracks.some(x => x.info?.type === 'video')),
            hasAudio: this.segments.some(segment => segment.tracks.some(x => x.info?.type === 'audio')),
            codecStrings: codecStrings.filter(Boolean),
        });
    }
    async getMetadataTags() {
        await this.readMetadata();
        // Load metadata tags from each segment lazily (only once)
        for (const segment of this.segments) {
            if (!segment.metadataTagsCollected) {
                if (this.reader.fileSize !== null) {
                    await this.loadSegmentMetadata(segment);
                }
                else {
                    // The seeking would be too crazy, let's not
                }
                segment.metadataTagsCollected = true;
            }
        }
        // This is kinda handwavy, and how we handle multiple segments isn't suuuuper well-defined anyway; so we just
        // shallow-merge metadata tags from all (usually just one) segments.
        let metadataTags = {};
        for (const segment of this.segments) {
            metadataTags = { ...metadataTags, ...segment.metadataTags };
        }
        return metadataTags;
    }
    readMetadata() {
        return this.readMetadataPromise ??= (async () => {
            let currentPos = 0;
            // Loop over all top-level elements in the file
            while (true) {
                let slice = this.reader.requestSliceRange(currentPos, ebml/* MIN_HEADER_SIZE */.De, ebml/* MAX_HEADER_SIZE */.r1);
                if (slice instanceof Promise)
                    slice = await slice;
                if (!slice)
                    break;
                const header = (0,ebml/* readElementHeader */.ur)(slice);
                if (!header) {
                    break; // Zero padding at the end of the file triggers this, for example
                }
                const id = header.id;
                let size = header.size;
                const dataStartPos = slice.filePos;
                if (id === ebml/* EBMLId */.Cl.EBML) {
                    (0,ebml/* assertDefinedSize */.p)(size);
                    let slice = this.reader.requestSlice(dataStartPos, size);
                    if (slice instanceof Promise)
                        slice = await slice;
                    if (!slice)
                        break;
                    this.readContiguousElements(slice);
                }
                else if (id === ebml/* EBMLId */.Cl.Segment) { // Segment found!
                    await this.readSegment(dataStartPos, size);
                    if (size === undefined) {
                        // Segment sizes can be undefined (common in livestreamed files), so assume this is the last
                        // and only segment
                        break;
                    }
                    if (this.reader.fileSize === null) {
                        break; // Stop at the first segment
                    }
                }
                else if (id === ebml/* EBMLId */.Cl.Cluster) {
                    if (this.reader.fileSize === null) {
                        break; // Shouldn't be reached anyway, since we stop at the first segment
                    }
                    // Clusters are not a top-level element in Matroska, but some files contain a Segment whose size
                    // doesn't contain any of the clusters that follow it. In the case, we apply the following logic: if
                    // we find a top-level cluster, attribute it to the previous segment.
                    if (size === undefined) {
                        // Just in case this is one of those weird sizeless clusters, let's do our best and still try to
                        // determine its size.
                        const nextElementPos = await (0,ebml/* searchForNextElementId */.IQ)(this.reader, dataStartPos, ebml/* LEVEL_0_AND_1_EBML_IDS */.K9, this.reader.fileSize);
                        size = nextElementPos.pos - dataStartPos;
                    }
                    const lastSegment = (0,misc/* last */._g)(this.segments);
                    if (lastSegment) {
                        // Extend the previous segment's size
                        lastSegment.elementEndPos = dataStartPos + size;
                    }
                }
                (0,ebml/* assertDefinedSize */.p)(size);
                currentPos = dataStartPos + size;
            }
        })();
    }
    async readSegment(segmentDataStart, dataSize) {
        this.currentSegment = {
            seekHeadSeen: false,
            infoSeen: false,
            tracksSeen: false,
            cuesSeen: false,
            tagsSeen: false,
            attachmentsSeen: false,
            timestampScale: -1,
            timestampFactor: -1,
            duration: -1,
            seekEntries: [],
            tracks: [],
            cuePoints: [],
            dataStartPos: segmentDataStart,
            elementEndPos: dataSize === undefined
                ? null // Assume it goes until the end of the file
                : segmentDataStart + dataSize,
            clusterSeekStartPos: segmentDataStart,
            lastReadCluster: null,
            metadataTags: {},
            metadataTagsCollected: false,
        };
        this.segments.push(this.currentSegment);
        let currentPos = segmentDataStart;
        while (this.currentSegment.elementEndPos === null || currentPos < this.currentSegment.elementEndPos) {
            let slice = this.reader.requestSliceRange(currentPos, ebml/* MIN_HEADER_SIZE */.De, ebml/* MAX_HEADER_SIZE */.r1);
            if (slice instanceof Promise)
                slice = await slice;
            if (!slice)
                break;
            const elementStartPos = currentPos;
            const header = (0,ebml/* readElementHeader */.ur)(slice);
            if (!header || (!ebml/* LEVEL_1_EBML_IDS */.VE.includes(header.id) && header.id !== ebml/* EBMLId */.Cl.Void)) {
                // Potential junk. Let's try to resync
                const nextPos = await (0,ebml/* resync */.nE)(this.reader, elementStartPos, ebml/* LEVEL_1_EBML_IDS */.VE, Math.min(this.currentSegment.elementEndPos ?? Infinity, elementStartPos + MAX_RESYNC_LENGTH));
                if (nextPos) {
                    currentPos = nextPos;
                    continue;
                }
                else {
                    break; // Resync failed
                }
            }
            const { id, size } = header;
            const dataStartPos = slice.filePos;
            const metadataElementIndex = METADATA_ELEMENTS.findIndex(x => x.id === id);
            if (metadataElementIndex !== -1) {
                const field = METADATA_ELEMENTS[metadataElementIndex].flag;
                this.currentSegment[field] = true;
                (0,ebml/* assertDefinedSize */.p)(size);
                let slice = this.reader.requestSlice(dataStartPos, size);
                if (slice instanceof Promise)
                    slice = await slice;
                if (slice) {
                    this.readContiguousElements(slice);
                }
            }
            else if (id === ebml/* EBMLId */.Cl.Tags || id === ebml/* EBMLId */.Cl.Attachments) {
                // Metadata found at the beginning of the segment, great, let's parse it
                if (id === ebml/* EBMLId */.Cl.Tags) {
                    this.currentSegment.tagsSeen = true;
                }
                else {
                    this.currentSegment.attachmentsSeen = true;
                }
                (0,ebml/* assertDefinedSize */.p)(size);
                let slice = this.reader.requestSlice(dataStartPos, size);
                if (slice instanceof Promise)
                    slice = await slice;
                if (slice) {
                    this.readContiguousElements(slice);
                }
            }
            else if (id === ebml/* EBMLId */.Cl.Cluster) {
                this.currentSegment.clusterSeekStartPos = elementStartPos;
                break; // Stop at the first cluster
            }
            if (size === undefined) {
                break;
            }
            else {
                currentPos = dataStartPos + size;
            }
        }
        // Sort the seek entries by file position so reading them exhibits a sequential pattern
        this.currentSegment.seekEntries.sort((a, b) => a.segmentPosition - b.segmentPosition);
        if (this.reader.fileSize !== null) {
            // Use the seek head to read missing metadata elements
            for (const seekEntry of this.currentSegment.seekEntries) {
                const target = METADATA_ELEMENTS.find(x => x.id === seekEntry.id);
                if (!target) {
                    continue;
                }
                if (this.currentSegment[target.flag])
                    continue;
                let slice = this.reader.requestSliceRange(segmentDataStart + seekEntry.segmentPosition, ebml/* MIN_HEADER_SIZE */.De, ebml/* MAX_HEADER_SIZE */.r1);
                if (slice instanceof Promise)
                    slice = await slice;
                if (!slice)
                    continue;
                const header = (0,ebml/* readElementHeader */.ur)(slice);
                if (!header)
                    continue;
                const { id, size } = header;
                if (id !== target.id)
                    continue;
                (0,ebml/* assertDefinedSize */.p)(size);
                this.currentSegment[target.flag] = true;
                let dataSlice = this.reader.requestSlice(slice.filePos, size);
                if (dataSlice instanceof Promise)
                    dataSlice = await dataSlice;
                if (!dataSlice)
                    continue;
                this.readContiguousElements(dataSlice);
            }
        }
        if (this.currentSegment.timestampScale === -1) {
            // TimestampScale element is missing. Technically an invalid file, but let's default to the typical value,
            // which is 1e6.
            this.currentSegment.timestampScale = 1e6;
            this.currentSegment.timestampFactor = 1e9 / 1e6;
        }
        // Compute default duration for all tracks now that we have the timestamp factor
        for (const track of this.currentSegment.tracks) {
            if (track.defaultDurationNs !== null) {
                track.defaultDuration = (this.currentSegment.timestampFactor * track.defaultDurationNs) / 1e9;
            }
        }
        // Put default tracks first
        this.currentSegment.tracks.sort((a, b) => Number(b.disposition.default) - Number(a.disposition.default));
        // Now, let's distribute the cue points to the tracks
        const idToTrack = new Map(this.currentSegment.tracks.map(x => [x.id, x]));
        // Assign cue points to their respective tracks
        for (const cuePoint of this.currentSegment.cuePoints) {
            const track = idToTrack.get(cuePoint.trackId);
            if (track) {
                track.cuePoints.push(cuePoint);
            }
        }
        for (const track of this.currentSegment.tracks) {
            // Sort cue points by time
            track.cuePoints.sort((a, b) => a.time - b.time);
            // Remove multiple cue points for the same time
            for (let i = 0; i < track.cuePoints.length - 1; i++) {
                const cuePoint1 = track.cuePoints[i];
                const cuePoint2 = track.cuePoints[i + 1];
                if (cuePoint1.time === cuePoint2.time) {
                    track.cuePoints.splice(i + 1, 1);
                    i--;
                }
            }
        }
        let trackWithMostCuePoints = null;
        let maxCuePointCount = -Infinity;
        for (const track of this.currentSegment.tracks) {
            if (track.cuePoints.length > maxCuePointCount) {
                maxCuePointCount = track.cuePoints.length;
                trackWithMostCuePoints = track;
            }
        }
        // For every track that has received 0 cue points (can happen, often only the video track receives cue points),
        // we still want to have better seeking. Therefore, let's give it the cue points of the track with the most cue
        // points, which should provide us with the most fine-grained seeking.
        for (const track of this.currentSegment.tracks) {
            if (track.cuePoints.length === 0) {
                track.cuePoints = trackWithMostCuePoints.cuePoints;
            }
        }
        this.currentSegment = null;
    }
    async readCluster(startPos, segment) {
        if (segment.lastReadCluster?.elementStartPos === startPos) {
            return segment.lastReadCluster;
        }
        let headerSlice = this.reader.requestSliceRange(startPos, ebml/* MIN_HEADER_SIZE */.De, ebml/* MAX_HEADER_SIZE */.r1);
        if (headerSlice instanceof Promise)
            headerSlice = await headerSlice;
        (0,misc/* assert */.vA)(headerSlice);
        const elementStartPos = startPos;
        const elementHeader = (0,ebml/* readElementHeader */.ur)(headerSlice);
        (0,misc/* assert */.vA)(elementHeader);
        const id = elementHeader.id;
        (0,misc/* assert */.vA)(id === ebml/* EBMLId */.Cl.Cluster);
        let size = elementHeader.size;
        const dataStartPos = headerSlice.filePos;
        if (size === undefined) {
            // The cluster's size is undefined (can happen in livestreamed files). We'd still like to know the size of
            // it, so we have no other choice but to iterate over the EBML structure until we find an element at level
            // 0 or 1, indicating the end of the cluster (all elements inside the cluster are at level 2).
            const nextElementPos = await (0,ebml/* searchForNextElementId */.IQ)(this.reader, dataStartPos, ebml/* LEVEL_0_AND_1_EBML_IDS */.K9, segment.elementEndPos);
            size = nextElementPos.pos - dataStartPos;
        }
        // Load the entire cluster
        let dataSlice = this.reader.requestSlice(dataStartPos, size);
        if (dataSlice instanceof Promise)
            dataSlice = await dataSlice;
        const cluster = {
            segment,
            elementStartPos,
            elementEndPos: dataStartPos + size,
            dataStartPos,
            timestamp: -1,
            trackData: new Map(),
        };
        this.currentCluster = cluster;
        if (dataSlice) {
            // Read the children of the cluster, stopping early at level 0 or 1 EBML elements. We do this because some
            // clusters have incorrect sizes that are too large
            const endPos = this.readContiguousElements(dataSlice, ebml/* LEVEL_0_AND_1_EBML_IDS */.K9);
            cluster.elementEndPos = endPos;
        }
        for (const [, trackData] of cluster.trackData) {
            const track = trackData.track;
            // This must hold, as track datas only get created if a block for that track is encountered
            (0,misc/* assert */.vA)(trackData.blocks.length > 0);
            let hasLacedBlocks = false;
            for (let i = 0; i < trackData.blocks.length; i++) {
                const block = trackData.blocks[i];
                block.timestamp += cluster.timestamp;
                hasLacedBlocks ||= block.lacing !== BlockLacing.None;
            }
            trackData.presentationTimestamps = trackData.blocks
                .map((block, i) => ({ timestamp: block.timestamp, blockIndex: i }))
                .sort((a, b) => a.timestamp - b.timestamp);
            for (let i = 0; i < trackData.presentationTimestamps.length; i++) {
                const currentEntry = trackData.presentationTimestamps[i];
                const currentBlock = trackData.blocks[currentEntry.blockIndex];
                if (trackData.firstKeyFrameTimestamp === null && currentBlock.isKeyFrame) {
                    trackData.firstKeyFrameTimestamp = currentBlock.timestamp;
                }
                if (i < trackData.presentationTimestamps.length - 1) {
                    // Update block durations based on presentation order
                    const nextEntry = trackData.presentationTimestamps[i + 1];
                    currentBlock.duration = nextEntry.timestamp - currentBlock.timestamp;
                }
                else if (currentBlock.duration === 0) {
                    if (track.defaultDuration != null) {
                        if (currentBlock.lacing === BlockLacing.None) {
                            currentBlock.duration = track.defaultDuration;
                        }
                        else {
                            // Handled by the lace resolution code
                        }
                    }
                }
            }
            if (hasLacedBlocks) {
                // Perform lace resolution. Here, we expand each laced block into multiple blocks where each contains
                // one frame of the lace. We do this after determining block timestamps so we can properly distribute
                // the block's duration across the laced frames.
                this.expandLacedBlocks(trackData.blocks, track);
                // Recompute since blocks have changed
                trackData.presentationTimestamps = trackData.blocks
                    .map((block, i) => ({ timestamp: block.timestamp, blockIndex: i }))
                    .sort((a, b) => a.timestamp - b.timestamp);
            }
            const firstBlock = trackData.blocks[trackData.presentationTimestamps[0].blockIndex];
            const lastBlock = trackData.blocks[(0,misc/* last */._g)(trackData.presentationTimestamps).blockIndex];
            trackData.startTimestamp = firstBlock.timestamp;
            trackData.endTimestamp = lastBlock.timestamp + lastBlock.duration;
            // Let's remember that a cluster with a given timestamp is here, speeding up future lookups if no cues exist
            const insertionIndex = (0,misc/* binarySearchLessOrEqual */.eE)(track.clusterPositionCache, trackData.startTimestamp, x => x.startTimestamp);
            if (insertionIndex === -1
                || track.clusterPositionCache[insertionIndex].elementStartPos !== elementStartPos) {
                track.clusterPositionCache.splice(insertionIndex + 1, 0, {
                    elementStartPos: cluster.elementStartPos,
                    startTimestamp: trackData.startTimestamp,
                });
            }
        }
        segment.lastReadCluster = cluster;
        return cluster;
    }
    getTrackDataInCluster(cluster, trackNumber) {
        let trackData = cluster.trackData.get(trackNumber);
        if (!trackData) {
            const track = cluster.segment.tracks.find(x => x.id === trackNumber);
            if (!track) {
                return null;
            }
            trackData = {
                track,
                startTimestamp: 0,
                endTimestamp: 0,
                firstKeyFrameTimestamp: null,
                blocks: [],
                presentationTimestamps: [],
            };
            cluster.trackData.set(trackNumber, trackData);
        }
        return trackData;
    }
    expandLacedBlocks(blocks, track) {
        // https://www.matroska.org/technical/notes.html#block-lacing
        for (let blockIndex = 0; blockIndex < blocks.length; blockIndex++) {
            const originalBlock = blocks[blockIndex];
            if (originalBlock.lacing === BlockLacing.None) {
                continue;
            }
            // Decode the block data if it hasn't been decoded yet (needed for lacing expansion)
            if (!originalBlock.decoded) {
                originalBlock.data = this.decodeBlockData(track, originalBlock.data);
                originalBlock.decoded = true;
            }
            const slice = src_reader/* FileSlice */.x$.tempFromBytes(originalBlock.data);
            const frameSizes = [];
            const frameCount = (0,src_reader/* readU8 */.eo)(slice) + 1;
            switch (originalBlock.lacing) {
                case BlockLacing.Xiph:
                    {
                        let totalUsedSize = 0;
                        // Xiph lacing, just like in Ogg
                        for (let i = 0; i < frameCount - 1; i++) {
                            let frameSize = 0;
                            while (slice.bufferPos < slice.length) {
                                const value = (0,src_reader/* readU8 */.eo)(slice);
                                frameSize += value;
                                if (value < 255) {
                                    frameSizes.push(frameSize);
                                    totalUsedSize += frameSize;
                                    break;
                                }
                            }
                        }
                        // Compute the last frame's size from whatever's left
                        frameSizes.push(slice.length - (slice.bufferPos + totalUsedSize));
                    }
                    ;
                    break;
                case BlockLacing.FixedSize:
                    {
                        // Fixed size lacing: all frames have same size
                        const totalDataSize = slice.length - 1; // Minus the frame count byte
                        const frameSize = Math.floor(totalDataSize / frameCount);
                        for (let i = 0; i < frameCount; i++) {
                            frameSizes.push(frameSize);
                        }
                    }
                    ;
                    break;
                case BlockLacing.Ebml:
                    {
                        // EBML lacing: first size absolute, subsequent ones are coded as signed differences from the last
                        const firstResult = (0,ebml/* readVarInt */.pT)(slice);
                        (0,misc/* assert */.vA)(firstResult !== null); // Assume it's not an invalid VINT
                        let currentSize = firstResult;
                        frameSizes.push(currentSize);
                        let totalUsedSize = currentSize;
                        for (let i = 1; i < frameCount - 1; i++) {
                            const startPos = slice.bufferPos;
                            const diffResult = (0,ebml/* readVarInt */.pT)(slice);
                            (0,misc/* assert */.vA)(diffResult !== null);
                            const unsignedDiff = diffResult;
                            const width = slice.bufferPos - startPos;
                            const bias = (1 << (width * 7 - 1)) - 1; // Typo-corrected version of 2^((7*n)-1)^-1
                            const diff = unsignedDiff - bias;
                            currentSize += diff;
                            frameSizes.push(currentSize);
                            totalUsedSize += currentSize;
                        }
                        // Compute the last frame's size from whatever's left
                        frameSizes.push(slice.length - (slice.bufferPos + totalUsedSize));
                    }
                    ;
                    break;
                default: (0,misc/* assert */.vA)(false);
            }
            (0,misc/* assert */.vA)(frameSizes.length === frameCount);
            blocks.splice(blockIndex, 1); // Remove the original block
            const blockDuration = originalBlock.duration || frameCount * (track.defaultDuration ?? 0);
            // Now, let's insert each frame as its own block
            for (let i = 0; i < frameCount; i++) {
                const frameSize = frameSizes[i];
                const frameData = (0,src_reader/* readBytes */.io)(slice, frameSize);
                // Distribute timestamps evenly across the block duration
                const frameTimestamp = originalBlock.timestamp + (blockDuration * i / frameCount);
                const frameDuration = blockDuration / frameCount;
                blocks.splice(blockIndex + i, 0, {
                    timestamp: frameTimestamp,
                    duration: frameDuration,
                    isKeyFrame: originalBlock.isKeyFrame,
                    data: frameData,
                    lacing: BlockLacing.None,
                    decoded: true,
                    mainAdditional: originalBlock.mainAdditional,
                });
            }
            blockIndex += frameCount; // Skip the blocks we just added
            blockIndex--;
        }
    }
    async loadSegmentMetadata(segment) {
        for (const seekEntry of segment.seekEntries) {
            if (seekEntry.id === ebml/* EBMLId */.Cl.Tags && !segment.tagsSeen) {
                // We need to load the tags
            }
            else if (seekEntry.id === ebml/* EBMLId */.Cl.Attachments && !segment.attachmentsSeen) {
                // We need to load the attachments
            }
            else {
                continue;
            }
            let slice = this.reader.requestSliceRange(segment.dataStartPos + seekEntry.segmentPosition, ebml/* MIN_HEADER_SIZE */.De, ebml/* MAX_HEADER_SIZE */.r1);
            if (slice instanceof Promise)
                slice = await slice;
            if (!slice)
                continue;
            const header = (0,ebml/* readElementHeader */.ur)(slice);
            if (!header || header.id !== seekEntry.id)
                continue;
            const { size } = header;
            (0,ebml/* assertDefinedSize */.p)(size);
            (0,misc/* assert */.vA)(!this.currentSegment);
            this.currentSegment = segment;
            let dataSlice = this.reader.requestSlice(slice.filePos, size);
            if (dataSlice instanceof Promise)
                dataSlice = await dataSlice;
            if (dataSlice) {
                this.readContiguousElements(dataSlice);
            }
            this.currentSegment = null;
            // Mark as seen
            if (seekEntry.id === ebml/* EBMLId */.Cl.Tags) {
                segment.tagsSeen = true;
            }
            else if (seekEntry.id === ebml/* EBMLId */.Cl.Attachments) {
                segment.attachmentsSeen = true;
            }
        }
    }
    readContiguousElements(slice, stopIds) {
        while (slice.remainingLength >= ebml/* MIN_HEADER_SIZE */.De) {
            const startPos = slice.filePos;
            const foundElement = this.traverseElement(slice, stopIds);
            if (!foundElement) {
                return startPos;
            }
        }
        return slice.filePos;
    }
    traverseElement(slice, stopIds) {
        const header = (0,ebml/* readElementHeader */.ur)(slice);
        if (!header) {
            return false;
        }
        if (stopIds && stopIds.includes(header.id)) {
            return false;
        }
        const { id, size } = header;
        const dataStartPos = slice.filePos;
        (0,ebml/* assertDefinedSize */.p)(size);
        switch (id) {
            case ebml/* EBMLId */.Cl.DocType:
                {
                    this.isWebM = (0,ebml/* readAsciiString */.IX)(slice, size) === 'webm';
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.Seek:
                {
                    if (!this.currentSegment)
                        break;
                    const seekEntry = { id: -1, segmentPosition: -1 };
                    this.currentSegment.seekEntries.push(seekEntry);
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                    if (seekEntry.id === -1 || seekEntry.segmentPosition === -1) {
                        this.currentSegment.seekEntries.pop();
                    }
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.SeekID:
                {
                    const lastSeekEntry = this.currentSegment?.seekEntries[this.currentSegment.seekEntries.length - 1];
                    if (!lastSeekEntry)
                        break;
                    lastSeekEntry.id = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.SeekPosition:
                {
                    const lastSeekEntry = this.currentSegment?.seekEntries[this.currentSegment.seekEntries.length - 1];
                    if (!lastSeekEntry)
                        break;
                    lastSeekEntry.segmentPosition = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.TimestampScale:
                {
                    if (!this.currentSegment)
                        break;
                    this.currentSegment.timestampScale = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                    this.currentSegment.timestampFactor = 1e9 / this.currentSegment.timestampScale;
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.Duration:
                {
                    if (!this.currentSegment)
                        break;
                    this.currentSegment.duration = (0,ebml/* readFloat */.zH)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.TrackEntry:
                {
                    if (!this.currentSegment)
                        break;
                    this.currentTrack = {
                        id: -1,
                        segment: this.currentSegment,
                        demuxer: this,
                        clusterPositionCache: [],
                        cuePoints: [],
                        disposition: {
                            ...metadata/* DEFAULT_TRACK_DISPOSITION */.gM,
                        },
                        inputTrack: null,
                        codecId: null,
                        codecPrivate: null,
                        defaultDuration: null,
                        defaultDurationNs: null,
                        name: null,
                        languageCode: misc/* UNDETERMINED_LANGUAGE */.IR,
                        decodingInstructions: [],
                        info: null,
                    };
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                    // Check if track was disabled during parsing (e.g., by FlagEnabled being 0)
                    if (!this.currentTrack) {
                        break;
                    }
                    if (this.currentTrack.decodingInstructions.some((instruction) => {
                        return instruction.data?.type !== 'decompress'
                            || instruction.scope !== ContentEncodingScope.Block
                            || instruction.data.algorithm !== ContentCompAlgo.HeaderStripping;
                    })) {
                        console.warn(`Track #${this.currentTrack.id} has an unsupported content encoding; dropping.`);
                        this.currentTrack = null;
                    }
                    if (this.currentTrack
                        && this.currentTrack.id !== -1
                        && this.currentTrack.codecId
                        && this.currentTrack.info) {
                        const slashIndex = this.currentTrack.codecId.indexOf('/');
                        const codecIdWithoutSuffix = slashIndex === -1
                            ? this.currentTrack.codecId
                            : this.currentTrack.codecId.slice(0, slashIndex);
                        if (this.currentTrack.info.type === 'video'
                            && this.currentTrack.info.width !== -1
                            && this.currentTrack.info.height !== -1) {
                            if (this.currentTrack.codecId === ebml/* CODEC_STRING_MAP */.oo.avc) {
                                this.currentTrack.info.codec = 'avc';
                                this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                            }
                            else if (this.currentTrack.codecId === ebml/* CODEC_STRING_MAP */.oo.hevc) {
                                this.currentTrack.info.codec = 'hevc';
                                this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                            }
                            else if (codecIdWithoutSuffix === ebml/* CODEC_STRING_MAP */.oo.vp8) {
                                this.currentTrack.info.codec = 'vp8';
                            }
                            else if (codecIdWithoutSuffix === ebml/* CODEC_STRING_MAP */.oo.vp9) {
                                this.currentTrack.info.codec = 'vp9';
                            }
                            else if (codecIdWithoutSuffix === ebml/* CODEC_STRING_MAP */.oo.av1) {
                                this.currentTrack.info.codec = 'av1';
                            }
                            const videoTrack = this.currentTrack;
                            const inputTrack = new input_track/* InputVideoTrack */.N0(this.input, new MatroskaVideoTrackBacking(videoTrack));
                            this.currentTrack.inputTrack = inputTrack;
                            this.currentSegment.tracks.push(this.currentTrack);
                        }
                        else if (this.currentTrack.info.type === 'audio'
                            && this.currentTrack.info.numberOfChannels !== -1
                            && this.currentTrack.info.sampleRate !== -1) {
                            if (codecIdWithoutSuffix === ebml/* CODEC_STRING_MAP */.oo.aac) {
                                this.currentTrack.info.codec = 'aac';
                                this.currentTrack.info.aacCodecInfo = {
                                    isMpeg2: this.currentTrack.codecId.includes('MPEG2'),
                                    objectType: null,
                                };
                                this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                            }
                            else if (this.currentTrack.codecId === ebml/* CODEC_STRING_MAP */.oo.mp3) {
                                this.currentTrack.info.codec = 'mp3';
                            }
                            else if (codecIdWithoutSuffix === ebml/* CODEC_STRING_MAP */.oo.opus) {
                                this.currentTrack.info.codec = 'opus';
                                this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                                this.currentTrack.info.sampleRate = codec/* OPUS_SAMPLE_RATE */.yo; // Always the same
                            }
                            else if (codecIdWithoutSuffix === ebml/* CODEC_STRING_MAP */.oo.vorbis) {
                                this.currentTrack.info.codec = 'vorbis';
                                this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                            }
                            else if (codecIdWithoutSuffix === ebml/* CODEC_STRING_MAP */.oo.flac) {
                                this.currentTrack.info.codec = 'flac';
                                this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                            }
                            else if (codecIdWithoutSuffix === ebml/* CODEC_STRING_MAP */.oo.ac3) {
                                this.currentTrack.info.codec = 'ac3';
                                this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                            }
                            else if (codecIdWithoutSuffix === ebml/* CODEC_STRING_MAP */.oo.eac3) {
                                this.currentTrack.info.codec = 'eac3';
                                this.currentTrack.info.codecDescription = this.currentTrack.codecPrivate;
                            }
                            else if (this.currentTrack.codecId === 'A_PCM/INT/LIT') {
                                if (this.currentTrack.info.bitDepth === 8) {
                                    this.currentTrack.info.codec = 'pcm-u8';
                                }
                                else if (this.currentTrack.info.bitDepth === 16) {
                                    this.currentTrack.info.codec = 'pcm-s16';
                                }
                                else if (this.currentTrack.info.bitDepth === 24) {
                                    this.currentTrack.info.codec = 'pcm-s24';
                                }
                                else if (this.currentTrack.info.bitDepth === 32) {
                                    this.currentTrack.info.codec = 'pcm-s32';
                                }
                            }
                            else if (this.currentTrack.codecId === 'A_PCM/INT/BIG') {
                                if (this.currentTrack.info.bitDepth === 8) {
                                    this.currentTrack.info.codec = 'pcm-u8';
                                }
                                else if (this.currentTrack.info.bitDepth === 16) {
                                    this.currentTrack.info.codec = 'pcm-s16be';
                                }
                                else if (this.currentTrack.info.bitDepth === 24) {
                                    this.currentTrack.info.codec = 'pcm-s24be';
                                }
                                else if (this.currentTrack.info.bitDepth === 32) {
                                    this.currentTrack.info.codec = 'pcm-s32be';
                                }
                            }
                            else if (this.currentTrack.codecId === 'A_PCM/FLOAT/IEEE') {
                                if (this.currentTrack.info.bitDepth === 32) {
                                    this.currentTrack.info.codec = 'pcm-f32';
                                }
                                else if (this.currentTrack.info.bitDepth === 64) {
                                    this.currentTrack.info.codec = 'pcm-f64';
                                }
                            }
                            const audioTrack = this.currentTrack;
                            const inputTrack = new input_track/* InputAudioTrack */.Yi(this.input, new MatroskaAudioTrackBacking(audioTrack));
                            this.currentTrack.inputTrack = inputTrack;
                            this.currentSegment.tracks.push(this.currentTrack);
                        }
                    }
                    this.currentTrack = null;
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.TrackNumber:
                {
                    if (!this.currentTrack)
                        break;
                    this.currentTrack.id = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.TrackType:
                {
                    if (!this.currentTrack)
                        break;
                    const type = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                    if (type === 1) {
                        this.currentTrack.info = {
                            type: 'video',
                            width: -1,
                            height: -1,
                            rotation: 0,
                            codec: null,
                            codecDescription: null,
                            colorSpace: null,
                            alphaMode: false,
                        };
                    }
                    else if (type === 2) {
                        this.currentTrack.info = {
                            type: 'audio',
                            numberOfChannels: -1,
                            sampleRate: -1,
                            bitDepth: -1,
                            codec: null,
                            codecDescription: null,
                            aacCodecInfo: null,
                        };
                    }
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.FlagEnabled:
                {
                    if (!this.currentTrack)
                        break;
                    const enabled = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                    if (!enabled) {
                        this.currentTrack = null;
                    }
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.FlagDefault:
                {
                    if (!this.currentTrack)
                        break;
                    this.currentTrack.disposition.default = !!(0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.FlagForced:
                {
                    if (!this.currentTrack)
                        break;
                    this.currentTrack.disposition.forced = !!(0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.FlagOriginal:
                {
                    if (!this.currentTrack)
                        break;
                    this.currentTrack.disposition.original = !!(0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.FlagHearingImpaired:
                {
                    if (!this.currentTrack)
                        break;
                    this.currentTrack.disposition.hearingImpaired = !!(0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.FlagVisualImpaired:
                {
                    if (!this.currentTrack)
                        break;
                    this.currentTrack.disposition.visuallyImpaired = !!(0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.FlagCommentary:
                {
                    if (!this.currentTrack)
                        break;
                    this.currentTrack.disposition.commentary = !!(0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.CodecID:
                {
                    if (!this.currentTrack)
                        break;
                    this.currentTrack.codecId = (0,ebml/* readAsciiString */.IX)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.CodecPrivate:
                {
                    if (!this.currentTrack)
                        break;
                    this.currentTrack.codecPrivate = (0,src_reader/* readBytes */.io)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.DefaultDuration:
                {
                    if (!this.currentTrack)
                        break;
                    this.currentTrack.defaultDurationNs = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.Name:
                {
                    if (!this.currentTrack)
                        break;
                    this.currentTrack.name = (0,ebml/* readUnicodeString */.jR)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.Language:
                {
                    if (!this.currentTrack)
                        break;
                    if (this.currentTrack.languageCode !== misc/* UNDETERMINED_LANGUAGE */.IR) {
                        // LanguageBCP47 was present, which takes precedence
                        break;
                    }
                    this.currentTrack.languageCode = (0,ebml/* readAsciiString */.IX)(slice, size);
                    if (!(0,misc/* isIso639Dash2LanguageCode */.Nu)(this.currentTrack.languageCode)) {
                        this.currentTrack.languageCode = misc/* UNDETERMINED_LANGUAGE */.IR;
                    }
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.LanguageBCP47:
                {
                    if (!this.currentTrack)
                        break;
                    const bcp47 = (0,ebml/* readAsciiString */.IX)(slice, size);
                    const languageSubtag = bcp47.split('-')[0];
                    if (languageSubtag) {
                        // Technically invalid, for now: The language subtag might be a language code from ISO 639-1,
                        // ISO 639-2, ISO 639-3, ISO 639-5 or some other thing (source: Wikipedia). But, `languageCode` is
                        // documented as ISO 639-2. Changing the definition would be a breaking change. This will get
                        // cleaned up in the future by defining languageCode to be BCP 47 instead.
                        this.currentTrack.languageCode = languageSubtag;
                    }
                    else {
                        this.currentTrack.languageCode = misc/* UNDETERMINED_LANGUAGE */.IR;
                    }
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.Video:
                {
                    if (this.currentTrack?.info?.type !== 'video')
                        break;
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.PixelWidth:
                {
                    if (this.currentTrack?.info?.type !== 'video')
                        break;
                    this.currentTrack.info.width = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.PixelHeight:
                {
                    if (this.currentTrack?.info?.type !== 'video')
                        break;
                    this.currentTrack.info.height = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.AlphaMode:
                {
                    if (this.currentTrack?.info?.type !== 'video')
                        break;
                    this.currentTrack.info.alphaMode = (0,ebml/* readUnsignedInt */.dl)(slice, size) === 1;
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.Colour:
                {
                    if (this.currentTrack?.info?.type !== 'video')
                        break;
                    this.currentTrack.info.colorSpace = {};
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.MatrixCoefficients:
                {
                    if (this.currentTrack?.info?.type !== 'video' || !this.currentTrack.info.colorSpace)
                        break;
                    const matrixCoefficients = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                    const mapped = misc/* MATRIX_COEFFICIENTS_MAP_INVERSE */.fl[matrixCoefficients] ?? null;
                    this.currentTrack.info.colorSpace.matrix = mapped;
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.Range:
                {
                    if (this.currentTrack?.info?.type !== 'video' || !this.currentTrack.info.colorSpace)
                        break;
                    this.currentTrack.info.colorSpace.fullRange = (0,ebml/* readUnsignedInt */.dl)(slice, size) === 2;
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.TransferCharacteristics:
                {
                    if (this.currentTrack?.info?.type !== 'video' || !this.currentTrack.info.colorSpace)
                        break;
                    const transferCharacteristics = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                    const mapped = misc/* TRANSFER_CHARACTERISTICS_MAP_INVERSE */.x_[transferCharacteristics] ?? null;
                    this.currentTrack.info.colorSpace.transfer = mapped;
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.Primaries:
                {
                    if (this.currentTrack?.info?.type !== 'video' || !this.currentTrack.info.colorSpace)
                        break;
                    const primaries = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                    const mapped = misc/* COLOR_PRIMARIES_MAP_INVERSE */.BL[primaries] ?? null;
                    this.currentTrack.info.colorSpace.primaries = mapped;
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.Projection:
                {
                    if (this.currentTrack?.info?.type !== 'video')
                        break;
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.ProjectionPoseRoll:
                {
                    if (this.currentTrack?.info?.type !== 'video')
                        break;
                    const rotation = (0,ebml/* readFloat */.zH)(slice, size);
                    const flippedRotation = -rotation; // Convert counter-clockwise to clockwise
                    try {
                        this.currentTrack.info.rotation = (0,misc/* normalizeRotation */.qT)(flippedRotation);
                    }
                    catch {
                        // It wasn't a valid rotation
                    }
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.Audio:
                {
                    if (this.currentTrack?.info?.type !== 'audio')
                        break;
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.SamplingFrequency:
                {
                    if (this.currentTrack?.info?.type !== 'audio')
                        break;
                    this.currentTrack.info.sampleRate = (0,ebml/* readFloat */.zH)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.Channels:
                {
                    if (this.currentTrack?.info?.type !== 'audio')
                        break;
                    this.currentTrack.info.numberOfChannels = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.BitDepth:
                {
                    if (this.currentTrack?.info?.type !== 'audio')
                        break;
                    this.currentTrack.info.bitDepth = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.CuePoint:
                {
                    if (!this.currentSegment)
                        break;
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                    this.currentCueTime = null;
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.CueTime:
                {
                    this.currentCueTime = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.CueTrackPositions:
                {
                    if (this.currentCueTime === null)
                        break;
                    (0,misc/* assert */.vA)(this.currentSegment);
                    const cuePoint = { time: this.currentCueTime, trackId: -1, clusterPosition: -1 };
                    this.currentSegment.cuePoints.push(cuePoint);
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                    if (cuePoint.trackId === -1 || cuePoint.clusterPosition === -1) {
                        this.currentSegment.cuePoints.pop();
                    }
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.CueTrack:
                {
                    const lastCuePoint = this.currentSegment?.cuePoints[this.currentSegment.cuePoints.length - 1];
                    if (!lastCuePoint)
                        break;
                    lastCuePoint.trackId = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.CueClusterPosition:
                {
                    const lastCuePoint = this.currentSegment?.cuePoints[this.currentSegment.cuePoints.length - 1];
                    if (!lastCuePoint)
                        break;
                    (0,misc/* assert */.vA)(this.currentSegment);
                    lastCuePoint.clusterPosition = this.currentSegment.dataStartPos + (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.Timestamp:
                {
                    if (!this.currentCluster)
                        break;
                    this.currentCluster.timestamp = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.SimpleBlock:
                {
                    if (!this.currentCluster)
                        break;
                    const trackNumber = (0,ebml/* readVarInt */.pT)(slice);
                    if (trackNumber === null)
                        break;
                    const trackData = this.getTrackDataInCluster(this.currentCluster, trackNumber);
                    if (!trackData)
                        break; // Not a track we care about
                    const relativeTimestamp = (0,src_reader/* readI16Be */.iH)(slice);
                    const flags = (0,src_reader/* readU8 */.eo)(slice);
                    const lacing = (flags >> 1) & 0x3; // If the block is laced, we'll expand it later
                    let isKeyFrame = !!(flags & 0x80);
                    if (trackData.track.info?.type === 'audio' && trackData.track.info.codec) {
                        // Some files don't mark their audio packets as key packets (I'm looking at you, Firefox). But, we
                        // can fix this in most cases: if we recognize the codec of the track, then we know every packet is
                        // necessarily a key packet, no matter what the container says.
                        // https://github.com/Vanilagy/mediabunny/issues/192
                        isKeyFrame = true;
                    }
                    const blockData = (0,src_reader/* readBytes */.io)(slice, size - (slice.filePos - dataStartPos));
                    const hasDecodingInstructions = trackData.track.decodingInstructions.length > 0;
                    trackData.blocks.push({
                        timestamp: relativeTimestamp, // We'll add the cluster's timestamp to this later
                        duration: 0, // Will set later
                        isKeyFrame,
                        data: blockData,
                        lacing,
                        decoded: !hasDecodingInstructions,
                        mainAdditional: null,
                    });
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.BlockGroup:
                {
                    if (!this.currentCluster)
                        break;
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                    this.currentBlock = null;
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.Block:
                {
                    if (!this.currentCluster)
                        break;
                    const trackNumber = (0,ebml/* readVarInt */.pT)(slice);
                    if (trackNumber === null)
                        break;
                    const trackData = this.getTrackDataInCluster(this.currentCluster, trackNumber);
                    if (!trackData)
                        break;
                    const relativeTimestamp = (0,src_reader/* readI16Be */.iH)(slice);
                    const flags = (0,src_reader/* readU8 */.eo)(slice);
                    const lacing = (flags >> 1) & 0x3; // If the block is laced, we'll expand it later
                    const blockData = (0,src_reader/* readBytes */.io)(slice, size - (slice.filePos - dataStartPos));
                    const hasDecodingInstructions = trackData.track.decodingInstructions.length > 0;
                    this.currentBlock = {
                        timestamp: relativeTimestamp, // We'll add the cluster's timestamp to this later
                        duration: 0, // Will set later
                        isKeyFrame: true,
                        data: blockData,
                        lacing,
                        decoded: !hasDecodingInstructions,
                        mainAdditional: null,
                    };
                    trackData.blocks.push(this.currentBlock);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.BlockAdditions:
                {
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.BlockMore:
                {
                    if (!this.currentBlock)
                        break;
                    this.currentBlockAdditional = {
                        addId: 1,
                        data: null,
                    };
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                    if (this.currentBlockAdditional.data && this.currentBlockAdditional.addId === 1) {
                        this.currentBlock.mainAdditional = this.currentBlockAdditional.data;
                    }
                    this.currentBlockAdditional = null;
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.BlockAdditional:
                {
                    if (!this.currentBlockAdditional)
                        break;
                    this.currentBlockAdditional.data = (0,src_reader/* readBytes */.io)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.BlockAddID:
                {
                    if (!this.currentBlockAdditional)
                        break;
                    this.currentBlockAdditional.addId = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.BlockDuration:
                {
                    if (!this.currentBlock)
                        break;
                    this.currentBlock.duration = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.ReferenceBlock:
                {
                    if (!this.currentBlock)
                        break;
                    this.currentBlock.isKeyFrame = false;
                    // We ignore the actual value here, we just use the reference as an indicator for "not a key frame".
                    // This is in line with FFmpeg's behavior.
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.Tag:
                {
                    this.currentTagTargetIsMovie = true;
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.Targets:
                {
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.TargetTypeValue:
                {
                    const targetTypeValue = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                    if (targetTypeValue !== 50) {
                        this.currentTagTargetIsMovie = false;
                    }
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.TagTrackUID:
            case ebml/* EBMLId */.Cl.TagEditionUID:
            case ebml/* EBMLId */.Cl.TagChapterUID:
            case ebml/* EBMLId */.Cl.TagAttachmentUID:
                {
                    this.currentTagTargetIsMovie = false;
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.SimpleTag:
                {
                    if (!this.currentTagTargetIsMovie)
                        break;
                    this.currentSimpleTagName = null;
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.TagName:
                {
                    this.currentSimpleTagName = (0,ebml/* readUnicodeString */.jR)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.TagString:
                {
                    if (!this.currentSimpleTagName)
                        break;
                    const value = (0,ebml/* readUnicodeString */.jR)(slice, size);
                    this.processTagValue(this.currentSimpleTagName, value);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.TagBinary:
                {
                    if (!this.currentSimpleTagName)
                        break;
                    const value = (0,src_reader/* readBytes */.io)(slice, size);
                    this.processTagValue(this.currentSimpleTagName, value);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.AttachedFile:
                {
                    if (!this.currentSegment)
                        break;
                    this.currentAttachedFile = {
                        fileUid: null,
                        fileName: null,
                        fileMediaType: null,
                        fileData: null,
                        fileDescription: null,
                    };
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                    const tags = this.currentSegment.metadataTags;
                    if (this.currentAttachedFile.fileUid && this.currentAttachedFile.fileData) {
                        // All attached files get surfaced in the `raw` metadata tags
                        tags.raw ??= {};
                        tags.raw[this.currentAttachedFile.fileUid.toString()] = new metadata/* AttachedFile */.VF(this.currentAttachedFile.fileData, this.currentAttachedFile.fileMediaType ?? undefined, this.currentAttachedFile.fileName ?? undefined, this.currentAttachedFile.fileDescription ?? undefined);
                    }
                    // Only process image attachments
                    if (this.currentAttachedFile.fileMediaType?.startsWith('image/') && this.currentAttachedFile.fileData) {
                        const fileName = this.currentAttachedFile.fileName;
                        let kind = 'unknown';
                        if (fileName) {
                            const lowerName = fileName.toLowerCase();
                            if (lowerName.startsWith('cover.')) {
                                kind = 'coverFront';
                            }
                            else if (lowerName.startsWith('back.')) {
                                kind = 'coverBack';
                            }
                        }
                        tags.images ??= [];
                        tags.images.push({
                            data: this.currentAttachedFile.fileData,
                            mimeType: this.currentAttachedFile.fileMediaType,
                            kind,
                            name: this.currentAttachedFile.fileName ?? undefined,
                            description: this.currentAttachedFile.fileDescription ?? undefined,
                        });
                    }
                    this.currentAttachedFile = null;
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.FileUID:
                {
                    if (!this.currentAttachedFile)
                        break;
                    this.currentAttachedFile.fileUid = (0,ebml/* readUnsignedBigInt */.Ry)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.FileName:
                {
                    if (!this.currentAttachedFile)
                        break;
                    this.currentAttachedFile.fileName = (0,ebml/* readUnicodeString */.jR)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.FileMediaType:
                {
                    if (!this.currentAttachedFile)
                        break;
                    this.currentAttachedFile.fileMediaType = (0,ebml/* readAsciiString */.IX)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.FileData:
                {
                    if (!this.currentAttachedFile)
                        break;
                    this.currentAttachedFile.fileData = (0,src_reader/* readBytes */.io)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.FileDescription:
                {
                    if (!this.currentAttachedFile)
                        break;
                    this.currentAttachedFile.fileDescription = (0,ebml/* readUnicodeString */.jR)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.ContentEncodings:
                {
                    if (!this.currentTrack)
                        break;
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                    // "**MUST** start with the `ContentEncoding` with the highest `ContentEncodingOrder`"
                    this.currentTrack.decodingInstructions.sort((a, b) => b.order - a.order);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.ContentEncoding:
                {
                    this.currentDecodingInstruction = {
                        order: 0,
                        scope: ContentEncodingScope.Block,
                        data: null,
                    };
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                    if (this.currentDecodingInstruction.data) {
                        this.currentTrack.decodingInstructions.push(this.currentDecodingInstruction);
                    }
                    this.currentDecodingInstruction = null;
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.ContentEncodingOrder:
                {
                    if (!this.currentDecodingInstruction)
                        break;
                    this.currentDecodingInstruction.order = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.ContentEncodingScope:
                {
                    if (!this.currentDecodingInstruction)
                        break;
                    this.currentDecodingInstruction.scope = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.ContentCompression:
                {
                    if (!this.currentDecodingInstruction)
                        break;
                    this.currentDecodingInstruction.data = {
                        type: 'decompress',
                        algorithm: ContentCompAlgo.Zlib,
                        settings: null,
                    };
                    this.readContiguousElements(slice.slice(dataStartPos, size));
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.ContentCompAlgo:
                {
                    if (this.currentDecodingInstruction?.data?.type !== 'decompress')
                        break;
                    this.currentDecodingInstruction.data.algorithm = (0,ebml/* readUnsignedInt */.dl)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.ContentCompSettings:
                {
                    if (this.currentDecodingInstruction?.data?.type !== 'decompress')
                        break;
                    this.currentDecodingInstruction.data.settings = (0,src_reader/* readBytes */.io)(slice, size);
                }
                ;
                break;
            case ebml/* EBMLId */.Cl.ContentEncryption:
                {
                    if (!this.currentDecodingInstruction)
                        break;
                    this.currentDecodingInstruction.data = {
                        type: 'decrypt',
                    };
                }
                ;
                break;
        }
        slice.filePos = dataStartPos + size;
        return true;
    }
    decodeBlockData(track, rawData) {
        (0,misc/* assert */.vA)(track.decodingInstructions.length > 0); // This method shouldn't be called otherwise
        let currentData = rawData;
        for (const instruction of track.decodingInstructions) {
            (0,misc/* assert */.vA)(instruction.data);
            switch (instruction.data.type) {
                case 'decompress':
                    {
                        switch (instruction.data.algorithm) {
                            case ContentCompAlgo.HeaderStripping:
                                {
                                    if (instruction.data.settings && instruction.data.settings.length > 0) {
                                        const prefix = instruction.data.settings;
                                        const newData = new Uint8Array(prefix.length + currentData.length);
                                        newData.set(prefix, 0);
                                        newData.set(currentData, prefix.length);
                                        currentData = newData;
                                    }
                                }
                                ;
                                break;
                            default:
                                {
                                    // Unhandled
                                }
                                ;
                        }
                    }
                    ;
                    break;
                default:
                    {
                        // Unhandled
                    }
                    ;
            }
        }
        return currentData;
    }
    processTagValue(name, value) {
        if (!this.currentSegment?.metadataTags)
            return;
        const metadataTags = this.currentSegment.metadataTags;
        metadataTags.raw ??= {};
        metadataTags.raw[name] ??= value;
        if (typeof value === 'string') {
            switch (name.toLowerCase()) {
                case 'title':
                    {
                        metadataTags.title ??= value;
                    }
                    ;
                    break;
                case 'description':
                    {
                        metadataTags.description ??= value;
                    }
                    ;
                    break;
                case 'artist':
                    {
                        metadataTags.artist ??= value;
                    }
                    ;
                    break;
                case 'album':
                    {
                        metadataTags.album ??= value;
                    }
                    ;
                    break;
                case 'album_artist':
                    {
                        metadataTags.albumArtist ??= value;
                    }
                    ;
                    break;
                case 'genre':
                    {
                        metadataTags.genre ??= value;
                    }
                    ;
                    break;
                case 'comment':
                    {
                        metadataTags.comment ??= value;
                    }
                    ;
                    break;
                case 'lyrics':
                    {
                        metadataTags.lyrics ??= value;
                    }
                    ;
                    break;
                case 'date':
                    {
                        const date = new Date(value);
                        if (!Number.isNaN(date.getTime())) {
                            metadataTags.date ??= date;
                        }
                    }
                    ;
                    break;
                case 'track_number':
                case 'part_number':
                    {
                        const parts = value.split('/');
                        const trackNum = Number.parseInt(parts[0], 10);
                        const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);
                        if (Number.isInteger(trackNum) && trackNum > 0) {
                            metadataTags.trackNumber ??= trackNum;
                        }
                        if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {
                            metadataTags.tracksTotal ??= tracksTotal;
                        }
                    }
                    ;
                    break;
                case 'disc_number':
                case 'disc':
                    {
                        const discParts = value.split('/');
                        const discNum = Number.parseInt(discParts[0], 10);
                        const discsTotal = discParts[1] && Number.parseInt(discParts[1], 10);
                        if (Number.isInteger(discNum) && discNum > 0) {
                            metadataTags.discNumber ??= discNum;
                        }
                        if (discsTotal && Number.isInteger(discsTotal) && discsTotal > 0) {
                            metadataTags.discsTotal ??= discsTotal;
                        }
                    }
                    ;
                    break;
            }
        }
    }
}
class MatroskaTrackBacking {
    constructor(internalTrack) {
        this.internalTrack = internalTrack;
        this.packetToClusterLocation = new WeakMap();
    }
    getId() {
        return this.internalTrack.id;
    }
    getNumber() {
        const demuxer = this.internalTrack.demuxer;
        const inputTrack = this.internalTrack.inputTrack;
        const trackType = inputTrack.type;
        let number = 0;
        for (const segment of demuxer.segments) {
            for (const track of segment.tracks) {
                if (track.inputTrack.type === trackType) {
                    number++;
                }
                if (track === this.internalTrack) {
                    break;
                }
            }
        }
        return number;
    }
    getCodec() {
        throw new Error('Not implemented on base class.');
    }
    getInternalCodecId() {
        return this.internalTrack.codecId;
    }
    async computeDuration() {
        const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
        return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    getName() {
        return this.internalTrack.name;
    }
    getLanguageCode() {
        return this.internalTrack.languageCode;
    }
    async getFirstTimestamp() {
        const firstPacket = await this.getFirstPacket({ metadataOnly: true });
        return firstPacket?.timestamp ?? 0;
    }
    getTimeResolution() {
        return this.internalTrack.segment.timestampFactor;
    }
    getDisposition() {
        return this.internalTrack.disposition;
    }
    async getFirstPacket(options) {
        return this.performClusterLookup(null, (cluster) => {
            const trackData = cluster.trackData.get(this.internalTrack.id);
            if (trackData) {
                return {
                    blockIndex: 0,
                    correctBlockFound: true,
                };
            }
            return {
                blockIndex: -1,
                correctBlockFound: false,
            };
        }, -Infinity, // Use -Infinity as a search timestamp to avoid using the cues
        Infinity, options);
    }
    intoTimescale(timestamp) {
        // Do a little rounding to catch cases where the result is very close to an integer. If it is, it's likely
        // that the number was originally an integer divided by the timescale. For stability, it's best
        // to return the integer in this case.
        return (0,misc/* roundIfAlmostInteger */.aI)(timestamp * this.internalTrack.segment.timestampFactor);
    }
    async getPacket(timestamp, options) {
        const timestampInTimescale = this.intoTimescale(timestamp);
        return this.performClusterLookup(null, (cluster) => {
            const trackData = cluster.trackData.get(this.internalTrack.id);
            if (!trackData) {
                return { blockIndex: -1, correctBlockFound: false };
            }
            const index = (0,misc/* binarySearchLessOrEqual */.eE)(trackData.presentationTimestamps, timestampInTimescale, x => x.timestamp);
            const blockIndex = index !== -1 ? trackData.presentationTimestamps[index].blockIndex : -1;
            const correctBlockFound = index !== -1 && timestampInTimescale < trackData.endTimestamp;
            return { blockIndex, correctBlockFound };
        }, timestampInTimescale, timestampInTimescale, options);
    }
    async getNextPacket(packet, options) {
        const locationInCluster = this.packetToClusterLocation.get(packet);
        if (locationInCluster === undefined) {
            throw new Error('Packet was not created from this track.');
        }
        return this.performClusterLookup(locationInCluster.cluster, (cluster) => {
            if (cluster === locationInCluster.cluster) {
                const trackData = cluster.trackData.get(this.internalTrack.id);
                if (locationInCluster.blockIndex + 1 < trackData.blocks.length) {
                    // We can simply take the next block in the cluster
                    return {
                        blockIndex: locationInCluster.blockIndex + 1,
                        correctBlockFound: true,
                    };
                }
            }
            else {
                const trackData = cluster.trackData.get(this.internalTrack.id);
                if (trackData) {
                    return {
                        blockIndex: 0,
                        correctBlockFound: true,
                    };
                }
            }
            return {
                blockIndex: -1,
                correctBlockFound: false,
            };
        }, -Infinity, // Use -Infinity as a search timestamp to avoid using the cues
        Infinity, options);
    }
    async getKeyPacket(timestamp, options) {
        const timestampInTimescale = this.intoTimescale(timestamp);
        return this.performClusterLookup(null, (cluster) => {
            const trackData = cluster.trackData.get(this.internalTrack.id);
            if (!trackData) {
                return { blockIndex: -1, correctBlockFound: false };
            }
            const index = (0,misc/* findLastIndex */.Kl)(trackData.presentationTimestamps, (x) => {
                const block = trackData.blocks[x.blockIndex];
                return block.isKeyFrame && x.timestamp <= timestampInTimescale;
            });
            const blockIndex = index !== -1 ? trackData.presentationTimestamps[index].blockIndex : -1;
            const correctBlockFound = index !== -1 && timestampInTimescale < trackData.endTimestamp;
            return { blockIndex, correctBlockFound };
        }, timestampInTimescale, timestampInTimescale, options);
    }
    async getNextKeyPacket(packet, options) {
        const locationInCluster = this.packetToClusterLocation.get(packet);
        if (locationInCluster === undefined) {
            throw new Error('Packet was not created from this track.');
        }
        return this.performClusterLookup(locationInCluster.cluster, (cluster) => {
            if (cluster === locationInCluster.cluster) {
                const trackData = cluster.trackData.get(this.internalTrack.id);
                const nextKeyFrameIndex = trackData.blocks.findIndex((x, i) => x.isKeyFrame && i > locationInCluster.blockIndex);
                if (nextKeyFrameIndex !== -1) {
                    // We can simply take the next key frame in the cluster
                    return {
                        blockIndex: nextKeyFrameIndex,
                        correctBlockFound: true,
                    };
                }
            }
            else {
                const trackData = cluster.trackData.get(this.internalTrack.id);
                if (trackData && trackData.firstKeyFrameTimestamp !== null) {
                    const keyFrameIndex = trackData.blocks.findIndex(x => x.isKeyFrame);
                    (0,misc/* assert */.vA)(keyFrameIndex !== -1); // There must be one
                    return {
                        blockIndex: keyFrameIndex,
                        correctBlockFound: true,
                    };
                }
            }
            return {
                blockIndex: -1,
                correctBlockFound: false,
            };
        }, -Infinity, // Use -Infinity as a search timestamp to avoid using the cues
        Infinity, options);
    }
    async fetchPacketInCluster(cluster, blockIndex, options) {
        if (blockIndex === -1) {
            return null;
        }
        const trackData = cluster.trackData.get(this.internalTrack.id);
        const block = trackData.blocks[blockIndex];
        (0,misc/* assert */.vA)(block);
        // Perform lazy decoding if needed
        if (!block.decoded) {
            block.data = this.internalTrack.demuxer.decodeBlockData(this.internalTrack, block.data);
            block.decoded = true;
        }
        const data = options.metadataOnly ? src_packet/* PLACEHOLDER_DATA */.T : block.data;
        const timestamp = block.timestamp / this.internalTrack.segment.timestampFactor;
        const duration = block.duration / this.internalTrack.segment.timestampFactor;
        const sideData = {};
        if (block.mainAdditional && this.internalTrack.info?.type === 'video' && this.internalTrack.info.alphaMode) {
            sideData.alpha = options.metadataOnly ? src_packet/* PLACEHOLDER_DATA */.T : block.mainAdditional;
            sideData.alphaByteLength = block.mainAdditional.byteLength;
        }
        const packet = new src_packet/* EncodedPacket */.Z(data, block.isKeyFrame ? 'key' : 'delta', timestamp, duration, cluster.dataStartPos + blockIndex, block.data.byteLength, sideData);
        this.packetToClusterLocation.set(packet, { cluster, blockIndex });
        return packet;
    }
    /** Looks for a packet in the clusters while trying to load as few clusters as possible to retrieve it. */
    async performClusterLookup(
    // The cluster where we start looking
    startCluster, 
    // This function returns the best-matching block in a given cluster
    getMatchInCluster, 
    // The timestamp with which we can search the lookup table
    searchTimestamp, 
    // The timestamp for which we know the correct block will not come after it
    latestTimestamp, options) {
        const { demuxer, segment } = this.internalTrack;
        let currentCluster = null;
        let bestCluster = null;
        let bestBlockIndex = -1;
        if (startCluster) {
            const { blockIndex, correctBlockFound } = getMatchInCluster(startCluster);
            if (correctBlockFound) {
                return this.fetchPacketInCluster(startCluster, blockIndex, options);
            }
            if (blockIndex !== -1) {
                bestCluster = startCluster;
                bestBlockIndex = blockIndex;
            }
        }
        // Search for a cue point; this way, we won't need to start searching from the start of the file
        // but can jump right into the correct cluster (or at least nearby).
        const cuePointIndex = (0,misc/* binarySearchLessOrEqual */.eE)(this.internalTrack.cuePoints, searchTimestamp, x => x.time);
        const cuePoint = cuePointIndex !== -1
            ? this.internalTrack.cuePoints[cuePointIndex]
            : null;
        // Also check the position cache
        const positionCacheIndex = (0,misc/* binarySearchLessOrEqual */.eE)(this.internalTrack.clusterPositionCache, searchTimestamp, x => x.startTimestamp);
        const positionCacheEntry = positionCacheIndex !== -1
            ? this.internalTrack.clusterPositionCache[positionCacheIndex]
            : null;
        const lookupEntryPosition = Math.max(cuePoint?.clusterPosition ?? 0, positionCacheEntry?.elementStartPos ?? 0) || null;
        let currentPos;
        if (!startCluster) {
            currentPos = lookupEntryPosition ?? segment.clusterSeekStartPos;
        }
        else {
            if (lookupEntryPosition === null || startCluster.elementStartPos >= lookupEntryPosition) {
                currentPos = startCluster.elementEndPos;
                currentCluster = startCluster;
            }
            else {
                // Use the lookup entry
                currentPos = lookupEntryPosition;
            }
        }
        while (segment.elementEndPos === null || currentPos <= segment.elementEndPos - ebml/* MIN_HEADER_SIZE */.De) {
            if (currentCluster) {
                const trackData = currentCluster.trackData.get(this.internalTrack.id);
                if (trackData && trackData.startTimestamp > latestTimestamp) {
                    // We're already past the upper bound, no need to keep searching
                    break;
                }
            }
            // Load the header
            let slice = demuxer.reader.requestSliceRange(currentPos, ebml/* MIN_HEADER_SIZE */.De, ebml/* MAX_HEADER_SIZE */.r1);
            if (slice instanceof Promise)
                slice = await slice;
            if (!slice)
                break;
            const elementStartPos = currentPos;
            const elementHeader = (0,ebml/* readElementHeader */.ur)(slice);
            if (!elementHeader
                || (!ebml/* LEVEL_1_EBML_IDS */.VE.includes(elementHeader.id) && elementHeader.id !== ebml/* EBMLId */.Cl.Void)) {
                // There's an element here that shouldn't be here. Might be garbage. In this case, let's
                // try and resync to the next valid element.
                const nextPos = await (0,ebml/* resync */.nE)(demuxer.reader, elementStartPos, ebml/* LEVEL_1_EBML_IDS */.VE, Math.min(segment.elementEndPos ?? Infinity, elementStartPos + MAX_RESYNC_LENGTH));
                if (nextPos) {
                    currentPos = nextPos;
                    continue;
                }
                else {
                    break; // Resync failed
                }
            }
            const id = elementHeader.id;
            let size = elementHeader.size;
            const dataStartPos = slice.filePos;
            if (id === ebml/* EBMLId */.Cl.Cluster) {
                currentCluster = await demuxer.readCluster(elementStartPos, segment);
                // readCluster computes the proper size even if it's undefined in the header, so let's use that instead
                size = currentCluster.elementEndPos - dataStartPos;
                const { blockIndex, correctBlockFound } = getMatchInCluster(currentCluster);
                if (correctBlockFound) {
                    return this.fetchPacketInCluster(currentCluster, blockIndex, options);
                }
                if (blockIndex !== -1) {
                    bestCluster = currentCluster;
                    bestBlockIndex = blockIndex;
                }
            }
            if (size === undefined) {
                // Undefined element size (can happen in livestreamed files). In this case, we need to do some
                // searching to determine the actual size of the element.
                (0,misc/* assert */.vA)(id !== ebml/* EBMLId */.Cl.Cluster); // Undefined cluster sizes are fixed further up
                // Search for the next element at level 0 or 1
                const nextElementPos = await (0,ebml/* searchForNextElementId */.IQ)(demuxer.reader, dataStartPos, ebml/* LEVEL_0_AND_1_EBML_IDS */.K9, segment.elementEndPos);
                size = nextElementPos.pos - dataStartPos;
            }
            const endPos = dataStartPos + size;
            if (segment.elementEndPos === null) {
                // Check the next element. If it's a new segment, we know this segment ends here. The new
                // segment is just ignored, since we're likely in a livestreamed file and thus only care about
                // the first segment.
                let slice = demuxer.reader.requestSliceRange(endPos, ebml/* MIN_HEADER_SIZE */.De, ebml/* MAX_HEADER_SIZE */.r1);
                if (slice instanceof Promise)
                    slice = await slice;
                if (!slice)
                    break;
                const elementId = (0,ebml/* readElementId */.SR)(slice);
                if (elementId === ebml/* EBMLId */.Cl.Segment) {
                    segment.elementEndPos = endPos; // We now know the segment's size
                    break;
                }
            }
            currentPos = endPos;
        }
        // Catch faulty cue points
        if (cuePoint && (!bestCluster || bestCluster.elementStartPos < cuePoint.clusterPosition)) {
            // The cue point lied to us! We found a cue point but no cluster there that satisfied the match. In this
            // case, let's search again but using the cue point before that.
            const previousCuePoint = this.internalTrack.cuePoints[cuePointIndex - 1];
            (0,misc/* assert */.vA)(!previousCuePoint || previousCuePoint.time < cuePoint.time);
            const newSearchTimestamp = previousCuePoint?.time ?? -Infinity;
            return this.performClusterLookup(null, getMatchInCluster, newSearchTimestamp, latestTimestamp, options);
        }
        if (bestCluster) {
            // If we finished looping but didn't find a perfect match, still return the best match we found
            return this.fetchPacketInCluster(bestCluster, bestBlockIndex, options);
        }
        return null;
    }
}
class MatroskaVideoTrackBacking extends MatroskaTrackBacking {
    constructor(internalTrack) {
        super(internalTrack);
        this.decoderConfigPromise = null;
        this.internalTrack = internalTrack;
    }
    getCodec() {
        return this.internalTrack.info.codec;
    }
    getCodedWidth() {
        return this.internalTrack.info.width;
    }
    getCodedHeight() {
        return this.internalTrack.info.height;
    }
    getRotation() {
        return this.internalTrack.info.rotation;
    }
    async getColorSpace() {
        return {
            primaries: this.internalTrack.info.colorSpace?.primaries,
            transfer: this.internalTrack.info.colorSpace?.transfer,
            matrix: this.internalTrack.info.colorSpace?.matrix,
            fullRange: this.internalTrack.info.colorSpace?.fullRange,
        };
    }
    async canBeTransparent() {
        return this.internalTrack.info.alphaMode;
    }
    async getDecoderConfig() {
        if (!this.internalTrack.info.codec) {
            return null;
        }
        return this.decoderConfigPromise ??= (async () => {
            let firstPacket = null;
            const needsPacketForAdditionalInfo = this.internalTrack.info.codec === 'vp9'
                || this.internalTrack.info.codec === 'av1'
                // Packets are in Annex B format:
                || (this.internalTrack.info.codec === 'avc' && !this.internalTrack.info.codecDescription)
                // Packets are in Annex B format:
                || (this.internalTrack.info.codec === 'hevc' && !this.internalTrack.info.codecDescription);
            if (needsPacketForAdditionalInfo) {
                firstPacket = await this.getFirstPacket({});
            }
            return {
                codec: (0,codec/* extractVideoCodecString */.QP)({
                    width: this.internalTrack.info.width,
                    height: this.internalTrack.info.height,
                    codec: this.internalTrack.info.codec,
                    codecDescription: this.internalTrack.info.codecDescription,
                    colorSpace: this.internalTrack.info.colorSpace,
                    avcType: 1, // We don't know better (or do we?) so just assume 'avc1'
                    avcCodecInfo: this.internalTrack.info.codec === 'avc' && firstPacket
                        ? (0,codec_data/* extractAvcDecoderConfigurationRecord */.fH)(firstPacket.data)
                        : null,
                    hevcCodecInfo: this.internalTrack.info.codec === 'hevc' && firstPacket
                        ? (0,codec_data/* extractHevcDecoderConfigurationRecord */.D5)(firstPacket.data)
                        : null,
                    vp9CodecInfo: this.internalTrack.info.codec === 'vp9' && firstPacket
                        ? (0,codec_data/* extractVp9CodecInfoFromPacket */.bs)(firstPacket.data)
                        : null,
                    av1CodecInfo: this.internalTrack.info.codec === 'av1' && firstPacket
                        ? (0,codec_data/* extractAv1CodecInfoFromPacket */.UU)(firstPacket.data)
                        : null,
                }),
                codedWidth: this.internalTrack.info.width,
                codedHeight: this.internalTrack.info.height,
                description: this.internalTrack.info.codecDescription ?? undefined,
                colorSpace: this.internalTrack.info.colorSpace ?? undefined,
            };
        })();
    }
}
class MatroskaAudioTrackBacking extends MatroskaTrackBacking {
    constructor(internalTrack) {
        super(internalTrack);
        this.decoderConfig = null;
        this.internalTrack = internalTrack;
    }
    getCodec() {
        return this.internalTrack.info.codec;
    }
    getNumberOfChannels() {
        return this.internalTrack.info.numberOfChannels;
    }
    getSampleRate() {
        return this.internalTrack.info.sampleRate;
    }
    async getDecoderConfig() {
        if (!this.internalTrack.info.codec) {
            return null;
        }
        return this.decoderConfig ??= {
            codec: (0,codec/* extractAudioCodecString */.X0)({
                codec: this.internalTrack.info.codec,
                codecDescription: this.internalTrack.info.codecDescription,
                aacCodecInfo: this.internalTrack.info.aacCodecInfo,
            }),
            numberOfChannels: this.internalTrack.info.numberOfChannels,
            sampleRate: this.internalTrack.info.sampleRate,
            description: this.internalTrack.info.codecDescription ?? undefined,
        };
    }
}

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/shared/mp3-misc.js
var mp3_misc = __webpack_require__(2788);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/id3.js
var id3 = __webpack_require__(7576);
;// ./node_modules/mediabunny/dist/modules/src/mp3/mp3-reader.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */


const readNextMp3FrameHeader = async (reader, startPos, until) => {
    let currentPos = startPos;
    while (until === null || currentPos < until) {
        let slice = reader.requestSlice(currentPos, mp3_misc/* FRAME_HEADER_SIZE */.Yq);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice)
            break;
        const word = (0,src_reader/* readU32Be */.cN)(slice);
        const result = (0,mp3_misc/* readMp3FrameHeader */.P8)(word, reader.fileSize !== null ? reader.fileSize - currentPos : null);
        if (result.header) {
            return { header: result.header, startPos: currentPos };
        }
        currentPos += result.bytesAdvanced;
    }
    return null;
};

;// ./node_modules/mediabunny/dist/modules/src/mp3/mp3-demuxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */









class Mp3Demuxer extends demuxer/* Demuxer */.B {
    constructor(input) {
        super(input);
        this.metadataPromise = null;
        this.firstFrameHeader = null;
        this.loadedSamples = []; // All samples from the start of the file to lastLoadedPos
        this.metadataTags = null;
        this.tracks = [];
        this.readingMutex = new misc/* AsyncMutex */.aD();
        this.lastSampleLoaded = false;
        this.lastLoadedPos = 0;
        this.nextTimestampInSamples = 0;
        this.reader = input._reader;
    }
    async readMetadata() {
        return this.metadataPromise ??= (async () => {
            // Keep loading until we find the first frame header
            while (!this.firstFrameHeader && !this.lastSampleLoaded) {
                await this.advanceReader();
            }
            if (!this.firstFrameHeader) {
                throw new Error('No valid MP3 frame found.');
            }
            this.tracks = [new input_track/* InputAudioTrack */.Yi(this.input, new Mp3AudioTrackBacking(this))];
        })();
    }
    async advanceReader() {
        if (this.lastLoadedPos === 0) {
            // Let's skip all ID3v2 tags at the start of the file
            while (true) {
                let slice = this.reader.requestSlice(this.lastLoadedPos, id3/* ID3_V2_HEADER_SIZE */.sY);
                if (slice instanceof Promise)
                    slice = await slice;
                if (!slice) {
                    this.lastSampleLoaded = true;
                    return;
                }
                const id3V2Header = (0,id3/* readId3V2Header */.IX)(slice);
                if (!id3V2Header) {
                    break;
                }
                this.lastLoadedPos = slice.filePos + id3V2Header.size;
            }
        }
        const result = await readNextMp3FrameHeader(this.reader, this.lastLoadedPos, this.reader.fileSize);
        if (!result) {
            this.lastSampleLoaded = true;
            return;
        }
        const header = result.header;
        this.lastLoadedPos = result.startPos + header.totalSize - 1; // -1 in case the frame is 1 byte too short
        const xingOffset = (0,mp3_misc/* getXingOffset */.EZ)(header.mpegVersionId, header.channel);
        let slice = this.reader.requestSlice(result.startPos + xingOffset, 4);
        if (slice instanceof Promise)
            slice = await slice;
        if (slice) {
            const word = (0,src_reader/* readU32Be */.cN)(slice);
            const isXing = word === mp3_misc/* XING */.hY || word === mp3_misc/* INFO */.rD;
            if (isXing) {
                // There's no actual audio data in this frame, so let's skip it
                return;
            }
        }
        if (!this.firstFrameHeader) {
            this.firstFrameHeader = header;
        }
        if (header.sampleRate !== this.firstFrameHeader.sampleRate) {
            console.warn(`MP3 changed sample rate mid-file: ${this.firstFrameHeader.sampleRate} Hz to ${header.sampleRate} Hz.`
                + ` Might be a bug, so please report this file.`);
        }
        const sampleDuration = header.audioSamplesInFrame / this.firstFrameHeader.sampleRate;
        const sample = {
            timestamp: this.nextTimestampInSamples / this.firstFrameHeader.sampleRate,
            duration: sampleDuration,
            dataStart: result.startPos,
            dataSize: header.totalSize,
        };
        this.loadedSamples.push(sample);
        this.nextTimestampInSamples += header.audioSamplesInFrame;
        return;
    }
    async getMimeType() {
        return 'audio/mpeg';
    }
    async getTracks() {
        await this.readMetadata();
        return this.tracks;
    }
    async computeDuration() {
        await this.readMetadata();
        const track = this.tracks[0];
        (0,misc/* assert */.vA)(track);
        return track.computeDuration();
    }
    async getMetadataTags() {
        const release = await this.readingMutex.acquire();
        try {
            await this.readMetadata();
            if (this.metadataTags) {
                return this.metadataTags;
            }
            this.metadataTags = {};
            let currentPos = 0;
            let id3V2HeaderFound = false;
            while (true) {
                let headerSlice = this.reader.requestSlice(currentPos, id3/* ID3_V2_HEADER_SIZE */.sY);
                if (headerSlice instanceof Promise)
                    headerSlice = await headerSlice;
                if (!headerSlice)
                    break;
                const id3V2Header = (0,id3/* readId3V2Header */.IX)(headerSlice);
                if (!id3V2Header) {
                    break;
                }
                id3V2HeaderFound = true;
                let contentSlice = this.reader.requestSlice(headerSlice.filePos, id3V2Header.size);
                if (contentSlice instanceof Promise)
                    contentSlice = await contentSlice;
                if (!contentSlice)
                    break;
                (0,id3/* parseId3V2Tag */.cG)(contentSlice, id3V2Header, this.metadataTags);
                currentPos = headerSlice.filePos + id3V2Header.size;
            }
            if (!id3V2HeaderFound && this.reader.fileSize !== null && this.reader.fileSize >= id3/* ID3_V1_TAG_SIZE */.aU) {
                // Try reading an ID3v1 tag at the end of the file
                let slice = this.reader.requestSlice(this.reader.fileSize - id3/* ID3_V1_TAG_SIZE */.aU, id3/* ID3_V1_TAG_SIZE */.aU);
                if (slice instanceof Promise)
                    slice = await slice;
                (0,misc/* assert */.vA)(slice);
                const tag = (0,src_reader/* readAscii */.IT)(slice, 3);
                if (tag === 'TAG') {
                    (0,id3/* parseId3V1Tag */.p_)(slice, this.metadataTags);
                }
            }
            return this.metadataTags;
        }
        finally {
            release();
        }
    }
}
class Mp3AudioTrackBacking {
    constructor(demuxer) {
        this.demuxer = demuxer;
    }
    getId() {
        return 1;
    }
    getNumber() {
        return 1;
    }
    async getFirstTimestamp() {
        return 0;
    }
    getTimeResolution() {
        (0,misc/* assert */.vA)(this.demuxer.firstFrameHeader);
        return this.demuxer.firstFrameHeader.sampleRate / this.demuxer.firstFrameHeader.audioSamplesInFrame;
    }
    async computeDuration() {
        const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
        return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    getName() {
        return null;
    }
    getLanguageCode() {
        return misc/* UNDETERMINED_LANGUAGE */.IR;
    }
    getCodec() {
        return 'mp3';
    }
    getInternalCodecId() {
        return null;
    }
    getNumberOfChannels() {
        (0,misc/* assert */.vA)(this.demuxer.firstFrameHeader);
        return this.demuxer.firstFrameHeader.channel === 3 ? 1 : 2;
    }
    getSampleRate() {
        (0,misc/* assert */.vA)(this.demuxer.firstFrameHeader);
        return this.demuxer.firstFrameHeader.sampleRate;
    }
    getDisposition() {
        return {
            ...metadata/* DEFAULT_TRACK_DISPOSITION */.gM,
        };
    }
    async getDecoderConfig() {
        (0,misc/* assert */.vA)(this.demuxer.firstFrameHeader);
        return {
            codec: 'mp3',
            numberOfChannels: this.demuxer.firstFrameHeader.channel === 3 ? 1 : 2,
            sampleRate: this.demuxer.firstFrameHeader.sampleRate,
        };
    }
    async getPacketAtIndex(sampleIndex, options) {
        if (sampleIndex === -1) {
            return null;
        }
        const rawSample = this.demuxer.loadedSamples[sampleIndex];
        if (!rawSample) {
            return null;
        }
        let data;
        if (options.metadataOnly) {
            data = src_packet/* PLACEHOLDER_DATA */.T;
        }
        else {
            let slice = this.demuxer.reader.requestSlice(rawSample.dataStart, rawSample.dataSize);
            if (slice instanceof Promise)
                slice = await slice;
            if (!slice) {
                return null; // Data didn't fit into the rest of the file
            }
            data = (0,src_reader/* readBytes */.io)(slice, rawSample.dataSize);
        }
        return new src_packet/* EncodedPacket */.Z(data, 'key', rawSample.timestamp, rawSample.duration, sampleIndex, rawSample.dataSize);
    }
    getFirstPacket(options) {
        return this.getPacketAtIndex(0, options);
    }
    async getNextPacket(packet, options) {
        const release = await this.demuxer.readingMutex.acquire();
        try {
            const sampleIndex = (0,misc/* binarySearchExact */.pl)(this.demuxer.loadedSamples, packet.timestamp, x => x.timestamp);
            if (sampleIndex === -1) {
                throw new Error('Packet was not created from this track.');
            }
            const nextIndex = sampleIndex + 1;
            // Ensure the next sample exists
            while (nextIndex >= this.demuxer.loadedSamples.length
                && !this.demuxer.lastSampleLoaded) {
                await this.demuxer.advanceReader();
            }
            return this.getPacketAtIndex(nextIndex, options);
        }
        finally {
            release();
        }
    }
    async getPacket(timestamp, options) {
        const release = await this.demuxer.readingMutex.acquire();
        try {
            while (true) {
                const index = (0,misc/* binarySearchLessOrEqual */.eE)(this.demuxer.loadedSamples, timestamp, x => x.timestamp);
                if (index === -1 && this.demuxer.loadedSamples.length > 0) {
                    // We're before the first sample
                    return null;
                }
                if (this.demuxer.lastSampleLoaded) {
                    // All data is loaded, return what we found
                    return this.getPacketAtIndex(index, options);
                }
                if (index >= 0 && index + 1 < this.demuxer.loadedSamples.length) {
                    // The next packet also exists, we're done
                    return this.getPacketAtIndex(index, options);
                }
                // Otherwise, keep loading data
                await this.demuxer.advanceReader();
            }
        }
        finally {
            release();
        }
    }
    getKeyPacket(timestamp, options) {
        return this.getPacket(timestamp, options);
    }
    getNextKeyPacket(packet, options) {
        return this.getNextPacket(packet, options);
    }
}

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/ogg/ogg-misc.js
var ogg_misc = __webpack_require__(9730);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/ogg/ogg-reader.js
var ogg_reader = __webpack_require__(9841);
;// ./node_modules/mediabunny/dist/modules/src/ogg/ogg-demuxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */










class OggDemuxer extends demuxer/* Demuxer */.B {
    constructor(input) {
        super(input);
        this.metadataPromise = null;
        this.bitstreams = [];
        this.tracks = [];
        this.metadataTags = {};
        this.reader = input._reader;
    }
    async readMetadata() {
        return this.metadataPromise ??= (async () => {
            let currentPos = 0;
            while (true) {
                let slice = this.reader.requestSliceRange(currentPos, ogg_reader/* MIN_PAGE_HEADER_SIZE */.b0, ogg_reader/* MAX_PAGE_HEADER_SIZE */.H9);
                if (slice instanceof Promise)
                    slice = await slice;
                if (!slice)
                    break;
                const page = (0,ogg_reader/* readPageHeader */.BF)(slice);
                if (!page) {
                    break;
                }
                const isBos = !!(page.headerType & 0x02);
                if (!isBos) {
                    // All bos pages for all bitstreams are required to be at the start, so if the page is not bos then
                    // we know we've seen all bitstreams (minus chaining)
                    break;
                }
                this.bitstreams.push({
                    serialNumber: page.serialNumber,
                    bosPage: page,
                    description: null,
                    numberOfChannels: -1,
                    sampleRate: -1,
                    codecInfo: {
                        codec: null,
                        vorbisInfo: null,
                        opusInfo: null,
                    },
                    lastMetadataPacket: null,
                });
                currentPos = page.headerStartPos + page.totalSize;
            }
            for (const bitstream of this.bitstreams) {
                const firstPacket = await this.readPacket(bitstream.bosPage, 0);
                if (!firstPacket) {
                    continue;
                }
                if (
                // Check for Vorbis
                firstPacket.data.byteLength >= 7
                    && firstPacket.data[0] === 0x01 // Packet type 1 = identification header
                    && firstPacket.data[1] === 0x76 // 'v'
                    && firstPacket.data[2] === 0x6f // 'o'
                    && firstPacket.data[3] === 0x72 // 'r'
                    && firstPacket.data[4] === 0x62 // 'b'
                    && firstPacket.data[5] === 0x69 // 'i'
                    && firstPacket.data[6] === 0x73 // 's'
                ) {
                    await this.readVorbisMetadata(firstPacket, bitstream);
                }
                else if (
                // Check for Opus
                firstPacket.data.byteLength >= 8
                    && firstPacket.data[0] === 0x4f // 'O'
                    && firstPacket.data[1] === 0x70 // 'p'
                    && firstPacket.data[2] === 0x75 // 'u'
                    && firstPacket.data[3] === 0x73 // 's'
                    && firstPacket.data[4] === 0x48 // 'H'
                    && firstPacket.data[5] === 0x65 // 'e'
                    && firstPacket.data[6] === 0x61 // 'a'
                    && firstPacket.data[7] === 0x64 // 'd'
                ) {
                    await this.readOpusMetadata(firstPacket, bitstream);
                }
                if (bitstream.codecInfo.codec !== null) {
                    this.tracks.push(new input_track/* InputAudioTrack */.Yi(this.input, new OggAudioTrackBacking(bitstream, this)));
                }
            }
        })();
    }
    async readVorbisMetadata(firstPacket, bitstream) {
        let nextPacketPosition = await this.findNextPacketStart(firstPacket);
        if (!nextPacketPosition) {
            return;
        }
        const secondPacket = await this.readPacket(nextPacketPosition.startPage, nextPacketPosition.startSegmentIndex);
        if (!secondPacket) {
            return;
        }
        nextPacketPosition = await this.findNextPacketStart(secondPacket);
        if (!nextPacketPosition) {
            return;
        }
        const thirdPacket = await this.readPacket(nextPacketPosition.startPage, nextPacketPosition.startSegmentIndex);
        if (!thirdPacket) {
            return;
        }
        if (secondPacket.data[0] !== 0x03 || thirdPacket.data[0] !== 0x05) {
            return;
        }
        const lacingValues = [];
        const addBytesToSegmentTable = (bytes) => {
            while (true) {
                lacingValues.push(Math.min(255, bytes));
                if (bytes < 255) {
                    break;
                }
                bytes -= 255;
            }
        };
        addBytesToSegmentTable(firstPacket.data.length);
        addBytesToSegmentTable(secondPacket.data.length);
        // We don't add the last packet to the segment table, as it is assumed to be whatever bytes remain
        const description = new Uint8Array(1 + lacingValues.length
            + firstPacket.data.length + secondPacket.data.length + thirdPacket.data.length);
        description[0] = 2; // Num entries in the segment table
        description.set(lacingValues, 1);
        description.set(firstPacket.data, 1 + lacingValues.length);
        description.set(secondPacket.data, 1 + lacingValues.length + firstPacket.data.length);
        description.set(thirdPacket.data, 1 + lacingValues.length + firstPacket.data.length + secondPacket.data.length);
        bitstream.codecInfo.codec = 'vorbis';
        bitstream.description = description;
        bitstream.lastMetadataPacket = thirdPacket;
        const view = (0,misc/* toDataView */.Zc)(firstPacket.data);
        bitstream.numberOfChannels = view.getUint8(11);
        bitstream.sampleRate = view.getUint32(12, true);
        const blockSizeByte = view.getUint8(28);
        bitstream.codecInfo.vorbisInfo = {
            blocksizes: [
                1 << (blockSizeByte & 0xf),
                1 << (blockSizeByte >> 4),
            ],
            modeBlockflags: (0,codec_data/* parseModesFromVorbisSetupPacket */.Co)(thirdPacket.data).modeBlockflags,
        };
        (0,codec_data/* readVorbisComments */.Oc)(secondPacket.data.subarray(7), this.metadataTags); // Skip header type and 'vorbis'
    }
    async readOpusMetadata(firstPacket, bitstream) {
        // From https://datatracker.ietf.org/doc/html/rfc7845#section-5:
        // "An Ogg Opus logical stream contains exactly two mandatory header packets: an identification header and a
        // comment header."
        const nextPacketPosition = await this.findNextPacketStart(firstPacket);
        if (!nextPacketPosition) {
            return;
        }
        const secondPacket = await this.readPacket(nextPacketPosition.startPage, nextPacketPosition.startSegmentIndex);
        if (!secondPacket) {
            return;
        }
        bitstream.codecInfo.codec = 'opus';
        bitstream.description = firstPacket.data;
        bitstream.lastMetadataPacket = secondPacket;
        const header = (0,codec_data/* parseOpusIdentificationHeader */.Qf)(firstPacket.data);
        bitstream.numberOfChannels = header.outputChannelCount;
        bitstream.sampleRate = codec/* OPUS_SAMPLE_RATE */.yo; // Always the same
        bitstream.codecInfo.opusInfo = {
            preSkip: header.preSkip,
        };
        (0,codec_data/* readVorbisComments */.Oc)(secondPacket.data.subarray(8), this.metadataTags); // Skip 'OpusTags'
    }
    async readPacket(startPage, startSegmentIndex) {
        (0,misc/* assert */.vA)(startSegmentIndex < startPage.lacingValues.length);
        let startDataOffset = 0;
        for (let i = 0; i < startSegmentIndex; i++) {
            startDataOffset += startPage.lacingValues[i];
        }
        let currentPage = startPage;
        let currentDataOffset = startDataOffset;
        let currentSegmentIndex = startSegmentIndex;
        const chunks = [];
        outer: while (true) {
            // Load the entire page data
            let pageSlice = this.reader.requestSlice(currentPage.dataStartPos, currentPage.dataSize);
            if (pageSlice instanceof Promise)
                pageSlice = await pageSlice;
            (0,misc/* assert */.vA)(pageSlice);
            const pageData = (0,src_reader/* readBytes */.io)(pageSlice, currentPage.dataSize);
            while (true) {
                if (currentSegmentIndex === currentPage.lacingValues.length) {
                    chunks.push(pageData.subarray(startDataOffset, currentDataOffset));
                    break;
                }
                const lacingValue = currentPage.lacingValues[currentSegmentIndex];
                currentDataOffset += lacingValue;
                if (lacingValue < 255) {
                    chunks.push(pageData.subarray(startDataOffset, currentDataOffset));
                    break outer;
                }
                currentSegmentIndex++;
            }
            // The packet extends to the next page; let's find it
            let currentPos = currentPage.headerStartPos + currentPage.totalSize;
            while (true) {
                let headerSlice = this.reader.requestSliceRange(currentPos, ogg_reader/* MIN_PAGE_HEADER_SIZE */.b0, ogg_reader/* MAX_PAGE_HEADER_SIZE */.H9);
                if (headerSlice instanceof Promise)
                    headerSlice = await headerSlice;
                if (!headerSlice) {
                    return null;
                }
                const nextPage = (0,ogg_reader/* readPageHeader */.BF)(headerSlice);
                if (!nextPage) {
                    return null;
                }
                currentPage = nextPage;
                if (currentPage.serialNumber === startPage.serialNumber) {
                    break;
                }
                currentPos = currentPage.headerStartPos + currentPage.totalSize;
            }
            startDataOffset = 0;
            currentDataOffset = 0;
            currentSegmentIndex = 0;
        }
        const totalPacketSize = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
        if (totalPacketSize === 0) {
            return null; // Invalid packet, treat it as end of stream
        }
        const packetData = new Uint8Array(totalPacketSize);
        let offset = 0;
        for (let i = 0; i < chunks.length; i++) {
            const chunk = chunks[i];
            packetData.set(chunk, offset);
            offset += chunk.length;
        }
        return {
            data: packetData,
            endPage: currentPage,
            endSegmentIndex: currentSegmentIndex,
        };
    }
    async findNextPacketStart(lastPacket) {
        // If there's another segment in the same page, return it
        if (lastPacket.endSegmentIndex < lastPacket.endPage.lacingValues.length - 1) {
            return { startPage: lastPacket.endPage, startSegmentIndex: lastPacket.endSegmentIndex + 1 };
        }
        const isEos = !!(lastPacket.endPage.headerType & 0x04);
        if (isEos) {
            // The page is marked as the last page of the logical bitstream, so we won't find anything beyond it
            return null;
        }
        // Otherwise, search for the next page belonging to the same bitstream
        let currentPos = lastPacket.endPage.headerStartPos + lastPacket.endPage.totalSize;
        while (true) {
            let slice = this.reader.requestSliceRange(currentPos, ogg_reader/* MIN_PAGE_HEADER_SIZE */.b0, ogg_reader/* MAX_PAGE_HEADER_SIZE */.H9);
            if (slice instanceof Promise)
                slice = await slice;
            if (!slice) {
                return null;
            }
            const nextPage = (0,ogg_reader/* readPageHeader */.BF)(slice);
            if (!nextPage) {
                return null;
            }
            if (nextPage.serialNumber === lastPacket.endPage.serialNumber) {
                return { startPage: nextPage, startSegmentIndex: 0 };
            }
            currentPos = nextPage.headerStartPos + nextPage.totalSize;
        }
    }
    async getMimeType() {
        await this.readMetadata();
        const codecStrings = await Promise.all(this.tracks.map(x => x.getCodecParameterString()));
        return (0,ogg_misc/* buildOggMimeType */.Ob)({
            codecStrings: codecStrings.filter(Boolean),
        });
    }
    async getTracks() {
        await this.readMetadata();
        return this.tracks;
    }
    async computeDuration() {
        const tracks = await this.getTracks();
        const trackDurations = await Promise.all(tracks.map(x => x.computeDuration()));
        return Math.max(0, ...trackDurations);
    }
    async getMetadataTags() {
        await this.readMetadata();
        return this.metadataTags;
    }
}
class OggAudioTrackBacking {
    constructor(bitstream, demuxer) {
        this.bitstream = bitstream;
        this.demuxer = demuxer;
        this.encodedPacketToMetadata = new WeakMap();
        this.sequentialScanCache = [];
        this.sequentialScanMutex = new misc/* AsyncMutex */.aD();
        // Opus always uses a fixed sample rate for its internal calculations, even if the actual rate is different
        this.internalSampleRate = bitstream.codecInfo.codec === 'opus'
            ? codec/* OPUS_SAMPLE_RATE */.yo
            : bitstream.sampleRate;
    }
    getId() {
        return this.bitstream.serialNumber;
    }
    getNumber() {
        // All Ogg tracks are audio, so the track's index + 1 is its number
        const index = this.demuxer.tracks.findIndex(t => t._backing.bitstream === this.bitstream);
        (0,misc/* assert */.vA)(index !== -1);
        return index + 1;
    }
    getNumberOfChannels() {
        return this.bitstream.numberOfChannels;
    }
    getSampleRate() {
        return this.bitstream.sampleRate;
    }
    getTimeResolution() {
        return this.bitstream.sampleRate;
    }
    getCodec() {
        return this.bitstream.codecInfo.codec;
    }
    getInternalCodecId() {
        return null;
    }
    async getDecoderConfig() {
        (0,misc/* assert */.vA)(this.bitstream.codecInfo.codec);
        return {
            codec: this.bitstream.codecInfo.codec,
            numberOfChannels: this.bitstream.numberOfChannels,
            sampleRate: this.bitstream.sampleRate,
            description: this.bitstream.description ?? undefined,
        };
    }
    getName() {
        return null;
    }
    getLanguageCode() {
        return misc/* UNDETERMINED_LANGUAGE */.IR;
    }
    getDisposition() {
        return {
            ...metadata/* DEFAULT_TRACK_DISPOSITION */.gM,
        };
    }
    async getFirstTimestamp() {
        return 0;
    }
    async computeDuration() {
        const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
        return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    granulePositionToTimestampInSamples(granulePosition) {
        if (this.bitstream.codecInfo.codec === 'opus') {
            (0,misc/* assert */.vA)(this.bitstream.codecInfo.opusInfo);
            return granulePosition - this.bitstream.codecInfo.opusInfo.preSkip;
        }
        return granulePosition;
    }
    createEncodedPacketFromOggPacket(packet, additional, options) {
        if (!packet) {
            return null;
        }
        const { durationInSamples, vorbisBlockSize } = (0,ogg_misc/* extractSampleMetadata */.nL)(packet.data, this.bitstream.codecInfo, additional.vorbisLastBlocksize);
        const encodedPacket = new src_packet/* EncodedPacket */.Z(options.metadataOnly ? src_packet/* PLACEHOLDER_DATA */.T : packet.data, 'key', Math.max(0, additional.timestampInSamples) / this.internalSampleRate, durationInSamples / this.internalSampleRate, packet.endPage.headerStartPos + packet.endSegmentIndex, packet.data.byteLength);
        this.encodedPacketToMetadata.set(encodedPacket, {
            packet,
            timestampInSamples: additional.timestampInSamples,
            durationInSamples,
            vorbisLastBlockSize: additional.vorbisLastBlocksize,
            vorbisBlockSize,
        });
        return encodedPacket;
    }
    async getFirstPacket(options) {
        (0,misc/* assert */.vA)(this.bitstream.lastMetadataPacket);
        const packetPosition = await this.demuxer.findNextPacketStart(this.bitstream.lastMetadataPacket);
        if (!packetPosition) {
            return null;
        }
        let timestampInSamples = 0;
        if (this.bitstream.codecInfo.codec === 'opus') {
            (0,misc/* assert */.vA)(this.bitstream.codecInfo.opusInfo);
            timestampInSamples -= this.bitstream.codecInfo.opusInfo.preSkip;
        }
        const packet = await this.demuxer.readPacket(packetPosition.startPage, packetPosition.startSegmentIndex);
        return this.createEncodedPacketFromOggPacket(packet, {
            timestampInSamples,
            vorbisLastBlocksize: null,
        }, options);
    }
    async getNextPacket(prevPacket, options) {
        const prevMetadata = this.encodedPacketToMetadata.get(prevPacket);
        if (!prevMetadata) {
            throw new Error('Packet was not created from this track.');
        }
        const packetPosition = await this.demuxer.findNextPacketStart(prevMetadata.packet);
        if (!packetPosition) {
            return null;
        }
        const timestampInSamples = prevMetadata.timestampInSamples + prevMetadata.durationInSamples;
        const packet = await this.demuxer.readPacket(packetPosition.startPage, packetPosition.startSegmentIndex);
        return this.createEncodedPacketFromOggPacket(packet, {
            timestampInSamples,
            vorbisLastBlocksize: prevMetadata.vorbisBlockSize,
        }, options);
    }
    async getPacket(timestamp, options) {
        if (this.demuxer.reader.fileSize === null) {
            // No file size known, can't do binary search, but fall back to sequential algo instead
            return this.getPacketSequential(timestamp, options);
        }
        const timestampInSamples = (0,misc/* roundIfAlmostInteger */.aI)(timestamp * this.internalSampleRate);
        if (timestampInSamples === 0) {
            // Fast path for timestamp 0 - avoids binary search when playing back from the start
            return this.getFirstPacket(options);
        }
        if (timestampInSamples < 0) {
            // There's nothing here
            return null;
        }
        (0,misc/* assert */.vA)(this.bitstream.lastMetadataPacket);
        const startPosition = await this.demuxer.findNextPacketStart(this.bitstream.lastMetadataPacket);
        if (!startPosition) {
            return null;
        }
        let lowPage = startPosition.startPage;
        let high = this.demuxer.reader.fileSize;
        const lowPages = [lowPage];
        // First, let's perform a binary serach (bisection search) on the file to find the approximate page where
        // we'll find the packet. We want to find a page whose end packet position is less than or equal to the
        // packet position we're searching for.
        // Outer loop: Does the binary serach
        outer: while (lowPage.headerStartPos + lowPage.totalSize < high) {
            const low = lowPage.headerStartPos;
            const mid = Math.floor((low + high) / 2);
            let searchStartPos = mid;
            // Inner loop: Does a linear forward scan if the page cannot be found immediately
            while (true) {
                const until = Math.min(searchStartPos + ogg_reader/* MAX_PAGE_SIZE */.H4, high - ogg_reader/* MIN_PAGE_HEADER_SIZE */.b0);
                let searchSlice = this.demuxer.reader.requestSlice(searchStartPos, until - searchStartPos);
                if (searchSlice instanceof Promise)
                    searchSlice = await searchSlice;
                (0,misc/* assert */.vA)(searchSlice);
                const found = (0,ogg_reader/* findNextPageHeader */.v5)(searchSlice, until);
                if (!found) {
                    high = mid + ogg_reader/* MIN_PAGE_HEADER_SIZE */.b0;
                    continue outer;
                }
                let headerSlice = this.demuxer.reader.requestSliceRange(searchSlice.filePos, ogg_reader/* MIN_PAGE_HEADER_SIZE */.b0, ogg_reader/* MAX_PAGE_HEADER_SIZE */.H9);
                if (headerSlice instanceof Promise)
                    headerSlice = await headerSlice;
                (0,misc/* assert */.vA)(headerSlice);
                const page = (0,ogg_reader/* readPageHeader */.BF)(headerSlice);
                (0,misc/* assert */.vA)(page);
                let pageValid = false;
                if (page.serialNumber === this.bitstream.serialNumber) {
                    // Serial numbers are basically random numbers, and the chance of finding a fake page with
                    // matching serial number is astronomically low, so we can be pretty sure this page is legit.
                    pageValid = true;
                }
                else {
                    let pageSlice = this.demuxer.reader.requestSlice(page.headerStartPos, page.totalSize);
                    if (pageSlice instanceof Promise)
                        pageSlice = await pageSlice;
                    (0,misc/* assert */.vA)(pageSlice);
                    // Validate the page by checking checksum
                    const bytes = (0,src_reader/* readBytes */.io)(pageSlice, page.totalSize);
                    const crc = (0,ogg_misc/* computeOggPageCrc */._S)(bytes);
                    pageValid = crc === page.checksum;
                }
                if (!pageValid) {
                    // Keep searching for a valid page
                    searchStartPos = page.headerStartPos + 4; // 'OggS' is 4 bytes
                    continue;
                }
                if (pageValid && page.serialNumber !== this.bitstream.serialNumber) {
                    // Page is valid but from a different bitstream, so keep searching forward until we find one
                    // belonging to the our bitstream
                    searchStartPos = page.headerStartPos + page.totalSize;
                    continue;
                }
                const isContinuationPage = page.granulePosition === -1;
                if (isContinuationPage) {
                    // No packet ends on this page - keep looking
                    searchStartPos = page.headerStartPos + page.totalSize;
                    continue;
                }
                // The page is valid and belongs to our bitstream; let's check its granule position to see where we
                // need to take the bisection search.
                if (this.granulePositionToTimestampInSamples(page.granulePosition) > timestampInSamples) {
                    high = page.headerStartPos;
                }
                else {
                    lowPage = page;
                    lowPages.push(page);
                }
                continue outer;
            }
        }
        // Now we have the last page with a packet position <= the packet position we're looking for, but there
        // might be multiple pages with the packet position, in which case we actually need to find the first of
        // such pages. We'll do this in two steps: First, let's find the latest page we know with an earlier packet
        // position, and then linear scan ourselves forward until we find the correct page.
        let lowerPage = startPosition.startPage;
        for (const otherLowPage of lowPages) {
            if (otherLowPage.granulePosition === lowPage.granulePosition) {
                break;
            }
            if (!lowerPage || otherLowPage.headerStartPos > lowerPage.headerStartPos) {
                lowerPage = otherLowPage;
            }
        }
        let currentPage = lowerPage;
        // Keep track of the pages we traversed, we need these later for backwards seeking
        const previousPages = [currentPage];
        while (true) {
            // This loop must terminate as we'll eventually reach lowPage
            if (currentPage.serialNumber === this.bitstream.serialNumber
                && currentPage.granulePosition === lowPage.granulePosition) {
                break;
            }
            const nextPos = currentPage.headerStartPos + currentPage.totalSize;
            let slice = this.demuxer.reader.requestSliceRange(nextPos, ogg_reader/* MIN_PAGE_HEADER_SIZE */.b0, ogg_reader/* MAX_PAGE_HEADER_SIZE */.H9);
            if (slice instanceof Promise)
                slice = await slice;
            (0,misc/* assert */.vA)(slice);
            const nextPage = (0,ogg_reader/* readPageHeader */.BF)(slice);
            (0,misc/* assert */.vA)(nextPage);
            currentPage = nextPage;
            if (currentPage.serialNumber === this.bitstream.serialNumber) {
                previousPages.push(currentPage);
            }
        }
        (0,misc/* assert */.vA)(currentPage.granulePosition !== -1);
        let currentSegmentIndex = null;
        let currentTimestampInSamples;
        let currentTimestampIsCorrect;
        // These indicate the end position of the packet that the granule position belongs to
        let endPage = currentPage;
        let endSegmentIndex = 0;
        if (currentPage.headerStartPos === startPosition.startPage.headerStartPos) {
            currentTimestampInSamples = this.granulePositionToTimestampInSamples(0);
            currentTimestampIsCorrect = true;
            currentSegmentIndex = 0;
        }
        else {
            currentTimestampInSamples = 0; // Placeholder value! We'll refine it once we can
            currentTimestampIsCorrect = false;
            // Find the segment index of the next packet
            for (let i = currentPage.lacingValues.length - 1; i >= 0; i--) {
                const value = currentPage.lacingValues[i];
                if (value < 255) {
                    // We know the last packet ended at i, so the next one starts at i + 1
                    currentSegmentIndex = i + 1;
                    break;
                }
            }
            // This must hold: Since this page has a granule position set, that means there must be a packet that
            // ends in this page.
            if (currentSegmentIndex === null) {
                throw new Error('Invalid page with granule position: no packets end on this page.');
            }
            endSegmentIndex = currentSegmentIndex - 1;
            const pseudopacket = {
                data: src_packet/* PLACEHOLDER_DATA */.T,
                endPage,
                endSegmentIndex,
            };
            const nextPosition = await this.demuxer.findNextPacketStart(pseudopacket);
            if (nextPosition) {
                // Let's rewind a single step (packet) - this previous packet ensures that we'll correctly compute
                // the duration for the packet we're looking for.
                const endPosition = findPreviousPacketEndPosition(previousPages, currentPage, currentSegmentIndex);
                (0,misc/* assert */.vA)(endPosition);
                const startPosition = findPacketStartPosition(previousPages, endPosition.page, endPosition.segmentIndex);
                if (startPosition) {
                    currentPage = startPosition.page;
                    currentSegmentIndex = startPosition.segmentIndex;
                }
            }
            else {
                // There is no next position, which means we're looking for the last packet in the bitstream. The
                // granule position on the last page tends to be fucky, so let's instead start the search on the
                // page before that. So let's loop until we find a packet that ends in a previous page.
                while (true) {
                    const endPosition = findPreviousPacketEndPosition(previousPages, currentPage, currentSegmentIndex);
                    if (!endPosition) {
                        break;
                    }
                    const startPosition = findPacketStartPosition(previousPages, endPosition.page, endPosition.segmentIndex);
                    if (!startPosition) {
                        break;
                    }
                    currentPage = startPosition.page;
                    currentSegmentIndex = startPosition.segmentIndex;
                    if (endPosition.page.headerStartPos !== endPage.headerStartPos) {
                        endPage = endPosition.page;
                        endSegmentIndex = endPosition.segmentIndex;
                        break;
                    }
                }
            }
        }
        let lastEncodedPacket = null;
        let lastEncodedPacketMetadata = null;
        // Alright, now it's time for the final, granular seek: We keep iterating over packets until we've found the
        // one with the correct timestamp - i.e., the last one with a timestamp <= the timestamp we're looking for.
        while (currentPage !== null) {
            (0,misc/* assert */.vA)(currentSegmentIndex !== null);
            const packet = await this.demuxer.readPacket(currentPage, currentSegmentIndex);
            if (!packet) {
                break;
            }
            // We might need to skip the packet if it's a metadata one
            const skipPacket = currentPage.headerStartPos === startPosition.startPage.headerStartPos
                && currentSegmentIndex < startPosition.startSegmentIndex;
            if (!skipPacket) {
                let encodedPacket = this.createEncodedPacketFromOggPacket(packet, {
                    timestampInSamples: currentTimestampInSamples,
                    vorbisLastBlocksize: lastEncodedPacketMetadata?.vorbisBlockSize ?? null,
                }, options);
                (0,misc/* assert */.vA)(encodedPacket);
                let encodedPacketMetadata = this.encodedPacketToMetadata.get(encodedPacket);
                (0,misc/* assert */.vA)(encodedPacketMetadata);
                if (!currentTimestampIsCorrect
                    && packet.endPage.headerStartPos === endPage.headerStartPos
                    && packet.endSegmentIndex === endSegmentIndex) {
                    // We know this packet end timestamp can be derived from the page's granule position
                    currentTimestampInSamples = this.granulePositionToTimestampInSamples(currentPage.granulePosition);
                    currentTimestampIsCorrect = true;
                    // Let's backpatch the packet we just created with the correct timestamp
                    encodedPacket = this.createEncodedPacketFromOggPacket(packet, {
                        timestampInSamples: currentTimestampInSamples - encodedPacketMetadata.durationInSamples,
                        vorbisLastBlocksize: lastEncodedPacketMetadata?.vorbisBlockSize ?? null,
                    }, options);
                    (0,misc/* assert */.vA)(encodedPacket);
                    encodedPacketMetadata = this.encodedPacketToMetadata.get(encodedPacket);
                    (0,misc/* assert */.vA)(encodedPacketMetadata);
                }
                else {
                    currentTimestampInSamples += encodedPacketMetadata.durationInSamples;
                }
                lastEncodedPacket = encodedPacket;
                lastEncodedPacketMetadata = encodedPacketMetadata;
                if (currentTimestampIsCorrect
                    && (
                    // Next timestamp will be too late
                    Math.max(currentTimestampInSamples, 0) > timestampInSamples
                        // This timestamp already matches
                        || Math.max(encodedPacketMetadata.timestampInSamples, 0) === timestampInSamples)) {
                    break;
                }
            }
            const nextPosition = await this.demuxer.findNextPacketStart(packet);
            if (!nextPosition) {
                break;
            }
            currentPage = nextPosition.startPage;
            currentSegmentIndex = nextPosition.startSegmentIndex;
        }
        return lastEncodedPacket;
    }
    // A slower but simpler and sequential algorithm for finding a packet in a file
    async getPacketSequential(timestamp, options) {
        const release = await this.sequentialScanMutex.acquire(); // Requires exclusivity because we write to a cache
        try {
            const timestampInSamples = (0,misc/* roundIfAlmostInteger */.aI)(timestamp * this.internalSampleRate);
            timestamp = timestampInSamples / this.internalSampleRate;
            const index = (0,misc/* binarySearchLessOrEqual */.eE)(this.sequentialScanCache, timestampInSamples, x => x.timestampInSamples);
            let currentPacket;
            if (index !== -1) {
                // We don't need to start from the beginning, we can start at a previous scan point
                const cacheEntry = this.sequentialScanCache[index];
                currentPacket = this.createEncodedPacketFromOggPacket(cacheEntry.packet, {
                    timestampInSamples: cacheEntry.timestampInSamples,
                    vorbisLastBlocksize: cacheEntry.vorbisLastBlockSize,
                }, options);
            }
            else {
                currentPacket = await this.getFirstPacket(options);
            }
            let i = 0;
            while (currentPacket && currentPacket.timestamp < timestamp) {
                const nextPacket = await this.getNextPacket(currentPacket, options);
                if (!nextPacket || nextPacket.timestamp > timestamp) {
                    break;
                }
                currentPacket = nextPacket;
                i++;
                if (i === 100) {
                    // Add "checkpoints" every once in a while to speed up subsequent random accesses
                    i = 0;
                    const metadata = this.encodedPacketToMetadata.get(currentPacket);
                    (0,misc/* assert */.vA)(metadata);
                    if (this.sequentialScanCache.length > 0) {
                        // If we reach this case, we must be at the end of the cache
                        (0,misc/* assert */.vA)((0,misc/* last */._g)(this.sequentialScanCache).timestampInSamples <= metadata.timestampInSamples);
                    }
                    this.sequentialScanCache.push(metadata);
                }
            }
            return currentPacket;
        }
        finally {
            release();
        }
    }
    getKeyPacket(timestamp, options) {
        return this.getPacket(timestamp, options);
    }
    getNextKeyPacket(packet, options) {
        return this.getNextPacket(packet, options);
    }
}
/** Finds the start position of a packet given its end position. */
const findPacketStartPosition = (pageList, endPage, endSegmentIndex) => {
    let page = endPage;
    let segmentIndex = endSegmentIndex;
    outer: while (true) {
        segmentIndex--;
        for (segmentIndex; segmentIndex >= 0; segmentIndex--) {
            const lacingValue = page.lacingValues[segmentIndex];
            if (lacingValue < 255) {
                segmentIndex++; // We know the last packet starts here
                break outer;
            }
        }
        (0,misc/* assert */.vA)(segmentIndex === -1);
        const pageStartsWithFreshPacket = !(page.headerType & 0x01);
        if (pageStartsWithFreshPacket) {
            // Fast exit: We know we don't need to look in the previous page
            segmentIndex = 0;
            break;
        }
        const previousPage = (0,misc/* findLast */.Uk)(pageList, x => x.headerStartPos < page.headerStartPos);
        if (!previousPage) {
            return null;
        }
        page = previousPage;
        segmentIndex = page.lacingValues.length;
    }
    (0,misc/* assert */.vA)(segmentIndex !== -1);
    if (segmentIndex === page.lacingValues.length) {
        // Wrap back around to the first segment of the next page
        const nextPage = pageList[pageList.indexOf(page) + 1];
        (0,misc/* assert */.vA)(nextPage);
        page = nextPage;
        segmentIndex = 0;
    }
    return { page, segmentIndex };
};
/** Finds the end position of a packet given the start position of the following packet. */
const findPreviousPacketEndPosition = (pageList, startPage, startSegmentIndex) => {
    if (startSegmentIndex > 0) {
        // Easy
        return { page: startPage, segmentIndex: startSegmentIndex - 1 };
    }
    const previousPage = (0,misc/* findLast */.Uk)(pageList, x => x.headerStartPos < startPage.headerStartPos);
    if (!previousPage) {
        return null;
    }
    return { page: previousPage, segmentIndex: previousPage.lacingValues.length - 1 };
};

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/wave/wave-demuxer.js
var wave_demuxer = __webpack_require__(260);
// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/adts/adts-reader.js
var adts_reader = __webpack_require__(8475);
;// ./node_modules/mediabunny/dist/modules/src/adts/adts-demuxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */









const SAMPLES_PER_AAC_FRAME = 1024;
class AdtsDemuxer extends demuxer/* Demuxer */.B {
    constructor(input) {
        super(input);
        this.metadataPromise = null;
        this.firstFrameHeader = null;
        this.loadedSamples = [];
        this.metadataTags = null;
        this.tracks = [];
        this.readingMutex = new misc/* AsyncMutex */.aD();
        this.lastSampleLoaded = false;
        this.lastLoadedPos = 0;
        this.nextTimestampInSamples = 0;
        this.reader = input._reader;
    }
    async readMetadata() {
        return this.metadataPromise ??= (async () => {
            // Keep loading until we find the first frame header
            while (!this.firstFrameHeader && !this.lastSampleLoaded) {
                await this.advanceReader();
            }
            // There has to be a frame if this demuxer got selected
            (0,misc/* assert */.vA)(this.firstFrameHeader);
            // Create the single audio track
            this.tracks = [new input_track/* InputAudioTrack */.Yi(this.input, new AdtsAudioTrackBacking(this))];
        })();
    }
    async advanceReader() {
        if (this.lastLoadedPos === 0) {
            // Skip all ID3v2 tags at the start of the file
            while (true) {
                let slice = this.reader.requestSlice(this.lastLoadedPos, id3/* ID3_V2_HEADER_SIZE */.sY);
                if (slice instanceof Promise)
                    slice = await slice;
                if (!slice) {
                    this.lastSampleLoaded = true;
                    return;
                }
                const id3V2Header = (0,id3/* readId3V2Header */.IX)(slice);
                if (!id3V2Header) {
                    break;
                }
                this.lastLoadedPos = slice.filePos + id3V2Header.size;
            }
        }
        let slice = this.reader.requestSliceRange(this.lastLoadedPos, adts_reader/* MIN_ADTS_FRAME_HEADER_SIZE */.gc, adts_reader/* MAX_ADTS_FRAME_HEADER_SIZE */.Y$);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice) {
            this.lastSampleLoaded = true;
            return;
        }
        const header = (0,adts_reader/* readAdtsFrameHeader */.lh)(slice);
        if (!header) {
            this.lastSampleLoaded = true;
            return;
        }
        if (this.reader.fileSize !== null && header.startPos + header.frameLength > this.reader.fileSize) {
            // Frame doesn't fit in the rest of the file
            this.lastSampleLoaded = true;
            return;
        }
        if (!this.firstFrameHeader) {
            this.firstFrameHeader = header;
        }
        const sampleRate = codec/* aacFrequencyTable */.Im[header.samplingFrequencyIndex];
        (0,misc/* assert */.vA)(sampleRate !== undefined);
        const sampleDuration = SAMPLES_PER_AAC_FRAME / sampleRate;
        const sample = {
            timestamp: this.nextTimestampInSamples / sampleRate,
            duration: sampleDuration,
            dataStart: header.startPos,
            dataSize: header.frameLength,
        };
        this.loadedSamples.push(sample);
        this.nextTimestampInSamples += SAMPLES_PER_AAC_FRAME;
        this.lastLoadedPos = header.startPos + header.frameLength;
    }
    async getMimeType() {
        return 'audio/aac';
    }
    async getTracks() {
        await this.readMetadata();
        return this.tracks;
    }
    async computeDuration() {
        await this.readMetadata();
        const track = this.tracks[0];
        (0,misc/* assert */.vA)(track);
        return track.computeDuration();
    }
    async getMetadataTags() {
        const release = await this.readingMutex.acquire();
        try {
            await this.readMetadata();
            if (this.metadataTags) {
                return this.metadataTags;
            }
            this.metadataTags = {};
            let currentPos = 0;
            while (true) {
                let headerSlice = this.reader.requestSlice(currentPos, id3/* ID3_V2_HEADER_SIZE */.sY);
                if (headerSlice instanceof Promise)
                    headerSlice = await headerSlice;
                if (!headerSlice)
                    break;
                const id3V2Header = (0,id3/* readId3V2Header */.IX)(headerSlice);
                if (!id3V2Header) {
                    break;
                }
                let contentSlice = this.reader.requestSlice(headerSlice.filePos, id3V2Header.size);
                if (contentSlice instanceof Promise)
                    contentSlice = await contentSlice;
                if (!contentSlice)
                    break;
                (0,id3/* parseId3V2Tag */.cG)(contentSlice, id3V2Header, this.metadataTags);
                currentPos = headerSlice.filePos + id3V2Header.size;
            }
            return this.metadataTags;
        }
        finally {
            release();
        }
    }
}
class AdtsAudioTrackBacking {
    constructor(demuxer) {
        this.demuxer = demuxer;
    }
    getId() {
        return 1;
    }
    getNumber() {
        return 1;
    }
    async getFirstTimestamp() {
        return 0;
    }
    getTimeResolution() {
        const sampleRate = this.getSampleRate();
        return sampleRate / SAMPLES_PER_AAC_FRAME;
    }
    async computeDuration() {
        const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
        return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    getName() {
        return null;
    }
    getLanguageCode() {
        return misc/* UNDETERMINED_LANGUAGE */.IR;
    }
    getCodec() {
        return 'aac';
    }
    getInternalCodecId() {
        (0,misc/* assert */.vA)(this.demuxer.firstFrameHeader);
        return this.demuxer.firstFrameHeader.objectType;
    }
    getNumberOfChannels() {
        (0,misc/* assert */.vA)(this.demuxer.firstFrameHeader);
        const numberOfChannels = codec/* aacChannelMap */.Ti[this.demuxer.firstFrameHeader.channelConfiguration];
        (0,misc/* assert */.vA)(numberOfChannels !== undefined);
        return numberOfChannels;
    }
    getSampleRate() {
        (0,misc/* assert */.vA)(this.demuxer.firstFrameHeader);
        const sampleRate = codec/* aacFrequencyTable */.Im[this.demuxer.firstFrameHeader.samplingFrequencyIndex];
        (0,misc/* assert */.vA)(sampleRate !== undefined);
        return sampleRate;
    }
    getDisposition() {
        return {
            ...metadata/* DEFAULT_TRACK_DISPOSITION */.gM,
        };
    }
    async getDecoderConfig() {
        (0,misc/* assert */.vA)(this.demuxer.firstFrameHeader);
        return {
            codec: `mp4a.40.${this.demuxer.firstFrameHeader.objectType}`,
            numberOfChannels: this.getNumberOfChannels(),
            sampleRate: this.getSampleRate(),
        };
    }
    async getPacketAtIndex(sampleIndex, options) {
        if (sampleIndex === -1) {
            return null;
        }
        const rawSample = this.demuxer.loadedSamples[sampleIndex];
        if (!rawSample) {
            return null;
        }
        let data;
        if (options.metadataOnly) {
            data = src_packet/* PLACEHOLDER_DATA */.T;
        }
        else {
            let slice = this.demuxer.reader.requestSlice(rawSample.dataStart, rawSample.dataSize);
            if (slice instanceof Promise)
                slice = await slice;
            if (!slice) {
                return null; // Data didn't fit into the rest of the file
            }
            data = (0,src_reader/* readBytes */.io)(slice, rawSample.dataSize);
        }
        return new src_packet/* EncodedPacket */.Z(data, 'key', rawSample.timestamp, rawSample.duration, sampleIndex, rawSample.dataSize);
    }
    getFirstPacket(options) {
        return this.getPacketAtIndex(0, options);
    }
    async getNextPacket(packet, options) {
        const release = await this.demuxer.readingMutex.acquire();
        try {
            const sampleIndex = (0,misc/* binarySearchExact */.pl)(this.demuxer.loadedSamples, packet.timestamp, x => x.timestamp);
            if (sampleIndex === -1) {
                throw new Error('Packet was not created from this track.');
            }
            const nextIndex = sampleIndex + 1;
            // Ensure the next sample exists
            while (nextIndex >= this.demuxer.loadedSamples.length
                && !this.demuxer.lastSampleLoaded) {
                await this.demuxer.advanceReader();
            }
            return this.getPacketAtIndex(nextIndex, options);
        }
        finally {
            release();
        }
    }
    async getPacket(timestamp, options) {
        const release = await this.demuxer.readingMutex.acquire();
        try {
            while (true) {
                const index = (0,misc/* binarySearchLessOrEqual */.eE)(this.demuxer.loadedSamples, timestamp, x => x.timestamp);
                if (index === -1 && this.demuxer.loadedSamples.length > 0) {
                    // We're before the first sample
                    return null;
                }
                if (this.demuxer.lastSampleLoaded) {
                    // All data is loaded, return what we found
                    return this.getPacketAtIndex(index, options);
                }
                if (index >= 0 && index + 1 < this.demuxer.loadedSamples.length) {
                    // The next packet also exists, we're done
                    return this.getPacketAtIndex(index, options);
                }
                // Otherwise, keep loading data
                await this.demuxer.advanceReader();
            }
        }
        finally {
            release();
        }
    }
    getKeyPacket(timestamp, options) {
        return this.getPacket(timestamp, options);
    }
    getNextKeyPacket(packet, options) {
        return this.getNextPacket(packet, options);
    }
}

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/flac/flac-misc.js
var flac_misc = __webpack_require__(5828);
;// ./node_modules/mediabunny/dist/modules/src/flac/flac-demuxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */








class FlacDemuxer extends demuxer/* Demuxer */.B {
    constructor(input) {
        super(input);
        this.loadedSamples = []; // All samples from the start of the file to lastLoadedPos
        this.metadataPromise = null;
        this.track = null;
        this.metadataTags = {};
        this.audioInfo = null;
        this.lastLoadedPos = null;
        this.blockingBit = null;
        this.readingMutex = new misc/* AsyncMutex */.aD();
        this.lastSampleLoaded = false;
        this.reader = input._reader;
    }
    async computeDuration() {
        await this.readMetadata();
        (0,misc/* assert */.vA)(this.track);
        return this.track.computeDuration();
    }
    async getMetadataTags() {
        await this.readMetadata();
        return this.metadataTags;
    }
    async getTracks() {
        await this.readMetadata();
        (0,misc/* assert */.vA)(this.track);
        return [this.track];
    }
    async getMimeType() {
        return 'audio/flac';
    }
    async readMetadata() {
        let currentPos = 4; // Skip 'fLaC'
        return (this.metadataPromise ??= (async () => {
            while (this.reader.fileSize === null
                || currentPos < this.reader.fileSize) {
                let sizeSlice = this.reader.requestSlice(currentPos, 4);
                if (sizeSlice instanceof Promise)
                    sizeSlice = await sizeSlice;
                currentPos += 4;
                if (sizeSlice === null) {
                    throw new Error(`Metadata block at position ${currentPos} is too small! Corrupted file.`);
                }
                (0,misc/* assert */.vA)(sizeSlice);
                const byte = (0,src_reader/* readU8 */.eo)(sizeSlice); // first bit: isLastMetadata, remaining 7 bits: metaBlockType
                const size = (0,src_reader/* readU24Be */.n2)(sizeSlice);
                const isLastMetadata = (byte & 0x80) !== 0;
                const metaBlockType = byte & 0x7f;
                switch (metaBlockType) {
                    case codec_data/* FlacBlockType */.A3.STREAMINFO: {
                        // Parse streaminfo block
                        // https://www.rfc-editor.org/rfc/rfc9639.html#section-8.2
                        let streamInfoBlock = this.reader.requestSlice(currentPos, size);
                        if (streamInfoBlock instanceof Promise)
                            streamInfoBlock = await streamInfoBlock;
                        (0,misc/* assert */.vA)(streamInfoBlock);
                        if (streamInfoBlock === null) {
                            throw new Error(`StreamInfo block at position ${currentPos} is too small! Corrupted file.`);
                        }
                        const streamInfoBytes = (0,src_reader/* readBytes */.io)(streamInfoBlock, 34);
                        const bitstream = new misc/* Bitstream */._c(streamInfoBytes);
                        const minimumBlockSize = bitstream.readBits(16);
                        const maximumBlockSize = bitstream.readBits(16);
                        const minimumFrameSize = bitstream.readBits(24);
                        const maximumFrameSize = bitstream.readBits(24);
                        const sampleRate = bitstream.readBits(20);
                        const numberOfChannels = bitstream.readBits(3) + 1;
                        bitstream.readBits(5); // bitsPerSample - 1
                        const totalSamples = bitstream.readBits(36);
                        // https://www.w3.org/TR/webcodecs-flac-codec-registration/#audiodecoderconfig-description
                        // description is required, and has to be the following:
                        // 1. The bytes 0x66 0x4C 0x61 0x43 ("fLaC" in ASCII)
                        // 2. A metadata block (called the STREAMINFO block) as described in section 7 of [FLAC]
                        // 3. Optionaly (sic) other metadata blocks, that are not used by the specification
                        bitstream.skipBits(16 * 8); // md5 hash
                        const description = new Uint8Array(42);
                        // 1. "fLaC"
                        description.set(new Uint8Array([0x66, 0x4c, 0x61, 0x43]), 0);
                        // 2. STREAMINFO block
                        description.set(new Uint8Array([128, 0, 0, 34]), 4);
                        // 3. Other metadata blocks
                        description.set(streamInfoBytes, 8);
                        this.audioInfo = {
                            numberOfChannels,
                            sampleRate,
                            totalSamples,
                            minimumBlockSize,
                            maximumBlockSize,
                            minimumFrameSize,
                            maximumFrameSize,
                            description,
                        };
                        this.track = new input_track/* InputAudioTrack */.Yi(this.input, new FlacAudioTrackBacking(this));
                        break;
                    }
                    case codec_data/* FlacBlockType */.A3.VORBIS_COMMENT: {
                        // Parse vorbis comment block
                        // https://www.rfc-editor.org/rfc/rfc9639.html#name-vorbis-comment
                        let vorbisCommentBlock = this.reader.requestSlice(currentPos, size);
                        if (vorbisCommentBlock instanceof Promise)
                            vorbisCommentBlock = await vorbisCommentBlock;
                        (0,misc/* assert */.vA)(vorbisCommentBlock);
                        (0,codec_data/* readVorbisComments */.Oc)((0,src_reader/* readBytes */.io)(vorbisCommentBlock, size), this.metadataTags);
                        break;
                    }
                    case codec_data/* FlacBlockType */.A3.PICTURE: {
                        // Parse picture block
                        // https://www.rfc-editor.org/rfc/rfc9639.html#name-picture
                        let pictureBlock = this.reader.requestSlice(currentPos, size);
                        if (pictureBlock instanceof Promise)
                            pictureBlock = await pictureBlock;
                        (0,misc/* assert */.vA)(pictureBlock);
                        const pictureType = (0,src_reader/* readU32Be */.cN)(pictureBlock);
                        const mediaTypeLength = (0,src_reader/* readU32Be */.cN)(pictureBlock);
                        const mediaType = misc/* textDecoder */.su.decode((0,src_reader/* readBytes */.io)(pictureBlock, mediaTypeLength));
                        const descriptionLength = (0,src_reader/* readU32Be */.cN)(pictureBlock);
                        const description = misc/* textDecoder */.su.decode((0,src_reader/* readBytes */.io)(pictureBlock, descriptionLength));
                        pictureBlock.skip(4 + 4 + 4 + 4); // Skip width, height, color depth, number of indexed colors
                        const dataLength = (0,src_reader/* readU32Be */.cN)(pictureBlock);
                        const data = (0,src_reader/* readBytes */.io)(pictureBlock, dataLength);
                        this.metadataTags.images ??= [];
                        this.metadataTags.images.push({
                            data,
                            mimeType: mediaType,
                            // https://www.rfc-editor.org/rfc/rfc9639.html#table13
                            kind: pictureType === 3
                                ? 'coverFront'
                                : pictureType === 4
                                    ? 'coverBack'
                                    : 'unknown',
                            description,
                        });
                        break;
                    }
                    default:
                        break;
                }
                currentPos += size;
                if (isLastMetadata) {
                    this.lastLoadedPos = currentPos;
                    break;
                }
            }
        })());
    }
    async readNextFlacFrame({ startPos, isFirstPacket, }) {
        (0,misc/* assert */.vA)(this.audioInfo);
        // we expect that there are at least `minimumFrameSize` bytes left in the file
        // Ideally we also want to validate the next header is valid
        // to throw out an accidential sync word
        // The shortest valid FLAC header I can think of, based off the code
        // of readFlacFrameHeader:
        // 4 bytes used for bitstream from syncword to bit depth
        // 1 byte coded number
        // (uncommon values, no bytes read)
        // 1 byte crc
        // --> 6 bytes
        const minimumHeaderLength = 6;
        // If we read everything in readFlacFrameHeader, we read 16 bytes
        const maximumHeaderSize = 16;
        const maximumSliceLength = this.audioInfo.maximumFrameSize + maximumHeaderSize;
        const slice = await this.reader.requestSliceRange(startPos, this.audioInfo.minimumFrameSize, maximumSliceLength);
        if (!slice) {
            return null;
        }
        const frameHeader = this.readFlacFrameHeader({
            slice,
            isFirstPacket: isFirstPacket,
        });
        if (!frameHeader) {
            return null;
        }
        // We don't know exactly how long the packet is, we only know the `minimumFrameSize` and `maximumFrameSize`
        // The packet is over if the next 2 bytes are the sync word followed by a valid header
        // or the end of the file is reached
        // The next sync word is expected at earliest when `minimumFrameSize` is reached,
        // we can skip over anything before that
        slice.filePos = startPos + this.audioInfo.minimumFrameSize;
        while (true) {
            // Reached end of the file, packet is over
            if (slice.filePos > slice.end - minimumHeaderLength) {
                return {
                    num: frameHeader.num,
                    blockSize: frameHeader.blockSize,
                    sampleRate: frameHeader.sampleRate,
                    size: slice.end - startPos,
                    isLastFrame: true,
                };
            }
            const nextByte = (0,src_reader/* readU8 */.eo)(slice);
            if (nextByte === 0xff) {
                const positionBeforeReading = slice.filePos;
                const byteAfterNextByte = (0,src_reader/* readU8 */.eo)(slice);
                const expected = this.blockingBit === 1 ? 0b1111_1001 : 0b1111_1000;
                if (byteAfterNextByte !== expected) {
                    slice.filePos = positionBeforeReading;
                    continue;
                }
                slice.skip(-2);
                const lengthIfNextFlacFrameHeaderIsLegit = slice.filePos - startPos;
                const nextFrameHeader = this.readFlacFrameHeader({
                    slice,
                    isFirstPacket: false,
                });
                if (!nextFrameHeader) {
                    slice.filePos = positionBeforeReading;
                    continue;
                }
                // Ensure the frameOrSampleNum is consecutive.
                // https://github.com/Vanilagy/mediabunny/issues/194
                if (this.blockingBit === 0) {
                    // Case A: If the stream is fixed block size, this is the frame number, which increments by 1
                    if (nextFrameHeader.num - frameHeader.num !== 1) {
                        slice.filePos = positionBeforeReading;
                        continue;
                    }
                }
                else {
                    // Case B: If the stream is variable block size, this is the sample number, which increments by
                    // amount of samples in a frame.
                    if (nextFrameHeader.num - frameHeader.num !== frameHeader.blockSize) {
                        slice.filePos = positionBeforeReading;
                        continue;
                    }
                }
                return {
                    num: frameHeader.num,
                    blockSize: frameHeader.blockSize,
                    sampleRate: frameHeader.sampleRate,
                    size: lengthIfNextFlacFrameHeaderIsLegit,
                    isLastFrame: false,
                };
            }
        }
    }
    readFlacFrameHeader({ slice, isFirstPacket, }) {
        // In this function, generally it is not safe to throw errors.
        // We might end up here because we stumbled upon a syncword,
        // but the data might not actually be a FLAC frame, it might be random bitstream
        // data, in that case we should return null and continue.
        const startOffset = slice.filePos;
        // https://www.rfc-editor.org/rfc/rfc9639.html#section-9.1
        // Each frame MUST start on a byte boundary and start with the 15-bit frame
        // sync code 0b111111111111100. Following the sync code is the blocking strategy
        // bit, which MUST NOT change during the audio stream.
        const bytes = (0,src_reader/* readBytes */.io)(slice, 4);
        const bitstream = new misc/* Bitstream */._c(bytes);
        const bits = bitstream.readBits(15);
        if (bits !== 0b111111111111100) {
            // This cannot be a valid FLAC frame, must start with the syncword
            return null;
        }
        if (this.blockingBit === null) {
            (0,misc/* assert */.vA)(isFirstPacket);
            const newBlockingBit = bitstream.readBits(1);
            this.blockingBit = newBlockingBit;
        }
        else if (this.blockingBit === 1) {
            (0,misc/* assert */.vA)(!isFirstPacket);
            const newBlockingBit = bitstream.readBits(1);
            if (newBlockingBit !== 1) {
                // This cannot be a valid FLAC frame, expected 1 but got 0
                return null;
            }
        }
        else if (this.blockingBit === 0) {
            (0,misc/* assert */.vA)(!isFirstPacket);
            const newBlockingBit = bitstream.readBits(1);
            if (newBlockingBit !== 0) {
                // This cannot be a valid FLAC frame, expected 0 but got 1
                return null;
            }
        }
        else {
            throw new Error('Invalid blocking bit');
        }
        const blockSizeOrUncommon = (0,flac_misc/* getBlockSizeOrUncommon */.iv)(bitstream.readBits(4));
        if (!blockSizeOrUncommon) {
            // This cannot be a valid FLAC frame, the syncword was just coincidental
            return null;
        }
        (0,misc/* assert */.vA)(this.audioInfo);
        const sampleRateOrUncommon = (0,flac_misc/* getSampleRateOrUncommon */.oP)(bitstream.readBits(4), this.audioInfo.sampleRate);
        if (!sampleRateOrUncommon) {
            // This cannot be a valid FLAC frame, the syncword was just coincidental
            return null;
        }
        bitstream.readBits(4); // channel count
        bitstream.readBits(3); // bit depth
        const reservedZero = bitstream.readBits(1); // reserved zero
        if (reservedZero !== 0) {
            // This cannot be a valid FLAC frame, the syncword was just coincidental
            return null;
        }
        const num = (0,flac_misc/* readCodedNumber */.X7)(slice);
        const blockSize = (0,flac_misc/* readBlockSize */.f6)(slice, blockSizeOrUncommon);
        const sampleRate = (0,flac_misc/* readSampleRate */.Ld)(slice, sampleRateOrUncommon);
        if (sampleRate === null) {
            // This cannot be a valid FLAC frame, the syncword was just coincidental
            return null;
        }
        if (sampleRate !== this.audioInfo.sampleRate) {
            // This cannot be a valid FLAC frame, the sample rate is not the same as in the stream info
            return null;
        }
        const size = slice.filePos - startOffset;
        const crc = (0,src_reader/* readU8 */.eo)(slice);
        slice.skip(-size);
        slice.skip(-1);
        const crcCalculated = (0,flac_misc/* calculateCrc8 */.Be)((0,src_reader/* readBytes */.io)(slice, size));
        if (crc !== crcCalculated) {
            // Maybe this wasn't a FLAC frame at all, the syncword was just coincidentally
            // in the bitstream
            return null;
        }
        return { num, blockSize, sampleRate };
    }
    async advanceReader() {
        await this.readMetadata();
        (0,misc/* assert */.vA)(this.lastLoadedPos !== null);
        (0,misc/* assert */.vA)(this.audioInfo);
        const startPos = this.lastLoadedPos;
        const frame = await this.readNextFlacFrame({
            startPos,
            isFirstPacket: this.loadedSamples.length === 0,
        });
        if (!frame) {
            // Unexpected case, failed to read next FLAC frame
            // handling gracefully
            this.lastSampleLoaded = true;
            return;
        }
        const lastSample = this.loadedSamples[this.loadedSamples.length - 1];
        const blockOffset = lastSample
            ? lastSample.blockOffset + lastSample.blockSize
            : 0;
        const sample = {
            blockOffset,
            blockSize: frame.blockSize,
            byteOffset: startPos,
            byteSize: frame.size,
        };
        this.lastLoadedPos = this.lastLoadedPos + frame.size;
        this.loadedSamples.push(sample);
        if (frame.isLastFrame) {
            this.lastSampleLoaded = true;
            return;
        }
    }
}
class FlacAudioTrackBacking {
    constructor(demuxer) {
        this.demuxer = demuxer;
    }
    getId() {
        return 1;
    }
    getNumber() {
        return 1;
    }
    getCodec() {
        return 'flac';
    }
    getInternalCodecId() {
        return null;
    }
    getNumberOfChannels() {
        (0,misc/* assert */.vA)(this.demuxer.audioInfo);
        return this.demuxer.audioInfo.numberOfChannels;
    }
    async computeDuration() {
        const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
        return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    getSampleRate() {
        (0,misc/* assert */.vA)(this.demuxer.audioInfo);
        return this.demuxer.audioInfo.sampleRate;
    }
    getName() {
        return null;
    }
    getLanguageCode() {
        return misc/* UNDETERMINED_LANGUAGE */.IR;
    }
    getTimeResolution() {
        (0,misc/* assert */.vA)(this.demuxer.audioInfo);
        return this.demuxer.audioInfo.sampleRate;
    }
    getDisposition() {
        return {
            ...metadata/* DEFAULT_TRACK_DISPOSITION */.gM,
        };
    }
    async getFirstTimestamp() {
        return 0;
    }
    async getDecoderConfig() {
        (0,misc/* assert */.vA)(this.demuxer.audioInfo);
        return {
            codec: 'flac',
            numberOfChannels: this.demuxer.audioInfo.numberOfChannels,
            sampleRate: this.demuxer.audioInfo.sampleRate,
            description: this.demuxer.audioInfo.description,
        };
    }
    async getPacket(timestamp, options) {
        (0,misc/* assert */.vA)(this.demuxer.audioInfo);
        if (timestamp < 0) {
            throw new Error('Timestamp cannot be negative');
        }
        const release = await this.demuxer.readingMutex.acquire();
        try {
            while (true) {
                const packetIndex = (0,misc/* binarySearchLessOrEqual */.eE)(this.demuxer.loadedSamples, timestamp, x => x.blockOffset / this.demuxer.audioInfo.sampleRate);
                if (packetIndex === -1) {
                    await this.demuxer.advanceReader();
                    continue;
                }
                const packet = this.demuxer.loadedSamples[packetIndex];
                const sampleTimestamp = packet.blockOffset / this.demuxer.audioInfo.sampleRate;
                const sampleDuration = packet.blockSize / this.demuxer.audioInfo.sampleRate;
                if (sampleTimestamp + sampleDuration <= timestamp) {
                    if (this.demuxer.lastSampleLoaded) {
                        return this.getPacketAtIndex(this.demuxer.loadedSamples.length - 1, options);
                    }
                    await this.demuxer.advanceReader();
                    continue;
                }
                return this.getPacketAtIndex(packetIndex, options);
            }
        }
        finally {
            release();
        }
    }
    async getNextPacket(packet, options) {
        const release = await this.demuxer.readingMutex.acquire();
        try {
            const nextIndex = packet.sequenceNumber + 1;
            if (this.demuxer.lastSampleLoaded
                && nextIndex >= this.demuxer.loadedSamples.length) {
                return null;
            }
            // Ensure the next sample exists
            while (nextIndex >= this.demuxer.loadedSamples.length
                && !this.demuxer.lastSampleLoaded) {
                await this.demuxer.advanceReader();
            }
            return this.getPacketAtIndex(nextIndex, options);
        }
        finally {
            release();
        }
    }
    getKeyPacket(timestamp, options) {
        return this.getPacket(timestamp, options);
    }
    getNextKeyPacket(packet, options) {
        return this.getNextPacket(packet, options);
    }
    async getPacketAtIndex(sampleIndex, options) {
        const rawSample = this.demuxer.loadedSamples[sampleIndex];
        if (!rawSample) {
            return null;
        }
        let data;
        if (options.metadataOnly) {
            data = src_packet/* PLACEHOLDER_DATA */.T;
        }
        else {
            let slice = this.demuxer.reader.requestSlice(rawSample.byteOffset, rawSample.byteSize);
            if (slice instanceof Promise)
                slice = await slice;
            if (!slice) {
                return null; // Data didn't fit into the rest of the file
            }
            data = (0,src_reader/* readBytes */.io)(slice, rawSample.byteSize);
        }
        (0,misc/* assert */.vA)(this.demuxer.audioInfo);
        const timestamp = rawSample.blockOffset / this.demuxer.audioInfo.sampleRate;
        const duration = rawSample.blockSize / this.demuxer.audioInfo.sampleRate;
        return new src_packet/* EncodedPacket */.Z(data, 'key', timestamp, duration, sampleIndex, rawSample.byteSize);
    }
    async getFirstPacket(options) {
        // Ensure the next sample exists
        while (this.demuxer.loadedSamples.length === 0
            && !this.demuxer.lastSampleLoaded) {
            await this.demuxer.advanceReader();
        }
        return this.getPacketAtIndex(0, options);
    }
}

// EXTERNAL MODULE: ./node_modules/mediabunny/dist/modules/src/mpeg-ts/mpeg-ts-misc.js
var mpeg_ts_misc = __webpack_require__(2490);
;// ./node_modules/mediabunny/dist/modules/src/mpeg-ts/mpeg-ts-demuxer.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */













class MpegTsDemuxer extends demuxer/* Demuxer */.B {
    constructor(input) {
        super(input);
        this.metadataPromise = null;
        this.elementaryStreams = [];
        this.tracks = [];
        this.packetOffset = 0;
        this.packetStride = -1;
        this.sectionEndPositions = [];
        this.seekChunkSize = 5 * 1024 * 1024; // 5 MiB, picked because most HLS segments are below this size
        this.minReferencePointByteDistance = -1;
        this.reader = input._reader;
    }
    async readMetadata() {
        return this.metadataPromise ??= (async () => {
            const lengthToCheck = mpeg_ts_misc/* TS_PACKET_SIZE */.ZT + 16 + 1;
            let startingSlice = this.reader.requestSlice(0, lengthToCheck);
            if (startingSlice instanceof Promise)
                startingSlice = await startingSlice;
            (0,misc/* assert */.vA)(startingSlice);
            const startingBytes = (0,src_reader/* readBytes */.io)(startingSlice, lengthToCheck);
            if (startingBytes[0] === 0x47 && startingBytes[mpeg_ts_misc/* TS_PACKET_SIZE */.ZT] === 0x47) {
                // Regular MPEG-TS
                this.packetOffset = 0;
                this.packetStride = mpeg_ts_misc/* TS_PACKET_SIZE */.ZT;
            }
            else if (startingBytes[0] === 0x47 && startingBytes[mpeg_ts_misc/* TS_PACKET_SIZE */.ZT + 16] === 0x47) {
                // MPEG-TS with Forward Error Correction
                this.packetOffset = 0;
                this.packetStride = mpeg_ts_misc/* TS_PACKET_SIZE */.ZT + 16;
            }
            else if (startingBytes[4] === 0x47 && startingBytes[4 + mpeg_ts_misc/* TS_PACKET_SIZE */.ZT] === 0x47) {
                // MPEG-2-TS (DVHS)
                this.packetOffset = 4;
                this.packetStride = mpeg_ts_misc/* TS_PACKET_SIZE */.ZT;
            }
            else {
                throw new Error('Unreachable.');
            }
            const MIN_REFERENCE_POINT_PACKET_DISTANCE = 256;
            this.minReferencePointByteDistance = MIN_REFERENCE_POINT_PACKET_DISTANCE * this.packetStride;
            let currentPos = this.packetOffset;
            let programMapPid = null;
            // Some files contain these multiple times, but we only care about their first appearance
            let hasProgramAssociationTable = false;
            let hasProgramMap = false;
            while (true) {
                const packetHeader = await this.readPacketHeader(currentPos);
                if (!packetHeader) {
                    break;
                }
                if (packetHeader.payloadUnitStartIndicator === 0) {
                    // Not the start of a section
                    currentPos += this.packetStride;
                    continue;
                }
                const section = await this.readSection(currentPos, true, !hasProgramMap);
                if (!section) {
                    break;
                }
                const BYTES_BEFORE_SECTION_LENGTH = 3;
                const BITS_IN_CRC_32 = 32; // Duh
                // Some streams don't contain a PAT for some reason, so we must do some guesswork to figure out where
                // the PMT is.
                let isProbablyProgramMap = false;
                if (!hasProgramMap && section.pid !== 0) {
                    const isPesPacket = section.payload[0] === 0x00 && section.payload[1] === 0x00 && section.payload[2] === 0x01;
                    if (!isPesPacket) {
                        // Assume it's a PSI
                        const bitstream = new misc/* Bitstream */._c(section.payload);
                        const pointerField = bitstream.readAlignedByte();
                        bitstream.skipBits(8 * pointerField);
                        const tableId = bitstream.readBits(8);
                        isProbablyProgramMap = tableId === 0x02; // 0x02 == TS_program_map_section
                    }
                }
                if (section.pid === 0 && !hasProgramAssociationTable) {
                    const bitstream = new misc/* Bitstream */._c(section.payload);
                    const pointerField = bitstream.readAlignedByte();
                    bitstream.skipBits(8 * pointerField);
                    bitstream.skipBits(14);
                    const sectionLength = bitstream.readBits(10);
                    bitstream.skipBits(40);
                    while (8 * (sectionLength + BYTES_BEFORE_SECTION_LENGTH) - bitstream.pos > BITS_IN_CRC_32) {
                        const programNumber = bitstream.readBits(16);
                        bitstream.skipBits(3); // Reserved
                        if (programNumber !== 0) {
                            if (programMapPid !== null) {
                                throw new Error('Only files with a single program are supported.');
                            }
                            else {
                                programMapPid = bitstream.readBits(13);
                            }
                        }
                    }
                    if (programMapPid === null) {
                        throw new Error('Program Association Table must link to a Program Map Table.');
                    }
                    hasProgramAssociationTable = true;
                }
                else if ((section.pid === programMapPid || isProbablyProgramMap) && !hasProgramMap) {
                    const bitstream = new misc/* Bitstream */._c(section.payload);
                    const pointerField = bitstream.readAlignedByte();
                    bitstream.skipBits(8 * pointerField);
                    bitstream.skipBits(12);
                    const sectionLength = bitstream.readBits(12);
                    bitstream.skipBits(43);
                    // eslint-disable-next-line @typescript-eslint/no-unused-vars
                    const pcrPid = bitstream.readBits(13);
                    bitstream.skipBits(6);
                    // "The remaining 10 bits specify the number of bytes of the descriptors immediately following the
                    // program_info_length field"
                    const programInfoLength = bitstream.readBits(10);
                    bitstream.skipBits(8 * programInfoLength);
                    while (8 * (sectionLength + BYTES_BEFORE_SECTION_LENGTH) - bitstream.pos > BITS_IN_CRC_32) {
                        const streamType = bitstream.readBits(8);
                        bitstream.skipBits(3);
                        const elementaryPid = bitstream.readBits(13);
                        bitstream.skipBits(6);
                        const esInfoLength = bitstream.readBits(10);
                        // Check ES descriptors to detect AC-3/E-AC-3 in System B
                        const esInfoEndPos = bitstream.pos + 8 * esInfoLength;
                        let hasAc3Descriptor = false;
                        let hasEac3Descriptor = false;
                        while (bitstream.pos < esInfoEndPos) {
                            const descriptorTag = bitstream.readBits(8);
                            const descriptorLength = bitstream.readBits(8);
                            if (descriptorTag === 0x6a) {
                                hasAc3Descriptor = true;
                            }
                            else if (descriptorTag === 0x7a || descriptorTag === 0xcc) {
                                hasEac3Descriptor = true;
                            }
                            bitstream.skipBits(8 * descriptorLength);
                        }
                        let info = null;
                        switch (streamType) {
                            case 3 /* MpegTsStreamType.MP3_MPEG1 */:
                            case 4 /* MpegTsStreamType.MP3_MPEG2 */:
                            case 15 /* MpegTsStreamType.AAC */:
                                {
                                    const codec = streamType === 15 /* MpegTsStreamType.AAC */ ? 'aac' : 'mp3';
                                    info = {
                                        type: 'audio',
                                        codec,
                                        aacCodecInfo: null,
                                        numberOfChannels: -1,
                                        sampleRate: -1,
                                    };
                                }
                                ;
                                break;
                            case 27 /* MpegTsStreamType.AVC */:
                            case 36 /* MpegTsStreamType.HEVC */:
                                {
                                    const codec = streamType === 27 /* MpegTsStreamType.AVC */ ? 'avc' : 'hevc';
                                    info = {
                                        type: 'video',
                                        codec: codec,
                                        avcCodecInfo: null,
                                        hevcCodecInfo: null,
                                        colorSpace: {
                                            primaries: null,
                                            transfer: null,
                                            matrix: null,
                                            fullRange: null,
                                        },
                                        width: -1,
                                        height: -1,
                                        reorderSize: -1,
                                    };
                                }
                                ;
                                break;
                            case 129 /* MpegTsStreamType.AC3_SYSTEM_A */:
                                {
                                    info = {
                                        type: 'audio',
                                        codec: 'ac3',
                                        aacCodecInfo: null,
                                        numberOfChannels: -1,
                                        sampleRate: -1,
                                    };
                                }
                                ;
                                break;
                            case 135 /* MpegTsStreamType.EAC3_SYSTEM_A */:
                                {
                                    info = {
                                        type: 'audio',
                                        codec: 'eac3',
                                        aacCodecInfo: null,
                                        numberOfChannels: -1,
                                        sampleRate: -1,
                                    };
                                }
                                ;
                                break;
                            case 6 /* MpegTsStreamType.PRIVATE_DATA */:
                                {
                                    if (hasEac3Descriptor) {
                                        info = {
                                            type: 'audio',
                                            codec: 'eac3',
                                            aacCodecInfo: null,
                                            numberOfChannels: -1,
                                            sampleRate: -1,
                                        };
                                    }
                                    else if (hasAc3Descriptor) {
                                        info = {
                                            type: 'audio',
                                            codec: 'ac3',
                                            aacCodecInfo: null,
                                            numberOfChannels: -1,
                                            sampleRate: -1,
                                        };
                                    }
                                }
                                ;
                                break;
                            default: {
                                // If we don't recognize the codec, we don't surface the track at all. This is because
                                // we can't determine its metadata and also have no idea how to packetize its data.
                                console.warn(`Unsupported stream_type 0x${streamType.toString(16)}; ignoring stream.`);
                            }
                        }
                        if (info) {
                            this.elementaryStreams.push({
                                demuxer: this,
                                pid: elementaryPid,
                                streamType,
                                initialized: false,
                                firstSection: null,
                                info,
                                referencePesPackets: [],
                            });
                        }
                    }
                    hasProgramMap = true;
                }
                else {
                    const elementaryStream = this.elementaryStreams.find(x => x.pid === section.pid);
                    if (elementaryStream && !elementaryStream.initialized) {
                        const pesPacket = readPesPacket(section);
                        if (!pesPacket) {
                            throw new Error(`Couldn't read first PES packet for Elementary Stream with PID ${elementaryStream.pid}`);
                        }
                        elementaryStream.firstSection = section;
                        if (elementaryStream.info.type === 'video') {
                            if (elementaryStream.info.codec === 'avc') {
                                elementaryStream.info.avcCodecInfo
                                    = (0,codec_data/* extractAvcDecoderConfigurationRecord */.fH)(pesPacket.data);
                                if (!elementaryStream.info.avcCodecInfo) {
                                    throw new Error('Invalid AVC video stream; could not extract AVCDecoderConfigurationRecord'
                                        + ' from first packet.');
                                }
                                const spsUnit = elementaryStream.info.avcCodecInfo.sequenceParameterSets[0];
                                (0,misc/* assert */.vA)(spsUnit);
                                const spsInfo = (0,codec_data/* parseAvcSps */.eM)(spsUnit);
                                elementaryStream.info.width = spsInfo.displayWidth;
                                elementaryStream.info.height = spsInfo.displayHeight;
                                elementaryStream.info.colorSpace = {
                                    primaries: misc/* COLOR_PRIMARIES_MAP_INVERSE */.BL[spsInfo.colourPrimaries],
                                    transfer: misc/* TRANSFER_CHARACTERISTICS_MAP_INVERSE */.x_[spsInfo.transferCharacteristics],
                                    matrix: misc/* MATRIX_COEFFICIENTS_MAP_INVERSE */.fl[spsInfo.matrixCoefficients],
                                    fullRange: !!spsInfo.fullRangeFlag,
                                };
                                elementaryStream.info.reorderSize = spsInfo.maxDecFrameBuffering;
                                elementaryStream.initialized = true;
                            }
                            else if (elementaryStream.info.codec === 'hevc') {
                                elementaryStream.info.hevcCodecInfo
                                    = (0,codec_data/* extractHevcDecoderConfigurationRecord */.D5)(pesPacket.data);
                                if (!elementaryStream.info.hevcCodecInfo) {
                                    throw new Error('Invalid HEVC video stream; could not extract HVCDecoderConfigurationRecord'
                                        + ' from first packet.');
                                }
                                const spsArray = elementaryStream.info.hevcCodecInfo.arrays.find(a => a.nalUnitType === codec_data/* HevcNalUnitType */.iJ.SPS_NUT);
                                const spsUnit = spsArray.nalUnits[0];
                                (0,misc/* assert */.vA)(spsUnit);
                                const spsInfo = (0,codec_data/* parseHevcSps */.gT)(spsUnit);
                                elementaryStream.info.width = spsInfo.displayWidth;
                                elementaryStream.info.height = spsInfo.displayHeight;
                                elementaryStream.info.colorSpace = {
                                    primaries: misc/* COLOR_PRIMARIES_MAP_INVERSE */.BL[spsInfo.colourPrimaries],
                                    transfer: misc/* TRANSFER_CHARACTERISTICS_MAP_INVERSE */.x_[spsInfo.transferCharacteristics],
                                    matrix: misc/* MATRIX_COEFFICIENTS_MAP_INVERSE */.fl[spsInfo.matrixCoefficients],
                                    fullRange: !!spsInfo.fullRangeFlag,
                                };
                                elementaryStream.info.reorderSize = spsInfo.maxDecFrameBuffering;
                                elementaryStream.initialized = true;
                            }
                            else {
                                throw new Error('Unhandled.');
                            }
                        }
                        else {
                            if (elementaryStream.info.codec === 'aac') {
                                const slice = src_reader/* FileSlice */.x$.tempFromBytes(pesPacket.data);
                                const header = (0,adts_reader/* readAdtsFrameHeader */.lh)(slice);
                                if (!header) {
                                    throw new Error('Invalid AAC audio stream; could not read ADTS frame header from first packet.');
                                }
                                elementaryStream.info.aacCodecInfo = {
                                    isMpeg2: false,
                                    objectType: header.objectType,
                                };
                                elementaryStream.info.numberOfChannels
                                    = codec/* aacChannelMap */.Ti[header.channelConfiguration];
                                elementaryStream.info.sampleRate
                                    = codec/* aacFrequencyTable */.Im[header.samplingFrequencyIndex];
                                elementaryStream.initialized = true;
                            }
                            else if (elementaryStream.info.codec === 'mp3') {
                                const word = (0,src_reader/* readU32Be */.cN)(src_reader/* FileSlice */.x$.tempFromBytes(pesPacket.data));
                                const result = (0,mp3_misc/* readMp3FrameHeader */.P8)(word, pesPacket.data.byteLength);
                                if (!result.header) {
                                    throw new Error('Invalid MP3 audio stream; could not read frame header from first packet.');
                                }
                                elementaryStream.info.numberOfChannels = result.header.channel === 3 ? 1 : 2;
                                elementaryStream.info.sampleRate = result.header.sampleRate;
                                elementaryStream.initialized = true;
                            }
                            else if (elementaryStream.info.codec === 'ac3') {
                                const frameInfo = (0,codec_data/* parseAc3SyncFrame */.LM)(pesPacket.data);
                                if (!frameInfo) {
                                    throw new Error('Invalid AC-3 audio stream; could not read sync frame from first packet.');
                                }
                                if (frameInfo.fscod === 3) {
                                    throw new Error('Invalid AC-3 audio stream; reserved sample rate code found in first packet.');
                                }
                                elementaryStream.info.numberOfChannels
                                    = codec_data/* AC3_ACMOD_CHANNEL_COUNTS */.ux[frameInfo.acmod] + frameInfo.lfeon;
                                elementaryStream.info.sampleRate = ac3_misc/* AC3_SAMPLE_RATES */.N[frameInfo.fscod];
                                elementaryStream.initialized = true;
                            }
                            else if (elementaryStream.info.codec === 'eac3') {
                                const frameInfo = (0,codec_data/* parseEac3SyncFrame */.oL)(pesPacket.data);
                                if (!frameInfo) {
                                    throw new Error('Invalid E-AC-3 audio stream; could not read sync frame from first packet.');
                                }
                                const sampleRate = (0,codec_data/* getEac3SampleRate */.PK)(frameInfo);
                                if (sampleRate === null) {
                                    throw new Error('Invalid E-AC-3 audio stream; reserved sample rate code found in first packet.');
                                }
                                elementaryStream.info.numberOfChannels = (0,codec_data/* getEac3ChannelCount */.zV)(frameInfo);
                                elementaryStream.info.sampleRate = sampleRate;
                                elementaryStream.initialized = true;
                            }
                            else {
                                throw new Error('Unhandled.');
                            }
                        }
                    }
                }
                const isDone = hasProgramMap && this.elementaryStreams.every(x => x.initialized);
                if (isDone) {
                    break;
                }
                currentPos += this.packetStride;
            }
            if (!hasProgramMap) {
                if (!hasProgramAssociationTable) {
                    throw new Error('No Program Association Table found in the file.');
                }
                throw new Error('No Program Map Table found in the file.');
            }
            for (const stream of this.elementaryStreams) {
                if (stream.info.type === 'video') {
                    this.tracks.push(new input_track/* InputVideoTrack */.N0(this.input, new MpegTsVideoTrackBacking(stream)));
                }
                else {
                    this.tracks.push(new input_track/* InputAudioTrack */.Yi(this.input, new MpegTsAudioTrackBacking(stream)));
                }
            }
        })();
    }
    async getTracks() {
        await this.readMetadata();
        return this.tracks;
    }
    async getMetadataTags() {
        return {}; // Nothing for now
    }
    async computeDuration() {
        const tracks = await this.getTracks();
        const trackDurations = await Promise.all(tracks.map(x => x.computeDuration()));
        return Math.max(0, ...trackDurations);
    }
    async getMimeType() {
        await this.readMetadata();
        const tracks = await this.getTracks();
        const codecStrings = await Promise.all(tracks.map(x => x.getCodecParameterString()));
        return (0,mpeg_ts_misc/* buildMpegTsMimeType */.Vx)(codecStrings);
    }
    async readSection(startPos, full, contiguous = false) {
        let endPos = startPos;
        let currentPos = startPos;
        const chunks = [];
        let chunksByteLength = 0;
        let firstPacket = null;
        let mustAddSectionEnd = true;
        let randomAccessIndicator = 0;
        while (true) {
            const packet = await this.readPacket(currentPos);
            currentPos += this.packetStride;
            if (!packet) {
                break;
            }
            if (!firstPacket) {
                if (packet.payloadUnitStartIndicator === 0) {
                    break;
                }
                firstPacket = packet;
            }
            else {
                if (packet.pid !== firstPacket.pid) {
                    if (contiguous) {
                        break; // End of section
                    }
                    else {
                        continue; // Ignore this packet
                    }
                }
                if (packet.payloadUnitStartIndicator === 1) {
                    break;
                }
            }
            const hasAdaptationField = !!(packet.adaptationFieldControl & 0b10);
            const hasPayload = !!(packet.adaptationFieldControl & 0b01);
            let adaptationFieldLength = 0;
            if (hasAdaptationField) {
                adaptationFieldLength = 1 + packet.body[0];
                // Extract random_access_indicator from first packet's adaptation field
                if (packet === firstPacket && adaptationFieldLength > 1) {
                    randomAccessIndicator = (packet.body[1] >> 6) & 1;
                }
            }
            if (hasPayload) {
                if (adaptationFieldLength === 0) {
                    chunks.push(packet.body);
                    chunksByteLength += packet.body.byteLength;
                }
                else {
                    chunks.push(packet.body.subarray(adaptationFieldLength));
                    chunksByteLength += packet.body.byteLength - adaptationFieldLength;
                }
            }
            endPos = currentPos;
            // 64 is just "a bit of data", enough for the PES packet header
            if (!full && chunksByteLength >= 64) {
                mustAddSectionEnd = false; // Not the actual section end
                break;
            }
            // Check if we already know this is a section end
            const isKnownSectionEnd = (0,misc/* binarySearchExact */.pl)(this.sectionEndPositions, endPos, x => x) !== -1;
            if (isKnownSectionEnd) {
                mustAddSectionEnd = false;
                break;
            }
        }
        if (mustAddSectionEnd) {
            const index = (0,misc/* binarySearchLessOrEqual */.eE)(this.sectionEndPositions, endPos, x => x);
            this.sectionEndPositions.splice(index + 1, 0, endPos);
        }
        if (!firstPacket) {
            return null;
        }
        let merged;
        if (chunks.length === 1) {
            merged = chunks[0];
        }
        else {
            const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
            merged = new Uint8Array(totalLength);
            let offset = 0;
            for (const chunk of chunks) {
                merged.set(chunk, offset);
                offset += chunk.length;
            }
        }
        return {
            startPos,
            endPos: full ? endPos : null,
            pid: firstPacket.pid,
            payload: merged,
            randomAccessIndicator,
        };
    }
    async readPacketHeader(pos) {
        let slice = this.reader.requestSlice(pos, 4);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice) {
            return null;
        }
        const syncByte = (0,src_reader/* readU8 */.eo)(slice);
        if (syncByte !== 0x47) {
            throw new Error('Invalid TS packet sync byte. Likely an internal bug, please report this file.');
        }
        const nextTwoBytes = (0,src_reader/* readU16Be */.mH)(slice);
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const transportErrorIndicator = nextTwoBytes >> 15;
        const payloadUnitStartIndicator = (nextTwoBytes >> 14) & 0x1;
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const transportPriority = (nextTwoBytes >> 13) & 0x1;
        const pid = nextTwoBytes & 0x1FFF;
        const nextByte = (0,src_reader/* readU8 */.eo)(slice);
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const transportScramblingControl = nextByte >> 6;
        const adaptationFieldControl = (nextByte >> 4) & 0x3;
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const continuityCounter = nextByte & 0xF;
        return {
            payloadUnitStartIndicator,
            pid,
            adaptationFieldControl,
        };
    }
    async readPacket(pos) {
        // Code in here is duplicated from readPacketHeader for performance reasons
        let slice = this.reader.requestSlice(pos, mpeg_ts_misc/* TS_PACKET_SIZE */.ZT);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice) {
            return null;
        }
        const bytes = (0,src_reader/* readBytes */.io)(slice, mpeg_ts_misc/* TS_PACKET_SIZE */.ZT);
        const syncByte = bytes[0];
        if (syncByte !== 0x47) {
            throw new Error('Invalid TS packet sync byte. Likely an internal bug, please report this file.');
        }
        const nextTwoBytes = (bytes[1] << 8) + bytes[2];
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const transportErrorIndicator = nextTwoBytes >> 15;
        const payloadUnitStartIndicator = (nextTwoBytes >> 14) & 0x1;
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const transportPriority = (nextTwoBytes >> 13) & 0x1;
        const pid = nextTwoBytes & 0x1FFF;
        const nextByte = bytes[3];
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const transportScramblingControl = nextByte >> 6;
        const adaptationFieldControl = (nextByte >> 4) & 0x3;
        // eslint-disable-next-line @typescript-eslint/no-unused-vars
        const continuityCounter = nextByte & 0xF;
        return {
            payloadUnitStartIndicator,
            pid,
            adaptationFieldControl,
            body: bytes.subarray(4),
        };
    }
}
const readPesPacketHeader = (section) => {
    if (section.payload.byteLength < 3) {
        return null;
    }
    const bitstream = new misc/* Bitstream */._c(section.payload);
    const startCodePrefix = bitstream.readBits(24);
    if (startCodePrefix !== 0x000001) {
        return null;
    }
    const streamId = bitstream.readBits(8);
    bitstream.skipBits(16);
    if (streamId === 0b10111100 // program_stream_map
        || streamId === 0b10111110 // padding_stream
        || streamId === 0b10111111 // private_stream_2
        || streamId === 0b11110000 // ECM
        || streamId === 0b11110001 // EMM
        || streamId === 0b11111111 // program_stream_directory
        || streamId === 0b11110010 // DSMCC_stream
        || streamId === 0b11111000 // ITU-T Rec. H.222.1 type E stream
    ) {
        return null;
    }
    bitstream.skipBits(8);
    const ptsDtsFlags = bitstream.readBits(2);
    bitstream.skipBits(14);
    let pts = 0;
    if (ptsDtsFlags === 0b10 || ptsDtsFlags === 0b11) {
        bitstream.skipBits(4);
        pts += bitstream.readBits(3) * (1 << 30);
        bitstream.skipBits(1);
        pts += bitstream.readBits(15) * (1 << 15);
        bitstream.skipBits(1);
        pts += bitstream.readBits(15);
    }
    else {
        throw new Error('PES packets without PTS are not currently supported. If you think this file should be supported,'
            + ' please report it.');
    }
    return {
        sectionStartPos: section.startPos,
        sectionEndPos: section.endPos,
        pts,
        randomAccessIndicator: section.randomAccessIndicator,
    };
};
const readPesPacket = (section) => {
    (0,misc/* assert */.vA)(section.endPos !== null); // Can only read full PES packets from fully read sections
    const header = readPesPacketHeader(section);
    if (!header) {
        return null;
    }
    const bitstream = new misc/* Bitstream */._c(section.payload);
    bitstream.skipBits(32);
    const pesPacketLength = bitstream.readBits(16);
    const BYTES_UNTIL_END_OF_PES_PACKET_LENGTH = 6;
    bitstream.skipBits(16);
    const pesHeaderDataLength = bitstream.readBits(8);
    const pesHeaderEndPos = bitstream.pos + 8 * pesHeaderDataLength;
    bitstream.pos = pesHeaderEndPos;
    const bytePos = pesHeaderEndPos / 8;
    (0,misc/* assert */.vA)(Number.isInteger(bytePos));
    const data = section.payload.subarray(bytePos, 
    // "A value of 0 indicates that the PES packet length is neither specified nor bounded and is allowed only in
    // PES packets whose payload consists of bytes from a video elementary stream contained in
    // transport stream packets."
    pesPacketLength > 0
        ? BYTES_UNTIL_END_OF_PES_PACKET_LENGTH + pesPacketLength
        : section.payload.byteLength);
    return {
        ...header,
        data,
    };
};
class MpegTsTrackBacking {
    constructor(elementaryStream) {
        this.elementaryStream = elementaryStream;
        this.packetBuffers = new WeakMap();
        /** Used for recreating PacketBuffers if necessary. */
        this.packetSectionStarts = new WeakMap();
    }
    getId() {
        return this.elementaryStream.pid;
    }
    getNumber() {
        const demuxer = this.elementaryStream.demuxer;
        const trackType = this.elementaryStream.info.type;
        let number = 0;
        for (const track of demuxer.tracks) {
            if (track.type === trackType) {
                number++;
            }
            (0,misc/* assert */.vA)(track._backing instanceof MpegTsTrackBacking);
            if (track._backing.elementaryStream === this.elementaryStream) {
                break;
            }
        }
        return number;
    }
    getCodec() {
        throw new Error('Not implemented on base class.');
    }
    getInternalCodecId() {
        return this.elementaryStream.streamType;
    }
    getName() {
        return null;
    }
    getLanguageCode() {
        return misc/* UNDETERMINED_LANGUAGE */.IR;
    }
    getDisposition() {
        return metadata/* DEFAULT_TRACK_DISPOSITION */.gM;
    }
    getTimeResolution() {
        return mpeg_ts_misc/* TIMESCALE */.cS;
    }
    async computeDuration() {
        const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
        return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    async getFirstTimestamp() {
        const firstPacket = await this.getFirstPacket({ metadataOnly: true });
        return firstPacket?.timestamp ?? 0;
    }
    createEncodedPacket(suppliedPacket, duration, options) {
        let packetType;
        if (this.allPacketsAreKeyPackets()) {
            packetType = 'key';
        }
        else {
            packetType = suppliedPacket.randomAccessIndicator === 1
                ? 'key'
                : 'delta';
        }
        return new src_packet/* EncodedPacket */.Z(options.metadataOnly ? src_packet/* PLACEHOLDER_DATA */.T : suppliedPacket.data, packetType, suppliedPacket.pts / mpeg_ts_misc/* TIMESCALE */.cS, Math.max(duration / mpeg_ts_misc/* TIMESCALE */.cS, 0), suppliedPacket.sequenceNumber, suppliedPacket.data.byteLength);
    }
    async getFirstPacket(options) {
        const section = this.elementaryStream.firstSection;
        (0,misc/* assert */.vA)(section);
        const pesPacket = readPesPacket(section);
        (0,misc/* assert */.vA)(pesPacket);
        const context = new PacketReadingContext(this.elementaryStream, pesPacket);
        const buffer = new PacketBuffer(this, context);
        const result = await buffer.readNext();
        if (!result) {
            return null;
        }
        // result.packet.randomAccessIndicator = 1; // Assume the first packet is always a key packet
        const packet = this.createEncodedPacket(result.packet, result.duration, options);
        this.packetBuffers.set(packet, buffer);
        this.packetSectionStarts.set(packet, result.packet.sectionStartPos);
        return packet;
    }
    async getNextPacket(packet, options) {
        let buffer = this.packetBuffers.get(packet);
        if (buffer) {
            // Fast path
            const result = await buffer.readNext();
            if (!result) {
                return null;
            }
            // Remove PacketBuffer access from the old packet, it belongs to the next packet now
            this.packetBuffers.delete(packet);
            const newPacket = this.createEncodedPacket(result.packet, result.duration, options);
            this.packetBuffers.set(newPacket, buffer);
            this.packetSectionStarts.set(newPacket, result.packet.sectionStartPos);
            return newPacket;
        }
        // No buffer, we gotta do some rereading
        const sectionStartPos = this.packetSectionStarts.get(packet);
        if (sectionStartPos === undefined) {
            throw new Error('Packet was not created from this track.');
        }
        const demuxer = this.elementaryStream.demuxer;
        const section = await demuxer.readSection(sectionStartPos, true);
        (0,misc/* assert */.vA)(section);
        const pesPacket = readPesPacket(section);
        (0,misc/* assert */.vA)(pesPacket);
        const context = new PacketReadingContext(this.elementaryStream, pesPacket);
        buffer = new PacketBuffer(this, context);
        // Advance until we pass the current packet's sequence number
        const targetSequenceNumber = packet.sequenceNumber;
        while (true) {
            const result = await buffer.readNext();
            if (!result) {
                return null;
            }
            if (result.packet.sequenceNumber > targetSequenceNumber) {
                // We found the next packet!
                const newPacket = this.createEncodedPacket(result.packet, result.duration, options);
                this.packetBuffers.set(newPacket, buffer);
                this.packetSectionStarts.set(newPacket, result.packet.sectionStartPos);
                return newPacket;
            }
        }
    }
    async getNextKeyPacket(packet, options) {
        let currentPacket = packet;
        // Just loop until we hit one
        while (true) {
            currentPacket = await this.getNextPacket(currentPacket, options);
            if (!currentPacket) {
                return null;
            }
            if (currentPacket.type === 'key') {
                return currentPacket;
            }
        }
    }
    getPacket(timestamp, options) {
        return this.doPacketLookup(timestamp, false, options);
    }
    getKeyPacket(timestamp, options) {
        return this.doPacketLookup(timestamp, true, options);
    }
    /**
     * Searches for the packet with the largest timestamp not larger than `timestamp` in the file, using a combination
     * of chunk-based binary search and linear refinement. The reason the coarse search is done in large chunks is to
     * make it more performant for small files and over high-latency readers such as the network.
     */
    async doPacketLookup(timestamp, keyframesOnly, options) {
        const searchPts = (0,misc/* roundIfAlmostInteger */.aI)(timestamp * mpeg_ts_misc/* TIMESCALE */.cS);
        const demuxer = this.elementaryStream.demuxer;
        const { reader, seekChunkSize } = demuxer;
        const pid = this.elementaryStream.pid;
        const findFirstPesPacketHeaderInChunk = async (startPos, endPos) => {
            let currentPos = startPos;
            while (currentPos < endPos) {
                const packetHeader = await demuxer.readPacketHeader(currentPos);
                if (!packetHeader) {
                    return null;
                }
                if (packetHeader.pid === pid && packetHeader.payloadUnitStartIndicator === 1) {
                    const section = await demuxer.readSection(currentPos, false);
                    if (!section) {
                        return null;
                    }
                    const pesPacketHeader = readPesPacketHeader(section);
                    if (pesPacketHeader) {
                        return pesPacketHeader;
                    }
                }
                currentPos += demuxer.packetStride;
            }
            return null;
        };
        // Get the first PES packet of the track (always treated as a key frame candidate)
        const firstSection = this.elementaryStream.firstSection;
        (0,misc/* assert */.vA)(firstSection);
        const firstPesPacketHeader = readPesPacketHeader(firstSection);
        (0,misc/* assert */.vA)(firstPesPacketHeader);
        if (searchPts < firstPesPacketHeader.pts) {
            // We're before the first packet, definitely nothing here
            return null;
        }
        let scanStartPos;
        const referencePesPackets = this.elementaryStream.referencePesPackets;
        const referencePointIndex = (0,misc/* binarySearchLessOrEqual */.eE)(referencePesPackets, searchPts, x => x.pts);
        const referencePoint = referencePointIndex !== -1 ? referencePesPackets[referencePointIndex] : null;
        if (referencePoint && searchPts - referencePoint.pts < mpeg_ts_misc/* TIMESCALE */.cS / 2) {
            // Reference point ain't too far away, prefer it over the chunk search
            scanStartPos = referencePoint.sectionStartPos;
        }
        else {
            let startChunkIndex = 0;
            if (reader.fileSize !== null) {
                const numChunks = Math.ceil(reader.fileSize / seekChunkSize);
                if (numChunks > 1) {
                    // Binary search to find the chunk with highest index whose first PES has pts <= searchPts
                    let low = 0;
                    let high = numChunks - 1;
                    startChunkIndex = low;
                    while (low <= high) {
                        const mid = Math.floor((low + high) / 2);
                        const chunkStartPos = (0,misc/* floorToMultiple */.Q5)(mid * seekChunkSize, demuxer.packetStride)
                            + firstPesPacketHeader.sectionStartPos;
                        const chunkEndPos = chunkStartPos + seekChunkSize;
                        const pesHeader = await findFirstPesPacketHeaderInChunk(chunkStartPos, chunkEndPos);
                        if (!pesHeader) {
                            // No PES packet found in this chunk, search left
                            high = mid - 1;
                            continue;
                        }
                        if (pesHeader.pts <= searchPts) {
                            // This chunk's first PES is <= searchPts, it's a candidate
                            startChunkIndex = mid;
                            low = mid + 1; // Search right
                        }
                        else {
                            // Search left
                            high = mid - 1;
                        }
                    }
                }
            }
            scanStartPos = (0,misc/* floorToMultiple */.Q5)(startChunkIndex * seekChunkSize, demuxer.packetStride) + firstPesPacketHeader.sectionStartPos;
        }
        // Find the first PES packet at or after scanStartPos
        let currentPesHeader = await findFirstPesPacketHeaderInChunk(scanStartPos, reader.fileSize ?? Infinity);
        if (!currentPesHeader) {
            // Fallback to first packet
            currentPesHeader = firstPesPacketHeader;
        }
        const reorderSize = this.getReorderSize();
        const retrieveEncodedPacket = async (sectionStartPos, predicate) => {
            // Load the relevant section in full
            const section = await demuxer.readSection(sectionStartPos, true);
            (0,misc/* assert */.vA)(section);
            const pesPacket = readPesPacket(section);
            (0,misc/* assert */.vA)(pesPacket);
            const context = new PacketReadingContext(this.elementaryStream, pesPacket);
            const buffer = new PacketBuffer(this, context);
            // Advance until the top-most presentation timestamp crosses or equals searchPts
            while (true) {
                const topPts = (0,misc/* last */._g)(buffer.presentationOrderPackets)?.pts ?? -Infinity;
                if (topPts >= searchPts) {
                    break;
                }
                const didRead = await buffer.readNextPacket();
                if (!didRead) {
                    break;
                }
            }
            const targetIndex = (0,misc/* findLastIndex */.Kl)(buffer.presentationOrderPackets, predicate);
            if (targetIndex === -1) {
                return null;
            }
            const targetPacket = buffer.presentationOrderPackets[targetIndex];
            const lastDuration = targetIndex === 0
                ? 0
                : targetPacket.pts - buffer.presentationOrderPackets[targetIndex - 1].pts;
            // Pop packets in decode order until we hit the target packet
            while (buffer.decodeOrderPackets[0] !== targetPacket) {
                buffer.decodeOrderPackets.shift();
            }
            buffer.lastDuration = lastDuration; // Kinda ugly but necessary fix
            const result = await buffer.readNext();
            (0,misc/* assert */.vA)(result);
            const packet = this.createEncodedPacket(result.packet, result.duration, options);
            this.packetBuffers.set(packet, buffer);
            this.packetSectionStarts.set(packet, result.packet.sectionStartPos);
            return packet;
        };
        if (!keyframesOnly || this.allPacketsAreKeyPackets()) {
            // Normat packet lookup case. Slightly easier since we just need to search (mostly) forward to find the
            // packet.
            // Linear scan to find the PES packet with largest pts <= searchPts. This will be used as the "midpoint"
            // of the next refinement step (which is needed because of B-frames).
            outer: while (true) {
                let currentPos = currentPesHeader.sectionStartPos + demuxer.packetStride;
                while (true) {
                    const packetHeader = await demuxer.readPacketHeader(currentPos);
                    if (!packetHeader) {
                        break outer; // End of file
                    }
                    if (packetHeader.pid === pid && packetHeader.payloadUnitStartIndicator === 1) {
                        const section = await demuxer.readSection(currentPos, false);
                        if (section) {
                            const nextPesHeader = readPesPacketHeader(section);
                            if (nextPesHeader) {
                                if (nextPesHeader.pts > searchPts) {
                                    break outer;
                                }
                                currentPesHeader = nextPesHeader;
                                maybeInsertReferencePacket(this.elementaryStream, nextPesHeader);
                                break;
                            }
                        }
                    }
                    currentPos += demuxer.packetStride;
                }
            }
            // Rewind by reorderSize PES packets (even for audio! To ensure proper durations)
            outer: for (let i = 0; i < reorderSize; i++) {
                let pos = currentPesHeader.sectionStartPos - demuxer.packetStride;
                while (pos >= demuxer.packetOffset) {
                    const packetHeader = await demuxer.readPacketHeader(pos);
                    if (!packetHeader) {
                        break outer;
                    }
                    if (packetHeader.pid === pid && packetHeader.payloadUnitStartIndicator === 1) {
                        const section = await demuxer.readSection(pos, false);
                        if (section) {
                            const header = readPesPacketHeader(section);
                            if (header) {
                                currentPesHeader = header;
                                break;
                            }
                        }
                    }
                    pos -= demuxer.packetStride;
                }
            }
            return retrieveEncodedPacket(currentPesHeader.sectionStartPos, p => p.pts <= searchPts);
        }
        else {
            // Key packet lookup case. Slightly harder since the starting chunk may not have a key packet at all, which
            // means we might need to search the previous chunks until we find something.
            let currentChunkStartPos = scanStartPos;
            let nextChunkStartPos = null; // "next" as in later in the file, even tho we scan backwards
            while (true) {
                let bestKeyPesHeader = null;
                const isFirstChunk = currentChunkStartPos <= firstPesPacketHeader.sectionStartPos;
                let pesHeader;
                if (isFirstChunk) {
                    pesHeader = firstPesPacketHeader;
                    // Since we force the first packet to be seen as a key frame:
                    bestKeyPesHeader = firstPesPacketHeader;
                }
                else {
                    pesHeader = await findFirstPesPacketHeaderInChunk(currentChunkStartPos, reader.fileSize ?? Infinity);
                }
                let passedSearchPts = false;
                let lookaheadCount = 0;
                outer: while (pesHeader) {
                    if (nextChunkStartPos !== null && pesHeader.sectionStartPos >= nextChunkStartPos) {
                        // Stop at the next chunk boundary
                        break;
                    }
                    const isKeyCandidate = pesHeader.randomAccessIndicator === 1;
                    if (isKeyCandidate && pesHeader.pts <= searchPts) {
                        bestKeyPesHeader = pesHeader;
                    }
                    if (pesHeader.pts > searchPts) {
                        passedSearchPts = true;
                    }
                    // If we've passed searchPts, do lookahead for reorderSize-1 more packets just to be sure
                    if (passedSearchPts) {
                        lookaheadCount++;
                        if (lookaheadCount >= reorderSize) {
                            break;
                        }
                    }
                    // Find next PES packet
                    let currentPos = pesHeader.sectionStartPos + demuxer.packetStride;
                    while (true) {
                        const packetHeader = await demuxer.readPacketHeader(currentPos);
                        if (!packetHeader) {
                            break outer; // End of file
                        }
                        if (packetHeader.pid === pid && packetHeader.payloadUnitStartIndicator === 1) {
                            const section = await demuxer.readSection(currentPos, false);
                            if (section) {
                                pesHeader = readPesPacketHeader(section);
                                if (pesHeader) {
                                    maybeInsertReferencePacket(this.elementaryStream, pesHeader);
                                    break;
                                }
                            }
                        }
                        currentPos += demuxer.packetStride;
                    }
                }
                if (bestKeyPesHeader) {
                    let startPesHeader = bestKeyPesHeader;
                    if (lookaheadCount === 0) {
                        // Packet is at the end of stream, let's rewind a little to obtain the correct packet duration
                        outer: for (let i = 0; i < reorderSize - 1; i++) {
                            let pos = startPesHeader.sectionStartPos - demuxer.packetStride;
                            while (pos >= demuxer.packetOffset) {
                                const packetHeader = await demuxer.readPacketHeader(pos);
                                if (!packetHeader) {
                                    break outer;
                                }
                                if (packetHeader.pid === pid && packetHeader.payloadUnitStartIndicator === 1) {
                                    const section = await demuxer.readSection(pos, false);
                                    if (section) {
                                        const header = readPesPacketHeader(section);
                                        if (header) {
                                            startPesHeader = header;
                                            break;
                                        }
                                    }
                                }
                                pos -= demuxer.packetStride;
                            }
                        }
                    }
                    const encodedPacket = await retrieveEncodedPacket(startPesHeader.sectionStartPos, p => p.pts <= searchPts && p.randomAccessIndicator === 1);
                    (0,misc/* assert */.vA)(encodedPacket); // There must be one
                    return encodedPacket;
                }
                (0,misc/* assert */.vA)(!isFirstChunk); // Impossible not to find a key frame in the first chunk
                // No key frame found in this chunk, move one chunk to the left
                nextChunkStartPos = currentChunkStartPos;
                currentChunkStartPos = Math.max((0,misc/* floorToMultiple */.Q5)(currentChunkStartPos - firstPesPacketHeader.sectionStartPos - seekChunkSize, demuxer.packetStride) + firstPesPacketHeader.sectionStartPos, firstPesPacketHeader.sectionStartPos);
            }
        }
    }
}
class MpegTsVideoTrackBacking extends MpegTsTrackBacking {
    constructor(elementaryStream) {
        super(elementaryStream);
        this.elementaryStream = elementaryStream;
        this.decoderConfig = {
            codec: (0,codec/* extractVideoCodecString */.QP)({
                width: this.elementaryStream.info.width,
                height: this.elementaryStream.info.height,
                codec: this.elementaryStream.info.codec,
                codecDescription: null,
                colorSpace: this.elementaryStream.info.colorSpace,
                avcType: 1,
                avcCodecInfo: this.elementaryStream.info.avcCodecInfo,
                hevcCodecInfo: this.elementaryStream.info.hevcCodecInfo,
                vp9CodecInfo: null,
                av1CodecInfo: null,
            }),
            codedWidth: this.elementaryStream.info.width,
            codedHeight: this.elementaryStream.info.height,
            colorSpace: this.elementaryStream.info.colorSpace,
        };
    }
    getCodec() {
        return this.elementaryStream.info.codec;
    }
    getCodedWidth() {
        return this.elementaryStream.info.width;
    }
    getCodedHeight() {
        return this.elementaryStream.info.height;
    }
    getRotation() {
        return 0;
    }
    async getColorSpace() {
        return this.elementaryStream.info.colorSpace;
    }
    async canBeTransparent() {
        return false;
    }
    async getDecoderConfig() {
        return this.decoderConfig;
    }
    allPacketsAreKeyPackets() {
        return false;
    }
    getReorderSize() {
        return this.elementaryStream.info.reorderSize;
    }
}
class MpegTsAudioTrackBacking extends MpegTsTrackBacking {
    constructor(elementaryStream) {
        super(elementaryStream);
        this.elementaryStream = elementaryStream;
    }
    getCodec() {
        return this.elementaryStream.info.codec;
    }
    getNumberOfChannels() {
        return this.elementaryStream.info.numberOfChannels;
    }
    getSampleRate() {
        return this.elementaryStream.info.sampleRate;
    }
    async getDecoderConfig() {
        return {
            codec: (0,codec/* extractAudioCodecString */.X0)({
                codec: this.elementaryStream.info.codec,
                codecDescription: null,
                aacCodecInfo: this.elementaryStream.info.aacCodecInfo,
            }),
            numberOfChannels: this.elementaryStream.info.numberOfChannels,
            sampleRate: this.elementaryStream.info.sampleRate,
        };
    }
    allPacketsAreKeyPackets() {
        return true;
    }
    getReorderSize() {
        return 1; // No reordering, since no B-frames because goated
    }
}
const maybeInsertReferencePacket = (elementaryStream, pesPacketHeader) => {
    const referencePesPackets = elementaryStream.referencePesPackets;
    const index = (0,misc/* binarySearchLessOrEqual */.eE)(referencePesPackets, pesPacketHeader.sectionStartPos, x => x.sectionStartPos);
    if (index >= 0) {
        // Since pts and file position don't necessarily have a monotonic relationship (since pts can go crazy),
        // let's see if inserting at the given index would violate the pts order. If so, return.
        const entry = referencePesPackets[index];
        if (pesPacketHeader.pts <= entry.pts) {
            return false;
        }
        const minByteDistance = elementaryStream.demuxer.minReferencePointByteDistance;
        if (pesPacketHeader.sectionStartPos - entry.sectionStartPos < minByteDistance) {
            // Too close
            return false;
        }
        if (index < referencePesPackets.length - 1) {
            const nextEntry = referencePesPackets[index + 1];
            if (nextEntry.pts < pesPacketHeader.pts) {
                // Out of order
                return false;
            }
            if (nextEntry.sectionStartPos - pesPacketHeader.sectionStartPos < minByteDistance) {
                // Too close
                return false;
            }
        }
    }
    referencePesPackets.splice(index + 1, 0, pesPacketHeader);
    return true;
};
const markNextPacket = async (context) => {
    (0,misc/* assert */.vA)(!context.suppliedPacket);
    const elementaryStream = context.elementaryStream;
    if (elementaryStream.info.type === 'video') {
        const codec = elementaryStream.info.codec;
        const CHUNK_SIZE = 1024;
        if (codec !== 'avc' && codec !== 'hevc') {
            throw new Error('Unhandled.');
        }
        let packetStartPos = null;
        while (true) {
            let remaining = context.ensureBuffered(CHUNK_SIZE);
            if (remaining instanceof Promise)
                remaining = await remaining;
            if (remaining === 0) {
                break;
            }
            const chunkStartPos = context.currentPos;
            const chunk = context.readBytes(remaining);
            const length = chunk.byteLength;
            let i = 0;
            while (i < length) {
                const zeroIndex = chunk.indexOf(0, i);
                if (zeroIndex === -1 || zeroIndex >= length) {
                    break;
                }
                i = zeroIndex;
                // Check if we have enough bytes to identify a start code
                const posBeforeZero = chunkStartPos + i;
                // Need at least 4 more bytes after the 0x00 to check for start code + NAL type
                if (i + 4 >= length) {
                    // Not enough data in current chunk, seek back and let the next iteration handle it
                    context.seekTo(posBeforeZero);
                    break;
                }
                const b1 = chunk[i + 1];
                const b2 = chunk[i + 2];
                const b3 = chunk[i + 3];
                let startCodeLength = 0;
                let nalUnitTypeByte = null;
                // Check for 4-byte start code (0x00000001)
                if (b1 === 0x00 && b2 === 0x00 && b3 === 0x01) {
                    startCodeLength = 4;
                    nalUnitTypeByte = chunk[i + 4];
                }
                else if (b1 === 0x00 && b2 === 0x01) {
                    // 3-byte start code (0x000001)
                    startCodeLength = 3;
                    nalUnitTypeByte = b3;
                }
                if (startCodeLength === 0) {
                    // Not a start code, continue
                    i++;
                    continue;
                }
                const startCodePos = posBeforeZero;
                if (packetStartPos === null) {
                    // This is our first start code, mark packet start
                    packetStartPos = startCodePos;
                    i += startCodeLength;
                    continue;
                }
                // We have a second start code. Check if it's an AUD.
                if (nalUnitTypeByte !== null) {
                    const nalUnitType = codec === 'avc'
                        ? (0,codec_data/* extractNalUnitTypeForAvc */.uN)(nalUnitTypeByte)
                        : (0,codec_data/* extractNalUnitTypeForHevc */.O9)(nalUnitTypeByte);
                    const isAud = codec === 'avc'
                        ? nalUnitType === codec_data/* AvcNalUnitType */.mY.AUD
                        : nalUnitType === codec_data/* HevcNalUnitType */.iJ.AUD_NUT;
                    if (isAud) {
                        // End the packet at this start code (before the AUD)
                        const packetLength = startCodePos - packetStartPos;
                        context.seekTo(packetStartPos);
                        return context.supplyPacket(packetLength, 0);
                    }
                }
                // Not an AUD, continue searching
                i += startCodeLength;
            }
            if (remaining < CHUNK_SIZE) {
                // End of stream
                break;
            }
        }
        // End of stream - return remaining data if we have a packet start
        if (packetStartPos !== null) {
            const packetLength = context.endPos - packetStartPos;
            context.seekTo(packetStartPos);
            return context.supplyPacket(packetLength, 0);
        }
    }
    else {
        const codec = elementaryStream.info.codec;
        const CHUNK_SIZE = 128;
        while (true) {
            let remaining = context.ensureBuffered(CHUNK_SIZE);
            if (remaining instanceof Promise)
                remaining = await remaining;
            const startPos = context.currentPos;
            while (context.currentPos - startPos < remaining) {
                const byte = context.readU8();
                if (codec === 'aac') {
                    if (byte !== 0xff) {
                        continue;
                    }
                    context.skip(-1);
                    const possibleHeaderStartPos = context.currentPos;
                    let remaining = context.ensureBuffered(adts_reader/* MAX_ADTS_FRAME_HEADER_SIZE */.Y$);
                    if (remaining instanceof Promise)
                        remaining = await remaining;
                    if (remaining < adts_reader/* MAX_ADTS_FRAME_HEADER_SIZE */.Y$) {
                        return;
                    }
                    const headerBytes = context.readBytes(adts_reader/* MAX_ADTS_FRAME_HEADER_SIZE */.Y$);
                    const header = (0,adts_reader/* readAdtsFrameHeader */.lh)(src_reader/* FileSlice */.x$.tempFromBytes(headerBytes));
                    if (header) {
                        context.seekTo(possibleHeaderStartPos);
                        let remaining = context.ensureBuffered(header.frameLength);
                        if (remaining instanceof Promise)
                            remaining = await remaining;
                        return context.supplyPacket(remaining, Math.round(SAMPLES_PER_AAC_FRAME * mpeg_ts_misc/* TIMESCALE */.cS / elementaryStream.info.sampleRate));
                    }
                    else {
                        context.seekTo(possibleHeaderStartPos + 1);
                    }
                }
                else if (codec === 'mp3') {
                    if (byte !== 0xff) {
                        continue;
                    }
                    context.skip(-1);
                    const possibleHeaderStartPos = context.currentPos;
                    let remaining = context.ensureBuffered(mp3_misc/* FRAME_HEADER_SIZE */.Yq);
                    if (remaining instanceof Promise)
                        remaining = await remaining;
                    if (remaining < mp3_misc/* FRAME_HEADER_SIZE */.Yq) {
                        return;
                    }
                    const headerBytes = context.readBytes(mp3_misc/* FRAME_HEADER_SIZE */.Yq);
                    const word = (0,misc/* toDataView */.Zc)(headerBytes).getUint32(0);
                    const result = (0,mp3_misc/* readMp3FrameHeader */.P8)(word, null);
                    if (result.header) {
                        context.seekTo(possibleHeaderStartPos);
                        let remaining = context.ensureBuffered(result.header.totalSize);
                        if (remaining instanceof Promise)
                            remaining = await remaining;
                        const duration = result.header.audioSamplesInFrame * mpeg_ts_misc/* TIMESCALE */.cS
                            / elementaryStream.info.sampleRate;
                        return context.supplyPacket(remaining, Math.round(duration));
                    }
                    else {
                        context.seekTo(possibleHeaderStartPos + 1);
                    }
                }
                else if (codec === 'ac3') {
                    if (byte !== 0x0b) {
                        continue;
                    }
                    context.skip(-1);
                    const possibleSyncPos = context.currentPos;
                    // Need at least 5 bytes for sync word + CRC + fscod/frmsizecod
                    let remaining = context.ensureBuffered(5);
                    if (remaining instanceof Promise)
                        remaining = await remaining;
                    if (remaining < 5) {
                        return;
                    }
                    const headerBytes = context.readBytes(5);
                    // Verify sync word (0x0B77)
                    if (headerBytes[0] !== 0x0b || headerBytes[1] !== 0x77) {
                        context.seekTo(possibleSyncPos + 1);
                        continue;
                    }
                    const fscod = headerBytes[4] >> 6;
                    const frmsizecod = headerBytes[4] & 0x3f;
                    if (fscod === 3 || frmsizecod > 37) {
                        // Invalid
                        context.seekTo(possibleSyncPos + 1);
                        continue;
                    }
                    const frameSize = codec_data/* AC3_FRAME_SIZES */.Pl[3 * frmsizecod + fscod];
                    (0,misc/* assert */.vA)(frameSize !== undefined);
                    context.seekTo(possibleSyncPos);
                    remaining = context.ensureBuffered(frameSize);
                    if (remaining instanceof Promise)
                        remaining = await remaining;
                    const duration = Math.round(codec_data/* AC3_SAMPLES_PER_FRAME */.Ir * mpeg_ts_misc/* TIMESCALE */.cS / elementaryStream.info.sampleRate);
                    return context.supplyPacket(remaining, duration);
                }
                else if (codec === 'eac3') {
                    if (byte !== 0x0b) {
                        continue;
                    }
                    context.skip(-1);
                    const possibleSyncPos = context.currentPos;
                    // Need at least 5 bytes for E-AC-3 header parsing (sync word + frmsiz + fscod/numblkscod)
                    let remaining = context.ensureBuffered(5);
                    if (remaining instanceof Promise)
                        remaining = await remaining;
                    if (remaining < 5) {
                        return;
                    }
                    const headerBytes = context.readBytes(5);
                    if (headerBytes[0] !== 0x0b || headerBytes[1] !== 0x77) {
                        context.seekTo(possibleSyncPos + 1);
                        continue;
                    }
                    const frmsiz = ((headerBytes[2] & 0x07) << 8) | headerBytes[3];
                    const frameSize = (frmsiz + 1) * 2;
                    const fscod = headerBytes[4] >> 6;
                    const numblkscod = fscod === 3 ? 3 : (headerBytes[4] >> 4) & 0x03;
                    const numblks = codec_data/* EAC3_NUMBLKS_TABLE */.FY[numblkscod];
                    context.seekTo(possibleSyncPos);
                    remaining = context.ensureBuffered(frameSize);
                    if (remaining instanceof Promise)
                        remaining = await remaining;
                    // Duration = numblks * 256 samples per block
                    const samplesPerFrame = numblks * 256;
                    const duration = Math.round(samplesPerFrame * mpeg_ts_misc/* TIMESCALE */.cS / elementaryStream.info.sampleRate);
                    return context.supplyPacket(remaining, duration);
                }
                else {
                    throw new Error('Unhandled.');
                }
            }
            if (remaining < CHUNK_SIZE) {
                break;
            }
        }
    }
};
/** Stateful context used to extract exact encoded packets from the underlying data stream. */
class PacketReadingContext {
    constructor(elementaryStream, startingPesPacket) {
        this.currentPos = 0; // Relative to the data in startingPesPacket
        this.pesPackets = [];
        this.currentPesPacketIndex = 0;
        this.currentPesPacketPos = 0;
        this.endPos = 0;
        this.nextPts = 0;
        this.suppliedPacket = null;
        this.elementaryStream = elementaryStream;
        this.pid = elementaryStream.pid;
        this.demuxer = elementaryStream.demuxer;
        this.startingPesPacket = startingPesPacket;
    }
    clone() {
        const clone = new PacketReadingContext(this.elementaryStream, this.startingPesPacket);
        clone.currentPos = this.currentPos;
        clone.pesPackets = [...this.pesPackets];
        clone.currentPesPacketIndex = this.currentPesPacketIndex;
        clone.currentPesPacketPos = this.currentPesPacketPos;
        clone.endPos = this.endPos;
        clone.nextPts = this.nextPts;
        return clone;
    }
    ensureBuffered(length) {
        const remaining = this.endPos - this.currentPos;
        if (remaining >= length) {
            return length;
        }
        return this.bufferData(length - remaining)
            .then(() => Math.min(this.endPos - this.currentPos, length));
    }
    getCurrentPesPacket() {
        const packet = this.pesPackets[this.currentPesPacketIndex];
        (0,misc/* assert */.vA)(packet);
        return packet;
    }
    async bufferData(length) {
        const targetEndPos = this.endPos + length;
        while (this.endPos < targetEndPos) {
            let pesPacket;
            if (this.pesPackets.length === 0) {
                pesPacket = this.startingPesPacket;
            }
            else {
                // Find the next PES packet
                let currentPos = (0,misc/* last */._g)(this.pesPackets).sectionEndPos;
                (0,misc/* assert */.vA)(currentPos !== null);
                while (true) {
                    const packetHeader = await this.demuxer.readPacketHeader(currentPos);
                    if (!packetHeader) {
                        return;
                    }
                    if (packetHeader.pid === this.pid) {
                        const nextSection = await this.demuxer.readSection(currentPos, true);
                        if (!nextSection) {
                            return;
                        }
                        const nextPesPacket = readPesPacket(nextSection);
                        if (nextPesPacket) {
                            pesPacket = nextPesPacket;
                            break;
                        }
                    }
                    currentPos += this.demuxer.packetStride;
                }
            }
            this.pesPackets.push(pesPacket);
            this.endPos += pesPacket.data.byteLength;
            if (this.pesPackets.length === 1) {
                // It's the first PES packet, set the PTS
                this.nextPts = pesPacket.pts;
            }
        }
    }
    readBytes(length) {
        const currentPesPacket = this.getCurrentPesPacket();
        const relativeStartOffset = this.currentPos - this.currentPesPacketPos;
        const relativeEndOffset = relativeStartOffset + length;
        this.currentPos += length;
        if (relativeEndOffset <= currentPesPacket.data.byteLength) {
            // Request can be satisfied with one PES packet
            return currentPesPacket.data.subarray(relativeStartOffset, relativeEndOffset);
        }
        // Data spans multiple PES packets, we must do some merging
        const result = new Uint8Array(length);
        result.set(currentPesPacket.data.subarray(relativeStartOffset));
        let offset = currentPesPacket.data.byteLength - relativeStartOffset;
        while (true) {
            this.advanceCurrentPacket();
            const currentPesPacket = this.getCurrentPesPacket();
            const relativeEndOffset = length - offset;
            if (relativeEndOffset <= currentPesPacket.data.byteLength) {
                result.set(currentPesPacket.data.subarray(0, relativeEndOffset), offset);
                break;
            }
            result.set(currentPesPacket.data, offset);
            offset += currentPesPacket.data.byteLength;
        }
        return result;
    }
    readU8() {
        let currentPesPacket = this.getCurrentPesPacket();
        const relativeOffset = this.currentPos - this.currentPesPacketPos;
        this.currentPos++;
        if (relativeOffset < currentPesPacket.data.byteLength) {
            return currentPesPacket.data[relativeOffset];
        }
        this.advanceCurrentPacket();
        currentPesPacket = this.getCurrentPesPacket();
        return currentPesPacket.data[0];
    }
    seekTo(pos) {
        if (pos === this.currentPos) {
            return;
        }
        if (pos < this.currentPos) {
            while (pos < this.currentPesPacketPos) {
                // Move to the previous PES packet
                this.currentPesPacketIndex--;
                const currentPacket = this.getCurrentPesPacket();
                this.currentPesPacketPos -= currentPacket.data.byteLength;
                this.nextPts = currentPacket.pts;
            }
        }
        else {
            while (true) {
                // Move to the next PES packet
                const currentPesPacket = this.getCurrentPesPacket();
                const currentEndPos = this.currentPesPacketPos + currentPesPacket.data.byteLength;
                if (pos < currentEndPos) {
                    break;
                }
                this.currentPesPacketPos += currentPesPacket.data.byteLength;
                this.currentPesPacketIndex++;
                this.nextPts = this.getCurrentPesPacket().pts;
            }
        }
        this.currentPos = pos;
    }
    skip(n) {
        this.seekTo(this.currentPos + n);
    }
    advanceCurrentPacket() {
        this.currentPesPacketPos += this.getCurrentPesPacket().data.byteLength;
        this.currentPesPacketIndex++;
        this.nextPts = this.getCurrentPesPacket().pts;
    }
    /** Supplies the context with a new encoded packet, beginning at the current position. */
    supplyPacket(packetLength, intrinsicDuration) {
        const currentPesPacket = this.getCurrentPesPacket();
        maybeInsertReferencePacket(this.elementaryStream, currentPesPacket);
        const pts = this.nextPts;
        this.nextPts += intrinsicDuration;
        const sectionStartPos = currentPesPacket.sectionStartPos;
        // The sequence number is the starting position of the section the PES packet is in, PLUS the offset within the
        // PES packet where the packet starts.
        const sequenceNumber = sectionStartPos + (this.currentPos - this.currentPesPacketPos);
        const data = this.readBytes(packetLength);
        let randomAccessIndicator = currentPesPacket.randomAccessIndicator;
        (0,misc/* assert */.vA)(this.elementaryStream.firstSection);
        if (currentPesPacket.sectionStartPos === this.elementaryStream.firstSection.startPos) {
            randomAccessIndicator = 1; // Force the first PES packet to behave like a key packet always
        }
        this.suppliedPacket = {
            pts,
            data,
            sequenceNumber,
            sectionStartPos,
            randomAccessIndicator,
        };
        this.pesPackets.splice(0, this.currentPesPacketIndex);
        this.currentPesPacketIndex = 0;
    }
}
/**
 * A buffer that simulates decoder frame reordering to compute packet durations. Packets arrive in decode order but
 * durations are based on presentation order.
 */
class PacketBuffer {
    constructor(backing, context) {
        this.decodeOrderPackets = [];
        this.reorderBuffer = [];
        this.presentationOrderPackets = [];
        this.reachedEnd = false;
        this.lastDuration = 0;
        this.backing = backing;
        this.context = context;
        this.reorderSize = backing.getReorderSize();
        (0,misc/* assert */.vA)(this.reorderSize >= 0);
    }
    async readNext() {
        if (this.decodeOrderPackets.length === 0) {
            // We need the next packet
            const didRead = await this.readNextPacket();
            if (!didRead) {
                return null;
            }
        }
        // Ensure we know the next packet in presentation order so we can compute the current packet's duration
        await this.ensureCurrentPacketHasNext();
        const packet = this.decodeOrderPackets[0];
        // Let's compute the duration
        const presentationIndex = this.presentationOrderPackets.indexOf(packet);
        (0,misc/* assert */.vA)(presentationIndex !== -1);
        let duration;
        if (presentationIndex === this.presentationOrderPackets.length - 1) {
            duration = this.lastDuration; // Reasonable heuristic
        }
        else {
            const nextPacket = this.presentationOrderPackets[presentationIndex + 1];
            duration = nextPacket.pts - packet.pts;
            this.lastDuration = duration;
        }
        this.decodeOrderPackets.shift();
        // Shrink the presentation array as much as possible
        while (this.presentationOrderPackets.length > 0) {
            const first = this.presentationOrderPackets[0];
            if (this.decodeOrderPackets.includes(first)) {
                break;
            }
            this.presentationOrderPackets.shift();
        }
        return { packet, duration };
    }
    async readNextPacket() {
        if (this.reachedEnd) {
            return false;
        }
        let suppliedPacket;
        if (this.context.suppliedPacket) {
            // Small optimization: there was already a supplied packet in the context, so let's first use that one
            suppliedPacket = this.context.suppliedPacket;
        }
        else {
            await markNextPacket(this.context);
            suppliedPacket = this.context.suppliedPacket;
        }
        this.context.suppliedPacket = null;
        if (!suppliedPacket) {
            this.reachedEnd = true;
            this.flushReorderBuffer();
            return false;
        }
        this.decodeOrderPackets.push(suppliedPacket);
        this.processPacketThroughReorderBuffer(suppliedPacket);
        return true;
    }
    async ensureCurrentPacketHasNext() {
        const current = this.decodeOrderPackets[0];
        (0,misc/* assert */.vA)(current);
        while (true) {
            const presentationIndex = this.presentationOrderPackets.indexOf(current);
            // Check if current packet has a next packet
            if (presentationIndex !== -1 && presentationIndex <= this.presentationOrderPackets.length - 2) {
                break;
            }
            const didRead = await this.readNextPacket();
            if (!didRead) {
                break;
            }
        }
    }
    processPacketThroughReorderBuffer(packet) {
        this.reorderBuffer.push(packet);
        // If buffer is full, output the packet with smallest PTS
        if (this.reorderBuffer.length >= this.reorderSize) {
            let minIndex = 0;
            for (let i = 1; i < this.reorderBuffer.length; i++) {
                if (this.reorderBuffer[i].pts < this.reorderBuffer[minIndex].pts) {
                    minIndex = i;
                }
            }
            const packet = this.reorderBuffer.splice(minIndex, 1)[0];
            this.presentationOrderPackets.push(packet);
        }
    }
    flushReorderBuffer() {
        this.reorderBuffer.sort((a, b) => a.pts - b.pts);
        this.presentationOrderPackets.push(...this.reorderBuffer);
        this.reorderBuffer.length = 0;
    }
}

;// ./node_modules/mediabunny/dist/modules/src/input-format.js
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */















/**
 * Base class representing an input media file format.
 * @group Input formats
 * @public
 */
class InputFormat {
}
/**
 * Format representing files compatible with the ISO base media file format (ISOBMFF), like MP4 or MOV files.
 * @group Input formats
 * @public
 */
class IsobmffInputFormat extends InputFormat {
    /** @internal */
    async _getMajorBrand(input) {
        let slice = input._reader.requestSlice(0, 12);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice)
            return null;
        slice.skip(4);
        const fourCc = (0,src_reader/* readAscii */.IT)(slice, 4);
        if (fourCc !== 'ftyp') {
            return null;
        }
        return (0,src_reader/* readAscii */.IT)(slice, 4);
    }
    /** @internal */
    _createDemuxer(input) {
        return new IsobmffDemuxer(input);
    }
}
/**
 * MPEG-4 Part 14 (MP4) file format.
 *
 * Do not instantiate this class; use the {@link MP4} singleton instead.
 *
 * @group Input formats
 * @public
 */
class Mp4InputFormat extends IsobmffInputFormat {
    /** @internal */
    async _canReadInput(input) {
        const majorBrand = await this._getMajorBrand(input);
        return !!majorBrand && majorBrand !== 'qt  ';
    }
    get name() {
        return 'MP4';
    }
    get mimeType() {
        return 'video/mp4';
    }
}
/**
 * QuickTime File Format (QTFF), often called MOV.
 *
 * Do not instantiate this class; use the {@link QTFF} singleton instead.
 *
 * @group Input formats
 * @public
 */
class QuickTimeInputFormat extends IsobmffInputFormat {
    /** @internal */
    async _canReadInput(input) {
        const majorBrand = await this._getMajorBrand(input);
        return majorBrand === 'qt  ';
    }
    get name() {
        return 'QuickTime File Format';
    }
    get mimeType() {
        return 'video/quicktime';
    }
}
/**
 * Matroska file format.
 *
 * Do not instantiate this class; use the {@link MATROSKA} singleton instead.
 *
 * @group Input formats
 * @public
 */
class MatroskaInputFormat extends InputFormat {
    /** @internal */
    async isSupportedEBMLOfDocType(input, desiredDocType) {
        let headerSlice = input._reader.requestSlice(0, ebml/* MAX_HEADER_SIZE */.r1);
        if (headerSlice instanceof Promise)
            headerSlice = await headerSlice;
        if (!headerSlice)
            return false;
        const varIntSize = (0,ebml/* readVarIntSize */.YO)(headerSlice);
        if (varIntSize === null) {
            return false;
        }
        if (varIntSize < 1 || varIntSize > 8) {
            return false;
        }
        const id = (0,ebml/* readUnsignedInt */.dl)(headerSlice, varIntSize);
        if (id !== ebml/* EBMLId */.Cl.EBML) {
            return false;
        }
        const dataSize = (0,ebml/* readElementSize */.Kb)(headerSlice);
        if (typeof dataSize !== 'number') {
            return false; // Miss me with that shit
        }
        let dataSlice = input._reader.requestSlice(headerSlice.filePos, dataSize);
        if (dataSlice instanceof Promise)
            dataSlice = await dataSlice;
        if (!dataSlice)
            return false;
        const startPos = headerSlice.filePos;
        while (dataSlice.filePos <= startPos + dataSize - ebml/* MIN_HEADER_SIZE */.De) {
            const header = (0,ebml/* readElementHeader */.ur)(dataSlice);
            if (!header)
                break;
            const { id, size } = header;
            const dataStartPos = dataSlice.filePos;
            if (size === undefined)
                return false;
            switch (id) {
                case ebml/* EBMLId */.Cl.EBMLVersion:
                    {
                        const ebmlVersion = (0,ebml/* readUnsignedInt */.dl)(dataSlice, size);
                        if (ebmlVersion !== 1) {
                            return false;
                        }
                    }
                    ;
                    break;
                case ebml/* EBMLId */.Cl.EBMLReadVersion:
                    {
                        const ebmlReadVersion = (0,ebml/* readUnsignedInt */.dl)(dataSlice, size);
                        if (ebmlReadVersion !== 1) {
                            return false;
                        }
                    }
                    ;
                    break;
                case ebml/* EBMLId */.Cl.DocType:
                    {
                        const docType = (0,ebml/* readAsciiString */.IX)(dataSlice, size);
                        if (docType !== desiredDocType) {
                            return false;
                        }
                    }
                    ;
                    break;
                case ebml/* EBMLId */.Cl.DocTypeVersion:
                    {
                        const docTypeVersion = (0,ebml/* readUnsignedInt */.dl)(dataSlice, size);
                        if (docTypeVersion > 4) { // Support up to Matroska v4
                            return false;
                        }
                    }
                    ;
                    break;
            }
            dataSlice.filePos = dataStartPos + size;
        }
        return true;
    }
    /** @internal */
    _canReadInput(input) {
        return this.isSupportedEBMLOfDocType(input, 'matroska');
    }
    /** @internal */
    _createDemuxer(input) {
        return new MatroskaDemuxer(input);
    }
    get name() {
        return 'Matroska';
    }
    get mimeType() {
        return 'video/x-matroska';
    }
}
/**
 * WebM file format, based on Matroska.
 *
 * Do not instantiate this class; use the {@link WEBM} singleton instead.
 *
 * @group Input formats
 * @public
 */
class WebMInputFormat extends MatroskaInputFormat {
    /** @internal */
    _canReadInput(input) {
        return this.isSupportedEBMLOfDocType(input, 'webm');
    }
    get name() {
        return 'WebM';
    }
    get mimeType() {
        return 'video/webm';
    }
}
/**
 * MP3 file format.
 *
 * Do not instantiate this class; use the {@link MP3} singleton instead.
 *
 * @group Input formats
 * @public
 */
class Mp3InputFormat extends InputFormat {
    /** @internal */
    async _canReadInput(input) {
        let currentPos = 0;
        while (true) {
            let slice = input._reader.requestSlice(currentPos, id3/* ID3_V2_HEADER_SIZE */.sY);
            if (slice instanceof Promise)
                slice = await slice;
            if (!slice)
                break;
            const id3V2Header = (0,id3/* readId3V2Header */.IX)(slice);
            if (!id3V2Header) {
                break;
            }
            currentPos = slice.filePos + id3V2Header.size;
        }
        const firstResult = await readNextMp3FrameHeader(input._reader, currentPos, currentPos + 4096);
        if (!firstResult) {
            return false;
        }
        const firstHeader = firstResult.header;
        const xingOffset = (0,mp3_misc/* getXingOffset */.EZ)(firstHeader.mpegVersionId, firstHeader.channel);
        let slice = input._reader.requestSlice(firstResult.startPos + xingOffset, 4);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice)
            return false;
        const word = (0,src_reader/* readU32Be */.cN)(slice);
        const isXing = word === mp3_misc/* XING */.hY || word === mp3_misc/* INFO */.rD;
        if (isXing) {
            // Gotta be MP3
            return true;
        }
        currentPos = firstResult.startPos + firstResult.header.totalSize;
        // Fine, we found one frame header, but we're still not entirely sure this is MP3. Let's check if we can find
        // another header right after it:
        const secondResult = await readNextMp3FrameHeader(input._reader, currentPos, currentPos + mp3_misc/* FRAME_HEADER_SIZE */.Yq);
        if (!secondResult) {
            return false;
        }
        const secondHeader = secondResult.header;
        // In a well-formed MP3 file, we'd expect these two frames to share some similarities:
        if (firstHeader.channel !== secondHeader.channel || firstHeader.sampleRate !== secondHeader.sampleRate) {
            return false;
        }
        // We have found two matching consecutive MP3 frames, a strong indicator that this is an MP3 file
        return true;
    }
    /** @internal */
    _createDemuxer(input) {
        return new Mp3Demuxer(input);
    }
    get name() {
        return 'MP3';
    }
    get mimeType() {
        return 'audio/mpeg';
    }
}
/**
 * WAVE file format, based on RIFF.
 *
 * Do not instantiate this class; use the {@link WAVE} singleton instead.
 *
 * @group Input formats
 * @public
 */
class WaveInputFormat extends InputFormat {
    /** @internal */
    async _canReadInput(input) {
        let slice = input._reader.requestSlice(0, 12);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice)
            return false;
        const riffType = (0,src_reader/* readAscii */.IT)(slice, 4);
        if (riffType !== 'RIFF' && riffType !== 'RIFX' && riffType !== 'RF64') {
            return false;
        }
        slice.skip(4);
        const format = (0,src_reader/* readAscii */.IT)(slice, 4);
        return format === 'WAVE';
    }
    /** @internal */
    _createDemuxer(input) {
        return new wave_demuxer/* WaveDemuxer */.E(input);
    }
    get name() {
        return 'WAVE';
    }
    get mimeType() {
        return 'audio/wav';
    }
}
/**
 * Ogg file format.
 *
 * Do not instantiate this class; use the {@link OGG} singleton instead.
 *
 * @group Input formats
 * @public
 */
class OggInputFormat extends InputFormat {
    /** @internal */
    async _canReadInput(input) {
        let slice = input._reader.requestSlice(0, 4);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice)
            return false;
        return (0,src_reader/* readAscii */.IT)(slice, 4) === 'OggS';
    }
    /** @internal */
    _createDemuxer(input) {
        return new OggDemuxer(input);
    }
    get name() {
        return 'Ogg';
    }
    get mimeType() {
        return 'application/ogg';
    }
}
/**
 * FLAC file format.
 *
 * Do not instantiate this class; use the {@link FLAC} singleton instead.
 *
 * @group Input formats
 * @public
 */
class FlacInputFormat extends InputFormat {
    /** @internal */
    async _canReadInput(input) {
        let slice = input._reader.requestSlice(0, 4);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice)
            return false;
        return (0,src_reader/* readAscii */.IT)(slice, 4) === 'fLaC';
    }
    get name() {
        return 'FLAC';
    }
    get mimeType() {
        return 'audio/flac';
    }
    /** @internal */
    _createDemuxer(input) {
        return new FlacDemuxer(input);
    }
}
/**
 * ADTS file format.
 *
 * Do not instantiate this class; use the {@link ADTS} singleton instead.
 *
 * @group Input formats
 * @public
 */
class AdtsInputFormat extends InputFormat {
    /** @internal */
    async _canReadInput(input) {
        let currentPos = 0;
        while (true) {
            let slice = input._reader.requestSlice(currentPos, id3/* ID3_V2_HEADER_SIZE */.sY);
            if (slice instanceof Promise)
                slice = await slice;
            if (!slice)
                break;
            const id3V2Header = (0,id3/* readId3V2Header */.IX)(slice);
            if (!id3V2Header) {
                break;
            }
            currentPos = slice.filePos + id3V2Header.size;
        }
        let slice = input._reader.requestSliceRange(currentPos, adts_reader/* MIN_ADTS_FRAME_HEADER_SIZE */.gc, adts_reader/* MAX_ADTS_FRAME_HEADER_SIZE */.Y$);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice)
            return false;
        const firstHeader = (0,adts_reader/* readAdtsFrameHeader */.lh)(slice);
        if (!firstHeader) {
            return false;
        }
        currentPos += firstHeader.frameLength;
        slice = input._reader.requestSliceRange(currentPos, adts_reader/* MIN_ADTS_FRAME_HEADER_SIZE */.gc, adts_reader/* MAX_ADTS_FRAME_HEADER_SIZE */.Y$);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice)
            return false;
        const secondHeader = (0,adts_reader/* readAdtsFrameHeader */.lh)(slice);
        if (!secondHeader) {
            return false;
        }
        return firstHeader.objectType === secondHeader.objectType
            && firstHeader.samplingFrequencyIndex === secondHeader.samplingFrequencyIndex
            && firstHeader.channelConfiguration === secondHeader.channelConfiguration;
    }
    /** @internal */
    _createDemuxer(input) {
        return new AdtsDemuxer(input);
    }
    get name() {
        return 'ADTS';
    }
    get mimeType() {
        return 'audio/aac';
    }
}
/**
 * MPEG Transport Stream (MPEG-TS) file format.
 *
 * Do not instantiate this class; use the {@link MPEG_TS} singleton instead.
 *
 * @group Input formats
 * @public
 */
class MpegTsInputFormat extends InputFormat {
    /** @internal */
    async _canReadInput(input) {
        const lengthToCheck = mpeg_ts_misc/* TS_PACKET_SIZE */.ZT + 16 + 1;
        let slice = input._reader.requestSlice(0, lengthToCheck);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice)
            return false;
        const bytes = (0,src_reader/* readBytes */.io)(slice, lengthToCheck);
        if (bytes[0] === 0x47 && bytes[mpeg_ts_misc/* TS_PACKET_SIZE */.ZT] === 0x47) {
            // Regular MPEG-TS
            return true;
        }
        else if (bytes[0] === 0x47 && bytes[mpeg_ts_misc/* TS_PACKET_SIZE */.ZT + 16] === 0x47) {
            // MPEG-TS with Forward Error Correction
            return true;
        }
        else if (bytes[4] === 0x47 && bytes[4 + mpeg_ts_misc/* TS_PACKET_SIZE */.ZT] === 0x47) {
            // MPEG-2-TS (DVHS)
            return true;
        }
        return false;
    }
    /** @internal */
    _createDemuxer(input) {
        return new MpegTsDemuxer(input);
    }
    get name() {
        return 'MPEG Transport Stream';
    }
    get mimeType() {
        return 'video/MP2T';
    }
}
/**
 * MP4 input format singleton.
 * @group Input formats
 * @public
 */
const MP4 = /* #__PURE__ */ new Mp4InputFormat();
/**
 * QuickTime File Format input format singleton.
 * @group Input formats
 * @public
 */
const QTFF = /* #__PURE__ */ new QuickTimeInputFormat();
/**
 * Matroska input format singleton.
 * @group Input formats
 * @public
 */
const MATROSKA = /* #__PURE__ */ new MatroskaInputFormat();
/**
 * WebM input format singleton.
 * @group Input formats
 * @public
 */
const WEBM = /* #__PURE__ */ new WebMInputFormat();
/**
 * MP3 input format singleton.
 * @group Input formats
 * @public
 */
const MP3 = /* #__PURE__ */ new Mp3InputFormat();
/**
 * WAVE input format singleton.
 * @group Input formats
 * @public
 */
const WAVE = /* #__PURE__ */ new WaveInputFormat();
/**
 * Ogg input format singleton.
 * @group Input formats
 * @public
 */
const OGG = /* #__PURE__ */ new OggInputFormat();
/**
 * ADTS input format singleton.
 * @group Input formats
 * @public
 */
const ADTS = /* #__PURE__ */ new AdtsInputFormat();
/**
 * FLAC input format singleton.
 * @group Input formats
 * @public
 */
const FLAC = /* #__PURE__ */ new FlacInputFormat();
/**
 * MPEG-TS input format singleton.
 * @group Input formats
 * @public
 */
const MPEG_TS = /* #__PURE__ */ new MpegTsInputFormat();
/**
 * List of all input format singletons. If you don't need to support all input formats, you should specify the
 * formats individually for better tree shaking.
 * @group Input formats
 * @public
 */
const ALL_FORMATS = [MP4, QTFF, MATROSKA, WEBM, WAVE, OGG, FLAC, MP3, ADTS, MPEG_TS];


/***/ },

/***/ 6244
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Kh: () => (/* binding */ InputTrack),
/* harmony export */   N0: () => (/* binding */ InputVideoTrack),
/* harmony export */   Yi: () => (/* binding */ InputAudioTrack)
/* harmony export */ });
/* harmony import */ var _codec_data_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6297);
/* harmony import */ var _custom_coder_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8647);
/* harmony import */ var _media_sink_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(388);
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3912);
/* harmony import */ var _packet_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3936);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */





/**
 * Represents a media track in an input file.
 * @group Input files & tracks
 * @public
 */
class InputTrack {
    /** @internal */
    constructor(input, backing) {
        this.input = input;
        this._backing = backing;
    }
    /** Returns true if and only if this track is a video track. */
    isVideoTrack() {
        return this instanceof InputVideoTrack;
    }
    /** Returns true if and only if this track is an audio track. */
    isAudioTrack() {
        return this instanceof InputAudioTrack;
    }
    /** The unique ID of this track in the input file. */
    get id() {
        return this._backing.getId();
    }
    /**
     * The 1-based index of this track among all tracks of the same type in the input file. For example, the first
     * video track has number 1, the second video track has number 2, and so on. The index refers to the order in
     * which the tracks are returned by {@link Input.getTracks}.
     */
    get number() {
        return this._backing.getNumber();
    }
    /**
     * The identifier of the codec used internally by the container. It is not homogenized by Mediabunny
     * and depends entirely on the container format.
     *
     * This field can be used to determine the codec of a track in case Mediabunny doesn't know that codec.
     *
     * - For ISOBMFF files, this field returns the name of the Sample Description Box (e.g. `'avc1'`).
     * - For Matroska files, this field returns the value of the `CodecID` element.
     * - For WAVE files, this field returns the value of the format tag in the `'fmt '` chunk.
     * - For ADTS files, this field contains the `MPEG-4 Audio Object Type`.
     * - For MPEG-TS files, this field contains the `streamType` value from the Program Map Table.
     * - In all other cases, this field is `null`.
     */
    get internalCodecId() {
        return this._backing.getInternalCodecId();
    }
    /**
     * The ISO 639-2/T language code for this track. If the language is unknown, this field is `'und'` (undetermined).
     */
    get languageCode() {
        return this._backing.getLanguageCode();
    }
    /** A user-defined name for this track. */
    get name() {
        return this._backing.getName();
    }
    /**
     * A positive number x such that all timestamps and durations of all packets of this track are
     * integer multiples of 1/x.
     */
    get timeResolution() {
        return this._backing.getTimeResolution();
    }
    /** The track's disposition, i.e. information about its intended usage. */
    get disposition() {
        return this._backing.getDisposition();
    }
    /**
     * Returns the start timestamp of the first packet of this track, in seconds. While often near zero, this value
     * may be positive or even negative. A negative starting timestamp means the track's timing has been offset. Samples
     * with a negative timestamp should not be presented.
     */
    getFirstTimestamp() {
        return this._backing.getFirstTimestamp();
    }
    /** Returns the end timestamp of the last packet of this track, in seconds. */
    computeDuration() {
        return this._backing.computeDuration();
    }
    /**
     * Computes aggregate packet statistics for this track, such as average packet rate or bitrate.
     *
     * @param targetPacketCount - This optional parameter sets a target for how many packets this method must have
     * looked at before it can return early; this means, you can use it to aggregate only a subset (prefix) of all
     * packets. This is very useful for getting a great estimate of video frame rate without having to scan through the
     * entire file.
     */
    async computePacketStats(targetPacketCount = Infinity) {
        const sink = new _media_sink_js__WEBPACK_IMPORTED_MODULE_2__/* .EncodedPacketSink */ .kQ(this);
        let startTimestamp = Infinity;
        let endTimestamp = -Infinity;
        let packetCount = 0;
        let totalPacketBytes = 0;
        for await (const packet of sink.packets(undefined, undefined, { metadataOnly: true })) {
            if (packetCount >= targetPacketCount
                // This additional condition is needed to produce correct results with out-of-presentation-order packets
                && packet.timestamp >= endTimestamp) {
                break;
            }
            startTimestamp = Math.min(startTimestamp, packet.timestamp);
            endTimestamp = Math.max(endTimestamp, packet.timestamp + packet.duration);
            packetCount++;
            totalPacketBytes += packet.byteLength;
        }
        return {
            packetCount,
            averagePacketRate: packetCount
                ? Number((packetCount / (endTimestamp - startTimestamp)).toPrecision(16))
                : 0,
            averageBitrate: packetCount
                ? Number((8 * totalPacketBytes / (endTimestamp - startTimestamp)).toPrecision(16))
                : 0,
        };
    }
}
/**
 * Represents a video track in an input file.
 * @group Input files & tracks
 * @public
 */
class InputVideoTrack extends InputTrack {
    /** @internal */
    constructor(input, backing) {
        super(input, backing);
        this._backing = backing;
    }
    get type() {
        return 'video';
    }
    get codec() {
        return this._backing.getCodec();
    }
    /** The width in pixels of the track's coded samples, before any transformations or rotations. */
    get codedWidth() {
        return this._backing.getCodedWidth();
    }
    /** The height in pixels of the track's coded samples, before any transformations or rotations. */
    get codedHeight() {
        return this._backing.getCodedHeight();
    }
    /** The angle in degrees by which the track's frames should be rotated (clockwise). */
    get rotation() {
        return this._backing.getRotation();
    }
    /** The width in pixels of the track's frames after rotation. */
    get displayWidth() {
        const rotation = this._backing.getRotation();
        return rotation % 180 === 0 ? this._backing.getCodedWidth() : this._backing.getCodedHeight();
    }
    /** The height in pixels of the track's frames after rotation. */
    get displayHeight() {
        const rotation = this._backing.getRotation();
        return rotation % 180 === 0 ? this._backing.getCodedHeight() : this._backing.getCodedWidth();
    }
    /** Returns the color space of the track's samples. */
    getColorSpace() {
        return this._backing.getColorSpace();
    }
    /** If this method returns true, the track's samples use a high dynamic range (HDR). */
    async hasHighDynamicRange() {
        const colorSpace = await this._backing.getColorSpace();
        return colorSpace.primaries === 'bt2020' || colorSpace.primaries === 'smpte432'
            || colorSpace.transfer === 'pg' || colorSpace.transfer === 'hlg'
            || colorSpace.matrix === 'bt2020-ncl';
    }
    /** Checks if this track may contain transparent samples with alpha data. */
    canBeTransparent() {
        return this._backing.canBeTransparent();
    }
    /**
     * Returns the [decoder configuration](https://www.w3.org/TR/webcodecs/#video-decoder-config) for decoding the
     * track's packets using a [`VideoDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/VideoDecoder). Returns
     * null if the track's codec is unknown.
     */
    getDecoderConfig() {
        return this._backing.getDecoderConfig();
    }
    async getCodecParameterString() {
        const decoderConfig = await this._backing.getDecoderConfig();
        return decoderConfig?.codec ?? null;
    }
    async canDecode() {
        try {
            const decoderConfig = await this._backing.getDecoderConfig();
            if (!decoderConfig) {
                return false;
            }
            const codec = this._backing.getCodec();
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(codec !== null);
            if (_custom_coder_js__WEBPACK_IMPORTED_MODULE_1__/* .customVideoDecoders */ .wb.some(x => x.supports(codec, decoderConfig))) {
                return true;
            }
            if (typeof VideoDecoder === 'undefined') {
                return false;
            }
            const support = await VideoDecoder.isConfigSupported(decoderConfig);
            return support.supported === true;
        }
        catch (error) {
            console.error('Error during decodability check:', error);
            return false;
        }
    }
    async determinePacketType(packet) {
        if (!(packet instanceof _packet_js__WEBPACK_IMPORTED_MODULE_4__/* .EncodedPacket */ .Z)) {
            throw new TypeError('packet must be an EncodedPacket.');
        }
        if (packet.isMetadataOnly) {
            throw new TypeError('packet must not be metadata-only to determine its type.');
        }
        if (this.codec === null) {
            return null;
        }
        const decoderConfig = await this.getDecoderConfig();
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(decoderConfig);
        return (0,_codec_data_js__WEBPACK_IMPORTED_MODULE_0__/* .determineVideoPacketType */ .PR)(this.codec, decoderConfig, packet.data);
    }
}
/**
 * Represents an audio track in an input file.
 * @group Input files & tracks
 * @public
 */
class InputAudioTrack extends InputTrack {
    /** @internal */
    constructor(input, backing) {
        super(input, backing);
        this._backing = backing;
    }
    get type() {
        return 'audio';
    }
    get codec() {
        return this._backing.getCodec();
    }
    /** The number of audio channels in the track. */
    get numberOfChannels() {
        return this._backing.getNumberOfChannels();
    }
    /** The track's audio sample rate in hertz. */
    get sampleRate() {
        return this._backing.getSampleRate();
    }
    /**
     * Returns the [decoder configuration](https://www.w3.org/TR/webcodecs/#audio-decoder-config) for decoding the
     * track's packets using an [`AudioDecoder`](https://developer.mozilla.org/en-US/docs/Web/API/AudioDecoder). Returns
     * null if the track's codec is unknown.
     */
    getDecoderConfig() {
        return this._backing.getDecoderConfig();
    }
    async getCodecParameterString() {
        const decoderConfig = await this._backing.getDecoderConfig();
        return decoderConfig?.codec ?? null;
    }
    async canDecode() {
        try {
            const decoderConfig = await this._backing.getDecoderConfig();
            if (!decoderConfig) {
                return false;
            }
            const codec = this._backing.getCodec();
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(codec !== null);
            if (_custom_coder_js__WEBPACK_IMPORTED_MODULE_1__/* .customAudioDecoders */ .zx.some(x => x.supports(codec, decoderConfig))) {
                return true;
            }
            if (decoderConfig.codec.startsWith('pcm-')) {
                return true; // Since we decode it ourselves
            }
            else {
                if (typeof AudioDecoder === 'undefined') {
                    return false;
                }
                const support = await AudioDecoder.isConfigSupported(decoderConfig);
                return support.supported === true;
            }
        }
        catch (error) {
            console.error('Error during decodability check:', error);
            return false;
        }
    }
    async determinePacketType(packet) {
        if (!(packet instanceof _packet_js__WEBPACK_IMPORTED_MODULE_4__/* .EncodedPacket */ .Z)) {
            throw new TypeError('packet must be an EncodedPacket.');
        }
        if (this.codec === null) {
            return null;
        }
        return 'key'; // No audio codec with delta packets
    }
}


/***/ },

/***/ 2030
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Q: () => (/* binding */ InputDisposedError),
/* harmony export */   p: () => (/* binding */ Input)
/* harmony export */ });
/* harmony import */ var _input_format_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2912);
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3912);
/* harmony import */ var _reader_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7735);
/* harmony import */ var _source_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4709);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */




(0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .polyfillSymbolDispose */ .XQ)();
/**
 * Represents an input media file. This is the root object from which all media read operations start.
 * @group Input files & tracks
 * @public
 */
class Input {
    /** True if the input has been disposed. */
    get disposed() {
        return this._disposed;
    }
    /**
     * Creates a new input file from the specified options. No reading operations will be performed until methods are
     * called on this instance.
     */
    constructor(options) {
        /** @internal */
        this._demuxerPromise = null;
        /** @internal */
        this._format = null;
        /** @internal */
        this._disposed = false;
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (!Array.isArray(options.formats) || options.formats.some(x => !(x instanceof _input_format_js__WEBPACK_IMPORTED_MODULE_0__/* .InputFormat */ .CW))) {
            throw new TypeError('options.formats must be an array of InputFormat.');
        }
        if (!(options.source instanceof _source_js__WEBPACK_IMPORTED_MODULE_3__/* .Source */ .kL)) {
            throw new TypeError('options.source must be a Source.');
        }
        if (options.source._disposed) {
            throw new Error('options.source must not be disposed.');
        }
        this._formats = options.formats;
        this._source = options.source;
        this._reader = new _reader_js__WEBPACK_IMPORTED_MODULE_2__/* .Reader */ .mP(options.source);
    }
    /** @internal */
    _getDemuxer() {
        return this._demuxerPromise ??= (async () => {
            this._reader.fileSize = await this._source.getSizeOrNull();
            for (const format of this._formats) {
                const canRead = await format._canReadInput(this);
                if (canRead) {
                    this._format = format;
                    return format._createDemuxer(this);
                }
            }
            throw new Error('Input has an unsupported or unrecognizable format.');
        })();
    }
    /**
     * Returns the source from which this input file reads its data. This is the same source that was passed to the
     * constructor.
     */
    get source() {
        return this._source;
    }
    /**
     * Returns the format of the input file. You can compare this result directly to the {@link InputFormat} singletons
     * or use `instanceof` checks for subset-aware logic (for example, `format instanceof MatroskaInputFormat` is true
     * for both MKV and WebM).
     */
    async getFormat() {
        await this._getDemuxer();
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assert */ .vA)(this._format);
        return this._format;
    }
    /**
     * Computes the duration of the input file, in seconds. More precisely, returns the largest end timestamp among
     * all tracks.
     */
    async computeDuration() {
        const demuxer = await this._getDemuxer();
        return demuxer.computeDuration();
    }
    /**
     * Returns the timestamp at which the input file starts. More precisely, returns the smallest starting timestamp
     * among all tracks.
     */
    async getFirstTimestamp() {
        const tracks = await this.getTracks();
        if (tracks.length === 0) {
            return 0;
        }
        const firstTimestamps = await Promise.all(tracks.map(x => x.getFirstTimestamp()));
        return Math.min(...firstTimestamps);
    }
    /** Returns the list of all tracks of this input file. */
    async getTracks() {
        const demuxer = await this._getDemuxer();
        return demuxer.getTracks();
    }
    /** Returns the list of all video tracks of this input file. */
    async getVideoTracks() {
        const tracks = await this.getTracks();
        return tracks.filter(x => x.isVideoTrack());
    }
    /** Returns the list of all audio tracks of this input file. */
    async getAudioTracks() {
        const tracks = await this.getTracks();
        return tracks.filter(x => x.isAudioTrack());
    }
    /** Returns the primary video track of this input file, or null if there are no video tracks. */
    async getPrimaryVideoTrack() {
        const tracks = await this.getTracks();
        return tracks.find(x => x.isVideoTrack()) ?? null;
    }
    /** Returns the primary audio track of this input file, or null if there are no audio tracks. */
    async getPrimaryAudioTrack() {
        const tracks = await this.getTracks();
        return tracks.find(x => x.isAudioTrack()) ?? null;
    }
    /** Returns the full MIME type of this input file, including track codecs. */
    async getMimeType() {
        const demuxer = await this._getDemuxer();
        return demuxer.getMimeType();
    }
    /**
     * Returns descriptive metadata tags about the media file, such as title, author, date, cover art, or other
     * attached files.
     */
    async getMetadataTags() {
        const demuxer = await this._getDemuxer();
        return demuxer.getMetadataTags();
    }
    /**
     * Disposes this input and frees connected resources. When an input is disposed, ongoing read operations will be
     * canceled, all future read operations will fail, any open decoders will be closed, and all ongoing media sink
     * operations will be canceled. Disallowed and canceled operations will throw an {@link InputDisposedError}.
     *
     * You are expected not to use an input after disposing it. While some operations may still work, it is not
     * specified and may change in any future update.
     */
    dispose() {
        if (this._disposed) {
            return;
        }
        this._disposed = true;
        this._source._disposed = true;
        this._source._dispose();
    }
    /**
     * Calls `.dispose()` on the input, implementing the `Disposable` interface for use with
     * JavaScript Explicit Resource Management features.
     */
    [Symbol.dispose]() {
        this.dispose();
    }
}
/**
 * Thrown when an operation was prevented because the corresponding {@link Input} has been disposed.
 * @group Input files & tracks
 * @public
 */
class InputDisposedError extends Error {
    /** Creates a new {@link InputDisposedError}. */
    constructor(message = 'Input has been disposed.') {
        super(message);
        this.name = 'InputDisposedError';
    }
}


/***/ },

/***/ 1826
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   X: () => (/* binding */ buildIsobmffMimeType)
/* harmony export */ });
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */
const buildIsobmffMimeType = (info) => {
    const base = info.hasVideo
        ? 'video/'
        : info.hasAudio
            ? 'audio/'
            : 'application/';
    let string = base + (info.isQuickTime ? 'quicktime' : 'mp4');
    if (info.codecStrings.length > 0) {
        const uniqueCodecMimeTypes = [...new Set(info.codecStrings)];
        string += `; codecs="${uniqueCodecMimeTypes.join(', ')}"`;
    }
    return string;
};


/***/ },

/***/ 8561
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   $L: () => (/* binding */ readMetadataStringShort),
/* harmony export */   Cp: () => (/* binding */ readDataBox),
/* harmony export */   IS: () => (/* binding */ readFixed_2_30),
/* harmony export */   Vl: () => (/* binding */ readBoxHeader),
/* harmony export */   Xk: () => (/* binding */ MAX_BOX_HEADER_SIZE),
/* harmony export */   ZM: () => (/* binding */ MIN_BOX_HEADER_SIZE),
/* harmony export */   hs: () => (/* binding */ readIsomVariableInteger),
/* harmony export */   vX: () => (/* binding */ readFixed_16_16)
/* harmony export */ });
/* harmony import */ var _metadata_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(5165);
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3912);
/* harmony import */ var _reader_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7735);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */



const MIN_BOX_HEADER_SIZE = 8;
const MAX_BOX_HEADER_SIZE = 16;
const readBoxHeader = (slice) => {
    let totalSize = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readU32Be */ .cN)(slice);
    const name = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readAscii */ .IT)(slice, 4);
    let headerSize = 8;
    const hasLargeSize = totalSize === 1;
    if (hasLargeSize) {
        totalSize = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readU64Be */ .th)(slice);
        headerSize = 16;
    }
    const contentSize = totalSize - headerSize;
    if (contentSize < 0) {
        return null; // Hardly a box is it
    }
    return { name, totalSize, headerSize, contentSize };
};
const readFixed_16_16 = (slice) => {
    return (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readI32Be */ .Ar)(slice) / 0x10000;
};
const readFixed_2_30 = (slice) => {
    return (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readI32Be */ .Ar)(slice) / 0x40000000;
};
const readIsomVariableInteger = (slice) => {
    let result = 0;
    for (let i = 0; i < 4; i++) {
        result <<= 7;
        const nextByte = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readU8 */ .eo)(slice);
        result |= nextByte & 0x7f;
        if ((nextByte & 0x80) === 0) {
            break;
        }
    }
    return result;
};
const readMetadataStringShort = (slice) => {
    let stringLength = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readU16Be */ .mH)(slice);
    slice.skip(2); // Language
    stringLength = Math.min(stringLength, slice.remainingLength);
    return _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .textDecoder */ .su.decode((0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readBytes */ .io)(slice, stringLength));
};
const readDataBox = (slice) => {
    const header = readBoxHeader(slice);
    if (!header || header.name !== 'data') {
        return null;
    }
    if (slice.remainingLength < 8) {
        // Box is too small
        return null;
    }
    const typeIndicator = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readU32Be */ .cN)(slice);
    slice.skip(4); // Locale indicator
    const data = (0,_reader_js__WEBPACK_IMPORTED_MODULE_2__/* .readBytes */ .io)(slice, header.contentSize - 8);
    switch (typeIndicator) {
        case 1: return _misc_js__WEBPACK_IMPORTED_MODULE_1__/* .textDecoder */ .su.decode(data); // UTF-8
        case 2: return new TextDecoder('utf-16be').decode(data); // UTF-16-BE
        case 13: return new _metadata_js__WEBPACK_IMPORTED_MODULE_0__/* .RichImageData */ .sF(data, 'image/jpeg');
        case 14: return new _metadata_js__WEBPACK_IMPORTED_MODULE_0__/* .RichImageData */ .sF(data, 'image/png');
        case 27: return new _metadata_js__WEBPACK_IMPORTED_MODULE_0__/* .RichImageData */ .sF(data, 'image/bmp');
        default: return data;
    }
};


/***/ },

/***/ 6411
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Cl: () => (/* binding */ EBMLId),
/* harmony export */   De: () => (/* binding */ MIN_HEADER_SIZE),
/* harmony export */   IQ: () => (/* binding */ searchForNextElementId),
/* harmony export */   IX: () => (/* binding */ readAsciiString),
/* harmony export */   K9: () => (/* binding */ LEVEL_0_AND_1_EBML_IDS),
/* harmony export */   Kb: () => (/* binding */ readElementSize),
/* harmony export */   Qn: () => (/* binding */ EBMLWriter),
/* harmony export */   Ry: () => (/* binding */ readUnsignedBigInt),
/* harmony export */   SR: () => (/* binding */ readElementId),
/* harmony export */   VE: () => (/* binding */ LEVEL_1_EBML_IDS),
/* harmony export */   YO: () => (/* binding */ readVarIntSize),
/* harmony export */   Z4: () => (/* binding */ EBMLFloat64),
/* harmony export */   _v: () => (/* binding */ EBMLFloat32),
/* harmony export */   dl: () => (/* binding */ readUnsignedInt),
/* harmony export */   jR: () => (/* binding */ readUnicodeString),
/* harmony export */   lT: () => (/* binding */ EBMLUnicodeString),
/* harmony export */   nE: () => (/* binding */ resync),
/* harmony export */   oo: () => (/* binding */ CODEC_STRING_MAP),
/* harmony export */   p: () => (/* binding */ assertDefinedSize),
/* harmony export */   pT: () => (/* binding */ readVarInt),
/* harmony export */   r1: () => (/* binding */ MAX_HEADER_SIZE),
/* harmony export */   ur: () => (/* binding */ readElementHeader),
/* harmony export */   ys: () => (/* binding */ EBMLSignedInt),
/* harmony export */   zH: () => (/* binding */ readFloat)
/* harmony export */ });
/* unused harmony exports LEVEL_0_EBML_IDS, measureUnsignedInt, measureUnsignedBigInt, measureSignedInt, measureVarInt, MAX_VAR_INT_SIZE, readSignedInt */
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3912);
/* harmony import */ var _reader_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(7735);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */


/** Wrapper around a number to be able to differentiate it in the writer. */
class EBMLFloat32 {
    constructor(value) {
        this.value = value;
    }
}
/** Wrapper around a number to be able to differentiate it in the writer. */
class EBMLFloat64 {
    constructor(value) {
        this.value = value;
    }
}
/** Wrapper around a number to be able to differentiate it in the writer. */
class EBMLSignedInt {
    constructor(value) {
        this.value = value;
    }
}
class EBMLUnicodeString {
    constructor(value) {
        this.value = value;
    }
}
/** Defines some of the EBML IDs used by Matroska files. */
var EBMLId;
(function (EBMLId) {
    EBMLId[EBMLId["EBML"] = 440786851] = "EBML";
    EBMLId[EBMLId["EBMLVersion"] = 17030] = "EBMLVersion";
    EBMLId[EBMLId["EBMLReadVersion"] = 17143] = "EBMLReadVersion";
    EBMLId[EBMLId["EBMLMaxIDLength"] = 17138] = "EBMLMaxIDLength";
    EBMLId[EBMLId["EBMLMaxSizeLength"] = 17139] = "EBMLMaxSizeLength";
    EBMLId[EBMLId["DocType"] = 17026] = "DocType";
    EBMLId[EBMLId["DocTypeVersion"] = 17031] = "DocTypeVersion";
    EBMLId[EBMLId["DocTypeReadVersion"] = 17029] = "DocTypeReadVersion";
    EBMLId[EBMLId["Void"] = 236] = "Void";
    EBMLId[EBMLId["Segment"] = 408125543] = "Segment";
    EBMLId[EBMLId["SeekHead"] = 290298740] = "SeekHead";
    EBMLId[EBMLId["Seek"] = 19899] = "Seek";
    EBMLId[EBMLId["SeekID"] = 21419] = "SeekID";
    EBMLId[EBMLId["SeekPosition"] = 21420] = "SeekPosition";
    EBMLId[EBMLId["Duration"] = 17545] = "Duration";
    EBMLId[EBMLId["Info"] = 357149030] = "Info";
    EBMLId[EBMLId["TimestampScale"] = 2807729] = "TimestampScale";
    EBMLId[EBMLId["MuxingApp"] = 19840] = "MuxingApp";
    EBMLId[EBMLId["WritingApp"] = 22337] = "WritingApp";
    EBMLId[EBMLId["Tracks"] = 374648427] = "Tracks";
    EBMLId[EBMLId["TrackEntry"] = 174] = "TrackEntry";
    EBMLId[EBMLId["TrackNumber"] = 215] = "TrackNumber";
    EBMLId[EBMLId["TrackUID"] = 29637] = "TrackUID";
    EBMLId[EBMLId["TrackType"] = 131] = "TrackType";
    EBMLId[EBMLId["FlagEnabled"] = 185] = "FlagEnabled";
    EBMLId[EBMLId["FlagDefault"] = 136] = "FlagDefault";
    EBMLId[EBMLId["FlagForced"] = 21930] = "FlagForced";
    EBMLId[EBMLId["FlagOriginal"] = 21934] = "FlagOriginal";
    EBMLId[EBMLId["FlagHearingImpaired"] = 21931] = "FlagHearingImpaired";
    EBMLId[EBMLId["FlagVisualImpaired"] = 21932] = "FlagVisualImpaired";
    EBMLId[EBMLId["FlagCommentary"] = 21935] = "FlagCommentary";
    EBMLId[EBMLId["FlagLacing"] = 156] = "FlagLacing";
    EBMLId[EBMLId["Name"] = 21358] = "Name";
    EBMLId[EBMLId["Language"] = 2274716] = "Language";
    EBMLId[EBMLId["LanguageBCP47"] = 2274717] = "LanguageBCP47";
    EBMLId[EBMLId["CodecID"] = 134] = "CodecID";
    EBMLId[EBMLId["CodecPrivate"] = 25506] = "CodecPrivate";
    EBMLId[EBMLId["CodecDelay"] = 22186] = "CodecDelay";
    EBMLId[EBMLId["SeekPreRoll"] = 22203] = "SeekPreRoll";
    EBMLId[EBMLId["DefaultDuration"] = 2352003] = "DefaultDuration";
    EBMLId[EBMLId["Video"] = 224] = "Video";
    EBMLId[EBMLId["PixelWidth"] = 176] = "PixelWidth";
    EBMLId[EBMLId["PixelHeight"] = 186] = "PixelHeight";
    EBMLId[EBMLId["AlphaMode"] = 21440] = "AlphaMode";
    EBMLId[EBMLId["Audio"] = 225] = "Audio";
    EBMLId[EBMLId["SamplingFrequency"] = 181] = "SamplingFrequency";
    EBMLId[EBMLId["Channels"] = 159] = "Channels";
    EBMLId[EBMLId["BitDepth"] = 25188] = "BitDepth";
    EBMLId[EBMLId["SimpleBlock"] = 163] = "SimpleBlock";
    EBMLId[EBMLId["BlockGroup"] = 160] = "BlockGroup";
    EBMLId[EBMLId["Block"] = 161] = "Block";
    EBMLId[EBMLId["BlockAdditions"] = 30113] = "BlockAdditions";
    EBMLId[EBMLId["BlockMore"] = 166] = "BlockMore";
    EBMLId[EBMLId["BlockAdditional"] = 165] = "BlockAdditional";
    EBMLId[EBMLId["BlockAddID"] = 238] = "BlockAddID";
    EBMLId[EBMLId["BlockDuration"] = 155] = "BlockDuration";
    EBMLId[EBMLId["ReferenceBlock"] = 251] = "ReferenceBlock";
    EBMLId[EBMLId["Cluster"] = 524531317] = "Cluster";
    EBMLId[EBMLId["Timestamp"] = 231] = "Timestamp";
    EBMLId[EBMLId["Cues"] = 475249515] = "Cues";
    EBMLId[EBMLId["CuePoint"] = 187] = "CuePoint";
    EBMLId[EBMLId["CueTime"] = 179] = "CueTime";
    EBMLId[EBMLId["CueTrackPositions"] = 183] = "CueTrackPositions";
    EBMLId[EBMLId["CueTrack"] = 247] = "CueTrack";
    EBMLId[EBMLId["CueClusterPosition"] = 241] = "CueClusterPosition";
    EBMLId[EBMLId["Colour"] = 21936] = "Colour";
    EBMLId[EBMLId["MatrixCoefficients"] = 21937] = "MatrixCoefficients";
    EBMLId[EBMLId["TransferCharacteristics"] = 21946] = "TransferCharacteristics";
    EBMLId[EBMLId["Primaries"] = 21947] = "Primaries";
    EBMLId[EBMLId["Range"] = 21945] = "Range";
    EBMLId[EBMLId["Projection"] = 30320] = "Projection";
    EBMLId[EBMLId["ProjectionType"] = 30321] = "ProjectionType";
    EBMLId[EBMLId["ProjectionPoseRoll"] = 30325] = "ProjectionPoseRoll";
    EBMLId[EBMLId["Attachments"] = 423732329] = "Attachments";
    EBMLId[EBMLId["AttachedFile"] = 24999] = "AttachedFile";
    EBMLId[EBMLId["FileDescription"] = 18046] = "FileDescription";
    EBMLId[EBMLId["FileName"] = 18030] = "FileName";
    EBMLId[EBMLId["FileMediaType"] = 18016] = "FileMediaType";
    EBMLId[EBMLId["FileData"] = 18012] = "FileData";
    EBMLId[EBMLId["FileUID"] = 18094] = "FileUID";
    EBMLId[EBMLId["Chapters"] = 272869232] = "Chapters";
    EBMLId[EBMLId["Tags"] = 307544935] = "Tags";
    EBMLId[EBMLId["Tag"] = 29555] = "Tag";
    EBMLId[EBMLId["Targets"] = 25536] = "Targets";
    EBMLId[EBMLId["TargetTypeValue"] = 26826] = "TargetTypeValue";
    EBMLId[EBMLId["TargetType"] = 25546] = "TargetType";
    EBMLId[EBMLId["TagTrackUID"] = 25541] = "TagTrackUID";
    EBMLId[EBMLId["TagEditionUID"] = 25545] = "TagEditionUID";
    EBMLId[EBMLId["TagChapterUID"] = 25540] = "TagChapterUID";
    EBMLId[EBMLId["TagAttachmentUID"] = 25542] = "TagAttachmentUID";
    EBMLId[EBMLId["SimpleTag"] = 26568] = "SimpleTag";
    EBMLId[EBMLId["TagName"] = 17827] = "TagName";
    EBMLId[EBMLId["TagLanguage"] = 17530] = "TagLanguage";
    EBMLId[EBMLId["TagString"] = 17543] = "TagString";
    EBMLId[EBMLId["TagBinary"] = 17541] = "TagBinary";
    EBMLId[EBMLId["ContentEncodings"] = 28032] = "ContentEncodings";
    EBMLId[EBMLId["ContentEncoding"] = 25152] = "ContentEncoding";
    EBMLId[EBMLId["ContentEncodingOrder"] = 20529] = "ContentEncodingOrder";
    EBMLId[EBMLId["ContentEncodingScope"] = 20530] = "ContentEncodingScope";
    EBMLId[EBMLId["ContentCompression"] = 20532] = "ContentCompression";
    EBMLId[EBMLId["ContentCompAlgo"] = 16980] = "ContentCompAlgo";
    EBMLId[EBMLId["ContentCompSettings"] = 16981] = "ContentCompSettings";
    EBMLId[EBMLId["ContentEncryption"] = 20533] = "ContentEncryption";
})(EBMLId || (EBMLId = {}));
const LEVEL_0_EBML_IDS = [
    EBMLId.EBML,
    EBMLId.Segment,
];
// All the stuff that can appear in a segment, basically
const LEVEL_1_EBML_IDS = [
    EBMLId.SeekHead,
    EBMLId.Info,
    EBMLId.Cluster,
    EBMLId.Tracks,
    EBMLId.Cues,
    EBMLId.Attachments,
    EBMLId.Chapters,
    EBMLId.Tags,
];
const LEVEL_0_AND_1_EBML_IDS = [
    ...LEVEL_0_EBML_IDS,
    ...LEVEL_1_EBML_IDS,
];
const measureUnsignedInt = (value) => {
    if (value < (1 << 8)) {
        return 1;
    }
    else if (value < (1 << 16)) {
        return 2;
    }
    else if (value < (1 << 24)) {
        return 3;
    }
    else if (value < 2 ** 32) {
        return 4;
    }
    else if (value < 2 ** 40) {
        return 5;
    }
    else {
        return 6;
    }
};
const measureUnsignedBigInt = (value) => {
    if (value < (1n << 8n)) {
        return 1;
    }
    else if (value < (1n << 16n)) {
        return 2;
    }
    else if (value < (1n << 24n)) {
        return 3;
    }
    else if (value < (1n << 32n)) {
        return 4;
    }
    else if (value < (1n << 40n)) {
        return 5;
    }
    else if (value < (1n << 48n)) {
        return 6;
    }
    else if (value < (1n << 56n)) {
        return 7;
    }
    else {
        return 8;
    }
};
const measureSignedInt = (value) => {
    if (value >= -(1 << 6) && value < (1 << 6)) {
        return 1;
    }
    else if (value >= -(1 << 13) && value < (1 << 13)) {
        return 2;
    }
    else if (value >= -(1 << 20) && value < (1 << 20)) {
        return 3;
    }
    else if (value >= -(1 << 27) && value < (1 << 27)) {
        return 4;
    }
    else if (value >= -(2 ** 34) && value < 2 ** 34) {
        return 5;
    }
    else {
        return 6;
    }
};
const measureVarInt = (value) => {
    if (value < (1 << 7) - 1) {
        /** Top bit is set, leaving 7 bits to hold the integer, but we can't store
         * 127 because "all bits set to one" is a reserved value. Same thing for the
         * other cases below:
         */
        return 1;
    }
    else if (value < (1 << 14) - 1) {
        return 2;
    }
    else if (value < (1 << 21) - 1) {
        return 3;
    }
    else if (value < (1 << 28) - 1) {
        return 4;
    }
    else if (value < 2 ** 35 - 1) {
        return 5;
    }
    else if (value < 2 ** 42 - 1) {
        return 6;
    }
    else {
        throw new Error('EBML varint size not supported ' + value);
    }
};
class EBMLWriter {
    constructor(writer) {
        this.writer = writer;
        this.helper = new Uint8Array(8);
        this.helperView = new DataView(this.helper.buffer);
        /**
         * Stores the position from the start of the file to where EBML elements have been written. This is used to
         * rewrite/edit elements that were already added before, and to measure sizes of things.
         */
        this.offsets = new WeakMap();
        /** Same as offsets, but stores position where the element's data starts (after ID and size fields). */
        this.dataOffsets = new WeakMap();
    }
    writeByte(value) {
        this.helperView.setUint8(0, value);
        this.writer.write(this.helper.subarray(0, 1));
    }
    writeFloat32(value) {
        this.helperView.setFloat32(0, value, false);
        this.writer.write(this.helper.subarray(0, 4));
    }
    writeFloat64(value) {
        this.helperView.setFloat64(0, value, false);
        this.writer.write(this.helper);
    }
    writeUnsignedInt(value, width = measureUnsignedInt(value)) {
        let pos = 0;
        // Each case falls through:
        switch (width) {
            case 6:
                // Need to use division to access >32 bits of floating point var
                this.helperView.setUint8(pos++, (value / 2 ** 40) | 0);
            // eslint-disable-next-line no-fallthrough
            case 5:
                this.helperView.setUint8(pos++, (value / 2 ** 32) | 0);
            // eslint-disable-next-line no-fallthrough
            case 4:
                this.helperView.setUint8(pos++, value >> 24);
            // eslint-disable-next-line no-fallthrough
            case 3:
                this.helperView.setUint8(pos++, value >> 16);
            // eslint-disable-next-line no-fallthrough
            case 2:
                this.helperView.setUint8(pos++, value >> 8);
            // eslint-disable-next-line no-fallthrough
            case 1:
                this.helperView.setUint8(pos++, value);
                break;
            default:
                throw new Error('Bad unsigned int size ' + width);
        }
        this.writer.write(this.helper.subarray(0, pos));
    }
    writeUnsignedBigInt(value, width = measureUnsignedBigInt(value)) {
        let pos = 0;
        for (let i = width - 1; i >= 0; i--) {
            this.helperView.setUint8(pos++, Number((value >> BigInt(i * 8)) & 0xffn));
        }
        this.writer.write(this.helper.subarray(0, pos));
    }
    writeSignedInt(value, width = measureSignedInt(value)) {
        if (value < 0) {
            // Two's complement stuff
            value += 2 ** (width * 8);
        }
        this.writeUnsignedInt(value, width);
    }
    writeVarInt(value, width = measureVarInt(value)) {
        let pos = 0;
        switch (width) {
            case 1:
                this.helperView.setUint8(pos++, (1 << 7) | value);
                break;
            case 2:
                this.helperView.setUint8(pos++, (1 << 6) | (value >> 8));
                this.helperView.setUint8(pos++, value);
                break;
            case 3:
                this.helperView.setUint8(pos++, (1 << 5) | (value >> 16));
                this.helperView.setUint8(pos++, value >> 8);
                this.helperView.setUint8(pos++, value);
                break;
            case 4:
                this.helperView.setUint8(pos++, (1 << 4) | (value >> 24));
                this.helperView.setUint8(pos++, value >> 16);
                this.helperView.setUint8(pos++, value >> 8);
                this.helperView.setUint8(pos++, value);
                break;
            case 5:
                /**
                 * JavaScript converts its doubles to 32-bit integers for bitwise
                 * operations, so we need to do a division by 2^32 instead of a
                 * right-shift of 32 to retain those top 3 bits
                 */
                this.helperView.setUint8(pos++, (1 << 3) | ((value / 2 ** 32) & 0x7));
                this.helperView.setUint8(pos++, value >> 24);
                this.helperView.setUint8(pos++, value >> 16);
                this.helperView.setUint8(pos++, value >> 8);
                this.helperView.setUint8(pos++, value);
                break;
            case 6:
                this.helperView.setUint8(pos++, (1 << 2) | ((value / 2 ** 40) & 0x3));
                this.helperView.setUint8(pos++, (value / 2 ** 32) | 0);
                this.helperView.setUint8(pos++, value >> 24);
                this.helperView.setUint8(pos++, value >> 16);
                this.helperView.setUint8(pos++, value >> 8);
                this.helperView.setUint8(pos++, value);
                break;
            default:
                throw new Error('Bad EBML varint size ' + width);
        }
        this.writer.write(this.helper.subarray(0, pos));
    }
    writeAsciiString(str) {
        this.writer.write(new Uint8Array(str.split('').map(x => x.charCodeAt(0))));
    }
    writeEBML(data) {
        if (data === null)
            return;
        if (data instanceof Uint8Array) {
            this.writer.write(data);
        }
        else if (Array.isArray(data)) {
            for (const elem of data) {
                this.writeEBML(elem);
            }
        }
        else {
            this.offsets.set(data, this.writer.getPos());
            this.writeUnsignedInt(data.id); // ID field
            if (Array.isArray(data.data)) {
                const sizePos = this.writer.getPos();
                const sizeSize = data.size === -1 ? 1 : (data.size ?? 4);
                if (data.size === -1) {
                    // Write the reserved all-one-bits marker for unknown/unbounded size.
                    this.writeByte(0xff);
                }
                else {
                    this.writer.seek(this.writer.getPos() + sizeSize);
                }
                const startPos = this.writer.getPos();
                this.dataOffsets.set(data, startPos);
                this.writeEBML(data.data);
                if (data.size !== -1) {
                    const size = this.writer.getPos() - startPos;
                    const endPos = this.writer.getPos();
                    this.writer.seek(sizePos);
                    this.writeVarInt(size, sizeSize);
                    this.writer.seek(endPos);
                }
            }
            else if (typeof data.data === 'number') {
                const size = data.size ?? measureUnsignedInt(data.data);
                this.writeVarInt(size);
                this.writeUnsignedInt(data.data, size);
            }
            else if (typeof data.data === 'bigint') {
                const size = data.size ?? measureUnsignedBigInt(data.data);
                this.writeVarInt(size);
                this.writeUnsignedBigInt(data.data, size);
            }
            else if (typeof data.data === 'string') {
                this.writeVarInt(data.data.length);
                this.writeAsciiString(data.data);
            }
            else if (data.data instanceof Uint8Array) {
                this.writeVarInt(data.data.byteLength, data.size);
                this.writer.write(data.data);
            }
            else if (data.data instanceof EBMLFloat32) {
                this.writeVarInt(4);
                this.writeFloat32(data.data.value);
            }
            else if (data.data instanceof EBMLFloat64) {
                this.writeVarInt(8);
                this.writeFloat64(data.data.value);
            }
            else if (data.data instanceof EBMLSignedInt) {
                const size = data.size ?? measureSignedInt(data.data.value);
                this.writeVarInt(size);
                this.writeSignedInt(data.data.value, size);
            }
            else if (data.data instanceof EBMLUnicodeString) {
                const bytes = _misc_js__WEBPACK_IMPORTED_MODULE_0__/* .textEncoder */ .UG.encode(data.data.value);
                this.writeVarInt(bytes.length);
                this.writer.write(bytes);
            }
            else {
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assertNever */ .xb)(data.data);
            }
        }
    }
}
const MAX_VAR_INT_SIZE = 8;
const MIN_HEADER_SIZE = 2; // 1-byte ID and 1-byte size
const MAX_HEADER_SIZE = 2 * MAX_VAR_INT_SIZE; // 8-byte ID and 8-byte size
const readVarIntSize = (slice) => {
    if (slice.remainingLength < 1) {
        return null;
    }
    const firstByte = (0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readU8 */ .eo)(slice);
    slice.skip(-1);
    if (firstByte === 0) {
        return null; // Invalid VINT
    }
    let width = 1;
    let mask = 0x80;
    while ((firstByte & mask) === 0) {
        width++;
        mask >>= 1;
    }
    // Check if we have enough bytes to read the full varint
    if (slice.remainingLength < width) {
        return null;
    }
    return width;
};
const readVarInt = (slice) => {
    if (slice.remainingLength < 1) {
        return null;
    }
    // Read the first byte to determine the width of the variable-length integer
    const firstByte = (0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readU8 */ .eo)(slice);
    if (firstByte === 0) {
        return null; // Invalid VINT
    }
    // Find the position of VINT_MARKER, which determines the width
    let width = 1;
    let mask = 1 << 7;
    while ((firstByte & mask) === 0) {
        width++;
        mask >>= 1;
    }
    if (slice.remainingLength < width - 1) {
        // Not enough bytes
        return null;
    }
    // First byte's value needs the marker bit cleared
    let value = firstByte & (mask - 1);
    // Read remaining bytes
    for (let i = 1; i < width; i++) {
        value *= 1 << 8;
        value += (0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readU8 */ .eo)(slice);
    }
    return value;
};
const readUnsignedInt = (slice, width) => {
    if (width < 1 || width > 8) {
        throw new Error('Bad unsigned int size ' + width);
    }
    let value = 0;
    // Read bytes from most significant to least significant
    for (let i = 0; i < width; i++) {
        value *= 1 << 8;
        value += (0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readU8 */ .eo)(slice);
    }
    return value;
};
const readUnsignedBigInt = (slice, width) => {
    if (width < 1) {
        throw new Error('Bad unsigned int size ' + width);
    }
    let value = 0n;
    for (let i = 0; i < width; i++) {
        value <<= 8n;
        value += BigInt((0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readU8 */ .eo)(slice));
    }
    return value;
};
const readSignedInt = (slice, width) => {
    let value = readUnsignedInt(slice, width);
    // If the highest bit is set, convert from two's complement
    if (value & (1 << (width * 8 - 1))) {
        value -= 2 ** (width * 8);
    }
    return value;
};
const readElementId = (slice) => {
    const size = readVarIntSize(slice);
    if (size === null) {
        return null;
    }
    if (slice.remainingLength < size) {
        return null; // It don't fit
    }
    const id = readUnsignedInt(slice, size);
    return id;
};
/** Returns `undefined` to indicate the EBML undefined size. Returns `null` if the size couldn't be read. */
const readElementSize = (slice) => {
    // Need at least 1 byte to read the size
    if (slice.remainingLength < 1) {
        return null;
    }
    const firstByte = (0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readU8 */ .eo)(slice);
    if (firstByte === 0xff) {
        return undefined;
    }
    slice.skip(-1);
    const size = readVarInt(slice);
    if (size === null) {
        return null;
    }
    // In some (livestreamed) files, this is the value of the size field. While this technically is just a very
    // large number, it is intended to behave like the reserved size 0xFF, meaning the size is undefined. We
    // catch the number here. Note that it cannot be perfectly represented as a double, but the comparison works
    // nonetheless.
    // eslint-disable-next-line no-loss-of-precision
    if (size === 0x00ffffffffffffff) {
        return undefined;
    }
    return size;
};
const readElementHeader = (slice) => {
    (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(slice.remainingLength >= MIN_HEADER_SIZE);
    const id = readElementId(slice);
    if (id === null) {
        return null;
    }
    const size = readElementSize(slice);
    if (size === null) {
        return null;
    }
    return { id, size };
};
const readAsciiString = (slice, length) => {
    const bytes = (0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readBytes */ .io)(slice, length);
    // Actual string length might be shorter due to null terminators
    let strLength = 0;
    while (strLength < length && bytes[strLength] !== 0) {
        strLength += 1;
    }
    return String.fromCharCode(...bytes.subarray(0, strLength));
};
const readUnicodeString = (slice, length) => {
    const bytes = (0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readBytes */ .io)(slice, length);
    // Actual string length might be shorter due to null terminators
    let strLength = 0;
    while (strLength < length && bytes[strLength] !== 0) {
        strLength += 1;
    }
    return _misc_js__WEBPACK_IMPORTED_MODULE_0__/* .textDecoder */ .su.decode(bytes.subarray(0, strLength));
};
const readFloat = (slice, width) => {
    if (width === 0) {
        return 0;
    }
    if (width !== 4 && width !== 8) {
        throw new Error('Bad float size ' + width);
    }
    return width === 4 ? (0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readF32Be */ .Jk)(slice) : (0,_reader_js__WEBPACK_IMPORTED_MODULE_1__/* .readF64Be */ ._3)(slice);
};
/** Returns the byte offset in the file of the next element with a matching ID. */
const searchForNextElementId = async (reader, startPos, ids, until) => {
    const idsSet = new Set(ids);
    let currentPos = startPos;
    while (until === null || currentPos < until) {
        let slice = reader.requestSliceRange(currentPos, MIN_HEADER_SIZE, MAX_HEADER_SIZE);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice)
            break;
        const elementHeader = readElementHeader(slice);
        if (!elementHeader) {
            break;
        }
        if (idsSet.has(elementHeader.id)) {
            return { pos: currentPos, found: true };
        }
        assertDefinedSize(elementHeader.size);
        currentPos = slice.filePos + elementHeader.size;
    }
    return { pos: (until !== null && until > currentPos) ? until : currentPos, found: false };
};
/** Searches for the next occurrence of an element ID using a naive byte-wise search. */
const resync = async (reader, startPos, ids, until) => {
    const CHUNK_SIZE = 2 ** 16; // So we don't need to grab thousands of slices
    const idsSet = new Set(ids);
    let currentPos = startPos;
    while (currentPos < until) {
        let slice = reader.requestSliceRange(currentPos, 0, Math.min(CHUNK_SIZE, until - currentPos));
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice)
            break;
        if (slice.length < MAX_VAR_INT_SIZE)
            break;
        for (let i = 0; i < slice.length - MAX_VAR_INT_SIZE; i++) {
            slice.filePos = currentPos;
            const elementId = readElementId(slice);
            if (elementId !== null && idsSet.has(elementId)) {
                return currentPos;
            }
            currentPos++;
        }
    }
    return null;
};
const CODEC_STRING_MAP = {
    'avc': 'V_MPEG4/ISO/AVC',
    'hevc': 'V_MPEGH/ISO/HEVC',
    'vp8': 'V_VP8',
    'vp9': 'V_VP9',
    'av1': 'V_AV1',
    'aac': 'A_AAC',
    'mp3': 'A_MPEG/L3',
    'opus': 'A_OPUS',
    'vorbis': 'A_VORBIS',
    'flac': 'A_FLAC',
    'ac3': 'A_AC3',
    'eac3': 'A_EAC3',
    'pcm-u8': 'A_PCM/INT/LIT',
    'pcm-s16': 'A_PCM/INT/LIT',
    'pcm-s16be': 'A_PCM/INT/BIG',
    'pcm-s24': 'A_PCM/INT/LIT',
    'pcm-s24be': 'A_PCM/INT/BIG',
    'pcm-s32': 'A_PCM/INT/LIT',
    'pcm-s32be': 'A_PCM/INT/BIG',
    'pcm-f32': 'A_PCM/FLOAT/IEEE',
    'pcm-f64': 'A_PCM/FLOAT/IEEE',
    'webvtt': 'S_TEXT/WEBVTT',
};
function assertDefinedSize(size) {
    if (size === undefined) {
        throw new Error('Undefined element size is used in a place where it is not supported.');
    }
}
;


/***/ },

/***/ 3616
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   V: () => (/* binding */ buildMatroskaMimeType)
/* harmony export */ });
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */
const buildMatroskaMimeType = (info) => {
    const base = info.hasVideo
        ? 'video/'
        : info.hasAudio
            ? 'audio/'
            : 'application/';
    let string = base + (info.isWebM ? 'webm' : 'x-matroska');
    if (info.codecStrings.length > 0) {
        const uniqueCodecMimeTypes = [...new Set(info.codecStrings.filter(Boolean))];
        string += `; codecs="${uniqueCodecMimeTypes.join(', ')}"`;
    }
    return string;
};


/***/ },

/***/ 388
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   kQ: () => (/* binding */ EncodedPacketSink),
/* harmony export */   lc: () => (/* binding */ VideoSampleSink)
/* harmony export */ });
/* unused harmony exports BaseMediaSampleSink, CanvasSink, AudioSampleSink, AudioBufferSink */
/* unused harmony import specifier */ var InputVideoTrack;
/* unused harmony import specifier */ var InputAudioTrack;
/* unused harmony import specifier */ var isFirefox;
/* unused harmony import specifier */ var assert;
/* unused harmony import specifier */ var mapAsyncGenerator;
/* unused harmony import specifier */ var validateCropRectangle;
/* unused harmony import specifier */ var clampCropRectangle;
/* harmony import */ var _codec_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1188);
/* harmony import */ var _codec_data_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6297);
/* harmony import */ var _custom_coder_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(8647);
/* harmony import */ var _input_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(2030);
/* harmony import */ var _input_track_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(6244);
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(3912);
/* harmony import */ var _packet_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(3936);
/* harmony import */ var _pcm_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(358);
/* harmony import */ var _sample_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(4166);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */









const validatePacketRetrievalOptions = (options) => {
    if (!options || typeof options !== 'object') {
        throw new TypeError('options must be an object.');
    }
    if (options.metadataOnly !== undefined && typeof options.metadataOnly !== 'boolean') {
        throw new TypeError('options.metadataOnly, when defined, must be a boolean.');
    }
    if (options.verifyKeyPackets !== undefined && typeof options.verifyKeyPackets !== 'boolean') {
        throw new TypeError('options.verifyKeyPackets, when defined, must be a boolean.');
    }
    if (options.verifyKeyPackets && options.metadataOnly) {
        throw new TypeError('options.verifyKeyPackets and options.metadataOnly cannot be enabled together.');
    }
};
const validateTimestamp = (timestamp) => {
    if (!(0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .isNumber */ .Et)(timestamp)) {
        throw new TypeError('timestamp must be a number.'); // It can be non-finite, that's fine
    }
};
const maybeFixPacketType = (track, promise, options) => {
    if (options.verifyKeyPackets) {
        return promise.then(async (packet) => {
            if (!packet || packet.type === 'delta') {
                return packet;
            }
            const determinedType = await track.determinePacketType(packet);
            if (determinedType) {
                // @ts-expect-error Technically readonly
                packet.type = determinedType;
            }
            return packet;
        });
    }
    else {
        return promise;
    }
};
/**
 * Sink for retrieving encoded packets from an input track.
 * @group Media sinks
 * @public
 */
class EncodedPacketSink {
    /** Creates a new {@link EncodedPacketSink} for the given {@link InputTrack}. */
    constructor(track) {
        if (!(track instanceof _input_track_js__WEBPACK_IMPORTED_MODULE_4__/* .InputTrack */ .Kh)) {
            throw new TypeError('track must be an InputTrack.');
        }
        this._track = track;
    }
    /**
     * Retrieves the track's first packet (in decode order), or null if it has no packets. The first packet is very
     * likely to be a key packet.
     */
    getFirstPacket(options = {}) {
        validatePacketRetrievalOptions(options);
        if (this._track.input._disposed) {
            throw new _input_js__WEBPACK_IMPORTED_MODULE_3__/* .InputDisposedError */ .Q();
        }
        return maybeFixPacketType(this._track, this._track._backing.getFirstPacket(options), options);
    }
    /**
     * Retrieves the packet corresponding to the given timestamp, in seconds. More specifically, returns the last packet
     * (in presentation order) with a start timestamp less than or equal to the given timestamp. This method can be
     * used to retrieve a track's last packet using `getPacket(Infinity)`. The method returns null if the timestamp
     * is before the first packet in the track.
     *
     * @param timestamp - The timestamp used for retrieval, in seconds.
     */
    getPacket(timestamp, options = {}) {
        validateTimestamp(timestamp);
        validatePacketRetrievalOptions(options);
        if (this._track.input._disposed) {
            throw new _input_js__WEBPACK_IMPORTED_MODULE_3__/* .InputDisposedError */ .Q();
        }
        return maybeFixPacketType(this._track, this._track._backing.getPacket(timestamp, options), options);
    }
    /**
     * Retrieves the packet following the given packet (in decode order), or null if the given packet is the
     * last packet.
     */
    getNextPacket(packet, options = {}) {
        if (!(packet instanceof _packet_js__WEBPACK_IMPORTED_MODULE_6__/* .EncodedPacket */ .Z)) {
            throw new TypeError('packet must be an EncodedPacket.');
        }
        validatePacketRetrievalOptions(options);
        if (this._track.input._disposed) {
            throw new _input_js__WEBPACK_IMPORTED_MODULE_3__/* .InputDisposedError */ .Q();
        }
        return maybeFixPacketType(this._track, this._track._backing.getNextPacket(packet, options), options);
    }
    /**
     * Retrieves the key packet corresponding to the given timestamp, in seconds. More specifically, returns the last
     * key packet (in presentation order) with a start timestamp less than or equal to the given timestamp. A key packet
     * is a packet that doesn't require previous packets to be decoded. This method can be used to retrieve a track's
     * last key packet using `getKeyPacket(Infinity)`. The method returns null if the timestamp is before the first
     * key packet in the track.
     *
     * To ensure that the returned packet is guaranteed to be a real key frame, enable `options.verifyKeyPackets`.
     *
     * @param timestamp - The timestamp used for retrieval, in seconds.
     */
    async getKeyPacket(timestamp, options = {}) {
        validateTimestamp(timestamp);
        validatePacketRetrievalOptions(options);
        if (this._track.input._disposed) {
            throw new _input_js__WEBPACK_IMPORTED_MODULE_3__/* .InputDisposedError */ .Q();
        }
        if (!options.verifyKeyPackets) {
            return this._track._backing.getKeyPacket(timestamp, options);
        }
        const packet = await this._track._backing.getKeyPacket(timestamp, options);
        if (!packet) {
            return packet;
        }
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(packet.type === 'key');
        const determinedType = await this._track.determinePacketType(packet);
        if (determinedType === 'delta') {
            // Try returning the previous key packet (in hopes that it's actually a key packet)
            return this.getKeyPacket(packet.timestamp - 1 / this._track.timeResolution, options);
        }
        return packet;
    }
    /**
     * Retrieves the key packet following the given packet (in decode order), or null if the given packet is the last
     * key packet.
     *
     * To ensure that the returned packet is guaranteed to be a real key frame, enable `options.verifyKeyPackets`.
     */
    async getNextKeyPacket(packet, options = {}) {
        if (!(packet instanceof _packet_js__WEBPACK_IMPORTED_MODULE_6__/* .EncodedPacket */ .Z)) {
            throw new TypeError('packet must be an EncodedPacket.');
        }
        validatePacketRetrievalOptions(options);
        if (this._track.input._disposed) {
            throw new _input_js__WEBPACK_IMPORTED_MODULE_3__/* .InputDisposedError */ .Q();
        }
        if (!options.verifyKeyPackets) {
            return this._track._backing.getNextKeyPacket(packet, options);
        }
        const nextPacket = await this._track._backing.getNextKeyPacket(packet, options);
        if (!nextPacket) {
            return nextPacket;
        }
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(nextPacket.type === 'key');
        const determinedType = await this._track.determinePacketType(nextPacket);
        if (determinedType === 'delta') {
            // Try returning the next key packet (in hopes that it's actually a key packet)
            return this.getNextKeyPacket(nextPacket, options);
        }
        return nextPacket;
    }
    /**
     * Creates an async iterator that yields the packets in this track in decode order. To enable fast iteration, this
     * method will intelligently preload packets based on the speed of the consumer.
     *
     * @param startPacket - (optional) The packet from which iteration should begin. This packet will also be yielded.
     * @param endTimestamp - (optional) The timestamp at which iteration should end. This packet will _not_ be yielded.
     */
    packets(startPacket, endPacket, options = {}) {
        if (startPacket !== undefined && !(startPacket instanceof _packet_js__WEBPACK_IMPORTED_MODULE_6__/* .EncodedPacket */ .Z)) {
            throw new TypeError('startPacket must be an EncodedPacket.');
        }
        if (startPacket !== undefined && startPacket.isMetadataOnly && !options?.metadataOnly) {
            throw new TypeError('startPacket can only be metadata-only if options.metadataOnly is enabled.');
        }
        if (endPacket !== undefined && !(endPacket instanceof _packet_js__WEBPACK_IMPORTED_MODULE_6__/* .EncodedPacket */ .Z)) {
            throw new TypeError('endPacket must be an EncodedPacket.');
        }
        validatePacketRetrievalOptions(options);
        if (this._track.input._disposed) {
            throw new _input_js__WEBPACK_IMPORTED_MODULE_3__/* .InputDisposedError */ .Q();
        }
        const packetQueue = [];
        let { promise: queueNotEmpty, resolve: onQueueNotEmpty } = (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .promiseWithResolvers */ .nJ)();
        let { promise: queueDequeue, resolve: onQueueDequeue } = (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .promiseWithResolvers */ .nJ)();
        let ended = false;
        let terminated = false;
        // This stores errors that are "out of band" in the sense that they didn't occur in the normal flow of this
        // method but instead in a different context. This error should not go unnoticed and must be bubbled up to
        // the consumer.
        let outOfBandError = null;
        const timestamps = [];
        // The queue should always be big enough to hold 1 second worth of packets
        const maxQueueSize = () => Math.max(2, timestamps.length);
        // The following is the "pump" process that keeps pumping packets into the queue
        (async () => {
            let packet = startPacket ?? await this.getFirstPacket(options);
            while (packet && !terminated && !this._track.input._disposed) {
                if (endPacket && packet.sequenceNumber >= endPacket?.sequenceNumber) {
                    break;
                }
                if (packetQueue.length > maxQueueSize()) {
                    ({ promise: queueDequeue, resolve: onQueueDequeue } = (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .promiseWithResolvers */ .nJ)());
                    await queueDequeue;
                    continue;
                }
                packetQueue.push(packet);
                onQueueNotEmpty();
                ({ promise: queueNotEmpty, resolve: onQueueNotEmpty } = (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .promiseWithResolvers */ .nJ)());
                packet = await this.getNextPacket(packet, options);
            }
            ended = true;
            onQueueNotEmpty();
        })().catch((error) => {
            if (!outOfBandError) {
                outOfBandError = error;
                onQueueNotEmpty();
            }
        });
        const track = this._track;
        return {
            async next() {
                while (true) {
                    if (track.input._disposed) {
                        throw new _input_js__WEBPACK_IMPORTED_MODULE_3__/* .InputDisposedError */ .Q();
                    }
                    else if (terminated) {
                        return { value: undefined, done: true };
                    }
                    else if (outOfBandError) {
                        throw outOfBandError;
                    }
                    else if (packetQueue.length > 0) {
                        const value = packetQueue.shift();
                        const now = performance.now();
                        timestamps.push(now);
                        while (timestamps.length > 0 && now - timestamps[0] >= 1000) {
                            timestamps.shift();
                        }
                        onQueueDequeue();
                        return { value, done: false };
                    }
                    else if (ended) {
                        return { value: undefined, done: true };
                    }
                    else {
                        await queueNotEmpty;
                    }
                }
            },
            async return() {
                terminated = true;
                onQueueDequeue();
                onQueueNotEmpty();
                return { value: undefined, done: true };
            },
            async throw(error) {
                throw error;
            },
            [Symbol.asyncIterator]() {
                return this;
            },
        };
    }
}
class DecoderWrapper {
    constructor(onSample, onError) {
        this.onSample = onSample;
        this.onError = onError;
    }
}
/**
 * Base class for decoded media sample sinks.
 * @group Media sinks
 * @public
 */
class BaseMediaSampleSink {
    /** @internal */
    mediaSamplesInRange(startTimestamp = 0, endTimestamp = Infinity) {
        validateTimestamp(startTimestamp);
        validateTimestamp(endTimestamp);
        const sampleQueue = [];
        let firstSampleQueued = false;
        let lastSample = null;
        let { promise: queueNotEmpty, resolve: onQueueNotEmpty } = (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .promiseWithResolvers */ .nJ)();
        let { promise: queueDequeue, resolve: onQueueDequeue } = (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .promiseWithResolvers */ .nJ)();
        let decoderIsFlushed = false;
        let ended = false;
        let terminated = false;
        // This stores errors that are "out of band" in the sense that they didn't occur in the normal flow of this
        // method but instead in a different context. This error should not go unnoticed and must be bubbled up to
        // the consumer.
        let outOfBandError = null;
        // The following is the "pump" process that keeps pumping packets into the decoder
        (async () => {
            const decoder = await this._createDecoder((sample) => {
                onQueueDequeue();
                if (sample.timestamp >= endTimestamp) {
                    ended = true;
                }
                if (ended) {
                    sample.close();
                    return;
                }
                if (lastSample) {
                    if (sample.timestamp > startTimestamp) {
                        // We don't know ahead of time what the first first is. This is because the first first is the
                        // last first whose timestamp is less than or equal to the start timestamp. Therefore we need to
                        // wait for the first first after the start timestamp, and then we'll know that the previous
                        // first was the first first.
                        sampleQueue.push(lastSample);
                        firstSampleQueued = true;
                    }
                    else {
                        lastSample.close();
                    }
                }
                if (sample.timestamp >= startTimestamp) {
                    sampleQueue.push(sample);
                    firstSampleQueued = true;
                }
                lastSample = firstSampleQueued ? null : sample;
                if (sampleQueue.length > 0) {
                    onQueueNotEmpty();
                    ({ promise: queueNotEmpty, resolve: onQueueNotEmpty } = (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .promiseWithResolvers */ .nJ)());
                }
            }, (error) => {
                if (!outOfBandError) {
                    outOfBandError = error;
                    onQueueNotEmpty();
                }
            });
            const packetSink = this._createPacketSink();
            const keyPacket = await packetSink.getKeyPacket(startTimestamp, { verifyKeyPackets: true })
                ?? await packetSink.getFirstPacket();
            let currentPacket = keyPacket;
            // B-frames make it exceedingly difficult to properly define an upper bound for packet iteration if an end
            // timestamp is set, so we just don't do it. The case that makes it especially tricky is when the frames
            // following a key frame have a lower timestamp than the keyframe; something that quite frequently happens
            // in HEVC streams. The price to pay for not upper-bounding the packet iterator is a slight increase in
            // decoder work at the end of the range, but the added correctness and reliability makes this tradeoff worth
            // it.
            const endPacket = undefined;
            const packets = packetSink.packets(keyPacket ?? undefined, endPacket);
            await packets.next(); // Skip the start packet as we already have it
            while (currentPacket && !ended && !this._track.input._disposed) {
                const maxQueueSize = computeMaxQueueSize(sampleQueue.length);
                if (sampleQueue.length + decoder.getDecodeQueueSize() > maxQueueSize) {
                    ({ promise: queueDequeue, resolve: onQueueDequeue } = (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .promiseWithResolvers */ .nJ)());
                    await queueDequeue;
                    continue;
                }
                decoder.decode(currentPacket);
                const packetResult = await packets.next();
                if (packetResult.done) {
                    break;
                }
                currentPacket = packetResult.value;
            }
            await packets.return();
            if (!terminated && !this._track.input._disposed) {
                await decoder.flush();
            }
            decoder.close();
            if (!firstSampleQueued && lastSample) {
                sampleQueue.push(lastSample);
            }
            decoderIsFlushed = true;
            onQueueNotEmpty(); // To unstuck the generator
        })().catch((error) => {
            if (!outOfBandError) {
                outOfBandError = error;
                onQueueNotEmpty();
            }
        });
        const track = this._track;
        const closeSamples = () => {
            lastSample?.close();
            for (const sample of sampleQueue) {
                sample.close();
            }
        };
        return {
            async next() {
                while (true) {
                    if (track.input._disposed) {
                        closeSamples();
                        throw new _input_js__WEBPACK_IMPORTED_MODULE_3__/* .InputDisposedError */ .Q();
                    }
                    else if (terminated) {
                        return { value: undefined, done: true };
                    }
                    else if (outOfBandError) {
                        closeSamples();
                        throw outOfBandError;
                    }
                    else if (sampleQueue.length > 0) {
                        const value = sampleQueue.shift();
                        onQueueDequeue();
                        return { value, done: false };
                    }
                    else if (!decoderIsFlushed) {
                        await queueNotEmpty;
                    }
                    else {
                        return { value: undefined, done: true };
                    }
                }
            },
            async return() {
                terminated = true;
                ended = true;
                onQueueDequeue();
                onQueueNotEmpty();
                closeSamples();
                return { value: undefined, done: true };
            },
            async throw(error) {
                throw error;
            },
            [Symbol.asyncIterator]() {
                return this;
            },
        };
    }
    /** @internal */
    mediaSamplesAtTimestamps(timestamps) {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .validateAnyIterable */ .D5)(timestamps);
        const timestampIterator = (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .toAsyncIterator */ .i1)(timestamps);
        const timestampsOfInterest = [];
        const sampleQueue = [];
        let { promise: queueNotEmpty, resolve: onQueueNotEmpty } = (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .promiseWithResolvers */ .nJ)();
        let { promise: queueDequeue, resolve: onQueueDequeue } = (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .promiseWithResolvers */ .nJ)();
        let decoderIsFlushed = false;
        let terminated = false;
        // This stores errors that are "out of band" in the sense that they didn't occur in the normal flow of this
        // method but instead in a different context. This error should not go unnoticed and must be bubbled up to
        // the consumer.
        let outOfBandError = null;
        const pushToQueue = (sample) => {
            sampleQueue.push(sample);
            onQueueNotEmpty();
            ({ promise: queueNotEmpty, resolve: onQueueNotEmpty } = (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .promiseWithResolvers */ .nJ)());
        };
        // The following is the "pump" process that keeps pumping packets into the decoder
        (async () => {
            const decoder = await this._createDecoder((sample) => {
                onQueueDequeue();
                if (terminated) {
                    sample.close();
                    return;
                }
                let sampleUses = 0;
                while (timestampsOfInterest.length > 0
                    && sample.timestamp - timestampsOfInterest[0] > -1e-10 // Give it a little epsilon
                ) {
                    sampleUses++;
                    timestampsOfInterest.shift();
                }
                if (sampleUses > 0) {
                    for (let i = 0; i < sampleUses; i++) {
                        // Clone the sample if we need to emit it multiple times
                        pushToQueue((i < sampleUses - 1 ? sample.clone() : sample));
                    }
                }
                else {
                    sample.close();
                }
            }, (error) => {
                if (!outOfBandError) {
                    outOfBandError = error;
                    onQueueNotEmpty();
                }
            });
            const packetSink = this._createPacketSink();
            let lastPacket = null;
            let lastKeyPacket = null;
            // The end sequence number (inclusive) in the next batch of packets that will be decoded. The batch starts
            // at the last key frame and goes until this sequence number.
            let maxSequenceNumber = -1;
            const decodePackets = async () => {
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(lastKeyPacket);
                // Start at the current key packet
                let currentPacket = lastKeyPacket;
                decoder.decode(currentPacket);
                while (currentPacket.sequenceNumber < maxSequenceNumber) {
                    const maxQueueSize = computeMaxQueueSize(sampleQueue.length);
                    while (sampleQueue.length + decoder.getDecodeQueueSize() > maxQueueSize && !terminated) {
                        ({ promise: queueDequeue, resolve: onQueueDequeue } = (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .promiseWithResolvers */ .nJ)());
                        await queueDequeue;
                    }
                    if (terminated) {
                        break;
                    }
                    const nextPacket = await packetSink.getNextPacket(currentPacket);
                    (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(nextPacket);
                    decoder.decode(nextPacket);
                    currentPacket = nextPacket;
                }
                maxSequenceNumber = -1;
            };
            const flushDecoder = async () => {
                await decoder.flush();
                // We don't expect this list to have any elements in it anymore, but in case it does, let's emit
                // nulls for every remaining element, then clear it.
                for (let i = 0; i < timestampsOfInterest.length; i++) {
                    pushToQueue(null);
                }
                timestampsOfInterest.length = 0;
            };
            for await (const timestamp of timestampIterator) {
                validateTimestamp(timestamp);
                if (terminated || this._track.input._disposed) {
                    break;
                }
                const targetPacket = await packetSink.getPacket(timestamp);
                const keyPacket = targetPacket && await packetSink.getKeyPacket(timestamp, { verifyKeyPackets: true });
                if (!keyPacket) {
                    if (maxSequenceNumber !== -1) {
                        await decodePackets();
                        await flushDecoder();
                    }
                    pushToQueue(null);
                    lastPacket = null;
                    continue;
                }
                // Check if the key packet has changed or if we're going back in time
                if (lastPacket
                    && (keyPacket.sequenceNumber !== lastKeyPacket.sequenceNumber
                        || targetPacket.timestamp < lastPacket.timestamp)) {
                    await decodePackets();
                    await flushDecoder(); // Always flush here, improves decoder compatibility
                }
                timestampsOfInterest.push(targetPacket.timestamp);
                maxSequenceNumber = Math.max(targetPacket.sequenceNumber, maxSequenceNumber);
                lastPacket = targetPacket;
                lastKeyPacket = keyPacket;
            }
            if (!terminated && !this._track.input._disposed) {
                if (maxSequenceNumber !== -1) {
                    // We still need to decode packets
                    await decodePackets();
                }
                await flushDecoder();
            }
            decoder.close();
            decoderIsFlushed = true;
            onQueueNotEmpty(); // To unstuck the generator
        })().catch((error) => {
            if (!outOfBandError) {
                outOfBandError = error;
                onQueueNotEmpty();
            }
        });
        const track = this._track;
        const closeSamples = () => {
            for (const sample of sampleQueue) {
                sample?.close();
            }
        };
        return {
            async next() {
                while (true) {
                    if (track.input._disposed) {
                        closeSamples();
                        throw new _input_js__WEBPACK_IMPORTED_MODULE_3__/* .InputDisposedError */ .Q();
                    }
                    else if (terminated) {
                        return { value: undefined, done: true };
                    }
                    else if (outOfBandError) {
                        closeSamples();
                        throw outOfBandError;
                    }
                    else if (sampleQueue.length > 0) {
                        const value = sampleQueue.shift();
                        (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(value !== undefined);
                        onQueueDequeue();
                        return { value, done: false };
                    }
                    else if (!decoderIsFlushed) {
                        await queueNotEmpty;
                    }
                    else {
                        return { value: undefined, done: true };
                    }
                }
            },
            async return() {
                terminated = true;
                onQueueDequeue();
                onQueueNotEmpty();
                closeSamples();
                return { value: undefined, done: true };
            },
            async throw(error) {
                throw error;
            },
            [Symbol.asyncIterator]() {
                return this;
            },
        };
    }
}
const computeMaxQueueSize = (decodedSampleQueueSize) => {
    // If we have decoded samples lying around, limit the total queue size to a small value (decoded samples can use up
    // a lot of memory). If not, we're fine with a much bigger queue of encoded packets waiting to be decoded. In fact,
    // some decoders only start flushing out decoded chunks when the packet queue is large enough.
    return decodedSampleQueueSize === 0 ? 40 : 8;
};
class VideoDecoderWrapper extends DecoderWrapper {
    constructor(onSample, onError, codec, decoderConfig, rotation, timeResolution) {
        super(onSample, onError);
        this.codec = codec;
        this.decoderConfig = decoderConfig;
        this.rotation = rotation;
        this.timeResolution = timeResolution;
        this.decoder = null;
        this.customDecoder = null;
        this.customDecoderCallSerializer = new _misc_js__WEBPACK_IMPORTED_MODULE_5__/* .CallSerializer */ .dY();
        this.customDecoderQueueSize = 0;
        this.inputTimestamps = []; // Timestamps input into the decoder, sorted.
        this.sampleQueue = []; // Safari-specific thing, check usage.
        this.currentPacketIndex = 0;
        this.raslSkipped = false; // For HEVC stuff
        // Alpha stuff
        this.alphaDecoder = null;
        this.alphaHadKeyframe = false;
        this.colorQueue = [];
        this.alphaQueue = [];
        this.merger = null;
        this.mergerCreationFailed = false;
        this.decodedAlphaChunkCount = 0;
        this.alphaDecoderQueueSize = 0;
        /** Each value is the number of decoded alpha chunks at which a null alpha frame should be added. */
        this.nullAlphaFrameQueue = [];
        this.currentAlphaPacketIndex = 0;
        this.alphaRaslSkipped = false; // For HEVC stuff
        const MatchingCustomDecoder = _custom_coder_js__WEBPACK_IMPORTED_MODULE_2__/* .customVideoDecoders */ .wb.find(x => x.supports(codec, decoderConfig));
        if (MatchingCustomDecoder) {
            // @ts-expect-error "Can't create instance of abstract class 🤓"
            this.customDecoder = new MatchingCustomDecoder();
            // @ts-expect-error It's technically readonly
            this.customDecoder.codec = codec;
            // @ts-expect-error It's technically readonly
            this.customDecoder.config = decoderConfig;
            // @ts-expect-error It's technically readonly
            this.customDecoder.onSample = (sample) => {
                if (!(sample instanceof _sample_js__WEBPACK_IMPORTED_MODULE_8__/* .VideoSample */ .U2)) {
                    throw new TypeError('The argument passed to onSample must be a VideoSample.');
                }
                this.finalizeAndEmitSample(sample);
            };
            void this.customDecoderCallSerializer.call(() => this.customDecoder.init());
        }
        else {
            const colorHandler = (frame) => {
                if (this.alphaQueue.length > 0) {
                    // Even when no alpha data is present (most of the time), there will be nulls in this queue
                    const alphaFrame = this.alphaQueue.shift();
                    (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(alphaFrame !== undefined);
                    this.mergeAlpha(frame, alphaFrame);
                }
                else {
                    this.colorQueue.push(frame);
                }
            };
            if (codec === 'avc' && this.decoderConfig.description && (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .isChromium */ .F2)()) {
                // Chromium has/had a bug with playing interlaced AVC (https://issues.chromium.org/issues/456919096)
                // which can be worked around by requesting that software decoding be used. So, here we peek into the
                // AVC description, if present, and switch to software decoding if we find interlaced content.
                const record = (0,_codec_data_js__WEBPACK_IMPORTED_MODULE_1__/* .deserializeAvcDecoderConfigurationRecord */ .BP)((0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .toUint8Array */ .Fo)(this.decoderConfig.description));
                if (record && record.sequenceParameterSets.length > 0) {
                    const sps = (0,_codec_data_js__WEBPACK_IMPORTED_MODULE_1__/* .parseAvcSps */ .eM)(record.sequenceParameterSets[0]);
                    if (sps && sps.frameMbsOnlyFlag === 0) {
                        this.decoderConfig = {
                            ...this.decoderConfig,
                            hardwareAcceleration: 'prefer-software',
                        };
                    }
                }
            }
            const stack = new Error('Decoding error').stack;
            this.decoder = new VideoDecoder({
                output: (frame) => {
                    try {
                        colorHandler(frame);
                    }
                    catch (error) {
                        this.onError(error);
                    }
                },
                error: (error) => {
                    error.stack = stack; // Provide a more useful stack trace, the default one sucks
                    this.onError(error);
                },
            });
            this.decoder.configure(this.decoderConfig);
        }
    }
    getDecodeQueueSize() {
        if (this.customDecoder) {
            return this.customDecoderQueueSize;
        }
        else {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(this.decoder);
            return Math.max(this.decoder.decodeQueueSize, this.alphaDecoder?.decodeQueueSize ?? 0);
        }
    }
    decode(packet) {
        if (this.codec === 'hevc' && this.currentPacketIndex > 0 && !this.raslSkipped) {
            if (this.hasHevcRaslPicture(packet.data)) {
                return; // Drop
            }
            this.raslSkipped = true;
        }
        if (this.customDecoder) {
            this.customDecoderQueueSize++;
            void this.customDecoderCallSerializer
                .call(() => this.customDecoder.decode(packet))
                .then(() => this.customDecoderQueueSize--);
        }
        else {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(this.decoder);
            if (!(0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .isWebKit */ .Tc)()) {
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .insertSorted */ .h8)(this.inputTimestamps, packet.timestamp, x => x);
            }
            // Workaround for https://issues.chromium.org/issues/470109459
            if ((0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .isChromium */ .F2)() && this.currentPacketIndex === 0 && this.codec === 'avc') {
                const filteredNalUnits = [];
                for (const loc of (0,_codec_data_js__WEBPACK_IMPORTED_MODULE_1__/* .iterateAvcNalUnits */ .RO)(packet.data, this.decoderConfig)) {
                    const type = (0,_codec_data_js__WEBPACK_IMPORTED_MODULE_1__/* .extractNalUnitTypeForAvc */ .uN)(packet.data[loc.offset]);
                    // These trip up Chromium's key frame detection, so let's strip them
                    if (!(type >= 20 && type <= 31)) {
                        filteredNalUnits.push(packet.data.subarray(loc.offset, loc.offset + loc.length));
                    }
                }
                const newData = (0,_codec_data_js__WEBPACK_IMPORTED_MODULE_1__/* .concatAvcNalUnits */ .Zi)(filteredNalUnits, this.decoderConfig);
                packet = new _packet_js__WEBPACK_IMPORTED_MODULE_6__/* .EncodedPacket */ .Z(newData, packet.type, packet.timestamp, packet.duration);
            }
            this.decoder.decode(packet.toEncodedVideoChunk());
            this.decodeAlphaData(packet);
        }
        this.currentPacketIndex++;
    }
    decodeAlphaData(packet) {
        if (!packet.sideData.alpha || this.mergerCreationFailed) {
            // No alpha side data in the packet, most common case
            this.pushNullAlphaFrame();
            return;
        }
        if (!this.merger) {
            try {
                this.merger = new ColorAlphaMerger();
            }
            catch (error) {
                console.error('Due to an error, only color data will be decoded.', error);
                this.mergerCreationFailed = true;
                this.decodeAlphaData(packet); // Go again
                return;
            }
        }
        // Check if we need to set up the alpha decoder
        if (!this.alphaDecoder) {
            const alphaHandler = (frame) => {
                this.alphaDecoderQueueSize--;
                if (this.colorQueue.length > 0) {
                    const colorFrame = this.colorQueue.shift();
                    (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(colorFrame !== undefined);
                    this.mergeAlpha(colorFrame, frame);
                }
                else {
                    this.alphaQueue.push(frame);
                }
                // Check if any null frames have been queued for this point
                this.decodedAlphaChunkCount++;
                while (this.nullAlphaFrameQueue.length > 0
                    && this.nullAlphaFrameQueue[0] === this.decodedAlphaChunkCount) {
                    this.nullAlphaFrameQueue.shift();
                    if (this.colorQueue.length > 0) {
                        const colorFrame = this.colorQueue.shift();
                        (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(colorFrame !== undefined);
                        this.mergeAlpha(colorFrame, null);
                    }
                    else {
                        this.alphaQueue.push(null);
                    }
                }
            };
            const stack = new Error('Decoding error').stack;
            this.alphaDecoder = new VideoDecoder({
                output: (frame) => {
                    try {
                        alphaHandler(frame);
                    }
                    catch (error) {
                        this.onError(error);
                    }
                },
                error: (error) => {
                    error.stack = stack; // Provide a more useful stack trace, the default one sucks
                    this.onError(error);
                },
            });
            this.alphaDecoder.configure(this.decoderConfig);
        }
        const type = (0,_codec_data_js__WEBPACK_IMPORTED_MODULE_1__/* .determineVideoPacketType */ .PR)(this.codec, this.decoderConfig, packet.sideData.alpha);
        // Alpha packets might follow a different key frame rhythm than the main packets. Therefore, before we start
        // decoding, we must first find a packet that's actually a key frame. Until then, we treat the image as opaque.
        if (!this.alphaHadKeyframe) {
            this.alphaHadKeyframe = type === 'key';
        }
        if (this.alphaHadKeyframe) {
            // Same RASL skipping logic as for color, unlikely to be hit (since who uses HEVC with separate alpha??) but
            // here for symmetry.
            if (this.codec === 'hevc' && this.currentAlphaPacketIndex > 0 && !this.alphaRaslSkipped) {
                if (this.hasHevcRaslPicture(packet.sideData.alpha)) {
                    this.pushNullAlphaFrame();
                    return;
                }
                this.alphaRaslSkipped = true;
            }
            this.currentAlphaPacketIndex++;
            this.alphaDecoder.decode(packet.alphaToEncodedVideoChunk(type ?? packet.type));
            this.alphaDecoderQueueSize++;
        }
        else {
            this.pushNullAlphaFrame();
        }
    }
    pushNullAlphaFrame() {
        if (this.alphaDecoderQueueSize === 0) {
            // Easy
            this.alphaQueue.push(null);
        }
        else {
            // There are still alpha chunks being decoded, so pushing `null` immediately would result in out-of-order
            // data and be incorrect. Instead, we need to enqueue a "null frame" for when the current decoder workload
            // has finished.
            this.nullAlphaFrameQueue.push(this.decodedAlphaChunkCount + this.alphaDecoderQueueSize);
        }
    }
    /**
     * If we're using HEVC, we need to make sure to skip any RASL slices that follow a non-IDR key frame such as
     * CRA_NUT. This is because RASL slices cannot be decoded without data before the CRA_NUT. Browsers behave
     * differently here: Chromium drops the packets, Safari throws a decoder error. Either way, it's not good
     * and causes bugs upstream. So, let's take the dropping into our own hands.
     */
    hasHevcRaslPicture(packetData) {
        for (const loc of (0,_codec_data_js__WEBPACK_IMPORTED_MODULE_1__/* .iterateHevcNalUnits */ .RF)(packetData, this.decoderConfig)) {
            const type = (0,_codec_data_js__WEBPACK_IMPORTED_MODULE_1__/* .extractNalUnitTypeForHevc */ .O9)(packetData[loc.offset]);
            if (type === _codec_data_js__WEBPACK_IMPORTED_MODULE_1__/* .HevcNalUnitType */ .iJ.RASL_N || type === _codec_data_js__WEBPACK_IMPORTED_MODULE_1__/* .HevcNalUnitType */ .iJ.RASL_R) {
                return true;
            }
        }
        return false;
    }
    /** Handler for the WebCodecs VideoDecoder for ironing out browser differences. */
    sampleHandler(sample) {
        if ((0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .isWebKit */ .Tc)()) {
            // For correct B-frame handling, we don't just hand over the frames directly but instead add them to
            // a queue, because we want to ensure frames are emitted in presentation order. We flush the queue
            // each time we receive a frame with a timestamp larger than the highest we've seen so far, as we
            // can sure that is not a B-frame. Typically, WebCodecs automatically guarantees that frames are
            // emitted in presentation order, but Safari doesn't always follow this rule.
            if (this.sampleQueue.length > 0 && (sample.timestamp >= (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .last */ ._g)(this.sampleQueue).timestamp)) {
                for (const sample of this.sampleQueue) {
                    this.finalizeAndEmitSample(sample);
                }
                this.sampleQueue.length = 0;
            }
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .insertSorted */ .h8)(this.sampleQueue, sample, x => x.timestamp);
        }
        else {
            // Assign it the next earliest timestamp from the input. We do this because browsers, by spec, are
            // required to emit decoded frames in presentation order *while* retaining the timestamp of their
            // originating EncodedVideoChunk. For files with B-frames but no out-of-order timestamps (like a
            // missing ctts box, for example), this causes a mismatch. We therefore fix the timestamps and
            // ensure they are sorted by doing this.
            const timestamp = this.inputTimestamps.shift();
            // There's no way we'd have more decoded frames than encoded packets we passed in. Actually, the
            // correspondence should be 1:1.
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(timestamp !== undefined);
            sample.setTimestamp(timestamp);
            this.finalizeAndEmitSample(sample);
        }
    }
    finalizeAndEmitSample(sample) {
        // Round the timestamps to the time resolution
        sample.setTimestamp(Math.round(sample.timestamp * this.timeResolution) / this.timeResolution);
        sample.setDuration(Math.round(sample.duration * this.timeResolution) / this.timeResolution);
        sample.setRotation(this.rotation);
        this.onSample(sample);
    }
    mergeAlpha(color, alpha) {
        if (!alpha) {
            // Nothing needs to be merged
            const finalSample = new _sample_js__WEBPACK_IMPORTED_MODULE_8__/* .VideoSample */ .U2(color);
            this.sampleHandler(finalSample);
            return;
        }
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(this.merger);
        this.merger.update(color, alpha);
        color.close();
        alpha.close();
        const finalFrame = new VideoFrame(this.merger.canvas, {
            timestamp: color.timestamp,
            duration: color.duration ?? undefined,
        });
        const finalSample = new _sample_js__WEBPACK_IMPORTED_MODULE_8__/* .VideoSample */ .U2(finalFrame);
        this.sampleHandler(finalSample);
    }
    async flush() {
        if (this.customDecoder) {
            await this.customDecoderCallSerializer.call(() => this.customDecoder.flush());
        }
        else {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(this.decoder);
            await Promise.all([
                this.decoder.flush(),
                this.alphaDecoder?.flush(),
            ]);
            this.colorQueue.forEach(x => x.close());
            this.colorQueue.length = 0;
            this.alphaQueue.forEach(x => x?.close());
            this.alphaQueue.length = 0;
            this.alphaHadKeyframe = false;
            this.decodedAlphaChunkCount = 0;
            this.alphaDecoderQueueSize = 0;
            this.nullAlphaFrameQueue.length = 0;
            this.currentAlphaPacketIndex = 0;
            this.alphaRaslSkipped = false;
        }
        if ((0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .isWebKit */ .Tc)()) {
            for (const sample of this.sampleQueue) {
                this.finalizeAndEmitSample(sample);
            }
            this.sampleQueue.length = 0;
        }
        this.currentPacketIndex = 0;
        this.raslSkipped = false;
    }
    close() {
        if (this.customDecoder) {
            void this.customDecoderCallSerializer.call(() => this.customDecoder.close());
        }
        else {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(this.decoder);
            this.decoder.close();
            this.alphaDecoder?.close();
            this.colorQueue.forEach(x => x.close());
            this.colorQueue.length = 0;
            this.alphaQueue.forEach(x => x?.close());
            this.alphaQueue.length = 0;
            this.merger?.close();
        }
        for (const sample of this.sampleQueue) {
            sample.close();
        }
        this.sampleQueue.length = 0;
    }
}
/** Utility class that merges together color and alpha information using simple WebGL 2 shaders. */
class ColorAlphaMerger {
    constructor() {
        // Canvas will be resized later
        if (typeof OffscreenCanvas !== 'undefined') {
            // Prefer OffscreenCanvas for Worker environments
            this.canvas = new OffscreenCanvas(300, 150);
        }
        else {
            this.canvas = document.createElement('canvas');
        }
        const gl = this.canvas.getContext('webgl2', {
            premultipliedAlpha: false,
        }); // Casting because of some TypeScript weirdness
        if (!gl) {
            throw new Error('Couldn\'t acquire WebGL 2 context.');
        }
        this.gl = gl;
        this.program = this.createProgram();
        this.vao = this.createVAO();
        this.colorTexture = this.createTexture();
        this.alphaTexture = this.createTexture();
        this.gl.useProgram(this.program);
        this.gl.uniform1i(this.gl.getUniformLocation(this.program, 'u_colorTexture'), 0);
        this.gl.uniform1i(this.gl.getUniformLocation(this.program, 'u_alphaTexture'), 1);
    }
    createProgram() {
        const vertexShader = this.createShader(this.gl.VERTEX_SHADER, `#version 300 es
			in vec2 a_position;
			in vec2 a_texCoord;
			out vec2 v_texCoord;
			
			void main() {
				gl_Position = vec4(a_position, 0.0, 1.0);
				v_texCoord = a_texCoord;
			}
		`);
        const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, `#version 300 es
			precision highp float;
			
			uniform sampler2D u_colorTexture;
			uniform sampler2D u_alphaTexture;
			in vec2 v_texCoord;
			out vec4 fragColor;
			
			void main() {
				vec3 color = texture(u_colorTexture, v_texCoord).rgb;
				float alpha = texture(u_alphaTexture, v_texCoord).r;
				fragColor = vec4(color, alpha);
			}
		`);
        const program = this.gl.createProgram();
        this.gl.attachShader(program, vertexShader);
        this.gl.attachShader(program, fragmentShader);
        this.gl.linkProgram(program);
        return program;
    }
    createShader(type, source) {
        const shader = this.gl.createShader(type);
        this.gl.shaderSource(shader, source);
        this.gl.compileShader(shader);
        return shader;
    }
    createVAO() {
        const vao = this.gl.createVertexArray();
        this.gl.bindVertexArray(vao);
        const vertices = new Float32Array([
            -1, -1, 0, 1,
            1, -1, 1, 1,
            -1, 1, 0, 0,
            1, 1, 1, 0,
        ]);
        const buffer = this.gl.createBuffer();
        this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
        this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);
        const positionLocation = this.gl.getAttribLocation(this.program, 'a_position');
        const texCoordLocation = this.gl.getAttribLocation(this.program, 'a_texCoord');
        this.gl.enableVertexAttribArray(positionLocation);
        this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 16, 0);
        this.gl.enableVertexAttribArray(texCoordLocation);
        this.gl.vertexAttribPointer(texCoordLocation, 2, this.gl.FLOAT, false, 16, 8);
        return vao;
    }
    createTexture() {
        const texture = this.gl.createTexture();
        this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
        this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
        return texture;
    }
    update(color, alpha) {
        if (color.displayWidth !== this.canvas.width || color.displayHeight !== this.canvas.height) {
            this.canvas.width = color.displayWidth;
            this.canvas.height = color.displayHeight;
        }
        this.gl.activeTexture(this.gl.TEXTURE0);
        this.gl.bindTexture(this.gl.TEXTURE_2D, this.colorTexture);
        this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, color);
        this.gl.activeTexture(this.gl.TEXTURE1);
        this.gl.bindTexture(this.gl.TEXTURE_2D, this.alphaTexture);
        this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, alpha);
        this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
        this.gl.clear(this.gl.COLOR_BUFFER_BIT);
        this.gl.bindVertexArray(this.vao);
        this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);
    }
    close() {
        this.gl.getExtension('WEBGL_lose_context')?.loseContext();
        this.gl = null;
    }
}
/**
 * A sink that retrieves decoded video samples (video frames) from a video track.
 * @group Media sinks
 * @public
 */
class VideoSampleSink extends BaseMediaSampleSink {
    /** Creates a new {@link VideoSampleSink} for the given {@link InputVideoTrack}. */
    constructor(videoTrack) {
        if (!(videoTrack instanceof _input_track_js__WEBPACK_IMPORTED_MODULE_4__/* .InputVideoTrack */ .N0)) {
            throw new TypeError('videoTrack must be an InputVideoTrack.');
        }
        super();
        this._track = videoTrack;
    }
    /** @internal */
    async _createDecoder(onSample, onError) {
        if (!(await this._track.canDecode())) {
            throw new Error('This video track cannot be decoded by this browser. Make sure to check decodability before using'
                + ' a track.');
        }
        const codec = this._track.codec;
        const rotation = this._track.rotation;
        const decoderConfig = await this._track.getDecoderConfig();
        const timeResolution = this._track.timeResolution;
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(codec && decoderConfig);
        return new VideoDecoderWrapper(onSample, onError, codec, decoderConfig, rotation, timeResolution);
    }
    /** @internal */
    _createPacketSink() {
        return new EncodedPacketSink(this._track);
    }
    /**
     * Retrieves the video sample (frame) corresponding to the given timestamp, in seconds. More specifically, returns
     * the last video sample (in presentation order) with a start timestamp less than or equal to the given timestamp.
     * Returns null if the timestamp is before the track's first timestamp.
     *
     * @param timestamp - The timestamp used for retrieval, in seconds.
     */
    async getSample(timestamp) {
        validateTimestamp(timestamp);
        for await (const sample of this.mediaSamplesAtTimestamps([timestamp])) {
            return sample;
        }
        throw new Error('Internal error: Iterator returned nothing.');
    }
    /**
     * Creates an async iterator that yields the video samples (frames) of this track in presentation order. This method
     * will intelligently pre-decode a few frames ahead to enable fast iteration.
     *
     * @param startTimestamp - The timestamp in seconds at which to start yielding samples (inclusive).
     * @param endTimestamp - The timestamp in seconds at which to stop yielding samples (exclusive).
     */
    samples(startTimestamp = 0, endTimestamp = Infinity) {
        return this.mediaSamplesInRange(startTimestamp, endTimestamp);
    }
    /**
     * Creates an async iterator that yields a video sample (frame) for each timestamp in the argument. This method
     * uses an optimized decoding pipeline if these timestamps are monotonically sorted, decoding each packet at most
     * once, and is therefore more efficient than manually getting the sample for every timestamp. The iterator may
     * yield null if no frame is available for a given timestamp.
     *
     * @param timestamps - An iterable or async iterable of timestamps in seconds.
     */
    samplesAtTimestamps(timestamps) {
        return this.mediaSamplesAtTimestamps(timestamps);
    }
}
/**
 * A sink that renders video samples (frames) of the given video track to canvases. This is often more useful than
 * directly retrieving frames, as it comes with common preprocessing steps such as resizing or applying rotation
 * metadata.
 *
 * This sink will yield `HTMLCanvasElement`s when in a DOM context, and `OffscreenCanvas`es otherwise.
 *
 * @group Media sinks
 * @public
 */
class CanvasSink {
    /** Creates a new {@link CanvasSink} for the given {@link InputVideoTrack}. */
    constructor(videoTrack, options = {}) {
        /** @internal */
        this._nextCanvasIndex = 0;
        if (!(videoTrack instanceof InputVideoTrack)) {
            throw new TypeError('videoTrack must be an InputVideoTrack.');
        }
        if (options && typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (options.alpha !== undefined && typeof options.alpha !== 'boolean') {
            throw new TypeError('options.alpha, when provided, must be a boolean.');
        }
        if (options.width !== undefined && (!Number.isInteger(options.width) || options.width <= 0)) {
            throw new TypeError('options.width, when defined, must be a positive integer.');
        }
        if (options.height !== undefined && (!Number.isInteger(options.height) || options.height <= 0)) {
            throw new TypeError('options.height, when defined, must be a positive integer.');
        }
        if (options.fit !== undefined && !['fill', 'contain', 'cover'].includes(options.fit)) {
            throw new TypeError('options.fit, when provided, must be one of "fill", "contain", or "cover".');
        }
        if (options.width !== undefined
            && options.height !== undefined
            && options.fit === undefined) {
            throw new TypeError('When both options.width and options.height are provided, options.fit must also be provided.');
        }
        if (options.rotation !== undefined && ![0, 90, 180, 270].includes(options.rotation)) {
            throw new TypeError('options.rotation, when provided, must be 0, 90, 180 or 270.');
        }
        if (options.crop !== undefined) {
            validateCropRectangle(options.crop, 'options.');
        }
        if (options.poolSize !== undefined
            && (typeof options.poolSize !== 'number' || !Number.isInteger(options.poolSize) || options.poolSize < 0)) {
            throw new TypeError('poolSize must be a non-negative integer.');
        }
        const rotation = options.rotation ?? videoTrack.rotation;
        const [rotatedWidth, rotatedHeight] = rotation % 180 === 0
            ? [videoTrack.codedWidth, videoTrack.codedHeight]
            : [videoTrack.codedHeight, videoTrack.codedWidth];
        const crop = options.crop;
        if (crop) {
            clampCropRectangle(crop, rotatedWidth, rotatedHeight);
        }
        let [width, height] = crop
            ? [crop.width, crop.height]
            : [rotatedWidth, rotatedHeight];
        const originalAspectRatio = width / height;
        // If width and height aren't defined together, deduce the missing value using the aspect ratio
        if (options.width !== undefined && options.height === undefined) {
            width = options.width;
            height = Math.round(width / originalAspectRatio);
        }
        else if (options.width === undefined && options.height !== undefined) {
            height = options.height;
            width = Math.round(height * originalAspectRatio);
        }
        else if (options.width !== undefined && options.height !== undefined) {
            width = options.width;
            height = options.height;
        }
        this._videoTrack = videoTrack;
        this._alpha = options.alpha ?? false;
        this._width = width;
        this._height = height;
        this._rotation = rotation;
        this._crop = crop;
        this._fit = options.fit ?? 'fill';
        this._videoSampleSink = new VideoSampleSink(videoTrack);
        this._canvasPool = Array.from({ length: options.poolSize ?? 0 }, () => null);
    }
    /** @internal */
    _videoSampleToWrappedCanvas(sample) {
        let canvas = this._canvasPool[this._nextCanvasIndex];
        let canvasIsNew = false;
        if (!canvas) {
            if (typeof document !== 'undefined') {
                // Prefer an HTMLCanvasElement
                canvas = document.createElement('canvas');
                canvas.width = this._width;
                canvas.height = this._height;
            }
            else {
                canvas = new OffscreenCanvas(this._width, this._height);
            }
            if (this._canvasPool.length > 0) {
                this._canvasPool[this._nextCanvasIndex] = canvas;
            }
            canvasIsNew = true;
        }
        if (this._canvasPool.length > 0) {
            this._nextCanvasIndex = (this._nextCanvasIndex + 1) % this._canvasPool.length;
        }
        const context = canvas.getContext('2d', {
            alpha: this._alpha || isFirefox(), // Firefox has VideoFrame glitches with opaque canvases
        });
        assert(context);
        context.resetTransform();
        if (!canvasIsNew) {
            if (!this._alpha && isFirefox()) {
                context.fillStyle = 'black';
                context.fillRect(0, 0, this._width, this._height);
            }
            else {
                context.clearRect(0, 0, this._width, this._height);
            }
        }
        sample.drawWithFit(context, {
            fit: this._fit,
            rotation: this._rotation,
            crop: this._crop,
        });
        const result = {
            canvas,
            timestamp: sample.timestamp,
            duration: sample.duration,
        };
        sample.close();
        return result;
    }
    /**
     * Retrieves a canvas with the video frame corresponding to the given timestamp, in seconds. More specifically,
     * returns the last video frame (in presentation order) with a start timestamp less than or equal to the given
     * timestamp. Returns null if the timestamp is before the track's first timestamp.
     *
     * @param timestamp - The timestamp used for retrieval, in seconds.
     */
    async getCanvas(timestamp) {
        validateTimestamp(timestamp);
        const sample = await this._videoSampleSink.getSample(timestamp);
        return sample && this._videoSampleToWrappedCanvas(sample);
    }
    /**
     * Creates an async iterator that yields canvases with the video frames of this track in presentation order. This
     * method will intelligently pre-decode a few frames ahead to enable fast iteration.
     *
     * @param startTimestamp - The timestamp in seconds at which to start yielding canvases (inclusive).
     * @param endTimestamp - The timestamp in seconds at which to stop yielding canvases (exclusive).
     */
    canvases(startTimestamp = 0, endTimestamp = Infinity) {
        return mapAsyncGenerator(this._videoSampleSink.samples(startTimestamp, endTimestamp), sample => this._videoSampleToWrappedCanvas(sample));
    }
    /**
     * Creates an async iterator that yields a canvas for each timestamp in the argument. This method uses an optimized
     * decoding pipeline if these timestamps are monotonically sorted, decoding each packet at most once, and is
     * therefore more efficient than manually getting the canvas for every timestamp. The iterator may yield null if
     * no frame is available for a given timestamp.
     *
     * @param timestamps - An iterable or async iterable of timestamps in seconds.
     */
    canvasesAtTimestamps(timestamps) {
        return mapAsyncGenerator(this._videoSampleSink.samplesAtTimestamps(timestamps), sample => sample && this._videoSampleToWrappedCanvas(sample));
    }
}
class AudioDecoderWrapper extends DecoderWrapper {
    constructor(onSample, onError, codec, decoderConfig) {
        super(onSample, onError);
        this.decoder = null;
        this.customDecoder = null;
        this.customDecoderCallSerializer = new _misc_js__WEBPACK_IMPORTED_MODULE_5__/* .CallSerializer */ .dY();
        this.customDecoderQueueSize = 0;
        // Internal state to accumulate a precise current timestamp based on audio durations, not the (potentially
        // inaccurate) packet timestamps.
        this.currentTimestamp = null;
        const sampleHandler = (sample) => {
            if (this.currentTimestamp === null
                || Math.abs(sample.timestamp - this.currentTimestamp) >= sample.duration) {
                // We need to sync with the sample timestamp again
                this.currentTimestamp = sample.timestamp;
            }
            const preciseTimestamp = this.currentTimestamp;
            this.currentTimestamp += sample.duration;
            if (sample.numberOfFrames === 0) {
                // We skip zero-data (empty) AudioSamples. These are sometimes emitted, for example, by Firefox when it
                // decodes Vorbis (at the start).
                sample.close();
                return;
            }
            // Round the timestamp to the sample rate
            const sampleRate = decoderConfig.sampleRate;
            sample.setTimestamp(Math.round(preciseTimestamp * sampleRate) / sampleRate);
            onSample(sample);
        };
        const MatchingCustomDecoder = _custom_coder_js__WEBPACK_IMPORTED_MODULE_2__/* .customAudioDecoders */ .zx.find(x => x.supports(codec, decoderConfig));
        if (MatchingCustomDecoder) {
            // @ts-expect-error "Can't create instance of abstract class 🤓"
            this.customDecoder = new MatchingCustomDecoder();
            // @ts-expect-error It's technically readonly
            this.customDecoder.codec = codec;
            // @ts-expect-error It's technically readonly
            this.customDecoder.config = decoderConfig;
            // @ts-expect-error It's technically readonly
            this.customDecoder.onSample = (sample) => {
                if (!(sample instanceof _sample_js__WEBPACK_IMPORTED_MODULE_8__/* .AudioSample */ .B1)) {
                    throw new TypeError('The argument passed to onSample must be an AudioSample.');
                }
                sampleHandler(sample);
            };
            void this.customDecoderCallSerializer.call(() => this.customDecoder.init());
        }
        else {
            const stack = new Error('Decoding error').stack;
            this.decoder = new AudioDecoder({
                output: (data) => {
                    try {
                        sampleHandler(new _sample_js__WEBPACK_IMPORTED_MODULE_8__/* .AudioSample */ .B1(data));
                    }
                    catch (error) {
                        this.onError(error);
                    }
                },
                error: (error) => {
                    error.stack = stack; // Provide a more useful stack trace, the default one sucks
                    this.onError(error);
                },
            });
            this.decoder.configure(decoderConfig);
        }
    }
    getDecodeQueueSize() {
        if (this.customDecoder) {
            return this.customDecoderQueueSize;
        }
        else {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(this.decoder);
            return this.decoder.decodeQueueSize;
        }
    }
    decode(packet) {
        if (this.customDecoder) {
            this.customDecoderQueueSize++;
            void this.customDecoderCallSerializer
                .call(() => this.customDecoder.decode(packet))
                .then(() => this.customDecoderQueueSize--);
        }
        else {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(this.decoder);
            this.decoder.decode(packet.toEncodedAudioChunk());
        }
    }
    flush() {
        if (this.customDecoder) {
            return this.customDecoderCallSerializer.call(() => this.customDecoder.flush());
        }
        else {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(this.decoder);
            return this.decoder.flush();
        }
    }
    close() {
        if (this.customDecoder) {
            void this.customDecoderCallSerializer.call(() => this.customDecoder.close());
        }
        else {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(this.decoder);
            this.decoder.close();
        }
    }
}
// There are a lot of PCM variants not natively supported by the browser and by AudioData. Therefore we need a simple
// decoder that maps any input PCM format into a PCM format supported by the browser.
class PcmAudioDecoderWrapper extends DecoderWrapper {
    constructor(onSample, onError, decoderConfig) {
        super(onSample, onError);
        this.decoderConfig = decoderConfig;
        // Internal state to accumulate a precise current timestamp based on audio durations, not the (potentially
        // inaccurate) packet timestamps.
        this.currentTimestamp = null;
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(_codec_js__WEBPACK_IMPORTED_MODULE_0__/* .PCM_AUDIO_CODECS */ .Wq.includes(decoderConfig.codec));
        this.codec = decoderConfig.codec;
        const { dataType, sampleSize, littleEndian } = (0,_codec_js__WEBPACK_IMPORTED_MODULE_0__/* .parsePcmCodec */ .Ei)(this.codec);
        this.inputSampleSize = sampleSize;
        switch (sampleSize) {
            case 1:
                {
                    if (dataType === 'unsigned') {
                        this.readInputValue = (view, byteOffset) => view.getUint8(byteOffset) - 2 ** 7;
                    }
                    else if (dataType === 'signed') {
                        this.readInputValue = (view, byteOffset) => view.getInt8(byteOffset);
                    }
                    else if (dataType === 'ulaw') {
                        this.readInputValue = (view, byteOffset) => (0,_pcm_js__WEBPACK_IMPORTED_MODULE_7__/* .fromUlaw */ .qS)(view.getUint8(byteOffset));
                    }
                    else if (dataType === 'alaw') {
                        this.readInputValue = (view, byteOffset) => (0,_pcm_js__WEBPACK_IMPORTED_MODULE_7__/* .fromAlaw */ .aw)(view.getUint8(byteOffset));
                    }
                    else {
                        (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(false);
                    }
                }
                ;
                break;
            case 2:
                {
                    if (dataType === 'unsigned') {
                        this.readInputValue = (view, byteOffset) => view.getUint16(byteOffset, littleEndian) - 2 ** 15;
                    }
                    else if (dataType === 'signed') {
                        this.readInputValue = (view, byteOffset) => view.getInt16(byteOffset, littleEndian);
                    }
                    else {
                        (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(false);
                    }
                }
                ;
                break;
            case 3:
                {
                    if (dataType === 'unsigned') {
                        this.readInputValue = (view, byteOffset) => (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .getUint24 */ .dq)(view, byteOffset, littleEndian) - 2 ** 23;
                    }
                    else if (dataType === 'signed') {
                        this.readInputValue = (view, byteOffset) => (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .getInt24 */ .Wh)(view, byteOffset, littleEndian);
                    }
                    else {
                        (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(false);
                    }
                }
                ;
                break;
            case 4:
                {
                    if (dataType === 'unsigned') {
                        this.readInputValue = (view, byteOffset) => view.getUint32(byteOffset, littleEndian) - 2 ** 31;
                    }
                    else if (dataType === 'signed') {
                        this.readInputValue = (view, byteOffset) => view.getInt32(byteOffset, littleEndian);
                    }
                    else if (dataType === 'float') {
                        this.readInputValue = (view, byteOffset) => view.getFloat32(byteOffset, littleEndian);
                    }
                    else {
                        (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(false);
                    }
                }
                ;
                break;
            case 8:
                {
                    if (dataType === 'float') {
                        this.readInputValue = (view, byteOffset) => view.getFloat64(byteOffset, littleEndian);
                    }
                    else {
                        (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(false);
                    }
                }
                ;
                break;
            default:
                {
                    (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assertNever */ .xb)(sampleSize);
                    (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(false);
                }
                ;
        }
        switch (sampleSize) {
            case 1:
                {
                    if (dataType === 'ulaw' || dataType === 'alaw') {
                        this.outputSampleSize = 2;
                        this.outputFormat = 's16';
                        this.writeOutputValue = (view, byteOffset, value) => view.setInt16(byteOffset, value, true);
                    }
                    else {
                        this.outputSampleSize = 1;
                        this.outputFormat = 'u8';
                        this.writeOutputValue = (view, byteOffset, value) => view.setUint8(byteOffset, value + 2 ** 7);
                    }
                }
                ;
                break;
            case 2:
                {
                    this.outputSampleSize = 2;
                    this.outputFormat = 's16';
                    this.writeOutputValue = (view, byteOffset, value) => view.setInt16(byteOffset, value, true);
                }
                ;
                break;
            case 3:
                {
                    this.outputSampleSize = 4;
                    this.outputFormat = 's32';
                    // From https://www.w3.org/TR/webcodecs:
                    // AudioData containing 24-bit samples SHOULD store those samples in s32 or f32. When samples are
                    // stored in s32, each sample MUST be left-shifted by 8 bits.
                    this.writeOutputValue = (view, byteOffset, value) => view.setInt32(byteOffset, value << 8, true);
                }
                ;
                break;
            case 4:
                {
                    this.outputSampleSize = 4;
                    if (dataType === 'float') {
                        this.outputFormat = 'f32';
                        this.writeOutputValue = (view, byteOffset, value) => view.setFloat32(byteOffset, value, true);
                    }
                    else {
                        this.outputFormat = 's32';
                        this.writeOutputValue = (view, byteOffset, value) => view.setInt32(byteOffset, value, true);
                    }
                }
                ;
                break;
            case 8:
                {
                    this.outputSampleSize = 4;
                    this.outputFormat = 'f32';
                    this.writeOutputValue = (view, byteOffset, value) => view.setFloat32(byteOffset, value, true);
                }
                ;
                break;
            default:
                {
                    (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assertNever */ .xb)(sampleSize);
                    (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(false);
                }
                ;
        }
        ;
    }
    getDecodeQueueSize() {
        return 0;
    }
    decode(packet) {
        const inputView = (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .toDataView */ .Zc)(packet.data);
        const numberOfFrames = packet.byteLength / this.decoderConfig.numberOfChannels / this.inputSampleSize;
        const outputBufferSize = numberOfFrames * this.decoderConfig.numberOfChannels * this.outputSampleSize;
        const outputBuffer = new ArrayBuffer(outputBufferSize);
        const outputView = new DataView(outputBuffer);
        for (let i = 0; i < numberOfFrames * this.decoderConfig.numberOfChannels; i++) {
            const inputIndex = i * this.inputSampleSize;
            const outputIndex = i * this.outputSampleSize;
            const value = this.readInputValue(inputView, inputIndex);
            this.writeOutputValue(outputView, outputIndex, value);
        }
        const preciseDuration = numberOfFrames / this.decoderConfig.sampleRate;
        if (this.currentTimestamp === null || Math.abs(packet.timestamp - this.currentTimestamp) >= preciseDuration) {
            // We need to sync with the packet timestamp again
            this.currentTimestamp = packet.timestamp;
        }
        const preciseTimestamp = this.currentTimestamp;
        this.currentTimestamp += preciseDuration;
        const audioSample = new _sample_js__WEBPACK_IMPORTED_MODULE_8__/* .AudioSample */ .B1({
            format: this.outputFormat,
            data: outputBuffer,
            numberOfChannels: this.decoderConfig.numberOfChannels,
            sampleRate: this.decoderConfig.sampleRate,
            numberOfFrames,
            timestamp: preciseTimestamp,
        });
        this.onSample(audioSample);
    }
    async flush() {
        // Do nothing
    }
    close() {
        // Do nothing
    }
}
/**
 * Sink for retrieving decoded audio samples from an audio track.
 * @group Media sinks
 * @public
 */
class AudioSampleSink extends BaseMediaSampleSink {
    /** Creates a new {@link AudioSampleSink} for the given {@link InputAudioTrack}. */
    constructor(audioTrack) {
        if (!(audioTrack instanceof _input_track_js__WEBPACK_IMPORTED_MODULE_4__/* .InputAudioTrack */ .Yi)) {
            throw new TypeError('audioTrack must be an InputAudioTrack.');
        }
        super();
        this._track = audioTrack;
    }
    /** @internal */
    async _createDecoder(onSample, onError) {
        if (!(await this._track.canDecode())) {
            throw new Error('This audio track cannot be decoded by this browser. Make sure to check decodability before using'
                + ' a track.');
        }
        const codec = this._track.codec;
        const decoderConfig = await this._track.getDecoderConfig();
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_5__/* .assert */ .vA)(codec && decoderConfig);
        if (_codec_js__WEBPACK_IMPORTED_MODULE_0__/* .PCM_AUDIO_CODECS */ .Wq.includes(decoderConfig.codec)) {
            return new PcmAudioDecoderWrapper(onSample, onError, decoderConfig);
        }
        else {
            return new AudioDecoderWrapper(onSample, onError, codec, decoderConfig);
        }
    }
    /** @internal */
    _createPacketSink() {
        return new EncodedPacketSink(this._track);
    }
    /**
     * Retrieves the audio sample corresponding to the given timestamp, in seconds. More specifically, returns
     * the last audio sample (in presentation order) with a start timestamp less than or equal to the given timestamp.
     * Returns null if the timestamp is before the track's first timestamp.
     *
     * @param timestamp - The timestamp used for retrieval, in seconds.
     */
    async getSample(timestamp) {
        validateTimestamp(timestamp);
        for await (const sample of this.mediaSamplesAtTimestamps([timestamp])) {
            return sample;
        }
        throw new Error('Internal error: Iterator returned nothing.');
    }
    /**
     * Creates an async iterator that yields the audio samples of this track in presentation order. This method
     * will intelligently pre-decode a few samples ahead to enable fast iteration.
     *
     * @param startTimestamp - The timestamp in seconds at which to start yielding samples (inclusive).
     * @param endTimestamp - The timestamp in seconds at which to stop yielding samples (exclusive).
     */
    samples(startTimestamp = 0, endTimestamp = Infinity) {
        return this.mediaSamplesInRange(startTimestamp, endTimestamp);
    }
    /**
     * Creates an async iterator that yields an audio sample for each timestamp in the argument. This method
     * uses an optimized decoding pipeline if these timestamps are monotonically sorted, decoding each packet at most
     * once, and is therefore more efficient than manually getting the sample for every timestamp. The iterator may
     * yield null if no sample is available for a given timestamp.
     *
     * @param timestamps - An iterable or async iterable of timestamps in seconds.
     */
    samplesAtTimestamps(timestamps) {
        return this.mediaSamplesAtTimestamps(timestamps);
    }
}
/**
 * A sink that retrieves decoded audio samples from an audio track and converts them to `AudioBuffer` instances. This is
 * often more useful than directly retrieving audio samples, as audio buffers can be directly used with the
 * Web Audio API.
 * @group Media sinks
 * @public
 */
class AudioBufferSink {
    /** Creates a new {@link AudioBufferSink} for the given {@link InputAudioTrack}. */
    constructor(audioTrack) {
        if (!(audioTrack instanceof InputAudioTrack)) {
            throw new TypeError('audioTrack must be an InputAudioTrack.');
        }
        this._audioSampleSink = new AudioSampleSink(audioTrack);
    }
    /** @internal */
    _audioSampleToWrappedArrayBuffer(sample) {
        const result = {
            buffer: sample.toAudioBuffer(),
            timestamp: sample.timestamp,
            duration: sample.duration,
        };
        sample.close();
        return result;
    }
    /**
     * Retrieves the audio buffer corresponding to the given timestamp, in seconds. More specifically, returns
     * the last audio buffer (in presentation order) with a start timestamp less than or equal to the given timestamp.
     * Returns null if the timestamp is before the track's first timestamp.
     *
     * @param timestamp - The timestamp used for retrieval, in seconds.
     */
    async getBuffer(timestamp) {
        validateTimestamp(timestamp);
        const data = await this._audioSampleSink.getSample(timestamp);
        return data && this._audioSampleToWrappedArrayBuffer(data);
    }
    /**
     * Creates an async iterator that yields audio buffers of this track in presentation order. This method
     * will intelligently pre-decode a few buffers ahead to enable fast iteration.
     *
     * @param startTimestamp - The timestamp in seconds at which to start yielding buffers (inclusive).
     * @param endTimestamp - The timestamp in seconds at which to stop yielding buffers (exclusive).
     */
    buffers(startTimestamp = 0, endTimestamp = Infinity) {
        return mapAsyncGenerator(this._audioSampleSink.samples(startTimestamp, endTimestamp), data => this._audioSampleToWrappedArrayBuffer(data));
    }
    /**
     * Creates an async iterator that yields an audio buffer for each timestamp in the argument. This method
     * uses an optimized decoding pipeline if these timestamps are monotonically sorted, decoding each packet at most
     * once, and is therefore more efficient than manually getting the buffer for every timestamp. The iterator may
     * yield null if no buffer is available for a given timestamp.
     *
     * @param timestamps - An iterable or async iterable of timestamps in seconds.
     */
    buffersAtTimestamps(timestamps) {
        return mapAsyncGenerator(this._audioSampleSink.samplesAtTimestamps(timestamps), data => data && this._audioSampleToWrappedArrayBuffer(data));
    }
}


/***/ },

/***/ 5165
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   VD: () => (/* binding */ validateMetadataTags),
/* harmony export */   VF: () => (/* binding */ AttachedFile),
/* harmony export */   Ze: () => (/* binding */ validateTrackDisposition),
/* harmony export */   cc: () => (/* binding */ metadataTagsAreEmpty),
/* harmony export */   gM: () => (/* binding */ DEFAULT_TRACK_DISPOSITION),
/* harmony export */   sF: () => (/* binding */ RichImageData)
/* harmony export */ });
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */
/**
 * Image data with additional metadata.
 *
 * @group Metadata tags
 * @public
 */
class RichImageData {
    /** Creates a new {@link RichImageData}. */
    constructor(
    /** The raw image data. */
    data, 
    /** An RFC 6838 MIME type (e.g. image/jpeg, image/png, etc.) */
    mimeType) {
        this.data = data;
        this.mimeType = mimeType;
        if (!(data instanceof Uint8Array)) {
            throw new TypeError('data must be a Uint8Array.');
        }
        if (typeof mimeType !== 'string') {
            throw new TypeError('mimeType must be a string.');
        }
    }
}
/**
 * A file attached to a media file.
 *
 * @group Metadata tags
 * @public
 */
class AttachedFile {
    /** Creates a new {@link AttachedFile}. */
    constructor(
    /** The raw file data. */
    data, 
    /** An RFC 6838 MIME type (e.g. image/jpeg, image/png, font/ttf, etc.) */
    mimeType, 
    /** The name of the file. */
    name, 
    /** A description of the file. */
    description) {
        this.data = data;
        this.mimeType = mimeType;
        this.name = name;
        this.description = description;
        if (!(data instanceof Uint8Array)) {
            throw new TypeError('data must be a Uint8Array.');
        }
        if (mimeType !== undefined && typeof mimeType !== 'string') {
            throw new TypeError('mimeType, when provided, must be a string.');
        }
        if (name !== undefined && typeof name !== 'string') {
            throw new TypeError('name, when provided, must be a string.');
        }
        if (description !== undefined && typeof description !== 'string') {
            throw new TypeError('description, when provided, must be a string.');
        }
    }
}
;
const validateMetadataTags = (tags) => {
    if (!tags || typeof tags !== 'object') {
        throw new TypeError('tags must be an object.');
    }
    if (tags.title !== undefined && typeof tags.title !== 'string') {
        throw new TypeError('tags.title, when provided, must be a string.');
    }
    if (tags.description !== undefined && typeof tags.description !== 'string') {
        throw new TypeError('tags.description, when provided, must be a string.');
    }
    if (tags.artist !== undefined && typeof tags.artist !== 'string') {
        throw new TypeError('tags.artist, when provided, must be a string.');
    }
    if (tags.album !== undefined && typeof tags.album !== 'string') {
        throw new TypeError('tags.album, when provided, must be a string.');
    }
    if (tags.albumArtist !== undefined && typeof tags.albumArtist !== 'string') {
        throw new TypeError('tags.albumArtist, when provided, must be a string.');
    }
    if (tags.trackNumber !== undefined && (!Number.isInteger(tags.trackNumber) || tags.trackNumber <= 0)) {
        throw new TypeError('tags.trackNumber, when provided, must be a positive integer.');
    }
    if (tags.tracksTotal !== undefined
        && (!Number.isInteger(tags.tracksTotal) || tags.tracksTotal <= 0)) {
        throw new TypeError('tags.tracksTotal, when provided, must be a positive integer.');
    }
    if (tags.discNumber !== undefined && (!Number.isInteger(tags.discNumber) || tags.discNumber <= 0)) {
        throw new TypeError('tags.discNumber, when provided, must be a positive integer.');
    }
    if (tags.discsTotal !== undefined
        && (!Number.isInteger(tags.discsTotal) || tags.discsTotal <= 0)) {
        throw new TypeError('tags.discsTotal, when provided, must be a positive integer.');
    }
    if (tags.genre !== undefined && typeof tags.genre !== 'string') {
        throw new TypeError('tags.genre, when provided, must be a string.');
    }
    if (tags.date !== undefined && (!(tags.date instanceof Date) || Number.isNaN(tags.date.getTime()))) {
        throw new TypeError('tags.date, when provided, must be a valid Date.');
    }
    if (tags.lyrics !== undefined && typeof tags.lyrics !== 'string') {
        throw new TypeError('tags.lyrics, when provided, must be a string.');
    }
    if (tags.images !== undefined) {
        if (!Array.isArray(tags.images)) {
            throw new TypeError('tags.images, when provided, must be an array.');
        }
        for (const image of tags.images) {
            if (!image || typeof image !== 'object') {
                throw new TypeError('Each image in tags.images must be an object.');
            }
            if (!(image.data instanceof Uint8Array)) {
                throw new TypeError('Each image.data must be a Uint8Array.');
            }
            if (typeof image.mimeType !== 'string') {
                throw new TypeError('Each image.mimeType must be a string.');
            }
            if (!['coverFront', 'coverBack', 'unknown'].includes(image.kind)) {
                throw new TypeError('Each image.kind must be \'coverFront\', \'coverBack\', or \'unknown\'.');
            }
        }
    }
    if (tags.comment !== undefined && typeof tags.comment !== 'string') {
        throw new TypeError('tags.comment, when provided, must be a string.');
    }
    if (tags.raw !== undefined) {
        if (!tags.raw || typeof tags.raw !== 'object') {
            throw new TypeError('tags.raw, when provided, must be an object.');
        }
        for (const value of Object.values(tags.raw)) {
            if (value !== null
                && typeof value !== 'string'
                && !(value instanceof Uint8Array)
                && !(value instanceof RichImageData)
                && !(value instanceof AttachedFile)) {
                throw new TypeError('Each value in tags.raw must be a string, Uint8Array, RichImageData, AttachedFile, or null.');
            }
        }
    }
};
const metadataTagsAreEmpty = (tags) => {
    return tags.title === undefined
        && tags.description === undefined
        && tags.artist === undefined
        && tags.album === undefined
        && tags.albumArtist === undefined
        && tags.trackNumber === undefined
        && tags.tracksTotal === undefined
        && tags.discNumber === undefined
        && tags.discsTotal === undefined
        && tags.genre === undefined
        && tags.date === undefined
        && tags.lyrics === undefined
        && (!tags.images || tags.images.length === 0)
        && tags.comment === undefined
        && (tags.raw === undefined || Object.keys(tags.raw).length === 0);
};
const DEFAULT_TRACK_DISPOSITION = {
    default: true,
    forced: false,
    original: false,
    commentary: false,
    hearingImpaired: false,
    visuallyImpaired: false,
};
const validateTrackDisposition = (disposition) => {
    if (!disposition || typeof disposition !== 'object') {
        throw new TypeError('disposition must be an object.');
    }
    if (disposition.default !== undefined && typeof disposition.default !== 'boolean') {
        throw new TypeError('disposition.default must be a boolean.');
    }
    if (disposition.forced !== undefined && typeof disposition.forced !== 'boolean') {
        throw new TypeError('disposition.forced must be a boolean.');
    }
    if (disposition.original !== undefined && typeof disposition.original !== 'boolean') {
        throw new TypeError('disposition.original must be a boolean.');
    }
    if (disposition.commentary !== undefined && typeof disposition.commentary !== 'boolean') {
        throw new TypeError('disposition.commentary must be a boolean.');
    }
    if (disposition.hearingImpaired !== undefined && typeof disposition.hearingImpaired !== 'boolean') {
        throw new TypeError('disposition.hearingImpaired must be a boolean.');
    }
    if (disposition.visuallyImpaired !== undefined && typeof disposition.visuallyImpaired !== 'boolean') {
        throw new TypeError('disposition.visuallyImpaired must be a boolean.');
    }
};


/***/ },

/***/ 3912
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Au: () => (/* binding */ MATRIX_COEFFICIENTS_MAP),
/* harmony export */   BL: () => (/* binding */ COLOR_PRIMARIES_MAP_INVERSE),
/* harmony export */   Br: () => (/* binding */ bytesToHexString),
/* harmony export */   D5: () => (/* binding */ validateAnyIterable),
/* harmony export */   Et: () => (/* binding */ isNumber),
/* harmony export */   F2: () => (/* binding */ isChromium),
/* harmony export */   Fo: () => (/* binding */ toUint8Array),
/* harmony export */   G8: () => (/* binding */ retriedFetch),
/* harmony export */   H9: () => (/* binding */ isIso88591Compatible),
/* harmony export */   HV: () => (/* binding */ colorSpaceIsComplete),
/* harmony export */   IP: () => (/* binding */ readExpGolomb),
/* harmony export */   IR: () => (/* binding */ UNDETERMINED_LANGUAGE),
/* harmony export */   Kl: () => (/* binding */ findLastIndex),
/* harmony export */   Kp: () => (/* binding */ base64ToBytes),
/* harmony export */   MW: () => (/* binding */ SECOND_TO_MICROSECOND_FACTOR),
/* harmony export */   Nu: () => (/* binding */ isIso639Dash2LanguageCode),
/* harmony export */   OO: () => (/* binding */ readSignedExpGolomb),
/* harmony export */   P5: () => (/* binding */ reverseBitsU32),
/* harmony export */   Q5: () => (/* binding */ floorToMultiple),
/* harmony export */   SM: () => (/* binding */ isAllowSharedBufferSource),
/* harmony export */   Sf: () => (/* binding */ coalesceIndex),
/* harmony export */   Tc: () => (/* binding */ isWebKit),
/* harmony export */   UG: () => (/* binding */ textEncoder),
/* harmony export */   Uk: () => (/* binding */ findLast),
/* harmony export */   Wh: () => (/* binding */ getInt24),
/* harmony export */   Wo: () => (/* binding */ writeBits),
/* harmony export */   XQ: () => (/* binding */ polyfillSymbolDispose),
/* harmony export */   Zc: () => (/* binding */ toDataView),
/* harmony export */   _c: () => (/* binding */ Bitstream),
/* harmony export */   _g: () => (/* binding */ last),
/* harmony export */   _h: () => (/* binding */ mergeRequestInit),
/* harmony export */   _j: () => (/* binding */ setInt64),
/* harmony export */   aD: () => (/* binding */ AsyncMutex),
/* harmony export */   aI: () => (/* binding */ roundIfAlmostInteger),
/* harmony export */   al: () => (/* binding */ ilog),
/* harmony export */   b_: () => (/* binding */ computeRationalApproximation),
/* harmony export */   dY: () => (/* binding */ CallSerializer),
/* harmony export */   dq: () => (/* binding */ getUint24),
/* harmony export */   eE: () => (/* binding */ binarySearchLessOrEqual),
/* harmony export */   fl: () => (/* binding */ MATRIX_COEFFICIENTS_MAP_INVERSE),
/* harmony export */   gm: () => (/* binding */ isFirefox),
/* harmony export */   h8: () => (/* binding */ insertSorted),
/* harmony export */   i1: () => (/* binding */ toAsyncIterator),
/* harmony export */   iP: () => (/* binding */ setInt24),
/* harmony export */   "if": () => (/* binding */ bytesToBase64),
/* harmony export */   "in": () => (/* binding */ roundToMultiple),
/* harmony export */   jD: () => (/* binding */ setUint24),
/* harmony export */   ju: () => (/* binding */ uint8ArraysAreEqual),
/* harmony export */   nJ: () => (/* binding */ promiseWithResolvers),
/* harmony export */   oX: () => (/* binding */ closedIntervalsOverlap),
/* harmony export */   pl: () => (/* binding */ binarySearchExact),
/* harmony export */   qE: () => (/* binding */ clamp),
/* harmony export */   qT: () => (/* binding */ normalizeRotation),
/* harmony export */   rk: () => (/* binding */ keyValueIterator),
/* harmony export */   sX: () => (/* binding */ imageMimeTypeToExtension),
/* harmony export */   su: () => (/* binding */ textDecoder),
/* harmony export */   uN: () => (/* binding */ TRANSFER_CHARACTERISTICS_MAP),
/* harmony export */   vA: () => (/* binding */ assert),
/* harmony export */   vv: () => (/* binding */ isU32),
/* harmony export */   wd: () => (/* binding */ COLOR_PRIMARIES_MAP),
/* harmony export */   x_: () => (/* binding */ TRANSFER_CHARACTERISTICS_MAP_INVERSE),
/* harmony export */   xb: () => (/* binding */ assertNever),
/* harmony export */   zp: () => (/* binding */ getChromiumVersion)
/* harmony export */ });
/* unused harmony exports removeItem, mapAsyncGenerator */
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */
function assert(x) {
    if (!x) {
        throw new Error('Assertion failed.');
    }
}
const normalizeRotation = (rotation) => {
    const mappedRotation = (rotation % 360 + 360) % 360;
    if (mappedRotation === 0 || mappedRotation === 90 || mappedRotation === 180 || mappedRotation === 270) {
        return mappedRotation;
    }
    else {
        throw new Error(`Invalid rotation ${rotation}.`);
    }
};
const last = (arr) => {
    return arr && arr[arr.length - 1];
};
const isU32 = (value) => {
    return value >= 0 && value < 2 ** 32;
};
class Bitstream {
    constructor(bytes) {
        this.bytes = bytes;
        /** Current offset in bits. */
        this.pos = 0;
    }
    seekToByte(byteOffset) {
        this.pos = 8 * byteOffset;
    }
    readBit() {
        const byteIndex = Math.floor(this.pos / 8);
        const byte = this.bytes[byteIndex] ?? 0;
        const bitIndex = 0b111 - (this.pos & 0b111);
        const bit = (byte & (1 << bitIndex)) >> bitIndex;
        this.pos++;
        return bit;
    }
    readBits(n) {
        if (n === 1) {
            return this.readBit();
        }
        let result = 0;
        for (let i = 0; i < n; i++) {
            result <<= 1;
            result |= this.readBit();
        }
        return result;
    }
    writeBits(n, value) {
        const end = this.pos + n;
        for (let i = this.pos; i < end; i++) {
            const byteIndex = Math.floor(i / 8);
            let byte = this.bytes[byteIndex];
            const bitIndex = 0b111 - (i & 0b111);
            byte &= ~(1 << bitIndex);
            byte |= ((value & (1 << (end - i - 1))) >> (end - i - 1)) << bitIndex;
            this.bytes[byteIndex] = byte;
        }
        this.pos = end;
    }
    ;
    readAlignedByte() {
        // Ensure we're byte-aligned
        if (this.pos % 8 !== 0) {
            throw new Error('Bitstream is not byte-aligned.');
        }
        const byteIndex = this.pos / 8;
        const byte = this.bytes[byteIndex] ?? 0;
        this.pos += 8;
        return byte;
    }
    skipBits(n) {
        this.pos += n;
    }
    getBitsLeft() {
        return this.bytes.length * 8 - this.pos;
    }
    clone() {
        const clone = new Bitstream(this.bytes);
        clone.pos = this.pos;
        return clone;
    }
}
/** Reads an exponential-Golomb universal code from a Bitstream.  */
const readExpGolomb = (bitstream) => {
    let leadingZeroBits = 0;
    while (bitstream.readBits(1) === 0 && leadingZeroBits < 32) {
        leadingZeroBits++;
    }
    if (leadingZeroBits >= 32) {
        throw new Error('Invalid exponential-Golomb code.');
    }
    const result = (1 << leadingZeroBits) - 1 + bitstream.readBits(leadingZeroBits);
    return result;
};
/** Reads a signed exponential-Golomb universal code from a Bitstream. */
const readSignedExpGolomb = (bitstream) => {
    const codeNum = readExpGolomb(bitstream);
    return ((codeNum & 1) === 0)
        ? -(codeNum >> 1)
        : ((codeNum + 1) >> 1);
};
const writeBits = (bytes, start, end, value) => {
    for (let i = start; i < end; i++) {
        const byteIndex = Math.floor(i / 8);
        let byte = bytes[byteIndex];
        const bitIndex = 0b111 - (i & 0b111);
        byte &= ~(1 << bitIndex);
        byte |= ((value & (1 << (end - i - 1))) >> (end - i - 1)) << bitIndex;
        bytes[byteIndex] = byte;
    }
};
const toUint8Array = (source) => {
    if (source.constructor === Uint8Array) { // We want a true Uint8Array, not something that extends it like Buffer
        return source;
    }
    else if (ArrayBuffer.isView(source)) {
        return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
    }
    else {
        return new Uint8Array(source);
    }
};
const toDataView = (source) => {
    if (source.constructor === DataView) {
        return source;
    }
    else if (ArrayBuffer.isView(source)) {
        return new DataView(source.buffer, source.byteOffset, source.byteLength);
    }
    else {
        return new DataView(source);
    }
};
const textDecoder = /* #__PURE__ */ new TextDecoder();
const textEncoder = /* #__PURE__ */ new TextEncoder();
const isIso88591Compatible = (text) => {
    for (let i = 0; i < text.length; i++) {
        const code = text.charCodeAt(i);
        if (code > 255) {
            return false;
        }
    }
    return true;
};
const invertObject = (object) => {
    return Object.fromEntries(Object.entries(object).map(([key, value]) => [value, key]));
};
// For the color space mappings, see Rec. ITU-T H.273.
const COLOR_PRIMARIES_MAP = {
    bt709: 1, // ITU-R BT.709
    bt470bg: 5, // ITU-R BT.470BG
    smpte170m: 6, // ITU-R BT.601 525 - SMPTE 170M
    bt2020: 9, // ITU-R BT.202
    smpte432: 12, // SMPTE EG 432-1
};
const COLOR_PRIMARIES_MAP_INVERSE = /* #__PURE__ */ invertObject(COLOR_PRIMARIES_MAP);
const TRANSFER_CHARACTERISTICS_MAP = {
    'bt709': 1, // ITU-R BT.709
    'smpte170m': 6, // SMPTE 170M
    'linear': 8, // Linear transfer characteristics
    'iec61966-2-1': 13, // IEC 61966-2-1
    'pq': 16, // Rec. ITU-R BT.2100-2 perceptual quantization (PQ) system
    'hlg': 18, // Rec. ITU-R BT.2100-2 hybrid loggamma (HLG) system
};
const TRANSFER_CHARACTERISTICS_MAP_INVERSE = /* #__PURE__ */ invertObject(TRANSFER_CHARACTERISTICS_MAP);
const MATRIX_COEFFICIENTS_MAP = {
    'rgb': 0, // Identity
    'bt709': 1, // ITU-R BT.709
    'bt470bg': 5, // ITU-R BT.470BG
    'smpte170m': 6, // SMPTE 170M
    'bt2020-ncl': 9, // ITU-R BT.2020-2 (non-constant luminance)
};
const MATRIX_COEFFICIENTS_MAP_INVERSE = /* #__PURE__ */ invertObject(MATRIX_COEFFICIENTS_MAP);
const colorSpaceIsComplete = (colorSpace) => {
    return (!!colorSpace
        && !!colorSpace.primaries
        && !!colorSpace.transfer
        && !!colorSpace.matrix
        && colorSpace.fullRange !== undefined);
};
const isAllowSharedBufferSource = (x) => {
    return (x instanceof ArrayBuffer
        || (typeof SharedArrayBuffer !== 'undefined' && x instanceof SharedArrayBuffer)
        || ArrayBuffer.isView(x));
};
class AsyncMutex {
    constructor() {
        this.currentPromise = Promise.resolve();
        this.pending = 0;
    }
    async acquire() {
        let resolver;
        const nextPromise = new Promise((resolve) => {
            let resolved = false;
            resolver = () => {
                if (resolved) {
                    return;
                }
                resolve();
                this.pending--;
                resolved = true;
            };
        });
        const currentPromiseAlias = this.currentPromise;
        this.currentPromise = nextPromise;
        this.pending++;
        await currentPromiseAlias;
        return resolver;
    }
}
const bytesToHexString = (bytes) => {
    return [...bytes].map(x => x.toString(16).padStart(2, '0')).join('');
};
const reverseBitsU32 = (x) => {
    x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);
    x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
    x = ((x >> 4) & 0x0f0f0f0f) | ((x & 0x0f0f0f0f) << 4);
    x = ((x >> 8) & 0x00ff00ff) | ((x & 0x00ff00ff) << 8);
    x = ((x >> 16) & 0x0000ffff) | ((x & 0x0000ffff) << 16);
    return x >>> 0; // Ensure it's treated as an unsigned 32-bit integer
};
/** Returns the smallest index i such that val[i] === key, or -1 if no such index exists. */
const binarySearchExact = (arr, key, valueGetter) => {
    let low = 0;
    let high = arr.length - 1;
    let ans = -1;
    while (low <= high) {
        const mid = (low + high) >> 1;
        const midVal = valueGetter(arr[mid]);
        if (midVal === key) {
            ans = mid;
            high = mid - 1; // Continue searching left to find the lowest index
        }
        else if (midVal < key) {
            low = mid + 1;
        }
        else {
            high = mid - 1;
        }
    }
    return ans;
};
/** Returns the largest index i such that val[i] <= key, or -1 if no such index exists. */
const binarySearchLessOrEqual = (arr, key, valueGetter) => {
    let low = 0;
    let high = arr.length - 1;
    let ans = -1;
    while (low <= high) {
        const mid = (low + (high - low + 1) / 2) | 0;
        const midVal = valueGetter(arr[mid]);
        if (midVal <= key) {
            ans = mid;
            low = mid + 1;
        }
        else {
            high = mid - 1;
        }
    }
    return ans;
};
/** Assumes the array is already sorted. */
const insertSorted = (arr, item, valueGetter) => {
    const insertionIndex = binarySearchLessOrEqual(arr, valueGetter(item), valueGetter);
    arr.splice(insertionIndex + 1, 0, item); // This even behaves correctly for the -1 case
};
const promiseWithResolvers = () => {
    let resolve;
    let reject;
    const promise = new Promise((res, rej) => {
        resolve = res;
        reject = rej;
    });
    return { promise, resolve: resolve, reject: reject };
};
const removeItem = (arr, item) => {
    const index = arr.indexOf(item);
    if (index !== -1) {
        arr.splice(index, 1);
    }
};
const findLast = (arr, predicate) => {
    for (let i = arr.length - 1; i >= 0; i--) {
        if (predicate(arr[i])) {
            return arr[i];
        }
    }
    return undefined;
};
const findLastIndex = (arr, predicate) => {
    for (let i = arr.length - 1; i >= 0; i--) {
        if (predicate(arr[i])) {
            return i;
        }
    }
    return -1;
};
const toAsyncIterator = async function* (source) {
    if (Symbol.iterator in source) {
        // @ts-expect-error Trust me
        yield* source[Symbol.iterator]();
    }
    else {
        // @ts-expect-error Trust me
        yield* source[Symbol.asyncIterator]();
    }
};
const validateAnyIterable = (iterable) => {
    if (!(Symbol.iterator in iterable) && !(Symbol.asyncIterator in iterable)) {
        throw new TypeError('Argument must be an iterable or async iterable.');
    }
};
const assertNever = (x) => {
    // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
    throw new Error(`Unexpected value: ${x}`);
};
const getUint24 = (view, byteOffset, littleEndian) => {
    const byte1 = view.getUint8(byteOffset);
    const byte2 = view.getUint8(byteOffset + 1);
    const byte3 = view.getUint8(byteOffset + 2);
    if (littleEndian) {
        return byte1 | (byte2 << 8) | (byte3 << 16);
    }
    else {
        return (byte1 << 16) | (byte2 << 8) | byte3;
    }
};
const getInt24 = (view, byteOffset, littleEndian) => {
    // The left shift pushes the most significant bit into the sign bit region, and the subsequent right shift
    // then correctly interprets the sign bit.
    return getUint24(view, byteOffset, littleEndian) << 8 >> 8;
};
const setUint24 = (view, byteOffset, value, littleEndian) => {
    // Ensure the value is within 24-bit unsigned range (0 to 16777215)
    value = value >>> 0; // Convert to unsigned 32-bit
    value = value & 0xFFFFFF; // Mask to 24 bits
    if (littleEndian) {
        view.setUint8(byteOffset, value & 0xFF);
        view.setUint8(byteOffset + 1, (value >>> 8) & 0xFF);
        view.setUint8(byteOffset + 2, (value >>> 16) & 0xFF);
    }
    else {
        view.setUint8(byteOffset, (value >>> 16) & 0xFF);
        view.setUint8(byteOffset + 1, (value >>> 8) & 0xFF);
        view.setUint8(byteOffset + 2, value & 0xFF);
    }
};
const setInt24 = (view, byteOffset, value, littleEndian) => {
    // Ensure the value is within 24-bit signed range (-8388608 to 8388607)
    value = clamp(value, -8388608, 8388607);
    // Convert negative values to their 24-bit representation
    if (value < 0) {
        value = (value + 0x1000000) & 0xFFFFFF;
    }
    setUint24(view, byteOffset, value, littleEndian);
};
const setInt64 = (view, byteOffset, value, littleEndian) => {
    if (littleEndian) {
        view.setUint32(byteOffset + 0, value, true);
        view.setInt32(byteOffset + 4, Math.floor(value / 2 ** 32), true);
    }
    else {
        view.setInt32(byteOffset + 0, Math.floor(value / 2 ** 32), true);
        view.setUint32(byteOffset + 4, value, true);
    }
};
/**
 * Calls a function on each value spat out by an async generator. The reason for writing this manually instead of
 * using a generator function is that the generator function queues return() calls - here, we forward them immediately.
 */
const mapAsyncGenerator = (generator, map) => {
    return {
        async next() {
            const result = await generator.next();
            if (result.done) {
                return { value: undefined, done: true };
            }
            else {
                return { value: map(result.value), done: false };
            }
        },
        return() {
            return generator.return();
        },
        throw(error) {
            return generator.throw(error);
        },
        [Symbol.asyncIterator]() {
            return this;
        },
    };
};
const clamp = (value, min, max) => {
    return Math.max(min, Math.min(max, value));
};
const UNDETERMINED_LANGUAGE = 'und';
const roundIfAlmostInteger = (value) => {
    const rounded = Math.round(value);
    if (Math.abs(value / rounded - 1) < 10 * Number.EPSILON) {
        return rounded;
    }
    else {
        return value;
    }
};
const roundToMultiple = (value, multiple) => {
    return Math.round(value / multiple) * multiple;
};
const floorToMultiple = (value, multiple) => {
    return Math.floor(value / multiple) * multiple;
};
const ilog = (x) => {
    let ret = 0;
    while (x) {
        ret++;
        x >>= 1;
    }
    return ret;
};
const ISO_639_2_REGEX = /^[a-z]{3}$/;
const isIso639Dash2LanguageCode = (x) => {
    return ISO_639_2_REGEX.test(x);
};
// Since the result will be truncated, add a bit of eps to compensate for floating point errors
const SECOND_TO_MICROSECOND_FACTOR = 1e6 * (1 + Number.EPSILON);
/**
 * Merges two RequestInit objects with special handling for headers.
 * Headers are merged case-insensitively, but original casing is preserved.
 * init2 headers take precedence and will override case-insensitive matches from init1.
 */
const mergeRequestInit = (init1, init2) => {
    const merged = { ...init1, ...init2 };
    // Special handling for headers
    if (init1.headers || init2.headers) {
        const headers1 = init1.headers ? normalizeHeaders(init1.headers) : {};
        const headers2 = init2.headers ? normalizeHeaders(init2.headers) : {};
        const mergedHeaders = { ...headers1 };
        // For each header in headers2, check if a case-insensitive match exists in mergedHeaders
        Object.entries(headers2).forEach(([key2, value2]) => {
            const existingKey = Object.keys(mergedHeaders).find(key1 => key1.toLowerCase() === key2.toLowerCase());
            if (existingKey) {
                delete mergedHeaders[existingKey];
            }
            mergedHeaders[key2] = value2;
        });
        merged.headers = mergedHeaders;
    }
    return merged;
};
/** Normalizes HeadersInit to a Record<string, string> format. */
const normalizeHeaders = (headers) => {
    if (headers instanceof Headers) {
        const result = {};
        headers.forEach((value, key) => {
            result[key] = value;
        });
        return result;
    }
    if (Array.isArray(headers)) {
        const result = {};
        headers.forEach(([key, value]) => {
            result[key] = value;
        });
        return result;
    }
    return headers;
};
const retriedFetch = async (fetchFn, url, requestInit, getRetryDelay, shouldStop) => {
    let attempts = 0;
    while (true) {
        try {
            return await fetchFn(url, requestInit);
        }
        catch (error) {
            if (shouldStop()) {
                throw error;
            }
            attempts++;
            const retryDelayInSeconds = getRetryDelay(attempts, error, url);
            if (retryDelayInSeconds === null) {
                throw error;
            }
            console.error('Retrying failed fetch. Error:', error);
            if (!Number.isFinite(retryDelayInSeconds) || retryDelayInSeconds < 0) {
                throw new TypeError('Retry delay must be a non-negative finite number.');
            }
            if (retryDelayInSeconds > 0) {
                await new Promise(resolve => setTimeout(resolve, 1000 * retryDelayInSeconds));
            }
            if (shouldStop()) {
                throw error;
            }
        }
    }
};
const computeRationalApproximation = (x, maxDenominator) => {
    // Handle negative numbers
    const sign = x < 0 ? -1 : 1;
    x = Math.abs(x);
    let prevNumerator = 0, prevDenominator = 1;
    let currNumerator = 1, currDenominator = 0;
    // Continued fraction algorithm
    let remainder = x;
    while (true) {
        const integer = Math.floor(remainder);
        // Calculate next convergent
        const nextNumerator = integer * currNumerator + prevNumerator;
        const nextDenominator = integer * currDenominator + prevDenominator;
        if (nextDenominator > maxDenominator) {
            return {
                numerator: sign * currNumerator,
                denominator: currDenominator,
            };
        }
        prevNumerator = currNumerator;
        prevDenominator = currDenominator;
        currNumerator = nextNumerator;
        currDenominator = nextDenominator;
        remainder = 1 / (remainder - integer);
        // Guard against precision issues
        if (!isFinite(remainder)) {
            break;
        }
    }
    return {
        numerator: sign * currNumerator,
        denominator: currDenominator,
    };
};
class CallSerializer {
    constructor() {
        this.currentPromise = Promise.resolve();
    }
    call(fn) {
        return this.currentPromise = this.currentPromise.then(fn);
    }
}
let isWebKitCache = null;
const isWebKit = () => {
    if (isWebKitCache !== null) {
        return isWebKitCache;
    }
    // This even returns true for WebKit-wrapping browsers such as Chrome on iOS
    return isWebKitCache = !!(typeof navigator !== 'undefined'
        && (navigator.vendor?.match(/apple/i)
            // Or, in workers:
            || (/AppleWebKit/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent))
            || /\b(iPad|iPhone|iPod)\b/.test(navigator.userAgent)));
};
let isFirefoxCache = null;
const isFirefox = () => {
    if (isFirefoxCache !== null) {
        return isFirefoxCache;
    }
    return isFirefoxCache = typeof navigator !== 'undefined' && navigator.userAgent?.includes('Firefox');
};
let isChromiumCache = null;
const isChromium = () => {
    if (isChromiumCache !== null) {
        return isChromiumCache;
    }
    return isChromiumCache = !!(typeof navigator !== 'undefined'
        && (navigator.vendor?.includes('Google Inc') || /Chrome/.test(navigator.userAgent)));
};
let chromiumVersionCache = null;
const getChromiumVersion = () => {
    if (chromiumVersionCache !== null) {
        return chromiumVersionCache;
    }
    if (typeof navigator === 'undefined') {
        return null;
    }
    const match = /\bChrome\/(\d+)/.exec(navigator.userAgent);
    if (!match) {
        return null;
    }
    return chromiumVersionCache = Number(match[1]);
};
/** Acts like `??` except the condition is -1 and not null/undefined. */
const coalesceIndex = (a, b) => {
    return a !== -1 ? a : b;
};
const closedIntervalsOverlap = (startA, endA, startB, endB) => {
    return startA <= endB && startB <= endA;
};
const keyValueIterator = function* (object) {
    for (const key in object) {
        const value = object[key];
        if (value === undefined) {
            continue;
        }
        yield { key, value };
    }
};
const imageMimeTypeToExtension = (mimeType) => {
    switch (mimeType.toLowerCase()) {
        case 'image/jpeg':
        case 'image/jpg':
            return '.jpg';
        case 'image/png':
            return '.png';
        case 'image/gif':
            return '.gif';
        case 'image/webp':
            return '.webp';
        case 'image/bmp':
            return '.bmp';
        case 'image/svg+xml':
            return '.svg';
        case 'image/tiff':
            return '.tiff';
        case 'image/avif':
            return '.avif';
        case 'image/x-icon':
        case 'image/vnd.microsoft.icon':
            return '.ico';
        default:
            return null;
    }
};
const base64ToBytes = (base64) => {
    const decoded = atob(base64);
    const bytes = new Uint8Array(decoded.length);
    for (let i = 0; i < decoded.length; i++) {
        bytes[i] = decoded.charCodeAt(i);
    }
    return bytes;
};
const bytesToBase64 = (bytes) => {
    let string = '';
    for (let i = 0; i < bytes.length; i++) {
        string += String.fromCharCode(bytes[i]);
    }
    return btoa(string);
};
const uint8ArraysAreEqual = (a, b) => {
    if (a.length !== b.length) {
        return false;
    }
    for (let i = 0; i < a.length; i++) {
        if (a[i] !== b[i]) {
            return false;
        }
    }
    return true;
};
const polyfillSymbolDispose = () => {
    // https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-2.html
    // @ts-expect-error Readonly
    Symbol.dispose ??= Symbol('Symbol.dispose');
};
const isNumber = (x) => {
    return typeof x === 'number' && !Number.isNaN(x);
};


/***/ },

/***/ 2490
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Vx: () => (/* binding */ buildMpegTsMimeType),
/* harmony export */   ZT: () => (/* binding */ TS_PACKET_SIZE),
/* harmony export */   cS: () => (/* binding */ TIMESCALE)
/* harmony export */ });
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */
const TIMESCALE = 90_000; // MPEG-TS timestamps run on a 90 kHz clock
const TS_PACKET_SIZE = 188;
const buildMpegTsMimeType = (codecStrings) => {
    let string = 'video/MP2T';
    const uniqueCodecStrings = [...new Set(codecStrings.filter(Boolean))];
    if (uniqueCodecStrings.length > 0) {
        string += `; codecs="${uniqueCodecStrings.join(', ')}"`;
    }
    return string;
};


/***/ },

/***/ 9730
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Ob: () => (/* binding */ buildOggMimeType),
/* harmony export */   Zk: () => (/* binding */ OGGS),
/* harmony export */   _S: () => (/* binding */ computeOggPageCrc),
/* harmony export */   nL: () => (/* binding */ extractSampleMetadata)
/* harmony export */ });
/* harmony import */ var _codec_data_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6297);
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3912);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */


const OGGS = 0x5367674f; // 'OggS'
const OGG_CRC_POLYNOMIAL = 0x04c11db7;
const OGG_CRC_TABLE = new Uint32Array(256);
for (let n = 0; n < 256; n++) {
    let crc = n << 24;
    for (let k = 0; k < 8; k++) {
        crc = (crc & 0x80000000)
            ? ((crc << 1) ^ OGG_CRC_POLYNOMIAL)
            : (crc << 1);
    }
    OGG_CRC_TABLE[n] = (crc >>> 0) & 0xffffffff;
}
const computeOggPageCrc = (bytes) => {
    const view = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .toDataView */ .Zc)(bytes);
    const originalChecksum = view.getUint32(22, true);
    view.setUint32(22, 0, true); // Zero out checksum field
    let crc = 0;
    for (let i = 0; i < bytes.length; i++) {
        const byte = bytes[i];
        crc = ((crc << 8) ^ OGG_CRC_TABLE[(crc >>> 24) ^ byte]) >>> 0;
    }
    view.setUint32(22, originalChecksum, true); // Restore checksum field
    return crc;
};
const extractSampleMetadata = (data, codecInfo, vorbisLastBlocksize) => {
    let durationInSamples = 0;
    let currentBlocksize = null;
    if (data.length > 0) {
        // To know sample duration, we'll need to peak inside the packet
        if (codecInfo.codec === 'vorbis') {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assert */ .vA)(codecInfo.vorbisInfo);
            const vorbisModeCount = codecInfo.vorbisInfo.modeBlockflags.length;
            const bitCount = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .ilog */ .al)(vorbisModeCount - 1);
            const modeMask = ((1 << bitCount) - 1) << 1;
            const modeNumber = (data[0] & modeMask) >> 1;
            if (modeNumber >= codecInfo.vorbisInfo.modeBlockflags.length) {
                throw new Error('Invalid mode number.');
            }
            // In Vorbis, packet duration also depends on the blocksize of the previous packet
            let prevBlocksize = vorbisLastBlocksize;
            const blockflag = codecInfo.vorbisInfo.modeBlockflags[modeNumber];
            currentBlocksize = codecInfo.vorbisInfo.blocksizes[blockflag];
            if (blockflag === 1) {
                const prevMask = (modeMask | 0x1) + 1;
                const flag = data[0] & prevMask ? 1 : 0;
                prevBlocksize = codecInfo.vorbisInfo.blocksizes[flag];
            }
            durationInSamples = prevBlocksize !== null
                ? (prevBlocksize + currentBlocksize) >> 2
                : 0; // The first sample outputs no audio data and therefore has a duration of 0
        }
        else if (codecInfo.codec === 'opus') {
            const toc = (0,_codec_data_js__WEBPACK_IMPORTED_MODULE_0__/* .parseOpusTocByte */ .ls)(data);
            durationInSamples = toc.durationInSamples;
        }
    }
    return {
        durationInSamples,
        vorbisBlockSize: currentBlocksize,
    };
};
const buildOggMimeType = (info) => {
    let string = 'audio/ogg';
    if (info.codecStrings) {
        const uniqueCodecMimeTypes = [...new Set(info.codecStrings)];
        string += `; codecs="${uniqueCodecMimeTypes.join(', ')}"`;
    }
    return string;
};


/***/ },

/***/ 9841
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   BF: () => (/* binding */ readPageHeader),
/* harmony export */   H4: () => (/* binding */ MAX_PAGE_SIZE),
/* harmony export */   H9: () => (/* binding */ MAX_PAGE_HEADER_SIZE),
/* harmony export */   b0: () => (/* binding */ MIN_PAGE_HEADER_SIZE),
/* harmony export */   v5: () => (/* binding */ findNextPageHeader)
/* harmony export */ });
/* harmony import */ var _reader_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7735);
/* harmony import */ var _ogg_misc_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9730);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */


const MIN_PAGE_HEADER_SIZE = 27;
const MAX_PAGE_HEADER_SIZE = 27 + 255;
const MAX_PAGE_SIZE = MAX_PAGE_HEADER_SIZE + 255 * 255;
const readPageHeader = (slice) => {
    const startPos = slice.filePos;
    const capturePattern = (0,_reader_js__WEBPACK_IMPORTED_MODULE_0__/* .readU32Le */ .aJ)(slice);
    if (capturePattern !== _ogg_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .OGGS */ .Zk) {
        return null;
    }
    slice.skip(1); // Version
    const headerType = (0,_reader_js__WEBPACK_IMPORTED_MODULE_0__/* .readU8 */ .eo)(slice);
    const granulePosition = (0,_reader_js__WEBPACK_IMPORTED_MODULE_0__/* .readI64Le */ .TH)(slice);
    const serialNumber = (0,_reader_js__WEBPACK_IMPORTED_MODULE_0__/* .readU32Le */ .aJ)(slice);
    const sequenceNumber = (0,_reader_js__WEBPACK_IMPORTED_MODULE_0__/* .readU32Le */ .aJ)(slice);
    const checksum = (0,_reader_js__WEBPACK_IMPORTED_MODULE_0__/* .readU32Le */ .aJ)(slice);
    const numberPageSegments = (0,_reader_js__WEBPACK_IMPORTED_MODULE_0__/* .readU8 */ .eo)(slice);
    const lacingValues = new Uint8Array(numberPageSegments);
    for (let i = 0; i < numberPageSegments; i++) {
        lacingValues[i] = (0,_reader_js__WEBPACK_IMPORTED_MODULE_0__/* .readU8 */ .eo)(slice);
    }
    const headerSize = 27 + numberPageSegments;
    const dataSize = lacingValues.reduce((a, b) => a + b, 0);
    const totalSize = headerSize + dataSize;
    return {
        headerStartPos: startPos,
        totalSize,
        dataStartPos: startPos + headerSize,
        dataSize,
        headerType,
        granulePosition,
        serialNumber,
        sequenceNumber,
        checksum,
        lacingValues,
    };
};
const findNextPageHeader = (slice, until) => {
    while (slice.filePos < until - (4 - 1)) { // Size of word minus 1
        const word = (0,_reader_js__WEBPACK_IMPORTED_MODULE_0__/* .readU32Le */ .aJ)(slice);
        const firstByte = word & 0xff;
        const secondByte = (word >>> 8) & 0xff;
        const thirdByte = (word >>> 16) & 0xff;
        const fourthByte = (word >>> 24) & 0xff;
        const O = 0x4f; // 'O'
        if (firstByte !== O && secondByte !== O && thirdByte !== O && fourthByte !== O) {
            continue;
        }
        slice.skip(-4);
        if (word === _ogg_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .OGGS */ .Zk) {
            // We have found the capture pattern
            return true;
        }
        slice.skip(1);
    }
    return false;
};


/***/ },

/***/ 3936
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   T: () => (/* binding */ PLACEHOLDER_DATA),
/* harmony export */   Z: () => (/* binding */ EncodedPacket)
/* harmony export */ });
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3912);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

const PLACEHOLDER_DATA = /* #__PURE__ */ new Uint8Array(0);
/**
 * Represents an encoded chunk of media. Mainly used as an expressive wrapper around WebCodecs API's
 * [`EncodedVideoChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) and
 * [`EncodedAudioChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedAudioChunk), but can also be used
 * standalone.
 * @group Packets
 * @public
 */
class EncodedPacket {
    /** Creates a new {@link EncodedPacket} from raw bytes and timing information. */
    constructor(
    /**
     * The encoded data of this packet. For any given codec, this data must adhere to the format specified in the
     * Mediabunny Codec Registry.
     */
    data, 
    /** The type of this packet. */
    type, 
    /**
     * The presentation timestamp of this packet in seconds. May be negative. Samples with negative end timestamps
     * should not be presented.
     */
    timestamp, 
    /** The duration of this packet in seconds. */
    duration, 
    /**
     * The sequence number indicates the decode order of the packets. Packet A  must be decoded before packet B if A
     * has a lower sequence number than B. If two packets have the same sequence number, they are the same packet.
     * Otherwise, sequence numbers are arbitrary and are not guaranteed to have any meaning besides their relative
     * ordering. Negative sequence numbers mean the sequence number is undefined.
     */
    sequenceNumber = -1, byteLength, sideData) {
        this.data = data;
        this.type = type;
        this.timestamp = timestamp;
        this.duration = duration;
        this.sequenceNumber = sequenceNumber;
        if (data === PLACEHOLDER_DATA && byteLength === undefined) {
            throw new Error('Internal error: byteLength must be explicitly provided when constructing metadata-only packets.');
        }
        if (byteLength === undefined) {
            byteLength = data.byteLength;
        }
        if (!(data instanceof Uint8Array)) {
            throw new TypeError('data must be a Uint8Array.');
        }
        if (type !== 'key' && type !== 'delta') {
            throw new TypeError('type must be either "key" or "delta".');
        }
        if (!Number.isFinite(timestamp)) {
            throw new TypeError('timestamp must be a number.');
        }
        if (!Number.isFinite(duration) || duration < 0) {
            throw new TypeError('duration must be a non-negative number.');
        }
        if (!Number.isFinite(sequenceNumber)) {
            throw new TypeError('sequenceNumber must be a number.');
        }
        if (!Number.isInteger(byteLength) || byteLength < 0) {
            throw new TypeError('byteLength must be a non-negative integer.');
        }
        if (sideData !== undefined && (typeof sideData !== 'object' || !sideData)) {
            throw new TypeError('sideData, when provided, must be an object.');
        }
        if (sideData?.alpha !== undefined && !(sideData.alpha instanceof Uint8Array)) {
            throw new TypeError('sideData.alpha, when provided, must be a Uint8Array.');
        }
        if (sideData?.alphaByteLength !== undefined
            && (!Number.isInteger(sideData.alphaByteLength) || sideData.alphaByteLength < 0)) {
            throw new TypeError('sideData.alphaByteLength, when provided, must be a non-negative integer.');
        }
        this.byteLength = byteLength;
        this.sideData = sideData ?? {};
        if (this.sideData.alpha && this.sideData.alphaByteLength === undefined) {
            this.sideData.alphaByteLength = this.sideData.alpha.byteLength;
        }
    }
    /**
     * If this packet is a metadata-only packet. Metadata-only packets don't contain their packet data. They are the
     * result of retrieving packets with {@link PacketRetrievalOptions.metadataOnly} set to `true`.
     */
    get isMetadataOnly() {
        return this.data === PLACEHOLDER_DATA;
    }
    /** The timestamp of this packet in microseconds. */
    get microsecondTimestamp() {
        return Math.trunc(_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .SECOND_TO_MICROSECOND_FACTOR */ .MW * this.timestamp);
    }
    /** The duration of this packet in microseconds. */
    get microsecondDuration() {
        return Math.trunc(_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .SECOND_TO_MICROSECOND_FACTOR */ .MW * this.duration);
    }
    /** Converts this packet to an
     * [`EncodedVideoChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) for use with the
     * WebCodecs API. */
    toEncodedVideoChunk() {
        if (this.isMetadataOnly) {
            throw new TypeError('Metadata-only packets cannot be converted to a video chunk.');
        }
        if (typeof EncodedVideoChunk === 'undefined') {
            throw new Error('Your browser does not support EncodedVideoChunk.');
        }
        return new EncodedVideoChunk({
            data: this.data,
            type: this.type,
            timestamp: this.microsecondTimestamp,
            duration: this.microsecondDuration,
        });
    }
    /**
     * Converts this packet to an
     * [`EncodedVideoChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) for use with the
     * WebCodecs API, using the alpha side data instead of the color data. Throws if no alpha side data is defined.
     */
    alphaToEncodedVideoChunk(type = this.type) {
        if (!this.sideData.alpha) {
            throw new TypeError('This packet does not contain alpha side data.');
        }
        if (this.isMetadataOnly) {
            throw new TypeError('Metadata-only packets cannot be converted to a video chunk.');
        }
        if (typeof EncodedVideoChunk === 'undefined') {
            throw new Error('Your browser does not support EncodedVideoChunk.');
        }
        return new EncodedVideoChunk({
            data: this.sideData.alpha,
            type,
            timestamp: this.microsecondTimestamp,
            duration: this.microsecondDuration,
        });
    }
    /** Converts this packet to an
     * [`EncodedAudioChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedAudioChunk) for use with the
     * WebCodecs API. */
    toEncodedAudioChunk() {
        if (this.isMetadataOnly) {
            throw new TypeError('Metadata-only packets cannot be converted to an audio chunk.');
        }
        if (typeof EncodedAudioChunk === 'undefined') {
            throw new Error('Your browser does not support EncodedAudioChunk.');
        }
        return new EncodedAudioChunk({
            data: this.data,
            type: this.type,
            timestamp: this.microsecondTimestamp,
            duration: this.microsecondDuration,
        });
    }
    /**
     * Creates an {@link EncodedPacket} from an
     * [`EncodedVideoChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) or
     * [`EncodedAudioChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedAudioChunk). This method is useful
     * for converting chunks from the WebCodecs API to `EncodedPacket` instances.
     */
    static fromEncodedChunk(chunk, sideData) {
        if (!(chunk instanceof EncodedVideoChunk || chunk instanceof EncodedAudioChunk)) {
            throw new TypeError('chunk must be an EncodedVideoChunk or EncodedAudioChunk.');
        }
        const data = new Uint8Array(chunk.byteLength);
        chunk.copyTo(data);
        return new EncodedPacket(data, chunk.type, chunk.timestamp / 1e6, (chunk.duration ?? 0) / 1e6, undefined, undefined, sideData);
    }
    /** Clones this packet while optionally modifying the new packet's data. */
    clone(options) {
        if (options !== undefined && (typeof options !== 'object' || options === null)) {
            throw new TypeError('options, when provided, must be an object.');
        }
        if (options?.data !== undefined && !(options.data instanceof Uint8Array)) {
            throw new TypeError('options.data, when provided, must be a Uint8Array.');
        }
        if (options?.type !== undefined && options.type !== 'key' && options.type !== 'delta') {
            throw new TypeError('options.type, when provided, must be either "key" or "delta".');
        }
        if (options?.timestamp !== undefined && !Number.isFinite(options.timestamp)) {
            throw new TypeError('options.timestamp, when provided, must be a number.');
        }
        if (options?.duration !== undefined && !Number.isFinite(options.duration)) {
            throw new TypeError('options.duration, when provided, must be a number.');
        }
        if (options?.sequenceNumber !== undefined && !Number.isFinite(options.sequenceNumber)) {
            throw new TypeError('options.sequenceNumber, when provided, must be a number.');
        }
        if (options?.sideData !== undefined && (typeof options.sideData !== 'object' || options.sideData === null)) {
            throw new TypeError('options.sideData, when provided, must be an object.');
        }
        return new EncodedPacket(options?.data ?? this.data, options?.type ?? this.type, options?.timestamp ?? this.timestamp, options?.duration ?? this.duration, options?.sequenceNumber ?? this.sequenceNumber, this.byteLength, options?.sideData ?? this.sideData);
    }
}


/***/ },

/***/ 358
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   aw: () => (/* binding */ fromAlaw),
/* harmony export */   qS: () => (/* binding */ fromUlaw),
/* harmony export */   vX: () => (/* binding */ toUlaw),
/* harmony export */   xq: () => (/* binding */ toAlaw)
/* harmony export */ });
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */
// https://github.com/dystopiancode/pcm-g711/blob/master/pcm-g711/g711.c
const toUlaw = (s16) => {
    const MULAW_MAX = 0x1FFF;
    const MULAW_BIAS = 33;
    let number = s16;
    let mask = 0x1000;
    let sign = 0;
    let position = 12;
    let lsb = 0;
    if (number < 0) {
        number = -number;
        sign = 0x80;
    }
    number += MULAW_BIAS;
    if (number > MULAW_MAX) {
        number = MULAW_MAX;
    }
    while ((number & mask) !== mask && position >= 5) {
        mask >>= 1;
        position--;
    }
    lsb = (number >> (position - 4)) & 0x0f;
    return ~(sign | ((position - 5) << 4) | lsb) & 0xFF;
};
const fromUlaw = (u8) => {
    const MULAW_BIAS = 33;
    let sign = 0;
    let position = 0;
    let number = ~u8;
    if (number & 0x80) {
        number &= ~(1 << 7);
        sign = -1;
    }
    position = ((number & 0xF0) >> 4) + 5;
    const decoded = ((1 << position) | ((number & 0x0F) << (position - 4))
        | (1 << (position - 5))) - MULAW_BIAS;
    return (sign === 0) ? decoded : -decoded;
};
const toAlaw = (s16) => {
    const ALAW_MAX = 0xFFF;
    let mask = 0x800;
    let sign = 0;
    let position = 11;
    let lsb = 0;
    let number = s16;
    if (number < 0) {
        number = -number;
        sign = 0x80;
    }
    if (number > ALAW_MAX) {
        number = ALAW_MAX;
    }
    while ((number & mask) !== mask && position >= 5) {
        mask >>= 1;
        position--;
    }
    lsb = (number >> ((position === 4) ? 1 : (position - 4))) & 0x0f;
    return (sign | ((position - 4) << 4) | lsb) ^ 0x55;
};
const fromAlaw = (u8) => {
    let sign = 0x00;
    let position = 0;
    let number = u8 ^ 0x55;
    if (number & 0x80) {
        number &= ~(1 << 7);
        sign = -1;
    }
    position = ((number & 0xF0) >> 4) + 4;
    let decoded = 0;
    if (position !== 4) {
        decoded = ((1 << position) | ((number & 0x0F) << (position - 4))
            | (1 << (position - 5)));
    }
    else {
        decoded = (number << 1) | 1;
    }
    return (sign === 0) ? decoded : -decoded;
};


/***/ },

/***/ 7735
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Ar: () => (/* binding */ readI32Be),
/* harmony export */   B5: () => (/* binding */ readI64Be),
/* harmony export */   IM: () => (/* binding */ readU64),
/* harmony export */   IT: () => (/* binding */ readAscii),
/* harmony export */   Jk: () => (/* binding */ readF32Be),
/* harmony export */   PF: () => (/* binding */ readU32),
/* harmony export */   TH: () => (/* binding */ readI64Le),
/* harmony export */   Vv: () => (/* binding */ readU16),
/* harmony export */   _3: () => (/* binding */ readF64Be),
/* harmony export */   aJ: () => (/* binding */ readU32Le),
/* harmony export */   cN: () => (/* binding */ readU32Be),
/* harmony export */   eo: () => (/* binding */ readU8),
/* harmony export */   iH: () => (/* binding */ readI16Be),
/* harmony export */   io: () => (/* binding */ readBytes),
/* harmony export */   mH: () => (/* binding */ readU16Be),
/* harmony export */   mP: () => (/* binding */ Reader),
/* harmony export */   n2: () => (/* binding */ readU24Be),
/* harmony export */   th: () => (/* binding */ readU64Be),
/* harmony export */   x$: () => (/* binding */ FileSlice)
/* harmony export */ });
/* unused harmony export readI32Le */
/* harmony import */ var _input_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2030);
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3912);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */


class Reader {
    constructor(source) {
        this.source = source;
    }
    requestSlice(start, length) {
        if (this.source._disposed) {
            throw new _input_js__WEBPACK_IMPORTED_MODULE_0__/* .InputDisposedError */ .Q();
        }
        if (start < 0) {
            return null;
        }
        if (this.fileSize !== null && start + length > this.fileSize) {
            return null;
        }
        const end = start + length;
        const result = this.source._read(start, end);
        if (result instanceof Promise) {
            return result.then((x) => {
                if (!x) {
                    return null;
                }
                return new FileSlice(x.bytes, x.view, x.offset, start, end);
            });
        }
        else {
            if (!result) {
                return null;
            }
            return new FileSlice(result.bytes, result.view, result.offset, start, end);
        }
    }
    requestSliceRange(start, minLength, maxLength) {
        if (this.source._disposed) {
            throw new _input_js__WEBPACK_IMPORTED_MODULE_0__/* .InputDisposedError */ .Q();
        }
        if (start < 0) {
            return null;
        }
        if (this.fileSize !== null) {
            return this.requestSlice(start, (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .clamp */ .qE)(this.fileSize - start, minLength, maxLength));
        }
        else {
            const promisedAttempt = this.requestSlice(start, maxLength);
            const handleAttempt = (attempt) => {
                if (attempt) {
                    return attempt;
                }
                const handleFileSize = (fileSize) => {
                    (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .assert */ .vA)(fileSize !== null); // The slice couldn't fit, meaning we must know the file size now
                    return this.requestSlice(start, (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .clamp */ .qE)(fileSize - start, minLength, maxLength));
                };
                const promisedFileSize = this.source._retrieveSize();
                if (promisedFileSize instanceof Promise) {
                    return promisedFileSize.then(handleFileSize);
                }
                else {
                    return handleFileSize(promisedFileSize);
                }
            };
            if (promisedAttempt instanceof Promise) {
                return promisedAttempt.then(handleAttempt);
            }
            else {
                return handleAttempt(promisedAttempt);
            }
        }
    }
}
class FileSlice {
    constructor(
    /** The underlying bytes backing this slice. Avoid using this directly and prefer reader functions instead. */
    bytes, 
    /** A view into the bytes backing this slice. Avoid using this directly and prefer reader functions instead. */
    view, 
    /** The offset in "file bytes" at which `bytes` begins in the file. */
    offset, 
    /** The offset in "file bytes" where this slice begins. */
    start, 
    /** The offset in "file bytes" where this slice ends (exclusive). */
    end) {
        this.bytes = bytes;
        this.view = view;
        this.offset = offset;
        this.start = start;
        this.end = end;
        this.bufferPos = start - offset;
    }
    static tempFromBytes(bytes) {
        return new FileSlice(bytes, (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .toDataView */ .Zc)(bytes), 0, 0, bytes.length);
    }
    get length() {
        return this.end - this.start;
    }
    get filePos() {
        return this.offset + this.bufferPos;
    }
    set filePos(value) {
        this.bufferPos = value - this.offset;
    }
    /** The number of bytes left from the current pos to the end of the slice. */
    get remainingLength() {
        return Math.max(this.end - this.filePos, 0);
    }
    skip(byteCount) {
        this.bufferPos += byteCount;
    }
    /** Creates a new subslice of this slice whose byte range must be contained within this slice. */
    slice(filePos, length = this.end - filePos) {
        if (filePos < this.start || filePos + length > this.end) {
            throw new RangeError('Slicing outside of original slice.');
        }
        return new FileSlice(this.bytes, this.view, this.offset, filePos, filePos + length);
    }
}
const checkIsInRange = (slice, bytesToRead) => {
    if (slice.filePos < slice.start || slice.filePos + bytesToRead > slice.end) {
        throw new RangeError(`Tried reading [${slice.filePos}, ${slice.filePos + bytesToRead}), but slice is`
            + ` [${slice.start}, ${slice.end}). This is likely an internal error, please report it alongside the file`
            + ` that caused it.`);
    }
};
const readBytes = (slice, length) => {
    checkIsInRange(slice, length);
    const bytes = slice.bytes.subarray(slice.bufferPos, slice.bufferPos + length);
    slice.bufferPos += length;
    return bytes;
};
const readU8 = (slice) => {
    checkIsInRange(slice, 1);
    return slice.view.getUint8(slice.bufferPos++);
};
const readU16 = (slice, littleEndian) => {
    checkIsInRange(slice, 2);
    const value = slice.view.getUint16(slice.bufferPos, littleEndian);
    slice.bufferPos += 2;
    return value;
};
const readU16Be = (slice) => {
    checkIsInRange(slice, 2);
    const value = slice.view.getUint16(slice.bufferPos, false);
    slice.bufferPos += 2;
    return value;
};
const readU24Be = (slice) => {
    checkIsInRange(slice, 3);
    const value = (0,_misc_js__WEBPACK_IMPORTED_MODULE_1__/* .getUint24 */ .dq)(slice.view, slice.bufferPos, false);
    slice.bufferPos += 3;
    return value;
};
const readI16Be = (slice) => {
    checkIsInRange(slice, 2);
    const value = slice.view.getInt16(slice.bufferPos, false);
    slice.bufferPos += 2;
    return value;
};
const readU32 = (slice, littleEndian) => {
    checkIsInRange(slice, 4);
    const value = slice.view.getUint32(slice.bufferPos, littleEndian);
    slice.bufferPos += 4;
    return value;
};
const readU32Be = (slice) => {
    checkIsInRange(slice, 4);
    const value = slice.view.getUint32(slice.bufferPos, false);
    slice.bufferPos += 4;
    return value;
};
const readU32Le = (slice) => {
    checkIsInRange(slice, 4);
    const value = slice.view.getUint32(slice.bufferPos, true);
    slice.bufferPos += 4;
    return value;
};
const readI32Be = (slice) => {
    checkIsInRange(slice, 4);
    const value = slice.view.getInt32(slice.bufferPos, false);
    slice.bufferPos += 4;
    return value;
};
const readI32Le = (slice) => {
    checkIsInRange(slice, 4);
    const value = slice.view.getInt32(slice.bufferPos, true);
    slice.bufferPos += 4;
    return value;
};
const readU64 = (slice, littleEndian) => {
    let low;
    let high;
    if (littleEndian) {
        low = readU32(slice, true);
        high = readU32(slice, true);
    }
    else {
        high = readU32(slice, false);
        low = readU32(slice, false);
    }
    return high * 0x100000000 + low;
};
const readU64Be = (slice) => {
    const high = readU32Be(slice);
    const low = readU32Be(slice);
    return high * 0x100000000 + low;
};
const readI64Be = (slice) => {
    const high = readI32Be(slice);
    const low = readU32Be(slice);
    return high * 0x100000000 + low;
};
const readI64Le = (slice) => {
    const low = readU32Le(slice);
    const high = readI32Le(slice);
    return high * 0x100000000 + low;
};
const readF32Be = (slice) => {
    checkIsInRange(slice, 4);
    const value = slice.view.getFloat32(slice.bufferPos, false);
    slice.bufferPos += 4;
    return value;
};
const readF64Be = (slice) => {
    checkIsInRange(slice, 8);
    const value = slice.view.getFloat64(slice.bufferPos, false);
    slice.bufferPos += 8;
    return value;
};
const readAscii = (slice, length) => {
    checkIsInRange(slice, length);
    let str = '';
    for (let i = 0; i < length; i++) {
        str += String.fromCharCode(slice.bytes[slice.bufferPos++]);
    }
    return str;
};


/***/ },

/***/ 4166
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   B1: () => (/* binding */ AudioSample),
/* harmony export */   U2: () => (/* binding */ VideoSample)
/* harmony export */ });
/* unused harmony exports VIDEO_SAMPLE_PIXEL_FORMATS, VideoSampleColorSpace, clampCropRectangle, validateCropRectangle */
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3912);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

(0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .polyfillSymbolDispose */ .XQ)();
// Let's manually handle logging the garbage collection errors that are typically logged by the browser. This way, they
// also kick for audio samples (which is normally not the case), making sure any incorrect code is quickly caught.
let lastVideoGcErrorLog = -Infinity;
let lastAudioGcErrorLog = -Infinity;
let finalizationRegistry = null;
if (typeof FinalizationRegistry !== 'undefined') {
    finalizationRegistry = new FinalizationRegistry((value) => {
        const now = Date.now();
        if (value.type === 'video') {
            if (now - lastVideoGcErrorLog >= 1000) {
                // This error is annoying but oh so important
                console.error(`A VideoSample was garbage collected without first being closed. For proper resource management,`
                    + ` make sure to call close() on all your VideoSamples as soon as you're done using them.`);
                lastVideoGcErrorLog = now;
            }
            if (typeof VideoFrame !== 'undefined' && value.data instanceof VideoFrame) {
                value.data.close(); // Prevent the browser error since we're logging our own
            }
        }
        else {
            if (now - lastAudioGcErrorLog >= 1000) {
                console.error(`An AudioSample was garbage collected without first being closed. For proper resource management,`
                    + ` make sure to call close() on all your AudioSamples as soon as you're done using them.`);
                lastAudioGcErrorLog = now;
            }
            if (typeof AudioData !== 'undefined' && value.data instanceof AudioData) {
                value.data.close();
            }
        }
    });
}
/**
 * The list of {@link VideoSample} pixel formats.
 * @group Samples
 * @public
 */
const VIDEO_SAMPLE_PIXEL_FORMATS = [
    // 4:2:0 Y, U, V
    'I420',
    'I420P10',
    'I420P12',
    // 4:2:0 Y, U, V, A
    'I420A',
    'I420AP10',
    'I420AP12',
    // 4:2:2 Y, U, V
    'I422',
    'I422P10',
    'I422P12',
    // 4:2:2 Y, U, V, A
    'I422A',
    'I422AP10',
    'I422AP12',
    // 4:4:4 Y, U, V
    'I444',
    'I444P10',
    'I444P12',
    // 4:4:4 Y, U, V, A
    'I444A',
    'I444AP10',
    'I444AP12',
    // 4:2:0 Y, UV
    'NV12',
    // 4:4:4 RGBA
    'RGBA',
    // 4:4:4 RGBX (opaque)
    'RGBX',
    // 4:4:4 BGRA
    'BGRA',
    // 4:4:4 BGRX (opaque)
    'BGRX',
];
const VIDEO_SAMPLE_PIXEL_FORMATS_SET = new Set(VIDEO_SAMPLE_PIXEL_FORMATS);
/**
 * Represents a raw, unencoded video sample (frame). Mainly used as an expressive wrapper around WebCodecs API's
 * [`VideoFrame`](https://developer.mozilla.org/en-US/docs/Web/API/VideoFrame), but can also be used standalone.
 * @group Samples
 * @public
 */
class VideoSample {
    /** The width of the frame in pixels after rotation. */
    get displayWidth() {
        return this.rotation % 180 === 0 ? this.codedWidth : this.codedHeight;
    }
    /** The height of the frame in pixels after rotation. */
    get displayHeight() {
        return this.rotation % 180 === 0 ? this.codedHeight : this.codedWidth;
    }
    /** The presentation timestamp of the frame in microseconds. */
    get microsecondTimestamp() {
        return Math.trunc(_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .SECOND_TO_MICROSECOND_FACTOR */ .MW * this.timestamp);
    }
    /** The duration of the frame in microseconds. */
    get microsecondDuration() {
        return Math.trunc(_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .SECOND_TO_MICROSECOND_FACTOR */ .MW * this.duration);
    }
    /**
     * Whether this sample uses a pixel format that can hold transparency data. Note that this doesn't necessarily mean
     * that the sample is transparent.
     */
    get hasAlpha() {
        return this.format && this.format.includes('A');
    }
    constructor(data, init) {
        /** @internal */
        this._closed = false;
        if (data instanceof ArrayBuffer
            || (typeof SharedArrayBuffer !== 'undefined' && data instanceof SharedArrayBuffer)
            || ArrayBuffer.isView(data)) {
            if (!init || typeof init !== 'object') {
                throw new TypeError('init must be an object.');
            }
            if (init.format === undefined || !VIDEO_SAMPLE_PIXEL_FORMATS_SET.has(init.format)) {
                throw new TypeError('init.format must be one of: ' + VIDEO_SAMPLE_PIXEL_FORMATS.join(', '));
            }
            if (!Number.isInteger(init.codedWidth) || init.codedWidth <= 0) {
                throw new TypeError('init.codedWidth must be a positive integer.');
            }
            if (!Number.isInteger(init.codedHeight) || init.codedHeight <= 0) {
                throw new TypeError('init.codedHeight must be a positive integer.');
            }
            if (init.rotation !== undefined && ![0, 90, 180, 270].includes(init.rotation)) {
                throw new TypeError('init.rotation, when provided, must be 0, 90, 180, or 270.');
            }
            if (!Number.isFinite(init.timestamp)) {
                throw new TypeError('init.timestamp must be a number.');
            }
            if (init.duration !== undefined && (!Number.isFinite(init.duration) || init.duration < 0)) {
                throw new TypeError('init.duration, when provided, must be a non-negative number.');
            }
            this._data = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toUint8Array */ .Fo)(data).slice(); // Copy it
            this._layout = init.layout ?? createDefaultPlaneLayout(init.format, init.codedWidth, init.codedHeight);
            this.format = init.format;
            this.codedWidth = init.codedWidth;
            this.codedHeight = init.codedHeight;
            this.rotation = init.rotation ?? 0;
            this.timestamp = init.timestamp;
            this.duration = init.duration ?? 0;
            this.colorSpace = new VideoSampleColorSpace(init.colorSpace);
        }
        else if (typeof VideoFrame !== 'undefined' && data instanceof VideoFrame) {
            if (init?.rotation !== undefined && ![0, 90, 180, 270].includes(init.rotation)) {
                throw new TypeError('init.rotation, when provided, must be 0, 90, 180, or 270.');
            }
            if (init?.timestamp !== undefined && !Number.isFinite(init?.timestamp)) {
                throw new TypeError('init.timestamp, when provided, must be a number.');
            }
            if (init?.duration !== undefined && (!Number.isFinite(init.duration) || init.duration < 0)) {
                throw new TypeError('init.duration, when provided, must be a non-negative number.');
            }
            this._data = data;
            this._layout = null;
            this.format = data.format;
            // Copying the display dimensions here, assuming no innate VideoFrame rotation
            this.codedWidth = data.displayWidth;
            this.codedHeight = data.displayHeight;
            // The VideoFrame's rotation is ignored here. It's still a new field, and I'm not sure of any application
            // where the browser makes use of it. If a case gets found, I'll add it.
            this.rotation = init?.rotation ?? 0;
            this.timestamp = init?.timestamp ?? data.timestamp / 1e6;
            this.duration = init?.duration ?? (data.duration ?? 0) / 1e6;
            this.colorSpace = new VideoSampleColorSpace(data.colorSpace);
        }
        else if ((typeof HTMLImageElement !== 'undefined' && data instanceof HTMLImageElement)
            || (typeof SVGImageElement !== 'undefined' && data instanceof SVGImageElement)
            || (typeof ImageBitmap !== 'undefined' && data instanceof ImageBitmap)
            || (typeof HTMLVideoElement !== 'undefined' && data instanceof HTMLVideoElement)
            || (typeof HTMLCanvasElement !== 'undefined' && data instanceof HTMLCanvasElement)
            || (typeof OffscreenCanvas !== 'undefined' && data instanceof OffscreenCanvas)) {
            if (!init || typeof init !== 'object') {
                throw new TypeError('init must be an object.');
            }
            if (init.rotation !== undefined && ![0, 90, 180, 270].includes(init.rotation)) {
                throw new TypeError('init.rotation, when provided, must be 0, 90, 180, or 270.');
            }
            if (!Number.isFinite(init.timestamp)) {
                throw new TypeError('init.timestamp must be a number.');
            }
            if (init.duration !== undefined && (!Number.isFinite(init.duration) || init.duration < 0)) {
                throw new TypeError('init.duration, when provided, must be a non-negative number.');
            }
            if (typeof VideoFrame !== 'undefined') {
                return new VideoSample(new VideoFrame(data, {
                    timestamp: Math.trunc(init.timestamp * _misc_js__WEBPACK_IMPORTED_MODULE_0__/* .SECOND_TO_MICROSECOND_FACTOR */ .MW),
                    // Drag 0 to undefined
                    duration: Math.trunc((init.duration ?? 0) * _misc_js__WEBPACK_IMPORTED_MODULE_0__/* .SECOND_TO_MICROSECOND_FACTOR */ .MW) || undefined,
                }), init);
            }
            let width = 0;
            let height = 0;
            // Determine the dimensions of the thing
            if ('naturalWidth' in data) {
                width = data.naturalWidth;
                height = data.naturalHeight;
            }
            else if ('videoWidth' in data) {
                width = data.videoWidth;
                height = data.videoHeight;
            }
            else if ('width' in data) {
                width = Number(data.width);
                height = Number(data.height);
            }
            if (!width || !height) {
                throw new TypeError('Could not determine dimensions.');
            }
            const canvas = new OffscreenCanvas(width, height);
            const context = canvas.getContext('2d', {
                alpha: (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .isFirefox */ .gm)(), // Firefox has VideoFrame glitches with opaque canvases
                willReadFrequently: true,
            });
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(context);
            // Draw it to a canvas
            context.drawImage(data, 0, 0);
            this._data = canvas;
            this._layout = null;
            this.format = 'RGBX';
            this.codedWidth = width;
            this.codedHeight = height;
            this.rotation = init.rotation ?? 0;
            this.timestamp = init.timestamp;
            this.duration = init.duration ?? 0;
            this.colorSpace = new VideoSampleColorSpace({
                matrix: 'rgb',
                primaries: 'bt709',
                transfer: 'iec61966-2-1',
                fullRange: true,
            });
        }
        else {
            throw new TypeError('Invalid data type: Must be a BufferSource or CanvasImageSource.');
        }
        finalizationRegistry?.register(this, { type: 'video', data: this._data }, this);
    }
    /** Clones this video sample. */
    clone() {
        if (this._closed) {
            throw new Error('VideoSample is closed.');
        }
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(this._data !== null);
        if (isVideoFrame(this._data)) {
            return new VideoSample(this._data.clone(), {
                timestamp: this.timestamp,
                duration: this.duration,
                rotation: this.rotation,
            });
        }
        else if (this._data instanceof Uint8Array) {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(this._layout);
            return new VideoSample(this._data, {
                format: this.format,
                layout: this._layout,
                codedWidth: this.codedWidth,
                codedHeight: this.codedHeight,
                timestamp: this.timestamp,
                duration: this.duration,
                colorSpace: this.colorSpace,
                rotation: this.rotation,
            });
        }
        else {
            return new VideoSample(this._data, {
                format: this.format,
                codedWidth: this.codedWidth,
                codedHeight: this.codedHeight,
                timestamp: this.timestamp,
                duration: this.duration,
                colorSpace: this.colorSpace,
                rotation: this.rotation,
            });
        }
    }
    /**
     * Closes this video sample, releasing held resources. Video samples should be closed as soon as they are not
     * needed anymore.
     */
    close() {
        if (this._closed) {
            return;
        }
        finalizationRegistry?.unregister(this);
        if (isVideoFrame(this._data)) {
            this._data.close();
        }
        else {
            this._data = null; // GC that shit
        }
        this._closed = true;
    }
    /**
     * Returns the number of bytes required to hold this video sample's pixel data. Throws if `format` is `null`.
     */
    allocationSize(options = {}) {
        validateVideoFrameCopyToOptions(options);
        if (this._closed) {
            throw new Error('VideoSample is closed.');
        }
        if (this.format === null) {
            // https://github.com/Vanilagy/mediabunny/issues/267
            // https://github.com/w3c/webcodecs/issues/920
            throw new Error('Cannot get allocation size when format is null. Sorry!');
        }
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(this._data !== null);
        if (!isVideoFrame(this._data)) {
            if (options.colorSpace
                || (options.format && options.format !== this.format)
                || options.layout
                || options.rect) {
                // Temporarily convert to VideoFrame to get it done
                // TODO: Compute this directly without needing to go through VideoFrame
                const videoFrame = this.toVideoFrame();
                const size = videoFrame.allocationSize(options);
                videoFrame.close();
                return size;
            }
        }
        if (isVideoFrame(this._data)) {
            return this._data.allocationSize(options);
        }
        else if (this._data instanceof Uint8Array) {
            return this._data.byteLength;
        }
        else {
            return this.codedWidth * this.codedHeight * 4; // RGBX
        }
    }
    /**
     * Copies this video sample's pixel data to an ArrayBuffer or ArrayBufferView. Throws if `format` is `null`.
     * @returns The byte layout of the planes of the copied data.
     */
    async copyTo(destination, options = {}) {
        if (!(0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .isAllowSharedBufferSource */ .SM)(destination)) {
            throw new TypeError('destination must be an ArrayBuffer or an ArrayBuffer view.');
        }
        validateVideoFrameCopyToOptions(options);
        if (this._closed) {
            throw new Error('VideoSample is closed.');
        }
        if (this.format === null) {
            throw new Error('Cannot copy video sample data when format is null. Sorry!');
        }
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(this._data !== null);
        if (!isVideoFrame(this._data)) {
            if (options.colorSpace
                || (options.format && options.format !== this.format)
                || options.layout
                || options.rect) {
                // Temporarily convert to VideoFrame to get it done
                // TODO: Do this directly without needing to go through VideoFrame
                const videoFrame = this.toVideoFrame();
                const layout = await videoFrame.copyTo(destination, options);
                videoFrame.close();
                return layout;
            }
        }
        if (isVideoFrame(this._data)) {
            return this._data.copyTo(destination, options);
        }
        else if (this._data instanceof Uint8Array) {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(this._layout);
            const dest = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toUint8Array */ .Fo)(destination);
            dest.set(this._data);
            return this._layout;
        }
        else {
            const canvas = this._data;
            const context = canvas.getContext('2d');
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(context);
            const imageData = context.getImageData(0, 0, this.codedWidth, this.codedHeight);
            const dest = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toUint8Array */ .Fo)(destination);
            dest.set(imageData.data);
            return [{
                    offset: 0,
                    stride: 4 * this.codedWidth,
                }];
        }
    }
    /**
     * Converts this video sample to a VideoFrame for use with the WebCodecs API. The VideoFrame returned by this
     * method *must* be closed separately from this video sample.
     */
    toVideoFrame() {
        if (this._closed) {
            throw new Error('VideoSample is closed.');
        }
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(this._data !== null);
        if (isVideoFrame(this._data)) {
            return new VideoFrame(this._data, {
                timestamp: this.microsecondTimestamp,
                duration: this.microsecondDuration || undefined, // Drag 0 duration to undefined, glitches some codecs
            });
        }
        else if (this._data instanceof Uint8Array) {
            return new VideoFrame(this._data, {
                format: this.format,
                codedWidth: this.codedWidth,
                codedHeight: this.codedHeight,
                timestamp: this.microsecondTimestamp,
                duration: this.microsecondDuration || undefined,
                colorSpace: this.colorSpace,
            });
        }
        else {
            return new VideoFrame(this._data, {
                timestamp: this.microsecondTimestamp,
                duration: this.microsecondDuration || undefined,
            });
        }
    }
    draw(context, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) {
        let sx = 0;
        let sy = 0;
        let sWidth = this.displayWidth;
        let sHeight = this.displayHeight;
        let dx = 0;
        let dy = 0;
        let dWidth = this.displayWidth;
        let dHeight = this.displayHeight;
        if (arg5 !== undefined) {
            sx = arg1;
            sy = arg2;
            sWidth = arg3;
            sHeight = arg4;
            dx = arg5;
            dy = arg6;
            if (arg7 !== undefined) {
                dWidth = arg7;
                dHeight = arg8;
            }
            else {
                dWidth = sWidth;
                dHeight = sHeight;
            }
        }
        else {
            dx = arg1;
            dy = arg2;
            if (arg3 !== undefined) {
                dWidth = arg3;
                dHeight = arg4;
            }
        }
        if (!((typeof CanvasRenderingContext2D !== 'undefined' && context instanceof CanvasRenderingContext2D)
            || (typeof OffscreenCanvasRenderingContext2D !== 'undefined'
                && context instanceof OffscreenCanvasRenderingContext2D))) {
            throw new TypeError('context must be a CanvasRenderingContext2D or OffscreenCanvasRenderingContext2D.');
        }
        if (!Number.isFinite(sx)) {
            throw new TypeError('sx must be a number.');
        }
        if (!Number.isFinite(sy)) {
            throw new TypeError('sy must be a number.');
        }
        if (!Number.isFinite(sWidth) || sWidth < 0) {
            throw new TypeError('sWidth must be a non-negative number.');
        }
        if (!Number.isFinite(sHeight) || sHeight < 0) {
            throw new TypeError('sHeight must be a non-negative number.');
        }
        if (!Number.isFinite(dx)) {
            throw new TypeError('dx must be a number.');
        }
        if (!Number.isFinite(dy)) {
            throw new TypeError('dy must be a number.');
        }
        if (!Number.isFinite(dWidth) || dWidth < 0) {
            throw new TypeError('dWidth must be a non-negative number.');
        }
        if (!Number.isFinite(dHeight) || dHeight < 0) {
            throw new TypeError('dHeight must be a non-negative number.');
        }
        if (this._closed) {
            throw new Error('VideoSample is closed.');
        }
        ({ sx, sy, sWidth, sHeight } = this._rotateSourceRegion(sx, sy, sWidth, sHeight, this.rotation));
        const source = this.toCanvasImageSource();
        context.save();
        const centerX = dx + dWidth / 2;
        const centerY = dy + dHeight / 2;
        context.translate(centerX, centerY);
        context.rotate(this.rotation * Math.PI / 180);
        const aspectRatioChange = this.rotation % 180 === 0 ? 1 : dWidth / dHeight;
        // Scale to compensate for aspect ratio changes when rotated
        context.scale(1 / aspectRatioChange, aspectRatioChange);
        context.drawImage(source, sx, sy, sWidth, sHeight, -dWidth / 2, -dHeight / 2, dWidth, dHeight);
        context.restore();
    }
    /**
     * Draws the sample in the middle of the canvas corresponding to the context with the specified fit behavior.
     */
    drawWithFit(context, options) {
        if (!((typeof CanvasRenderingContext2D !== 'undefined' && context instanceof CanvasRenderingContext2D)
            || (typeof OffscreenCanvasRenderingContext2D !== 'undefined'
                && context instanceof OffscreenCanvasRenderingContext2D))) {
            throw new TypeError('context must be a CanvasRenderingContext2D or OffscreenCanvasRenderingContext2D.');
        }
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (!['fill', 'contain', 'cover'].includes(options.fit)) {
            throw new TypeError('options.fit must be \'fill\', \'contain\', or \'cover\'.');
        }
        if (options.rotation !== undefined && ![0, 90, 180, 270].includes(options.rotation)) {
            throw new TypeError('options.rotation, when provided, must be 0, 90, 180, or 270.');
        }
        if (options.crop !== undefined) {
            validateCropRectangle(options.crop, 'options.');
        }
        const canvasWidth = context.canvas.width;
        const canvasHeight = context.canvas.height;
        const rotation = options.rotation ?? this.rotation;
        const [rotatedWidth, rotatedHeight] = rotation % 180 === 0
            ? [this.codedWidth, this.codedHeight]
            : [this.codedHeight, this.codedWidth];
        if (options.crop) {
            clampCropRectangle(options.crop, rotatedWidth, rotatedHeight);
        }
        // These variables specify where the final sample will be drawn on the canvas
        let dx;
        let dy;
        let newWidth;
        let newHeight;
        const { sx, sy, sWidth, sHeight } = this._rotateSourceRegion(options.crop?.left ?? 0, options.crop?.top ?? 0, options.crop?.width ?? rotatedWidth, options.crop?.height ?? rotatedHeight, rotation);
        if (options.fit === 'fill') {
            dx = 0;
            dy = 0;
            newWidth = canvasWidth;
            newHeight = canvasHeight;
        }
        else {
            const [sampleWidth, sampleHeight] = options.crop
                ? [options.crop.width, options.crop.height]
                : [rotatedWidth, rotatedHeight];
            const scale = options.fit === 'contain'
                ? Math.min(canvasWidth / sampleWidth, canvasHeight / sampleHeight)
                : Math.max(canvasWidth / sampleWidth, canvasHeight / sampleHeight);
            newWidth = sampleWidth * scale;
            newHeight = sampleHeight * scale;
            dx = (canvasWidth - newWidth) / 2;
            dy = (canvasHeight - newHeight) / 2;
        }
        context.save();
        const aspectRatioChange = rotation % 180 === 0 ? 1 : newWidth / newHeight;
        context.translate(canvasWidth / 2, canvasHeight / 2);
        context.rotate(rotation * Math.PI / 180);
        // This aspect ratio compensation is done so that we can draw the sample with the intended dimensions and
        // don't need to think about how those dimensions change after the rotation
        context.scale(1 / aspectRatioChange, aspectRatioChange);
        context.translate(-canvasWidth / 2, -canvasHeight / 2);
        // Important that we don't use .draw() here since that would take rotation into account, but we wanna handle it
        // ourselves here
        context.drawImage(this.toCanvasImageSource(), sx, sy, sWidth, sHeight, dx, dy, newWidth, newHeight);
        context.restore();
    }
    /** @internal */
    _rotateSourceRegion(sx, sy, sWidth, sHeight, rotation) {
        // The provided sx,sy,sWidth,sHeight refer to the final rotated image, but that's not actually how the image is
        // stored. Therefore, we must map these back onto the original, pre-rotation image.
        if (rotation === 90) {
            [sx, sy, sWidth, sHeight] = [
                sy,
                this.codedHeight - sx - sWidth,
                sHeight,
                sWidth,
            ];
        }
        else if (rotation === 180) {
            [sx, sy] = [
                this.codedWidth - sx - sWidth,
                this.codedHeight - sy - sHeight,
            ];
        }
        else if (rotation === 270) {
            [sx, sy, sWidth, sHeight] = [
                this.codedWidth - sy - sHeight,
                sx,
                sHeight,
                sWidth,
            ];
        }
        return { sx, sy, sWidth, sHeight };
    }
    /**
     * Converts this video sample to a
     * [`CanvasImageSource`](https://udn.realityripple.com/docs/Web/API/CanvasImageSource) for drawing to a canvas.
     *
     * You must use the value returned by this method immediately, as any VideoFrame created internally will
     * automatically be closed in the next microtask.
     */
    toCanvasImageSource() {
        if (this._closed) {
            throw new Error('VideoSample is closed.');
        }
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(this._data !== null);
        if (this._data instanceof Uint8Array) {
            // Requires VideoFrame to be defined
            const videoFrame = this.toVideoFrame();
            queueMicrotask(() => videoFrame.close()); // Let's automatically close the frame in the next microtask
            return videoFrame;
        }
        else {
            return this._data;
        }
    }
    /** Sets the rotation metadata of this video sample. */
    setRotation(newRotation) {
        if (![0, 90, 180, 270].includes(newRotation)) {
            throw new TypeError('newRotation must be 0, 90, 180, or 270.');
        }
        // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
        this.rotation = newRotation;
    }
    /** Sets the presentation timestamp of this video sample, in seconds. */
    setTimestamp(newTimestamp) {
        if (!Number.isFinite(newTimestamp)) {
            throw new TypeError('newTimestamp must be a number.');
        }
        // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
        this.timestamp = newTimestamp;
    }
    /** Sets the duration of this video sample, in seconds. */
    setDuration(newDuration) {
        if (!Number.isFinite(newDuration) || newDuration < 0) {
            throw new TypeError('newDuration must be a non-negative number.');
        }
        // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
        this.duration = newDuration;
    }
    /** Calls `.close()`. */
    [Symbol.dispose]() {
        this.close();
    }
}
/**
 * Describes the color space of a {@link VideoSample}. Corresponds to the WebCodecs API's VideoColorSpace.
 * @group Samples
 * @public
 */
class VideoSampleColorSpace {
    /** Creates a new VideoSampleColorSpace. */
    constructor(init) {
        this.primaries = init?.primaries ?? null;
        this.transfer = init?.transfer ?? null;
        this.matrix = init?.matrix ?? null;
        this.fullRange = init?.fullRange ?? null;
    }
    /** Serializes the color space to a JSON object. */
    toJSON() {
        return {
            primaries: this.primaries,
            transfer: this.transfer,
            matrix: this.matrix,
            fullRange: this.fullRange,
        };
    }
}
const isVideoFrame = (x) => {
    return typeof VideoFrame !== 'undefined' && x instanceof VideoFrame;
};
const clampCropRectangle = (crop, outerWidth, outerHeight) => {
    crop.left = Math.min(crop.left, outerWidth);
    crop.top = Math.min(crop.top, outerHeight);
    crop.width = Math.min(crop.width, outerWidth - crop.left);
    crop.height = Math.min(crop.height, outerHeight - crop.top);
    (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(crop.width >= 0);
    (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(crop.height >= 0);
};
const validateCropRectangle = (crop, prefix) => {
    if (!crop || typeof crop !== 'object') {
        throw new TypeError(prefix + 'crop, when provided, must be an object.');
    }
    if (!Number.isInteger(crop.left) || crop.left < 0) {
        throw new TypeError(prefix + 'crop.left must be a non-negative integer.');
    }
    if (!Number.isInteger(crop.top) || crop.top < 0) {
        throw new TypeError(prefix + 'crop.top must be a non-negative integer.');
    }
    if (!Number.isInteger(crop.width) || crop.width < 0) {
        throw new TypeError(prefix + 'crop.width must be a non-negative integer.');
    }
    if (!Number.isInteger(crop.height) || crop.height < 0) {
        throw new TypeError(prefix + 'crop.height must be a non-negative integer.');
    }
};
const validateVideoFrameCopyToOptions = (options) => {
    if (!options || typeof options !== 'object') {
        throw new TypeError('options must be an object.');
    }
    if (options.colorSpace !== undefined && !['display-p3', 'srgb'].includes(options.colorSpace)) {
        throw new TypeError('options.colorSpace, when provided, must be \'display-p3\' or \'srgb\'.');
    }
    if (options.format !== undefined && typeof options.format !== 'string') {
        throw new TypeError('options.format, when provided, must be a string.');
    }
    if (options.layout !== undefined) {
        if (!Array.isArray(options.layout)) {
            throw new TypeError('options.layout, when provided, must be an array.');
        }
        for (const plane of options.layout) {
            if (!plane || typeof plane !== 'object') {
                throw new TypeError('Each entry in options.layout must be an object.');
            }
            if (!Number.isInteger(plane.offset) || plane.offset < 0) {
                throw new TypeError('plane.offset must be a non-negative integer.');
            }
            if (!Number.isInteger(plane.stride) || plane.stride < 0) {
                throw new TypeError('plane.stride must be a non-negative integer.');
            }
        }
    }
    if (options.rect !== undefined) {
        if (!options.rect || typeof options.rect !== 'object') {
            throw new TypeError('options.rect, when provided, must be an object.');
        }
        if (options.rect.x !== undefined && (!Number.isInteger(options.rect.x) || options.rect.x < 0)) {
            throw new TypeError('options.rect.x, when provided, must be a non-negative integer.');
        }
        if (options.rect.y !== undefined && (!Number.isInteger(options.rect.y) || options.rect.y < 0)) {
            throw new TypeError('options.rect.y, when provided, must be a non-negative integer.');
        }
        if (options.rect.width !== undefined && (!Number.isInteger(options.rect.width) || options.rect.width < 0)) {
            throw new TypeError('options.rect.width, when provided, must be a non-negative integer.');
        }
        if (options.rect.height !== undefined && (!Number.isInteger(options.rect.height) || options.rect.height < 0)) {
            throw new TypeError('options.rect.height, when provided, must be a non-negative integer.');
        }
    }
};
/** Implements logic from WebCodecs § 9.4.6 "Compute Layout and Allocation Size" */
const createDefaultPlaneLayout = (format, codedWidth, codedHeight) => {
    const planes = getPlaneConfigs(format);
    const layouts = [];
    let currentOffset = 0;
    for (const plane of planes) {
        // Per § 9.8, dimensions are usually "rounded up to the nearest integer".
        const planeWidth = Math.ceil(codedWidth / plane.widthDivisor);
        const planeHeight = Math.ceil(codedHeight / plane.heightDivisor);
        const stride = planeWidth * plane.sampleBytes;
        // Tight packing
        const planeSize = stride * planeHeight;
        layouts.push({
            offset: currentOffset,
            stride: stride,
        });
        currentOffset += planeSize;
    }
    return layouts;
};
/** Helper to retrieve plane configurations based on WebCodecs § 9.8 Pixel Format definitions. */
const getPlaneConfigs = (format) => {
    // Helper for standard YUV planes
    const yuv = (yBytes, uvBytes, subX, subY, hasAlpha) => {
        const configs = [
            { sampleBytes: yBytes, widthDivisor: 1, heightDivisor: 1 },
            { sampleBytes: uvBytes, widthDivisor: subX, heightDivisor: subY },
            { sampleBytes: uvBytes, widthDivisor: subX, heightDivisor: subY },
        ];
        if (hasAlpha) {
            // Match luma dimensions
            configs.push({ sampleBytes: yBytes, widthDivisor: 1, heightDivisor: 1 });
        }
        return configs;
    };
    switch (format) {
        case 'I420':
            return yuv(1, 1, 2, 2, false);
        case 'I420P10':
        case 'I420P12':
            return yuv(2, 2, 2, 2, false);
        case 'I420A':
            return yuv(1, 1, 2, 2, true);
        case 'I420AP10':
        case 'I420AP12':
            return yuv(2, 2, 2, 2, true);
        case 'I422':
            return yuv(1, 1, 2, 1, false);
        case 'I422P10':
        case 'I422P12':
            return yuv(2, 2, 2, 1, false);
        case 'I422A':
            return yuv(1, 1, 2, 1, true);
        case 'I422AP10':
        case 'I422AP12':
            return yuv(2, 2, 2, 1, true);
        case 'I444':
            return yuv(1, 1, 1, 1, false);
        case 'I444P10':
        case 'I444P12':
            return yuv(2, 2, 1, 1, false);
        case 'I444A':
            return yuv(1, 1, 1, 1, true);
        case 'I444AP10':
        case 'I444AP12':
            return yuv(2, 2, 1, 1, true);
        case 'NV12':
            return [
                { sampleBytes: 1, widthDivisor: 1, heightDivisor: 1 },
                { sampleBytes: 2, widthDivisor: 2, heightDivisor: 2 }, // Interleaved U and V
            ];
        case 'RGBA':
        case 'RGBX':
        case 'BGRA':
        case 'BGRX':
            return [
                { sampleBytes: 4, widthDivisor: 1, heightDivisor: 1 },
            ];
        default:
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assertNever */ .xb)(format);
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(false);
    }
};
const AUDIO_SAMPLE_FORMATS = new Set(['f32', 'f32-planar', 's16', 's16-planar', 's32', 's32-planar', 'u8', 'u8-planar']);
/**
 * Represents a raw, unencoded audio sample. Mainly used as an expressive wrapper around WebCodecs API's
 * [`AudioData`](https://developer.mozilla.org/en-US/docs/Web/API/AudioData), but can also be used standalone.
 * @group Samples
 * @public
 */
class AudioSample {
    /** The presentation timestamp of the sample in microseconds. */
    get microsecondTimestamp() {
        return Math.trunc(_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .SECOND_TO_MICROSECOND_FACTOR */ .MW * this.timestamp);
    }
    /** The duration of the sample in microseconds. */
    get microsecondDuration() {
        return Math.trunc(_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .SECOND_TO_MICROSECOND_FACTOR */ .MW * this.duration);
    }
    /**
     * Creates a new {@link AudioSample}, either from an existing
     * [`AudioData`](https://developer.mozilla.org/en-US/docs/Web/API/AudioData) or from raw bytes specified in
     * {@link AudioSampleInit}.
     */
    constructor(init) {
        /** @internal */
        this._closed = false;
        if (isAudioData(init)) {
            if (init.format === null) {
                throw new TypeError('AudioData with null format is not supported.');
            }
            this._data = init;
            this.format = init.format;
            this.sampleRate = init.sampleRate;
            this.numberOfFrames = init.numberOfFrames;
            this.numberOfChannels = init.numberOfChannels;
            this.timestamp = init.timestamp / 1e6;
            this.duration = init.numberOfFrames / init.sampleRate;
        }
        else {
            if (!init || typeof init !== 'object') {
                throw new TypeError('Invalid AudioDataInit: must be an object.');
            }
            if (!AUDIO_SAMPLE_FORMATS.has(init.format)) {
                throw new TypeError('Invalid AudioDataInit: invalid format.');
            }
            if (!Number.isFinite(init.sampleRate) || init.sampleRate <= 0) {
                throw new TypeError('Invalid AudioDataInit: sampleRate must be > 0.');
            }
            if (!Number.isInteger(init.numberOfChannels) || init.numberOfChannels === 0) {
                throw new TypeError('Invalid AudioDataInit: numberOfChannels must be an integer > 0.');
            }
            if (!Number.isFinite(init?.timestamp)) {
                throw new TypeError('init.timestamp must be a number.');
            }
            const numberOfFrames = init.data.byteLength / (getBytesPerSample(init.format) * init.numberOfChannels);
            if (!Number.isInteger(numberOfFrames)) {
                throw new TypeError('Invalid AudioDataInit: data size is not a multiple of frame size.');
            }
            this.format = init.format;
            this.sampleRate = init.sampleRate;
            this.numberOfFrames = numberOfFrames;
            this.numberOfChannels = init.numberOfChannels;
            this.timestamp = init.timestamp;
            this.duration = numberOfFrames / init.sampleRate;
            let dataBuffer;
            if (init.data instanceof ArrayBuffer) {
                dataBuffer = new Uint8Array(init.data);
            }
            else if (ArrayBuffer.isView(init.data)) {
                dataBuffer = new Uint8Array(init.data.buffer, init.data.byteOffset, init.data.byteLength);
            }
            else {
                throw new TypeError('Invalid AudioDataInit: data is not a BufferSource.');
            }
            const expectedSize = this.numberOfFrames * this.numberOfChannels * getBytesPerSample(this.format);
            if (dataBuffer.byteLength < expectedSize) {
                throw new TypeError('Invalid AudioDataInit: insufficient data size.');
            }
            this._data = dataBuffer;
        }
        finalizationRegistry?.register(this, { type: 'audio', data: this._data }, this);
    }
    /** Returns the number of bytes required to hold the audio sample's data as specified by the given options. */
    allocationSize(options) {
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (!Number.isInteger(options.planeIndex) || options.planeIndex < 0) {
            throw new TypeError('planeIndex must be a non-negative integer.');
        }
        if (options.format !== undefined && !AUDIO_SAMPLE_FORMATS.has(options.format)) {
            throw new TypeError('Invalid format.');
        }
        if (options.frameOffset !== undefined && (!Number.isInteger(options.frameOffset) || options.frameOffset < 0)) {
            throw new TypeError('frameOffset must be a non-negative integer.');
        }
        if (options.frameCount !== undefined && (!Number.isInteger(options.frameCount) || options.frameCount < 0)) {
            throw new TypeError('frameCount must be a non-negative integer.');
        }
        if (this._closed) {
            throw new Error('AudioSample is closed.');
        }
        const destFormat = options.format ?? this.format;
        const frameOffset = options.frameOffset ?? 0;
        if (frameOffset >= this.numberOfFrames) {
            throw new RangeError('frameOffset out of range');
        }
        const copyFrameCount = options.frameCount !== undefined ? options.frameCount : (this.numberOfFrames - frameOffset);
        if (copyFrameCount > (this.numberOfFrames - frameOffset)) {
            throw new RangeError('frameCount out of range');
        }
        const bytesPerSample = getBytesPerSample(destFormat);
        const isPlanar = formatIsPlanar(destFormat);
        if (isPlanar && options.planeIndex >= this.numberOfChannels) {
            throw new RangeError('planeIndex out of range');
        }
        if (!isPlanar && options.planeIndex !== 0) {
            throw new RangeError('planeIndex out of range');
        }
        const elementCount = isPlanar ? copyFrameCount : copyFrameCount * this.numberOfChannels;
        return elementCount * bytesPerSample;
    }
    /** Copies the audio sample's data to an ArrayBuffer or ArrayBufferView as specified by the given options. */
    copyTo(destination, options) {
        if (!(0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .isAllowSharedBufferSource */ .SM)(destination)) {
            throw new TypeError('destination must be an ArrayBuffer or an ArrayBuffer view.');
        }
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (!Number.isInteger(options.planeIndex) || options.planeIndex < 0) {
            throw new TypeError('planeIndex must be a non-negative integer.');
        }
        if (options.format !== undefined && !AUDIO_SAMPLE_FORMATS.has(options.format)) {
            throw new TypeError('Invalid format.');
        }
        if (options.frameOffset !== undefined && (!Number.isInteger(options.frameOffset) || options.frameOffset < 0)) {
            throw new TypeError('frameOffset must be a non-negative integer.');
        }
        if (options.frameCount !== undefined && (!Number.isInteger(options.frameCount) || options.frameCount < 0)) {
            throw new TypeError('frameCount must be a non-negative integer.');
        }
        if (this._closed) {
            throw new Error('AudioSample is closed.');
        }
        const { planeIndex, format, frameCount: optFrameCount, frameOffset: optFrameOffset } = options;
        const srcFormat = this.format;
        const destFormat = format ?? this.format;
        if (!destFormat)
            throw new Error('Destination format not determined');
        const numFrames = this.numberOfFrames;
        const numChannels = this.numberOfChannels;
        const frameOffset = optFrameOffset ?? 0;
        if (frameOffset >= numFrames) {
            throw new RangeError('frameOffset out of range');
        }
        const copyFrameCount = optFrameCount !== undefined ? optFrameCount : (numFrames - frameOffset);
        if (copyFrameCount > (numFrames - frameOffset)) {
            throw new RangeError('frameCount out of range');
        }
        const destBytesPerSample = getBytesPerSample(destFormat);
        const destIsPlanar = formatIsPlanar(destFormat);
        if (destIsPlanar && planeIndex >= numChannels) {
            throw new RangeError('planeIndex out of range');
        }
        if (!destIsPlanar && planeIndex !== 0) {
            throw new RangeError('planeIndex out of range');
        }
        const destElementCount = destIsPlanar ? copyFrameCount : copyFrameCount * numChannels;
        const requiredSize = destElementCount * destBytesPerSample;
        if (destination.byteLength < requiredSize) {
            throw new RangeError('Destination buffer is too small');
        }
        const destView = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(destination);
        const writeFn = getWriteFunction(destFormat);
        if (isAudioData(this._data)) {
            if ((0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .isWebKit */ .Tc)() && numChannels > 2 && destFormat !== srcFormat) {
                // WebKit bug workaround
                doAudioDataCopyToWebKitWorkaround(this._data, destView, srcFormat, destFormat, numChannels, planeIndex, frameOffset, copyFrameCount);
            }
            else {
                // Per spec, only f32-planar conversion must be supported, but in practice, all browsers support all
                // destination formats, so let's just delegate here:
                this._data.copyTo(destination, {
                    planeIndex,
                    frameOffset,
                    frameCount: copyFrameCount,
                    format: destFormat,
                });
            }
        }
        else {
            const uint8Data = this._data;
            const srcView = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(uint8Data);
            const readFn = getReadFunction(srcFormat);
            const srcBytesPerSample = getBytesPerSample(srcFormat);
            const srcIsPlanar = formatIsPlanar(srcFormat);
            for (let i = 0; i < copyFrameCount; i++) {
                if (destIsPlanar) {
                    const destOffset = i * destBytesPerSample;
                    let srcOffset;
                    if (srcIsPlanar) {
                        srcOffset = (planeIndex * numFrames + (i + frameOffset)) * srcBytesPerSample;
                    }
                    else {
                        srcOffset = (((i + frameOffset) * numChannels) + planeIndex) * srcBytesPerSample;
                    }
                    const normalized = readFn(srcView, srcOffset);
                    writeFn(destView, destOffset, normalized);
                }
                else {
                    for (let ch = 0; ch < numChannels; ch++) {
                        const destIndex = i * numChannels + ch;
                        const destOffset = destIndex * destBytesPerSample;
                        let srcOffset;
                        if (srcIsPlanar) {
                            srcOffset = (ch * numFrames + (i + frameOffset)) * srcBytesPerSample;
                        }
                        else {
                            srcOffset = (((i + frameOffset) * numChannels) + ch) * srcBytesPerSample;
                        }
                        const normalized = readFn(srcView, srcOffset);
                        writeFn(destView, destOffset, normalized);
                    }
                }
            }
        }
    }
    /** Clones this audio sample. */
    clone() {
        if (this._closed) {
            throw new Error('AudioSample is closed.');
        }
        if (isAudioData(this._data)) {
            const sample = new AudioSample(this._data.clone());
            sample.setTimestamp(this.timestamp); // Make sure the timestamp is precise (beyond microsecond accuracy)
            return sample;
        }
        else {
            return new AudioSample({
                format: this.format,
                sampleRate: this.sampleRate,
                numberOfFrames: this.numberOfFrames,
                numberOfChannels: this.numberOfChannels,
                timestamp: this.timestamp,
                data: this._data,
            });
        }
    }
    /**
     * Closes this audio sample, releasing held resources. Audio samples should be closed as soon as they are not
     * needed anymore.
     */
    close() {
        if (this._closed) {
            return;
        }
        finalizationRegistry?.unregister(this);
        if (isAudioData(this._data)) {
            this._data.close();
        }
        else {
            this._data = new Uint8Array(0);
        }
        this._closed = true;
    }
    /**
     * Converts this audio sample to an AudioData for use with the WebCodecs API. The AudioData returned by this
     * method *must* be closed separately from this audio sample.
     */
    toAudioData() {
        if (this._closed) {
            throw new Error('AudioSample is closed.');
        }
        if (isAudioData(this._data)) {
            if (this._data.timestamp === this.microsecondTimestamp) {
                // Timestamp matches, let's just return the data (but cloned)
                return this._data.clone();
            }
            else {
                // It's impossible to simply change an AudioData's timestamp, so we'll need to create a new one
                if (formatIsPlanar(this.format)) {
                    const size = this.allocationSize({ planeIndex: 0, format: this.format });
                    const data = new ArrayBuffer(size * this.numberOfChannels);
                    // We gotta read out each plane individually
                    for (let i = 0; i < this.numberOfChannels; i++) {
                        this.copyTo(new Uint8Array(data, i * size, size), { planeIndex: i, format: this.format });
                    }
                    return new AudioData({
                        format: this.format,
                        sampleRate: this.sampleRate,
                        numberOfFrames: this.numberOfFrames,
                        numberOfChannels: this.numberOfChannels,
                        timestamp: this.microsecondTimestamp,
                        data,
                    });
                }
                else {
                    const data = new ArrayBuffer(this.allocationSize({ planeIndex: 0, format: this.format }));
                    this.copyTo(data, { planeIndex: 0, format: this.format });
                    return new AudioData({
                        format: this.format,
                        sampleRate: this.sampleRate,
                        numberOfFrames: this.numberOfFrames,
                        numberOfChannels: this.numberOfChannels,
                        timestamp: this.microsecondTimestamp,
                        data,
                    });
                }
            }
        }
        else {
            return new AudioData({
                format: this.format,
                sampleRate: this.sampleRate,
                numberOfFrames: this.numberOfFrames,
                numberOfChannels: this.numberOfChannels,
                timestamp: this.microsecondTimestamp,
                data: this._data.buffer instanceof ArrayBuffer
                    ? this._data.buffer
                    : this._data.slice(), // In the case of SharedArrayBuffer, convert to ArrayBuffer
            });
        }
    }
    /** Convert this audio sample to an AudioBuffer for use with the Web Audio API. */
    toAudioBuffer() {
        if (this._closed) {
            throw new Error('AudioSample is closed.');
        }
        const audioBuffer = new AudioBuffer({
            numberOfChannels: this.numberOfChannels,
            length: this.numberOfFrames,
            sampleRate: this.sampleRate,
        });
        const dataBytes = new Float32Array(this.allocationSize({ planeIndex: 0, format: 'f32-planar' }) / 4);
        for (let i = 0; i < this.numberOfChannels; i++) {
            this.copyTo(dataBytes, { planeIndex: i, format: 'f32-planar' });
            audioBuffer.copyToChannel(dataBytes, i);
        }
        return audioBuffer;
    }
    /** Sets the presentation timestamp of this audio sample, in seconds. */
    setTimestamp(newTimestamp) {
        if (!Number.isFinite(newTimestamp)) {
            throw new TypeError('newTimestamp must be a number.');
        }
        // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
        this.timestamp = newTimestamp;
    }
    /** Calls `.close()`. */
    [Symbol.dispose]() {
        this.close();
    }
    /** @internal */
    static *_fromAudioBuffer(audioBuffer, timestamp) {
        if (!(audioBuffer instanceof AudioBuffer)) {
            throw new TypeError('audioBuffer must be an AudioBuffer.');
        }
        const MAX_FLOAT_COUNT = 48000 * 5; // 5 seconds of mono 48 kHz audio per sample
        const numberOfChannels = audioBuffer.numberOfChannels;
        const sampleRate = audioBuffer.sampleRate;
        const totalFrames = audioBuffer.length;
        const maxFramesPerChunk = Math.floor(MAX_FLOAT_COUNT / numberOfChannels);
        let currentRelativeFrame = 0;
        let remainingFrames = totalFrames;
        // Create AudioSamples in a chunked fashion so we don't create huge Float32Arrays
        while (remainingFrames > 0) {
            const framesToCopy = Math.min(maxFramesPerChunk, remainingFrames);
            const chunkData = new Float32Array(numberOfChannels * framesToCopy);
            for (let channel = 0; channel < numberOfChannels; channel++) {
                audioBuffer.copyFromChannel(chunkData.subarray(channel * framesToCopy, (channel + 1) * framesToCopy), channel, currentRelativeFrame);
            }
            yield new AudioSample({
                format: 'f32-planar',
                sampleRate,
                numberOfFrames: framesToCopy,
                numberOfChannels,
                timestamp: timestamp + currentRelativeFrame / sampleRate,
                data: chunkData,
            });
            currentRelativeFrame += framesToCopy;
            remainingFrames -= framesToCopy;
        }
    }
    /**
     * Creates AudioSamples from an AudioBuffer, starting at the given timestamp in seconds. Typically creates exactly
     * one sample, but may create multiple if the AudioBuffer is exceedingly large.
     */
    static fromAudioBuffer(audioBuffer, timestamp) {
        if (!(audioBuffer instanceof AudioBuffer)) {
            throw new TypeError('audioBuffer must be an AudioBuffer.');
        }
        const MAX_FLOAT_COUNT = 48000 * 5; // 5 seconds of mono 48 kHz audio per sample
        const numberOfChannels = audioBuffer.numberOfChannels;
        const sampleRate = audioBuffer.sampleRate;
        const totalFrames = audioBuffer.length;
        const maxFramesPerChunk = Math.floor(MAX_FLOAT_COUNT / numberOfChannels);
        let currentRelativeFrame = 0;
        let remainingFrames = totalFrames;
        const result = [];
        // Create AudioSamples in a chunked fashion so we don't create huge Float32Arrays
        while (remainingFrames > 0) {
            const framesToCopy = Math.min(maxFramesPerChunk, remainingFrames);
            const chunkData = new Float32Array(numberOfChannels * framesToCopy);
            for (let channel = 0; channel < numberOfChannels; channel++) {
                audioBuffer.copyFromChannel(chunkData.subarray(channel * framesToCopy, (channel + 1) * framesToCopy), channel, currentRelativeFrame);
            }
            const audioSample = new AudioSample({
                format: 'f32-planar',
                sampleRate,
                numberOfFrames: framesToCopy,
                numberOfChannels,
                timestamp: timestamp + currentRelativeFrame / sampleRate,
                data: chunkData,
            });
            result.push(audioSample);
            currentRelativeFrame += framesToCopy;
            remainingFrames -= framesToCopy;
        }
        return result;
    }
}
const getBytesPerSample = (format) => {
    switch (format) {
        case 'u8':
        case 'u8-planar':
            return 1;
        case 's16':
        case 's16-planar':
            return 2;
        case 's32':
        case 's32-planar':
            return 4;
        case 'f32':
        case 'f32-planar':
            return 4;
        default:
            throw new Error('Unknown AudioSampleFormat');
    }
};
const formatIsPlanar = (format) => {
    switch (format) {
        case 'u8-planar':
        case 's16-planar':
        case 's32-planar':
        case 'f32-planar':
            return true;
        default:
            return false;
    }
};
const getReadFunction = (format) => {
    switch (format) {
        case 'u8':
        case 'u8-planar':
            return (view, offset) => (view.getUint8(offset) - 128) / 128;
        case 's16':
        case 's16-planar':
            return (view, offset) => view.getInt16(offset, true) / 32768;
        case 's32':
        case 's32-planar':
            return (view, offset) => view.getInt32(offset, true) / 2147483648;
        case 'f32':
        case 'f32-planar':
            return (view, offset) => view.getFloat32(offset, true);
    }
};
const getWriteFunction = (format) => {
    switch (format) {
        case 'u8':
        case 'u8-planar':
            return (view, offset, value) => view.setUint8(offset, (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .clamp */ .qE)((value + 1) * 127.5, 0, 255));
        case 's16':
        case 's16-planar':
            return (view, offset, value) => view.setInt16(offset, (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .clamp */ .qE)(Math.round(value * 32767), -32768, 32767), true);
        case 's32':
        case 's32-planar':
            return (view, offset, value) => view.setInt32(offset, (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .clamp */ .qE)(Math.round(value * 2147483647), -2147483648, 2147483647), true);
        case 'f32':
        case 'f32-planar':
            return (view, offset, value) => view.setFloat32(offset, value, true);
    }
};
const isAudioData = (x) => {
    return typeof AudioData !== 'undefined' && x instanceof AudioData;
};
/**
 * WebKit has a bug where calling AudioData.copyTo with a format different from the source format
 * crashes the tab when there are more than 2 channels. This function works around that by always
 * copying with the source format and then manually converting to the destination format.
 *
 * See https://bugs.webkit.org/show_bug.cgi?id=302521.
 */
const doAudioDataCopyToWebKitWorkaround = (audioData, destView, srcFormat, destFormat, numChannels, planeIndex, frameOffset, copyFrameCount) => {
    const readFn = getReadFunction(srcFormat);
    const writeFn = getWriteFunction(destFormat);
    const srcBytesPerSample = getBytesPerSample(srcFormat);
    const destBytesPerSample = getBytesPerSample(destFormat);
    const srcIsPlanar = formatIsPlanar(srcFormat);
    const destIsPlanar = formatIsPlanar(destFormat);
    if (destIsPlanar) {
        if (srcIsPlanar) {
            // src planar -> dest planar: copy single plane and convert
            const data = new ArrayBuffer(copyFrameCount * srcBytesPerSample);
            const dataView = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(data);
            audioData.copyTo(data, {
                planeIndex,
                frameOffset,
                frameCount: copyFrameCount,
                format: srcFormat,
            });
            for (let i = 0; i < copyFrameCount; i++) {
                const srcOffset = i * srcBytesPerSample;
                const destOffset = i * destBytesPerSample;
                const sample = readFn(dataView, srcOffset);
                writeFn(destView, destOffset, sample);
            }
        }
        else {
            // src interleaved -> dest planar: copy all interleaved data, extract one channel
            const data = new ArrayBuffer(copyFrameCount * numChannels * srcBytesPerSample);
            const dataView = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(data);
            audioData.copyTo(data, {
                planeIndex: 0,
                frameOffset,
                frameCount: copyFrameCount,
                format: srcFormat,
            });
            for (let i = 0; i < copyFrameCount; i++) {
                const srcOffset = (i * numChannels + planeIndex) * srcBytesPerSample;
                const destOffset = i * destBytesPerSample;
                const sample = readFn(dataView, srcOffset);
                writeFn(destView, destOffset, sample);
            }
        }
    }
    else {
        if (srcIsPlanar) {
            // src planar -> dest interleaved: copy each plane and interleave
            const planeSize = copyFrameCount * srcBytesPerSample;
            const data = new ArrayBuffer(planeSize);
            const dataView = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(data);
            for (let ch = 0; ch < numChannels; ch++) {
                audioData.copyTo(data, {
                    planeIndex: ch,
                    frameOffset,
                    frameCount: copyFrameCount,
                    format: srcFormat,
                });
                for (let i = 0; i < copyFrameCount; i++) {
                    const srcOffset = i * srcBytesPerSample;
                    const destOffset = (i * numChannels + ch) * destBytesPerSample;
                    const sample = readFn(dataView, srcOffset);
                    writeFn(destView, destOffset, sample);
                }
            }
        }
        else {
            // src interleaved -> dest interleaved: copy all and convert
            const data = new ArrayBuffer(copyFrameCount * numChannels * srcBytesPerSample);
            const dataView = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(data);
            audioData.copyTo(data, {
                planeIndex: 0,
                frameOffset,
                frameCount: copyFrameCount,
                format: srcFormat,
            });
            for (let i = 0; i < copyFrameCount; i++) {
                for (let ch = 0; ch < numChannels; ch++) {
                    const idx = i * numChannels + ch;
                    const srcOffset = idx * srcBytesPerSample;
                    const destOffset = idx * destBytesPerSample;
                    const sample = readFn(dataView, srcOffset);
                    writeFn(destView, destOffset, sample);
                }
            }
        }
    }
};


/***/ },

/***/ 4709
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
var _node_js__WEBPACK_IMPORTED_MODULE_1___namespace_cache;
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Ts: () => (/* binding */ UrlSource),
/* harmony export */   kL: () => (/* binding */ Source)
/* harmony export */ });
/* unused harmony exports BufferSource, BlobSource, FilePathSource, StreamSource, ReadableStreamSource */
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3912);
/* harmony import */ var _node_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1845);
/* harmony import */ var _input_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(2030);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */



const node = typeof /*#__PURE__*/ (_node_js__WEBPACK_IMPORTED_MODULE_1___namespace_cache || (_node_js__WEBPACK_IMPORTED_MODULE_1___namespace_cache = __webpack_require__.t(_node_js__WEBPACK_IMPORTED_MODULE_1__, 2))) !== 'undefined'
    ? /*#__PURE__*/ (_node_js__WEBPACK_IMPORTED_MODULE_1___namespace_cache || (_node_js__WEBPACK_IMPORTED_MODULE_1___namespace_cache = __webpack_require__.t(_node_js__WEBPACK_IMPORTED_MODULE_1__, 2))) // Aliasing it prevents some bundler warnings
    : undefined;
/**
 * The source base class, representing a resource from which bytes can be read.
 * @group Input sources
 * @public
 */
class Source {
    constructor() {
        /** @internal */
        this._disposed = false;
        /** @internal */
        this._sizePromise = null;
        /** Called each time data is retrieved from the source. Will be called with the retrieved range (end exclusive). */
        this.onread = null;
    }
    /**
     * Resolves with the total size of the file in bytes. This function is memoized, meaning only the first call
     * will retrieve the size.
     *
     * Returns null if the source is unsized.
     */
    async getSizeOrNull() {
        if (this._disposed) {
            throw new _input_js__WEBPACK_IMPORTED_MODULE_2__/* .InputDisposedError */ .Q();
        }
        return this._sizePromise ??= Promise.resolve(this._retrieveSize());
    }
    /**
     * Resolves with the total size of the file in bytes. This function is memoized, meaning only the first call
     * will retrieve the size.
     *
     * Throws an error if the source is unsized.
     */
    async getSize() {
        if (this._disposed) {
            throw new _input_js__WEBPACK_IMPORTED_MODULE_2__/* .InputDisposedError */ .Q();
        }
        const result = await this.getSizeOrNull();
        if (result === null) {
            throw new Error('Cannot determine the size of an unsized source.');
        }
        return result;
    }
}
/**
 * A source backed by an ArrayBuffer or ArrayBufferView, with the entire file held in memory.
 * @group Input sources
 * @public
 */
class BufferSource extends Source {
    /**
     * Creates a new {@link BufferSource} backed by the specified `ArrayBuffer`, `SharedArrayBuffer`,
     * or `ArrayBufferView`.
     */
    constructor(buffer) {
        if (!(buffer instanceof ArrayBuffer)
            && !(typeof SharedArrayBuffer !== 'undefined' && buffer instanceof SharedArrayBuffer)
            && !ArrayBuffer.isView(buffer)) {
            throw new TypeError('buffer must be an ArrayBuffer, SharedArrayBuffer, or ArrayBufferView.');
        }
        super();
        /** @internal */
        this._onreadCalled = false;
        this._bytes = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toUint8Array */ .Fo)(buffer);
        this._view = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(buffer);
    }
    /** @internal */
    _retrieveSize() {
        return this._bytes.byteLength;
    }
    /** @internal */
    _read() {
        if (!this._onreadCalled) {
            // We just say the first read retrives all bytes from the source (which, I mean, it does)
            this.onread?.(0, this._bytes.byteLength);
            this._onreadCalled = true;
        }
        return {
            bytes: this._bytes,
            view: this._view,
            offset: 0,
        };
    }
    /** @internal */
    _dispose() { }
}
/**
 * A source backed by a [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob). Since a
 * [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) is also a `Blob`, this is the source to use when
 * reading files off the disk.
 * @group Input sources
 * @public
 */
class BlobSource extends Source {
    /**
     * Creates a new {@link BlobSource} backed by the specified
     * [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob).
     */
    constructor(blob, options = {}) {
        if (!(blob instanceof Blob)) {
            throw new TypeError('blob must be a Blob.');
        }
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (options.maxCacheSize !== undefined
            && (!(0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .isNumber */ .Et)(options.maxCacheSize) || options.maxCacheSize < 0)) {
            throw new TypeError('options.maxCacheSize, when provided, must be a non-negative number.');
        }
        super();
        /** @internal */
        this._readers = new WeakMap();
        this._blob = blob;
        this._orchestrator = new ReadOrchestrator({
            maxCacheSize: options.maxCacheSize ?? (8 * 2 ** 20 /* 8 MiB */),
            maxWorkerCount: 4,
            runWorker: this._runWorker.bind(this),
            prefetchProfile: PREFETCH_PROFILES.fileSystem,
        });
    }
    /** @internal */
    _retrieveSize() {
        const size = this._blob.size;
        this._orchestrator.fileSize = size;
        return size;
    }
    /** @internal */
    _read(start, end) {
        return this._orchestrator.read(start, end);
    }
    /** @internal */
    async _runWorker(worker) {
        let reader = this._readers.get(worker);
        if (reader === undefined) {
            // https://github.com/Vanilagy/mediabunny/issues/184
            // WebKit has critical bugs with blob.stream():
            // - WebKitBlobResource error 1 when streaming large files
            // - Memory buildup and reload loops on iOS (network process crashes)
            // - ReadableStream stalls under backpressure (especially video)
            // Affects Safari and all iOS browsers (Chrome, Firefox, etc.).
            // Use arrayBuffer() fallback for WebKit browsers.
            if ('stream' in this._blob && !(0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .isWebKit */ .Tc)()) {
                // Get a reader of the blob starting at the required offset, and then keep it around
                const slice = this._blob.slice(worker.currentPos);
                reader = slice.stream().getReader();
            }
            else {
                // We'll need to use more primitive ways
                reader = null;
            }
            this._readers.set(worker, reader);
        }
        while (worker.currentPos < worker.targetPos && !worker.aborted) {
            if (reader) {
                const { done, value } = await reader.read();
                if (done) {
                    this._orchestrator.forgetWorker(worker);
                    throw new Error('Blob reader stopped unexpectedly before all requested data was read.');
                }
                if (worker.aborted) {
                    break;
                }
                this.onread?.(worker.currentPos, worker.currentPos + value.length);
                this._orchestrator.supplyWorkerData(worker, value);
            }
            else {
                const data = await this._blob.slice(worker.currentPos, worker.targetPos).arrayBuffer();
                if (worker.aborted) {
                    break;
                }
                this.onread?.(worker.currentPos, worker.currentPos + data.byteLength);
                this._orchestrator.supplyWorkerData(worker, new Uint8Array(data));
            }
        }
        worker.running = false;
        if (worker.aborted) {
            // MDN: "Calling this method signals a loss of interest in the stream by a consumer."
            await reader?.cancel();
        }
    }
    /** @internal */
    _dispose() {
        this._orchestrator.dispose();
    }
}
const URL_SOURCE_MIN_LOAD_AMOUNT = 0.5 * 2 ** 20; // 0.5 MiB
const DEFAULT_RETRY_DELAY = ((previousAttempts, error, src) => {
    // Check if this could be a CORS error. If so, we cannot recover from it and
    // should not attempt to retry.
    // CORS errors are intentionally not opaque, so we need to rely on heuristics.
    const couldBeCorsError = error instanceof Error && (error.message.includes('Failed to fetch') // Chrome
        || error.message.includes('Load failed') // Safari
        || error.message.includes('NetworkError when attempting to fetch resource') // Firefox
    );
    if (couldBeCorsError) {
        let originOfSrc = null;
        // Checking if the origin is different, because only then a CORS error could originate
        try {
            if (typeof window !== 'undefined' && typeof window.location !== 'undefined') {
                originOfSrc = new URL(src instanceof Request ? src.url : src, window.location.href).origin;
            }
        }
        catch {
            // URL parse failed
        }
        // If user is offline, it is probably not a CORS error.
        const isOnline = typeof navigator !== 'undefined' && typeof navigator.onLine === 'boolean' ? navigator.onLine : true;
        if (isOnline && originOfSrc !== null && originOfSrc !== window.location.origin) {
            console.warn(`Request will not be retried because a CORS error was suspected due to different origins. You can`
                + ` modify this behavior by providing your own function for the 'getRetryDelay' option.`);
            return null;
        }
    }
    return Math.min(2 ** (previousAttempts - 2), 16);
});
/**
 * A source backed by a URL. This is useful for reading data from the network. Requests will be made using an optimized
 * reading and prefetching pattern to minimize request count and latency.
 * @group Input sources
 * @public
 */
class UrlSource extends Source {
    /**
     * Creates a new {@link UrlSource} backed by the resource at the specified URL.
     *
     * When passing a `Request` instance, note that the `signal` and `headers.Range` options will be overridden by
     * Mediabunny. If you want to cancel ongoing requests, use {@link Input.dispose}.
     */
    constructor(url, options = {}) {
        if (typeof url !== 'string'
            && !(url instanceof URL)
            && !(typeof Request !== 'undefined' && url instanceof Request)) {
            throw new TypeError('url must be a string, URL or Request.');
        }
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (options.requestInit !== undefined && (!options.requestInit || typeof options.requestInit !== 'object')) {
            throw new TypeError('options.requestInit, when provided, must be an object.');
        }
        if (options.getRetryDelay !== undefined && typeof options.getRetryDelay !== 'function') {
            throw new TypeError('options.getRetryDelay, when provided, must be a function.');
        }
        if (options.maxCacheSize !== undefined
            && (!(0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .isNumber */ .Et)(options.maxCacheSize) || options.maxCacheSize < 0)) {
            throw new TypeError('options.maxCacheSize, when provided, must be a non-negative number.');
        }
        if (options.parallelism !== undefined && (!Number.isInteger(options.parallelism) || options.parallelism < 1)) {
            throw new TypeError('options.parallelism, when provided, must be a positive number.');
        }
        if (options.fetchFn !== undefined && typeof options.fetchFn !== 'function') {
            throw new TypeError('options.fetchFn, when provided, must be a function.');
            // Won't bother validating this function beyond this
        }
        super();
        /** @internal */
        this._existingResponses = new WeakMap();
        this._url = url;
        this._options = options;
        this._getRetryDelay = options.getRetryDelay ?? DEFAULT_RETRY_DELAY;
        // Most files in the real-world have a single sequential access pattern, but having two in parallel can
        // also happen
        const DEFAULT_PARALLELISM = 2;
        this._orchestrator = new ReadOrchestrator({
            maxCacheSize: options.maxCacheSize ?? (64 * 2 ** 20 /* 64 MiB */),
            maxWorkerCount: options.parallelism ?? DEFAULT_PARALLELISM,
            runWorker: this._runWorker.bind(this),
            prefetchProfile: PREFETCH_PROFILES.network,
        });
    }
    /** @internal */
    async _retrieveSize() {
        // Retrieving the resource size for UrlSource is optimized: Almost always (= always), the first bytes we have to
        // read are the start of the file. This means it's smart to combine size fetching with fetching the start of the
        // file. We additionally use this step to probe if the server supports range requests, killing three birds with
        // one stone.
        const abortController = new AbortController();
        const response = await (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .retriedFetch */ .G8)(this._options.fetchFn ?? fetch, this._url, (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .mergeRequestInit */ ._h)(this._options.requestInit ?? {}, {
            headers: {
                // We could also send a non-range request to request the same bytes (all of them), but doing it like
                // this is an easy way to check if the server supports range requests in the first place
                Range: 'bytes=0-',
            },
            signal: abortController.signal,
        }), this._getRetryDelay, () => this._disposed);
        if (!response.ok) {
            // eslint-disable-next-line @typescript-eslint/no-base-to-string
            throw new Error(`Error fetching ${String(this._url)}: ${response.status} ${response.statusText}`);
        }
        let worker;
        let fileSize;
        if (response.status === 206) {
            fileSize = this._getTotalLengthFromRangeResponse(response);
            worker = this._orchestrator.createWorker(0, Math.min(fileSize, URL_SOURCE_MIN_LOAD_AMOUNT));
        }
        else {
            // Server probably returned a 200.
            const contentLength = response.headers.get('Content-Length');
            if (contentLength) {
                fileSize = Number(contentLength);
                worker = this._orchestrator.createWorker(0, fileSize);
                this._orchestrator.options.maxCacheSize = Infinity; // 🤷
                console.warn('HTTP server did not respond with 206 Partial Content, meaning the entire remote resource now has'
                    + ' to be downloaded. For efficient media file streaming across a network, please make sure your'
                    + ' server supports range requests.');
            }
            else {
                throw new Error(`HTTP response (status ${response.status}) must surface Content-Length header.`);
            }
        }
        this._orchestrator.fileSize = fileSize;
        this._existingResponses.set(worker, { response, abortController });
        this._orchestrator.runWorker(worker);
        return fileSize;
    }
    /** @internal */
    _read(start, end) {
        return this._orchestrator.read(start, end);
    }
    /** @internal */
    async _runWorker(worker) {
        // The outer loop is for resuming a request if it dies mid-response
        while (true) {
            const existing = this._existingResponses.get(worker);
            this._existingResponses.delete(worker);
            let abortController = existing?.abortController;
            let response = existing?.response;
            if (!abortController) {
                abortController = new AbortController();
                response = await (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .retriedFetch */ .G8)(this._options.fetchFn ?? fetch, this._url, (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .mergeRequestInit */ ._h)(this._options.requestInit ?? {}, {
                    headers: {
                        Range: `bytes=${worker.currentPos}-`,
                    },
                    signal: abortController.signal,
                }), this._getRetryDelay, () => this._disposed);
            }
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(response);
            if (!response.ok) {
                // eslint-disable-next-line @typescript-eslint/no-base-to-string
                throw new Error(`Error fetching ${String(this._url)}: ${response.status} ${response.statusText}`);
            }
            if (worker.currentPos > 0 && response.status !== 206) {
                throw new Error('HTTP server did not respond with 206 Partial Content to a range request. To enable efficient media'
                    + ' file streaming across a network, please make sure your server supports range requests.');
            }
            if (!response.body) {
                throw new Error('Missing HTTP response body stream. The used fetch function must provide the response body as a'
                    + ' ReadableStream.');
            }
            const reader = response.body.getReader();
            while (true) {
                if (worker.currentPos >= worker.targetPos || worker.aborted) {
                    abortController.abort();
                    worker.running = false;
                    return;
                }
                let readResult;
                try {
                    readResult = await reader.read();
                }
                catch (error) {
                    if (this._disposed) {
                        // No need to try to retry
                        throw error;
                    }
                    const retryDelayInSeconds = this._getRetryDelay(1, error, this._url);
                    if (retryDelayInSeconds !== null) {
                        console.error('Error while reading response stream. Attempting to resume.', error);
                        await new Promise(resolve => setTimeout(resolve, 1000 * retryDelayInSeconds));
                        break;
                    }
                    else {
                        throw error;
                    }
                }
                if (worker.aborted) {
                    continue; // Cleanup happens in next iteration
                }
                const { done, value } = readResult;
                if (done) {
                    if (worker.currentPos >= worker.targetPos) {
                        // All data was delivered, we're good
                        this._orchestrator.forgetWorker(worker);
                        worker.running = false;
                        return;
                    }
                    // The response stopped early, before the target. This can happen if server decides to cap range
                    // requests arbitrarily, even if the request had an uncapped end. In this case, let's fetch the rest
                    // of the data using a new request.
                    break;
                }
                this.onread?.(worker.currentPos, worker.currentPos + value.length);
                this._orchestrator.supplyWorkerData(worker, value);
            }
        }
        // The previous UrlSource had logic for circumventing https://issues.chromium.org/issues/436025873; I haven't
        // been able to observe this bug with the new UrlSource (maybe because we're using response streaming), so the
        // logic for that has vanished for now. Leaving a comment here if this becomes relevant again.
    }
    /** @internal */
    _getTotalLengthFromRangeResponse(response) {
        const contentRange = response.headers.get('Content-Range');
        if (contentRange) {
            const match = /\/(\d+)/.exec(contentRange);
            if (match) {
                return Number(match[1]);
            }
        }
        const contentLength = response.headers.get('Content-Length');
        if (contentLength) {
            return Number(contentLength);
        }
        else {
            throw new Error('Partial HTTP response (status 206) must surface either Content-Range or'
                + ' Content-Length header.');
        }
    }
    /** @internal */
    _dispose() {
        this._orchestrator.dispose();
    }
}
/**
 * A source backed by a path to a file. Intended for server-side usage in Node, Bun, or Deno.
 *
 * Make sure to call `.dispose()` on the corresponding {@link Input} when done to explicitly free the internal file
 * handle acquired by this source.
 * @group Input sources
 * @public
 */
class FilePathSource extends Source {
    /** Creates a new {@link FilePathSource} backed by the file at the specified file path. */
    constructor(filePath, options = {}) {
        if (typeof filePath !== 'string') {
            throw new TypeError('filePath must be a string.');
        }
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (options.maxCacheSize !== undefined
            && (!(0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .isNumber */ .Et)(options.maxCacheSize) || options.maxCacheSize < 0)) {
            throw new TypeError('options.maxCacheSize, when provided, must be a non-negative number.');
        }
        super();
        /** @internal */
        this._fileHandle = null;
        // Let's back this source with a StreamSource, makes the implementation very simple
        this._streamSource = new StreamSource({
            getSize: async () => {
                this._fileHandle = await node.fs.open(filePath, 'r');
                const stats = await this._fileHandle.stat();
                return stats.size;
            },
            read: async (start, end) => {
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(this._fileHandle);
                const buffer = new Uint8Array(end - start);
                await this._fileHandle.read(buffer, 0, end - start, start);
                return buffer;
            },
            maxCacheSize: options.maxCacheSize,
            prefetchProfile: 'fileSystem',
        });
    }
    /** @internal */
    _read(start, end) {
        return this._streamSource._read(start, end);
    }
    /** @internal */
    _retrieveSize() {
        return this._streamSource._retrieveSize();
    }
    /** @internal */
    _dispose() {
        this._streamSource._dispose();
        void this._fileHandle?.close();
        this._fileHandle = null;
    }
}
/**
 * A general-purpose, callback-driven source that can get its data from anywhere.
 * @group Input sources
 * @public
 */
class StreamSource extends Source {
    /** Creates a new {@link StreamSource} whose behavior is specified by `options`.  */
    constructor(options) {
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (typeof options.getSize !== 'function') {
            throw new TypeError('options.getSize must be a function.');
        }
        if (typeof options.read !== 'function') {
            throw new TypeError('options.read must be a function.');
        }
        if (options.dispose !== undefined && typeof options.dispose !== 'function') {
            throw new TypeError('options.dispose, when provided, must be a function.');
        }
        if (options.maxCacheSize !== undefined
            && (!(0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .isNumber */ .Et)(options.maxCacheSize) || options.maxCacheSize < 0)) {
            throw new TypeError('options.maxCacheSize, when provided, must be a non-negative number.');
        }
        if (options.prefetchProfile && !['none', 'fileSystem', 'network'].includes(options.prefetchProfile)) {
            throw new TypeError('options.prefetchProfile, when provided, must be one of \'none\', \'fileSystem\' or \'network\'.');
        }
        super();
        this._options = options;
        this._orchestrator = new ReadOrchestrator({
            maxCacheSize: options.maxCacheSize ?? (8 * 2 ** 20 /* 8 MiB */),
            maxWorkerCount: 2, // Fixed for now, *should* be fine
            prefetchProfile: PREFETCH_PROFILES[options.prefetchProfile ?? 'none'],
            runWorker: this._runWorker.bind(this),
        });
    }
    /** @internal */
    _retrieveSize() {
        const result = this._options.getSize();
        if (result instanceof Promise) {
            return result.then((size) => {
                if (!Number.isInteger(size) || size < 0) {
                    throw new TypeError('options.getSize must return or resolve to a non-negative integer.');
                }
                this._orchestrator.fileSize = size;
                return size;
            });
        }
        else {
            if (!Number.isInteger(result) || result < 0) {
                throw new TypeError('options.getSize must return or resolve to a non-negative integer.');
            }
            this._orchestrator.fileSize = result;
            return result;
        }
    }
    /** @internal */
    _read(start, end) {
        return this._orchestrator.read(start, end);
    }
    /** @internal */
    async _runWorker(worker) {
        while (worker.currentPos < worker.targetPos && !worker.aborted) {
            const originalCurrentPos = worker.currentPos;
            const originalTargetPos = worker.targetPos;
            let data = this._options.read(worker.currentPos, originalTargetPos);
            if (data instanceof Promise)
                data = await data;
            if (worker.aborted) {
                break;
            }
            if (data instanceof Uint8Array) {
                data = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toUint8Array */ .Fo)(data); // Normalize things like Node.js Buffer to Uint8Array
                if (data.length !== originalTargetPos - worker.currentPos) {
                    // Yes, we're that strict
                    throw new Error(`options.read returned a Uint8Array with unexpected length: Requested ${originalTargetPos - worker.currentPos} bytes, but got ${data.length}.`);
                }
                this.onread?.(worker.currentPos, worker.currentPos + data.length);
                this._orchestrator.supplyWorkerData(worker, data);
            }
            else if (data instanceof ReadableStream) {
                const reader = data.getReader();
                while (worker.currentPos < originalTargetPos && !worker.aborted) {
                    const { done, value } = await reader.read();
                    if (done) {
                        if (worker.currentPos < originalTargetPos) {
                            // Yes, we're *that* strict
                            throw new Error(`ReadableStream returned by options.read ended before supplying enough data.`
                                + ` Requested ${originalTargetPos - originalCurrentPos} bytes, but got ${worker.currentPos - originalCurrentPos}`);
                        }
                        break;
                    }
                    if (!(value instanceof Uint8Array)) {
                        throw new TypeError('ReadableStream returned by options.read must yield Uint8Array chunks.');
                    }
                    if (worker.aborted) {
                        break;
                    }
                    const data = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toUint8Array */ .Fo)(value); // Normalize things like Node.js Buffer to Uint8Array
                    this.onread?.(worker.currentPos, worker.currentPos + data.length);
                    this._orchestrator.supplyWorkerData(worker, data);
                }
            }
            else {
                throw new TypeError('options.read must return or resolve to a Uint8Array or a ReadableStream.');
            }
        }
        worker.running = false;
    }
    /** @internal */
    _dispose() {
        this._orchestrator.dispose();
        this._options.dispose?.();
    }
}
/**
 * A source backed by a [`ReadableStream`](https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream) of
 * `Uint8Array`, representing an append-only byte stream of unknown length. This is the source to use for incrementally
 * streaming in input files that are still being constructed and whose size we don't yet know, like for example the
 * output chunks of [MediaRecorder](https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder).
 *
 * This source is *unsized*, meaning calls to `.getSize()` will throw and readers are more limited due to the
 * lack of random file access. You should only use this source with sequential access patterns, such as reading all
 * packets from start to end. This source does not work well with random access patterns unless you increase its
 * max cache size.
 *
 * @group Input sources
 * @public
 */
class ReadableStreamSource extends Source {
    /** Creates a new {@link ReadableStreamSource} backed by the specified `ReadableStream<Uint8Array>`. */
    constructor(stream, options = {}) {
        if (!(stream instanceof ReadableStream)) {
            throw new TypeError('stream must be a ReadableStream.');
        }
        if (!options || typeof options !== 'object') {
            throw new TypeError('options must be an object.');
        }
        if (options.maxCacheSize !== undefined
            && (!(0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .isNumber */ .Et)(options.maxCacheSize) || options.maxCacheSize < 0)) {
            throw new TypeError('options.maxCacheSize, when provided, must be a non-negative number.');
        }
        super();
        /** @internal */
        this._reader = null;
        /** @internal */
        this._cache = [];
        /** @internal */
        this._pendingSlices = [];
        /** @internal */
        this._currentIndex = 0;
        /** @internal */
        this._targetIndex = 0;
        /** @internal */
        this._maxRequestedIndex = 0;
        /** @internal */
        this._endIndex = null;
        /** @internal */
        this._pulling = false;
        this._stream = stream;
        this._maxCacheSize = options.maxCacheSize ?? (16 * 2 ** 20 /* 16 MiB */);
    }
    /** @internal */
    _retrieveSize() {
        return this._endIndex; // Starts out as null, meaning this source is unsized
    }
    /** @internal */
    _read(start, end) {
        if (this._endIndex !== null && end > this._endIndex) {
            return null;
        }
        this._maxRequestedIndex = Math.max(this._maxRequestedIndex, end);
        const cacheStartIndex = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .binarySearchLessOrEqual */ .eE)(this._cache, start, x => x.start);
        const cacheStartEntry = cacheStartIndex !== -1 ? this._cache[cacheStartIndex] : null;
        if (cacheStartEntry && cacheStartEntry.start <= start && end <= cacheStartEntry.end) {
            // The request can be satisfied with a single cache entry
            return {
                bytes: cacheStartEntry.bytes,
                view: cacheStartEntry.view,
                offset: cacheStartEntry.start,
            };
        }
        let lastEnd = start;
        const bytes = new Uint8Array(end - start);
        if (cacheStartIndex !== -1) {
            // Walk over the cache to see if we can satisfy the request using multiple cache entries
            for (let i = cacheStartIndex; i < this._cache.length; i++) {
                const cacheEntry = this._cache[i];
                if (cacheEntry.start >= end) {
                    break;
                }
                const cappedStart = Math.max(start, cacheEntry.start);
                if (cappedStart > lastEnd) {
                    // We're too far behind
                    this._throwDueToCacheMiss();
                }
                const cappedEnd = Math.min(end, cacheEntry.end);
                if (cappedStart < cappedEnd) {
                    bytes.set(cacheEntry.bytes.subarray(cappedStart - cacheEntry.start, cappedEnd - cacheEntry.start), cappedStart - start);
                    lastEnd = cappedEnd;
                }
            }
        }
        if (lastEnd === end) {
            return {
                bytes,
                view: (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(bytes),
                offset: start,
            };
        }
        // We need to pull more data
        if (this._currentIndex > lastEnd) {
            // We're too far behind
            this._throwDueToCacheMiss();
        }
        const { promise, resolve, reject } = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .promiseWithResolvers */ .nJ)();
        this._pendingSlices.push({
            start,
            end,
            bytes,
            resolve,
            reject,
        });
        this._targetIndex = Math.max(this._targetIndex, end);
        // Start pulling from the stream if we're not already doing it
        if (!this._pulling) {
            this._pulling = true;
            void this._pull()
                .catch((error) => {
                this._pulling = false;
                if (this._pendingSlices.length > 0) {
                    this._pendingSlices.forEach(x => x.reject(error)); // Make sure to propagate any errors
                    this._pendingSlices.length = 0;
                }
                else {
                    throw error; // So it doesn't get swallowed
                }
            });
        }
        return promise;
    }
    /** @internal */
    _throwDueToCacheMiss() {
        throw new Error('Read is before the cached region. With ReadableStreamSource, you must access the data more'
            + ' sequentially or increase the size of its cache.');
    }
    /** @internal */
    async _pull() {
        this._reader ??= this._stream.getReader();
        // This is the loop that keeps pulling data from the stream until a target index is reached, filling requests
        // in the process
        while (this._currentIndex < this._targetIndex && !this._disposed) {
            const { done, value } = await this._reader.read();
            if (done) {
                for (const pendingSlice of this._pendingSlices) {
                    pendingSlice.resolve(null);
                }
                this._pendingSlices.length = 0;
                this._endIndex = this._currentIndex; // We know how long the file is now!
                break;
            }
            const startIndex = this._currentIndex;
            const endIndex = this._currentIndex + value.byteLength;
            // Fill the pending slices with the data
            for (let i = 0; i < this._pendingSlices.length; i++) {
                const pendingSlice = this._pendingSlices[i];
                const cappedStart = Math.max(startIndex, pendingSlice.start);
                const cappedEnd = Math.min(endIndex, pendingSlice.end);
                if (cappedStart < cappedEnd) {
                    pendingSlice.bytes.set(value.subarray(cappedStart - startIndex, cappedEnd - startIndex), cappedStart - pendingSlice.start);
                    if (cappedEnd === pendingSlice.end) {
                        // Pending slice fully filled
                        pendingSlice.resolve({
                            bytes: pendingSlice.bytes,
                            view: (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(pendingSlice.bytes),
                            offset: pendingSlice.start,
                        });
                        this._pendingSlices.splice(i, 1);
                        i--;
                    }
                }
            }
            this._cache.push({
                start: startIndex,
                end: endIndex,
                bytes: value,
                view: (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(value),
                age: 0, // Unused
            });
            // Do cache eviction, based on the distance from the last-requested index. It's important that we do it like
            // this and not based on where the reader is at, because if the reader is fast, we'll unnecessarily evict
            // data that we still might need.
            while (this._cache.length > 0) {
                const firstEntry = this._cache[0];
                const distance = this._maxRequestedIndex - firstEntry.end;
                if (distance <= this._maxCacheSize) {
                    break;
                }
                this._cache.shift();
            }
            this._currentIndex += value.byteLength;
        }
        this._pulling = false;
    }
    /** @internal */
    _dispose() {
        this._pendingSlices.length = 0;
        this._cache.length = 0;
    }
}
const PREFETCH_PROFILES = {
    none: (start, end) => ({ start, end }),
    fileSystem: (start, end) => {
        const padding = 2 ** 16;
        start = Math.floor((start - padding) / padding) * padding;
        end = Math.ceil((end + padding) / padding) * padding;
        return { start, end };
    },
    network: (start, end, workers) => {
        // Add a slight bit of start padding because backwards reading is painful
        const paddingStart = 2 ** 16;
        start = Math.max(0, Math.floor((start - paddingStart) / paddingStart) * paddingStart);
        // Remote resources have extreme latency (relatively speaking), so the benefit from intelligent
        // prefetching is great. The network prefetch strategy is as follows: When we notice
        // successive reads to a worker's read region, we prefetch more data at the end of that region,
        // growing exponentially (up to a cap). This performs well for real-world use cases: Either we read a
        // small part of the file once and then never need it again, in which case the requested about of data
        // is small. Or, we're repeatedly doing a sequential access pattern (common in media files), in which
        // case we can become more and more confident to prefetch more and more data.
        for (const worker of workers) {
            const maxExtensionAmount = 8 * 2 ** 20; // 8 MiB
            // When the read region cross the threshold point, we trigger a prefetch. This point is typically
            // in the middle of the worker's read region, or a fixed offset from the end if the region has grown
            // really large.
            const thresholdPoint = Math.max((worker.startPos + worker.targetPos) / 2, worker.targetPos - maxExtensionAmount);
            if ((0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .closedIntervalsOverlap */ .oX)(start, end, thresholdPoint, worker.targetPos)) {
                const size = worker.targetPos - worker.startPos;
                // If we extend by maxExtensionAmount
                const a = Math.ceil((size + 1) / maxExtensionAmount) * maxExtensionAmount;
                // If we extend to the next power of 2
                const b = 2 ** Math.ceil(Math.log2(size + 1));
                const extent = Math.min(b, a);
                end = Math.max(end, worker.startPos + extent);
            }
        }
        end = Math.max(end, start + URL_SOURCE_MIN_LOAD_AMOUNT);
        return {
            start,
            end,
        };
    },
};
/**
 * Godclass for orchestrating complex, cached read operations. The reading model is as follows: Any reading task is
 * delegated to a *worker*, which is a sequential reader positioned somewhere along the file. All workers run in
 * parallel and can be stopped and resumed in their forward movement. When read requests come in, this orchestrator will
 * first try to satisfy the request with only the cached data. If this isn't possible, workers are spun up for all
 * missing parts (or existing workers are repurposed), and these workers will then fill the holes in the data as they
 * march along the file.
 */
class ReadOrchestrator {
    constructor(options) {
        this.options = options;
        this.fileSize = null;
        this.nextAge = 0; // Used for LRU eviction of both cache entries and workers
        this.workers = [];
        this.cache = [];
        this.currentCacheSize = 0;
        this.disposed = false;
    }
    read(innerStart, innerEnd) {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(this.fileSize !== null);
        const prefetchRange = this.options.prefetchProfile(innerStart, innerEnd, this.workers);
        const outerStart = Math.max(prefetchRange.start, 0);
        const outerEnd = Math.min(prefetchRange.end, this.fileSize);
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(outerStart <= innerStart && innerEnd <= outerEnd);
        let result = null;
        const innerCacheStartIndex = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .binarySearchLessOrEqual */ .eE)(this.cache, innerStart, x => x.start);
        const innerStartEntry = innerCacheStartIndex !== -1 ? this.cache[innerCacheStartIndex] : null;
        // See if the read request can be satisfied by a single cache entry
        if (innerStartEntry && innerStartEntry.start <= innerStart && innerEnd <= innerStartEntry.end) {
            innerStartEntry.age = this.nextAge++;
            result = {
                bytes: innerStartEntry.bytes,
                view: innerStartEntry.view,
                offset: innerStartEntry.start,
            };
            // Can't return yet though, still need to check if the prefetch range might lie outside the cached area
        }
        const outerCacheStartIndex = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .binarySearchLessOrEqual */ .eE)(this.cache, outerStart, x => x.start);
        const bytes = result ? null : new Uint8Array(innerEnd - innerStart);
        let contiguousBytesWriteEnd = 0; // Used to track if the cache is able to completely cover the bytes
        let lastEnd = outerStart;
        // The "holes" in the cache (the parts we need to load)
        const outerHoles = [];
        // Loop over the cache and build up the list of holes
        if (outerCacheStartIndex !== -1) {
            for (let i = outerCacheStartIndex; i < this.cache.length; i++) {
                const entry = this.cache[i];
                if (entry.start >= outerEnd) {
                    break;
                }
                if (entry.end <= outerStart) {
                    continue;
                }
                const cappedOuterStart = Math.max(outerStart, entry.start);
                const cappedOuterEnd = Math.min(outerEnd, entry.end);
                (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(cappedOuterStart <= cappedOuterEnd);
                if (lastEnd < cappedOuterStart) {
                    outerHoles.push({ start: lastEnd, end: cappedOuterStart });
                }
                lastEnd = cappedOuterEnd;
                if (bytes) {
                    const cappedInnerStart = Math.max(innerStart, entry.start);
                    const cappedInnerEnd = Math.min(innerEnd, entry.end);
                    if (cappedInnerStart < cappedInnerEnd) {
                        const relativeOffset = cappedInnerStart - innerStart;
                        // Fill the relevant section of the bytes with the cached data
                        bytes.set(entry.bytes.subarray(cappedInnerStart - entry.start, cappedInnerEnd - entry.start), relativeOffset);
                        if (relativeOffset === contiguousBytesWriteEnd) {
                            contiguousBytesWriteEnd = cappedInnerEnd - innerStart;
                        }
                    }
                }
                entry.age = this.nextAge++;
            }
            if (lastEnd < outerEnd) {
                outerHoles.push({ start: lastEnd, end: outerEnd });
            }
        }
        else {
            outerHoles.push({ start: outerStart, end: outerEnd });
        }
        if (bytes && contiguousBytesWriteEnd >= bytes.length) {
            // Multiple cache entries were able to completely cover the requested bytes!
            result = {
                bytes,
                view: (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(bytes),
                offset: innerStart,
            };
        }
        if (outerHoles.length === 0) {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(result);
            return result;
        }
        // We need to read more data, so now we're in async land
        const { promise, resolve, reject } = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .promiseWithResolvers */ .nJ)();
        const innerHoles = [];
        for (const outerHole of outerHoles) {
            const cappedStart = Math.max(innerStart, outerHole.start);
            const cappedEnd = Math.min(innerEnd, outerHole.end);
            if (cappedStart === outerHole.start && cappedEnd === outerHole.end) {
                innerHoles.push(outerHole); // Can reuse without allocating a new object
            }
            else if (cappedStart < cappedEnd) {
                innerHoles.push({ start: cappedStart, end: cappedEnd });
            }
        }
        // Fire off workers to take care of patching the holes
        for (const outerHole of outerHoles) {
            const pendingSlice = bytes && {
                start: innerStart,
                bytes,
                holes: innerHoles,
                resolve,
                reject,
            };
            let workerFound = false;
            for (const worker of this.workers) {
                // A small tolerance in the case that the requested region is *just* after the target position of an
                // existing worker. In that case, it's probably more efficient to repurpose that worker than to spawn
                // another one so close to it
                const gapTolerance = 2 ** 17;
                // This check also implies worker.currentPos <= outerHole.start, a critical condition
                if ((0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .closedIntervalsOverlap */ .oX)(outerHole.start - gapTolerance, outerHole.start, worker.currentPos, worker.targetPos)) {
                    worker.targetPos = Math.max(worker.targetPos, outerHole.end); // Update the worker's target position
                    workerFound = true;
                    if (pendingSlice && !worker.pendingSlices.includes(pendingSlice)) {
                        worker.pendingSlices.push(pendingSlice);
                    }
                    if (!worker.running) {
                        // Kick it off if it's idle
                        this.runWorker(worker);
                    }
                    break;
                }
            }
            if (!workerFound) {
                // We need to spawn a new worker
                const newWorker = this.createWorker(outerHole.start, outerHole.end);
                if (pendingSlice) {
                    newWorker.pendingSlices = [pendingSlice];
                }
                this.runWorker(newWorker);
            }
        }
        if (!result) {
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(bytes);
            result = promise.then(bytes => ({
                bytes,
                view: (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(bytes),
                offset: innerStart,
            }));
        }
        else {
            // The requested region was satisfied by the cache, but the entire prefetch region was not
        }
        return result;
    }
    createWorker(startPos, targetPos) {
        const worker = {
            startPos,
            currentPos: startPos,
            targetPos,
            running: false,
            // Due to async shenanigans, it can happen that workers are started after disposal. In this case, instead of
            // simply not creating the worker, we allow it to run but immediately label it as aborted, so it can then
            // shut itself down.
            aborted: this.disposed,
            pendingSlices: [],
            age: this.nextAge++,
        };
        this.workers.push(worker);
        // LRU eviction of the other workers
        while (this.workers.length > this.options.maxWorkerCount) {
            let oldestIndex = 0;
            let oldestWorker = this.workers[0];
            for (let i = 1; i < this.workers.length; i++) {
                const worker = this.workers[i];
                if (worker.age < oldestWorker.age) {
                    oldestIndex = i;
                    oldestWorker = worker;
                }
            }
            if (oldestWorker.running && oldestWorker.pendingSlices.length > 0) {
                break;
            }
            oldestWorker.aborted = true;
            this.workers.splice(oldestIndex, 1);
        }
        return worker;
    }
    runWorker(worker) {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(!worker.running);
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(worker.currentPos < worker.targetPos);
        worker.running = true;
        worker.age = this.nextAge++;
        void this.options.runWorker(worker)
            .catch((error) => {
            worker.running = false;
            if (worker.pendingSlices.length > 0) {
                worker.pendingSlices.forEach(x => x.reject(error)); // Make sure to propagate any errors
                worker.pendingSlices.length = 0;
            }
            else {
                throw error; // So it doesn't get swallowed
            }
        });
    }
    /** Called by a worker when it has read some data. */
    supplyWorkerData(worker, bytes) {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(!worker.aborted);
        const start = worker.currentPos;
        const end = start + bytes.length;
        this.insertIntoCache({
            start,
            end,
            bytes,
            view: (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(bytes),
            age: this.nextAge++,
        });
        worker.currentPos += bytes.length;
        worker.targetPos = Math.max(worker.targetPos, worker.currentPos); // In case it overshoots
        // Now, let's see if we can use the read bytes to fill any pending slice
        for (let i = 0; i < worker.pendingSlices.length; i++) {
            const pendingSlice = worker.pendingSlices[i];
            const clampedStart = Math.max(start, pendingSlice.start);
            const clampedEnd = Math.min(end, pendingSlice.start + pendingSlice.bytes.length);
            if (clampedStart < clampedEnd) {
                pendingSlice.bytes.set(bytes.subarray(clampedStart - start, clampedEnd - start), clampedStart - pendingSlice.start);
            }
            for (let j = 0; j < pendingSlice.holes.length; j++) {
                // The hole is intentionally not modified here if the read section starts somewhere in the middle of
                // the hole. We don't need to do "hole splitting", since the workers are spawned *by* the holes,
                // meaning there's always a worker which will consume the hole left to right.
                const hole = pendingSlice.holes[j];
                if (start <= hole.start && end > hole.start) {
                    hole.start = end;
                }
                if (hole.end <= hole.start) {
                    pendingSlice.holes.splice(j, 1);
                    j--;
                }
            }
            if (pendingSlice.holes.length === 0) {
                // The slice has been fulfilled, everything has been read. Let's resolve the promise
                pendingSlice.resolve(pendingSlice.bytes);
                worker.pendingSlices.splice(i, 1);
                i--;
            }
        }
        // Remove other idle workers if we "ate" into their territory
        for (let i = 0; i < this.workers.length; i++) {
            const otherWorker = this.workers[i];
            if (worker === otherWorker || otherWorker.running) {
                continue;
            }
            if ((0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .closedIntervalsOverlap */ .oX)(start, end, otherWorker.currentPos, otherWorker.targetPos)) {
                this.workers.splice(i, 1);
                i--;
            }
        }
    }
    forgetWorker(worker) {
        const index = this.workers.indexOf(worker);
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .assert */ .vA)(index !== -1);
        this.workers.splice(index, 1);
    }
    insertIntoCache(entry) {
        if (this.options.maxCacheSize === 0) {
            return; // No caching
        }
        let insertionIndex = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .binarySearchLessOrEqual */ .eE)(this.cache, entry.start, x => x.start) + 1;
        if (insertionIndex > 0) {
            const previous = this.cache[insertionIndex - 1];
            if (previous.end >= entry.end) {
                // Previous entry swallows the one to be inserted; we don't need to do anything
                return;
            }
            if (previous.end > entry.start) {
                // Partial overlap with the previous entry, let's join
                const joined = new Uint8Array(entry.end - previous.start);
                joined.set(previous.bytes, 0);
                joined.set(entry.bytes, entry.start - previous.start);
                this.currentCacheSize += entry.end - previous.end;
                previous.bytes = joined;
                previous.view = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(joined);
                previous.end = entry.end;
                // Do the rest of the logic with the previous entry instead
                insertionIndex--;
                entry = previous;
            }
            else {
                this.cache.splice(insertionIndex, 0, entry);
                this.currentCacheSize += entry.bytes.length;
            }
        }
        else {
            this.cache.splice(insertionIndex, 0, entry);
            this.currentCacheSize += entry.bytes.length;
        }
        for (let i = insertionIndex + 1; i < this.cache.length; i++) {
            const next = this.cache[i];
            if (entry.end <= next.start) {
                // Even if they touch, we don't wanna merge them, no need
                break;
            }
            if (entry.end >= next.end) {
                // The inserted entry completely swallows the next entry
                this.cache.splice(i, 1);
                this.currentCacheSize -= next.bytes.length;
                i--;
                continue;
            }
            // Partial overlap, let's join
            const joined = new Uint8Array(next.end - entry.start);
            joined.set(entry.bytes, 0);
            joined.set(next.bytes, next.start - entry.start);
            this.currentCacheSize -= entry.end - next.start; // Subtract the overlap
            entry.bytes = joined;
            entry.view = (0,_misc_js__WEBPACK_IMPORTED_MODULE_0__/* .toDataView */ .Zc)(joined);
            entry.end = next.end;
            this.cache.splice(i, 1);
            break; // After the join case, we're done: the next entry cannot possibly overlap with the inserted one.
        }
        // LRU eviction of cache entries
        while (this.currentCacheSize > this.options.maxCacheSize) {
            let oldestIndex = 0;
            let oldestEntry = this.cache[0];
            for (let i = 1; i < this.cache.length; i++) {
                const entry = this.cache[i];
                if (entry.age < oldestEntry.age) {
                    oldestIndex = i;
                    oldestEntry = entry;
                }
            }
            if (this.currentCacheSize - oldestEntry.bytes.length <= this.options.maxCacheSize) {
                // Don't evict if it would shrink the cache below the max size
                break;
            }
            this.cache.splice(oldestIndex, 1);
            this.currentCacheSize -= oldestEntry.bytes.length;
        }
    }
    dispose() {
        for (const worker of this.workers) {
            worker.aborted = true;
        }
        this.workers.length = 0;
        this.cache.length = 0;
        this.disposed = true;
    }
}


/***/ },

/***/ 260
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   D: () => (/* binding */ WaveFormat),
/* harmony export */   E: () => (/* binding */ WaveDemuxer)
/* harmony export */ });
/* harmony import */ var _demuxer_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7202);
/* harmony import */ var _input_track_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6244);
/* harmony import */ var _metadata_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5165);
/* harmony import */ var _misc_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3912);
/* harmony import */ var _packet_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(3936);
/* harmony import */ var _reader_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(7735);
/* harmony import */ var _id3_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(7576);
/*!
 * Copyright (c) 2026-present, Vanilagy and contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */







var WaveFormat;
(function (WaveFormat) {
    WaveFormat[WaveFormat["PCM"] = 1] = "PCM";
    WaveFormat[WaveFormat["IEEE_FLOAT"] = 3] = "IEEE_FLOAT";
    WaveFormat[WaveFormat["ALAW"] = 6] = "ALAW";
    WaveFormat[WaveFormat["MULAW"] = 7] = "MULAW";
    WaveFormat[WaveFormat["EXTENSIBLE"] = 65534] = "EXTENSIBLE";
})(WaveFormat || (WaveFormat = {}));
class WaveDemuxer extends _demuxer_js__WEBPACK_IMPORTED_MODULE_0__/* .Demuxer */ .B {
    constructor(input) {
        super(input);
        this.metadataPromise = null;
        this.dataStart = -1;
        this.dataSize = -1;
        this.audioInfo = null;
        this.tracks = [];
        this.lastKnownPacketIndex = 0;
        this.metadataTags = {};
        this.reader = input._reader;
    }
    async readMetadata() {
        return this.metadataPromise ??= (async () => {
            let slice = this.reader.requestSlice(0, 12);
            if (slice instanceof Promise)
                slice = await slice;
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(slice);
            const riffType = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readAscii */ .IT)(slice, 4);
            const littleEndian = riffType !== 'RIFX';
            const isRf64 = riffType === 'RF64';
            const outerChunkSize = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readU32 */ .PF)(slice, littleEndian);
            let totalFileSize = isRf64
                ? this.reader.fileSize
                : Math.min(outerChunkSize + 8, this.reader.fileSize ?? Infinity);
            const format = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readAscii */ .IT)(slice, 4);
            if (format !== 'WAVE') {
                throw new Error('Invalid WAVE file - wrong format');
            }
            let chunksRead = 0;
            let dataChunkSize = null;
            let currentPos = slice.filePos;
            while (totalFileSize === null || currentPos < totalFileSize) {
                let slice = this.reader.requestSlice(currentPos, 8);
                if (slice instanceof Promise)
                    slice = await slice;
                if (!slice)
                    break;
                const chunkId = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readAscii */ .IT)(slice, 4);
                const chunkSize = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readU32 */ .PF)(slice, littleEndian);
                const startPos = slice.filePos;
                if (isRf64 && chunksRead === 0 && chunkId !== 'ds64') {
                    throw new Error('Invalid RF64 file: First chunk must be "ds64".');
                }
                if (chunkId === 'fmt ') {
                    await this.parseFmtChunk(startPos, chunkSize, littleEndian);
                }
                else if (chunkId === 'data') {
                    dataChunkSize ??= chunkSize;
                    this.dataStart = slice.filePos;
                    this.dataSize = Math.min(dataChunkSize, (totalFileSize ?? Infinity) - this.dataStart);
                    if (this.reader.fileSize === null) {
                        break; // Stop once we hit the data chunk
                    }
                }
                else if (chunkId === 'ds64') {
                    // File and data chunk sizes are defined in here instead
                    let ds64Slice = this.reader.requestSlice(startPos, chunkSize);
                    if (ds64Slice instanceof Promise)
                        ds64Slice = await ds64Slice;
                    if (!ds64Slice)
                        break;
                    const riffChunkSize = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readU64 */ .IM)(ds64Slice, littleEndian);
                    dataChunkSize = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readU64 */ .IM)(ds64Slice, littleEndian);
                    totalFileSize = Math.min(riffChunkSize + 8, this.reader.fileSize ?? Infinity);
                }
                else if (chunkId === 'LIST') {
                    await this.parseListChunk(startPos, chunkSize, littleEndian);
                }
                else if (chunkId === 'ID3 ' || chunkId === 'id3 ') {
                    await this.parseId3Chunk(startPos, chunkSize);
                }
                currentPos = startPos + chunkSize + (chunkSize & 1); // Handle padding
                chunksRead++;
            }
            if (!this.audioInfo) {
                throw new Error('Invalid WAVE file - missing "fmt " chunk');
            }
            if (this.dataStart === -1) {
                throw new Error('Invalid WAVE file - missing "data" chunk');
            }
            const blockSize = this.audioInfo.blockSizeInBytes;
            this.dataSize = Math.floor(this.dataSize / blockSize) * blockSize;
            this.tracks.push(new _input_track_js__WEBPACK_IMPORTED_MODULE_1__/* .InputAudioTrack */ .Yi(this.input, new WaveAudioTrackBacking(this)));
        })();
    }
    async parseFmtChunk(startPos, size, littleEndian) {
        let slice = this.reader.requestSlice(startPos, size);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice)
            return; // File too short
        let formatTag = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readU16 */ .Vv)(slice, littleEndian);
        const numChannels = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readU16 */ .Vv)(slice, littleEndian);
        const sampleRate = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readU32 */ .PF)(slice, littleEndian);
        slice.skip(4); // Bytes per second
        const blockAlign = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readU16 */ .Vv)(slice, littleEndian);
        let bitsPerSample;
        if (size === 14) { // Plain WAVEFORMAT
            bitsPerSample = 8;
        }
        else {
            bitsPerSample = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readU16 */ .Vv)(slice, littleEndian);
        }
        // Handle WAVEFORMATEXTENSIBLE
        if (size >= 18 && formatTag !== 0x0165) {
            const cbSize = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readU16 */ .Vv)(slice, littleEndian);
            const remainingSize = size - 18;
            const extensionSize = Math.min(remainingSize, cbSize);
            if (extensionSize >= 22 && formatTag === WaveFormat.EXTENSIBLE) {
                // Parse WAVEFORMATEXTENSIBLE
                slice.skip(2 + 4);
                const subFormat = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readBytes */ .io)(slice, 16);
                // Get actual format from subFormat GUID
                formatTag = subFormat[0] | (subFormat[1] << 8);
            }
        }
        if (formatTag === WaveFormat.MULAW || formatTag === WaveFormat.ALAW) {
            bitsPerSample = 8;
        }
        this.audioInfo = {
            format: formatTag,
            numberOfChannels: numChannels,
            sampleRate,
            sampleSizeInBytes: Math.ceil(bitsPerSample / 8),
            blockSizeInBytes: blockAlign,
        };
    }
    async parseListChunk(startPos, size, littleEndian) {
        let slice = this.reader.requestSlice(startPos, size);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice)
            return; // File too short
        const infoType = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readAscii */ .IT)(slice, 4);
        if (infoType !== 'INFO' && infoType !== 'INF0') { // exiftool.org claims INF0 can happen
            return; // Not an INFO chunk
        }
        let currentPos = slice.filePos;
        while (currentPos <= startPos + size - 8) {
            slice.filePos = currentPos;
            const chunkName = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readAscii */ .IT)(slice, 4);
            const chunkSize = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readU32 */ .PF)(slice, littleEndian);
            const bytes = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readBytes */ .io)(slice, chunkSize);
            let stringLength = 0;
            for (let i = 0; i < bytes.length; i++) {
                if (bytes[i] === 0) {
                    break;
                }
                stringLength++;
            }
            const value = String.fromCharCode(...bytes.subarray(0, stringLength));
            this.metadataTags.raw ??= {};
            this.metadataTags.raw[chunkName] = value;
            switch (chunkName) {
                case 'INAM':
                case 'TITL':
                    {
                        this.metadataTags.title ??= value;
                    }
                    ;
                    break;
                case 'TIT3':
                    {
                        this.metadataTags.description ??= value;
                    }
                    ;
                    break;
                case 'IART':
                    {
                        this.metadataTags.artist ??= value;
                    }
                    ;
                    break;
                case 'IPRD':
                    {
                        this.metadataTags.album ??= value;
                    }
                    ;
                    break;
                case 'IPRT':
                case 'ITRK':
                case 'TRCK':
                    {
                        const parts = value.split('/');
                        const trackNum = Number.parseInt(parts[0], 10);
                        const tracksTotal = parts[1] && Number.parseInt(parts[1], 10);
                        if (Number.isInteger(trackNum) && trackNum > 0) {
                            this.metadataTags.trackNumber ??= trackNum;
                        }
                        if (tracksTotal && Number.isInteger(tracksTotal) && tracksTotal > 0) {
                            this.metadataTags.tracksTotal ??= tracksTotal;
                        }
                    }
                    ;
                    break;
                case 'ICRD':
                case 'IDIT':
                    {
                        const date = new Date(value);
                        if (!Number.isNaN(date.getTime())) {
                            this.metadataTags.date ??= date;
                        }
                    }
                    ;
                    break;
                case 'YEAR':
                    {
                        const year = Number.parseInt(value, 10);
                        if (Number.isInteger(year) && year > 0) {
                            this.metadataTags.date ??= new Date(year, 0, 1);
                        }
                    }
                    ;
                    break;
                case 'IGNR':
                case 'GENR':
                    {
                        this.metadataTags.genre ??= value;
                    }
                    ;
                    break;
                case 'ICMT':
                case 'CMNT':
                case 'COMM':
                    {
                        this.metadataTags.comment ??= value;
                    }
                    ;
                    break;
            }
            currentPos += 8 + chunkSize + (chunkSize & 1); // Handle padding
        }
    }
    async parseId3Chunk(startPos, size) {
        // Parse ID3 tag embedded in WAV file (non-default, but used a lot in practice anyway)
        let slice = this.reader.requestSlice(startPos, size);
        if (slice instanceof Promise)
            slice = await slice;
        if (!slice)
            return; // File too short
        const id3V2Header = (0,_id3_js__WEBPACK_IMPORTED_MODULE_6__/* .readId3V2Header */ .IX)(slice);
        if (id3V2Header) {
            // Clamp to the available data in case the ID3 header claims more than the WAV chunk provides
            // https://github.com/Vanilagy/mediabunny/issues/300
            const availableSize = size - _id3_js__WEBPACK_IMPORTED_MODULE_6__/* .ID3_V2_HEADER_SIZE */ .sY;
            id3V2Header.size = Math.min(id3V2Header.size, availableSize);
            if (id3V2Header.size > 0) {
                const contentSlice = slice.slice(startPos + _id3_js__WEBPACK_IMPORTED_MODULE_6__/* .ID3_V2_HEADER_SIZE */ .sY, id3V2Header.size);
                (0,_id3_js__WEBPACK_IMPORTED_MODULE_6__/* .parseId3V2Tag */ .cG)(contentSlice, id3V2Header, this.metadataTags);
            }
        }
    }
    getCodec() {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(this.audioInfo);
        if (this.audioInfo.format === WaveFormat.MULAW) {
            return 'ulaw';
        }
        if (this.audioInfo.format === WaveFormat.ALAW) {
            return 'alaw';
        }
        if (this.audioInfo.format === WaveFormat.PCM) {
            // All formats are little-endian
            if (this.audioInfo.sampleSizeInBytes === 1) {
                return 'pcm-u8';
            }
            else if (this.audioInfo.sampleSizeInBytes === 2) {
                return 'pcm-s16';
            }
            else if (this.audioInfo.sampleSizeInBytes === 3) {
                return 'pcm-s24';
            }
            else if (this.audioInfo.sampleSizeInBytes === 4) {
                return 'pcm-s32';
            }
        }
        if (this.audioInfo.format === WaveFormat.IEEE_FLOAT) {
            if (this.audioInfo.sampleSizeInBytes === 4) {
                return 'pcm-f32';
            }
        }
        return null;
    }
    async getMimeType() {
        return 'audio/wav';
    }
    async computeDuration() {
        await this.readMetadata();
        const track = this.tracks[0];
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(track);
        return track.computeDuration();
    }
    async getTracks() {
        await this.readMetadata();
        return this.tracks;
    }
    async getMetadataTags() {
        await this.readMetadata();
        return this.metadataTags;
    }
}
const PACKET_SIZE_IN_FRAMES = 2048;
class WaveAudioTrackBacking {
    constructor(demuxer) {
        this.demuxer = demuxer;
    }
    getId() {
        return 1;
    }
    getNumber() {
        return 1;
    }
    getCodec() {
        return this.demuxer.getCodec();
    }
    getInternalCodecId() {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(this.demuxer.audioInfo);
        return this.demuxer.audioInfo.format;
    }
    async getDecoderConfig() {
        const codec = this.demuxer.getCodec();
        if (!codec) {
            return null;
        }
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(this.demuxer.audioInfo);
        return {
            codec,
            numberOfChannels: this.demuxer.audioInfo.numberOfChannels,
            sampleRate: this.demuxer.audioInfo.sampleRate,
        };
    }
    async computeDuration() {
        const lastPacket = await this.getPacket(Infinity, { metadataOnly: true });
        return (lastPacket?.timestamp ?? 0) + (lastPacket?.duration ?? 0);
    }
    getNumberOfChannels() {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(this.demuxer.audioInfo);
        return this.demuxer.audioInfo.numberOfChannels;
    }
    getSampleRate() {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(this.demuxer.audioInfo);
        return this.demuxer.audioInfo.sampleRate;
    }
    getTimeResolution() {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(this.demuxer.audioInfo);
        return this.demuxer.audioInfo.sampleRate;
    }
    getName() {
        return null;
    }
    getLanguageCode() {
        return _misc_js__WEBPACK_IMPORTED_MODULE_3__/* .UNDETERMINED_LANGUAGE */ .IR;
    }
    getDisposition() {
        return {
            ..._metadata_js__WEBPACK_IMPORTED_MODULE_2__/* .DEFAULT_TRACK_DISPOSITION */ .gM,
        };
    }
    async getFirstTimestamp() {
        return 0;
    }
    async getPacketAtIndex(packetIndex, options) {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(packetIndex >= 0);
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(this.demuxer.audioInfo);
        const startOffset = packetIndex * PACKET_SIZE_IN_FRAMES * this.demuxer.audioInfo.blockSizeInBytes;
        if (startOffset >= this.demuxer.dataSize) {
            return null;
        }
        const sizeInBytes = Math.min(PACKET_SIZE_IN_FRAMES * this.demuxer.audioInfo.blockSizeInBytes, this.demuxer.dataSize - startOffset);
        if (this.demuxer.reader.fileSize === null) {
            // If the file size is unknown, we weren't able to cap the dataSize in the init logic and we instead have to
            // rely on the headers telling us how large the file is. But, these might be wrong, so let's check if the
            // requested slice actually exists.
            let slice = this.demuxer.reader.requestSlice(this.demuxer.dataStart + startOffset, sizeInBytes);
            if (slice instanceof Promise)
                slice = await slice;
            if (!slice) {
                return null;
            }
        }
        let data;
        if (options.metadataOnly) {
            data = _packet_js__WEBPACK_IMPORTED_MODULE_4__/* .PLACEHOLDER_DATA */ .T;
        }
        else {
            let slice = this.demuxer.reader.requestSlice(this.demuxer.dataStart + startOffset, sizeInBytes);
            if (slice instanceof Promise)
                slice = await slice;
            (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(slice);
            data = (0,_reader_js__WEBPACK_IMPORTED_MODULE_5__/* .readBytes */ .io)(slice, sizeInBytes);
        }
        const timestamp = packetIndex * PACKET_SIZE_IN_FRAMES / this.demuxer.audioInfo.sampleRate;
        const duration = sizeInBytes / this.demuxer.audioInfo.blockSizeInBytes / this.demuxer.audioInfo.sampleRate;
        this.demuxer.lastKnownPacketIndex = Math.max(packetIndex, this.demuxer.lastKnownPacketIndex);
        return new _packet_js__WEBPACK_IMPORTED_MODULE_4__/* .EncodedPacket */ .Z(data, 'key', timestamp, duration, packetIndex, sizeInBytes);
    }
    getFirstPacket(options) {
        return this.getPacketAtIndex(0, options);
    }
    async getPacket(timestamp, options) {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(this.demuxer.audioInfo);
        const packetIndex = Math.floor(Math.min(timestamp * this.demuxer.audioInfo.sampleRate / PACKET_SIZE_IN_FRAMES, (this.demuxer.dataSize - 1) / (PACKET_SIZE_IN_FRAMES * this.demuxer.audioInfo.blockSizeInBytes)));
        if (packetIndex < 0) {
            return null;
        }
        const packet = await this.getPacketAtIndex(packetIndex, options);
        if (packet) {
            return packet;
        }
        if (packetIndex === 0) {
            return null; // Empty data chunk
        }
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(this.demuxer.reader.fileSize === null);
        // The file is shorter than we thought, meaning the packet we were looking for doesn't exist. So, let's find
        // the last packet by doing a sequential scan, instead.
        let currentPacket = await this.getPacketAtIndex(this.demuxer.lastKnownPacketIndex, options);
        while (currentPacket) {
            const nextPacket = await this.getNextPacket(currentPacket, options);
            if (!nextPacket) {
                break;
            }
            currentPacket = nextPacket;
        }
        return currentPacket;
    }
    getNextPacket(packet, options) {
        (0,_misc_js__WEBPACK_IMPORTED_MODULE_3__/* .assert */ .vA)(this.demuxer.audioInfo);
        const packetIndex = Math.round(packet.timestamp * this.demuxer.audioInfo.sampleRate / PACKET_SIZE_IN_FRAMES);
        return this.getPacketAtIndex(packetIndex + 1, options);
    }
    getKeyPacket(timestamp, options) {
        return this.getPacket(timestamp, options);
    }
    getNextKeyPacket(packet, options) {
        return this.getNextPacket(packet, options);
    }
}


/***/ }

}]);
//# sourceMappingURL=517.bundle.js.map