/** * Worker code for inline Blob URL creation. * * This file is auto-generated by the build process. * Do not edit manually - run `npm run build` to regenerate. * * @package gutenberg */ // eslint-disable-next-line @typescript-eslint/no-unused-vars export const workerCode = "// node_modules/comctx/core/dist/index.js\nvar e = { APPLY: `apply`, CALLBACK: `callback`, PING: `ping`, PONG: `pong` };\nvar t = { PROVIDER: `provider`, INJECTOR: `injector` };\nvar n = (n2) => {\n let r2 = !!n2?.type && Object.values(e).includes(n2.type), i2 = !!n2?.id && typeof n2.id == `string`, a2 = !!n2?.path && Array.isArray(n2.path) && n2.path.every((e2) => typeof e2 == `string`), o2 = !!n2?.sender && Object.values(t).includes(n2.sender), s2 = n2?.callbackIds === void 0 || Array.isArray(n2.callbackIds) && n2.callbackIds.every((e2) => typeof e2 == `string`), c2 = n2?.args === void 0 || Array.isArray(n2.args), l2 = n2?.error === void 0 || typeof n2.error == `string`, u2 = !!n2?.meta && n2.meta !== null && typeof n2.meta == `object`, d2 = !!n2?.namespace && typeof n2.namespace == `string`, f2 = !!n2?.timeStamp && typeof n2.timeStamp == `number`;\n return r2 && i2 && a2 && o2 && s2 && c2 && l2 && u2 && d2 && f2;\n};\nvar r = () => [...[, , , ,]].map(() => Math.floor(Math.random() * (2 ** 53 - 1)).toString(16)).join(`-`);\nvar i = r;\nvar a = (e2, t2, ...n2) => {\n let r2 = setTimeout(() => {\n clearTimeout(r2), e2(...n2), r2 = setInterval(e2, t2, ...n2);\n }, 0);\n return () => clearInterval(r2);\n};\nvar o = a;\nvar s = (e2, t2) => t2 !== void 0 && e2 instanceof t2;\nvar c = s;\nvar l = (e2) => {\n let t2 = /* @__PURE__ */ new WeakSet(), n2 = (e3) => !e3 || typeof e3 != `object` || t2.has(e3) ? [] : (t2.add(e3), c(e3, globalThis.ArrayBuffer) || c(e3, globalThis.MessagePort) || c(e3, globalThis.ImageBitmap) || c(e3, globalThis.OffscreenCanvas) || c(e3, globalThis.AudioData) || c(e3, globalThis.VideoFrame) || c(e3, globalThis.RTCDataChannel) || c(e3, globalThis.MediaSourceHandle) || c(e3, globalThis.MIDIAccess) || c(e3, globalThis.MediaStreamTrack) || c(e3, globalThis.ReadableStream) || c(e3, globalThis.WritableStream) || c(e3, globalThis.TransformStream) ? [e3] : Array.isArray(e3) ? e3.flatMap(n2) : Object.values(e3).flatMap(n2));\n return n2(e2);\n};\nvar u = l;\nvar d = /* @__PURE__ */ Symbol(`PROXY_MARKER`);\nvar f = async (r2, a2) => {\n let s2, c2, l2 = /* @__PURE__ */ new Set(), d2 = new Promise((c3, d3) => {\n s2 = o(async () => {\n try {\n let o2 = i(), s3 = await r2.onMessage((r3) => {\n if (!n(r3)) return;\n let i2 = r3;\n i2.namespace === a2.namespace && i2.sender === t.PROVIDER && i2.type === e.PONG && i2.id === o2 && c3();\n });\n s3 && l2.add(s3);\n let d4 = { type: e.PING, sender: t.INJECTOR, id: o2, path: [], meta: {}, namespace: a2.namespace, timeStamp: Date.now() };\n r2.sendMessage(d4, a2.transfer ? u(d4) : []);\n } catch (e2) {\n d3(e2);\n }\n }, a2.heartbeatInterval);\n }), f2 = new Promise((e2, t2) => {\n let n2 = setTimeout(() => t2(Error(`Provider unavailable: heartbeat check timeout ${a2.heartbeatTimeout}ms.`)), a2.heartbeatTimeout);\n c2 = () => clearTimeout(n2);\n });\n await Promise.race([d2, f2]).finally(() => {\n s2(), c2(), l2.forEach((e2) => e2()), l2.clear();\n });\n};\nvar p = (r2, i2, a2) => (i2.onMessage(async (o2) => {\n if (!n(o2)) return;\n let s2 = o2;\n if (s2.namespace === a2.namespace && s2.sender === t.INJECTOR) switch (s2.type) {\n case e.PING: {\n let n2 = { type: e.PONG, sender: t.PROVIDER, id: s2.id, path: s2.path, meta: s2.meta, namespace: a2.namespace, timeStamp: Date.now() };\n i2.sendMessage(n2, a2.transfer ? u(n2) : []);\n break;\n }\n case e.APPLY: {\n try {\n let n3 = s2.args?.map((n4) => s2.callbackIds?.includes(n4) ? (...r3) => {\n let o3 = { type: e.CALLBACK, sender: t.PROVIDER, id: n4, path: s2.path, meta: s2.meta, data: r3, namespace: a2.namespace, timeStamp: Date.now() };\n i2.sendMessage(o3, a2.transfer ? u(o3) : []);\n } : n4);\n s2.data = await (s2.path?.reduce((e2, t2) => e2[t2], r2)).apply(r2, n3 || []);\n } catch (e2) {\n s2.error = e2.message;\n }\n let n2 = { type: e.APPLY, sender: t.PROVIDER, id: s2.id, path: s2.path, data: s2.data, error: s2.error, meta: s2.meta, namespace: a2.namespace, timeStamp: Date.now() };\n i2.sendMessage(n2, a2.transfer ? u(n2) : []);\n break;\n }\n }\n}), r2);\nvar m = (r2, a2, o2) => {\n let s2 = (r3, c2) => {\n let l2 = new Proxy(r3, { get(e2, t2, n2) {\n if (e2[d]) return Reflect.get(e2, t2, n2);\n let r4 = () => {\n };\n return r4[d] = true, s2(r4, [...c2, t2]);\n }, apply(r4, s3, l3) {\n return new Promise(async (r5, s4) => {\n try {\n o2.heartbeatCheck && await f(a2, o2);\n let d2 = [], p2 = l3.map((r6) => {\n if (typeof r6 == `function`) {\n let s5 = i();\n return d2.push(s5), a2.onMessage((i2) => {\n if (!n(i2)) return;\n let a3 = i2;\n a3.namespace === o2.namespace && a3.sender === t.PROVIDER && a3.type === e.CALLBACK && a3.id === s5 && r6(...a3.data);\n }), s5;\n } else return r6;\n }), m2 = i(), h2 = await a2.onMessage((i2) => {\n if (!n(i2)) return;\n let a3 = i2;\n a3.namespace === o2.namespace && a3.sender === t.PROVIDER && a3.type === e.APPLY && a3.id === m2 && (a3.error ? s4(Error(a3.error)) : r5(a3.data), h2?.());\n }), g2 = { type: e.APPLY, sender: t.INJECTOR, id: m2, path: c2, args: p2, meta: {}, callbackIds: d2, timeStamp: Date.now(), namespace: o2.namespace };\n a2.sendMessage(g2, o2.transfer ? u(g2) : []);\n } catch (e2) {\n s4(e2);\n }\n });\n } });\n return l2;\n };\n return s2(r2, []);\n};\nvar h = (e2, t2) => {\n let n2;\n return (r2, ...i2) => n2 ??= p(e2(...i2), r2, t2);\n};\nvar g = (e2, t2) => {\n let n2;\n return (r2) => n2 ??= m(t2.backup ? Object.freeze(e2()) : {}, r2, t2);\n};\nvar _ = (e2, t2) => {\n let n2 = { namespace: t2?.namespace ?? `__comctx__`, heartbeatCheck: t2?.heartbeatCheck ?? true, heartbeatInterval: t2?.heartbeatInterval ?? 300, heartbeatTimeout: t2?.heartbeatTimeout ?? 1e3, transfer: t2?.transfer ?? false, backup: t2?.backup ?? false };\n if (n2.heartbeatTimeout <= n2.heartbeatInterval) throw Error(`Invalid heartbeat config: timeout (${n2.heartbeatTimeout}ms) must exceed interval (${n2.heartbeatInterval}ms).`);\n return [h(e2, n2), g(e2, n2)];\n};\n\n// packages/worker-threads/build-module/worker-thread.mjs\nvar WorkerProvideAdapter = class {\n sendMessage = (message, transfer) => {\n self.postMessage(message, { transfer });\n };\n onMessage = (callback) => {\n const handler = (event) => callback(event.data);\n self.addEventListener(\"message\", handler);\n return () => self.removeEventListener(\"message\", handler);\n };\n};\nfunction normalizeThrowable(error) {\n if (error instanceof Error && error.message) {\n return error;\n }\n let message = \"\";\n try {\n message = String(error);\n } catch {\n }\n return new Error(message || \"Unknown error in worker thread\");\n}\nfunction withNormalizedErrors(target) {\n const wrapped = {};\n for (const key of Object.keys(target)) {\n const value = target[key];\n if (typeof value !== \"function\") {\n wrapped[key] = value;\n continue;\n }\n wrapped[key] = async (...args) => {\n try {\n return await value.apply(target, args);\n } catch (error) {\n throw normalizeThrowable(error);\n }\n };\n }\n return wrapped;\n}\nfunction expose(target) {\n const [provide] = _(() => withNormalizedErrors(target), {\n namespace: \"__wordpress_worker__\",\n heartbeatCheck: false,\n transfer: true\n });\n provide(new WorkerProvideAdapter());\n}\n\n// node_modules/mediabunny/dist/modules/src/misc.js\nfunction assert(x) {\n if (!x) {\n throw new Error(\"Assertion failed.\");\n }\n}\nvar normalizeRotation = (rotation) => {\n const mappedRotation = (rotation % 360 + 360) % 360;\n if (mappedRotation === 0 || mappedRotation === 90 || mappedRotation === 180 || mappedRotation === 270) {\n return mappedRotation;\n } else {\n throw new Error(`Invalid rotation ${rotation}.`);\n }\n};\nvar last = (arr) => {\n return arr && arr[arr.length - 1];\n};\nvar isU32 = (value) => {\n return value >= 0 && value < 2 ** 32;\n};\nvar readExpGolomb = (bitstream) => {\n let leadingZeroBits = 0;\n while (bitstream.readBits(1) === 0 && leadingZeroBits < 32) {\n leadingZeroBits++;\n }\n if (leadingZeroBits >= 32) {\n throw new Error(\"Invalid exponential-Golomb code.\");\n }\n const result = (1 << leadingZeroBits) - 1 + bitstream.readBits(leadingZeroBits);\n return result;\n};\nvar readSignedExpGolomb = (bitstream) => {\n const codeNum = readExpGolomb(bitstream);\n return (codeNum & 1) === 0 ? -(codeNum >> 1) : codeNum + 1 >> 1;\n};\nvar writeBits = (bytes2, start, end, value) => {\n for (let i2 = start; i2 < end; i2++) {\n const byteIndex = Math.floor(i2 / 8);\n let byte = bytes2[byteIndex];\n const bitIndex = 7 - (i2 & 7);\n byte &= ~(1 << bitIndex);\n byte |= (value & 1 << end - i2 - 1) >> end - i2 - 1 << bitIndex;\n bytes2[byteIndex] = byte;\n }\n};\nvar toUint8Array = (source) => {\n if (source.constructor === Uint8Array) {\n return source;\n } else if (ArrayBuffer.isView(source)) {\n return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);\n } else {\n return new Uint8Array(source);\n }\n};\nvar toDataView = (source) => {\n if (source.constructor === DataView) {\n return source;\n } else if (ArrayBuffer.isView(source)) {\n return new DataView(source.buffer, source.byteOffset, source.byteLength);\n } else {\n return new DataView(source);\n }\n};\nvar textEncoder = /* @__PURE__ */ new TextEncoder();\nvar COLOR_PRIMARIES_MAP = {\n bt709: 1,\n // ITU-R BT.709\n bt470bg: 5,\n // ITU-R BT.470BG\n smpte170m: 6,\n // ITU-R BT.601 525 - SMPTE 170M\n bt2020: 9,\n // ITU-R BT.202\n smpte432: 12\n // SMPTE EG 432-1\n};\nvar TRANSFER_CHARACTERISTICS_MAP = {\n \"bt709\": 1,\n // ITU-R BT.709\n \"smpte170m\": 6,\n // SMPTE 170M\n \"linear\": 8,\n // Linear transfer characteristics\n \"iec61966-2-1\": 13,\n // IEC 61966-2-1\n \"pq\": 16,\n // Rec. ITU-R BT.2100-2 perceptual quantization (PQ) system\n \"hlg\": 18\n // Rec. ITU-R BT.2100-2 hybrid loggamma (HLG) system\n};\nvar MATRIX_COEFFICIENTS_MAP = {\n \"rgb\": 0,\n // Identity\n \"bt709\": 1,\n // ITU-R BT.709\n \"bt470bg\": 5,\n // ITU-R BT.470BG\n \"smpte170m\": 6,\n // SMPTE 170M\n \"bt2020-ncl\": 9\n // ITU-R BT.2020-2 (non-constant luminance)\n};\nvar colorSpaceIsComplete = (colorSpace) => {\n return !!colorSpace && !!colorSpace.primaries && !!colorSpace.transfer && !!colorSpace.matrix && colorSpace.fullRange !== void 0;\n};\nvar isAllowSharedBufferSource = (x) => {\n return x instanceof ArrayBuffer || typeof SharedArrayBuffer !== \"undefined\" && x instanceof SharedArrayBuffer || ArrayBuffer.isView(x);\n};\nvar AsyncMutex = class {\n constructor() {\n this.currentPromise = Promise.resolve();\n this.pending = 0;\n }\n async acquire() {\n let resolver;\n const nextPromise = new Promise((resolve) => {\n let resolved = false;\n resolver = () => {\n if (resolved) {\n return;\n }\n resolve();\n this.pending--;\n resolved = true;\n };\n });\n const currentPromiseAlias = this.currentPromise;\n this.currentPromise = nextPromise;\n this.pending++;\n await currentPromiseAlias;\n return resolver;\n }\n};\nvar binarySearchLessOrEqual = (arr, key, valueGetter) => {\n let low = 0;\n let high = arr.length - 1;\n let ans = -1;\n while (low <= high) {\n const mid = low + (high - low + 1) / 2 | 0;\n const midVal = valueGetter(arr[mid]);\n if (midVal <= key) {\n ans = mid;\n low = mid + 1;\n } else {\n high = mid - 1;\n }\n }\n return ans;\n};\nvar promiseWithResolvers = () => {\n let resolve;\n let reject;\n const promise = new Promise((res, rej) => {\n resolve = res;\n reject = rej;\n });\n return { promise, resolve, reject };\n};\nvar assertNever = (x) => {\n throw new Error(`Unexpected value: ${x}`);\n};\nvar getUint24 = (view2, byteOffset, littleEndian) => {\n const byte1 = view2.getUint8(byteOffset);\n const byte2 = view2.getUint8(byteOffset + 1);\n const byte3 = view2.getUint8(byteOffset + 2);\n if (littleEndian) {\n return byte1 | byte2 << 8 | byte3 << 16;\n } else {\n return byte1 << 16 | byte2 << 8 | byte3;\n }\n};\nvar setUint24 = (view2, byteOffset, value, littleEndian) => {\n value = value >>> 0;\n value = value & 16777215;\n if (littleEndian) {\n view2.setUint8(byteOffset, value & 255);\n view2.setUint8(byteOffset + 1, value >>> 8 & 255);\n view2.setUint8(byteOffset + 2, value >>> 16 & 255);\n } else {\n view2.setUint8(byteOffset, value >>> 16 & 255);\n view2.setUint8(byteOffset + 1, value >>> 8 & 255);\n view2.setUint8(byteOffset + 2, value & 255);\n }\n};\nvar UNDETERMINED_LANGUAGE = \"und\";\nvar roundToMultiple = (value, multiple) => {\n return Math.round(value / multiple) * multiple;\n};\nvar roundToDivisor = (value, multiple) => {\n return Math.round(value * multiple) / multiple;\n};\nvar floorToDivisor = (value, multiple) => {\n return Math.floor(value * multiple) / multiple;\n};\nvar ISO_639_2_REGEX = /^[a-z]{3}$/;\nvar isIso639Dash2LanguageCode = (x) => {\n return ISO_639_2_REGEX.test(x);\n};\nvar SECOND_TO_MICROSECOND_FACTOR = 1e6 * (1 + Number.EPSILON);\nvar computeRationalApproximation = (x, maxDenominator) => {\n const sign = x < 0 ? -1 : 1;\n x = Math.abs(x);\n let prevNumerator = 0, prevDenominator = 1;\n let currNumerator = 1, currDenominator = 0;\n let remainder = x;\n while (true) {\n const integer = Math.floor(remainder);\n const nextNumerator = integer * currNumerator + prevNumerator;\n const nextDenominator = integer * currDenominator + prevDenominator;\n if (nextDenominator > maxDenominator) {\n return {\n num: sign * currNumerator,\n den: currDenominator\n };\n }\n prevNumerator = currNumerator;\n prevDenominator = currDenominator;\n currNumerator = nextNumerator;\n currDenominator = nextDenominator;\n remainder = 1 / (remainder - integer);\n if (!isFinite(remainder)) {\n break;\n }\n }\n return {\n num: sign * currNumerator,\n den: currDenominator\n };\n};\nvar CallSerializer = class {\n constructor() {\n this.currentPromise = Promise.resolve();\n }\n call(fn) {\n return this.currentPromise = this.currentPromise.then(fn);\n }\n};\nvar isFirefoxCache = null;\nvar isFirefox = () => {\n if (isFirefoxCache !== null) {\n return isFirefoxCache;\n }\n return isFirefoxCache = typeof navigator !== \"undefined\" && navigator.userAgent?.includes(\"Firefox\");\n};\nvar isChromiumCache = null;\nvar isChromium = () => {\n if (isChromiumCache !== null) {\n return isChromiumCache;\n }\n return isChromiumCache = !!(typeof navigator !== \"undefined\" && (navigator.vendor?.includes(\"Google Inc\") || /Chrome/.test(navigator.userAgent)));\n};\nvar chromiumVersionCache = null;\nvar getChromiumVersion = () => {\n if (chromiumVersionCache !== null) {\n return chromiumVersionCache;\n }\n if (typeof navigator === \"undefined\") {\n return null;\n }\n const match = /\\bChrome\\/(\\d+)/.exec(navigator.userAgent);\n if (!match) {\n return null;\n }\n return chromiumVersionCache = Number(match[1]);\n};\nvar keyValueIterator = function* (object) {\n for (const key in object) {\n const value = object[key];\n if (value === void 0) {\n continue;\n }\n yield { key, value };\n }\n};\nvar imageMimeTypeToExtension = (mimeType) => {\n switch (mimeType.toLowerCase()) {\n case \"image/jpeg\":\n case \"image/jpg\":\n return \".jpg\";\n case \"image/png\":\n return \".png\";\n case \"image/gif\":\n return \".gif\";\n case \"image/webp\":\n return \".webp\";\n case \"image/bmp\":\n return \".bmp\";\n case \"image/svg+xml\":\n return \".svg\";\n case \"image/tiff\":\n return \".tiff\";\n case \"image/avif\":\n return \".avif\";\n case \"image/x-icon\":\n case \"image/vnd.microsoft.icon\":\n return \".ico\";\n default:\n return null;\n }\n};\nvar uint8ArraysAreEqual = (a2, b) => {\n if (a2.length !== b.length) {\n return false;\n }\n for (let i2 = 0; i2 < a2.length; i2++) {\n if (a2[i2] !== b[i2]) {\n return false;\n }\n }\n return true;\n};\nvar polyfillSymbolDispose = () => {\n Symbol.dispose ??= /* @__PURE__ */ Symbol(\"Symbol.dispose\");\n};\nvar arrayArgmin = (array, getValue) => {\n let minIndex = -1;\n let minValue = Infinity;\n for (let i2 = 0; i2 < array.length; i2++) {\n const value = getValue(array[i2]);\n if (value < minValue) {\n minValue = value;\n minIndex = i2;\n }\n }\n return minIndex;\n};\nvar simplifyRational = (rational) => {\n assert(Number.isInteger(rational.num));\n assert(Number.isInteger(rational.den));\n assert(rational.den !== 0);\n let a2 = Math.abs(rational.num);\n let b = Math.abs(rational.den);\n while (b !== 0) {\n const t2 = a2 % b;\n a2 = b;\n b = t2;\n }\n const gcd = a2 || 1;\n return {\n num: rational.num / gcd,\n den: rational.den / gcd\n };\n};\nvar validateRectangle = (rect, propertyPath) => {\n if (typeof rect !== \"object\" || !rect) {\n throw new TypeError(`${propertyPath} must be an object.`);\n }\n if (!Number.isInteger(rect.left) || rect.left < 0) {\n throw new TypeError(`${propertyPath}.left must be a non-negative integer.`);\n }\n if (!Number.isInteger(rect.top) || rect.top < 0) {\n throw new TypeError(`${propertyPath}.top must be a non-negative integer.`);\n }\n if (!Number.isInteger(rect.width) || rect.width < 0) {\n throw new TypeError(`${propertyPath}.width must be a non-negative integer.`);\n }\n if (!Number.isInteger(rect.height) || rect.height < 0) {\n throw new TypeError(`${propertyPath}.height must be a non-negative integer.`);\n }\n};\nvar toArray = (x) => {\n if (Array.isArray(x)) {\n return x;\n } else {\n return [x];\n }\n};\nvar EventEmitter = class {\n constructor() {\n this._listeners = /* @__PURE__ */ new Map();\n }\n /** Registers a listener for the given event. Returns a function that, when called, removes the listener again. */\n on(event, listener, options) {\n if (!this._listeners.has(event)) {\n this._listeners.set(event, /* @__PURE__ */ new Set());\n }\n const entry = { fn: listener, once: options?.once ?? false };\n this._listeners.get(event).add(entry);\n return () => {\n this._listeners.get(event)?.delete(entry);\n };\n }\n /** @internal */\n _emit(...args) {\n const [event, data] = args;\n const listeners = this._listeners.get(event);\n if (!listeners) {\n return;\n }\n for (const entry of listeners) {\n try {\n entry.fn(data);\n } catch (error) {\n console.error(error);\n }\n if (entry.once) {\n listeners.delete(entry);\n }\n }\n }\n};\nvar isRecordStringString = (value) => {\n return value !== null && typeof value === \"object\" && Object.getPrototypeOf(value) === Object.prototype && Object.values(value).every((x) => typeof x === \"string\");\n};\n\n// node_modules/mediabunny/dist/modules/src/logging.js\nvar LogLevel;\n(function(LogLevel2) {\n LogLevel2[LogLevel2[\"Silent\"] = 0] = \"Silent\";\n LogLevel2[LogLevel2[\"Errors\"] = 1] = \"Errors\";\n LogLevel2[LogLevel2[\"Warnings\"] = 2] = \"Warnings\";\n LogLevel2[LogLevel2[\"Info\"] = 3] = \"Info\";\n})(LogLevel || (LogLevel = {}));\nvar Logging = class _Logging {\n constructor() {\n }\n /** The current log level. Defaults to {@link LogLevel.Info}. */\n static get level() {\n return _Logging._level;\n }\n static set level(value) {\n if (value !== LogLevel.Silent && value !== LogLevel.Errors && value !== LogLevel.Warnings && value !== LogLevel.Info) {\n throw new TypeError(\"Invalid log level. Use one of the values of the LogLevel enum.\");\n }\n _Logging._level = value;\n }\n /** @internal */\n static get _emitter() {\n return _Logging._emitterInstance ??= new EventEmitter();\n }\n /** Registers a listener for a log event. Returns a function that, when called, removes the listener again. */\n static on(event, listener, options) {\n return _Logging._emitter.on(event, listener, options);\n }\n /** @internal */\n static _error(...args) {\n _Logging._emitter._emit(\"error\", args);\n if (_Logging._level >= LogLevel.Errors) {\n console.error(...args);\n }\n }\n /** @internal */\n static _warn(...args) {\n _Logging._emitter._emit(\"warn\", args);\n if (_Logging._level >= LogLevel.Warnings) {\n console.warn(...args);\n }\n }\n /** @internal */\n static _info(...args) {\n _Logging._emitter._emit(\"info\", args);\n if (_Logging._level >= LogLevel.Info) {\n console.info(...args);\n }\n }\n};\nLogging._level = LogLevel.Info;\nLogging._emitterInstance = null;\n\n// node_modules/mediabunny/dist/modules/src/metadata.js\nvar RichImageData = class {\n /** Creates a new {@link RichImageData}. */\n constructor(data, mimeType) {\n this.data = data;\n this.mimeType = mimeType;\n if (!(data instanceof Uint8Array)) {\n throw new TypeError(\"data must be a Uint8Array.\");\n }\n if (typeof mimeType !== \"string\") {\n throw new TypeError(\"mimeType must be a string.\");\n }\n }\n};\nvar AttachedFile = class {\n /** Creates a new {@link AttachedFile}. */\n constructor(data, mimeType, name, description) {\n this.data = data;\n this.mimeType = mimeType;\n this.name = name;\n this.description = description;\n if (!(data instanceof Uint8Array)) {\n throw new TypeError(\"data must be a Uint8Array.\");\n }\n if (mimeType !== void 0 && typeof mimeType !== \"string\") {\n throw new TypeError(\"mimeType, when provided, must be a string.\");\n }\n if (name !== void 0 && typeof name !== \"string\") {\n throw new TypeError(\"name, when provided, must be a string.\");\n }\n if (description !== void 0 && typeof description !== \"string\") {\n throw new TypeError(\"description, when provided, must be a string.\");\n }\n }\n};\nvar validateMetadataTags = (tags) => {\n if (!tags || typeof tags !== \"object\") {\n throw new TypeError(\"tags must be an object.\");\n }\n if (tags.title !== void 0 && typeof tags.title !== \"string\") {\n throw new TypeError(\"tags.title, when provided, must be a string.\");\n }\n if (tags.description !== void 0 && typeof tags.description !== \"string\") {\n throw new TypeError(\"tags.description, when provided, must be a string.\");\n }\n if (tags.artist !== void 0 && typeof tags.artist !== \"string\") {\n throw new TypeError(\"tags.artist, when provided, must be a string.\");\n }\n if (tags.album !== void 0 && typeof tags.album !== \"string\") {\n throw new TypeError(\"tags.album, when provided, must be a string.\");\n }\n if (tags.albumArtist !== void 0 && typeof tags.albumArtist !== \"string\") {\n throw new TypeError(\"tags.albumArtist, when provided, must be a string.\");\n }\n if (tags.trackNumber !== void 0 && (!Number.isInteger(tags.trackNumber) || tags.trackNumber <= 0)) {\n throw new TypeError(\"tags.trackNumber, when provided, must be a positive integer.\");\n }\n if (tags.tracksTotal !== void 0 && (!Number.isInteger(tags.tracksTotal) || tags.tracksTotal <= 0)) {\n throw new TypeError(\"tags.tracksTotal, when provided, must be a positive integer.\");\n }\n if (tags.discNumber !== void 0 && (!Number.isInteger(tags.discNumber) || tags.discNumber <= 0)) {\n throw new TypeError(\"tags.discNumber, when provided, must be a positive integer.\");\n }\n if (tags.discsTotal !== void 0 && (!Number.isInteger(tags.discsTotal) || tags.discsTotal <= 0)) {\n throw new TypeError(\"tags.discsTotal, when provided, must be a positive integer.\");\n }\n if (tags.genre !== void 0 && typeof tags.genre !== \"string\") {\n throw new TypeError(\"tags.genre, when provided, must be a string.\");\n }\n if (tags.date !== void 0 && (!(tags.date instanceof Date) || Number.isNaN(tags.date.getTime()))) {\n throw new TypeError(\"tags.date, when provided, must be a valid Date.\");\n }\n if (tags.lyrics !== void 0 && typeof tags.lyrics !== \"string\") {\n throw new TypeError(\"tags.lyrics, when provided, must be a string.\");\n }\n if (tags.images !== void 0) {\n if (!Array.isArray(tags.images)) {\n throw new TypeError(\"tags.images, when provided, must be an array.\");\n }\n for (const image of tags.images) {\n if (!image || typeof image !== \"object\") {\n throw new TypeError(\"Each image in tags.images must be an object.\");\n }\n if (!(image.data instanceof Uint8Array)) {\n throw new TypeError(\"Each image.data must be a Uint8Array.\");\n }\n if (typeof image.mimeType !== \"string\") {\n throw new TypeError(\"Each image.mimeType must be a string.\");\n }\n if (![\"coverFront\", \"coverBack\", \"unknown\"].includes(image.kind)) {\n throw new TypeError(\"Each image.kind must be 'coverFront', 'coverBack', or 'unknown'.\");\n }\n }\n }\n if (tags.comment !== void 0 && typeof tags.comment !== \"string\") {\n throw new TypeError(\"tags.comment, when provided, must be a string.\");\n }\n if (tags.raw !== void 0) {\n if (!tags.raw || typeof tags.raw !== \"object\") {\n throw new TypeError(\"tags.raw, when provided, must be an object.\");\n }\n for (const value of Object.values(tags.raw)) {\n if (value !== null && typeof value !== \"string\" && !(value instanceof Uint8Array) && !(value instanceof RichImageData) && !(value instanceof AttachedFile) && !isRecordStringString(value)) {\n throw new TypeError(\"Each value in tags.raw must be a string, Uint8Array, RichImageData, AttachedFile, Record, or null.\");\n }\n }\n }\n};\nvar validateTrackDisposition = (disposition) => {\n if (!disposition || typeof disposition !== \"object\") {\n throw new TypeError(\"disposition must be an object.\");\n }\n if (disposition.default !== void 0 && typeof disposition.default !== \"boolean\") {\n throw new TypeError(\"disposition.default must be a boolean.\");\n }\n if (disposition.primary !== void 0 && typeof disposition.primary !== \"boolean\") {\n throw new TypeError(\"disposition.primary must be a boolean.\");\n }\n if (disposition.forced !== void 0 && typeof disposition.forced !== \"boolean\") {\n throw new TypeError(\"disposition.forced must be a boolean.\");\n }\n if (disposition.original !== void 0 && typeof disposition.original !== \"boolean\") {\n throw new TypeError(\"disposition.original must be a boolean.\");\n }\n if (disposition.commentary !== void 0 && typeof disposition.commentary !== \"boolean\") {\n throw new TypeError(\"disposition.commentary must be a boolean.\");\n }\n if (disposition.hearingImpaired !== void 0 && typeof disposition.hearingImpaired !== \"boolean\") {\n throw new TypeError(\"disposition.hearingImpaired must be a boolean.\");\n }\n if (disposition.visuallyImpaired !== void 0 && typeof disposition.visuallyImpaired !== \"boolean\") {\n throw new TypeError(\"disposition.visuallyImpaired must be a boolean.\");\n }\n};\n\n// node_modules/mediabunny/dist/modules/shared/bitstream.js\nvar Bitstream = class _Bitstream {\n constructor(bytes2) {\n this.bytes = bytes2;\n this.pos = 0;\n }\n seekToByte(byteOffset) {\n this.pos = 8 * byteOffset;\n }\n readBit() {\n const byteIndex = Math.floor(this.pos / 8);\n const byte = this.bytes[byteIndex] ?? 0;\n const bitIndex = 7 - (this.pos & 7);\n const bit = (byte & 1 << bitIndex) >> bitIndex;\n this.pos++;\n return bit;\n }\n readBits(n2) {\n if (n2 === 1) {\n return this.readBit();\n }\n let result = 0;\n for (let i2 = 0; i2 < n2; i2++) {\n result <<= 1;\n result |= this.readBit();\n }\n return result;\n }\n writeBits(n2, value) {\n const end = this.pos + n2;\n for (let i2 = this.pos; i2 < end; i2++) {\n const byteIndex = Math.floor(i2 / 8);\n let byte = this.bytes[byteIndex];\n const bitIndex = 7 - (i2 & 7);\n byte &= ~(1 << bitIndex);\n byte |= (value & 1 << end - i2 - 1) >> end - i2 - 1 << bitIndex;\n this.bytes[byteIndex] = byte;\n }\n this.pos = end;\n }\n readAlignedByte() {\n if (this.pos % 8 !== 0) {\n throw new Error(\"Bitstream is not byte-aligned.\");\n }\n const byteIndex = this.pos / 8;\n const byte = this.bytes[byteIndex] ?? 0;\n this.pos += 8;\n return byte;\n }\n skipBits(n2) {\n this.pos += n2;\n }\n getBitsLeft() {\n return this.bytes.length * 8 - this.pos;\n }\n clone() {\n const clone = new _Bitstream(this.bytes);\n clone.pos = this.pos;\n return clone;\n }\n};\n\n// node_modules/mediabunny/dist/modules/shared/aac-misc.js\nvar aacFrequencyTable = [\n 96e3,\n 88200,\n 64e3,\n 48e3,\n 44100,\n 32e3,\n 24e3,\n 22050,\n 16e3,\n 12e3,\n 11025,\n 8e3,\n 7350\n];\nvar aacChannelMap = [-1, 1, 2, 3, 4, 5, 6, 8];\nvar buildAacAudioSpecificConfig = (config) => {\n let frequencyIndex = aacFrequencyTable.indexOf(config.sampleRate);\n let customSampleRate = null;\n if (frequencyIndex === -1) {\n frequencyIndex = 15;\n customSampleRate = config.sampleRate;\n }\n const channelConfiguration = aacChannelMap.indexOf(config.numberOfChannels);\n if (channelConfiguration === -1) {\n throw new TypeError(`Unsupported number of channels: ${config.numberOfChannels}`);\n }\n let bitCount = 5 + 4 + 4;\n if (config.objectType >= 32) {\n bitCount += 6;\n }\n if (frequencyIndex === 15) {\n bitCount += 24;\n }\n const byteCount = Math.ceil(bitCount / 8);\n const bytes2 = new Uint8Array(byteCount);\n const bitstream = new Bitstream(bytes2);\n if (config.objectType < 32) {\n bitstream.writeBits(5, config.objectType);\n } else {\n bitstream.writeBits(5, 31);\n bitstream.writeBits(6, config.objectType - 32);\n }\n bitstream.writeBits(4, frequencyIndex);\n if (frequencyIndex === 15) {\n bitstream.writeBits(24, customSampleRate);\n }\n bitstream.writeBits(4, channelConfiguration);\n return bytes2;\n};\n\n// node_modules/mediabunny/dist/modules/src/codec.js\nvar VIDEO_CODECS = [\n \"avc\",\n \"hevc\",\n \"vp9\",\n \"av1\",\n \"vp8\"\n];\nvar PCM_AUDIO_CODECS = [\n \"pcm-s16\",\n // We don't prefix 'le' so we're compatible with the WebCodecs-registered PCM codec strings\n \"pcm-s16be\",\n \"pcm-s24\",\n \"pcm-s24be\",\n \"pcm-s32\",\n \"pcm-s32be\",\n \"pcm-f32\",\n \"pcm-f32be\",\n \"pcm-f64\",\n \"pcm-f64be\",\n \"pcm-u8\",\n \"pcm-s8\",\n \"ulaw\",\n \"alaw\"\n];\nvar NON_PCM_AUDIO_CODECS = [\n \"aac\",\n \"opus\",\n \"mp3\",\n \"vorbis\",\n \"flac\",\n \"ac3\",\n \"eac3\"\n];\nvar AUDIO_CODECS = [\n ...NON_PCM_AUDIO_CODECS,\n ...PCM_AUDIO_CODECS\n];\nvar SUBTITLE_CODECS = [\n \"webvtt\"\n];\nvar AVC_LEVEL_TABLE = [\n { maxMacroblocks: 99, maxBitrate: 64e3, maxDpbMbs: 396, level: 10 },\n // Level 1\n { maxMacroblocks: 396, maxBitrate: 192e3, maxDpbMbs: 900, level: 11 },\n // Level 1.1\n { maxMacroblocks: 396, maxBitrate: 384e3, maxDpbMbs: 2376, level: 12 },\n // Level 1.2\n { maxMacroblocks: 396, maxBitrate: 768e3, maxDpbMbs: 2376, level: 13 },\n // Level 1.3\n { maxMacroblocks: 396, maxBitrate: 2e6, maxDpbMbs: 2376, level: 20 },\n // Level 2\n { maxMacroblocks: 792, maxBitrate: 4e6, maxDpbMbs: 4752, level: 21 },\n // Level 2.1\n { maxMacroblocks: 1620, maxBitrate: 4e6, maxDpbMbs: 8100, level: 22 },\n // Level 2.2\n { maxMacroblocks: 1620, maxBitrate: 1e7, maxDpbMbs: 8100, level: 30 },\n // Level 3\n { maxMacroblocks: 3600, maxBitrate: 14e6, maxDpbMbs: 18e3, level: 31 },\n // Level 3.1\n { maxMacroblocks: 5120, maxBitrate: 2e7, maxDpbMbs: 20480, level: 32 },\n // Level 3.2\n { maxMacroblocks: 8192, maxBitrate: 2e7, maxDpbMbs: 32768, level: 40 },\n // Level 4\n { maxMacroblocks: 8192, maxBitrate: 5e7, maxDpbMbs: 32768, level: 41 },\n // Level 4.1\n { maxMacroblocks: 8704, maxBitrate: 5e7, maxDpbMbs: 34816, level: 42 },\n // Level 4.2\n { maxMacroblocks: 22080, maxBitrate: 135e6, maxDpbMbs: 110400, level: 50 },\n // Level 5\n { maxMacroblocks: 36864, maxBitrate: 24e7, maxDpbMbs: 184320, level: 51 },\n // Level 5.1\n { maxMacroblocks: 36864, maxBitrate: 24e7, maxDpbMbs: 184320, level: 52 },\n // Level 5.2\n { maxMacroblocks: 139264, maxBitrate: 24e7, maxDpbMbs: 696320, level: 60 },\n // Level 6\n { maxMacroblocks: 139264, maxBitrate: 48e7, maxDpbMbs: 696320, level: 61 },\n // Level 6.1\n { maxMacroblocks: 139264, maxBitrate: 8e8, maxDpbMbs: 696320, level: 62 }\n // Level 6.2\n];\nvar HEVC_LEVEL_TABLE = [\n { maxPictureSize: 36864, maxBitrate: 128e3, tier: \"L\", level: 30 },\n // Level 1 (Low Tier)\n { maxPictureSize: 122880, maxBitrate: 15e5, tier: \"L\", level: 60 },\n // Level 2 (Low Tier)\n { maxPictureSize: 245760, maxBitrate: 3e6, tier: \"L\", level: 63 },\n // Level 2.1 (Low Tier)\n { maxPictureSize: 552960, maxBitrate: 6e6, tier: \"L\", level: 90 },\n // Level 3 (Low Tier)\n { maxPictureSize: 983040, maxBitrate: 1e7, tier: \"L\", level: 93 },\n // Level 3.1 (Low Tier)\n { maxPictureSize: 2228224, maxBitrate: 12e6, tier: \"L\", level: 120 },\n // Level 4 (Low Tier)\n { maxPictureSize: 2228224, maxBitrate: 3e7, tier: \"H\", level: 120 },\n // Level 4 (High Tier)\n { maxPictureSize: 2228224, maxBitrate: 2e7, tier: \"L\", level: 123 },\n // Level 4.1 (Low Tier)\n { maxPictureSize: 2228224, maxBitrate: 5e7, tier: \"H\", level: 123 },\n // Level 4.1 (High Tier)\n { maxPictureSize: 8912896, maxBitrate: 25e6, tier: \"L\", level: 150 },\n // Level 5 (Low Tier)\n { maxPictureSize: 8912896, maxBitrate: 1e8, tier: \"H\", level: 150 },\n // Level 5 (High Tier)\n { maxPictureSize: 8912896, maxBitrate: 4e7, tier: \"L\", level: 153 },\n // Level 5.1 (Low Tier)\n { maxPictureSize: 8912896, maxBitrate: 16e7, tier: \"H\", level: 153 },\n // Level 5.1 (High Tier)\n { maxPictureSize: 8912896, maxBitrate: 6e7, tier: \"L\", level: 156 },\n // Level 5.2 (Low Tier)\n { maxPictureSize: 8912896, maxBitrate: 24e7, tier: \"H\", level: 156 },\n // Level 5.2 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 6e7, tier: \"L\", level: 180 },\n // Level 6 (Low Tier)\n { maxPictureSize: 35651584, maxBitrate: 24e7, tier: \"H\", level: 180 },\n // Level 6 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 12e7, tier: \"L\", level: 183 },\n // Level 6.1 (Low Tier)\n { maxPictureSize: 35651584, maxBitrate: 48e7, tier: \"H\", level: 183 },\n // Level 6.1 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 24e7, tier: \"L\", level: 186 },\n // Level 6.2 (Low Tier)\n { maxPictureSize: 35651584, maxBitrate: 8e8, tier: \"H\", level: 186 }\n // Level 6.2 (High Tier)\n];\nvar VP9_LEVEL_TABLE = [\n { maxPictureSize: 36864, maxBitrate: 2e5, level: 10 },\n // Level 1\n { maxPictureSize: 73728, maxBitrate: 8e5, level: 11 },\n // Level 1.1\n { maxPictureSize: 122880, maxBitrate: 18e5, level: 20 },\n // Level 2\n { maxPictureSize: 245760, maxBitrate: 36e5, level: 21 },\n // Level 2.1\n { maxPictureSize: 552960, maxBitrate: 72e5, level: 30 },\n // Level 3\n { maxPictureSize: 983040, maxBitrate: 12e6, level: 31 },\n // Level 3.1\n { maxPictureSize: 2228224, maxBitrate: 18e6, level: 40 },\n // Level 4\n { maxPictureSize: 2228224, maxBitrate: 3e7, level: 41 },\n // Level 4.1\n { maxPictureSize: 8912896, maxBitrate: 6e7, level: 50 },\n // Level 5\n { maxPictureSize: 8912896, maxBitrate: 12e7, level: 51 },\n // Level 5.1\n { maxPictureSize: 8912896, maxBitrate: 18e7, level: 52 },\n // Level 5.2\n { maxPictureSize: 35651584, maxBitrate: 18e7, level: 60 },\n // Level 6\n { maxPictureSize: 35651584, maxBitrate: 24e7, level: 61 },\n // Level 6.1\n { maxPictureSize: 35651584, maxBitrate: 48e7, level: 62 }\n // Level 6.2\n];\nvar AV1_LEVEL_TABLE = [\n { maxPictureSize: 147456, maxBitrate: 15e5, tier: \"M\", level: 0 },\n // Level 2.0 (Main Tier)\n { maxPictureSize: 278784, maxBitrate: 3e6, tier: \"M\", level: 1 },\n // Level 2.1 (Main Tier)\n { maxPictureSize: 665856, maxBitrate: 6e6, tier: \"M\", level: 4 },\n // Level 3.0 (Main Tier)\n { maxPictureSize: 1065024, maxBitrate: 1e7, tier: \"M\", level: 5 },\n // Level 3.1 (Main Tier)\n { maxPictureSize: 2359296, maxBitrate: 12e6, tier: \"M\", level: 8 },\n // Level 4.0 (Main Tier)\n { maxPictureSize: 2359296, maxBitrate: 3e7, tier: \"H\", level: 8 },\n // Level 4.0 (High Tier)\n { maxPictureSize: 2359296, maxBitrate: 2e7, tier: \"M\", level: 9 },\n // Level 4.1 (Main Tier)\n { maxPictureSize: 2359296, maxBitrate: 5e7, tier: \"H\", level: 9 },\n // Level 4.1 (High Tier)\n { maxPictureSize: 8912896, maxBitrate: 3e7, tier: \"M\", level: 12 },\n // Level 5.0 (Main Tier)\n { maxPictureSize: 8912896, maxBitrate: 1e8, tier: \"H\", level: 12 },\n // Level 5.0 (High Tier)\n { maxPictureSize: 8912896, maxBitrate: 4e7, tier: \"M\", level: 13 },\n // Level 5.1 (Main Tier)\n { maxPictureSize: 8912896, maxBitrate: 16e7, tier: \"H\", level: 13 },\n // Level 5.1 (High Tier)\n { maxPictureSize: 8912896, maxBitrate: 6e7, tier: \"M\", level: 14 },\n // Level 5.2 (Main Tier)\n { maxPictureSize: 8912896, maxBitrate: 24e7, tier: \"H\", level: 14 },\n // Level 5.2 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 6e7, tier: \"M\", level: 15 },\n // Level 5.3 (Main Tier)\n { maxPictureSize: 35651584, maxBitrate: 24e7, tier: \"H\", level: 15 },\n // Level 5.3 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 6e7, tier: \"M\", level: 16 },\n // Level 6.0 (Main Tier)\n { maxPictureSize: 35651584, maxBitrate: 24e7, tier: \"H\", level: 16 },\n // Level 6.0 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 1e8, tier: \"M\", level: 17 },\n // Level 6.1 (Main Tier)\n { maxPictureSize: 35651584, maxBitrate: 48e7, tier: \"H\", level: 17 },\n // Level 6.1 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 16e7, tier: \"M\", level: 18 },\n // Level 6.2 (Main Tier)\n { maxPictureSize: 35651584, maxBitrate: 8e8, tier: \"H\", level: 18 },\n // Level 6.2 (High Tier)\n { maxPictureSize: 35651584, maxBitrate: 16e7, tier: \"M\", level: 19 },\n // Level 6.3 (Main Tier)\n { maxPictureSize: 35651584, maxBitrate: 8e8, tier: \"H\", level: 19 }\n // Level 6.3 (High Tier)\n];\nvar buildVideoCodecString = (codec, width, height, bitrate) => {\n if (codec === \"avc\") {\n const profileIndication = 100;\n const totalMacroblocks = Math.ceil(width / 16) * Math.ceil(height / 16);\n const levelInfo = AVC_LEVEL_TABLE.find((level) => totalMacroblocks <= level.maxMacroblocks && bitrate <= level.maxBitrate) ?? last(AVC_LEVEL_TABLE);\n const levelIndication = levelInfo ? levelInfo.level : 0;\n const hexProfileIndication = profileIndication.toString(16).padStart(2, \"0\");\n const hexProfileCompatibility = \"00\";\n const hexLevelIndication = levelIndication.toString(16).padStart(2, \"0\");\n return `avc1.${hexProfileIndication}${hexProfileCompatibility}${hexLevelIndication}`;\n } else if (codec === \"hevc\") {\n const profilePrefix = \"\";\n const profileIdc = 1;\n const compatibilityFlags = \"6\";\n const pictureSize = width * height;\n const levelInfo = HEVC_LEVEL_TABLE.find((level) => pictureSize <= level.maxPictureSize && bitrate <= level.maxBitrate) ?? last(HEVC_LEVEL_TABLE);\n const constraintFlags = \"B0\";\n return `hev1.${profilePrefix}${profileIdc}.${compatibilityFlags}.${levelInfo.tier}${levelInfo.level}.${constraintFlags}`;\n } else if (codec === \"vp8\") {\n return \"vp8\";\n } else if (codec === \"vp9\") {\n const profile = \"00\";\n const pictureSize = width * height;\n const levelInfo = VP9_LEVEL_TABLE.find((level) => pictureSize <= level.maxPictureSize && bitrate <= level.maxBitrate) ?? last(VP9_LEVEL_TABLE);\n const bitDepth = \"08\";\n return `vp09.${profile}.${levelInfo.level.toString().padStart(2, \"0\")}.${bitDepth}`;\n } else if (codec === \"av1\") {\n const profile = 0;\n const pictureSize = width * height;\n const levelInfo = AV1_LEVEL_TABLE.find((level2) => pictureSize <= level2.maxPictureSize && bitrate <= level2.maxBitrate) ?? last(AV1_LEVEL_TABLE);\n const level = levelInfo.level.toString().padStart(2, \"0\");\n const bitDepth = \"08\";\n return `av01.${profile}.${level}${levelInfo.tier}.${bitDepth}`;\n }\n throw new TypeError(`Unhandled codec '${codec}'.`);\n};\nvar generateVp9CodecConfigurationFromCodecString = (codecString) => {\n const parts = codecString.split(\".\");\n const profile = Number(parts[1]);\n const level = Number(parts[2]);\n const bitDepth = Number(parts[3]);\n const chromaSubsampling = parts[4] ? Number(parts[4]) : 1;\n return [\n 1,\n 1,\n profile,\n 2,\n 1,\n level,\n 3,\n 1,\n bitDepth,\n 4,\n 1,\n chromaSubsampling\n ];\n};\nvar generateAv1CodecConfigurationFromCodecString = (codecString) => {\n const parts = codecString.split(\".\");\n const marker = 1;\n const version = 1;\n const firstByte = (marker << 7) + version;\n const profile = Number(parts[1]);\n const levelAndTier = parts[2];\n const level = Number(levelAndTier.slice(0, -1));\n const secondByte = (profile << 5) + level;\n const tier = levelAndTier.slice(-1) === \"H\" ? 1 : 0;\n const bitDepth = Number(parts[3]);\n const highBitDepth = bitDepth === 8 ? 0 : 1;\n const twelveBit = 0;\n const monochrome = parts[4] ? Number(parts[4]) : 0;\n const chromaSubsamplingX = parts[5] ? Number(parts[5][0]) : 1;\n const chromaSubsamplingY = parts[5] ? Number(parts[5][1]) : 1;\n const chromaSamplePosition = parts[5] ? Number(parts[5][2]) : 0;\n const thirdByte = (tier << 7) + (highBitDepth << 6) + (twelveBit << 5) + (monochrome << 4) + (chromaSubsamplingX << 3) + (chromaSubsamplingY << 2) + chromaSamplePosition;\n const initialPresentationDelayPresent = 0;\n const fourthByte = initialPresentationDelayPresent;\n return [firstByte, secondByte, thirdByte, fourthByte];\n};\nvar OPUS_SAMPLE_RATE = 48e3;\nvar PCM_CODEC_REGEX = /^pcm-([usf])(\\d+)(be)?$/;\nvar parsePcmCodec = (codec) => {\n assert(PCM_AUDIO_CODECS.includes(codec));\n if (codec === \"ulaw\") {\n return { dataType: \"ulaw\", sampleSize: 1, littleEndian: true, silentValue: 255 };\n } else if (codec === \"alaw\") {\n return { dataType: \"alaw\", sampleSize: 1, littleEndian: true, silentValue: 213 };\n }\n const match = PCM_CODEC_REGEX.exec(codec);\n assert(match);\n let dataType;\n if (match[1] === \"u\") {\n dataType = \"unsigned\";\n } else if (match[1] === \"s\") {\n dataType = \"signed\";\n } else {\n dataType = \"float\";\n }\n const sampleSize = Number(match[2]) / 8;\n const littleEndian = match[3] !== \"be\";\n const silentValue = codec === \"pcm-u8\" ? 2 ** 7 : 0;\n return { dataType, sampleSize, littleEndian, silentValue };\n};\nvar inferCodecFromCodecString = (codecString) => {\n if (codecString.startsWith(\"avc1\") || codecString.startsWith(\"avc3\")) {\n return \"avc\";\n } else if (codecString.startsWith(\"hev1\") || codecString.startsWith(\"hvc1\")) {\n return \"hevc\";\n } else if (codecString === \"vp8\") {\n return \"vp8\";\n } else if (codecString.startsWith(\"vp09\")) {\n return \"vp9\";\n } else if (codecString.startsWith(\"av01\")) {\n return \"av1\";\n }\n if (codecString === \"mp3\" || codecString === \"mp4a.69\" || codecString === \"mp4a.6B\" || codecString === \"mp4a.6b\" || codecString === \"mp4a.40.34\") {\n return \"mp3\";\n } else if (codecString.startsWith(\"mp4a.40.\") || codecString === \"mp4a.67\") {\n return \"aac\";\n } else if (codecString === \"opus\") {\n return \"opus\";\n } else if (codecString === \"vorbis\") {\n return \"vorbis\";\n } else if (codecString === \"flac\") {\n return \"flac\";\n } else if (codecString === \"ac-3\" || codecString === \"ac3\") {\n return \"ac3\";\n } else if (codecString === \"ec-3\" || codecString === \"eac3\") {\n return \"eac3\";\n } else if (codecString === \"ulaw\") {\n return \"ulaw\";\n } else if (codecString === \"alaw\") {\n return \"alaw\";\n } else if (PCM_CODEC_REGEX.test(codecString)) {\n return codecString;\n }\n if (codecString === \"webvtt\") {\n return \"webvtt\";\n }\n return null;\n};\nvar getVideoEncoderConfigExtension = (codec) => {\n if (codec === \"avc\") {\n return {\n avc: {\n format: \"avc\"\n // Ensure the format is not Annex B\n }\n };\n } else if (codec === \"hevc\") {\n return {\n hevc: {\n format: \"hevc\"\n // Ensure the format is not Annex B\n }\n };\n }\n return {};\n};\nvar VALID_VIDEO_CODEC_STRING_PREFIXES = [\"avc1\", \"avc3\", \"hev1\", \"hvc1\", \"vp8\", \"vp09\", \"av01\"];\nvar AVC_CODEC_STRING_REGEX = /^(avc1|avc3)\\.[0-9a-fA-F]{6}$/;\nvar HEVC_CODEC_STRING_REGEX = /^(hev1|hvc1)\\.(?:[ABC]?\\d+)\\.[0-9a-fA-F]{1,8}\\.[LH]\\d+(?:\\.[0-9a-fA-F]{1,2}){0,6}$/;\nvar VP9_CODEC_STRING_REGEX = /^vp09(?:\\.\\d{2}){3}(?:(?:\\.\\d{2}){5})?$/;\nvar AV1_CODEC_STRING_REGEX = /^av01\\.\\d\\.\\d{2}[MH]\\.\\d{2}(?:\\.\\d\\.\\d{3}\\.\\d{2}\\.\\d{2}\\.\\d{2}\\.\\d)?$/;\nvar validateVideoChunkMetadata = (metadata) => {\n if (!metadata) {\n throw new TypeError(\"Video chunk metadata must be provided.\");\n }\n if (typeof metadata !== \"object\") {\n throw new TypeError(\"Video chunk metadata must be an object.\");\n }\n if (!metadata.decoderConfig) {\n throw new TypeError(\"Video chunk metadata must include a decoder configuration.\");\n }\n if (typeof metadata.decoderConfig !== \"object\") {\n throw new TypeError(\"Video chunk metadata decoder configuration must be an object.\");\n }\n if (typeof metadata.decoderConfig.codec !== \"string\") {\n throw new TypeError(\"Video chunk metadata decoder configuration must specify a codec string.\");\n }\n if (!VALID_VIDEO_CODEC_STRING_PREFIXES.some((prefix) => metadata.decoderConfig.codec.startsWith(prefix))) {\n throw new TypeError(\"Video chunk metadata decoder configuration codec string must be a valid video codec string as specified in the Mediabunny Codec Registry.\");\n }\n if (!Number.isInteger(metadata.decoderConfig.codedWidth) || metadata.decoderConfig.codedWidth <= 0) {\n throw new TypeError(\"Video chunk metadata decoder configuration must specify a valid codedWidth (positive integer).\");\n }\n if (!Number.isInteger(metadata.decoderConfig.codedHeight) || metadata.decoderConfig.codedHeight <= 0) {\n throw new TypeError(\"Video chunk metadata decoder configuration must specify a valid codedHeight (positive integer).\");\n }\n if (metadata.decoderConfig.displayAspectWidth !== void 0 && (!Number.isInteger(metadata.decoderConfig.displayAspectWidth) || metadata.decoderConfig.displayAspectWidth <= 0)) {\n throw new TypeError(\"Video chunk metadata decoder configuration displayAspectWidth, when defined, must be a positive integer.\");\n }\n if (metadata.decoderConfig.displayAspectHeight !== void 0 && (!Number.isInteger(metadata.decoderConfig.displayAspectHeight) || metadata.decoderConfig.displayAspectHeight <= 0)) {\n throw new TypeError(\"Video chunk metadata decoder configuration displayAspectHeight, when defined, must be a positive integer.\");\n }\n if (metadata.decoderConfig.displayAspectWidth !== void 0 !== (metadata.decoderConfig.displayAspectHeight !== void 0)) {\n throw new TypeError(\"Video chunk metadata decoder configuration must specify both displayAspectWidth and displayAspectHeight, or neither.\");\n }\n if (metadata.decoderConfig.description !== void 0) {\n if (!isAllowSharedBufferSource(metadata.decoderConfig.description)) {\n throw new TypeError(\"Video chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view.\");\n }\n }\n if (metadata.decoderConfig.colorSpace !== void 0) {\n const { colorSpace } = metadata.decoderConfig;\n if (typeof colorSpace !== \"object\") {\n throw new TypeError(\"Video chunk metadata decoder configuration colorSpace, when provided, must be an object.\");\n }\n const primariesValues = Object.keys(COLOR_PRIMARIES_MAP);\n if (colorSpace.primaries != null && !primariesValues.includes(colorSpace.primaries)) {\n throw new TypeError(`Video chunk metadata decoder configuration colorSpace primaries, when defined, must be one of ${primariesValues.join(\", \")}.`);\n }\n const transferValues = Object.keys(TRANSFER_CHARACTERISTICS_MAP);\n if (colorSpace.transfer != null && !transferValues.includes(colorSpace.transfer)) {\n throw new TypeError(`Video chunk metadata decoder configuration colorSpace transfer, when defined, must be one of ${transferValues.join(\", \")}.`);\n }\n const matrixValues = Object.keys(MATRIX_COEFFICIENTS_MAP);\n if (colorSpace.matrix != null && !matrixValues.includes(colorSpace.matrix)) {\n throw new TypeError(`Video chunk metadata decoder configuration colorSpace matrix, when defined, must be one of ${matrixValues.join(\", \")}.`);\n }\n if (colorSpace.fullRange != null && typeof colorSpace.fullRange !== \"boolean\") {\n throw new TypeError(\"Video chunk metadata decoder configuration colorSpace fullRange, when defined, must be a boolean.\");\n }\n }\n if (metadata.decoderConfig.codec.startsWith(\"avc1\") || metadata.decoderConfig.codec.startsWith(\"avc3\")) {\n if (!AVC_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {\n 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.\");\n }\n } else if (metadata.decoderConfig.codec.startsWith(\"hev1\") || metadata.decoderConfig.codec.startsWith(\"hvc1\")) {\n if (!HEVC_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {\n 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.\");\n }\n } else if (metadata.decoderConfig.codec.startsWith(\"vp8\")) {\n if (metadata.decoderConfig.codec !== \"vp8\") {\n throw new TypeError('Video chunk metadata decoder configuration codec string for VP8 must be \"vp8\".');\n }\n } else if (metadata.decoderConfig.codec.startsWith(\"vp09\")) {\n if (!VP9_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {\n 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/.');\n }\n } else if (metadata.decoderConfig.codec.startsWith(\"av01\")) {\n if (!AV1_CODEC_STRING_REGEX.test(metadata.decoderConfig.codec)) {\n 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/.');\n }\n }\n};\nvar VALID_AUDIO_CODEC_STRING_PREFIXES = [\n \"mp4a\",\n \"mp3\",\n \"opus\",\n \"vorbis\",\n \"flac\",\n \"ulaw\",\n \"alaw\",\n \"pcm\",\n \"ac-3\",\n \"ec-3\"\n];\nvar validateAudioChunkMetadata = (metadata) => {\n if (!metadata) {\n throw new TypeError(\"Audio chunk metadata must be provided.\");\n }\n if (typeof metadata !== \"object\") {\n throw new TypeError(\"Audio chunk metadata must be an object.\");\n }\n if (!metadata.decoderConfig) {\n throw new TypeError(\"Audio chunk metadata must include a decoder configuration.\");\n }\n if (typeof metadata.decoderConfig !== \"object\") {\n throw new TypeError(\"Audio chunk metadata decoder configuration must be an object.\");\n }\n if (typeof metadata.decoderConfig.codec !== \"string\") {\n throw new TypeError(\"Audio chunk metadata decoder configuration must specify a codec string.\");\n }\n if (!VALID_AUDIO_CODEC_STRING_PREFIXES.some((prefix) => metadata.decoderConfig.codec.startsWith(prefix))) {\n throw new TypeError(\"Audio chunk metadata decoder configuration codec string must be a valid audio codec string as specified in the Mediabunny Codec Registry.\");\n }\n if (!Number.isInteger(metadata.decoderConfig.sampleRate) || metadata.decoderConfig.sampleRate <= 0) {\n throw new TypeError(\"Audio chunk metadata decoder configuration must specify a valid sampleRate (positive integer).\");\n }\n if (!Number.isInteger(metadata.decoderConfig.numberOfChannels) || metadata.decoderConfig.numberOfChannels <= 0) {\n throw new TypeError(\"Audio chunk metadata decoder configuration must specify a valid numberOfChannels (positive integer).\");\n }\n if (metadata.decoderConfig.description !== void 0) {\n if (!isAllowSharedBufferSource(metadata.decoderConfig.description)) {\n throw new TypeError(\"Audio chunk metadata decoder configuration description, when defined, must be an ArrayBuffer or an ArrayBuffer view.\");\n }\n }\n if (metadata.decoderConfig.codec.startsWith(\"mp4a\") && metadata.decoderConfig.codec !== \"mp4a.69\" && metadata.decoderConfig.codec !== \"mp4a.6B\" && metadata.decoderConfig.codec !== \"mp4a.6b\") {\n const validStrings = [\"mp4a.40.2\", \"mp4a.40.02\", \"mp4a.40.5\", \"mp4a.40.05\", \"mp4a.40.29\", \"mp4a.67\"];\n if (!validStrings.includes(metadata.decoderConfig.codec)) {\n 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/.\");\n }\n } else if (metadata.decoderConfig.codec.startsWith(\"mp3\") || metadata.decoderConfig.codec.startsWith(\"mp4a\")) {\n if (metadata.decoderConfig.codec !== \"mp3\" && metadata.decoderConfig.codec !== \"mp4a.69\" && metadata.decoderConfig.codec !== \"mp4a.6B\" && metadata.decoderConfig.codec !== \"mp4a.6b\") {\n throw new TypeError('Audio chunk metadata decoder configuration codec string for MP3 must be \"mp3\", \"mp4a.69\" or \"mp4a.6B\".');\n }\n } else if (metadata.decoderConfig.codec.startsWith(\"opus\")) {\n if (metadata.decoderConfig.codec !== \"opus\") {\n throw new TypeError('Audio chunk metadata decoder configuration codec string for Opus must be \"opus\".');\n }\n if (metadata.decoderConfig.description && metadata.decoderConfig.description.byteLength < 18) {\n 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.\");\n }\n } else if (metadata.decoderConfig.codec.startsWith(\"vorbis\")) {\n if (metadata.decoderConfig.codec !== \"vorbis\") {\n throw new TypeError('Audio chunk metadata decoder configuration codec string for Vorbis must be \"vorbis\".');\n }\n if (!metadata.decoderConfig.description) {\n 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/.\");\n }\n } else if (metadata.decoderConfig.codec.startsWith(\"flac\")) {\n if (metadata.decoderConfig.codec !== \"flac\") {\n throw new TypeError('Audio chunk metadata decoder configuration codec string for FLAC must be \"flac\".');\n }\n const minDescriptionSize = 4 + 4 + 34;\n if (!metadata.decoderConfig.description || metadata.decoderConfig.description.byteLength < minDescriptionSize) {\n 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/.\");\n }\n } else if (metadata.decoderConfig.codec.startsWith(\"ac-3\") || metadata.decoderConfig.codec.startsWith(\"ac3\")) {\n if (metadata.decoderConfig.codec !== \"ac-3\") {\n throw new TypeError('Audio chunk metadata decoder configuration codec string for AC-3 must be \"ac-3\".');\n }\n } else if (metadata.decoderConfig.codec.startsWith(\"ec-3\") || metadata.decoderConfig.codec.startsWith(\"eac3\")) {\n if (metadata.decoderConfig.codec !== \"ec-3\") {\n throw new TypeError('Audio chunk metadata decoder configuration codec string for EC-3 must be \"ec-3\".');\n }\n } else if (metadata.decoderConfig.codec.startsWith(\"pcm\") || metadata.decoderConfig.codec.startsWith(\"ulaw\") || metadata.decoderConfig.codec.startsWith(\"alaw\")) {\n if (!PCM_AUDIO_CODECS.includes(metadata.decoderConfig.codec)) {\n throw new TypeError(`Audio chunk metadata decoder configuration codec string for PCM must be one of the supported PCM codecs (${PCM_AUDIO_CODECS.join(\", \")}).`);\n }\n }\n};\nvar validateSubtitleMetadata = (metadata) => {\n if (!metadata) {\n throw new TypeError(\"Subtitle metadata must be provided.\");\n }\n if (typeof metadata !== \"object\") {\n throw new TypeError(\"Subtitle metadata must be an object.\");\n }\n if (!metadata.config) {\n throw new TypeError(\"Subtitle metadata must include a config object.\");\n }\n if (typeof metadata.config !== \"object\") {\n throw new TypeError(\"Subtitle metadata config must be an object.\");\n }\n if (typeof metadata.config.description !== \"string\") {\n throw new TypeError(\"Subtitle metadata config description must be a string.\");\n }\n};\n\n// node_modules/mediabunny/dist/modules/shared/ac3-misc.js\nvar AC3_SAMPLE_RATES = [48e3, 44100, 32e3];\nvar EAC3_REDUCED_SAMPLE_RATES = [24e3, 22050, 16e3];\n\n// node_modules/mediabunny/dist/modules/src/codec-data.js\nvar AvcNalUnitType;\n(function(AvcNalUnitType2) {\n AvcNalUnitType2[AvcNalUnitType2[\"NON_IDR_SLICE\"] = 1] = \"NON_IDR_SLICE\";\n AvcNalUnitType2[AvcNalUnitType2[\"SLICE_DPA\"] = 2] = \"SLICE_DPA\";\n AvcNalUnitType2[AvcNalUnitType2[\"SLICE_DPB\"] = 3] = \"SLICE_DPB\";\n AvcNalUnitType2[AvcNalUnitType2[\"SLICE_DPC\"] = 4] = \"SLICE_DPC\";\n AvcNalUnitType2[AvcNalUnitType2[\"IDR\"] = 5] = \"IDR\";\n AvcNalUnitType2[AvcNalUnitType2[\"SEI\"] = 6] = \"SEI\";\n AvcNalUnitType2[AvcNalUnitType2[\"SPS\"] = 7] = \"SPS\";\n AvcNalUnitType2[AvcNalUnitType2[\"PPS\"] = 8] = \"PPS\";\n AvcNalUnitType2[AvcNalUnitType2[\"AUD\"] = 9] = \"AUD\";\n AvcNalUnitType2[AvcNalUnitType2[\"SPS_EXT\"] = 13] = \"SPS_EXT\";\n})(AvcNalUnitType || (AvcNalUnitType = {}));\nvar HevcNalUnitType;\n(function(HevcNalUnitType2) {\n HevcNalUnitType2[HevcNalUnitType2[\"RASL_N\"] = 8] = \"RASL_N\";\n HevcNalUnitType2[HevcNalUnitType2[\"RASL_R\"] = 9] = \"RASL_R\";\n HevcNalUnitType2[HevcNalUnitType2[\"BLA_W_LP\"] = 16] = \"BLA_W_LP\";\n HevcNalUnitType2[HevcNalUnitType2[\"RSV_IRAP_VCL23\"] = 23] = \"RSV_IRAP_VCL23\";\n HevcNalUnitType2[HevcNalUnitType2[\"VPS_NUT\"] = 32] = \"VPS_NUT\";\n HevcNalUnitType2[HevcNalUnitType2[\"SPS_NUT\"] = 33] = \"SPS_NUT\";\n HevcNalUnitType2[HevcNalUnitType2[\"PPS_NUT\"] = 34] = \"PPS_NUT\";\n HevcNalUnitType2[HevcNalUnitType2[\"AUD_NUT\"] = 35] = \"AUD_NUT\";\n HevcNalUnitType2[HevcNalUnitType2[\"PREFIX_SEI_NUT\"] = 39] = \"PREFIX_SEI_NUT\";\n HevcNalUnitType2[HevcNalUnitType2[\"SUFFIX_SEI_NUT\"] = 40] = \"SUFFIX_SEI_NUT\";\n})(HevcNalUnitType || (HevcNalUnitType = {}));\nvar iterateNalUnitsInAnnexB = function* (packetData) {\n let i2 = 0;\n let nalStart = -1;\n while (i2 < packetData.length - 2) {\n const zeroIndex = packetData.indexOf(0, i2);\n if (zeroIndex === -1 || zeroIndex >= packetData.length - 2) {\n break;\n }\n i2 = zeroIndex;\n let startCodeLength = 0;\n if (i2 + 3 < packetData.length && packetData[i2 + 1] === 0 && packetData[i2 + 2] === 0 && packetData[i2 + 3] === 1) {\n startCodeLength = 4;\n } else if (packetData[i2 + 1] === 0 && packetData[i2 + 2] === 1) {\n startCodeLength = 3;\n }\n if (startCodeLength === 0) {\n i2++;\n continue;\n }\n if (nalStart !== -1 && i2 > nalStart) {\n yield {\n offset: nalStart,\n length: i2 - nalStart\n };\n }\n nalStart = i2 + startCodeLength;\n i2 = nalStart;\n }\n if (nalStart !== -1 && nalStart < packetData.length) {\n yield {\n offset: nalStart,\n length: packetData.length - nalStart\n };\n }\n};\nvar iterateNalUnitsInLengthPrefixed = function* (packetData, lengthSize) {\n let offset = 0;\n const dataView = new DataView(packetData.buffer, packetData.byteOffset, packetData.byteLength);\n while (offset + lengthSize <= packetData.length) {\n let nalUnitLength;\n if (lengthSize === 1) {\n nalUnitLength = dataView.getUint8(offset);\n } else if (lengthSize === 2) {\n nalUnitLength = dataView.getUint16(offset, false);\n } else if (lengthSize === 3) {\n nalUnitLength = getUint24(dataView, offset, false);\n } else {\n assert(lengthSize === 4);\n nalUnitLength = dataView.getUint32(offset, false);\n }\n offset += lengthSize;\n yield {\n offset,\n length: nalUnitLength\n };\n offset += nalUnitLength;\n }\n};\nvar iterateAvcNalUnits = (packetData, decoderConfig) => {\n if (decoderConfig.description) {\n const bytes2 = toUint8Array(decoderConfig.description);\n const lengthSizeMinusOne = bytes2[4] & 3;\n const lengthSize = lengthSizeMinusOne + 1;\n return iterateNalUnitsInLengthPrefixed(packetData, lengthSize);\n } else {\n return iterateNalUnitsInAnnexB(packetData);\n }\n};\nvar extractNalUnitTypeForAvc = (byte) => {\n return byte & 31;\n};\nvar removeEmulationPreventionBytes = (data) => {\n const result = [];\n const len = data.length;\n for (let i2 = 0; i2 < len; i2++) {\n if (i2 + 2 < len && data[i2] === 0 && data[i2 + 1] === 0 && data[i2 + 2] === 3) {\n result.push(0, 0);\n i2 += 2;\n } else {\n result.push(data[i2]);\n }\n }\n return new Uint8Array(result);\n};\nvar ANNEX_B_START_CODE = new Uint8Array([0, 0, 0, 1]);\nvar concatNalUnitsInLengthPrefixed = (nalUnits, lengthSize) => {\n const totalLength = nalUnits.reduce((a2, b) => a2 + lengthSize + b.byteLength, 0);\n const result = new Uint8Array(totalLength);\n let offset = 0;\n for (const nalUnit of nalUnits) {\n const dataView = new DataView(result.buffer, result.byteOffset, result.byteLength);\n switch (lengthSize) {\n case 1:\n dataView.setUint8(offset, nalUnit.byteLength);\n break;\n case 2:\n dataView.setUint16(offset, nalUnit.byteLength, false);\n break;\n case 3:\n setUint24(dataView, offset, nalUnit.byteLength, false);\n break;\n case 4:\n dataView.setUint32(offset, nalUnit.byteLength, false);\n break;\n }\n offset += lengthSize;\n result.set(nalUnit, offset);\n offset += nalUnit.byteLength;\n }\n return result;\n};\nvar extractAvcDecoderConfigurationRecord = (packetData) => {\n try {\n const spsUnits = [];\n const ppsUnits = [];\n const spsExtUnits = [];\n for (const loc of iterateNalUnitsInAnnexB(packetData)) {\n const nalUnit = packetData.subarray(loc.offset, loc.offset + loc.length);\n const type = extractNalUnitTypeForAvc(nalUnit[0]);\n if (type === AvcNalUnitType.SPS) {\n spsUnits.push(nalUnit);\n } else if (type === AvcNalUnitType.PPS) {\n ppsUnits.push(nalUnit);\n } else if (type === AvcNalUnitType.SPS_EXT) {\n spsExtUnits.push(nalUnit);\n }\n }\n if (spsUnits.length === 0) {\n return null;\n }\n if (ppsUnits.length === 0) {\n return null;\n }\n const spsData = spsUnits[0];\n const spsInfo = parseAvcSps(spsData);\n assert(spsInfo !== null);\n const hasExtendedData = spsInfo.profileIdc === 100 || spsInfo.profileIdc === 110 || spsInfo.profileIdc === 122 || spsInfo.profileIdc === 144;\n return {\n configurationVersion: 1,\n avcProfileIndication: spsInfo.profileIdc,\n profileCompatibility: spsInfo.constraintFlags,\n avcLevelIndication: spsInfo.levelIdc,\n lengthSizeMinusOne: 3,\n // Typically 4 bytes for length field\n sequenceParameterSets: spsUnits,\n pictureParameterSets: ppsUnits,\n chromaFormat: hasExtendedData ? spsInfo.chromaFormatIdc : null,\n bitDepthLumaMinus8: hasExtendedData ? spsInfo.bitDepthLumaMinus8 : null,\n bitDepthChromaMinus8: hasExtendedData ? spsInfo.bitDepthChromaMinus8 : null,\n sequenceParameterSetExt: hasExtendedData ? spsExtUnits : null\n };\n } catch (error) {\n Logging._error(\"Error building AVC Decoder Configuration Record:\", error);\n return null;\n }\n};\nvar serializeAvcDecoderConfigurationRecord = (record) => {\n const bytes2 = [];\n bytes2.push(record.configurationVersion);\n bytes2.push(record.avcProfileIndication);\n bytes2.push(record.profileCompatibility);\n bytes2.push(record.avcLevelIndication);\n bytes2.push(252 | record.lengthSizeMinusOne & 3);\n bytes2.push(224 | record.sequenceParameterSets.length & 31);\n for (const sps of record.sequenceParameterSets) {\n const length = sps.byteLength;\n bytes2.push(length >> 8);\n bytes2.push(length & 255);\n for (let i2 = 0; i2 < length; i2++) {\n bytes2.push(sps[i2]);\n }\n }\n bytes2.push(record.pictureParameterSets.length);\n for (const pps of record.pictureParameterSets) {\n const length = pps.byteLength;\n bytes2.push(length >> 8);\n bytes2.push(length & 255);\n for (let i2 = 0; i2 < length; i2++) {\n bytes2.push(pps[i2]);\n }\n }\n if (record.avcProfileIndication === 100 || record.avcProfileIndication === 110 || record.avcProfileIndication === 122 || record.avcProfileIndication === 144) {\n assert(record.chromaFormat !== null);\n assert(record.bitDepthLumaMinus8 !== null);\n assert(record.bitDepthChromaMinus8 !== null);\n assert(record.sequenceParameterSetExt !== null);\n bytes2.push(252 | record.chromaFormat & 3);\n bytes2.push(248 | record.bitDepthLumaMinus8 & 7);\n bytes2.push(248 | record.bitDepthChromaMinus8 & 7);\n bytes2.push(record.sequenceParameterSetExt.length);\n for (const spsExt of record.sequenceParameterSetExt) {\n const length = spsExt.byteLength;\n bytes2.push(length >> 8);\n bytes2.push(length & 255);\n for (let i2 = 0; i2 < length; i2++) {\n bytes2.push(spsExt[i2]);\n }\n }\n }\n return new Uint8Array(bytes2);\n};\nvar AVC_HEVC_ASPECT_RATIO_IDC_TABLE = {\n 1: { num: 1, den: 1 },\n 2: { num: 12, den: 11 },\n 3: { num: 10, den: 11 },\n 4: { num: 16, den: 11 },\n 5: { num: 40, den: 33 },\n 6: { num: 24, den: 11 },\n 7: { num: 20, den: 11 },\n 8: { num: 32, den: 11 },\n 9: { num: 80, den: 33 },\n 10: { num: 18, den: 11 },\n 11: { num: 15, den: 11 },\n 12: { num: 64, den: 33 },\n 13: { num: 160, den: 99 },\n 14: { num: 4, den: 3 },\n 15: { num: 3, den: 2 },\n 16: { num: 2, den: 1 }\n};\nvar parseAvcSps = (sps) => {\n try {\n const bitstream = new Bitstream(removeEmulationPreventionBytes(sps));\n bitstream.skipBits(1);\n bitstream.skipBits(2);\n const nalUnitType = bitstream.readBits(5);\n if (nalUnitType !== 7) {\n return null;\n }\n const profileIdc = bitstream.readAlignedByte();\n const constraintFlags = bitstream.readAlignedByte();\n const levelIdc = bitstream.readAlignedByte();\n readExpGolomb(bitstream);\n let chromaFormatIdc = 1;\n let bitDepthLumaMinus8 = 0;\n let bitDepthChromaMinus8 = 0;\n let separateColourPlaneFlag = 0;\n if (profileIdc === 100 || profileIdc === 110 || profileIdc === 122 || profileIdc === 244 || profileIdc === 44 || profileIdc === 83 || profileIdc === 86 || profileIdc === 118 || profileIdc === 128) {\n chromaFormatIdc = readExpGolomb(bitstream);\n if (chromaFormatIdc === 3) {\n separateColourPlaneFlag = bitstream.readBits(1);\n }\n bitDepthLumaMinus8 = readExpGolomb(bitstream);\n bitDepthChromaMinus8 = readExpGolomb(bitstream);\n bitstream.skipBits(1);\n const seqScalingMatrixPresentFlag = bitstream.readBits(1);\n if (seqScalingMatrixPresentFlag) {\n for (let i2 = 0; i2 < (chromaFormatIdc !== 3 ? 8 : 12); i2++) {\n const seqScalingListPresentFlag = bitstream.readBits(1);\n if (seqScalingListPresentFlag) {\n const sizeOfScalingList = i2 < 6 ? 16 : 64;\n let lastScale = 8;\n let nextScale = 8;\n for (let j = 0; j < sizeOfScalingList; j++) {\n if (nextScale !== 0) {\n const deltaScale = readSignedExpGolomb(bitstream);\n nextScale = (lastScale + deltaScale + 256) % 256;\n }\n lastScale = nextScale === 0 ? lastScale : nextScale;\n }\n }\n }\n }\n }\n readExpGolomb(bitstream);\n const picOrderCntType = readExpGolomb(bitstream);\n if (picOrderCntType === 0) {\n readExpGolomb(bitstream);\n } else if (picOrderCntType === 1) {\n bitstream.skipBits(1);\n readSignedExpGolomb(bitstream);\n readSignedExpGolomb(bitstream);\n const numRefFramesInPicOrderCntCycle = readExpGolomb(bitstream);\n for (let i2 = 0; i2 < numRefFramesInPicOrderCntCycle; i2++) {\n readSignedExpGolomb(bitstream);\n }\n }\n readExpGolomb(bitstream);\n bitstream.skipBits(1);\n const picWidthInMbsMinus1 = readExpGolomb(bitstream);\n const picHeightInMapUnitsMinus1 = readExpGolomb(bitstream);\n const codedWidth = 16 * (picWidthInMbsMinus1 + 1);\n const codedHeight = 16 * (picHeightInMapUnitsMinus1 + 1);\n let displayWidth = codedWidth;\n let displayHeight = codedHeight;\n const frameMbsOnlyFlag = bitstream.readBits(1);\n if (!frameMbsOnlyFlag) {\n bitstream.skipBits(1);\n }\n bitstream.skipBits(1);\n const frameCroppingFlag = bitstream.readBits(1);\n if (frameCroppingFlag) {\n const frameCropLeftOffset = readExpGolomb(bitstream);\n const frameCropRightOffset = readExpGolomb(bitstream);\n const frameCropTopOffset = readExpGolomb(bitstream);\n const frameCropBottomOffset = readExpGolomb(bitstream);\n let cropUnitX;\n let cropUnitY;\n const chromaArrayType = separateColourPlaneFlag === 0 ? chromaFormatIdc : 0;\n if (chromaArrayType === 0) {\n cropUnitX = 1;\n cropUnitY = 2 - frameMbsOnlyFlag;\n } else {\n const subWidthC = chromaFormatIdc === 3 ? 1 : 2;\n const subHeightC = chromaFormatIdc === 1 ? 2 : 1;\n cropUnitX = subWidthC;\n cropUnitY = subHeightC * (2 - frameMbsOnlyFlag);\n }\n displayWidth -= cropUnitX * (frameCropLeftOffset + frameCropRightOffset);\n displayHeight -= cropUnitY * (frameCropTopOffset + frameCropBottomOffset);\n }\n let colourPrimaries = 2;\n let transferCharacteristics = 2;\n let matrixCoefficients = 2;\n let fullRangeFlag = 0;\n let pixelAspectRatio = { num: 1, den: 1 };\n let numReorderFrames = null;\n let maxDecFrameBuffering = null;\n const vuiParametersPresentFlag = bitstream.readBits(1);\n if (vuiParametersPresentFlag) {\n const aspectRatioInfoPresentFlag = bitstream.readBits(1);\n if (aspectRatioInfoPresentFlag) {\n const aspectRatioIdc = bitstream.readBits(8);\n if (aspectRatioIdc === 255) {\n pixelAspectRatio = {\n num: bitstream.readBits(16),\n den: bitstream.readBits(16)\n };\n } else {\n const aspectRatio = AVC_HEVC_ASPECT_RATIO_IDC_TABLE[aspectRatioIdc];\n if (aspectRatio) {\n pixelAspectRatio = aspectRatio;\n }\n }\n }\n const overscanInfoPresentFlag = bitstream.readBits(1);\n if (overscanInfoPresentFlag) {\n bitstream.skipBits(1);\n }\n const videoSignalTypePresentFlag = bitstream.readBits(1);\n if (videoSignalTypePresentFlag) {\n bitstream.skipBits(3);\n fullRangeFlag = bitstream.readBits(1);\n const colourDescriptionPresentFlag = bitstream.readBits(1);\n if (colourDescriptionPresentFlag) {\n colourPrimaries = bitstream.readBits(8);\n transferCharacteristics = bitstream.readBits(8);\n matrixCoefficients = bitstream.readBits(8);\n }\n }\n const chromaLocInfoPresentFlag = bitstream.readBits(1);\n if (chromaLocInfoPresentFlag) {\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n }\n const timingInfoPresentFlag = bitstream.readBits(1);\n if (timingInfoPresentFlag) {\n bitstream.skipBits(32);\n bitstream.skipBits(32);\n bitstream.skipBits(1);\n }\n const nalHrdParametersPresentFlag = bitstream.readBits(1);\n if (nalHrdParametersPresentFlag) {\n skipAvcHrdParameters(bitstream);\n }\n const vclHrdParametersPresentFlag = bitstream.readBits(1);\n if (vclHrdParametersPresentFlag) {\n skipAvcHrdParameters(bitstream);\n }\n if (nalHrdParametersPresentFlag || vclHrdParametersPresentFlag) {\n bitstream.skipBits(1);\n }\n bitstream.skipBits(1);\n const bitstreamRestrictionFlag = bitstream.readBits(1);\n if (bitstreamRestrictionFlag) {\n bitstream.skipBits(1);\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n numReorderFrames = readExpGolomb(bitstream);\n maxDecFrameBuffering = readExpGolomb(bitstream);\n }\n }\n if (numReorderFrames === null) {\n assert(maxDecFrameBuffering === null);\n const constraintSet3Flag = constraintFlags & 16;\n if ((profileIdc === 44 || profileIdc === 86 || profileIdc === 100 || profileIdc === 110 || profileIdc === 122 || profileIdc === 244) && constraintSet3Flag) {\n numReorderFrames = 0;\n maxDecFrameBuffering = 0;\n } else {\n const picWidthInMbs = picWidthInMbsMinus1 + 1;\n const picHeightInMapUnits = picHeightInMapUnitsMinus1 + 1;\n const frameHeightInMbs = (2 - frameMbsOnlyFlag) * picHeightInMapUnits;\n const levelInfo = AVC_LEVEL_TABLE.find((x) => x.level >= levelIdc) ?? last(AVC_LEVEL_TABLE);\n const maxDpbFrames = Math.min(Math.floor(levelInfo.maxDpbMbs / (picWidthInMbs * frameHeightInMbs)), 16);\n numReorderFrames = maxDpbFrames;\n maxDecFrameBuffering = maxDpbFrames;\n }\n }\n assert(maxDecFrameBuffering !== null);\n return {\n profileIdc,\n constraintFlags,\n levelIdc,\n frameMbsOnlyFlag,\n chromaFormatIdc,\n bitDepthLumaMinus8,\n bitDepthChromaMinus8,\n codedWidth,\n codedHeight,\n displayWidth,\n displayHeight,\n pixelAspectRatio,\n colourPrimaries,\n matrixCoefficients,\n transferCharacteristics,\n fullRangeFlag,\n numReorderFrames,\n maxDecFrameBuffering\n };\n } catch (error) {\n Logging._error(\"Error parsing AVC SPS:\", error);\n return null;\n }\n};\nvar skipAvcHrdParameters = (bitstream) => {\n const cpb_cnt_minus1 = readExpGolomb(bitstream);\n bitstream.skipBits(4);\n bitstream.skipBits(4);\n for (let i2 = 0; i2 <= cpb_cnt_minus1; i2++) {\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n bitstream.skipBits(1);\n }\n bitstream.skipBits(5);\n bitstream.skipBits(5);\n bitstream.skipBits(5);\n bitstream.skipBits(5);\n};\nvar iterateHevcNalUnits = (packetData, decoderConfig) => {\n if (decoderConfig.description) {\n const bytes2 = toUint8Array(decoderConfig.description);\n const lengthSizeMinusOne = bytes2[21] & 3;\n const lengthSize = lengthSizeMinusOne + 1;\n return iterateNalUnitsInLengthPrefixed(packetData, lengthSize);\n } else {\n return iterateNalUnitsInAnnexB(packetData);\n }\n};\nvar extractNalUnitTypeForHevc = (byte) => {\n return byte >> 1 & 63;\n};\nvar parseHevcSps = (sps) => {\n try {\n const bitstream = new Bitstream(removeEmulationPreventionBytes(sps));\n bitstream.skipBits(16);\n bitstream.readBits(4);\n const spsMaxSubLayersMinus1 = bitstream.readBits(3);\n const spsTemporalIdNestingFlag = bitstream.readBits(1);\n const { general_profile_space, general_tier_flag, general_profile_idc, general_profile_compatibility_flags, general_constraint_indicator_flags, general_level_idc } = parseProfileTierLevel(bitstream, spsMaxSubLayersMinus1);\n readExpGolomb(bitstream);\n const chromaFormatIdc = readExpGolomb(bitstream);\n let separateColourPlaneFlag = 0;\n if (chromaFormatIdc === 3) {\n separateColourPlaneFlag = bitstream.readBits(1);\n }\n const picWidthInLumaSamples = readExpGolomb(bitstream);\n const picHeightInLumaSamples = readExpGolomb(bitstream);\n let displayWidth = picWidthInLumaSamples;\n let displayHeight = picHeightInLumaSamples;\n if (bitstream.readBits(1)) {\n const confWinLeftOffset = readExpGolomb(bitstream);\n const confWinRightOffset = readExpGolomb(bitstream);\n const confWinTopOffset = readExpGolomb(bitstream);\n const confWinBottomOffset = readExpGolomb(bitstream);\n let subWidthC = 1;\n let subHeightC = 1;\n const chromaArrayType = separateColourPlaneFlag === 0 ? chromaFormatIdc : 0;\n if (chromaArrayType === 1) {\n subWidthC = 2;\n subHeightC = 2;\n } else if (chromaArrayType === 2) {\n subWidthC = 2;\n subHeightC = 1;\n }\n displayWidth -= (confWinLeftOffset + confWinRightOffset) * subWidthC;\n displayHeight -= (confWinTopOffset + confWinBottomOffset) * subHeightC;\n }\n const bitDepthLumaMinus8 = readExpGolomb(bitstream);\n const bitDepthChromaMinus8 = readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n const spsSubLayerOrderingInfoPresentFlag = bitstream.readBits(1);\n const startI = spsSubLayerOrderingInfoPresentFlag ? 0 : spsMaxSubLayersMinus1;\n let spsMaxNumReorderPics = 0;\n for (let i2 = startI; i2 <= spsMaxSubLayersMinus1; i2++) {\n readExpGolomb(bitstream);\n spsMaxNumReorderPics = readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n }\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n if (bitstream.readBits(1)) {\n if (bitstream.readBits(1)) {\n skipScalingListData(bitstream);\n }\n }\n bitstream.skipBits(1);\n bitstream.skipBits(1);\n if (bitstream.readBits(1)) {\n bitstream.skipBits(4);\n bitstream.skipBits(4);\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n bitstream.skipBits(1);\n }\n const numShortTermRefPicSets = readExpGolomb(bitstream);\n skipAllStRefPicSets(bitstream, numShortTermRefPicSets);\n if (bitstream.readBits(1)) {\n const numLongTermRefPicsSps = readExpGolomb(bitstream);\n for (let i2 = 0; i2 < numLongTermRefPicsSps; i2++) {\n readExpGolomb(bitstream);\n bitstream.skipBits(1);\n }\n }\n bitstream.skipBits(1);\n bitstream.skipBits(1);\n let colourPrimaries = 2;\n let transferCharacteristics = 2;\n let matrixCoefficients = 2;\n let fullRangeFlag = 0;\n let minSpatialSegmentationIdc = 0;\n let pixelAspectRatio = { num: 1, den: 1 };\n if (bitstream.readBits(1)) {\n const vui = parseHevcVui(bitstream, spsMaxSubLayersMinus1);\n pixelAspectRatio = vui.pixelAspectRatio;\n colourPrimaries = vui.colourPrimaries;\n transferCharacteristics = vui.transferCharacteristics;\n matrixCoefficients = vui.matrixCoefficients;\n fullRangeFlag = vui.fullRangeFlag;\n minSpatialSegmentationIdc = vui.minSpatialSegmentationIdc;\n }\n return {\n displayWidth,\n displayHeight,\n pixelAspectRatio,\n colourPrimaries,\n transferCharacteristics,\n matrixCoefficients,\n fullRangeFlag,\n maxDecFrameBuffering: spsMaxNumReorderPics + 1,\n spsMaxSubLayersMinus1,\n spsTemporalIdNestingFlag,\n generalProfileSpace: general_profile_space,\n generalTierFlag: general_tier_flag,\n generalProfileIdc: general_profile_idc,\n generalProfileCompatibilityFlags: general_profile_compatibility_flags,\n generalConstraintIndicatorFlags: general_constraint_indicator_flags,\n generalLevelIdc: general_level_idc,\n chromaFormatIdc,\n bitDepthLumaMinus8,\n bitDepthChromaMinus8,\n minSpatialSegmentationIdc\n };\n } catch (error) {\n Logging._error(\"Error parsing HEVC SPS:\", error);\n return null;\n }\n};\nvar extractHevcDecoderConfigurationRecord = (packetData) => {\n try {\n const vpsUnits = [];\n const spsUnits = [];\n const ppsUnits = [];\n const seiUnits = [];\n for (const loc of iterateNalUnitsInAnnexB(packetData)) {\n const nalUnit = packetData.subarray(loc.offset, loc.offset + loc.length);\n const type = extractNalUnitTypeForHevc(nalUnit[0]);\n if (type === HevcNalUnitType.VPS_NUT) {\n vpsUnits.push(nalUnit);\n } else if (type === HevcNalUnitType.SPS_NUT) {\n spsUnits.push(nalUnit);\n } else if (type === HevcNalUnitType.PPS_NUT) {\n ppsUnits.push(nalUnit);\n } else if (type === HevcNalUnitType.PREFIX_SEI_NUT || type === HevcNalUnitType.SUFFIX_SEI_NUT) {\n seiUnits.push(nalUnit);\n }\n }\n if (spsUnits.length === 0 || ppsUnits.length === 0)\n return null;\n const spsInfo = parseHevcSps(spsUnits[0]);\n if (!spsInfo)\n return null;\n let parallelismType = 0;\n if (ppsUnits.length > 0) {\n const pps = ppsUnits[0];\n const ppsBitstream = new Bitstream(removeEmulationPreventionBytes(pps));\n ppsBitstream.skipBits(16);\n readExpGolomb(ppsBitstream);\n readExpGolomb(ppsBitstream);\n ppsBitstream.skipBits(1);\n ppsBitstream.skipBits(1);\n ppsBitstream.skipBits(3);\n ppsBitstream.skipBits(1);\n ppsBitstream.skipBits(1);\n readExpGolomb(ppsBitstream);\n readExpGolomb(ppsBitstream);\n readSignedExpGolomb(ppsBitstream);\n ppsBitstream.skipBits(1);\n ppsBitstream.skipBits(1);\n if (ppsBitstream.readBits(1)) {\n readExpGolomb(ppsBitstream);\n }\n readSignedExpGolomb(ppsBitstream);\n readSignedExpGolomb(ppsBitstream);\n ppsBitstream.skipBits(1);\n ppsBitstream.skipBits(1);\n ppsBitstream.skipBits(1);\n ppsBitstream.skipBits(1);\n const tiles_enabled_flag = ppsBitstream.readBits(1);\n const entropy_coding_sync_enabled_flag = ppsBitstream.readBits(1);\n if (!tiles_enabled_flag && !entropy_coding_sync_enabled_flag)\n parallelismType = 0;\n else if (tiles_enabled_flag && !entropy_coding_sync_enabled_flag)\n parallelismType = 2;\n else if (!tiles_enabled_flag && entropy_coding_sync_enabled_flag)\n parallelismType = 3;\n else\n parallelismType = 0;\n }\n const arrays = [\n ...vpsUnits.length ? [\n {\n arrayCompleteness: 1,\n nalUnitType: HevcNalUnitType.VPS_NUT,\n nalUnits: vpsUnits\n }\n ] : [],\n ...spsUnits.length ? [\n {\n arrayCompleteness: 1,\n nalUnitType: HevcNalUnitType.SPS_NUT,\n nalUnits: spsUnits\n }\n ] : [],\n ...ppsUnits.length ? [\n {\n arrayCompleteness: 1,\n nalUnitType: HevcNalUnitType.PPS_NUT,\n nalUnits: ppsUnits\n }\n ] : [],\n ...seiUnits.length ? [\n {\n arrayCompleteness: 1,\n nalUnitType: extractNalUnitTypeForHevc(seiUnits[0][0]),\n nalUnits: seiUnits\n }\n ] : []\n ];\n const record = {\n configurationVersion: 1,\n generalProfileSpace: spsInfo.generalProfileSpace,\n generalTierFlag: spsInfo.generalTierFlag,\n generalProfileIdc: spsInfo.generalProfileIdc,\n generalProfileCompatibilityFlags: spsInfo.generalProfileCompatibilityFlags,\n generalConstraintIndicatorFlags: spsInfo.generalConstraintIndicatorFlags,\n generalLevelIdc: spsInfo.generalLevelIdc,\n minSpatialSegmentationIdc: spsInfo.minSpatialSegmentationIdc,\n parallelismType,\n chromaFormatIdc: spsInfo.chromaFormatIdc,\n bitDepthLumaMinus8: spsInfo.bitDepthLumaMinus8,\n bitDepthChromaMinus8: spsInfo.bitDepthChromaMinus8,\n avgFrameRate: 0,\n constantFrameRate: 0,\n numTemporalLayers: spsInfo.spsMaxSubLayersMinus1 + 1,\n temporalIdNested: spsInfo.spsTemporalIdNestingFlag,\n lengthSizeMinusOne: 3,\n arrays\n };\n return record;\n } catch (error) {\n Logging._error(\"Error building HEVC Decoder Configuration Record:\", error);\n return null;\n }\n};\nvar parseProfileTierLevel = (bitstream, maxNumSubLayersMinus1) => {\n const general_profile_space = bitstream.readBits(2);\n const general_tier_flag = bitstream.readBits(1);\n const general_profile_idc = bitstream.readBits(5);\n let general_profile_compatibility_flags = 0;\n for (let i2 = 0; i2 < 32; i2++) {\n general_profile_compatibility_flags = general_profile_compatibility_flags << 1 | bitstream.readBits(1);\n }\n const general_constraint_indicator_flags = new Uint8Array(6);\n for (let i2 = 0; i2 < 6; i2++) {\n general_constraint_indicator_flags[i2] = bitstream.readBits(8);\n }\n const general_level_idc = bitstream.readBits(8);\n const sub_layer_profile_present_flag = [];\n const sub_layer_level_present_flag = [];\n for (let i2 = 0; i2 < maxNumSubLayersMinus1; i2++) {\n sub_layer_profile_present_flag.push(bitstream.readBits(1));\n sub_layer_level_present_flag.push(bitstream.readBits(1));\n }\n if (maxNumSubLayersMinus1 > 0) {\n for (let i2 = maxNumSubLayersMinus1; i2 < 8; i2++) {\n bitstream.skipBits(2);\n }\n }\n for (let i2 = 0; i2 < maxNumSubLayersMinus1; i2++) {\n if (sub_layer_profile_present_flag[i2])\n bitstream.skipBits(88);\n if (sub_layer_level_present_flag[i2])\n bitstream.skipBits(8);\n }\n return {\n general_profile_space,\n general_tier_flag,\n general_profile_idc,\n general_profile_compatibility_flags,\n general_constraint_indicator_flags,\n general_level_idc\n };\n};\nvar skipScalingListData = (bitstream) => {\n for (let sizeId = 0; sizeId < 4; sizeId++) {\n for (let matrixId = 0; matrixId < (sizeId === 3 ? 2 : 6); matrixId++) {\n const scaling_list_pred_mode_flag = bitstream.readBits(1);\n if (!scaling_list_pred_mode_flag) {\n readExpGolomb(bitstream);\n } else {\n const coefNum = Math.min(64, 1 << 4 + (sizeId << 1));\n if (sizeId > 1) {\n readSignedExpGolomb(bitstream);\n }\n for (let i2 = 0; i2 < coefNum; i2++) {\n readSignedExpGolomb(bitstream);\n }\n }\n }\n }\n};\nvar skipAllStRefPicSets = (bitstream, num_short_term_ref_pic_sets) => {\n const NumDeltaPocs = [];\n for (let stRpsIdx = 0; stRpsIdx < num_short_term_ref_pic_sets; stRpsIdx++) {\n NumDeltaPocs[stRpsIdx] = skipStRefPicSet(bitstream, stRpsIdx, num_short_term_ref_pic_sets, NumDeltaPocs);\n }\n};\nvar skipStRefPicSet = (bitstream, stRpsIdx, num_short_term_ref_pic_sets, NumDeltaPocs) => {\n let NumDeltaPocsThis = 0;\n let inter_ref_pic_set_prediction_flag = 0;\n let RefRpsIdx = 0;\n if (stRpsIdx !== 0) {\n inter_ref_pic_set_prediction_flag = bitstream.readBits(1);\n }\n if (inter_ref_pic_set_prediction_flag) {\n if (stRpsIdx === num_short_term_ref_pic_sets) {\n const delta_idx_minus1 = readExpGolomb(bitstream);\n RefRpsIdx = stRpsIdx - (delta_idx_minus1 + 1);\n } else {\n RefRpsIdx = stRpsIdx - 1;\n }\n bitstream.readBits(1);\n readExpGolomb(bitstream);\n const numDelta = NumDeltaPocs[RefRpsIdx] ?? 0;\n for (let j = 0; j <= numDelta; j++) {\n const used_by_curr_pic_flag = bitstream.readBits(1);\n if (!used_by_curr_pic_flag) {\n bitstream.readBits(1);\n }\n }\n NumDeltaPocsThis = NumDeltaPocs[RefRpsIdx];\n } else {\n const num_negative_pics = readExpGolomb(bitstream);\n const num_positive_pics = readExpGolomb(bitstream);\n for (let i2 = 0; i2 < num_negative_pics; i2++) {\n readExpGolomb(bitstream);\n bitstream.readBits(1);\n }\n for (let i2 = 0; i2 < num_positive_pics; i2++) {\n readExpGolomb(bitstream);\n bitstream.readBits(1);\n }\n NumDeltaPocsThis = num_negative_pics + num_positive_pics;\n }\n return NumDeltaPocsThis;\n};\nvar parseHevcVui = (bitstream, sps_max_sub_layers_minus1) => {\n let colourPrimaries = 2;\n let transferCharacteristics = 2;\n let matrixCoefficients = 2;\n let fullRangeFlag = 0;\n let minSpatialSegmentationIdc = 0;\n let pixelAspectRatio = { num: 1, den: 1 };\n if (bitstream.readBits(1)) {\n const aspect_ratio_idc = bitstream.readBits(8);\n if (aspect_ratio_idc === 255) {\n pixelAspectRatio = {\n num: bitstream.readBits(16),\n den: bitstream.readBits(16)\n };\n } else {\n const aspectRatio = AVC_HEVC_ASPECT_RATIO_IDC_TABLE[aspect_ratio_idc];\n if (aspectRatio) {\n pixelAspectRatio = aspectRatio;\n }\n }\n }\n if (bitstream.readBits(1)) {\n bitstream.readBits(1);\n }\n if (bitstream.readBits(1)) {\n bitstream.readBits(3);\n fullRangeFlag = bitstream.readBits(1);\n if (bitstream.readBits(1)) {\n colourPrimaries = bitstream.readBits(8);\n transferCharacteristics = bitstream.readBits(8);\n matrixCoefficients = bitstream.readBits(8);\n }\n }\n if (bitstream.readBits(1)) {\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n }\n bitstream.readBits(1);\n bitstream.readBits(1);\n bitstream.readBits(1);\n if (bitstream.readBits(1)) {\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n }\n if (bitstream.readBits(1)) {\n bitstream.readBits(32);\n bitstream.readBits(32);\n if (bitstream.readBits(1)) {\n readExpGolomb(bitstream);\n }\n if (bitstream.readBits(1)) {\n skipHevcHrdParameters(bitstream, true, sps_max_sub_layers_minus1);\n }\n }\n if (bitstream.readBits(1)) {\n bitstream.readBits(1);\n bitstream.readBits(1);\n bitstream.readBits(1);\n minSpatialSegmentationIdc = readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n }\n return {\n pixelAspectRatio,\n colourPrimaries,\n transferCharacteristics,\n matrixCoefficients,\n fullRangeFlag,\n minSpatialSegmentationIdc\n };\n};\nvar skipHevcHrdParameters = (bitstream, commonInfPresentFlag, maxNumSubLayersMinus1) => {\n let nal_hrd_parameters_present_flag = false;\n let vcl_hrd_parameters_present_flag = false;\n let sub_pic_hrd_params_present_flag = false;\n if (commonInfPresentFlag) {\n nal_hrd_parameters_present_flag = bitstream.readBits(1) === 1;\n vcl_hrd_parameters_present_flag = bitstream.readBits(1) === 1;\n if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) {\n sub_pic_hrd_params_present_flag = bitstream.readBits(1) === 1;\n if (sub_pic_hrd_params_present_flag) {\n bitstream.readBits(8);\n bitstream.readBits(5);\n bitstream.readBits(1);\n bitstream.readBits(5);\n }\n bitstream.readBits(4);\n bitstream.readBits(4);\n if (sub_pic_hrd_params_present_flag) {\n bitstream.readBits(4);\n }\n bitstream.readBits(5);\n bitstream.readBits(5);\n bitstream.readBits(5);\n }\n }\n for (let i2 = 0; i2 <= maxNumSubLayersMinus1; i2++) {\n const fixed_pic_rate_general_flag = bitstream.readBits(1) === 1;\n let fixed_pic_rate_within_cvs_flag = true;\n if (!fixed_pic_rate_general_flag) {\n fixed_pic_rate_within_cvs_flag = bitstream.readBits(1) === 1;\n }\n let low_delay_hrd_flag = false;\n if (fixed_pic_rate_within_cvs_flag) {\n readExpGolomb(bitstream);\n } else {\n low_delay_hrd_flag = bitstream.readBits(1) === 1;\n }\n let CpbCnt = 1;\n if (!low_delay_hrd_flag) {\n const cpb_cnt_minus1 = readExpGolomb(bitstream);\n CpbCnt = cpb_cnt_minus1 + 1;\n }\n if (nal_hrd_parameters_present_flag) {\n skipSubLayerHrdParameters(bitstream, CpbCnt, sub_pic_hrd_params_present_flag);\n }\n if (vcl_hrd_parameters_present_flag) {\n skipSubLayerHrdParameters(bitstream, CpbCnt, sub_pic_hrd_params_present_flag);\n }\n }\n};\nvar skipSubLayerHrdParameters = (bitstream, CpbCnt, sub_pic_hrd_params_present_flag) => {\n for (let i2 = 0; i2 < CpbCnt; i2++) {\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n if (sub_pic_hrd_params_present_flag) {\n readExpGolomb(bitstream);\n readExpGolomb(bitstream);\n }\n bitstream.readBits(1);\n }\n};\nvar serializeHevcDecoderConfigurationRecord = (record) => {\n const bytes2 = [];\n bytes2.push(record.configurationVersion);\n bytes2.push((record.generalProfileSpace & 3) << 6 | (record.generalTierFlag & 1) << 5 | record.generalProfileIdc & 31);\n bytes2.push(record.generalProfileCompatibilityFlags >>> 24 & 255);\n bytes2.push(record.generalProfileCompatibilityFlags >>> 16 & 255);\n bytes2.push(record.generalProfileCompatibilityFlags >>> 8 & 255);\n bytes2.push(record.generalProfileCompatibilityFlags & 255);\n bytes2.push(...record.generalConstraintIndicatorFlags);\n bytes2.push(record.generalLevelIdc & 255);\n bytes2.push(240 | record.minSpatialSegmentationIdc >> 8 & 15);\n bytes2.push(record.minSpatialSegmentationIdc & 255);\n bytes2.push(252 | record.parallelismType & 3);\n bytes2.push(252 | record.chromaFormatIdc & 3);\n bytes2.push(248 | record.bitDepthLumaMinus8 & 7);\n bytes2.push(248 | record.bitDepthChromaMinus8 & 7);\n bytes2.push(record.avgFrameRate >> 8 & 255);\n bytes2.push(record.avgFrameRate & 255);\n bytes2.push((record.constantFrameRate & 3) << 6 | (record.numTemporalLayers & 7) << 3 | (record.temporalIdNested & 1) << 2 | record.lengthSizeMinusOne & 3);\n bytes2.push(record.arrays.length & 255);\n for (const arr of record.arrays) {\n bytes2.push((arr.arrayCompleteness & 1) << 7 | 0 << 6 | arr.nalUnitType & 63);\n bytes2.push(arr.nalUnits.length >> 8 & 255);\n bytes2.push(arr.nalUnits.length & 255);\n for (const nal of arr.nalUnits) {\n bytes2.push(nal.length >> 8 & 255);\n bytes2.push(nal.length & 255);\n for (let i2 = 0; i2 < nal.length; i2++) {\n bytes2.push(nal[i2]);\n }\n }\n }\n return new Uint8Array(bytes2);\n};\nvar HevcNaluOrderState;\n(function(HevcNaluOrderState2) {\n HevcNaluOrderState2[HevcNaluOrderState2[\"audAllowed\"] = 0] = \"audAllowed\";\n HevcNaluOrderState2[HevcNaluOrderState2[\"beforeFirstVcl\"] = 1] = \"beforeFirstVcl\";\n HevcNaluOrderState2[HevcNaluOrderState2[\"afterFirstVcl\"] = 2] = \"afterFirstVcl\";\n HevcNaluOrderState2[HevcNaluOrderState2[\"eoBitstreamAllowed\"] = 3] = \"eoBitstreamAllowed\";\n HevcNaluOrderState2[HevcNaluOrderState2[\"noMoreDataAllowed\"] = 4] = \"noMoreDataAllowed\";\n})(HevcNaluOrderState || (HevcNaluOrderState = {}));\nvar iterateAv1PacketObus = function* (packet) {\n const bitstream = new Bitstream(packet);\n const readLeb128 = () => {\n let value = 0;\n for (let i2 = 0; i2 < 8; i2++) {\n const byte = bitstream.readAlignedByte();\n value |= (byte & 127) << i2 * 7;\n if (!(byte & 128)) {\n break;\n }\n if (i2 === 7 && byte & 128) {\n return null;\n }\n }\n if (value >= 2 ** 32 - 1) {\n return null;\n }\n return value;\n };\n while (bitstream.getBitsLeft() >= 8) {\n bitstream.skipBits(1);\n const obuType = bitstream.readBits(4);\n const obuExtension = bitstream.readBits(1);\n const obuHasSizeField = bitstream.readBits(1);\n bitstream.skipBits(1);\n if (obuExtension) {\n bitstream.skipBits(8);\n }\n let obuSize;\n if (obuHasSizeField) {\n const obuSizeValue = readLeb128();\n if (obuSizeValue === null)\n return;\n obuSize = obuSizeValue;\n } else {\n obuSize = Math.floor(bitstream.getBitsLeft() / 8);\n }\n assert(bitstream.pos % 8 === 0);\n yield {\n type: obuType,\n data: packet.subarray(bitstream.pos / 8, bitstream.pos / 8 + obuSize)\n };\n bitstream.skipBits(obuSize * 8);\n }\n};\nvar parseOpusIdentificationHeader = (bytes2) => {\n const view2 = toDataView(bytes2);\n const outputChannelCount = view2.getUint8(9);\n const preSkip = view2.getUint16(10, true);\n const inputSampleRate = view2.getUint32(12, true);\n const outputGain = view2.getInt16(16, true);\n const channelMappingFamily = view2.getUint8(18);\n let channelMappingTable = null;\n if (channelMappingFamily) {\n channelMappingTable = bytes2.subarray(19, 19 + 2 + outputChannelCount);\n }\n return {\n outputChannelCount,\n preSkip,\n inputSampleRate,\n outputGain,\n channelMappingFamily,\n channelMappingTable\n };\n};\nvar determineVideoPacketType = (codec, decoderConfig, packetData) => {\n switch (codec) {\n case \"avc\":\n {\n for (const loc of iterateAvcNalUnits(packetData, decoderConfig)) {\n const nalTypeByte = packetData[loc.offset];\n const type = extractNalUnitTypeForAvc(nalTypeByte);\n if (type >= AvcNalUnitType.NON_IDR_SLICE && type <= AvcNalUnitType.SLICE_DPC) {\n return \"delta\";\n }\n if (type === AvcNalUnitType.IDR) {\n return \"key\";\n }\n if (type === AvcNalUnitType.SEI && (!isChromium() || getChromiumVersion() >= 144)) {\n const nalUnit = packetData.subarray(loc.offset, loc.offset + loc.length);\n const bytes2 = removeEmulationPreventionBytes(nalUnit);\n let pos = 1;\n do {\n let payloadType = 0;\n while (true) {\n const nextByte = bytes2[pos++];\n if (nextByte === void 0)\n break;\n payloadType += nextByte;\n if (nextByte < 255) {\n break;\n }\n }\n let payloadSize = 0;\n while (true) {\n const nextByte = bytes2[pos++];\n if (nextByte === void 0)\n break;\n payloadSize += nextByte;\n if (nextByte < 255) {\n break;\n }\n }\n const PAYLOAD_TYPE_RECOVERY_POINT = 6;\n if (payloadType === PAYLOAD_TYPE_RECOVERY_POINT) {\n const bitstream = new Bitstream(bytes2);\n bitstream.pos = 8 * pos;\n const recoveryFrameCount = readExpGolomb(bitstream);\n const exactMatchFlag = bitstream.readBits(1);\n if (recoveryFrameCount === 0 && exactMatchFlag === 1) {\n return \"key\";\n }\n }\n pos += payloadSize;\n } while (pos < bytes2.length - 1);\n }\n }\n return \"delta\";\n }\n ;\n case \"hevc\":\n {\n for (const loc of iterateHevcNalUnits(packetData, decoderConfig)) {\n const type = extractNalUnitTypeForHevc(packetData[loc.offset]);\n if (type < HevcNalUnitType.BLA_W_LP) {\n return \"delta\";\n }\n if (type <= HevcNalUnitType.RSV_IRAP_VCL23) {\n return \"key\";\n }\n }\n return \"delta\";\n }\n ;\n case \"vp8\":\n {\n const frameType = packetData[0] & 1;\n return frameType === 0 ? \"key\" : \"delta\";\n }\n ;\n case \"vp9\":\n {\n const bitstream = new Bitstream(packetData);\n if (bitstream.readBits(2) !== 2) {\n return null;\n }\n ;\n const profileLowBit = bitstream.readBits(1);\n const profileHighBit = bitstream.readBits(1);\n const profile = (profileHighBit << 1) + profileLowBit;\n if (profile === 3) {\n bitstream.skipBits(1);\n }\n const showExistingFrame = bitstream.readBits(1);\n if (showExistingFrame) {\n return null;\n }\n const frameType = bitstream.readBits(1);\n return frameType === 0 ? \"key\" : \"delta\";\n }\n ;\n case \"av1\":\n {\n let reducedStillPictureHeader = false;\n for (const { type, data } of iterateAv1PacketObus(packetData)) {\n if (type === 1) {\n const bitstream = new Bitstream(data);\n bitstream.skipBits(4);\n reducedStillPictureHeader = !!bitstream.readBits(1);\n } else if (type === 3 || type === 6 || type === 7) {\n if (reducedStillPictureHeader) {\n return \"key\";\n }\n const bitstream = new Bitstream(data);\n const showExistingFrame = bitstream.readBits(1);\n if (showExistingFrame) {\n return null;\n }\n const frameType = bitstream.readBits(2);\n return frameType === 0 ? \"key\" : \"delta\";\n }\n }\n return null;\n }\n ;\n default:\n {\n assertNever(codec);\n assert(false);\n }\n ;\n }\n};\nvar FlacBlockType;\n(function(FlacBlockType2) {\n FlacBlockType2[FlacBlockType2[\"STREAMINFO\"] = 0] = \"STREAMINFO\";\n FlacBlockType2[FlacBlockType2[\"VORBIS_COMMENT\"] = 4] = \"VORBIS_COMMENT\";\n FlacBlockType2[FlacBlockType2[\"PICTURE\"] = 6] = \"PICTURE\";\n})(FlacBlockType || (FlacBlockType = {}));\nvar parseAc3SyncFrame = (data) => {\n if (data.length < 7) {\n return null;\n }\n if (data[0] !== 11 || data[1] !== 119) {\n return null;\n }\n const bitstream = new Bitstream(data);\n bitstream.skipBits(16);\n bitstream.skipBits(16);\n const fscod = bitstream.readBits(2);\n if (fscod === 3) {\n return null;\n }\n const frmsizecod = bitstream.readBits(6);\n const bsid = bitstream.readBits(5);\n if (bsid > 8) {\n return null;\n }\n const bsmod = bitstream.readBits(3);\n const acmod = bitstream.readBits(3);\n if ((acmod & 1) !== 0 && acmod !== 1) {\n bitstream.skipBits(2);\n }\n if ((acmod & 4) !== 0) {\n bitstream.skipBits(2);\n }\n if (acmod === 2) {\n bitstream.skipBits(2);\n }\n const lfeon = bitstream.readBits(1);\n const bitRateCode = Math.floor(frmsizecod / 2);\n return { fscod, bsid, bsmod, acmod, lfeon, bitRateCode };\n};\nvar AC3_FRAME_SIZES = [\n // frmsizecod, [48kHz, 44.1kHz, 32kHz] in bytes\n 64 * 2,\n 69 * 2,\n 96 * 2,\n 64 * 2,\n 70 * 2,\n 96 * 2,\n 80 * 2,\n 87 * 2,\n 120 * 2,\n 80 * 2,\n 88 * 2,\n 120 * 2,\n 96 * 2,\n 104 * 2,\n 144 * 2,\n 96 * 2,\n 105 * 2,\n 144 * 2,\n 112 * 2,\n 121 * 2,\n 168 * 2,\n 112 * 2,\n 122 * 2,\n 168 * 2,\n 128 * 2,\n 139 * 2,\n 192 * 2,\n 128 * 2,\n 140 * 2,\n 192 * 2,\n 160 * 2,\n 174 * 2,\n 240 * 2,\n 160 * 2,\n 175 * 2,\n 240 * 2,\n 192 * 2,\n 208 * 2,\n 288 * 2,\n 192 * 2,\n 209 * 2,\n 288 * 2,\n 224 * 2,\n 243 * 2,\n 336 * 2,\n 224 * 2,\n 244 * 2,\n 336 * 2,\n 256 * 2,\n 278 * 2,\n 384 * 2,\n 256 * 2,\n 279 * 2,\n 384 * 2,\n 320 * 2,\n 348 * 2,\n 480 * 2,\n 320 * 2,\n 349 * 2,\n 480 * 2,\n 384 * 2,\n 417 * 2,\n 576 * 2,\n 384 * 2,\n 418 * 2,\n 576 * 2,\n 448 * 2,\n 487 * 2,\n 672 * 2,\n 448 * 2,\n 488 * 2,\n 672 * 2,\n 512 * 2,\n 557 * 2,\n 768 * 2,\n 512 * 2,\n 558 * 2,\n 768 * 2,\n 640 * 2,\n 696 * 2,\n 960 * 2,\n 640 * 2,\n 697 * 2,\n 960 * 2,\n 768 * 2,\n 835 * 2,\n 1152 * 2,\n 768 * 2,\n 836 * 2,\n 1152 * 2,\n 896 * 2,\n 975 * 2,\n 1344 * 2,\n 896 * 2,\n 976 * 2,\n 1344 * 2,\n 1024 * 2,\n 1114 * 2,\n 1536 * 2,\n 1024 * 2,\n 1115 * 2,\n 1536 * 2,\n 1152 * 2,\n 1253 * 2,\n 1728 * 2,\n 1152 * 2,\n 1254 * 2,\n 1728 * 2,\n 1280 * 2,\n 1393 * 2,\n 1920 * 2,\n 1280 * 2,\n 1394 * 2,\n 1920 * 2\n];\nvar AC3_REGISTRATION_DESCRIPTOR = new Uint8Array([5, 4, 65, 67, 45, 51]);\nvar EAC3_REGISTRATION_DESCRIPTOR = new Uint8Array([5, 4, 69, 65, 67, 51]);\nvar EAC3_NUMBLKS_TABLE = [1, 2, 3, 6];\nvar parseEac3SyncFrame = (data) => {\n if (data.length < 6) {\n return null;\n }\n if (data[0] !== 11 || data[1] !== 119) {\n return null;\n }\n const bitstream = new Bitstream(data);\n bitstream.skipBits(16);\n const strmtyp = bitstream.readBits(2);\n bitstream.skipBits(3);\n if (strmtyp !== 0 && strmtyp !== 2) {\n return null;\n }\n const frmsiz = bitstream.readBits(11);\n const fscod = bitstream.readBits(2);\n let fscod2 = 0;\n let numblkscod;\n if (fscod === 3) {\n fscod2 = bitstream.readBits(2);\n numblkscod = 3;\n } else {\n numblkscod = bitstream.readBits(2);\n }\n const acmod = bitstream.readBits(3);\n const lfeon = bitstream.readBits(1);\n const bsid = bitstream.readBits(5);\n if (bsid < 11 || bsid > 16) {\n return null;\n }\n const numblks = EAC3_NUMBLKS_TABLE[numblkscod];\n let fs;\n if (fscod < 3) {\n fs = AC3_SAMPLE_RATES[fscod] / 1e3;\n } else {\n fs = EAC3_REDUCED_SAMPLE_RATES[fscod2] / 1e3;\n }\n const dataRate = Math.round((frmsiz + 1) * fs / (numblks * 16));\n const bsmod = 0;\n const numDepSub = 0;\n const chanLoc = 0;\n const substream = {\n fscod,\n fscod2,\n bsid,\n bsmod,\n acmod,\n lfeon,\n numDepSub,\n chanLoc\n };\n return {\n dataRate,\n substreams: [substream]\n };\n};\n\n// node_modules/mediabunny/dist/modules/src/packet.js\nvar PLACEHOLDER_DATA = /* @__PURE__ */ new Uint8Array(0);\nvar EncodedPacket = class _EncodedPacket {\n /** Creates a new {@link EncodedPacket} from raw bytes and timing information. */\n constructor(data, type, timestamp, duration, sequenceNumber = -1, byteLength, sideData) {\n this.data = data;\n this.type = type;\n this.timestamp = timestamp;\n this.duration = duration;\n this.sequenceNumber = sequenceNumber;\n if (data === PLACEHOLDER_DATA && byteLength === void 0) {\n throw new Error(\"Internal error: byteLength must be explicitly provided when constructing metadata-only packets.\");\n }\n if (byteLength === void 0) {\n byteLength = data.byteLength;\n }\n if (!(data instanceof Uint8Array)) {\n throw new TypeError(\"data must be a Uint8Array.\");\n }\n if (type !== \"key\" && type !== \"delta\") {\n throw new TypeError('type must be either \"key\" or \"delta\".');\n }\n if (!Number.isFinite(timestamp)) {\n throw new TypeError(\"timestamp must be a number.\");\n }\n if (!Number.isFinite(duration) || duration < 0) {\n throw new TypeError(\"duration must be a non-negative number.\");\n }\n if (!Number.isFinite(sequenceNumber)) {\n throw new TypeError(\"sequenceNumber must be a number.\");\n }\n if (!Number.isInteger(byteLength) || byteLength < 0) {\n throw new TypeError(\"byteLength must be a non-negative integer.\");\n }\n if (sideData !== void 0 && (typeof sideData !== \"object\" || !sideData)) {\n throw new TypeError(\"sideData, when provided, must be an object.\");\n }\n if (sideData?.alpha !== void 0 && !(sideData.alpha instanceof Uint8Array)) {\n throw new TypeError(\"sideData.alpha, when provided, must be a Uint8Array.\");\n }\n if (sideData?.alphaByteLength !== void 0 && (!Number.isInteger(sideData.alphaByteLength) || sideData.alphaByteLength < 0)) {\n throw new TypeError(\"sideData.alphaByteLength, when provided, must be a non-negative integer.\");\n }\n this.byteLength = byteLength;\n this.sideData = sideData ?? {};\n if (this.sideData.alpha && this.sideData.alphaByteLength === void 0) {\n this.sideData.alphaByteLength = this.sideData.alpha.byteLength;\n }\n }\n /**\n * If this packet is a metadata-only packet. Metadata-only packets don't contain their packet data. They are the\n * result of retrieving packets with {@link PacketRetrievalOptions.metadataOnly} set to `true`.\n */\n get isMetadataOnly() {\n return this.data === PLACEHOLDER_DATA;\n }\n /** The timestamp of this packet in microseconds. */\n get microsecondTimestamp() {\n return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.timestamp);\n }\n /** The duration of this packet in microseconds. */\n get microsecondDuration() {\n return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.duration);\n }\n /** Converts this packet to an\n * [`EncodedVideoChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) for use with the\n * WebCodecs API. */\n toEncodedVideoChunk() {\n if (this.isMetadataOnly) {\n throw new TypeError(\"Metadata-only packets cannot be converted to a video chunk.\");\n }\n if (typeof EncodedVideoChunk === \"undefined\") {\n throw new Error(\"Your browser does not support EncodedVideoChunk.\");\n }\n return new EncodedVideoChunk({\n data: this.data,\n type: this.type,\n timestamp: this.microsecondTimestamp,\n duration: this.microsecondDuration\n });\n }\n /**\n * Converts this packet to an\n * [`EncodedVideoChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) for use with the\n * WebCodecs API, using the alpha side data instead of the color data. Throws if no alpha side data is defined.\n */\n alphaToEncodedVideoChunk(type = this.type) {\n if (!this.sideData.alpha) {\n throw new TypeError(\"This packet does not contain alpha side data.\");\n }\n if (this.isMetadataOnly) {\n throw new TypeError(\"Metadata-only packets cannot be converted to a video chunk.\");\n }\n if (typeof EncodedVideoChunk === \"undefined\") {\n throw new Error(\"Your browser does not support EncodedVideoChunk.\");\n }\n return new EncodedVideoChunk({\n data: this.sideData.alpha,\n type,\n timestamp: this.microsecondTimestamp,\n duration: this.microsecondDuration\n });\n }\n /** Converts this packet to an\n * [`EncodedAudioChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedAudioChunk) for use with the\n * WebCodecs API. */\n toEncodedAudioChunk() {\n if (this.isMetadataOnly) {\n throw new TypeError(\"Metadata-only packets cannot be converted to an audio chunk.\");\n }\n if (typeof EncodedAudioChunk === \"undefined\") {\n throw new Error(\"Your browser does not support EncodedAudioChunk.\");\n }\n return new EncodedAudioChunk({\n data: this.data,\n type: this.type,\n timestamp: this.microsecondTimestamp,\n duration: this.microsecondDuration\n });\n }\n /**\n * Creates an {@link EncodedPacket} from an\n * [`EncodedVideoChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedVideoChunk) or\n * [`EncodedAudioChunk`](https://developer.mozilla.org/en-US/docs/Web/API/EncodedAudioChunk). This method is useful\n * for converting chunks from the WebCodecs API to `EncodedPacket` instances.\n */\n static fromEncodedChunk(chunk, sideData) {\n if (!(chunk instanceof EncodedVideoChunk || chunk instanceof EncodedAudioChunk)) {\n throw new TypeError(\"chunk must be an EncodedVideoChunk or EncodedAudioChunk.\");\n }\n const data = new Uint8Array(chunk.byteLength);\n chunk.copyTo(data);\n return new _EncodedPacket(data, chunk.type, chunk.timestamp / 1e6, (chunk.duration ?? 0) / 1e6, void 0, void 0, sideData);\n }\n /** Clones this packet while optionally modifying the new packet's data. */\n clone(options) {\n if (options !== void 0 && (typeof options !== \"object\" || options === null)) {\n throw new TypeError(\"options, when provided, must be an object.\");\n }\n if (options?.data !== void 0 && !(options.data instanceof Uint8Array)) {\n throw new TypeError(\"options.data, when provided, must be a Uint8Array.\");\n }\n if (options?.type !== void 0 && options.type !== \"key\" && options.type !== \"delta\") {\n throw new TypeError('options.type, when provided, must be either \"key\" or \"delta\".');\n }\n if (options?.timestamp !== void 0 && !Number.isFinite(options.timestamp)) {\n throw new TypeError(\"options.timestamp, when provided, must be a number.\");\n }\n if (options?.duration !== void 0 && !Number.isFinite(options.duration)) {\n throw new TypeError(\"options.duration, when provided, must be a number.\");\n }\n if (options?.sequenceNumber !== void 0 && !Number.isFinite(options.sequenceNumber)) {\n throw new TypeError(\"options.sequenceNumber, when provided, must be a number.\");\n }\n if (options?.sideData !== void 0 && (typeof options.sideData !== \"object\" || options.sideData === null)) {\n throw new TypeError(\"options.sideData, when provided, must be an object.\");\n }\n 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);\n }\n};\n\n// node_modules/mediabunny/dist/modules/src/isobmff/isobmff-misc.js\nvar buildIsobmffMimeType = (info) => {\n const base = info.hasVideo ? \"video/\" : info.hasAudio ? \"audio/\" : \"application/\";\n let string = base + (info.isQuickTime ? \"quicktime\" : \"mp4\");\n if (info.codecStrings.length > 0) {\n const uniqueCodecMimeTypes = [...new Set(info.codecStrings)];\n string += `; codecs=\"${uniqueCodecMimeTypes.join(\", \")}\"`;\n }\n return string;\n};\n\n// node_modules/mediabunny/dist/modules/src/isobmff/isobmff-reader.js\nvar MIN_BOX_HEADER_SIZE = 8;\nvar MAX_BOX_HEADER_SIZE = 16;\n\n// node_modules/mediabunny/dist/modules/src/matroska/ebml.js\nvar EBMLFloat32 = class {\n constructor(value) {\n this.value = value;\n }\n};\nvar EBMLFloat64 = class {\n constructor(value) {\n this.value = value;\n }\n};\nvar EBMLSignedInt = class {\n constructor(value) {\n this.value = value;\n }\n};\nvar EBMLUnicodeString = class {\n constructor(value) {\n this.value = value;\n }\n};\nvar EBMLId;\n(function(EBMLId2) {\n EBMLId2[EBMLId2[\"EBML\"] = 440786851] = \"EBML\";\n EBMLId2[EBMLId2[\"EBMLVersion\"] = 17030] = \"EBMLVersion\";\n EBMLId2[EBMLId2[\"EBMLReadVersion\"] = 17143] = \"EBMLReadVersion\";\n EBMLId2[EBMLId2[\"EBMLMaxIDLength\"] = 17138] = \"EBMLMaxIDLength\";\n EBMLId2[EBMLId2[\"EBMLMaxSizeLength\"] = 17139] = \"EBMLMaxSizeLength\";\n EBMLId2[EBMLId2[\"DocType\"] = 17026] = \"DocType\";\n EBMLId2[EBMLId2[\"DocTypeVersion\"] = 17031] = \"DocTypeVersion\";\n EBMLId2[EBMLId2[\"DocTypeReadVersion\"] = 17029] = \"DocTypeReadVersion\";\n EBMLId2[EBMLId2[\"Void\"] = 236] = \"Void\";\n EBMLId2[EBMLId2[\"Segment\"] = 408125543] = \"Segment\";\n EBMLId2[EBMLId2[\"SeekHead\"] = 290298740] = \"SeekHead\";\n EBMLId2[EBMLId2[\"Seek\"] = 19899] = \"Seek\";\n EBMLId2[EBMLId2[\"SeekID\"] = 21419] = \"SeekID\";\n EBMLId2[EBMLId2[\"SeekPosition\"] = 21420] = \"SeekPosition\";\n EBMLId2[EBMLId2[\"Duration\"] = 17545] = \"Duration\";\n EBMLId2[EBMLId2[\"Info\"] = 357149030] = \"Info\";\n EBMLId2[EBMLId2[\"TimestampScale\"] = 2807729] = \"TimestampScale\";\n EBMLId2[EBMLId2[\"MuxingApp\"] = 19840] = \"MuxingApp\";\n EBMLId2[EBMLId2[\"WritingApp\"] = 22337] = \"WritingApp\";\n EBMLId2[EBMLId2[\"Tracks\"] = 374648427] = \"Tracks\";\n EBMLId2[EBMLId2[\"TrackEntry\"] = 174] = \"TrackEntry\";\n EBMLId2[EBMLId2[\"TrackNumber\"] = 215] = \"TrackNumber\";\n EBMLId2[EBMLId2[\"TrackUID\"] = 29637] = \"TrackUID\";\n EBMLId2[EBMLId2[\"TrackType\"] = 131] = \"TrackType\";\n EBMLId2[EBMLId2[\"FlagEnabled\"] = 185] = \"FlagEnabled\";\n EBMLId2[EBMLId2[\"FlagDefault\"] = 136] = \"FlagDefault\";\n EBMLId2[EBMLId2[\"FlagForced\"] = 21930] = \"FlagForced\";\n EBMLId2[EBMLId2[\"FlagOriginal\"] = 21934] = \"FlagOriginal\";\n EBMLId2[EBMLId2[\"FlagHearingImpaired\"] = 21931] = \"FlagHearingImpaired\";\n EBMLId2[EBMLId2[\"FlagVisualImpaired\"] = 21932] = \"FlagVisualImpaired\";\n EBMLId2[EBMLId2[\"FlagCommentary\"] = 21935] = \"FlagCommentary\";\n EBMLId2[EBMLId2[\"FlagLacing\"] = 156] = \"FlagLacing\";\n EBMLId2[EBMLId2[\"Name\"] = 21358] = \"Name\";\n EBMLId2[EBMLId2[\"Language\"] = 2274716] = \"Language\";\n EBMLId2[EBMLId2[\"LanguageBCP47\"] = 2274717] = \"LanguageBCP47\";\n EBMLId2[EBMLId2[\"CodecID\"] = 134] = \"CodecID\";\n EBMLId2[EBMLId2[\"CodecPrivate\"] = 25506] = \"CodecPrivate\";\n EBMLId2[EBMLId2[\"CodecDelay\"] = 22186] = \"CodecDelay\";\n EBMLId2[EBMLId2[\"SeekPreRoll\"] = 22203] = \"SeekPreRoll\";\n EBMLId2[EBMLId2[\"DefaultDuration\"] = 2352003] = \"DefaultDuration\";\n EBMLId2[EBMLId2[\"Video\"] = 224] = \"Video\";\n EBMLId2[EBMLId2[\"PixelWidth\"] = 176] = \"PixelWidth\";\n EBMLId2[EBMLId2[\"PixelHeight\"] = 186] = \"PixelHeight\";\n EBMLId2[EBMLId2[\"DisplayWidth\"] = 21680] = \"DisplayWidth\";\n EBMLId2[EBMLId2[\"DisplayHeight\"] = 21690] = \"DisplayHeight\";\n EBMLId2[EBMLId2[\"DisplayUnit\"] = 21682] = \"DisplayUnit\";\n EBMLId2[EBMLId2[\"AlphaMode\"] = 21440] = \"AlphaMode\";\n EBMLId2[EBMLId2[\"Audio\"] = 225] = \"Audio\";\n EBMLId2[EBMLId2[\"SamplingFrequency\"] = 181] = \"SamplingFrequency\";\n EBMLId2[EBMLId2[\"Channels\"] = 159] = \"Channels\";\n EBMLId2[EBMLId2[\"BitDepth\"] = 25188] = \"BitDepth\";\n EBMLId2[EBMLId2[\"SimpleBlock\"] = 163] = \"SimpleBlock\";\n EBMLId2[EBMLId2[\"BlockGroup\"] = 160] = \"BlockGroup\";\n EBMLId2[EBMLId2[\"Block\"] = 161] = \"Block\";\n EBMLId2[EBMLId2[\"BlockAdditions\"] = 30113] = \"BlockAdditions\";\n EBMLId2[EBMLId2[\"BlockMore\"] = 166] = \"BlockMore\";\n EBMLId2[EBMLId2[\"BlockAdditional\"] = 165] = \"BlockAdditional\";\n EBMLId2[EBMLId2[\"BlockAddID\"] = 238] = \"BlockAddID\";\n EBMLId2[EBMLId2[\"BlockDuration\"] = 155] = \"BlockDuration\";\n EBMLId2[EBMLId2[\"ReferenceBlock\"] = 251] = \"ReferenceBlock\";\n EBMLId2[EBMLId2[\"Cluster\"] = 524531317] = \"Cluster\";\n EBMLId2[EBMLId2[\"Timestamp\"] = 231] = \"Timestamp\";\n EBMLId2[EBMLId2[\"Cues\"] = 475249515] = \"Cues\";\n EBMLId2[EBMLId2[\"CuePoint\"] = 187] = \"CuePoint\";\n EBMLId2[EBMLId2[\"CueTime\"] = 179] = \"CueTime\";\n EBMLId2[EBMLId2[\"CueTrackPositions\"] = 183] = \"CueTrackPositions\";\n EBMLId2[EBMLId2[\"CueTrack\"] = 247] = \"CueTrack\";\n EBMLId2[EBMLId2[\"CueClusterPosition\"] = 241] = \"CueClusterPosition\";\n EBMLId2[EBMLId2[\"Colour\"] = 21936] = \"Colour\";\n EBMLId2[EBMLId2[\"MatrixCoefficients\"] = 21937] = \"MatrixCoefficients\";\n EBMLId2[EBMLId2[\"TransferCharacteristics\"] = 21946] = \"TransferCharacteristics\";\n EBMLId2[EBMLId2[\"Primaries\"] = 21947] = \"Primaries\";\n EBMLId2[EBMLId2[\"Range\"] = 21945] = \"Range\";\n EBMLId2[EBMLId2[\"Projection\"] = 30320] = \"Projection\";\n EBMLId2[EBMLId2[\"ProjectionType\"] = 30321] = \"ProjectionType\";\n EBMLId2[EBMLId2[\"ProjectionPoseRoll\"] = 30325] = \"ProjectionPoseRoll\";\n EBMLId2[EBMLId2[\"Attachments\"] = 423732329] = \"Attachments\";\n EBMLId2[EBMLId2[\"AttachedFile\"] = 24999] = \"AttachedFile\";\n EBMLId2[EBMLId2[\"FileDescription\"] = 18046] = \"FileDescription\";\n EBMLId2[EBMLId2[\"FileName\"] = 18030] = \"FileName\";\n EBMLId2[EBMLId2[\"FileMediaType\"] = 18016] = \"FileMediaType\";\n EBMLId2[EBMLId2[\"FileData\"] = 18012] = \"FileData\";\n EBMLId2[EBMLId2[\"FileUID\"] = 18094] = \"FileUID\";\n EBMLId2[EBMLId2[\"Chapters\"] = 272869232] = \"Chapters\";\n EBMLId2[EBMLId2[\"Tags\"] = 307544935] = \"Tags\";\n EBMLId2[EBMLId2[\"Tag\"] = 29555] = \"Tag\";\n EBMLId2[EBMLId2[\"Targets\"] = 25536] = \"Targets\";\n EBMLId2[EBMLId2[\"TargetTypeValue\"] = 26826] = \"TargetTypeValue\";\n EBMLId2[EBMLId2[\"TargetType\"] = 25546] = \"TargetType\";\n EBMLId2[EBMLId2[\"TagTrackUID\"] = 25541] = \"TagTrackUID\";\n EBMLId2[EBMLId2[\"TagEditionUID\"] = 25545] = \"TagEditionUID\";\n EBMLId2[EBMLId2[\"TagChapterUID\"] = 25540] = \"TagChapterUID\";\n EBMLId2[EBMLId2[\"TagAttachmentUID\"] = 25542] = \"TagAttachmentUID\";\n EBMLId2[EBMLId2[\"SimpleTag\"] = 26568] = \"SimpleTag\";\n EBMLId2[EBMLId2[\"TagName\"] = 17827] = \"TagName\";\n EBMLId2[EBMLId2[\"TagLanguage\"] = 17530] = \"TagLanguage\";\n EBMLId2[EBMLId2[\"TagString\"] = 17543] = \"TagString\";\n EBMLId2[EBMLId2[\"TagBinary\"] = 17541] = \"TagBinary\";\n EBMLId2[EBMLId2[\"ContentEncodings\"] = 28032] = \"ContentEncodings\";\n EBMLId2[EBMLId2[\"ContentEncoding\"] = 25152] = \"ContentEncoding\";\n EBMLId2[EBMLId2[\"ContentEncodingOrder\"] = 20529] = \"ContentEncodingOrder\";\n EBMLId2[EBMLId2[\"ContentEncodingScope\"] = 20530] = \"ContentEncodingScope\";\n EBMLId2[EBMLId2[\"ContentCompression\"] = 20532] = \"ContentCompression\";\n EBMLId2[EBMLId2[\"ContentCompAlgo\"] = 16980] = \"ContentCompAlgo\";\n EBMLId2[EBMLId2[\"ContentCompSettings\"] = 16981] = \"ContentCompSettings\";\n EBMLId2[EBMLId2[\"ContentEncryption\"] = 20533] = \"ContentEncryption\";\n})(EBMLId || (EBMLId = {}));\nvar LEVEL_0_EBML_IDS = [\n EBMLId.EBML,\n EBMLId.Segment\n];\nvar LEVEL_1_EBML_IDS = [\n EBMLId.SeekHead,\n EBMLId.Info,\n EBMLId.Cluster,\n EBMLId.Tracks,\n EBMLId.Cues,\n EBMLId.Attachments,\n EBMLId.Chapters,\n EBMLId.Tags\n];\nvar LEVEL_0_AND_1_EBML_IDS = [\n ...LEVEL_0_EBML_IDS,\n ...LEVEL_1_EBML_IDS\n];\nvar measureUnsignedInt = (value) => {\n if (value < 1 << 8) {\n return 1;\n } else if (value < 1 << 16) {\n return 2;\n } else if (value < 1 << 24) {\n return 3;\n } else if (value < 2 ** 32) {\n return 4;\n } else if (value < 2 ** 40) {\n return 5;\n } else {\n return 6;\n }\n};\nvar measureUnsignedBigInt = (value) => {\n if (value < 1n << 8n) {\n return 1;\n } else if (value < 1n << 16n) {\n return 2;\n } else if (value < 1n << 24n) {\n return 3;\n } else if (value < 1n << 32n) {\n return 4;\n } else if (value < 1n << 40n) {\n return 5;\n } else if (value < 1n << 48n) {\n return 6;\n } else if (value < 1n << 56n) {\n return 7;\n } else {\n return 8;\n }\n};\nvar measureSignedInt = (value) => {\n if (value >= -(1 << 6) && value < 1 << 6) {\n return 1;\n } else if (value >= -(1 << 13) && value < 1 << 13) {\n return 2;\n } else if (value >= -(1 << 20) && value < 1 << 20) {\n return 3;\n } else if (value >= -(1 << 27) && value < 1 << 27) {\n return 4;\n } else if (value >= -(2 ** 34) && value < 2 ** 34) {\n return 5;\n } else {\n return 6;\n }\n};\nvar measureVarInt = (value) => {\n if (value < (1 << 7) - 1) {\n return 1;\n } else if (value < (1 << 14) - 1) {\n return 2;\n } else if (value < (1 << 21) - 1) {\n return 3;\n } else if (value < (1 << 28) - 1) {\n return 4;\n } else if (value < 2 ** 35 - 1) {\n return 5;\n } else if (value < 2 ** 42 - 1) {\n return 6;\n } else {\n throw new Error(\"EBML varint size not supported \" + value);\n }\n};\nvar EBMLWriter = class {\n constructor(writer) {\n this.writer = writer;\n this.helper = new Uint8Array(8);\n this.helperView = new DataView(this.helper.buffer);\n this.offsets = /* @__PURE__ */ new WeakMap();\n this.dataOffsets = /* @__PURE__ */ new WeakMap();\n }\n writeByte(value) {\n this.helperView.setUint8(0, value);\n this.writer.write(this.helper.subarray(0, 1));\n }\n writeFloat32(value) {\n this.helperView.setFloat32(0, value, false);\n this.writer.write(this.helper.subarray(0, 4));\n }\n writeFloat64(value) {\n this.helperView.setFloat64(0, value, false);\n this.writer.write(this.helper);\n }\n writeUnsignedInt(value, width = measureUnsignedInt(value)) {\n let pos = 0;\n switch (width) {\n case 6:\n this.helperView.setUint8(pos++, value / 2 ** 40 | 0);\n // eslint-disable-next-line no-fallthrough\n case 5:\n this.helperView.setUint8(pos++, value / 2 ** 32 | 0);\n // eslint-disable-next-line no-fallthrough\n case 4:\n this.helperView.setUint8(pos++, value >> 24);\n // eslint-disable-next-line no-fallthrough\n case 3:\n this.helperView.setUint8(pos++, value >> 16);\n // eslint-disable-next-line no-fallthrough\n case 2:\n this.helperView.setUint8(pos++, value >> 8);\n // eslint-disable-next-line no-fallthrough\n case 1:\n this.helperView.setUint8(pos++, value);\n break;\n default:\n throw new Error(\"Bad unsigned int size \" + width);\n }\n this.writer.write(this.helper.subarray(0, pos));\n }\n writeUnsignedBigInt(value, width = measureUnsignedBigInt(value)) {\n let pos = 0;\n for (let i2 = width - 1; i2 >= 0; i2--) {\n this.helperView.setUint8(pos++, Number(value >> BigInt(i2 * 8) & 0xffn));\n }\n this.writer.write(this.helper.subarray(0, pos));\n }\n writeSignedInt(value, width = measureSignedInt(value)) {\n if (value < 0) {\n value += 2 ** (width * 8);\n }\n this.writeUnsignedInt(value, width);\n }\n writeVarInt(value, width = measureVarInt(value)) {\n let pos = 0;\n switch (width) {\n case 1:\n this.helperView.setUint8(pos++, 1 << 7 | value);\n break;\n case 2:\n this.helperView.setUint8(pos++, 1 << 6 | value >> 8);\n this.helperView.setUint8(pos++, value);\n break;\n case 3:\n this.helperView.setUint8(pos++, 1 << 5 | value >> 16);\n this.helperView.setUint8(pos++, value >> 8);\n this.helperView.setUint8(pos++, value);\n break;\n case 4:\n this.helperView.setUint8(pos++, 1 << 4 | value >> 24);\n this.helperView.setUint8(pos++, value >> 16);\n this.helperView.setUint8(pos++, value >> 8);\n this.helperView.setUint8(pos++, value);\n break;\n case 5:\n this.helperView.setUint8(pos++, 1 << 3 | value / 2 ** 32 & 7);\n this.helperView.setUint8(pos++, value >> 24);\n this.helperView.setUint8(pos++, value >> 16);\n this.helperView.setUint8(pos++, value >> 8);\n this.helperView.setUint8(pos++, value);\n break;\n case 6:\n this.helperView.setUint8(pos++, 1 << 2 | value / 2 ** 40 & 3);\n this.helperView.setUint8(pos++, value / 2 ** 32 | 0);\n this.helperView.setUint8(pos++, value >> 24);\n this.helperView.setUint8(pos++, value >> 16);\n this.helperView.setUint8(pos++, value >> 8);\n this.helperView.setUint8(pos++, value);\n break;\n default:\n throw new Error(\"Bad EBML varint size \" + width);\n }\n this.writer.write(this.helper.subarray(0, pos));\n }\n writeAsciiString(str) {\n this.writer.write(new Uint8Array(str.split(\"\").map((x) => x.charCodeAt(0))));\n }\n writeEBML(data) {\n if (data === null)\n return;\n if (data instanceof Uint8Array) {\n this.writer.write(data);\n } else if (Array.isArray(data)) {\n for (const elem of data) {\n this.writeEBML(elem);\n }\n } else {\n this.offsets.set(data, this.writer.getPos());\n this.writeUnsignedInt(data.id);\n if (Array.isArray(data.data)) {\n const sizePos = this.writer.getPos();\n const sizeSize = data.size === -1 ? 1 : data.size ?? 4;\n if (data.size === -1) {\n this.writeByte(255);\n } else {\n this.writer.seek(this.writer.getPos() + sizeSize);\n }\n const startPos = this.writer.getPos();\n this.dataOffsets.set(data, startPos);\n this.writeEBML(data.data);\n if (data.size !== -1) {\n const size = this.writer.getPos() - startPos;\n const endPos = this.writer.getPos();\n this.writer.seek(sizePos);\n this.writeVarInt(size, sizeSize);\n this.writer.seek(endPos);\n }\n } else if (typeof data.data === \"number\") {\n const size = data.size ?? measureUnsignedInt(data.data);\n this.writeVarInt(size);\n this.writeUnsignedInt(data.data, size);\n } else if (typeof data.data === \"bigint\") {\n const size = data.size ?? measureUnsignedBigInt(data.data);\n this.writeVarInt(size);\n this.writeUnsignedBigInt(data.data, size);\n } else if (typeof data.data === \"string\") {\n this.writeVarInt(data.data.length);\n this.writeAsciiString(data.data);\n } else if (data.data instanceof Uint8Array) {\n this.writeVarInt(data.data.byteLength, data.size);\n this.writer.write(data.data);\n } else if (data.data instanceof EBMLFloat32) {\n this.writeVarInt(4);\n this.writeFloat32(data.data.value);\n } else if (data.data instanceof EBMLFloat64) {\n this.writeVarInt(8);\n this.writeFloat64(data.data.value);\n } else if (data.data instanceof EBMLSignedInt) {\n const size = data.size ?? measureSignedInt(data.data.value);\n this.writeVarInt(size);\n this.writeSignedInt(data.data.value, size);\n } else if (data.data instanceof EBMLUnicodeString) {\n const bytes2 = textEncoder.encode(data.data.value);\n this.writeVarInt(bytes2.length);\n this.writer.write(bytes2);\n } else {\n assertNever(data.data);\n }\n }\n }\n};\nvar MAX_VAR_INT_SIZE = 8;\nvar MAX_HEADER_SIZE = 2 * MAX_VAR_INT_SIZE;\nvar CODEC_STRING_MAP = {\n \"avc\": \"V_MPEG4/ISO/AVC\",\n \"hevc\": \"V_MPEGH/ISO/HEVC\",\n \"vp8\": \"V_VP8\",\n \"vp9\": \"V_VP9\",\n \"av1\": \"V_AV1\",\n \"aac\": \"A_AAC\",\n \"mp3\": \"A_MPEG/L3\",\n \"opus\": \"A_OPUS\",\n \"vorbis\": \"A_VORBIS\",\n \"flac\": \"A_FLAC\",\n \"ac3\": \"A_AC3\",\n \"eac3\": \"A_EAC3\",\n \"pcm-u8\": \"A_PCM/INT/LIT\",\n \"pcm-s16\": \"A_PCM/INT/LIT\",\n \"pcm-s16be\": \"A_PCM/INT/BIG\",\n \"pcm-s24\": \"A_PCM/INT/LIT\",\n \"pcm-s24be\": \"A_PCM/INT/BIG\",\n \"pcm-s32\": \"A_PCM/INT/LIT\",\n \"pcm-s32be\": \"A_PCM/INT/BIG\",\n \"pcm-f32\": \"A_PCM/FLOAT/IEEE\",\n \"pcm-f64\": \"A_PCM/FLOAT/IEEE\",\n \"webvtt\": \"S_TEXT/WEBVTT\"\n};\n\n// node_modules/mediabunny/dist/modules/src/matroska/matroska-misc.js\nvar buildMatroskaMimeType = (info) => {\n const base = info.hasVideo ? \"video/\" : info.hasAudio ? \"audio/\" : \"application/\";\n let string = base + (info.isWebM ? \"webm\" : \"x-matroska\");\n if (info.codecStrings.length > 0) {\n const uniqueCodecMimeTypes = [...new Set(info.codecStrings.filter(Boolean))];\n string += `; codecs=\"${uniqueCodecMimeTypes.join(\", \")}\"`;\n }\n return string;\n};\n\n// node_modules/mediabunny/dist/modules/src/adts/adts-reader.js\nvar MIN_ADTS_FRAME_HEADER_SIZE = 7;\nvar MAX_ADTS_FRAME_HEADER_SIZE = 9;\nvar readAdtsFrameHeader = (slice) => {\n const startPos = slice.filePos;\n const bytes2 = readBytes(slice, 9);\n const bitstream = new Bitstream(bytes2);\n const syncword = bitstream.readBits(12);\n if (syncword !== 4095) {\n return null;\n }\n bitstream.skipBits(1);\n const layer = bitstream.readBits(2);\n if (layer !== 0) {\n return null;\n }\n const protectionAbsence = bitstream.readBits(1);\n const objectType = bitstream.readBits(2) + 1;\n const samplingFrequencyIndex = bitstream.readBits(4);\n if (samplingFrequencyIndex === 15) {\n return null;\n }\n bitstream.skipBits(1);\n const channelConfiguration = bitstream.readBits(3);\n if (channelConfiguration === 0) {\n throw new Error(\"ADTS frames with channel configuration 0 are not supported.\");\n }\n bitstream.skipBits(1);\n bitstream.skipBits(1);\n bitstream.skipBits(1);\n bitstream.skipBits(1);\n const frameLength = bitstream.readBits(13);\n bitstream.skipBits(11);\n const numberOfAacFrames = bitstream.readBits(2) + 1;\n if (numberOfAacFrames !== 1) {\n throw new Error(\"ADTS frames with more than one AAC frame are not supported.\");\n }\n let crcCheck = null;\n if (protectionAbsence === 1) {\n slice.filePos -= 2;\n } else {\n crcCheck = bitstream.readBits(16);\n }\n return {\n objectType,\n samplingFrequencyIndex,\n channelConfiguration,\n frameLength,\n numberOfAacFrames,\n crcCheck,\n startPos\n };\n};\n\n// node_modules/mediabunny/dist/modules/src/sample.js\nvar __addDisposableResource = function(env, value, async) {\n if (value !== null && value !== void 0) {\n if (typeof value !== \"object\" && typeof value !== \"function\") throw new TypeError(\"Object expected.\");\n var dispose, inner;\n if (async) {\n if (!Symbol.asyncDispose) throw new TypeError(\"Symbol.asyncDispose is not defined.\");\n dispose = value[Symbol.asyncDispose];\n }\n if (dispose === void 0) {\n if (!Symbol.dispose) throw new TypeError(\"Symbol.dispose is not defined.\");\n dispose = value[Symbol.dispose];\n if (async) inner = dispose;\n }\n if (typeof dispose !== \"function\") throw new TypeError(\"Object not disposable.\");\n if (inner) dispose = function() {\n try {\n inner.call(this);\n } catch (e2) {\n return Promise.reject(e2);\n }\n };\n env.stack.push({ value, dispose, async });\n } else if (async) {\n env.stack.push({ async: true });\n }\n return value;\n};\nvar __disposeResources = /* @__PURE__ */ (function(SuppressedError2) {\n return function(env) {\n function fail(e2) {\n env.error = env.hasError ? new SuppressedError2(e2, env.error, \"An error was suppressed during disposal.\") : e2;\n env.hasError = true;\n }\n var r2, s2 = 0;\n function next() {\n while (r2 = env.stack.pop()) {\n try {\n if (!r2.async && s2 === 1) return s2 = 0, env.stack.push(r2), Promise.resolve().then(next);\n if (r2.dispose) {\n var result = r2.dispose.call(r2.value);\n if (r2.async) return s2 |= 2, Promise.resolve(result).then(next, function(e2) {\n fail(e2);\n return next();\n });\n } else s2 |= 1;\n } catch (e2) {\n fail(e2);\n }\n }\n if (s2 === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();\n if (env.hasError) throw env.error;\n }\n return next();\n };\n})(typeof SuppressedError === \"function\" ? SuppressedError : function(error, suppressed, message) {\n var e2 = new Error(message);\n return e2.name = \"SuppressedError\", e2.error = error, e2.suppressed = suppressed, e2;\n});\npolyfillSymbolDispose();\nvar lastVideoGcErrorLog = -Infinity;\nvar lastAudioGcErrorLog = -Infinity;\nvar finalizationRegistry = null;\nif (typeof FinalizationRegistry !== \"undefined\") {\n finalizationRegistry = new FinalizationRegistry((value) => {\n const now = performance.now();\n if (value.type === \"video\") {\n if (now - lastVideoGcErrorLog >= 1e3) {\n Logging._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.`);\n lastVideoGcErrorLog = now;\n }\n if (typeof VideoFrame !== \"undefined\" && value.data instanceof VideoFrame) {\n value.data.close();\n }\n } else {\n if (now - lastAudioGcErrorLog >= 1e3) {\n Logging._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.`);\n lastAudioGcErrorLog = now;\n }\n if (typeof AudioData !== \"undefined\" && value.data instanceof AudioData) {\n value.data.close();\n }\n }\n });\n}\nvar VideoSampleResource = class {\n constructor() {\n this._referenceCount = 0;\n this._lastAllocationBuffer = null;\n }\n};\nvar VIDEO_SAMPLE_PIXEL_FORMATS = [\n // 4:2:0 Y, U, V\n \"I420\",\n \"I420P10\",\n \"I420P12\",\n // 4:2:0 Y, U, V, A\n \"I420A\",\n \"I420AP10\",\n \"I420AP12\",\n // 4:2:2 Y, U, V\n \"I422\",\n \"I422P10\",\n \"I422P12\",\n // 4:2:2 Y, U, V, A\n \"I422A\",\n \"I422AP10\",\n \"I422AP12\",\n // 4:4:4 Y, U, V\n \"I444\",\n \"I444P10\",\n \"I444P12\",\n // 4:4:4 Y, U, V, A\n \"I444A\",\n \"I444AP10\",\n \"I444AP12\",\n // 4:2:0 Y, UV\n \"NV12\",\n // 4:4:4 RGBA\n \"RGBA\",\n // 4:4:4 RGBX (opaque)\n \"RGBX\",\n // 4:4:4 BGRA\n \"BGRA\",\n // 4:4:4 BGRX (opaque)\n \"BGRX\"\n];\nvar VIDEO_SAMPLE_PIXEL_FORMATS_SET = new Set(VIDEO_SAMPLE_PIXEL_FORMATS);\nvar VideoSample = class _VideoSample {\n /** The width of the frame in pixels. */\n get codedWidth() {\n return this.visibleRect.width;\n }\n /** The height of the frame in pixels. */\n get codedHeight() {\n return this.visibleRect.height;\n }\n /** The display width of the frame in pixels, after aspect ratio adjustment and rotation. */\n get displayWidth() {\n return this.rotation % 180 === 0 ? this.squarePixelWidth : this.squarePixelHeight;\n }\n /** The display height of the frame in pixels, after aspect ratio adjustment and rotation. */\n get displayHeight() {\n return this.rotation % 180 === 0 ? this.squarePixelHeight : this.squarePixelWidth;\n }\n /** The presentation timestamp of the frame in microseconds. */\n get microsecondTimestamp() {\n return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.timestamp);\n }\n /** The duration of the frame in microseconds. */\n get microsecondDuration() {\n return Math.trunc(SECOND_TO_MICROSECOND_FACTOR * this.duration);\n }\n /**\n * Whether this sample uses a pixel format that can hold transparency data. Note that this doesn't necessarily mean\n * that the sample is transparent.\n */\n get hasAlpha() {\n return this.format && this.format.includes(\"A\");\n }\n constructor(data, init) {\n this._closed = false;\n if (data instanceof ArrayBuffer || typeof SharedArrayBuffer !== \"undefined\" && data instanceof SharedArrayBuffer || ArrayBuffer.isView(data)) {\n if (!init || typeof init !== \"object\") {\n throw new TypeError(\"init must be an object.\");\n }\n if (init.format === void 0 || !VIDEO_SAMPLE_PIXEL_FORMATS_SET.has(init.format)) {\n throw new TypeError(\"init.format must be one of: \" + VIDEO_SAMPLE_PIXEL_FORMATS.join(\", \"));\n }\n if (!Number.isInteger(init.codedWidth) || init.codedWidth <= 0) {\n throw new TypeError(\"init.codedWidth must be a positive integer.\");\n }\n if (!Number.isInteger(init.codedHeight) || init.codedHeight <= 0) {\n throw new TypeError(\"init.codedHeight must be a positive integer.\");\n }\n if (init.rotation !== void 0 && ![0, 90, 180, 270].includes(init.rotation)) {\n throw new TypeError(\"init.rotation, when provided, must be 0, 90, 180, or 270.\");\n }\n if (!Number.isFinite(init.timestamp)) {\n throw new TypeError(\"init.timestamp must be a number.\");\n }\n if (init.duration !== void 0 && (!Number.isFinite(init.duration) || init.duration < 0)) {\n throw new TypeError(\"init.duration, when provided, must be a non-negative number.\");\n }\n if (init.layout !== void 0) {\n if (!Array.isArray(init.layout)) {\n throw new TypeError(\"init.layout, when provided, must be an array.\");\n }\n for (const plane of init.layout) {\n if (!plane || typeof plane !== \"object\" || Array.isArray(plane)) {\n throw new TypeError(\"Each entry in init.layout must be an object.\");\n }\n if (!Number.isInteger(plane.offset) || plane.offset < 0) {\n throw new TypeError(\"plane.offset must be a non-negative integer.\");\n }\n if (!Number.isInteger(plane.stride) || plane.stride < 0) {\n throw new TypeError(\"plane.stride must be a non-negative integer.\");\n }\n }\n }\n if (init.visibleRect !== void 0) {\n validateRectangle(init.visibleRect, \"init.visibleRect\");\n }\n if (init.displayWidth !== void 0 && (!Number.isInteger(init.displayWidth) || init.displayWidth <= 0)) {\n throw new TypeError(\"init.displayWidth, when provided, must be a positive integer.\");\n }\n if (init.displayHeight !== void 0 && (!Number.isInteger(init.displayHeight) || init.displayHeight <= 0)) {\n throw new TypeError(\"init.displayHeight, when provided, must be a positive integer.\");\n }\n if (init.displayWidth !== void 0 !== (init.displayHeight !== void 0)) {\n throw new TypeError(\"init.displayWidth and init.displayHeight must be either both provided or both omitted.\");\n }\n this._data = init._doNotCopy ? toUint8Array(data) : toUint8Array(data).slice();\n this._layout = init.layout ?? createDefaultPlaneLayout(init.format, init.codedWidth, init.codedHeight);\n this.format = init.format;\n this.rotation = init.rotation ?? 0;\n this.timestamp = init.timestamp;\n this.duration = init.duration ?? 0;\n let colorSpaceInit = init.colorSpace ?? null;\n if (colorSpaceInit === null) {\n if (this.format === \"RGBA\" || this.format === \"RGBX\" || this.format === \"BGRA\" || this.format === \"BGRX\") {\n colorSpaceInit = {\n primaries: \"bt709\",\n transfer: \"iec61966-2-1\",\n matrix: \"rgb\",\n fullRange: true\n };\n } else {\n colorSpaceInit = {\n primaries: \"bt709\",\n transfer: \"bt709\",\n matrix: \"bt709\",\n fullRange: false\n };\n }\n }\n this.colorSpace = new VideoSampleColorSpace(colorSpaceInit);\n this.visibleRect = {\n left: init.visibleRect?.left ?? 0,\n top: init.visibleRect?.top ?? 0,\n width: init.visibleRect?.width ?? init.codedWidth,\n height: init.visibleRect?.height ?? init.codedHeight\n };\n if (init.displayWidth !== void 0) {\n this.squarePixelWidth = this.rotation % 180 === 0 ? init.displayWidth : init.displayHeight;\n this.squarePixelHeight = this.rotation % 180 === 0 ? init.displayHeight : init.displayWidth;\n } else {\n this.squarePixelWidth = this.visibleRect.width;\n this.squarePixelHeight = this.visibleRect.height;\n }\n } else if (typeof VideoFrame !== \"undefined\" && data instanceof VideoFrame) {\n if (init?.rotation !== void 0 && ![0, 90, 180, 270].includes(init.rotation)) {\n throw new TypeError(\"init.rotation, when provided, must be 0, 90, 180, or 270.\");\n }\n if (init?.timestamp !== void 0 && !Number.isFinite(init?.timestamp)) {\n throw new TypeError(\"init.timestamp, when provided, must be a number.\");\n }\n if (init?.duration !== void 0 && (!Number.isFinite(init.duration) || init.duration < 0)) {\n throw new TypeError(\"init.duration, when provided, must be a non-negative number.\");\n }\n if (init?.visibleRect !== void 0) {\n validateRectangle(init.visibleRect, \"init.visibleRect\");\n }\n this._data = data;\n this._layout = null;\n this.format = data.format;\n this.visibleRect = {\n left: data.visibleRect?.x ?? 0,\n top: data.visibleRect?.y ?? 0,\n width: data.visibleRect?.width ?? data.codedWidth,\n height: data.visibleRect?.height ?? data.codedHeight\n };\n this.rotation = init?.rotation ?? 0;\n this.squarePixelWidth = data.displayWidth;\n this.squarePixelHeight = data.displayHeight;\n this.timestamp = init?.timestamp ?? data.timestamp / 1e6;\n this.duration = init?.duration ?? (data.duration ?? 0) / 1e6;\n this.colorSpace = new VideoSampleColorSpace(data.colorSpace);\n } 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) {\n if (!init || typeof init !== \"object\") {\n throw new TypeError(\"init must be an object.\");\n }\n if (init.rotation !== void 0 && ![0, 90, 180, 270].includes(init.rotation)) {\n throw new TypeError(\"init.rotation, when provided, must be 0, 90, 180, or 270.\");\n }\n if (!Number.isFinite(init.timestamp)) {\n throw new TypeError(\"init.timestamp must be a number.\");\n }\n if (init.duration !== void 0 && (!Number.isFinite(init.duration) || init.duration < 0)) {\n throw new TypeError(\"init.duration, when provided, must be a non-negative number.\");\n }\n if (typeof VideoFrame !== \"undefined\") {\n return new _VideoSample(new VideoFrame(data, {\n timestamp: Math.trunc(init.timestamp * SECOND_TO_MICROSECOND_FACTOR),\n // Drag 0 to undefined\n duration: Math.trunc((init.duration ?? 0) * SECOND_TO_MICROSECOND_FACTOR) || void 0\n }), init);\n }\n let width = 0;\n let height = 0;\n if (\"naturalWidth\" in data) {\n width = data.naturalWidth;\n height = data.naturalHeight;\n } else if (\"videoWidth\" in data) {\n width = data.videoWidth;\n height = data.videoHeight;\n } else if (\"width\" in data) {\n width = Number(data.width);\n height = Number(data.height);\n }\n if (!width || !height) {\n throw new TypeError(\"Could not determine dimensions.\");\n }\n const canvas = new OffscreenCanvas(width, height);\n const context = canvas.getContext(\"2d\", {\n alpha: isFirefox(),\n // Firefox has VideoFrame glitches with opaque canvases\n willReadFrequently: true\n });\n if (!context) {\n throw new Error(\"OffscreenCanvas must have support for the '2d' context in order to create a VideoSample from this data.\");\n }\n context.drawImage(data, 0, 0);\n this._data = canvas;\n this._layout = null;\n this.format = \"RGBX\";\n this.visibleRect = { left: 0, top: 0, width, height };\n this.squarePixelWidth = width;\n this.squarePixelHeight = height;\n this.rotation = init.rotation ?? 0;\n this.timestamp = init.timestamp;\n this.duration = init.duration ?? 0;\n this.colorSpace = new VideoSampleColorSpace({\n matrix: \"rgb\",\n primaries: \"bt709\",\n transfer: \"iec61966-2-1\",\n fullRange: true\n });\n } else if (data instanceof VideoSampleResource) {\n if (!init || typeof init !== \"object\") {\n throw new TypeError(\"init must be an object.\");\n }\n if (init.rotation !== void 0 && ![0, 90, 180, 270].includes(init.rotation)) {\n throw new TypeError(\"init.rotation, when provided, must be 0, 90, 180, or 270.\");\n }\n if (!Number.isFinite(init.timestamp)) {\n throw new TypeError(\"init.timestamp must be a number.\");\n }\n if (init.duration !== void 0 && (!Number.isFinite(init.duration) || init.duration < 0)) {\n throw new TypeError(\"init.duration, when provided, must be a non-negative number.\");\n }\n this._data = data;\n data._referenceCount++;\n this.format = data.getFormat();\n if (this.format !== null && !VIDEO_SAMPLE_PIXEL_FORMATS.includes(this.format)) {\n throw new TypeError(\"getFormat() must return a VideoSamplePixelFormat or null.\");\n }\n this.visibleRect = {\n left: 0,\n top: 0,\n width: data.getCodedWidth(),\n height: data.getCodedHeight()\n };\n if (!Number.isInteger(this.visibleRect.width) || this.visibleRect.width <= 0) {\n throw new TypeError(\"getCodedWidth() must return a positive integer.\");\n }\n if (!Number.isInteger(this.visibleRect.height) || this.visibleRect.height <= 0) {\n throw new TypeError(\"getCodedHeight() must return a positive integer.\");\n }\n this.squarePixelWidth = data.getSquarePixelWidth();\n if (!Number.isInteger(this.squarePixelWidth) || this.squarePixelWidth <= 0) {\n throw new TypeError(\"getSquarePixelWidth() must return a positive integer.\");\n }\n this.squarePixelHeight = data.getSquarePixelHeight();\n if (!Number.isInteger(this.squarePixelHeight) || this.squarePixelHeight <= 0) {\n throw new TypeError(\"getSquarePixelHeight() must return a positive integer.\");\n }\n this.rotation = init.rotation ?? 0;\n this.timestamp = init.timestamp;\n this.duration = init.duration ?? 0;\n this.colorSpace = data.getColorSpace();\n } else {\n throw new TypeError(\"Invalid data type: Must be a BufferSource, CanvasImageSource, or VideoSampleResource.\");\n }\n this.encodeOptions = init?.encodeOptions ?? {};\n this.pixelAspectRatio = simplifyRational({\n num: this.squarePixelWidth * this.codedHeight,\n den: this.squarePixelHeight * this.codedWidth\n });\n finalizationRegistry?.register(this, { type: \"video\", data: this._data }, this);\n }\n /** Clones this video sample. */\n clone() {\n if (this._closed) {\n throw new Error(\"VideoSample is closed.\");\n }\n assert(this._data !== null);\n if (this._data instanceof VideoSampleResource) {\n return new _VideoSample(this._data, {\n timestamp: this.timestamp,\n duration: this.duration,\n rotation: this.rotation,\n encodeOptions: this.encodeOptions\n });\n } else if (isVideoFrame(this._data)) {\n return new _VideoSample(this._data.clone(), {\n timestamp: this.timestamp,\n duration: this.duration,\n rotation: this.rotation,\n encodeOptions: this.encodeOptions\n });\n } else if (this._data instanceof Uint8Array) {\n assert(this._layout);\n return new _VideoSample(this._data, {\n format: this.format,\n layout: this._layout,\n codedWidth: this.codedWidth,\n codedHeight: this.codedHeight,\n timestamp: this.timestamp,\n duration: this.duration,\n colorSpace: this.colorSpace,\n rotation: this.rotation,\n visibleRect: this.visibleRect,\n displayWidth: this.displayWidth,\n displayHeight: this.displayHeight,\n encodeOptions: this.encodeOptions,\n // It's already been copied, if we copy it again we make the clone unnecessarily expensive\n _doNotCopy: true\n });\n } else {\n return new _VideoSample(this._data, {\n format: this.format,\n codedWidth: this.codedWidth,\n codedHeight: this.codedHeight,\n timestamp: this.timestamp,\n duration: this.duration,\n colorSpace: this.colorSpace,\n rotation: this.rotation,\n visibleRect: this.visibleRect,\n displayWidth: this.displayWidth,\n displayHeight: this.displayHeight,\n encodeOptions: this.encodeOptions\n });\n }\n }\n /**\n * Closes this video sample, releasing held resources. Video samples should be closed as soon as they are not\n * needed anymore.\n */\n close() {\n if (this._closed) {\n return;\n }\n finalizationRegistry?.unregister(this);\n if (this._data instanceof VideoSampleResource) {\n this._data._referenceCount--;\n if (this._data._referenceCount === 0) {\n this._data.close();\n }\n } else if (isVideoFrame(this._data)) {\n this._data.close();\n } else {\n this._data = null;\n }\n this._closed = true;\n }\n /**\n * Returns the number of bytes required to hold this video sample's pixel data.\n */\n allocationSize(options = {}) {\n validateVideoFrameCopyToOptions(options);\n if (this._closed) {\n throw new Error(\"VideoSample is closed.\");\n }\n if ((options.format ?? this.format) == null) {\n throw new Error(\"Cannot get allocation size when format is null.\");\n }\n if (isVideoFrame(this._data)) {\n return this._data.allocationSize(options);\n }\n const combinedLayout = ParseVideoFrameCopyToOptions(this, options);\n return combinedLayout.allocationSize;\n }\n /**\n * Copies this video sample's pixel data to an ArrayBuffer or ArrayBufferView.\n * @returns The byte layout of the planes of the copied data.\n */\n async copyTo(destination, options = {}) {\n if (!isAllowSharedBufferSource(destination)) {\n throw new TypeError(\"destination must be an ArrayBuffer or an ArrayBuffer view.\");\n }\n validateVideoFrameCopyToOptions(options);\n if (this._closed) {\n throw new Error(\"VideoSample is closed.\");\n }\n if ((options.format ?? this.format) == null) {\n throw new Error(\"Cannot copy video sample data when format is null.\");\n }\n assert(this._data !== null);\n if (isVideoFrame(this._data)) {\n return this._data.copyTo(destination, options);\n }\n if (options.format && ![\"RGBA\", \"RGBX\", \"BGRA\", \"BGRX\"].includes(this.format) && [\"RGBA\", \"RGBX\", \"BGRA\", \"BGRX\"].includes(options.format)) {\n if (this._data instanceof VideoSampleResource) {\n const env_1 = { stack: [], error: void 0, hasError: false };\n try {\n const rgbSample = __addDisposableResource(env_1, await this._data.toRgbSample({\n timestamp: this.timestamp,\n duration: this.duration,\n rotation: this.rotation\n }, options.colorSpace ?? \"srgb\"), false);\n if (!(rgbSample instanceof _VideoSample)) {\n throw new TypeError(\"toRgbSample() must return a VideoSample.\");\n }\n if (![\"RGBA\", \"RGBX\", \"BGRA\", \"BGRX\"].includes(rgbSample.format)) {\n throw new Error(`Sample returned by toRgbSample was expected to have an RGB format, got '${rgbSample.format}' instead.`);\n }\n return await rgbSample.copyTo(destination, options);\n } catch (e_1) {\n env_1.error = e_1;\n env_1.hasError = true;\n } finally {\n __disposeResources(env_1);\n }\n } else {\n if (typeof VideoFrame === \"undefined\") {\n throw new Error(\"For this sample, converting from a non-RGB to an RGB format requires VideoFrame to be defined.\");\n }\n const tempFrame = this.toVideoFrame();\n const result = await tempFrame.copyTo(destination, options);\n tempFrame.close();\n return result;\n }\n }\n const combinedLayout = ParseVideoFrameCopyToOptions(this, options);\n assert(this.format);\n const destBytes = toUint8Array(destination);\n if (destBytes.byteLength < combinedLayout.allocationSize) {\n throw new TypeError(`Destination buffer too small. Required: ${combinedLayout.allocationSize}, Available: ${destBytes.byteLength}`);\n }\n const planeConfigs = getPlaneConfigs(this.format);\n let dataPlanes;\n if (this._data instanceof VideoSampleResource) {\n let result = this._data.getDataPlanes();\n if (result instanceof Promise)\n result = await result;\n if (!Array.isArray(result) || result.some((x) => !(x.data instanceof Uint8Array) || !Number.isInteger(x.stride) || x.stride < 0)) {\n throw new TypeError('getDataPlanes() must return an array of objects with a Uint8Array \"data\" property and a non-negative integer \"stride\" property.');\n }\n dataPlanes = result;\n } else if (this._data instanceof Uint8Array) {\n assert(this._layout);\n assert(this._layout.length === planeConfigs.length);\n dataPlanes = this._layout.map((planeLayout, i2) => {\n const height = Math.ceil(this.codedHeight / planeConfigs[i2].heightDivisor);\n return {\n data: this._data.subarray(planeLayout.offset, planeLayout.offset + planeLayout.stride * height),\n stride: planeLayout.stride\n };\n });\n } else {\n const canvas = this._data;\n const context = canvas.getContext(\"2d\");\n assert(context);\n const imageData = context.getImageData(0, 0, this.codedWidth, this.codedHeight);\n dataPlanes = [{\n data: toUint8Array(imageData.data),\n stride: 4 * this.codedWidth\n }];\n }\n const planeLayouts = [];\n const numPlanes = planeConfigs.length;\n for (let planeIndex = 0; planeIndex < numPlanes; planeIndex++) {\n const computedLayout = combinedLayout.computedLayouts[planeIndex];\n const sourceStride = dataPlanes[planeIndex].stride;\n const sourceData = dataPlanes[planeIndex].data;\n let sourceOffset = computedLayout.sourceTop * sourceStride;\n sourceOffset += computedLayout.sourceLeftBytes;\n let destinationOffset = computedLayout.destinationOffset;\n const rowBytes = computedLayout.sourceWidthBytes;\n const layout = {\n offset: destinationOffset,\n stride: computedLayout.destinationStride\n };\n for (let row = 0; row < computedLayout.sourceHeight; row++) {\n if (sourceOffset + rowBytes > sourceData.byteLength) {\n throw new Error(`Source buffer OOB read.`);\n }\n if (destinationOffset + rowBytes > destBytes.byteLength) {\n throw new Error(`Destination buffer OOB write.`);\n }\n const srcSub = sourceData.subarray(sourceOffset, sourceOffset + rowBytes);\n destBytes.set(srcSub, destinationOffset);\n sourceOffset += sourceStride;\n destinationOffset += computedLayout.destinationStride;\n }\n planeLayouts.push(layout);\n }\n if (options.format !== void 0) {\n const needsRgbConversion = this.format.startsWith(\"RGB\") !== options.format.startsWith(\"RGB\");\n const needsAlphaConversion = this.format.includes(\"X\") && options.format.includes(\"A\");\n if (needsRgbConversion || needsAlphaConversion) {\n for (let i2 = 0; i2 < combinedLayout.allocationSize; i2 += 4) {\n if (needsRgbConversion) {\n const r2 = destBytes[i2];\n const b = destBytes[i2 + 2];\n destBytes[i2] = b;\n destBytes[i2 + 2] = r2;\n }\n if (needsAlphaConversion) {\n destBytes[i2 + 3] = 255;\n }\n }\n }\n }\n return planeLayouts;\n }\n /**\n * Converts this video sample to a VideoFrame for use with the WebCodecs API. The VideoFrame returned by this\n * method *must* be closed separately from this video sample.\n */\n toVideoFrame() {\n if (this._closed) {\n throw new Error(\"VideoSample is closed.\");\n }\n assert(this._data !== null);\n if (this._data instanceof VideoSampleResource) {\n if (this.format === null) {\n throw new Error(\"Cannot convert a VideoSampleResource-backed VideoSample to VideoFrame if format is null.\");\n }\n const planes = this._data.getDataPlanes();\n if (planes instanceof Promise) {\n throw new Error(\"Cannot convert a VideoSampleResource-backed VideoSample to VideoFrame if getDataPlanes() returns a promise.\");\n }\n const size = planes.reduce((a2, b) => a2 + b.data.byteLength, 0);\n const buffer = new Uint8Array(size);\n let offset = 0;\n const offsets = [];\n for (const plane of planes) {\n buffer.set(plane.data, offset);\n offsets.push(offset);\n offset += plane.data.byteLength;\n }\n return new VideoFrame(buffer, {\n format: this.format,\n layout: planes.map((x, i2) => ({\n offset: offsets[i2],\n stride: x.stride\n })),\n codedWidth: this.codedWidth,\n codedHeight: this.codedHeight,\n timestamp: this.microsecondTimestamp,\n duration: this.microsecondDuration,\n colorSpace: this.colorSpace,\n displayWidth: this.squarePixelWidth,\n // Not display* since we're not passing rotation\n displayHeight: this.squarePixelHeight\n });\n } else if (isVideoFrame(this._data)) {\n return new VideoFrame(this._data, {\n timestamp: this.microsecondTimestamp,\n duration: this.microsecondDuration || void 0\n // Drag 0 duration to undefined, glitches some codecs\n });\n } else if (this._data instanceof Uint8Array) {\n return new VideoFrame(this._data, {\n format: this.format,\n codedWidth: this.codedWidth,\n codedHeight: this.codedHeight,\n timestamp: this.microsecondTimestamp,\n duration: this.microsecondDuration || void 0,\n colorSpace: this.colorSpace,\n displayWidth: this.squarePixelWidth,\n // Not display* since we're not passing rotation\n displayHeight: this.squarePixelHeight\n });\n } else {\n return new VideoFrame(this._data, {\n timestamp: this.microsecondTimestamp,\n duration: this.microsecondDuration || void 0\n });\n }\n }\n draw(context, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) {\n let sx = 0;\n let sy = 0;\n let sWidth = this.displayWidth;\n let sHeight = this.displayHeight;\n let dx = 0;\n let dy = 0;\n let dWidth = this.displayWidth;\n let dHeight = this.displayHeight;\n if (arg5 !== void 0) {\n sx = arg1;\n sy = arg2;\n sWidth = arg3;\n sHeight = arg4;\n dx = arg5;\n dy = arg6;\n if (arg7 !== void 0) {\n dWidth = arg7;\n dHeight = arg8;\n } else {\n dWidth = sWidth;\n dHeight = sHeight;\n }\n } else {\n dx = arg1;\n dy = arg2;\n if (arg3 !== void 0) {\n dWidth = arg3;\n dHeight = arg4;\n }\n }\n if (!(typeof CanvasRenderingContext2D !== \"undefined\" && context instanceof CanvasRenderingContext2D || typeof OffscreenCanvasRenderingContext2D !== \"undefined\" && context instanceof OffscreenCanvasRenderingContext2D)) {\n throw new TypeError(\"context must be a CanvasRenderingContext2D or OffscreenCanvasRenderingContext2D.\");\n }\n if (!Number.isFinite(sx)) {\n throw new TypeError(\"sx must be a number.\");\n }\n if (!Number.isFinite(sy)) {\n throw new TypeError(\"sy must be a number.\");\n }\n if (!Number.isFinite(sWidth) || sWidth < 0) {\n throw new TypeError(\"sWidth must be a non-negative number.\");\n }\n if (!Number.isFinite(sHeight) || sHeight < 0) {\n throw new TypeError(\"sHeight must be a non-negative number.\");\n }\n if (!Number.isFinite(dx)) {\n throw new TypeError(\"dx must be a number.\");\n }\n if (!Number.isFinite(dy)) {\n throw new TypeError(\"dy must be a number.\");\n }\n if (!Number.isFinite(dWidth) || dWidth < 0) {\n throw new TypeError(\"dWidth must be a non-negative number.\");\n }\n if (!Number.isFinite(dHeight) || dHeight < 0) {\n throw new TypeError(\"dHeight must be a non-negative number.\");\n }\n if (this._closed) {\n throw new Error(\"VideoSample is closed.\");\n }\n ({ sx, sy, sWidth, sHeight } = this._rotateSourceRegion(sx, sy, sWidth, sHeight, this.rotation));\n const source = this.toCanvasImageSource();\n context.save();\n const centerX = dx + dWidth / 2;\n const centerY = dy + dHeight / 2;\n context.translate(centerX, centerY);\n context.rotate(this.rotation * Math.PI / 180);\n const aspectRatioChange = this.rotation % 180 === 0 ? 1 : dWidth / dHeight;\n context.scale(1 / aspectRatioChange, aspectRatioChange);\n context.drawImage(source, sx, sy, sWidth, sHeight, -dWidth / 2, -dHeight / 2, dWidth, dHeight);\n context.restore();\n }\n /**\n * Draws the sample in the middle of the canvas corresponding to the context with the specified fit behavior.\n */\n drawWithFit(context, options) {\n if (!(typeof CanvasRenderingContext2D !== \"undefined\" && context instanceof CanvasRenderingContext2D || typeof OffscreenCanvasRenderingContext2D !== \"undefined\" && context instanceof OffscreenCanvasRenderingContext2D)) {\n throw new TypeError(\"context must be a CanvasRenderingContext2D or OffscreenCanvasRenderingContext2D.\");\n }\n if (!options || typeof options !== \"object\") {\n throw new TypeError(\"options must be an object.\");\n }\n if (![\"fill\", \"contain\", \"cover\"].includes(options.fit)) {\n throw new TypeError(\"options.fit must be 'fill', 'contain', or 'cover'.\");\n }\n if (options.rotation !== void 0 && ![0, 90, 180, 270].includes(options.rotation)) {\n throw new TypeError(\"options.rotation, when provided, must be 0, 90, 180, or 270.\");\n }\n if (options.crop !== void 0) {\n validateCropRectangle(options.crop, \"options.\");\n }\n const canvasWidth = context.canvas.width;\n const canvasHeight = context.canvas.height;\n const rotation = options.rotation ?? this.rotation;\n const [rotatedWidth, rotatedHeight] = rotation % 180 === 0 ? [this.squarePixelWidth, this.squarePixelHeight] : [this.squarePixelHeight, this.squarePixelWidth];\n let finalCrop = options.crop;\n if (finalCrop) {\n finalCrop = clampCropRectangle(finalCrop, rotatedWidth, rotatedHeight);\n }\n let dx;\n let dy;\n let newWidth;\n let newHeight;\n const { sx, sy, sWidth, sHeight } = this._rotateSourceRegion(options.crop?.left ?? 0, options.crop?.top ?? 0, options.crop?.width ?? rotatedWidth, options.crop?.height ?? rotatedHeight, rotation);\n if (options.fit === \"fill\") {\n dx = 0;\n dy = 0;\n newWidth = canvasWidth;\n newHeight = canvasHeight;\n } else {\n const [sampleWidth, sampleHeight] = options.crop ? [options.crop.width, options.crop.height] : [rotatedWidth, rotatedHeight];\n const scale = options.fit === \"contain\" ? Math.min(canvasWidth / sampleWidth, canvasHeight / sampleHeight) : Math.max(canvasWidth / sampleWidth, canvasHeight / sampleHeight);\n newWidth = sampleWidth * scale;\n newHeight = sampleHeight * scale;\n dx = (canvasWidth - newWidth) / 2;\n dy = (canvasHeight - newHeight) / 2;\n }\n context.save();\n const aspectRatioChange = rotation % 180 === 0 ? 1 : newWidth / newHeight;\n context.translate(canvasWidth / 2, canvasHeight / 2);\n context.rotate(rotation * Math.PI / 180);\n context.scale(1 / aspectRatioChange, aspectRatioChange);\n context.translate(-canvasWidth / 2, -canvasHeight / 2);\n context.drawImage(this.toCanvasImageSource(), sx, sy, sWidth, sHeight, dx, dy, newWidth, newHeight);\n context.restore();\n }\n /** @internal */\n _rotateSourceRegion(sx, sy, sWidth, sHeight, rotation) {\n if (rotation === 90) {\n [sx, sy, sWidth, sHeight] = [\n sy,\n this.squarePixelHeight - sx - sWidth,\n sHeight,\n sWidth\n ];\n } else if (rotation === 180) {\n [sx, sy] = [\n this.squarePixelWidth - sx - sWidth,\n this.squarePixelHeight - sy - sHeight\n ];\n } else if (rotation === 270) {\n [sx, sy, sWidth, sHeight] = [\n this.squarePixelWidth - sy - sHeight,\n sx,\n sHeight,\n sWidth\n ];\n }\n return { sx, sy, sWidth, sHeight };\n }\n /**\n * Converts this video sample to a\n * [`CanvasImageSource`](https://udn.realityripple.com/docs/Web/API/CanvasImageSource) for drawing to a canvas.\n *\n * You must use the value returned by this method immediately, as any VideoFrame created internally may\n * automatically be closed in the next microtask.\n */\n toCanvasImageSource() {\n if (this._closed) {\n throw new Error(\"VideoSample is closed.\");\n }\n assert(this._data !== null);\n if (this._data instanceof VideoSampleResource || this._data instanceof Uint8Array) {\n const videoFrame = this.toVideoFrame();\n queueMicrotask(() => videoFrame.close());\n return videoFrame;\n } else {\n return this._data;\n }\n }\n /**\n * Transform this video sample to a new video sample given the options. Can be used to resize, rotate, and crop\n * the sample.\n *\n * In non-browser environments, this method will not work by default. To make it work, register a custom\n * transformer function via {@link registerVideoSampleTransformer}.\n */\n async transform(options) {\n if (!options || typeof options !== \"object\") {\n throw new TypeError(\"options must be an object.\");\n }\n if (options.width !== void 0 && (!Number.isInteger(options.width) || options.width <= 0)) {\n throw new TypeError(\"options.width, when provided, must be a positive integer.\");\n }\n if (options.height !== void 0 && (!Number.isInteger(options.height) || options.height <= 0)) {\n throw new TypeError(\"options.height, when provided, must be a positive integer.\");\n }\n if (options.roundDimensionsTo !== void 0 && (!Number.isInteger(options.roundDimensionsTo) || options.roundDimensionsTo <= 0)) {\n throw new TypeError(\"options.roundDimensionsTo, when provided, must be a positive integer.\");\n }\n if (options.fit !== void 0 && ![\"fill\", \"contain\", \"cover\"].includes(options.fit)) {\n throw new TypeError('options.fit, when provided, must be one of \"fill\", \"contain\", or \"cover\".');\n }\n if (options.width !== void 0 && options.height !== void 0 && options.fit === void 0) {\n throw new TypeError(\"When both options.width and options.height are provided, options.fit must also be provided.\");\n }\n if (options.rotate !== void 0 && ![0, 90, 180, 270].includes(options.rotate)) {\n throw new TypeError(\"options.rotate, when provided, must be 0, 90, 180 or 270.\");\n }\n if (options.crop !== void 0) {\n validateCropRectangle(options.crop, \"options.\");\n }\n if (options.alpha !== void 0 && ![\"keep\", \"discard\"].includes(options.alpha)) {\n throw new TypeError(\"options.alpha, when provided, must be 'keep' or 'discard'.\");\n }\n const rotation = normalizeRotation(this.rotation + (options.rotate ?? 0));\n const [rotatedWidth, rotatedHeight] = rotation % 180 === 0 ? [this.squarePixelWidth, this.squarePixelHeight] : [this.squarePixelHeight, this.squarePixelWidth];\n let finalCrop = options.crop;\n if (finalCrop) {\n finalCrop = clampCropRectangle(finalCrop, rotatedWidth, rotatedHeight);\n }\n const cropWidth = finalCrop ? finalCrop.width : rotatedWidth;\n const cropHeight = finalCrop ? finalCrop.height : rotatedHeight;\n const originalAspectRatio = cropWidth / cropHeight;\n let targetWidth;\n let targetHeight;\n if (options.width !== void 0 && options.height === void 0) {\n targetWidth = options.width;\n targetHeight = targetWidth / originalAspectRatio;\n } else if (options.width === void 0 && options.height !== void 0) {\n targetHeight = options.height;\n targetWidth = targetHeight * originalAspectRatio;\n } else if (options.width !== void 0 && options.height !== void 0) {\n targetWidth = options.width;\n targetHeight = options.height;\n } else {\n targetWidth = cropWidth;\n targetHeight = cropHeight;\n }\n targetWidth = roundToMultiple(targetWidth, options.roundDimensionsTo ?? 1);\n targetHeight = roundToMultiple(targetHeight, options.roundDimensionsTo ?? 1);\n const description = {\n width: targetWidth,\n height: targetHeight,\n fit: options.fit ?? \"fill\",\n rotation,\n crop: finalCrop ?? {\n left: 0,\n top: 0,\n width: rotatedWidth,\n height: rotatedHeight\n },\n alpha: options.alpha ?? \"keep\"\n };\n for (const transformer of registeredVideoSampleTransformers) {\n let result = transformer(this, description);\n if (result instanceof Promise)\n result = await result;\n if (result !== null) {\n return result;\n }\n }\n let canvas = null;\n let canvasIsNew = false;\n for (const entry of transformationCanvasCache) {\n if (entry.canvas.width === description.width && entry.canvas.height === description.height) {\n canvas = entry.canvas;\n entry.age = transformationCanvasCacheNextAge++;\n break;\n }\n }\n if (canvas === null) {\n if (typeof OffscreenCanvas !== \"undefined\") {\n canvas = new OffscreenCanvas(description.width, description.height);\n } else {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n throw new Error(\"Cannot transform VideoSamples in this environment. Either run in an environment with OffscreenCanvas or HTMLCanvasElement, or supply a custom VideoSample transformer using registerVideoSampleTransformer().\");\n }\n canvas = document.createElement(\"canvas\");\n canvas.width = description.width;\n canvas.height = description.height;\n }\n canvasIsNew = true;\n if (transformationCanvasCache.length >= TRANSFORMATION_CANVAS_CACHE_MAX_SIZE) {\n transformationCanvasCache.splice(arrayArgmin(transformationCanvasCache, (x) => x.age), 1);\n }\n transformationCanvasCache.push({\n canvas,\n age: transformationCanvasCacheNextAge++\n });\n }\n const context = canvas.getContext(\"2d\", {\n alpha: true\n });\n if (!context) {\n throw new Error(\"The '2d' canvas context is required to transform VideoSamples. Register a custom transformer using registerVideoSampleTransformer to work around this limitation.\");\n }\n if (description.alpha === \"discard\") {\n context.fillStyle = \"black\";\n context.fillRect(0, 0, description.width, description.height);\n } else if (!canvasIsNew) {\n context.clearRect(0, 0, description.width, description.height);\n }\n this.drawWithFit(context, {\n fit: description.fit,\n rotation: description.rotation,\n crop: description.crop\n });\n return new _VideoSample(canvas, {\n timestamp: this.timestamp,\n duration: this.duration,\n rotation: 0\n // Any previous rotation is now baked in\n });\n }\n /** Sets the rotation metadata of this video sample. */\n setRotation(newRotation) {\n if (![0, 90, 180, 270].includes(newRotation)) {\n throw new TypeError(\"newRotation must be 0, 90, 180, or 270.\");\n }\n this.rotation = newRotation;\n }\n /** Sets the presentation timestamp of this video sample, in seconds. */\n setTimestamp(newTimestamp) {\n if (!Number.isFinite(newTimestamp)) {\n throw new TypeError(\"newTimestamp must be a number.\");\n }\n this.timestamp = newTimestamp;\n }\n /** Sets the duration of this video sample, in seconds. */\n setDuration(newDuration) {\n if (!Number.isFinite(newDuration) || newDuration < 0) {\n throw new TypeError(\"newDuration must be a non-negative number.\");\n }\n this.duration = newDuration;\n }\n /** Sets the encode options used when this sample is passed to an encoder. */\n setEncodeOptions(newEncodeOptions) {\n if (!newEncodeOptions || typeof newEncodeOptions !== \"object\") {\n throw new TypeError(\"newEncodeOptions must be an object.\");\n }\n this.encodeOptions = newEncodeOptions;\n }\n /** Calls `.close()`. */\n [Symbol.dispose]() {\n this.close();\n }\n};\nvar registeredVideoSampleTransformers = [];\nvar TRANSFORMATION_CANVAS_CACHE_MAX_SIZE = 3;\nvar transformationCanvasCache = [];\nvar transformationCanvasCacheNextAge = 0;\nvar VideoSampleColorSpace = class {\n /** Creates a new VideoSampleColorSpace. */\n constructor(init) {\n if (init !== void 0) {\n if (!init || typeof init !== \"object\") {\n throw new TypeError(\"init.colorSpace, when provided, must be an object.\");\n }\n const primariesValues = Object.keys(COLOR_PRIMARIES_MAP);\n if (init.primaries != null && !primariesValues.includes(init.primaries)) {\n throw new TypeError(`init.colorSpace.primaries, when provided, must be one of ${primariesValues.join(\", \")}.`);\n }\n const transferValues = Object.keys(TRANSFER_CHARACTERISTICS_MAP);\n if (init.transfer != null && !transferValues.includes(init.transfer)) {\n throw new TypeError(`init.colorSpace.transfer, when provided, must be one of ${transferValues.join(\", \")}.`);\n }\n const matrixValues = Object.keys(MATRIX_COEFFICIENTS_MAP);\n if (init.matrix != null && !matrixValues.includes(init.matrix)) {\n throw new TypeError(`init.colorSpace.matrix, when provided, must be one of ${matrixValues.join(\", \")}.`);\n }\n if (init.fullRange != null && typeof init.fullRange !== \"boolean\") {\n throw new TypeError(\"init.colorSpace.fullRange, when provided, must be a boolean.\");\n }\n }\n this.primaries = init?.primaries ?? null;\n this.transfer = init?.transfer ?? null;\n this.matrix = init?.matrix ?? null;\n this.fullRange = init?.fullRange ?? null;\n }\n /** Serializes the color space to a JSON object. */\n toJSON() {\n return {\n primaries: this.primaries,\n transfer: this.transfer,\n matrix: this.matrix,\n fullRange: this.fullRange\n };\n }\n};\nvar isVideoFrame = (x) => {\n return typeof VideoFrame !== \"undefined\" && x instanceof VideoFrame;\n};\nvar clampCropRectangle = (crop, outerWidth, outerHeight) => {\n const left = Math.min(crop.left, outerWidth);\n const top = Math.min(crop.top, outerHeight);\n const width = Math.min(crop.width, outerWidth - left);\n const height = Math.min(crop.height, outerHeight - top);\n assert(width >= 0);\n assert(height >= 0);\n return { left, top, width, height };\n};\nvar validateCropRectangle = (crop, prefix) => {\n if (!crop || typeof crop !== \"object\") {\n throw new TypeError(prefix + \"crop, when provided, must be an object.\");\n }\n if (!Number.isInteger(crop.left) || crop.left < 0) {\n throw new TypeError(prefix + \"crop.left must be a non-negative integer.\");\n }\n if (!Number.isInteger(crop.top) || crop.top < 0) {\n throw new TypeError(prefix + \"crop.top must be a non-negative integer.\");\n }\n if (!Number.isInteger(crop.width) || crop.width < 0) {\n throw new TypeError(prefix + \"crop.width must be a non-negative integer.\");\n }\n if (!Number.isInteger(crop.height) || crop.height < 0) {\n throw new TypeError(prefix + \"crop.height must be a non-negative integer.\");\n }\n};\nvar validateVideoFrameCopyToOptions = (options) => {\n if (!options || typeof options !== \"object\") {\n throw new TypeError(\"options must be an object.\");\n }\n if (options.colorSpace !== void 0 && ![\"display-p3\", \"srgb\"].includes(options.colorSpace)) {\n throw new TypeError(\"options.colorSpace, when provided, must be 'display-p3' or 'srgb'.\");\n }\n if (options.format !== void 0 && typeof options.format !== \"string\") {\n throw new TypeError(\"options.format, when provided, must be a string.\");\n }\n if (options.layout !== void 0) {\n if (!Array.isArray(options.layout)) {\n throw new TypeError(\"options.layout, when provided, must be an array.\");\n }\n for (const plane of options.layout) {\n if (!plane || typeof plane !== \"object\") {\n throw new TypeError(\"Each entry in options.layout must be an object.\");\n }\n if (!Number.isInteger(plane.offset) || plane.offset < 0) {\n throw new TypeError(\"plane.offset must be a non-negative integer.\");\n }\n if (!Number.isInteger(plane.stride) || plane.stride < 0) {\n throw new TypeError(\"plane.stride must be a non-negative integer.\");\n }\n }\n }\n if (options.rect !== void 0) {\n if (!options.rect || typeof options.rect !== \"object\") {\n throw new TypeError(\"options.rect, when provided, must be an object.\");\n }\n if (options.rect.x !== void 0 && (!Number.isInteger(options.rect.x) || options.rect.x < 0)) {\n throw new TypeError(\"options.rect.x, when provided, must be a non-negative integer.\");\n }\n if (options.rect.y !== void 0 && (!Number.isInteger(options.rect.y) || options.rect.y < 0)) {\n throw new TypeError(\"options.rect.y, when provided, must be a non-negative integer.\");\n }\n if (options.rect.width !== void 0 && (!Number.isInteger(options.rect.width) || options.rect.width < 0)) {\n throw new TypeError(\"options.rect.width, when provided, must be a non-negative integer.\");\n }\n if (options.rect.height !== void 0 && (!Number.isInteger(options.rect.height) || options.rect.height < 0)) {\n throw new TypeError(\"options.rect.height, when provided, must be a non-negative integer.\");\n }\n }\n};\nvar createDefaultPlaneLayout = (format, codedWidth, codedHeight) => {\n const planes = getPlaneConfigs(format);\n const layouts = [];\n let currentOffset = 0;\n for (const plane of planes) {\n const planeWidth = Math.ceil(codedWidth / plane.widthDivisor);\n const planeHeight = Math.ceil(codedHeight / plane.heightDivisor);\n const stride = planeWidth * plane.sampleBytes;\n const planeSize = stride * planeHeight;\n layouts.push({\n offset: currentOffset,\n stride\n });\n currentOffset += planeSize;\n }\n return layouts;\n};\nvar getPlaneConfigs = (format) => {\n const yuv = (yBytes, uvBytes, subX, subY, hasAlpha) => {\n const configs = [\n { sampleBytes: yBytes, widthDivisor: 1, heightDivisor: 1 },\n { sampleBytes: uvBytes, widthDivisor: subX, heightDivisor: subY },\n { sampleBytes: uvBytes, widthDivisor: subX, heightDivisor: subY }\n ];\n if (hasAlpha) {\n configs.push({ sampleBytes: yBytes, widthDivisor: 1, heightDivisor: 1 });\n }\n return configs;\n };\n switch (format) {\n case \"I420\":\n return yuv(1, 1, 2, 2, false);\n case \"I420P10\":\n case \"I420P12\":\n return yuv(2, 2, 2, 2, false);\n case \"I420A\":\n return yuv(1, 1, 2, 2, true);\n case \"I420AP10\":\n case \"I420AP12\":\n return yuv(2, 2, 2, 2, true);\n case \"I422\":\n return yuv(1, 1, 2, 1, false);\n case \"I422P10\":\n case \"I422P12\":\n return yuv(2, 2, 2, 1, false);\n case \"I422A\":\n return yuv(1, 1, 2, 1, true);\n case \"I422AP10\":\n case \"I422AP12\":\n return yuv(2, 2, 2, 1, true);\n case \"I444\":\n return yuv(1, 1, 1, 1, false);\n case \"I444P10\":\n case \"I444P12\":\n return yuv(2, 2, 1, 1, false);\n case \"I444A\":\n return yuv(1, 1, 1, 1, true);\n case \"I444AP10\":\n case \"I444AP12\":\n return yuv(2, 2, 1, 1, true);\n case \"NV12\":\n return [\n { sampleBytes: 1, widthDivisor: 1, heightDivisor: 1 },\n { sampleBytes: 2, widthDivisor: 2, heightDivisor: 2 }\n // Interleaved U and V\n ];\n case \"RGBA\":\n case \"RGBX\":\n case \"BGRA\":\n case \"BGRX\":\n return [\n { sampleBytes: 4, widthDivisor: 1, heightDivisor: 1 }\n ];\n default:\n assertNever(format);\n assert(false);\n }\n};\nvar ParseVideoFrameCopyToOptions = (sample, options) => {\n const defaultRect = {\n left: 0,\n top: 0,\n width: sample.codedWidth,\n height: sample.codedHeight\n };\n const overrideRect = options.rect;\n const parsedRect = ParseVisibleRect(defaultRect, overrideRect, sample.codedWidth, sample.codedHeight, sample.format);\n const optLayout = options.layout;\n let format;\n if (!options.format || options.format === sample.format) {\n format = sample.format;\n } else if ([\"RGBA\", \"RGBX\", \"BGRA\", \"BGRX\"].includes(options.format)) {\n format = options.format;\n } else {\n throw new Error(\"NotSupportedError: Invalid destination format.\");\n }\n return ComputeLayoutAndAllocationSize(parsedRect, format, optLayout);\n};\nvar ParseVisibleRect = (defaultRect, overrideRect, codedWidth, codedHeight, format) => {\n const sourceRect = { ...defaultRect };\n if (overrideRect !== void 0) {\n if (overrideRect.width === 0 || overrideRect.height === 0) {\n throw new TypeError(\"visibleRect dimensions cannot be zero.\");\n }\n if ((overrideRect.x || 0) + (overrideRect.width || 0) > codedWidth) {\n throw new TypeError(\"visibleRect exceeds codedWidth.\");\n }\n if ((overrideRect.y || 0) + (overrideRect.height || 0) > codedHeight) {\n throw new TypeError(\"visibleRect exceeds codedHeight.\");\n }\n sourceRect.x = overrideRect.x || 0;\n sourceRect.y = overrideRect.y || 0;\n sourceRect.width = overrideRect.width || 0;\n sourceRect.height = overrideRect.height || 0;\n }\n const validAlignment = VerifyRectOffsetAlignment(format, sourceRect);\n if (!validAlignment) {\n throw new TypeError(\"visibleRect alignment is invalid for the format.\");\n }\n return sourceRect;\n};\nvar VerifyRectOffsetAlignment = (format, rect) => {\n if (format === null)\n return true;\n const planes = getPlaneConfigs(format);\n for (let planeIndex = 0; planeIndex < planes.length; planeIndex++) {\n const plane = planes[planeIndex];\n const sampleWidth = plane.widthDivisor;\n const sampleHeight = plane.heightDivisor;\n if ((rect.x || 0) % sampleWidth !== 0)\n return false;\n if ((rect.y || 0) % sampleHeight !== 0)\n return false;\n }\n return true;\n};\nvar ComputeLayoutAndAllocationSize = (parsedRect, format, layout) => {\n const planes = getPlaneConfigs(format);\n const numPlanes = planes.length;\n if (layout !== void 0 && layout.length !== numPlanes) {\n throw new TypeError(`Layout must have ${numPlanes} planes.`);\n }\n let minAllocationSize = 0;\n const computedLayouts = [];\n const endOffsets = [];\n for (let planeIndex = 0; planeIndex < numPlanes; planeIndex++) {\n const plane = planes[planeIndex];\n const sampleBytes = plane.sampleBytes;\n const sampleWidth = plane.widthDivisor;\n const sampleHeight = plane.heightDivisor;\n const computedLayout = {\n destinationOffset: 0,\n destinationStride: 0,\n sourceTop: 0,\n sourceHeight: 0,\n sourceLeftBytes: 0,\n sourceWidthBytes: 0\n };\n computedLayout.sourceTop = Math.ceil(Math.trunc(parsedRect.y || 0) / sampleHeight);\n computedLayout.sourceHeight = Math.ceil(Math.trunc(parsedRect.height || 0) / sampleHeight);\n computedLayout.sourceLeftBytes = Math.floor(Math.trunc(parsedRect.x || 0) / sampleWidth) * sampleBytes;\n computedLayout.sourceWidthBytes = Math.floor(Math.trunc(parsedRect.width || 0) / sampleWidth) * sampleBytes;\n if (layout !== void 0) {\n const planeLayout = layout[planeIndex];\n if (planeLayout.stride < computedLayout.sourceWidthBytes) {\n throw new TypeError(`Stride for plane ${planeIndex} is too small.`);\n }\n computedLayout.destinationOffset = planeLayout.offset;\n computedLayout.destinationStride = planeLayout.stride;\n } else {\n computedLayout.destinationOffset = minAllocationSize;\n computedLayout.destinationStride = computedLayout.sourceWidthBytes;\n }\n const planeSize = computedLayout.destinationStride * computedLayout.sourceHeight;\n const planeEnd = planeSize + computedLayout.destinationOffset;\n if (planeEnd > 4294967295) {\n throw new TypeError(\"Allocation size exceeds limit.\");\n }\n endOffsets.push(planeEnd);\n minAllocationSize = Math.max(minAllocationSize, planeEnd);\n for (let earlierPlaneIndex = 0; earlierPlaneIndex < planeIndex; earlierPlaneIndex++) {\n const earlierLayout = computedLayouts[earlierPlaneIndex];\n if (endOffsets[planeIndex] <= earlierLayout.destinationOffset || endOffsets[earlierPlaneIndex] <= computedLayout.destinationOffset) {\n continue;\n }\n throw new TypeError(\"Planes overlap.\");\n }\n computedLayouts.push(computedLayout);\n }\n return {\n allocationSize: minAllocationSize,\n computedLayouts\n };\n};\n\n// node_modules/mediabunny/dist/modules/src/encode.js\nvar canEncodeVideoMemo = /* @__PURE__ */ new Map();\nvar validateVideoEncodingConfig = (config) => {\n if (!config || typeof config !== \"object\") {\n throw new TypeError(\"Encoding config must be an object.\");\n }\n if (!VIDEO_CODECS.includes(config.codec)) {\n throw new TypeError(`Invalid video codec '${config.codec}'. Must be one of: ${VIDEO_CODECS.join(\", \")}.`);\n }\n if (!(config.bitrate instanceof Quality) && (!Number.isInteger(config.bitrate) || config.bitrate <= 0)) {\n throw new TypeError(\"config.bitrate must be a positive integer or a quality.\");\n }\n if (config.keyFrameInterval !== void 0 && (!Number.isFinite(config.keyFrameInterval) || config.keyFrameInterval < 0)) {\n throw new TypeError(\"config.keyFrameInterval, when provided, must be a non-negative number.\");\n }\n if (config.sizeChangeBehavior !== void 0 && ![\"deny\", \"passThrough\", \"fill\", \"contain\", \"cover\"].includes(config.sizeChangeBehavior)) {\n throw new TypeError(\"config.sizeChangeBehavior, when provided, must be 'deny', 'passThrough', 'fill', 'contain' or 'cover'.\");\n }\n if (config.transform !== void 0) {\n if (typeof config.transform !== \"object\" || !config.transform) {\n throw new TypeError(\"config.transform, when provided, must be an object.\");\n }\n if (config.transform.width !== void 0 && (!Number.isInteger(config.transform.width) || config.transform.width <= 0)) {\n throw new TypeError(\"config.transform.width, when provided, must be a positive integer.\");\n }\n if (config.transform.height !== void 0 && (!Number.isInteger(config.transform.height) || config.transform.height <= 0)) {\n throw new TypeError(\"config.transform.height, when provided, must be a positive integer.\");\n }\n if (config.transform.fit !== void 0 && ![\"fill\", \"contain\", \"cover\"].includes(config.transform.fit)) {\n throw new TypeError('config.transform.fit, when provided, must be one of \"fill\", \"contain\", or \"cover\".');\n }\n if (config.transform.width !== void 0 && config.transform.height !== void 0 && config.transform.fit === void 0 && ![\"fill\", \"contain\", \"cover\"].includes(config.sizeChangeBehavior)) {\n throw new TypeError(\"When both config.transform.width and config.transform.height are provided, config.transform.fit must also be provided.\");\n }\n if (config.transform.fit !== void 0 && [\"fill\", \"contain\", \"cover\"].includes(config.sizeChangeBehavior) && config.transform.fit !== config.sizeChangeBehavior) {\n throw new TypeError(\"config.transform.fit, when provided, cannot differ from config.sizeChangeBehavior when config.sizeChangeBehavior is 'fill', 'contain' or 'cover', as sizeChangeBehavior already determines the fitting algorithm.\");\n }\n if (config.transform.rotate !== void 0 && ![0, 90, 180, 270].includes(config.transform.rotate)) {\n throw new TypeError(\"config.transform.rotate, when provided, must be 0, 90, 180 or 270.\");\n }\n if (config.transform.crop !== void 0) {\n validateCropRectangle(config.transform.crop, \"config.transform.\");\n }\n if (config.transform.process !== void 0 && typeof config.transform.process !== \"function\") {\n throw new TypeError(\"config.transform.process, when provided, must be a function.\");\n }\n if (config.transform.frameRate !== void 0 && (!Number.isFinite(config.transform.frameRate) || config.transform.frameRate <= 0)) {\n throw new TypeError(\"config.transform.frameRate, when provided, must be a finite positive number.\");\n }\n if (config.transform.force !== void 0 && typeof config.transform.force !== \"boolean\") {\n throw new TypeError(\"config.transform.force, when provided, must be a boolean.\");\n }\n }\n if (config.onEncodedPacket !== void 0 && typeof config.onEncodedPacket !== \"function\") {\n throw new TypeError(\"config.onEncodedPacket, when provided, must be a function.\");\n }\n if (config.onEncoderConfig !== void 0 && typeof config.onEncoderConfig !== \"function\") {\n throw new TypeError(\"config.onEncoderConfig, when provided, must be a function.\");\n }\n if (config.onEncodedSample !== void 0 && typeof config.onEncodedSample !== \"function\") {\n throw new TypeError(\"config.onEncodedSample, when provided, must be a function.\");\n }\n validateVideoEncodingAdditionalOptions(config.codec, config);\n};\nvar validateVideoEncodingAdditionalOptions = (codec, options) => {\n if (!options || typeof options !== \"object\") {\n throw new TypeError(\"Encoding options must be an object.\");\n }\n if (options.alpha !== void 0 && ![\"discard\", \"keep\"].includes(options.alpha)) {\n throw new TypeError(\"options.alpha, when provided, must be 'discard' or 'keep'.\");\n }\n if (options.bitrateMode !== void 0 && ![\"constant\", \"variable\"].includes(options.bitrateMode)) {\n throw new TypeError(\"bitrateMode, when provided, must be 'constant' or 'variable'.\");\n }\n if (options.latencyMode !== void 0 && ![\"quality\", \"realtime\"].includes(options.latencyMode)) {\n throw new TypeError(\"latencyMode, when provided, must be 'quality' or 'realtime'.\");\n }\n if (options.fullCodecString !== void 0 && typeof options.fullCodecString !== \"string\") {\n throw new TypeError(\"fullCodecString, when provided, must be a string.\");\n }\n if (options.fullCodecString !== void 0 && inferCodecFromCodecString(options.fullCodecString) !== codec) {\n throw new TypeError(`fullCodecString, when provided, must be a string that matches the specified codec (${codec}).`);\n }\n if (options.hardwareAcceleration !== void 0 && ![\"no-preference\", \"prefer-hardware\", \"prefer-software\"].includes(options.hardwareAcceleration)) {\n throw new TypeError(\"hardwareAcceleration, when provided, must be 'no-preference', 'prefer-hardware' or 'prefer-software'.\");\n }\n if (options.scalabilityMode !== void 0 && typeof options.scalabilityMode !== \"string\") {\n throw new TypeError(\"scalabilityMode, when provided, must be a string.\");\n }\n if (options.contentHint !== void 0 && typeof options.contentHint !== \"string\") {\n throw new TypeError(\"contentHint, when provided, must be a string.\");\n }\n};\nvar buildVideoEncoderConfig = (options) => {\n const resolvedBitrate = options.bitrate instanceof Quality ? options.bitrate._toVideoBitrate(options.codec, options.width, options.height) : options.bitrate;\n return {\n codec: options.fullCodecString ?? buildVideoCodecString(options.codec, options.width, options.height, resolvedBitrate),\n width: options.width,\n height: options.height,\n displayWidth: options.squarePixelWidth,\n displayHeight: options.squarePixelHeight,\n bitrate: resolvedBitrate,\n bitrateMode: options.bitrateMode,\n alpha: options.alpha ?? \"discard\",\n framerate: options.framerate,\n latencyMode: options.latencyMode,\n hardwareAcceleration: options.hardwareAcceleration,\n scalabilityMode: options.scalabilityMode,\n contentHint: options.contentHint,\n ...getVideoEncoderConfigExtension(options.codec)\n };\n};\nvar Quality = class {\n /** @internal */\n constructor(factor) {\n this._factor = factor;\n }\n /** @internal */\n _toVideoBitrate(codec, width, height) {\n const pixels = width * height;\n const codecEfficiencyFactors = {\n avc: 1,\n // H.264/AVC (baseline)\n hevc: 0.6,\n // H.265/HEVC (~40% more efficient than AVC)\n vp9: 0.6,\n // Similar to HEVC\n av1: 0.4,\n // ~60% more efficient than AVC\n vp8: 1.2\n // Slightly less efficient than AVC\n };\n const referencePixels = 1920 * 1080;\n const referenceBitrate = 3e6;\n const scaleFactor = Math.pow(pixels / referencePixels, 0.95);\n const baseBitrate = referenceBitrate * scaleFactor;\n const codecAdjustedBitrate = baseBitrate * codecEfficiencyFactors[codec];\n const finalBitrate = codecAdjustedBitrate * this._factor;\n return Math.ceil(finalBitrate / 1e3) * 1e3;\n }\n /** @internal */\n _toAudioBitrate(codec) {\n if (PCM_AUDIO_CODECS.includes(codec) || codec === \"flac\") {\n return void 0;\n }\n const baseRates = {\n aac: 128e3,\n // 128kbps base for AAC\n opus: 64e3,\n // 64kbps base for Opus\n mp3: 16e4,\n // 160kbps base for MP3\n vorbis: 64e3,\n // 64kbps base for Vorbis\n ac3: 384e3,\n // 384kbps base for AC-3\n eac3: 192e3\n // 192kbps base for E-AC-3\n };\n const baseBitrate = baseRates[codec];\n if (!baseBitrate) {\n throw new Error(`Unhandled codec: ${codec}`);\n }\n let finalBitrate = baseBitrate * this._factor;\n if (codec === \"aac\") {\n const validRates = [96e3, 128e3, 16e4, 192e3];\n finalBitrate = validRates.reduce((prev, curr) => Math.abs(curr - finalBitrate) < Math.abs(prev - finalBitrate) ? curr : prev);\n } else if (codec === \"opus\" || codec === \"vorbis\") {\n finalBitrate = Math.max(6e3, finalBitrate);\n } else if (codec === \"mp3\") {\n const validRates = [\n 8e3,\n 16e3,\n 24e3,\n 32e3,\n 4e4,\n 48e3,\n 64e3,\n 8e4,\n 96e3,\n 112e3,\n 128e3,\n 16e4,\n 192e3,\n 224e3,\n 256e3,\n 32e4\n ];\n finalBitrate = validRates.reduce((prev, curr) => Math.abs(curr - finalBitrate) < Math.abs(prev - finalBitrate) ? curr : prev);\n }\n return Math.round(finalBitrate / 1e3) * 1e3;\n }\n};\nvar QUALITY_HIGH = /* @__PURE__ */ new Quality(2);\nvar canEncodeVideo = async (codec, options = {}) => {\n const { width = 1280, height = 720, bitrate = 1e6, ...restOptions } = options;\n if (!VIDEO_CODECS.includes(codec)) {\n return false;\n }\n if (!Number.isInteger(width) || width <= 0) {\n throw new TypeError(\"width must be a positive integer.\");\n }\n if (!Number.isInteger(height) || height <= 0) {\n throw new TypeError(\"height must be a positive integer.\");\n }\n if (!(bitrate instanceof Quality) && (!Number.isInteger(bitrate) || bitrate <= 0)) {\n throw new TypeError(\"bitrate must be a positive integer or a quality.\");\n }\n validateVideoEncodingAdditionalOptions(codec, restOptions);\n const encoderConfig = buildVideoEncoderConfig({\n codec,\n width,\n height,\n bitrate,\n framerate: void 0,\n ...restOptions,\n alpha: \"discard\"\n // Since we handle alpha ourselves\n });\n const key = JSON.stringify(encoderConfig);\n const memoized = canEncodeVideoMemo.get(key);\n if (memoized) {\n return memoized;\n }\n const promise = (async () => {\n if (customVideoEncoders.some((x) => x.supports(codec, encoderConfig))) {\n return true;\n }\n if (typeof VideoEncoder === \"undefined\") {\n return false;\n }\n const hasOddDimension = width % 2 === 1 || height % 2 === 1;\n if (hasOddDimension && (codec === \"avc\" || codec === \"hevc\")) {\n return false;\n }\n const support = await VideoEncoder.isConfigSupported(encoderConfig);\n if (!support.supported) {\n return false;\n }\n if (isFirefox()) {\n return new Promise(async (resolve) => {\n try {\n const encoder = new VideoEncoder({\n output: () => {\n },\n error: () => resolve(false)\n });\n encoder.configure(encoderConfig);\n const frameData = new Uint8Array(width * height * 4);\n const frame = new VideoFrame(frameData, {\n format: \"RGBA\",\n codedWidth: width,\n codedHeight: height,\n timestamp: 0\n });\n encoder.encode(frame);\n frame.close();\n await encoder.flush();\n resolve(true);\n } catch {\n resolve(false);\n }\n });\n }\n return true;\n })();\n canEncodeVideoMemo.set(key, promise);\n return promise;\n};\n\n// node_modules/mediabunny/dist/modules/src/custom-coder.js\nvar customVideoEncoders = [];\n\n// node_modules/mediabunny/dist/modules/src/reader.js\nvar FileSlice = class _FileSlice {\n constructor(bytes2, view2, offset, start, end) {\n this.bytes = bytes2;\n this.view = view2;\n this.offset = offset;\n this.start = start;\n this.end = end;\n this.bufferPos = start - offset;\n }\n static tempFromBytes(bytes2) {\n return new _FileSlice(bytes2, toDataView(bytes2), 0, 0, bytes2.length);\n }\n get length() {\n return this.end - this.start;\n }\n get filePos() {\n return this.offset + this.bufferPos;\n }\n set filePos(value) {\n this.bufferPos = value - this.offset;\n }\n /** The number of bytes left from the current pos to the end of the slice. */\n get remainingLength() {\n return Math.max(this.end - this.filePos, 0);\n }\n skip(byteCount) {\n this.bufferPos += byteCount;\n }\n /** Creates a new subslice of this slice whose byte range must be contained within this slice. */\n slice(filePos, length = this.end - filePos) {\n if (filePos < this.start || filePos + length > this.end) {\n throw new RangeError(\"Slicing outside of original slice.\");\n }\n return new _FileSlice(this.bytes, this.view, this.offset, filePos, filePos + length);\n }\n};\nvar checkIsInRange = (slice, bytesToRead) => {\n if (slice.filePos < slice.start || slice.filePos + bytesToRead > slice.end) {\n 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.`);\n }\n};\nvar readBytes = (slice, length) => {\n checkIsInRange(slice, length);\n const bytes2 = slice.bytes.subarray(slice.bufferPos, slice.bufferPos + length);\n slice.bufferPos += length;\n return bytes2;\n};\n\n// node_modules/mediabunny/dist/modules/src/muxer.js\nvar Muxer = class {\n constructor(output) {\n this.mutex = new AsyncMutex();\n this.trackTimestampInfo = /* @__PURE__ */ new WeakMap();\n this.output = output;\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onTrackClose(track) {\n }\n validateTimestamp(track, timestampInSeconds, isKeyPacket) {\n if (timestampInSeconds < 0) {\n throw new Error(`Timestamps must be non-negative (got ${timestampInSeconds}s).`);\n }\n let timestampInfo = this.trackTimestampInfo.get(track);\n if (!timestampInfo) {\n if (!isKeyPacket) {\n throw new Error(\"First packet must be a key packet.\");\n }\n timestampInfo = {\n maxTimestamp: timestampInSeconds,\n maxTimestampBeforeLastKeyPacket: null\n };\n this.trackTimestampInfo.set(track, timestampInfo);\n } else {\n if (isKeyPacket) {\n timestampInfo.maxTimestampBeforeLastKeyPacket = timestampInfo.maxTimestamp;\n }\n if (timestampInfo.maxTimestampBeforeLastKeyPacket !== null && timestampInSeconds < timestampInfo.maxTimestampBeforeLastKeyPacket) {\n 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.`);\n }\n timestampInfo.maxTimestamp = Math.max(timestampInfo.maxTimestamp, timestampInSeconds);\n }\n }\n};\n\n// node_modules/mediabunny/dist/modules/src/subtitles.js\nvar inlineTimestampRegex = /<(?:(\\d{2}):)?(\\d{2}):(\\d{2}).(\\d{3})>/g;\nvar timestampRegex = /(?:(\\d{2}):)?(\\d{2}):(\\d{2}).(\\d{3})/;\nvar parseSubtitleTimestamp = (string) => {\n const match = timestampRegex.exec(string);\n if (!match)\n throw new Error(\"Expected match.\");\n return 60 * 60 * 1e3 * Number(match[1] || \"0\") + 60 * 1e3 * Number(match[2]) + 1e3 * Number(match[3]) + Number(match[4]);\n};\nvar formatSubtitleTimestamp = (timestamp) => {\n const hours = Math.floor(timestamp / (60 * 60 * 1e3));\n const minutes = Math.floor(timestamp % (60 * 60 * 1e3) / (60 * 1e3));\n const seconds = Math.floor(timestamp % (60 * 1e3) / 1e3);\n const milliseconds = timestamp % 1e3;\n return hours.toString().padStart(2, \"0\") + \":\" + minutes.toString().padStart(2, \"0\") + \":\" + seconds.toString().padStart(2, \"0\") + \".\" + milliseconds.toString().padStart(3, \"0\");\n};\n\n// node_modules/mediabunny/dist/modules/src/isobmff/isobmff-boxes.js\nvar IsobmffBoxWriter = class {\n constructor(writer) {\n this.writer = writer;\n this.helper = new Uint8Array(8);\n this.helperView = new DataView(this.helper.buffer);\n this.offsets = /* @__PURE__ */ new WeakMap();\n }\n writeU32(value) {\n this.helperView.setUint32(0, value, false);\n this.writer.write(this.helper.subarray(0, 4));\n }\n writeU64(value) {\n this.helperView.setUint32(0, Math.floor(value / 2 ** 32), false);\n this.helperView.setUint32(4, value, false);\n this.writer.write(this.helper.subarray(0, 8));\n }\n writeAscii(text) {\n for (let i2 = 0; i2 < text.length; i2++) {\n this.helperView.setUint8(i2 % 8, text.charCodeAt(i2));\n if (i2 % 8 === 7)\n this.writer.write(this.helper);\n }\n if (text.length % 8 !== 0) {\n this.writer.write(this.helper.subarray(0, text.length % 8));\n }\n }\n writeBox(box2) {\n this.offsets.set(box2, this.writer.getPos());\n if (box2.contents && !box2.children) {\n this.writeBoxHeader(box2, box2.size ?? box2.contents.byteLength + 8);\n this.writer.write(box2.contents);\n } else {\n const startPos = this.writer.getPos();\n this.writeBoxHeader(box2, 0);\n if (box2.contents)\n this.writer.write(box2.contents);\n if (box2.children) {\n for (const child of box2.children)\n if (child)\n this.writeBox(child);\n }\n const endPos = this.writer.getPos();\n const size = box2.size ?? endPos - startPos;\n this.writer.seek(startPos);\n this.writeBoxHeader(box2, size);\n this.writer.seek(endPos);\n }\n }\n writeBoxHeader(box2, size) {\n this.writeU32(box2.largeSize ? 1 : size);\n this.writeAscii(box2.type);\n if (box2.largeSize)\n this.writeU64(size);\n }\n measureBoxHeader(box2) {\n return 8 + (box2.largeSize ? 8 : 0);\n }\n patchBox(box2) {\n const boxOffset = this.offsets.get(box2);\n assert(boxOffset !== void 0);\n const endPos = this.writer.getPos();\n this.writer.seek(boxOffset);\n this.writeBox(box2);\n this.writer.seek(endPos);\n }\n measureBox(box2) {\n if (box2.contents && !box2.children) {\n const headerSize = this.measureBoxHeader(box2);\n return headerSize + box2.contents.byteLength;\n } else {\n let result = this.measureBoxHeader(box2);\n if (box2.contents)\n result += box2.contents.byteLength;\n if (box2.children) {\n for (const child of box2.children)\n if (child)\n result += this.measureBox(child);\n }\n return result;\n }\n }\n};\nvar bytes = /* @__PURE__ */ new Uint8Array(8);\nvar view = /* @__PURE__ */ new DataView(bytes.buffer);\nvar u8 = (value) => {\n return [(value % 256 + 256) % 256];\n};\nvar u16 = (value) => {\n view.setUint16(0, value, false);\n return [bytes[0], bytes[1]];\n};\nvar i16 = (value) => {\n view.setInt16(0, value, false);\n return [bytes[0], bytes[1]];\n};\nvar u24 = (value) => {\n view.setUint32(0, value, false);\n return [bytes[1], bytes[2], bytes[3]];\n};\nvar u32 = (value) => {\n view.setUint32(0, value, false);\n return [bytes[0], bytes[1], bytes[2], bytes[3]];\n};\nvar i32 = (value) => {\n view.setInt32(0, value, false);\n return [bytes[0], bytes[1], bytes[2], bytes[3]];\n};\nvar u64 = (value) => {\n view.setUint32(0, Math.floor(value / 2 ** 32), false);\n view.setUint32(4, value, false);\n return [bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]];\n};\nvar i64 = (value) => {\n view.setInt32(0, Math.floor(value / 2 ** 32), false);\n view.setUint32(4, value, false);\n return [bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7]];\n};\nvar fixed_8_8 = (value) => {\n view.setInt16(0, 2 ** 8 * value, false);\n return [bytes[0], bytes[1]];\n};\nvar fixed_16_16 = (value) => {\n view.setInt32(0, 2 ** 16 * value, false);\n return [bytes[0], bytes[1], bytes[2], bytes[3]];\n};\nvar fixed_2_30 = (value) => {\n view.setInt32(0, 2 ** 30 * value, false);\n return [bytes[0], bytes[1], bytes[2], bytes[3]];\n};\nvar variableUnsignedInt = (value, byteLength) => {\n const bytes2 = [];\n let remaining = value;\n do {\n let byte = remaining & 127;\n remaining >>= 7;\n if (bytes2.length > 0) {\n byte |= 128;\n }\n bytes2.push(byte);\n if (byteLength !== void 0) {\n byteLength--;\n }\n } while (remaining > 0 || byteLength);\n return bytes2.reverse();\n};\nvar ascii = (text, nullTerminated = false) => {\n const bytes2 = Array(text.length).fill(null).map((_2, i2) => text.charCodeAt(i2));\n if (nullTerminated)\n bytes2.push(0);\n return bytes2;\n};\nvar rotationMatrix = (rotationInDegrees) => {\n const theta = rotationInDegrees * (Math.PI / 180);\n const cosTheta = Math.round(Math.cos(theta));\n const sinTheta = Math.round(Math.sin(theta));\n return [\n cosTheta,\n sinTheta,\n 0,\n -sinTheta,\n cosTheta,\n 0,\n 0,\n 0,\n 1\n ];\n};\nvar IDENTITY_MATRIX = /* @__PURE__ */ rotationMatrix(0);\nvar matrixToBytes = (matrix) => {\n return [\n fixed_16_16(matrix[0]),\n fixed_16_16(matrix[1]),\n fixed_2_30(matrix[2]),\n fixed_16_16(matrix[3]),\n fixed_16_16(matrix[4]),\n fixed_2_30(matrix[5]),\n fixed_16_16(matrix[6]),\n fixed_16_16(matrix[7]),\n fixed_2_30(matrix[8])\n ];\n};\nvar box = (type, contents, children) => ({\n type,\n contents: contents && new Uint8Array(contents.flat(10)),\n children\n});\nvar fullBox = (type, version, flags, contents, children) => box(type, [u8(version), u24(flags), contents ?? []], children);\nvar ftyp = (details) => {\n const minorVersion = 512;\n if (details.isQuickTime) {\n return box(\"ftyp\", [\n ascii(\"qt \"),\n // Major brand\n u32(minorVersion),\n // Minor version\n // Compatible brands\n ascii(\"qt \")\n ]);\n }\n if (details.fragmented) {\n if (details.cmaf) {\n return box(\"ftyp\", [\n ascii(\"iso5\"),\n // Major brand\n u32(minorVersion),\n // Minor version\n // Compatible brands\n ascii(\"iso5\"),\n ascii(\"iso6\"),\n ascii(\"mp41\"),\n ascii(\"cmfc\"),\n ascii(\"dash\")\n ]);\n } else {\n return box(\"ftyp\", [\n ascii(\"iso5\"),\n // Major brand\n u32(minorVersion),\n // Minor version\n // Compatible brands\n ascii(\"iso5\"),\n ascii(\"iso6\"),\n ascii(\"mp41\")\n ]);\n }\n }\n return box(\"ftyp\", [\n ascii(\"isom\"),\n // Major brand\n u32(minorVersion),\n // Minor version\n // Compatible brands\n ascii(\"isom\"),\n details.holdsAvc ? ascii(\"avc1\") : [],\n ascii(\"mp41\")\n ]);\n};\nvar styp = () => box(\"styp\", [\n ascii(\"iso5\"),\n // Major brand\n u32(0),\n // Minor version\n // Compatible brands\n ascii(\"iso5\"),\n ascii(\"iso6\"),\n ascii(\"mp41\"),\n ascii(\"cmfc\"),\n ascii(\"dash\")\n]);\nvar sidx = (muxer, referencedSize) => {\n let duration = muxer.maxWrittenEndTimestamp - muxer.minWrittenTimestamp;\n if (!Number.isFinite(duration)) {\n duration = 0;\n }\n return fullBox(\"sidx\", 1, 0, [\n u32(1),\n // Reference ID\n u32(GLOBAL_TIMESCALE),\n // Timescale\n u64(intoTimescale(muxer.minWrittenTimestamp, GLOBAL_TIMESCALE)),\n // Earliest presentation time\n u64(0),\n // First offset\n u16(0),\n // Reserved\n u16(1),\n // Reference count\n u32(referencedSize & 2147483647),\n // Reference type (0) + referenced size\n u32(intoTimescale(duration, GLOBAL_TIMESCALE)),\n // Subsegment duration\n u32(0)\n // Starts with SAP + SAP type + SAP delta time (no information provided)\n ]);\n};\nvar mdat = (reserveLargeSize) => ({ type: \"mdat\", largeSize: reserveLargeSize });\nvar free = (size) => ({ type: \"free\", size });\nvar moov = (muxer) => {\n return box(\"moov\", void 0, [\n mvhd(muxer.creationTime, muxer.trackDatas),\n ...muxer.trackDatas.map((x) => trak(x, muxer.creationTime)),\n muxer.isFragmented ? mvex(muxer.trackDatas) : null,\n udta(muxer)\n ]);\n};\nvar mvhd = (creationTime, trackDatas) => {\n const duration = Math.max(0, ...trackDatas.map((trackData) => intoTimescale(presentationSpan(trackData), GLOBAL_TIMESCALE) + intoTimescale(trackData.startTimestampOffset ?? 0, GLOBAL_TIMESCALE)));\n const nextTrackId = Math.max(0, ...trackDatas.map((x) => x.track.id)) + 1;\n const needsU64 = !isU32(creationTime) || !isU32(duration);\n const u32OrU64 = needsU64 ? u64 : u32;\n return fullBox(\"mvhd\", +needsU64, 0, [\n u32OrU64(creationTime),\n // Creation time\n u32OrU64(creationTime),\n // Modification time\n u32(GLOBAL_TIMESCALE),\n // Timescale\n u32OrU64(duration),\n // Duration\n fixed_16_16(1),\n // Preferred rate\n fixed_8_8(1),\n // Preferred volume\n Array(10).fill(0),\n // Reserved\n matrixToBytes(IDENTITY_MATRIX),\n // Matrix\n Array(24).fill(0),\n // Pre-defined\n u32(nextTrackId)\n // Next track ID\n ]);\n};\nvar presentationSpan = (trackData) => {\n if (trackData.samples.length === 0) {\n return 0;\n }\n let minTimestamp = Infinity;\n let maxEndTimestamp = -Infinity;\n for (let i2 = 0; i2 < trackData.samples.length; i2++) {\n const sample = trackData.samples[i2];\n if (sample.timestamp < minTimestamp) {\n minTimestamp = sample.timestamp;\n }\n if (sample.timestamp + sample.duration > maxEndTimestamp) {\n maxEndTimestamp = sample.timestamp + sample.duration;\n }\n }\n if (minTimestamp === Infinity) {\n return 0;\n }\n return maxEndTimestamp - minTimestamp;\n};\nvar trak = (trackData, creationTime) => {\n const trackMetadata = getTrackMetadata(trackData);\n const needsEditList = trackData.startTimestampOffset !== null && trackData.startTimestampOffset > 0;\n return box(\"trak\", void 0, [\n tkhd(trackData, creationTime),\n needsEditList ? edts(trackData, trackData.startTimestampOffset) : null,\n mdia(trackData, creationTime),\n trackMetadata.name !== void 0 ? box(\"udta\", void 0, [\n box(\"name\", [\n ...textEncoder.encode(trackMetadata.name)\n ])\n ]) : null\n ]);\n};\nvar tkhd = (trackData, creationTime) => {\n const durationInGlobalTimescale = intoTimescale(presentationSpan(trackData), GLOBAL_TIMESCALE) + intoTimescale(trackData.startTimestampOffset ?? 0, GLOBAL_TIMESCALE);\n const needsU64 = !isU32(creationTime) || !isU32(durationInGlobalTimescale);\n const u32OrU64 = needsU64 ? u64 : u32;\n let matrix;\n if (trackData.type === \"video\") {\n const rotation = trackData.track.metadata.rotation;\n matrix = rotationMatrix(rotation ?? 0);\n } else {\n matrix = IDENTITY_MATRIX;\n }\n let flags = 2;\n if (trackData.track.metadata.disposition?.default !== false) {\n flags |= 1;\n }\n return fullBox(\"tkhd\", +needsU64, flags, [\n u32OrU64(creationTime),\n // Creation time\n u32OrU64(creationTime),\n // Modification time\n u32(trackData.track.id),\n // Track ID\n u32(0),\n // Reserved\n u32OrU64(durationInGlobalTimescale),\n // Duration\n Array(8).fill(0),\n // Reserved\n u16(0),\n // Layer\n u16(trackData.track.id),\n // Alternate group\n fixed_8_8(trackData.type === \"audio\" ? 1 : 0),\n // Volume\n u16(0),\n // Reserved\n matrixToBytes(matrix),\n // Matrix\n fixed_16_16(trackData.type === \"video\" ? trackData.info.width : 0),\n // Track width\n fixed_16_16(trackData.type === \"video\" ? trackData.info.height : 0)\n // Track height\n ]);\n};\nvar edts = (trackData, offset) => {\n const startOffset = intoTimescale(offset, GLOBAL_TIMESCALE);\n const mediaDuration = intoTimescale(presentationSpan(trackData), GLOBAL_TIMESCALE);\n const needs64Bits = !isU32(startOffset) || !isU32(mediaDuration);\n const u32OrU64 = needs64Bits ? u64 : u32;\n const i32OrI64 = needs64Bits ? i64 : i32;\n return box(\"edts\", void 0, [\n fullBox(\"elst\", needs64Bits ? 1 : 0, 0, [\n u32(2),\n // Entry count\n // #1\n u32OrU64(startOffset),\n // Segment duration\n i32OrI64(-1),\n // Media time\n fixed_16_16(1),\n // Media rate\n // #2\n u32OrU64(mediaDuration),\n // Segment duration\n i32OrI64(0),\n // Media time\n fixed_16_16(1)\n // Media rate\n ])\n ]);\n};\nvar mdia = (trackData, creationTime) => box(\"mdia\", void 0, [\n mdhd(trackData, creationTime),\n hdlr(true, TRACK_TYPE_TO_COMPONENT_SUBTYPE[trackData.type], TRACK_TYPE_TO_HANDLER_NAME[trackData.type]),\n minf(trackData)\n]);\nvar mdhd = (trackData, creationTime) => {\n const localDuration = intoTimescale(presentationSpan(trackData), trackData.timescale);\n const needsU64 = !isU32(creationTime) || !isU32(localDuration);\n const u32OrU64 = needsU64 ? u64 : u32;\n return fullBox(\"mdhd\", +needsU64, 0, [\n u32OrU64(creationTime),\n // Creation time\n u32OrU64(creationTime),\n // Modification time\n u32(trackData.timescale),\n // Timescale\n u32OrU64(localDuration),\n // Duration\n u16(getLanguageCodeInt(trackData.track.metadata.languageCode ?? UNDETERMINED_LANGUAGE)),\n // Language\n u16(0)\n // Quality\n ]);\n};\nvar TRACK_TYPE_TO_COMPONENT_SUBTYPE = {\n video: \"vide\",\n audio: \"soun\",\n subtitle: \"text\"\n};\nvar TRACK_TYPE_TO_HANDLER_NAME = {\n video: \"MediabunnyVideoHandler\",\n audio: \"MediabunnySoundHandler\",\n subtitle: \"MediabunnyTextHandler\"\n};\nvar hdlr = (hasComponentType, handlerType, name, manufacturer = \"\\0\\0\\0\\0\") => fullBox(\"hdlr\", 0, 0, [\n hasComponentType ? ascii(\"mhlr\") : u32(0),\n // Component type\n ascii(handlerType),\n // Component subtype\n ascii(manufacturer),\n // Component manufacturer\n u32(0),\n // Component flags\n u32(0),\n // Component flags mask\n ascii(name, true)\n // Component name\n]);\nvar minf = (trackData) => box(\"minf\", void 0, [\n TRACK_TYPE_TO_HEADER_BOX[trackData.type](),\n dinf(),\n stbl(trackData)\n]);\nvar vmhd = () => fullBox(\"vmhd\", 0, 1, [\n u16(0),\n // Graphics mode\n u16(0),\n // Opcolor R\n u16(0),\n // Opcolor G\n u16(0)\n // Opcolor B\n]);\nvar smhd = () => fullBox(\"smhd\", 0, 0, [\n u16(0),\n // Balance\n u16(0)\n // Reserved\n]);\nvar nmhd = () => fullBox(\"nmhd\", 0, 0);\nvar TRACK_TYPE_TO_HEADER_BOX = {\n video: vmhd,\n audio: smhd,\n subtitle: nmhd\n};\nvar dinf = () => box(\"dinf\", void 0, [\n dref()\n]);\nvar dref = () => fullBox(\"dref\", 0, 0, [\n u32(1)\n // Entry count\n], [\n url()\n]);\nvar url = () => fullBox(\"url \", 0, 1);\nvar stbl = (trackData) => {\n const needsCtts = trackData.compositionTimeOffsetTable.length > 1 || trackData.compositionTimeOffsetTable.some((x) => x.sampleCompositionTimeOffset !== 0);\n return box(\"stbl\", void 0, [\n stsd(trackData),\n stts(trackData),\n needsCtts ? ctts(trackData) : null,\n needsCtts ? cslg(trackData) : null,\n stsc(trackData),\n stsz(trackData),\n stco(trackData),\n stss(trackData)\n ]);\n};\nvar stsd = (trackData) => {\n let sampleDescription;\n if (trackData.type === \"video\") {\n sampleDescription = videoSampleDescription(videoCodecToBoxName(trackData.track.source._codec, trackData.info.decoderConfig.codec), trackData);\n } else if (trackData.type === \"audio\") {\n const boxName = audioCodecToBoxName(trackData.track.source._codec, trackData.muxer.isQuickTime);\n assert(boxName);\n sampleDescription = soundSampleDescription(boxName, trackData);\n } else if (trackData.type === \"subtitle\") {\n sampleDescription = subtitleSampleDescription(SUBTITLE_CODEC_TO_BOX_NAME[trackData.track.source._codec], trackData);\n }\n assert(sampleDescription);\n return fullBox(\"stsd\", 0, 0, [\n u32(1)\n // Entry count\n ], [\n sampleDescription\n ]);\n};\nvar videoSampleDescription = (compressionType, trackData) => box(compressionType, [\n Array(6).fill(0),\n // Reserved\n u16(1),\n // Data reference index\n u16(0),\n // Pre-defined\n u16(0),\n // Reserved\n Array(12).fill(0),\n // Pre-defined\n u16(trackData.info.width),\n // Width\n u16(trackData.info.height),\n // Height\n u32(4718592),\n // Horizontal resolution\n u32(4718592),\n // Vertical resolution\n u32(0),\n // Reserved\n u16(1),\n // Frame count\n Array(32).fill(0),\n // Compressor name\n u16(24),\n // Depth\n i16(65535)\n // Pre-defined\n], [\n VIDEO_CODEC_TO_CONFIGURATION_BOX[trackData.track.source._codec](trackData),\n pasp(trackData),\n colorSpaceIsComplete(trackData.info.decoderConfig.colorSpace) ? colr(trackData) : null\n]);\nvar pasp = (trackData) => {\n if (trackData.info.pixelAspectRatio.num === trackData.info.pixelAspectRatio.den) {\n return null;\n }\n return box(\"pasp\", [\n u32(trackData.info.pixelAspectRatio.num),\n u32(trackData.info.pixelAspectRatio.den)\n ]);\n};\nvar colr = (trackData) => box(\"colr\", [\n ascii(trackData.muxer.isQuickTime ? \"nclc\" : \"nclx\"),\n // Colour type\n u16(COLOR_PRIMARIES_MAP[trackData.info.decoderConfig.colorSpace.primaries]),\n // Colour primaries\n u16(TRANSFER_CHARACTERISTICS_MAP[trackData.info.decoderConfig.colorSpace.transfer]),\n // Transfer characteristics\n u16(MATRIX_COEFFICIENTS_MAP[trackData.info.decoderConfig.colorSpace.matrix]),\n // Matrix coefficients\n trackData.muxer.isQuickTime ? [] : u8((trackData.info.decoderConfig.colorSpace.fullRange ? 1 : 0) << 7)\n // Full range flag\n]);\nvar avcC = (trackData) => trackData.info.decoderConfig && box(\"avcC\", [\n // For AVC, description is an AVCDecoderConfigurationRecord, so nothing else to do here\n ...toUint8Array(trackData.info.decoderConfig.description)\n]);\nvar hvcC = (trackData) => trackData.info.decoderConfig && box(\"hvcC\", [\n // For HEVC, description is an HEVCDecoderConfigurationRecord, so nothing else to do here\n ...toUint8Array(trackData.info.decoderConfig.description)\n]);\nvar vpcC = (trackData) => {\n if (!trackData.info.decoderConfig) {\n return null;\n }\n const decoderConfig = trackData.info.decoderConfig;\n const parts = decoderConfig.codec.split(\".\");\n const profile = Number(parts[1]);\n const level = Number(parts[2]);\n const bitDepth = Number(parts[3]);\n const chromaSubsampling = parts[4] ? Number(parts[4]) : 1;\n const videoFullRangeFlag = parts[8] ? Number(parts[8]) : Number(decoderConfig.colorSpace?.fullRange ?? 0);\n const thirdByte = (bitDepth << 4) + (chromaSubsampling << 1) + videoFullRangeFlag;\n const colourPrimaries = parts[5] ? Number(parts[5]) : decoderConfig.colorSpace?.primaries ? COLOR_PRIMARIES_MAP[decoderConfig.colorSpace.primaries] : 2;\n const transferCharacteristics = parts[6] ? Number(parts[6]) : decoderConfig.colorSpace?.transfer ? TRANSFER_CHARACTERISTICS_MAP[decoderConfig.colorSpace.transfer] : 2;\n const matrixCoefficients = parts[7] ? Number(parts[7]) : decoderConfig.colorSpace?.matrix ? MATRIX_COEFFICIENTS_MAP[decoderConfig.colorSpace.matrix] : 2;\n return fullBox(\"vpcC\", 1, 0, [\n u8(profile),\n // Profile\n u8(level),\n // Level\n u8(thirdByte),\n // Bit depth, chroma subsampling, full range\n u8(colourPrimaries),\n // Colour primaries\n u8(transferCharacteristics),\n // Transfer characteristics\n u8(matrixCoefficients),\n // Matrix coefficients\n u16(0)\n // Codec initialization data size\n ]);\n};\nvar av1C = (trackData) => {\n return box(\"av1C\", generateAv1CodecConfigurationFromCodecString(trackData.info.decoderConfig.codec));\n};\nvar soundSampleDescription = (compressionType, trackData) => {\n let version = 0;\n let contents;\n let sampleSizeInBits = 16;\n const isPcmCodec = PCM_AUDIO_CODECS.includes(trackData.track.source._codec);\n if (isPcmCodec) {\n const codec = trackData.track.source._codec;\n const { sampleSize } = parsePcmCodec(codec);\n sampleSizeInBits = 8 * sampleSize;\n if (sampleSizeInBits > 16) {\n version = 1;\n }\n }\n if (trackData.muxer.isQuickTime) {\n version = 1;\n }\n if (version === 0) {\n contents = [\n Array(6).fill(0),\n // Reserved\n u16(1),\n // Data reference index\n u16(version),\n // Version\n u16(0),\n // Revision level\n u32(0),\n // Vendor\n u16(trackData.info.numberOfChannels),\n // Number of channels\n u16(sampleSizeInBits),\n // Sample size (bits)\n u16(0),\n // Compression ID\n u16(0),\n // Packet size\n u16(trackData.info.sampleRate < 2 ** 16 ? trackData.info.sampleRate : 0),\n // Sample rate (upper)\n u16(0)\n // Sample rate (lower)\n ];\n } else {\n const compressionId = isPcmCodec ? 0 : -2;\n contents = [\n Array(6).fill(0),\n // Reserved\n u16(1),\n // Data reference index\n u16(version),\n // Version\n u16(0),\n // Revision level\n u32(0),\n // Vendor\n u16(trackData.info.numberOfChannels),\n // Number of channels\n u16(Math.min(sampleSizeInBits, 16)),\n // Sample size (bits)\n i16(compressionId),\n // Compression ID\n u16(0),\n // Packet size\n u16(trackData.info.sampleRate < 2 ** 16 ? trackData.info.sampleRate : 0),\n // Sample rate (upper)\n u16(0),\n // Sample rate (lower)\n isPcmCodec ? [\n u32(1),\n // Samples per packet (must be 1 for uncompressed formats)\n u32(sampleSizeInBits / 8),\n // Bytes per packet\n u32(trackData.info.numberOfChannels * sampleSizeInBits / 8)\n // Bytes per frame\n ] : [\n u32(0),\n // Samples per packet (don't bother, still works with 0)\n u32(0),\n // Bytes per packet (variable)\n u32(0)\n // Bytes per frame (variable)\n ],\n u32(2)\n // Bytes per sample (constant in FFmpeg)\n ];\n }\n return box(compressionType, contents, [\n audioCodecToConfigurationBox(trackData.track.source._codec, trackData.muxer.isQuickTime)?.(trackData) ?? null\n ]);\n};\nvar esds = (trackData) => {\n let objectTypeIndication;\n switch (trackData.track.source._codec) {\n case \"aac\":\n {\n objectTypeIndication = 64;\n }\n ;\n break;\n case \"mp3\":\n {\n objectTypeIndication = 107;\n }\n ;\n break;\n case \"vorbis\":\n {\n objectTypeIndication = 221;\n }\n ;\n break;\n default:\n throw new Error(`Unhandled audio codec: ${trackData.track.source._codec}`);\n }\n let bytes2 = [\n ...u8(objectTypeIndication),\n // Object type indication\n ...u8(21),\n // stream type(6bits)=5 audio, flags(2bits)=1\n ...u24(0),\n // 24bit buffer size\n ...u32(0),\n // max bitrate\n ...u32(0)\n // avg bitrate\n ];\n if (trackData.info.decoderConfig.description) {\n const description = toUint8Array(trackData.info.decoderConfig.description);\n bytes2 = [\n ...bytes2,\n ...u8(5),\n // TAG(5) = DecoderSpecificInfo\n ...variableUnsignedInt(description.byteLength),\n ...description\n ];\n }\n bytes2 = [\n ...u16(1),\n // ES_ID = 1\n ...u8(0),\n // flags etc = 0\n ...u8(4),\n // TAG(4) = ES Descriptor\n ...variableUnsignedInt(bytes2.length),\n ...bytes2,\n ...u8(6),\n // TAG(6)\n ...u8(1),\n // length\n ...u8(2)\n // data\n ];\n bytes2 = [\n ...u8(3),\n // TAG(3) = Object Descriptor\n ...variableUnsignedInt(bytes2.length),\n ...bytes2\n ];\n return fullBox(\"esds\", 0, 0, bytes2);\n};\nvar wave = (trackData) => {\n return box(\"wave\", void 0, [\n frma(trackData),\n enda(trackData),\n box(\"\\0\\0\\0\\0\")\n // NULL tag at the end\n ]);\n};\nvar frma = (trackData) => {\n return box(\"frma\", [\n ascii(audioCodecToBoxName(trackData.track.source._codec, trackData.muxer.isQuickTime))\n ]);\n};\nvar enda = (trackData) => {\n const { littleEndian } = parsePcmCodec(trackData.track.source._codec);\n return box(\"enda\", [\n u16(+littleEndian)\n ]);\n};\nvar dOps = (trackData) => {\n let outputChannelCount = trackData.info.numberOfChannels;\n let preSkip = 3840;\n let inputSampleRate = trackData.info.sampleRate;\n let outputGain = 0;\n let channelMappingFamily = 0;\n let channelMappingTable = new Uint8Array(0);\n const description = trackData.info.decoderConfig?.description;\n if (description) {\n assert(description.byteLength >= 18);\n const bytes2 = toUint8Array(description);\n const header = parseOpusIdentificationHeader(bytes2);\n outputChannelCount = header.outputChannelCount;\n preSkip = header.preSkip;\n inputSampleRate = header.inputSampleRate;\n outputGain = header.outputGain;\n channelMappingFamily = header.channelMappingFamily;\n if (header.channelMappingTable) {\n channelMappingTable = header.channelMappingTable;\n }\n }\n return box(\"dOps\", [\n u8(0),\n // Version\n u8(outputChannelCount),\n // OutputChannelCount\n u16(preSkip),\n // PreSkip\n u32(inputSampleRate),\n // InputSampleRate\n i16(outputGain),\n // OutputGain\n u8(channelMappingFamily),\n // ChannelMappingFamily\n ...channelMappingTable\n ]);\n};\nvar dfLa = (trackData) => {\n const description = trackData.info.decoderConfig?.description;\n assert(description);\n const bytes2 = toUint8Array(description);\n return fullBox(\"dfLa\", 0, 0, [\n ...bytes2.subarray(4)\n ]);\n};\nvar pcmC = (trackData) => {\n const { littleEndian, sampleSize } = parsePcmCodec(trackData.track.source._codec);\n const formatFlags = +littleEndian;\n return fullBox(\"pcmC\", 0, 0, [\n u8(formatFlags),\n u8(8 * sampleSize)\n ]);\n};\nvar dac3 = (trackData) => {\n const frameInfo = parseAc3SyncFrame(trackData.info.firstPacket.data);\n if (!frameInfo) {\n 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).\");\n }\n const bytes2 = new Uint8Array(3);\n const bitstream = new Bitstream(bytes2);\n bitstream.writeBits(2, frameInfo.fscod);\n bitstream.writeBits(5, frameInfo.bsid);\n bitstream.writeBits(3, frameInfo.bsmod);\n bitstream.writeBits(3, frameInfo.acmod);\n bitstream.writeBits(1, frameInfo.lfeon);\n bitstream.writeBits(5, frameInfo.bitRateCode);\n bitstream.writeBits(5, 0);\n return box(\"dac3\", [...bytes2]);\n};\nvar dec3 = (trackData) => {\n const frameInfo = parseEac3SyncFrame(trackData.info.firstPacket.data);\n if (!frameInfo) {\n 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).\");\n }\n let totalBits = 16;\n for (const sub of frameInfo.substreams) {\n totalBits += 23;\n if (sub.numDepSub > 0) {\n totalBits += 9;\n } else {\n totalBits += 1;\n }\n }\n const size = Math.ceil(totalBits / 8);\n const bytes2 = new Uint8Array(size);\n const bitstream = new Bitstream(bytes2);\n bitstream.writeBits(13, frameInfo.dataRate);\n bitstream.writeBits(3, frameInfo.substreams.length - 1);\n for (const sub of frameInfo.substreams) {\n bitstream.writeBits(2, sub.fscod);\n bitstream.writeBits(5, sub.bsid);\n bitstream.writeBits(1, 0);\n bitstream.writeBits(1, 0);\n bitstream.writeBits(3, sub.bsmod);\n bitstream.writeBits(3, sub.acmod);\n bitstream.writeBits(1, sub.lfeon);\n bitstream.writeBits(3, 0);\n bitstream.writeBits(4, sub.numDepSub);\n if (sub.numDepSub > 0) {\n bitstream.writeBits(9, sub.chanLoc);\n } else {\n bitstream.writeBits(1, 0);\n }\n }\n return box(\"dec3\", [...bytes2]);\n};\nvar subtitleSampleDescription = (compressionType, trackData) => box(compressionType, [\n Array(6).fill(0),\n // Reserved\n u16(1)\n // Data reference index\n], [\n SUBTITLE_CODEC_TO_CONFIGURATION_BOX[trackData.track.source._codec](trackData)\n]);\nvar vttC = (trackData) => box(\"vttC\", [\n ...textEncoder.encode(trackData.info.config.description)\n]);\nvar stts = (trackData) => {\n return fullBox(\"stts\", 0, 0, [\n u32(trackData.timeToSampleTable.length),\n // Number of entries\n trackData.timeToSampleTable.map((x) => [\n u32(x.sampleCount),\n // Sample count\n u32(x.sampleDelta)\n // Sample duration\n ])\n ]);\n};\nvar stss = (trackData) => {\n if (trackData.samples.every((x) => x.type === \"key\"))\n return null;\n const keySamples = [...trackData.samples.entries()].filter(([, sample]) => sample.type === \"key\");\n return fullBox(\"stss\", 0, 0, [\n u32(keySamples.length),\n // Number of entries\n keySamples.map(([index]) => u32(index + 1))\n // Sync sample table\n ]);\n};\nvar stsc = (trackData) => {\n return fullBox(\"stsc\", 0, 0, [\n u32(trackData.compactlyCodedChunkTable.length),\n // Number of entries\n trackData.compactlyCodedChunkTable.map((x) => [\n u32(x.firstChunk),\n // First chunk\n u32(x.samplesPerChunk),\n // Samples per chunk\n u32(1)\n // Sample description index\n ])\n ]);\n};\nvar stsz = (trackData) => {\n if (trackData.type === \"audio\" && trackData.info.requiresPcmTransformation) {\n const { sampleSize } = parsePcmCodec(trackData.track.source._codec);\n return fullBox(\"stsz\", 0, 0, [\n u32(sampleSize * trackData.info.numberOfChannels),\n // Sample size\n u32(trackData.samples.reduce((acc, x) => acc + intoTimescale(x.duration, trackData.timescale), 0))\n ]);\n }\n return fullBox(\"stsz\", 0, 0, [\n u32(0),\n // Sample size (0 means non-constant size)\n u32(trackData.samples.length),\n // Number of entries\n trackData.samples.map((x) => u32(x.size))\n // Sample size table\n ]);\n};\nvar stco = (trackData) => {\n if (trackData.finalizedChunks.length > 0 && last(trackData.finalizedChunks).offset >= 2 ** 32) {\n return fullBox(\"co64\", 0, 0, [\n u32(trackData.finalizedChunks.length),\n // Number of entries\n trackData.finalizedChunks.map((x) => u64(x.offset))\n // Chunk offset table\n ]);\n }\n return fullBox(\"stco\", 0, 0, [\n u32(trackData.finalizedChunks.length),\n // Number of entries\n trackData.finalizedChunks.map((x) => u32(x.offset))\n // Chunk offset table\n ]);\n};\nvar ctts = (trackData) => {\n return fullBox(\"ctts\", 1, 0, [\n u32(trackData.compositionTimeOffsetTable.length),\n // Number of entries\n trackData.compositionTimeOffsetTable.map((x) => [\n u32(x.sampleCount),\n // Sample count\n i32(x.sampleCompositionTimeOffset)\n // Sample offset\n ])\n ]);\n};\nvar cslg = (trackData) => {\n let leastDecodeToDisplayDelta = Infinity;\n let greatestDecodeToDisplayDelta = -Infinity;\n let compositionStartTime = Infinity;\n let compositionEndTime = -Infinity;\n assert(trackData.compositionTimeOffsetTable.length > 0);\n assert(trackData.samples.length > 0);\n for (let i2 = 0; i2 < trackData.compositionTimeOffsetTable.length; i2++) {\n const entry = trackData.compositionTimeOffsetTable[i2];\n leastDecodeToDisplayDelta = Math.min(leastDecodeToDisplayDelta, entry.sampleCompositionTimeOffset);\n greatestDecodeToDisplayDelta = Math.max(greatestDecodeToDisplayDelta, entry.sampleCompositionTimeOffset);\n }\n for (let i2 = 0; i2 < trackData.samples.length; i2++) {\n const sample = trackData.samples[i2];\n compositionStartTime = Math.min(compositionStartTime, intoTimescale(sample.timestamp, trackData.timescale));\n compositionEndTime = Math.max(compositionEndTime, intoTimescale(sample.timestamp + sample.duration, trackData.timescale));\n }\n const compositionToDtsShift = Math.max(-leastDecodeToDisplayDelta, 0);\n if (compositionEndTime >= 2 ** 31) {\n return null;\n }\n return fullBox(\"cslg\", 0, 0, [\n i32(compositionToDtsShift),\n // Composition to DTS shift\n i32(leastDecodeToDisplayDelta),\n // Least decode to display delta\n i32(greatestDecodeToDisplayDelta),\n // Greatest decode to display delta\n i32(compositionStartTime),\n // Composition start time\n i32(compositionEndTime)\n // Composition end time\n ]);\n};\nvar mvex = (trackDatas) => {\n return box(\"mvex\", void 0, trackDatas.map(trex));\n};\nvar trex = (trackData) => {\n return fullBox(\"trex\", 0, 0, [\n u32(trackData.track.id),\n // Track ID\n u32(1),\n // Default sample description index\n u32(0),\n // Default sample duration\n u32(0),\n // Default sample size\n u32(0)\n // Default sample flags\n ]);\n};\nvar moof = (sequenceNumber, trackDatas) => {\n return box(\"moof\", void 0, [\n mfhd(sequenceNumber),\n ...trackDatas.map(traf)\n ]);\n};\nvar mfhd = (sequenceNumber) => {\n return fullBox(\"mfhd\", 0, 0, [\n u32(sequenceNumber)\n // Sequence number\n ]);\n};\nvar fragmentSampleFlags = (sample) => {\n let byte1 = 0;\n let byte2 = 0;\n const byte3 = 0;\n const byte4 = 0;\n const sampleIsDifferenceSample = sample.type === \"delta\";\n byte2 |= +sampleIsDifferenceSample;\n if (sampleIsDifferenceSample) {\n byte1 |= 1;\n } else {\n byte1 |= 2;\n }\n return byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;\n};\nvar traf = (trackData) => {\n return box(\"traf\", void 0, [\n tfhd(trackData),\n tfdt(trackData),\n trun(trackData)\n ]);\n};\nvar tfhd = (trackData) => {\n assert(trackData.currentChunk);\n let tfFlags = 0;\n tfFlags |= 8;\n tfFlags |= 16;\n tfFlags |= 32;\n tfFlags |= 131072;\n const referenceSample = trackData.currentChunk.samples[1] ?? trackData.currentChunk.samples[0];\n const referenceSampleInfo = {\n duration: referenceSample.timescaleUnitsToNextSample,\n size: referenceSample.size,\n flags: fragmentSampleFlags(referenceSample)\n };\n return fullBox(\"tfhd\", 0, tfFlags, [\n u32(trackData.track.id),\n // Track ID\n u32(referenceSampleInfo.duration),\n // Default sample duration\n u32(referenceSampleInfo.size),\n // Default sample size\n u32(referenceSampleInfo.flags)\n // Default sample flags\n ]);\n};\nvar tfdt = (trackData) => {\n assert(trackData.currentChunk);\n return fullBox(\"tfdt\", 1, 0, [\n u64(intoTimescale(trackData.currentChunk.startTimestamp, trackData.timescale))\n // Base Media Decode Time\n ]);\n};\nvar trun = (trackData) => {\n assert(trackData.currentChunk);\n const allSampleDurations = trackData.currentChunk.samples.map((x) => x.timescaleUnitsToNextSample);\n const allSampleSizes = trackData.currentChunk.samples.map((x) => x.size);\n const allSampleFlags = trackData.currentChunk.samples.map(fragmentSampleFlags);\n const allSampleCompositionTimeOffsets = trackData.currentChunk.samples.map((x) => intoTimescale(x.timestamp - x.decodeTimestamp, trackData.timescale));\n const uniqueSampleDurations = new Set(allSampleDurations);\n const uniqueSampleSizes = new Set(allSampleSizes);\n const uniqueSampleFlags = new Set(allSampleFlags);\n const uniqueSampleCompositionTimeOffsets = new Set(allSampleCompositionTimeOffsets);\n const firstSampleFlagsPresent = uniqueSampleFlags.size === 2 && allSampleFlags[0] !== allSampleFlags[1];\n const sampleDurationPresent = uniqueSampleDurations.size > 1;\n const sampleSizePresent = uniqueSampleSizes.size > 1;\n const sampleFlagsPresent = !firstSampleFlagsPresent && uniqueSampleFlags.size > 1;\n const sampleCompositionTimeOffsetsPresent = uniqueSampleCompositionTimeOffsets.size > 1 || [...uniqueSampleCompositionTimeOffsets].some((x) => x !== 0);\n let flags = 0;\n flags |= 1;\n flags |= 4 * +firstSampleFlagsPresent;\n flags |= 256 * +sampleDurationPresent;\n flags |= 512 * +sampleSizePresent;\n flags |= 1024 * +sampleFlagsPresent;\n flags |= 2048 * +sampleCompositionTimeOffsetsPresent;\n return fullBox(\"trun\", 1, flags, [\n u32(trackData.currentChunk.samples.length),\n // Sample count\n u32(trackData.currentChunk.offset - trackData.currentChunk.moofOffset || 0),\n // Data offset\n firstSampleFlagsPresent ? u32(allSampleFlags[0]) : [],\n trackData.currentChunk.samples.map((_2, i2) => [\n sampleDurationPresent ? u32(allSampleDurations[i2]) : [],\n // Sample duration\n sampleSizePresent ? u32(allSampleSizes[i2]) : [],\n // Sample size\n sampleFlagsPresent ? u32(allSampleFlags[i2]) : [],\n // Sample flags\n // Sample composition time offsets\n sampleCompositionTimeOffsetsPresent ? i32(allSampleCompositionTimeOffsets[i2]) : []\n ])\n ]);\n};\nvar mfra = (trackDatas) => {\n return box(\"mfra\", void 0, [\n ...trackDatas.map(tfra),\n mfro()\n ]);\n};\nvar tfra = (trackData, trackIndex) => {\n const version = 1;\n return fullBox(\"tfra\", version, 0, [\n u32(trackData.track.id),\n // Track ID\n u32(63),\n // This specifies that traf number, trun number and sample number are 32-bit ints\n u32(trackData.finalizedChunks.length),\n // Number of entries\n trackData.finalizedChunks.map((chunk) => [\n u64(intoTimescale(chunk.samples[0].timestamp, trackData.timescale)),\n // Time (in presentation time)\n u64(chunk.moofOffset),\n // moof offset\n u32(trackIndex + 1),\n // traf number\n u32(1),\n // trun number\n u32(1)\n // Sample number\n ])\n ]);\n};\nvar mfro = () => {\n return fullBox(\"mfro\", 0, 0, [\n // This value needs to be overwritten manually from the outside, where the actual size of the enclosing mfra box\n // is known\n u32(0)\n // Size\n ]);\n};\nvar vtte = () => box(\"vtte\");\nvar vttc = (payload, timestamp, identifier, settings, sourceId) => box(\"vttc\", void 0, [\n sourceId !== null ? box(\"vsid\", [i32(sourceId)]) : null,\n identifier !== null ? box(\"iden\", [...textEncoder.encode(identifier)]) : null,\n timestamp !== null ? box(\"ctim\", [...textEncoder.encode(formatSubtitleTimestamp(timestamp))]) : null,\n settings !== null ? box(\"sttg\", [...textEncoder.encode(settings)]) : null,\n box(\"payl\", [...textEncoder.encode(payload)])\n]);\nvar vtta = (notes) => box(\"vtta\", [...textEncoder.encode(notes)]);\nvar udta = (muxer) => {\n const boxes = [];\n const metadataFormat = muxer.format._options.metadataFormat ?? \"auto\";\n const metadataTags = muxer.output._metadataTags;\n if (metadataFormat === \"mdir\" || metadataFormat === \"auto\" && !muxer.isQuickTime) {\n const metaBox = metaMdir(metadataTags);\n if (metaBox)\n boxes.push(metaBox);\n } else if (metadataFormat === \"mdta\") {\n const metaBox = metaMdta(metadataTags);\n if (metaBox)\n boxes.push(metaBox);\n } else if (metadataFormat === \"udta\" || metadataFormat === \"auto\" && muxer.isQuickTime) {\n addQuickTimeMetadataTagBoxes(boxes, muxer.output._metadataTags);\n }\n if (boxes.length === 0) {\n return null;\n }\n return box(\"udta\", void 0, boxes);\n};\nvar addQuickTimeMetadataTagBoxes = (boxes, tags) => {\n for (const { key, value } of keyValueIterator(tags)) {\n switch (key) {\n case \"title\":\n {\n boxes.push(metadataTagStringBoxShort(\"©nam\", value));\n }\n ;\n break;\n case \"description\":\n {\n boxes.push(metadataTagStringBoxShort(\"©des\", value));\n }\n ;\n break;\n case \"artist\":\n {\n boxes.push(metadataTagStringBoxShort(\"©ART\", value));\n }\n ;\n break;\n case \"album\":\n {\n boxes.push(metadataTagStringBoxShort(\"©alb\", value));\n }\n ;\n break;\n case \"albumArtist\":\n {\n boxes.push(metadataTagStringBoxShort(\"albr\", value));\n }\n ;\n break;\n case \"genre\":\n {\n boxes.push(metadataTagStringBoxShort(\"©gen\", value));\n }\n ;\n break;\n case \"date\":\n {\n boxes.push(metadataTagStringBoxShort(\"©day\", value.toISOString().slice(0, 10)));\n }\n ;\n break;\n case \"comment\":\n {\n boxes.push(metadataTagStringBoxShort(\"©cmt\", value));\n }\n ;\n break;\n case \"lyrics\":\n {\n boxes.push(metadataTagStringBoxShort(\"©lyr\", value));\n }\n ;\n break;\n case \"raw\":\n {\n }\n ;\n break;\n case \"discNumber\":\n case \"discsTotal\":\n case \"trackNumber\":\n case \"tracksTotal\":\n case \"images\":\n {\n }\n ;\n break;\n default:\n assertNever(key);\n }\n }\n if (tags.raw) {\n for (const key in tags.raw) {\n const value = tags.raw[key];\n if (value == null || key.length !== 4 || boxes.some((x) => x.type === key)) {\n continue;\n }\n if (typeof value === \"string\") {\n boxes.push(metadataTagStringBoxShort(key, value));\n } else if (value instanceof Uint8Array) {\n boxes.push(box(key, Array.from(value)));\n }\n }\n }\n};\nvar metadataTagStringBoxShort = (name, value) => {\n const encoded = textEncoder.encode(value);\n return box(name, [\n u16(encoded.length),\n u16(getLanguageCodeInt(\"und\")),\n Array.from(encoded)\n ]);\n};\nvar DATA_BOX_MIME_TYPE_MAP = {\n \"image/jpeg\": 13,\n \"image/png\": 14,\n \"image/bmp\": 27\n};\nvar generateMetadataPairs = (tags, isMdta) => {\n const pairs = [];\n for (const { key, value } of keyValueIterator(tags)) {\n switch (key) {\n case \"title\":\n {\n pairs.push({ key: isMdta ? \"title\" : \"©nam\", value: dataStringBoxLong(value) });\n }\n ;\n break;\n case \"description\":\n {\n pairs.push({ key: isMdta ? \"description\" : \"©des\", value: dataStringBoxLong(value) });\n }\n ;\n break;\n case \"artist\":\n {\n pairs.push({ key: isMdta ? \"artist\" : \"©ART\", value: dataStringBoxLong(value) });\n }\n ;\n break;\n case \"album\":\n {\n pairs.push({ key: isMdta ? \"album\" : \"©alb\", value: dataStringBoxLong(value) });\n }\n ;\n break;\n case \"albumArtist\":\n {\n pairs.push({ key: isMdta ? \"album_artist\" : \"aART\", value: dataStringBoxLong(value) });\n }\n ;\n break;\n case \"comment\":\n {\n pairs.push({ key: isMdta ? \"comment\" : \"©cmt\", value: dataStringBoxLong(value) });\n }\n ;\n break;\n case \"genre\":\n {\n pairs.push({ key: isMdta ? \"genre\" : \"©gen\", value: dataStringBoxLong(value) });\n }\n ;\n break;\n case \"lyrics\":\n {\n pairs.push({ key: isMdta ? \"lyrics\" : \"©lyr\", value: dataStringBoxLong(value) });\n }\n ;\n break;\n case \"date\":\n {\n pairs.push({\n key: isMdta ? \"date\" : \"©day\",\n value: dataStringBoxLong(value.toISOString().slice(0, 10))\n });\n }\n ;\n break;\n case \"images\":\n {\n for (const image of value) {\n if (image.kind !== \"coverFront\") {\n continue;\n }\n pairs.push({ key: \"covr\", value: box(\"data\", [\n u32(DATA_BOX_MIME_TYPE_MAP[image.mimeType] ?? 0),\n // Type indicator\n u32(0),\n // Locale indicator\n Array.from(image.data)\n // Kinda slow, hopefully temp\n ]) });\n }\n }\n ;\n break;\n case \"trackNumber\":\n {\n if (isMdta) {\n const string = tags.tracksTotal !== void 0 ? `${value}/${tags.tracksTotal}` : value.toString();\n pairs.push({ key: \"track\", value: dataStringBoxLong(string) });\n } else {\n pairs.push({ key: \"trkn\", value: box(\"data\", [\n u32(0),\n // 8 bytes empty\n u32(0),\n u16(0),\n // Empty\n u16(value),\n u16(tags.tracksTotal ?? 0),\n u16(0)\n // Empty\n ]) });\n }\n }\n ;\n break;\n case \"discNumber\":\n {\n if (!isMdta) {\n pairs.push({ key: \"disc\", value: box(\"data\", [\n u32(0),\n // 8 bytes empty\n u32(0),\n u16(0),\n // Empty\n u16(value),\n u16(tags.discsTotal ?? 0),\n u16(0)\n // Empty\n ]) });\n }\n }\n ;\n break;\n case \"tracksTotal\":\n case \"discsTotal\":\n {\n }\n ;\n break;\n case \"raw\":\n {\n }\n ;\n break;\n default:\n assertNever(key);\n }\n }\n if (tags.raw) {\n for (const key in tags.raw) {\n const value = tags.raw[key];\n if (value == null || !isMdta && key.length !== 4 || pairs.some((x) => x.key === key)) {\n continue;\n }\n if (typeof value === \"string\") {\n pairs.push({ key, value: dataStringBoxLong(value) });\n } else if (value instanceof Uint8Array) {\n pairs.push({ key, value: box(\"data\", [\n u32(0),\n // Type indicator\n u32(0),\n // Locale indicator\n Array.from(value)\n ]) });\n } else if (value instanceof RichImageData) {\n pairs.push({ key, value: box(\"data\", [\n u32(DATA_BOX_MIME_TYPE_MAP[value.mimeType] ?? 0),\n // Type indicator\n u32(0),\n // Locale indicator\n Array.from(value.data)\n // Kinda slow, hopefully temp\n ]) });\n }\n }\n }\n return pairs;\n};\nvar metaMdir = (tags) => {\n const pairs = generateMetadataPairs(tags, false);\n if (pairs.length === 0) {\n return null;\n }\n return fullBox(\"meta\", 0, 0, void 0, [\n hdlr(false, \"mdir\", \"\", \"appl\"),\n // mdir handler\n box(\"ilst\", void 0, pairs.map((pair) => box(pair.key, void 0, [pair.value])))\n // Item list without keys box\n ]);\n};\nvar metaMdta = (tags) => {\n const pairs = generateMetadataPairs(tags, true);\n if (pairs.length === 0) {\n return null;\n }\n return box(\"meta\", void 0, [\n hdlr(false, \"mdta\", \"\"),\n // mdta handler\n fullBox(\"keys\", 0, 0, [\n u32(pairs.length)\n ], pairs.map((pair) => box(\"mdta\", [\n ...textEncoder.encode(pair.key)\n ]))),\n box(\"ilst\", void 0, pairs.map((pair, i2) => {\n const boxName = String.fromCharCode(...u32(i2 + 1));\n return box(boxName, void 0, [pair.value]);\n }))\n ]);\n};\nvar dataStringBoxLong = (value) => {\n return box(\"data\", [\n u32(1),\n // Type indicator (UTF-8)\n u32(0),\n // Locale indicator\n ...textEncoder.encode(value)\n ]);\n};\nvar videoCodecToBoxName = (codec, fullCodecString) => {\n switch (codec) {\n case \"avc\":\n return fullCodecString.startsWith(\"avc3\") ? \"avc3\" : \"avc1\";\n case \"hevc\":\n return \"hvc1\";\n case \"vp8\":\n return \"vp08\";\n case \"vp9\":\n return \"vp09\";\n case \"av1\":\n return \"av01\";\n }\n};\nvar VIDEO_CODEC_TO_CONFIGURATION_BOX = {\n avc: avcC,\n hevc: hvcC,\n vp8: vpcC,\n vp9: vpcC,\n av1: av1C\n};\nvar audioCodecToBoxName = (codec, isQuickTime) => {\n switch (codec) {\n case \"aac\":\n return \"mp4a\";\n case \"mp3\":\n return \"mp4a\";\n case \"opus\":\n return \"Opus\";\n case \"vorbis\":\n return \"mp4a\";\n case \"flac\":\n return \"fLaC\";\n case \"ulaw\":\n return \"ulaw\";\n case \"alaw\":\n return \"alaw\";\n case \"pcm-u8\":\n return \"raw \";\n case \"pcm-s8\":\n return \"sowt\";\n case \"ac3\":\n return \"ac-3\";\n case \"eac3\":\n return \"ec-3\";\n }\n if (isQuickTime) {\n switch (codec) {\n case \"pcm-s16\":\n return \"sowt\";\n case \"pcm-s16be\":\n return \"twos\";\n case \"pcm-s24\":\n return \"in24\";\n case \"pcm-s24be\":\n return \"in24\";\n case \"pcm-s32\":\n return \"in32\";\n case \"pcm-s32be\":\n return \"in32\";\n case \"pcm-f32\":\n return \"fl32\";\n case \"pcm-f32be\":\n return \"fl32\";\n case \"pcm-f64\":\n return \"fl64\";\n case \"pcm-f64be\":\n return \"fl64\";\n }\n } else {\n switch (codec) {\n case \"pcm-s16\":\n return \"ipcm\";\n case \"pcm-s16be\":\n return \"ipcm\";\n case \"pcm-s24\":\n return \"ipcm\";\n case \"pcm-s24be\":\n return \"ipcm\";\n case \"pcm-s32\":\n return \"ipcm\";\n case \"pcm-s32be\":\n return \"ipcm\";\n case \"pcm-f32\":\n return \"fpcm\";\n case \"pcm-f32be\":\n return \"fpcm\";\n case \"pcm-f64\":\n return \"fpcm\";\n case \"pcm-f64be\":\n return \"fpcm\";\n }\n }\n};\nvar audioCodecToConfigurationBox = (codec, isQuickTime) => {\n switch (codec) {\n case \"aac\":\n return esds;\n case \"mp3\":\n return esds;\n case \"opus\":\n return dOps;\n case \"vorbis\":\n return esds;\n case \"flac\":\n return dfLa;\n case \"ac3\":\n return dac3;\n case \"eac3\":\n return dec3;\n }\n if (isQuickTime) {\n switch (codec) {\n case \"pcm-s24\":\n return wave;\n case \"pcm-s24be\":\n return wave;\n case \"pcm-s32\":\n return wave;\n case \"pcm-s32be\":\n return wave;\n case \"pcm-f32\":\n return wave;\n case \"pcm-f32be\":\n return wave;\n case \"pcm-f64\":\n return wave;\n case \"pcm-f64be\":\n return wave;\n }\n } else {\n switch (codec) {\n case \"pcm-s16\":\n return pcmC;\n case \"pcm-s16be\":\n return pcmC;\n case \"pcm-s24\":\n return pcmC;\n case \"pcm-s24be\":\n return pcmC;\n case \"pcm-s32\":\n return pcmC;\n case \"pcm-s32be\":\n return pcmC;\n case \"pcm-f32\":\n return pcmC;\n case \"pcm-f32be\":\n return pcmC;\n case \"pcm-f64\":\n return pcmC;\n case \"pcm-f64be\":\n return pcmC;\n }\n }\n return null;\n};\nvar SUBTITLE_CODEC_TO_BOX_NAME = {\n webvtt: \"wvtt\"\n};\nvar SUBTITLE_CODEC_TO_CONFIGURATION_BOX = {\n webvtt: vttC\n};\nvar getLanguageCodeInt = (code) => {\n assert(code.length === 3);\n ;\n let language = 0;\n for (let i2 = 0; i2 < 3; i2++) {\n language <<= 5;\n language += code.charCodeAt(i2) - 96;\n }\n return language;\n};\n\n// node_modules/mediabunny/dist/modules/src/writer.js\nvar Writer = class {\n constructor(target, isMonotonic) {\n this.finalized = false;\n this.started = false;\n this.pos = 0;\n this.trackedWrites = null;\n this.trackedStart = -1;\n this.trackedEnd = -1;\n if (target._writerAcquired) {\n throw new Error(\"Can't have multiple Writers for the same Target.\");\n }\n this.target = target;\n target._setMonotonicity(isMonotonic);\n target._writerAcquired = true;\n }\n start() {\n assert(!this.started);\n this.target._start();\n this.started = true;\n }\n /** Writes the given data to the target, at the current position. */\n write(data) {\n assert(this.started && !this.finalized);\n this.maybeTrackWrites(data);\n this.target._write(data, this.pos);\n this.pos += data.byteLength;\n }\n /** Sets the current position for future writes to a new one. */\n seek(newPos) {\n this.pos = newPos;\n }\n /** Returns the current position. */\n getPos() {\n return this.pos;\n }\n /** Signals to the writer that it may be time to flush. */\n async flush() {\n assert(this.started && !this.finalized);\n return this.target._flush();\n }\n /** Called after muxing has finished. */\n async finalize() {\n assert(this.started && !this.finalized);\n await this.target._finalize();\n this.finalized = true;\n }\n maybeTrackWrites(data) {\n if (!this.trackedWrites) {\n return;\n }\n let pos = this.getPos();\n if (pos < this.trackedStart) {\n if (pos + data.byteLength <= this.trackedStart) {\n return;\n }\n data = data.subarray(this.trackedStart - pos);\n pos = 0;\n }\n const neededSize = pos + data.byteLength - this.trackedStart;\n let newLength = this.trackedWrites.byteLength;\n while (newLength < neededSize) {\n newLength *= 2;\n }\n if (newLength !== this.trackedWrites.byteLength) {\n const copy = new Uint8Array(newLength);\n copy.set(this.trackedWrites, 0);\n this.trackedWrites = copy;\n }\n this.trackedWrites.set(data, pos - this.trackedStart);\n this.trackedEnd = Math.max(this.trackedEnd, pos + data.byteLength);\n }\n startTrackingWrites() {\n this.trackedWrites = new Uint8Array(2 ** 10);\n this.trackedStart = this.getPos();\n this.trackedEnd = this.trackedStart;\n }\n stopTrackingWrites() {\n if (!this.trackedWrites) {\n throw new Error(\"Internal error: Can't get tracked writes since nothing was tracked.\");\n }\n const slice = this.trackedWrites.subarray(0, this.trackedEnd - this.trackedStart);\n const result = {\n data: slice,\n start: this.trackedStart,\n end: this.trackedEnd\n };\n this.trackedWrites = null;\n return result;\n }\n};\n\n// node_modules/mediabunny/dist/modules/src/target.js\nvar Target = class extends EventEmitter {\n constructor() {\n super(...arguments);\n this._writerAcquired = false;\n this._monotonicity = null;\n this.onwrite = null;\n }\n /** @internal */\n _setMonotonicity(monotonicity) {\n if (this._monotonicity !== false) {\n this._monotonicity = monotonicity;\n } else {\n }\n }\n /** @internal */\n _dispatchWrite(start, end) {\n this.onwrite?.(start, end);\n this._emit(\"write\", { start, end });\n }\n /**\n * Returns a new {@link RangedTarget} that writes data to this target using the given offset.\n *\n * Useful for writing a file into a section of a larger file.\n */\n slice(offset) {\n if (!Number.isInteger(offset) || offset < 0) {\n throw new TypeError(\"offset must be a non-negative integer.\");\n }\n return new RangedTarget(this, offset);\n }\n};\nvar ARRAY_BUFFER_INITIAL_SIZE = 2 ** 16;\nvar ARRAY_BUFFER_MAX_SIZE = 2 ** 32;\nvar BufferTarget = class extends Target {\n /** Creates a new {@link BufferTarget}. The buffer holding the data will be created and managed internally. */\n constructor(options = {}) {\n super();\n this.buffer = null;\n this._maxPos = 0;\n if (!options || typeof options !== \"object\") {\n throw new TypeError(\"BufferTarget options, when provided, must be an object.\");\n }\n if (options.onFinalize !== void 0 && typeof options.onFinalize !== \"function\") {\n throw new TypeError(\"options.onFinalize, when provided, must be a function.\");\n }\n this._options = options;\n this._supportsResize = \"resize\" in new ArrayBuffer(0);\n if (this._supportsResize) {\n try {\n this._buffer = new ArrayBuffer(ARRAY_BUFFER_INITIAL_SIZE, { maxByteLength: ARRAY_BUFFER_MAX_SIZE });\n } catch {\n this._buffer = new ArrayBuffer(ARRAY_BUFFER_INITIAL_SIZE);\n this._supportsResize = false;\n }\n } else {\n this._buffer = new ArrayBuffer(ARRAY_BUFFER_INITIAL_SIZE);\n }\n this._bytes = new Uint8Array(this._buffer);\n }\n /** @internal */\n _ensureSize(size) {\n let newLength = this._buffer.byteLength;\n while (newLength < size)\n newLength *= 2;\n if (newLength === this._buffer.byteLength)\n return;\n if (newLength > ARRAY_BUFFER_MAX_SIZE) {\n throw new Error(`ArrayBuffer exceeded maximum size of ${ARRAY_BUFFER_MAX_SIZE} bytes. Please consider using another target.`);\n }\n if (this._supportsResize) {\n this._buffer.resize(newLength);\n } else {\n const newBuffer = new ArrayBuffer(newLength);\n const newBytes = new Uint8Array(newBuffer);\n newBytes.set(this._bytes, 0);\n this._buffer = newBuffer;\n this._bytes = newBytes;\n }\n }\n /** @internal */\n _start() {\n }\n /** @internal */\n _write(data, pos) {\n this._ensureSize(pos + data.byteLength);\n this._bytes.set(data, pos);\n this._maxPos = Math.max(this._maxPos, pos + data.byteLength);\n this._dispatchWrite(pos, pos + data.byteLength);\n }\n /** @internal */\n async _flush() {\n }\n /** @internal */\n async _finalize() {\n this.buffer = this._buffer.slice(0, this._maxPos);\n if (this._options.onFinalize) {\n await this._options.onFinalize(this.buffer);\n }\n this._emit(\"finalized\");\n }\n /** @internal */\n async _close() {\n }\n /** @internal */\n _getSlice(start, end) {\n return this._bytes.slice(start, end);\n }\n};\nvar DEFAULT_CHUNK_SIZE = 2 ** 24;\nvar RangedTarget = class extends Target {\n /** @internal */\n constructor(baseTarget, offset) {\n super();\n this._baseTarget = baseTarget;\n this._offset = offset;\n }\n /** @internal */\n _start() {\n }\n /** @internal */\n _write(data, pos) {\n this._baseTarget._write(data, this._offset + pos);\n this._dispatchWrite(pos, pos + data.byteLength);\n }\n /** @internal */\n _flush() {\n return this._baseTarget._flush();\n }\n /** @internal */\n async _finalize() {\n this._emit(\"finalized\");\n }\n /** @internal */\n async _close() {\n }\n /** @internal */\n _setMonotonicity(monotonicity) {\n super._setMonotonicity(monotonicity);\n this._baseTarget._setMonotonicity(monotonicity);\n }\n};\nvar PathedTarget = class {\n /** Creates a new {@link PathedTarget} from a root path and a callback. */\n constructor(rootPath, getTarget) {\n this.rootPath = rootPath;\n this.getTarget = getTarget;\n if (typeof rootPath !== \"string\") {\n throw new TypeError(\"rootPath must be a string.\");\n }\n if (typeof getTarget !== \"function\") {\n throw new TypeError(\"getTarget must be a function.\");\n }\n }\n};\n\n// node_modules/mediabunny/dist/modules/src/isobmff/isobmff-muxer.js\nvar GLOBAL_TIMESCALE = 57600;\nvar TIMESTAMP_OFFSET = 2082844800;\nvar getTrackMetadata = (trackData) => {\n const metadata = {};\n const track = trackData.track;\n if (track.metadata.name !== void 0) {\n metadata.name = track.metadata.name;\n }\n return metadata;\n};\nvar intoTimescale = (timeInSeconds, timescale, round = true) => {\n const value = timeInSeconds * timescale;\n return round ? Math.round(value) : value;\n};\nvar IsobmffMuxer = class extends Muxer {\n constructor(output, format) {\n super(output);\n this.writer = null;\n this.boxWriter = null;\n this.initWriter = null;\n this.initBoxWriter = null;\n this.auxTarget = new BufferTarget();\n this.auxWriter = new Writer(this.auxTarget, false);\n this.auxBoxWriter = new IsobmffBoxWriter(this.auxWriter);\n this.mdat = null;\n this.ftypSize = null;\n this.trackDatas = [];\n this.allTracksKnown = promiseWithResolvers();\n this.creationTime = Math.floor(Date.now() / 1e3) + TIMESTAMP_OFFSET;\n this.finalizedChunks = [];\n this.nextFragmentNumber = 1;\n this.maxWrittenTimestamp = -Infinity;\n this.minWrittenTimestamp = Infinity;\n this.maxWrittenEndTimestamp = -Infinity;\n this.segmentHeaderSize = null;\n this.format = format;\n this.isQuickTime = format instanceof MovOutputFormat;\n this.isCmaf = format instanceof CmafOutputFormat;\n this.minimumFragmentDuration = format._options.minimumFragmentDuration ?? (format instanceof CmafOutputFormat ? Infinity : 1);\n }\n async start() {\n const release = await this.mutex.acquire();\n if (!this.isCmaf) {\n this.writer = await this.output._getRootWriter((target) => this.format._options.fastStart !== void 0 ? this.format._options.fastStart === \"fragmented\" : target instanceof BufferTarget);\n this.boxWriter = new IsobmffBoxWriter(this.writer);\n this.fastStart = this.format._options.fastStart ?? (this.writer.target instanceof BufferTarget ? \"in-memory\" : false);\n this.isFragmented = this.fastStart === \"fragmented\";\n } else {\n this.fastStart = \"fragmented\";\n this.isFragmented = true;\n }\n if (this.isCmaf) {\n if (!this.output._hasInitTarget()) {\n throw new Error(`CMAF outputs require the initTarget field in OutputOptions to be set; the init segment will be written to it.`);\n }\n const initTarget = await this.output._getInitTarget();\n const initWriter = new Writer(initTarget, true);\n initWriter.start();\n this.initWriter = initWriter;\n this.initBoxWriter = new IsobmffBoxWriter(initWriter);\n }\n const holdsAvc = this.output._tracks.some((x) => x.isVideoTrack() && x.source._codec === \"avc\");\n {\n const boxWriter = this.initBoxWriter ?? this.boxWriter;\n assert(boxWriter);\n if (this.format._options.onFtyp) {\n boxWriter.writer.startTrackingWrites();\n }\n boxWriter.writeBox(ftyp({\n isQuickTime: this.isQuickTime,\n holdsAvc,\n fragmented: this.isFragmented,\n cmaf: this.isCmaf\n }));\n if (this.format._options.onFtyp) {\n const { data, start } = boxWriter.writer.stopTrackingWrites();\n this.format._options.onFtyp(data, start);\n }\n this.ftypSize = boxWriter.writer.getPos();\n if (this.isCmaf) {\n await this.initWriter.flush();\n }\n }\n if (this.fastStart === \"in-memory\") {\n } else if (this.fastStart === \"reserve\") {\n for (const track of this.output._tracks) {\n if (track.metadata.maximumPacketCount === void 0) {\n throw new Error(\"All tracks must specify maximumPacketCount in their metadata when using fastStart: 'reserve'.\");\n }\n }\n } else if (this.isFragmented) {\n } else {\n assert(this.writer);\n assert(this.boxWriter);\n if (this.format._options.onMdat) {\n this.writer.startTrackingWrites();\n }\n this.mdat = mdat(true);\n this.boxWriter.writeBox(this.mdat);\n }\n await this.writer?.flush();\n release();\n }\n allTracksAreKnown() {\n for (const track of this.output._tracks) {\n if (!track.source._closed && !this.trackDatas.some((x) => x.track === track)) {\n return false;\n }\n }\n return true;\n }\n async getMimeType() {\n await this.allTracksKnown.promise;\n const codecStrings = this.trackDatas.map((trackData) => {\n if (trackData.type === \"video\") {\n return trackData.info.decoderConfig.codec;\n } else if (trackData.type === \"audio\") {\n return trackData.info.decoderConfig.codec;\n } else {\n const map = {\n webvtt: \"wvtt\"\n };\n return map[trackData.track.source._codec];\n }\n });\n return buildIsobmffMimeType({\n isQuickTime: this.isQuickTime,\n hasVideo: this.trackDatas.some((x) => x.type === \"video\"),\n hasAudio: this.trackDatas.some((x) => x.type === \"audio\"),\n codecStrings\n });\n }\n getVideoTrackData(track, packet, meta) {\n const existingTrackData = this.trackDatas.find((x) => x.track === track);\n if (existingTrackData) {\n return existingTrackData;\n }\n validateVideoChunkMetadata(meta);\n assert(meta);\n assert(meta.decoderConfig);\n const decoderConfig = { ...meta.decoderConfig };\n assert(decoderConfig.codedWidth !== void 0);\n assert(decoderConfig.codedHeight !== void 0);\n let requiresAnnexBTransformation = false;\n if (track.source._codec === \"avc\" && !decoderConfig.description) {\n const decoderConfigurationRecord = extractAvcDecoderConfigurationRecord(packet.data);\n if (!decoderConfigurationRecord) {\n 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.\");\n }\n decoderConfig.description = serializeAvcDecoderConfigurationRecord(decoderConfigurationRecord);\n requiresAnnexBTransformation = true;\n } else if (track.source._codec === \"hevc\" && !decoderConfig.description) {\n const decoderConfigurationRecord = extractHevcDecoderConfigurationRecord(packet.data);\n if (!decoderConfigurationRecord) {\n 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.\");\n }\n decoderConfig.description = serializeHevcDecoderConfigurationRecord(decoderConfigurationRecord);\n requiresAnnexBTransformation = true;\n }\n const timescale = computeRationalApproximation(1 / (track.metadata.frameRate ?? GLOBAL_TIMESCALE), 1e6).den;\n const displayAspectWidth = decoderConfig.displayAspectWidth;\n const displayAspectHeight = decoderConfig.displayAspectHeight;\n const pixelAspectRatio = displayAspectWidth === void 0 || displayAspectHeight === void 0 ? { num: 1, den: 1 } : simplifyRational({\n num: displayAspectWidth * decoderConfig.codedHeight,\n den: displayAspectHeight * decoderConfig.codedWidth\n });\n const newTrackData = {\n muxer: this,\n track,\n type: \"video\",\n info: {\n width: decoderConfig.codedWidth,\n height: decoderConfig.codedHeight,\n pixelAspectRatio,\n decoderConfig,\n requiresAnnexBTransformation\n },\n timescale,\n samples: [],\n sampleQueue: [],\n timestampProcessingQueue: [],\n timeToSampleTable: [],\n compositionTimeOffsetTable: [],\n lastTimescaleUnits: null,\n lastSample: null,\n startTimestampOffset: null,\n finalizedChunks: [],\n currentChunk: null,\n compactlyCodedChunkTable: [],\n closed: false\n };\n this.trackDatas.push(newTrackData);\n this.trackDatas.sort((a2, b) => a2.track.id - b.track.id);\n if (this.allTracksAreKnown()) {\n this.allTracksKnown.resolve();\n }\n return newTrackData;\n }\n getAudioTrackData(track, packet, meta) {\n const existingTrackData = this.trackDatas.find((x) => x.track === track);\n if (existingTrackData) {\n return existingTrackData;\n }\n validateAudioChunkMetadata(meta);\n assert(meta);\n assert(meta.decoderConfig);\n const decoderConfig = { ...meta.decoderConfig };\n let requiresAdtsStripping = false;\n if (track.source._codec === \"aac\" && !decoderConfig.description) {\n const adtsFrame = readAdtsFrameHeader(FileSlice.tempFromBytes(packet.data));\n if (!adtsFrame) {\n 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.\");\n }\n const sampleRate = aacFrequencyTable[adtsFrame.samplingFrequencyIndex];\n const numberOfChannels = aacChannelMap[adtsFrame.channelConfiguration];\n if (sampleRate === void 0 || numberOfChannels === void 0) {\n throw new Error(\"Invalid ADTS frame header.\");\n }\n decoderConfig.description = buildAacAudioSpecificConfig({\n objectType: adtsFrame.objectType,\n sampleRate,\n numberOfChannels\n });\n requiresAdtsStripping = true;\n }\n const newTrackData = {\n muxer: this,\n track,\n type: \"audio\",\n info: {\n numberOfChannels: meta.decoderConfig.numberOfChannels,\n sampleRate: meta.decoderConfig.sampleRate,\n decoderConfig,\n requiresPcmTransformation: !this.isFragmented && PCM_AUDIO_CODECS.includes(track.source._codec),\n expectedNextPcmPacketTimestamp: null,\n requiresAdtsStripping,\n firstPacket: packet\n },\n timescale: decoderConfig.sampleRate,\n samples: [],\n sampleQueue: [],\n timestampProcessingQueue: [],\n timeToSampleTable: [],\n compositionTimeOffsetTable: [],\n lastTimescaleUnits: null,\n lastSample: null,\n startTimestampOffset: null,\n finalizedChunks: [],\n currentChunk: null,\n compactlyCodedChunkTable: [],\n closed: false\n };\n this.trackDatas.push(newTrackData);\n this.trackDatas.sort((a2, b) => a2.track.id - b.track.id);\n if (this.allTracksAreKnown()) {\n this.allTracksKnown.resolve();\n }\n return newTrackData;\n }\n getSubtitleTrackData(track, meta) {\n const existingTrackData = this.trackDatas.find((x) => x.track === track);\n if (existingTrackData) {\n return existingTrackData;\n }\n validateSubtitleMetadata(meta);\n assert(meta);\n assert(meta.config);\n const newTrackData = {\n muxer: this,\n track,\n type: \"subtitle\",\n info: {\n config: meta.config\n },\n timescale: 1e3,\n // Reasonable\n samples: [],\n sampleQueue: [],\n timestampProcessingQueue: [],\n timeToSampleTable: [],\n compositionTimeOffsetTable: [],\n lastTimescaleUnits: null,\n lastSample: null,\n startTimestampOffset: null,\n finalizedChunks: [],\n currentChunk: null,\n compactlyCodedChunkTable: [],\n closed: false,\n lastCueEndTimestamp: 0,\n cueQueue: [],\n nextSourceId: 0,\n cueToSourceId: /* @__PURE__ */ new WeakMap()\n };\n this.trackDatas.push(newTrackData);\n this.trackDatas.sort((a2, b) => a2.track.id - b.track.id);\n if (this.allTracksAreKnown()) {\n this.allTracksKnown.resolve();\n }\n return newTrackData;\n }\n async addEncodedVideoPacket(track, packet, meta) {\n const release = await this.mutex.acquire();\n try {\n const trackData = this.getVideoTrackData(track, packet, meta);\n let packetData = packet.data;\n if (trackData.info.requiresAnnexBTransformation) {\n const nalUnits = [...iterateNalUnitsInAnnexB(packetData)].map((loc) => packetData.subarray(loc.offset, loc.offset + loc.length));\n if (nalUnits.length === 0) {\n 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.\");\n }\n packetData = concatNalUnitsInLengthPrefixed(nalUnits, 4);\n }\n this.validateTimestamp(trackData.track, packet.timestamp, packet.type === \"key\");\n const internalSample = this.createSampleForTrack(trackData, packetData, packet.timestamp, packet.duration, packet.type);\n await this.registerSample(trackData, internalSample);\n } finally {\n release();\n }\n }\n async addEncodedAudioPacket(track, packet, meta) {\n const release = await this.mutex.acquire();\n try {\n const trackData = this.getAudioTrackData(track, packet, meta);\n let packetData = packet.data;\n if (trackData.info.requiresAdtsStripping) {\n const adtsFrame = readAdtsFrameHeader(FileSlice.tempFromBytes(packetData));\n if (!adtsFrame) {\n throw new Error(\"Expected ADTS frame, didn't get one.\");\n }\n const headerLength = adtsFrame.crcCheck === null ? MIN_ADTS_FRAME_HEADER_SIZE : MAX_ADTS_FRAME_HEADER_SIZE;\n packetData = packetData.subarray(headerLength);\n }\n this.validateTimestamp(trackData.track, packet.timestamp, packet.type === \"key\");\n let timestamp = packet.timestamp;\n let duration = packet.duration;\n if (trackData.info.requiresPcmTransformation) {\n const pcmInfo = parsePcmCodec(trackData.info.decoderConfig.codec);\n const frameSize = pcmInfo.sampleSize * trackData.info.numberOfChannels;\n duration = packetData.byteLength / frameSize / trackData.info.sampleRate;\n if (trackData.info.expectedNextPcmPacketTimestamp !== null) {\n const diff = timestamp - trackData.info.expectedNextPcmPacketTimestamp;\n if (diff < 0.01) {\n timestamp = trackData.info.expectedNextPcmPacketTimestamp;\n } else {\n const paddedDuration = await this.padWithSilence(trackData, trackData.info.expectedNextPcmPacketTimestamp, diff);\n timestamp = trackData.info.expectedNextPcmPacketTimestamp + paddedDuration;\n }\n }\n trackData.info.expectedNextPcmPacketTimestamp = timestamp + duration;\n }\n const internalSample = this.createSampleForTrack(trackData, packetData, timestamp, duration, packet.type);\n await this.registerSample(trackData, internalSample);\n } finally {\n release();\n }\n }\n async padWithSilence(trackData, timestamp, duration) {\n const deltaInTimescale = intoTimescale(duration, trackData.timescale);\n duration = deltaInTimescale / trackData.timescale;\n if (deltaInTimescale > 0) {\n const { sampleSize, silentValue } = parsePcmCodec(trackData.info.decoderConfig.codec);\n const samplesNeeded = deltaInTimescale * trackData.info.numberOfChannels;\n const data = new Uint8Array(sampleSize * samplesNeeded).fill(silentValue);\n const paddingSample = this.createSampleForTrack(trackData, new Uint8Array(data.buffer), timestamp, duration, \"key\");\n await this.registerSample(trackData, paddingSample);\n }\n return duration;\n }\n async addSubtitleCue(track, cue, meta) {\n const release = await this.mutex.acquire();\n try {\n const trackData = this.getSubtitleTrackData(track, meta);\n this.validateTimestamp(trackData.track, cue.timestamp, true);\n if (track.source._codec === \"webvtt\") {\n trackData.cueQueue.push(cue);\n await this.processWebVTTCues(trackData, cue.timestamp);\n } else {\n }\n } finally {\n release();\n }\n }\n async processWebVTTCues(trackData, until) {\n while (trackData.cueQueue.length > 0) {\n const timestamps = /* @__PURE__ */ new Set([]);\n for (const cue of trackData.cueQueue) {\n assert(cue.timestamp <= until);\n assert(trackData.lastCueEndTimestamp <= cue.timestamp + cue.duration);\n timestamps.add(Math.max(cue.timestamp, trackData.lastCueEndTimestamp));\n timestamps.add(cue.timestamp + cue.duration);\n }\n const sortedTimestamps = [...timestamps].sort((a2, b) => a2 - b);\n const sampleStart = sortedTimestamps[0];\n const sampleEnd = sortedTimestamps[1] ?? sampleStart;\n if (until < sampleEnd) {\n break;\n }\n if (trackData.lastCueEndTimestamp < sampleStart) {\n this.auxWriter.seek(0);\n const box2 = vtte();\n this.auxBoxWriter.writeBox(box2);\n const body2 = this.auxTarget._getSlice(0, this.auxWriter.getPos());\n const sample2 = this.createSampleForTrack(trackData, body2, trackData.lastCueEndTimestamp, sampleStart - trackData.lastCueEndTimestamp, \"key\");\n await this.registerSample(trackData, sample2);\n trackData.lastCueEndTimestamp = sampleStart;\n }\n this.auxWriter.seek(0);\n for (let i2 = 0; i2 < trackData.cueQueue.length; i2++) {\n const cue = trackData.cueQueue[i2];\n if (cue.timestamp >= sampleEnd) {\n break;\n }\n inlineTimestampRegex.lastIndex = 0;\n const containsTimestamp = inlineTimestampRegex.test(cue.text);\n const endTimestamp = cue.timestamp + cue.duration;\n let sourceId = trackData.cueToSourceId.get(cue);\n if (sourceId === void 0 && sampleEnd < endTimestamp) {\n sourceId = trackData.nextSourceId++;\n trackData.cueToSourceId.set(cue, sourceId);\n }\n if (cue.notes) {\n const box3 = vtta(cue.notes);\n this.auxBoxWriter.writeBox(box3);\n }\n const box2 = vttc(cue.text, containsTimestamp ? sampleStart : null, cue.identifier ?? null, cue.settings ?? null, sourceId ?? null);\n this.auxBoxWriter.writeBox(box2);\n if (endTimestamp === sampleEnd) {\n trackData.cueQueue.splice(i2--, 1);\n }\n }\n const body = this.auxTarget._getSlice(0, this.auxWriter.getPos());\n const sample = this.createSampleForTrack(trackData, body, sampleStart, sampleEnd - sampleStart, \"key\");\n await this.registerSample(trackData, sample);\n trackData.lastCueEndTimestamp = sampleEnd;\n }\n }\n createSampleForTrack(trackData, data, timestamp, duration, type) {\n const sample = {\n timestamp,\n decodeTimestamp: timestamp,\n // This may be refined later\n duration,\n data,\n size: data.byteLength,\n type,\n timescaleUnitsToNextSample: intoTimescale(duration, trackData.timescale)\n // Will be refined\n };\n return sample;\n }\n processTimestamps(trackData, nextSample) {\n if (trackData.timestampProcessingQueue.length === 0) {\n return;\n }\n if (trackData.type === \"audio\" && trackData.info.requiresPcmTransformation) {\n if (!this.isFragmented) {\n trackData.startTimestampOffset ??= trackData.timestampProcessingQueue[0].timestamp;\n }\n let totalDuration = 0;\n for (let i2 = 0; i2 < trackData.timestampProcessingQueue.length; i2++) {\n const sample = trackData.timestampProcessingQueue[i2];\n const duration = intoTimescale(sample.duration, trackData.timescale);\n totalDuration += duration;\n }\n if (trackData.timeToSampleTable.length === 0) {\n trackData.timeToSampleTable.push({\n sampleCount: totalDuration,\n sampleDelta: 1\n });\n } else {\n const lastEntry = last(trackData.timeToSampleTable);\n lastEntry.sampleCount += totalDuration;\n }\n trackData.timestampProcessingQueue.length = 0;\n return;\n }\n const sortedTimestamps = trackData.timestampProcessingQueue.map((x) => x.timestamp).sort((a2, b) => a2 - b);\n if (!this.isFragmented) {\n trackData.startTimestampOffset ??= sortedTimestamps[0];\n }\n for (let i2 = 0; i2 < trackData.timestampProcessingQueue.length; i2++) {\n const sample = trackData.timestampProcessingQueue[i2];\n sample.decodeTimestamp = sortedTimestamps[i2];\n const sampleCompositionTimeOffset = intoTimescale(sample.timestamp - sample.decodeTimestamp, trackData.timescale);\n const durationInTimescale = intoTimescale(sample.duration, trackData.timescale);\n if (trackData.lastTimescaleUnits !== null) {\n assert(trackData.lastSample);\n const timescaleUnits = intoTimescale(sample.decodeTimestamp, trackData.timescale, false);\n const delta = Math.round(timescaleUnits - trackData.lastTimescaleUnits);\n assert(delta >= 0);\n trackData.lastTimescaleUnits += delta;\n trackData.lastSample.timescaleUnitsToNextSample = delta;\n if (!this.isFragmented) {\n let lastTableEntry = last(trackData.timeToSampleTable);\n assert(lastTableEntry);\n if (lastTableEntry.sampleCount === 1) {\n lastTableEntry.sampleDelta = delta;\n const entryBefore = trackData.timeToSampleTable[trackData.timeToSampleTable.length - 2];\n if (entryBefore && entryBefore.sampleDelta === delta) {\n entryBefore.sampleCount++;\n trackData.timeToSampleTable.pop();\n lastTableEntry = entryBefore;\n }\n } else if (lastTableEntry.sampleDelta !== delta) {\n lastTableEntry.sampleCount--;\n trackData.timeToSampleTable.push(lastTableEntry = {\n sampleCount: 1,\n sampleDelta: delta\n });\n }\n if (lastTableEntry.sampleDelta === durationInTimescale) {\n lastTableEntry.sampleCount++;\n } else {\n trackData.timeToSampleTable.push({\n sampleCount: 1,\n sampleDelta: durationInTimescale\n });\n }\n const lastCompositionTimeOffsetTableEntry = last(trackData.compositionTimeOffsetTable);\n assert(lastCompositionTimeOffsetTableEntry);\n if (lastCompositionTimeOffsetTableEntry.sampleCompositionTimeOffset === sampleCompositionTimeOffset) {\n lastCompositionTimeOffsetTableEntry.sampleCount++;\n } else {\n trackData.compositionTimeOffsetTable.push({\n sampleCount: 1,\n sampleCompositionTimeOffset\n });\n }\n }\n } else {\n trackData.lastTimescaleUnits = intoTimescale(sample.decodeTimestamp, trackData.timescale, false);\n if (!this.isFragmented) {\n trackData.timeToSampleTable.push({\n sampleCount: 1,\n sampleDelta: durationInTimescale\n });\n trackData.compositionTimeOffsetTable.push({\n sampleCount: 1,\n sampleCompositionTimeOffset\n });\n }\n }\n trackData.lastSample = sample;\n }\n trackData.timestampProcessingQueue.length = 0;\n assert(trackData.lastSample);\n assert(trackData.lastTimescaleUnits !== null);\n if (nextSample !== void 0 && trackData.lastSample.timescaleUnitsToNextSample === 0) {\n assert(nextSample.type === \"key\");\n const timescaleUnits = intoTimescale(nextSample.timestamp, trackData.timescale, false);\n const delta = Math.round(timescaleUnits - trackData.lastTimescaleUnits);\n trackData.lastSample.timescaleUnitsToNextSample = delta;\n }\n }\n async registerSample(trackData, sample) {\n if (sample.type === \"key\") {\n this.processTimestamps(trackData, sample);\n }\n trackData.timestampProcessingQueue.push(sample);\n if (this.isFragmented) {\n trackData.sampleQueue.push(sample);\n await this.interleaveSamples();\n } else if (this.fastStart === \"reserve\") {\n await this.registerSampleFastStartReserve(trackData, sample);\n } else {\n await this.addSampleToTrack(trackData, sample);\n }\n }\n async addSampleToTrack(trackData, sample) {\n if (!this.isFragmented) {\n trackData.samples.push(sample);\n if (this.fastStart === \"reserve\") {\n const maximumPacketCount = trackData.track.metadata.maximumPacketCount;\n assert(maximumPacketCount !== void 0);\n if (trackData.samples.length > maximumPacketCount) {\n 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.`);\n }\n }\n }\n let beginNewChunk = false;\n if (!trackData.currentChunk) {\n beginNewChunk = true;\n } else {\n trackData.currentChunk.startTimestamp = Math.min(trackData.currentChunk.startTimestamp, sample.timestamp);\n const currentChunkDuration = sample.timestamp - trackData.currentChunk.startTimestamp;\n if (this.isFragmented) {\n const keyFrameQueuedEverywhere = this.trackDatas.every((otherTrackData) => {\n if (trackData === otherTrackData) {\n return sample.type === \"key\";\n }\n const firstQueuedSample = otherTrackData.sampleQueue[0];\n if (firstQueuedSample) {\n return firstQueuedSample.type === \"key\";\n }\n return otherTrackData.closed;\n });\n if (currentChunkDuration >= this.minimumFragmentDuration && keyFrameQueuedEverywhere && sample.timestamp > this.maxWrittenTimestamp) {\n beginNewChunk = true;\n await this.finalizeFragment();\n }\n } else {\n beginNewChunk = currentChunkDuration >= 0.5;\n }\n }\n if (beginNewChunk) {\n if (trackData.currentChunk) {\n await this.finalizeCurrentChunk(trackData);\n }\n trackData.currentChunk = {\n startTimestamp: sample.timestamp,\n samples: [],\n offset: null,\n moofOffset: null\n };\n }\n assert(trackData.currentChunk);\n trackData.currentChunk.samples.push(sample);\n if (this.isFragmented) {\n this.maxWrittenTimestamp = Math.max(this.maxWrittenTimestamp, sample.timestamp);\n this.maxWrittenEndTimestamp = Math.max(this.maxWrittenEndTimestamp, sample.timestamp + sample.duration);\n this.minWrittenTimestamp = Math.min(this.minWrittenTimestamp, sample.timestamp);\n }\n }\n async finalizeCurrentChunk(trackData) {\n assert(!this.isFragmented);\n assert(this.writer);\n if (!trackData.currentChunk)\n return;\n trackData.finalizedChunks.push(trackData.currentChunk);\n this.finalizedChunks.push(trackData.currentChunk);\n let sampleCount = trackData.currentChunk.samples.length;\n if (trackData.type === \"audio\" && trackData.info.requiresPcmTransformation) {\n sampleCount = trackData.currentChunk.samples.reduce((acc, sample) => acc + intoTimescale(sample.duration, trackData.timescale), 0);\n }\n if (trackData.compactlyCodedChunkTable.length === 0 || last(trackData.compactlyCodedChunkTable).samplesPerChunk !== sampleCount) {\n trackData.compactlyCodedChunkTable.push({\n firstChunk: trackData.finalizedChunks.length,\n // 1-indexed\n samplesPerChunk: sampleCount\n });\n }\n if (this.fastStart === \"in-memory\") {\n trackData.currentChunk.offset = 0;\n return;\n }\n trackData.currentChunk.offset = this.writer.getPos();\n for (const sample of trackData.currentChunk.samples) {\n assert(sample.data);\n this.writer.write(sample.data);\n sample.data = null;\n }\n await this.writer.flush();\n }\n async interleaveSamples(isFinalCall = false) {\n assert(this.isFragmented);\n if (!isFinalCall && !this.allTracksAreKnown()) {\n return;\n }\n outer: while (true) {\n let trackWithMinTimestamp = null;\n let minTimestamp = Infinity;\n for (const trackData of this.trackDatas) {\n if (!isFinalCall && trackData.sampleQueue.length === 0 && !trackData.closed) {\n break outer;\n }\n if (trackData.sampleQueue.length > 0 && trackData.sampleQueue[0].timestamp < minTimestamp) {\n trackWithMinTimestamp = trackData;\n minTimestamp = trackData.sampleQueue[0].timestamp;\n }\n }\n if (!trackWithMinTimestamp) {\n break;\n }\n const sample = trackWithMinTimestamp.sampleQueue.shift();\n await this.addSampleToTrack(trackWithMinTimestamp, sample);\n }\n }\n async finalizeFragment(flushWriter = !this.isCmaf) {\n assert(this.isFragmented);\n const fragmentNumber = this.nextFragmentNumber++;\n if (fragmentNumber === 1) {\n const boxWriter = this.initBoxWriter ?? this.boxWriter;\n assert(boxWriter);\n if (this.format._options.onMoov) {\n boxWriter.writer.startTrackingWrites();\n }\n this.ensureOneEnabledTrack();\n const movieBox = moov(this);\n boxWriter.writeBox(movieBox);\n if (this.format._options.onMoov) {\n const { data, start } = boxWriter.writer.stopTrackingWrites();\n this.format._options.onMoov(data, start);\n }\n if (this.isCmaf) {\n assert(this.initWriter);\n await this.initWriter.flush();\n await this.initWriter.finalize();\n this.writer = await this.output._getRootWriter(true);\n this.boxWriter = new IsobmffBoxWriter(this.writer);\n const stypSize = this.boxWriter.measureBox(styp());\n const sidxSize = this.boxWriter.measureBox(sidx(this, 0));\n this.segmentHeaderSize = stypSize + sidxSize;\n this.writer.seek(this.segmentHeaderSize);\n }\n }\n assert(this.writer);\n assert(this.boxWriter);\n const tracksInFragment = this.trackDatas.filter((x) => x.currentChunk);\n const moofBox = moof(fragmentNumber, tracksInFragment);\n const moofOffset = this.writer.getPos();\n const mdatStartPos = moofOffset + this.boxWriter.measureBox(moofBox);\n let currentPos = mdatStartPos + MIN_BOX_HEADER_SIZE;\n let fragmentStartTimestamp = Infinity;\n for (const trackData of tracksInFragment) {\n trackData.currentChunk.offset = currentPos;\n trackData.currentChunk.moofOffset = moofOffset;\n for (const sample of trackData.currentChunk.samples) {\n currentPos += sample.size;\n }\n fragmentStartTimestamp = Math.min(fragmentStartTimestamp, trackData.currentChunk.startTimestamp);\n }\n const mdatSize = currentPos - mdatStartPos;\n const needsLargeMdatSize = mdatSize >= 2 ** 32;\n if (needsLargeMdatSize) {\n for (const trackData of tracksInFragment) {\n trackData.currentChunk.offset += MAX_BOX_HEADER_SIZE - MIN_BOX_HEADER_SIZE;\n }\n }\n if (this.format._options.onMoof) {\n this.writer.startTrackingWrites();\n }\n const newMoofBox = moof(fragmentNumber, tracksInFragment);\n this.boxWriter.writeBox(newMoofBox);\n if (this.format._options.onMoof) {\n const { data, start } = this.writer.stopTrackingWrites();\n this.format._options.onMoof(data, start, fragmentStartTimestamp);\n }\n assert(this.writer.getPos() === mdatStartPos);\n if (this.format._options.onMdat) {\n this.writer.startTrackingWrites();\n }\n const mdatBox = mdat(needsLargeMdatSize);\n mdatBox.size = mdatSize;\n this.boxWriter.writeBox(mdatBox);\n this.writer.seek(mdatStartPos + (needsLargeMdatSize ? MAX_BOX_HEADER_SIZE : MIN_BOX_HEADER_SIZE));\n for (const trackData of tracksInFragment) {\n for (const sample of trackData.currentChunk.samples) {\n this.writer.write(sample.data);\n sample.data = null;\n }\n }\n if (this.format._options.onMdat) {\n const { data, start } = this.writer.stopTrackingWrites();\n this.format._options.onMdat(data, start);\n }\n for (const trackData of tracksInFragment) {\n trackData.finalizedChunks.push(trackData.currentChunk);\n this.finalizedChunks.push(trackData.currentChunk);\n trackData.currentChunk = null;\n }\n if (flushWriter) {\n await this.writer.flush();\n }\n }\n async registerSampleFastStartReserve(trackData, sample) {\n assert(this.writer);\n assert(this.boxWriter);\n if (this.allTracksAreKnown()) {\n if (!this.mdat) {\n this.ensureOneEnabledTrack();\n const moovBox = moov(this);\n const moovSize = this.boxWriter.measureBox(moovBox);\n const reservedSize = moovSize + this.computeSampleTableSizeUpperBound() + 4096;\n assert(this.ftypSize !== null);\n this.writer.seek(this.ftypSize + reservedSize);\n if (this.format._options.onMdat) {\n this.writer.startTrackingWrites();\n }\n this.mdat = mdat(true);\n this.boxWriter.writeBox(this.mdat);\n for (const trackData2 of this.trackDatas) {\n for (const sample2 of trackData2.sampleQueue) {\n await this.addSampleToTrack(trackData2, sample2);\n }\n trackData2.sampleQueue.length = 0;\n }\n }\n await this.addSampleToTrack(trackData, sample);\n } else {\n trackData.sampleQueue.push(sample);\n }\n }\n computeSampleTableSizeUpperBound() {\n assert(this.fastStart === \"reserve\");\n let upperBound = 0;\n for (const trackData of this.trackDatas) {\n const n2 = trackData.track.metadata.maximumPacketCount;\n assert(n2 !== void 0);\n upperBound += (4 + 4) * Math.ceil(2 / 3 * n2);\n upperBound += 4 * n2;\n upperBound += (4 + 4) * Math.ceil(2 / 3 * n2);\n upperBound += (4 + 4 + 4) * Math.ceil(2 / 3 * n2);\n upperBound += 4 * n2;\n upperBound += 8 * n2;\n }\n return upperBound;\n }\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async onTrackClose(track) {\n const release = await this.mutex.acquire();\n const trackData = this.trackDatas.find((x) => x.track === track);\n if (trackData) {\n trackData.closed = true;\n if (trackData.type === \"subtitle\" && track.source._codec === \"webvtt\") {\n await this.processWebVTTCues(trackData, Infinity);\n }\n this.processTimestamps(trackData);\n }\n if (this.allTracksAreKnown()) {\n this.allTracksKnown.resolve();\n }\n if (this.isFragmented) {\n await this.interleaveSamples();\n }\n release();\n }\n ensureOneEnabledTrack() {\n for (const type of [\"video\", \"audio\", \"subtitle\"]) {\n const tracks = this.trackDatas.filter((t2) => t2.type === type);\n if (tracks.length === 0) {\n continue;\n }\n const hasEnabled = tracks.some((t2) => t2.track.metadata.disposition?.default !== false);\n if (!hasEnabled) {\n const firstTrack = tracks[0];\n firstTrack.track.metadata.disposition = {\n ...firstTrack.track.metadata.disposition,\n default: true\n };\n }\n }\n }\n /** Finalizes the file, making it ready for use. Must be called after all video and audio chunks have been added. */\n async finalize() {\n const release = await this.mutex.acquire();\n this.allTracksKnown.resolve();\n this.ensureOneEnabledTrack();\n for (const trackData of this.trackDatas) {\n trackData.closed = true;\n if (trackData.type === \"subtitle\" && trackData.track.source._codec === \"webvtt\") {\n await this.processWebVTTCues(trackData, Infinity);\n }\n this.processTimestamps(trackData);\n }\n if (this.isFragmented) {\n await this.interleaveSamples(true);\n await this.finalizeFragment(false);\n } else {\n for (const trackData of this.trackDatas) {\n await this.finalizeCurrentChunk(trackData);\n assert(trackData.startTimestampOffset !== null);\n for (let i2 = 0; i2 < trackData.samples.length; i2++) {\n const sample = trackData.samples[i2];\n sample.timestamp -= trackData.startTimestampOffset;\n sample.decodeTimestamp -= trackData.startTimestampOffset;\n }\n }\n }\n assert(this.writer);\n assert(this.boxWriter);\n if (this.fastStart === \"in-memory\") {\n this.mdat = mdat(false);\n let mdatSize;\n for (let i2 = 0; i2 < 2; i2++) {\n const movieBox2 = moov(this);\n const movieBoxSize = this.boxWriter.measureBox(movieBox2);\n mdatSize = this.boxWriter.measureBox(this.mdat);\n let currentChunkPos = this.writer.getPos() + movieBoxSize + mdatSize;\n for (const chunk of this.finalizedChunks) {\n chunk.offset = currentChunkPos;\n for (const { data } of chunk.samples) {\n assert(data);\n currentChunkPos += data.byteLength;\n mdatSize += data.byteLength;\n }\n }\n if (currentChunkPos < 2 ** 32)\n break;\n if (mdatSize >= 2 ** 32)\n this.mdat.largeSize = true;\n }\n if (this.format._options.onMoov) {\n this.writer.startTrackingWrites();\n }\n const movieBox = moov(this);\n this.boxWriter.writeBox(movieBox);\n if (this.format._options.onMoov) {\n const { data, start } = this.writer.stopTrackingWrites();\n this.format._options.onMoov(data, start);\n }\n if (this.format._options.onMdat) {\n this.writer.startTrackingWrites();\n }\n this.mdat.size = mdatSize;\n this.boxWriter.writeBox(this.mdat);\n for (const chunk of this.finalizedChunks) {\n for (const sample of chunk.samples) {\n assert(sample.data);\n this.writer.write(sample.data);\n sample.data = null;\n }\n }\n if (this.format._options.onMdat) {\n const { data, start } = this.writer.stopTrackingWrites();\n this.format._options.onMdat(data, start);\n }\n } else if (this.isFragmented) {\n if (this.isCmaf) {\n const contentSize = this.segmentHeaderSize !== null ? this.writer.getPos() - this.segmentHeaderSize : 0;\n this.writer.seek(0);\n this.boxWriter.writeBox(styp());\n this.boxWriter.writeBox(sidx(this, contentSize));\n } else {\n const startPos = this.writer.getPos();\n const mfraBox = mfra(this.trackDatas);\n this.boxWriter.writeBox(mfraBox);\n const mfraBoxSize = this.writer.getPos() - startPos;\n this.writer.seek(this.writer.getPos() - 4);\n this.boxWriter.writeU32(mfraBoxSize);\n }\n } else {\n assert(this.mdat);\n const mdatPos = this.boxWriter.offsets.get(this.mdat);\n assert(mdatPos !== void 0);\n const mdatSize = this.writer.getPos() - mdatPos;\n this.mdat.size = mdatSize;\n this.mdat.largeSize = mdatSize >= 2 ** 32;\n this.boxWriter.patchBox(this.mdat);\n if (this.format._options.onMdat) {\n const { data, start } = this.writer.stopTrackingWrites();\n this.format._options.onMdat(data, start);\n }\n const movieBox = moov(this);\n if (this.fastStart === \"reserve\") {\n assert(this.ftypSize !== null);\n this.writer.seek(this.ftypSize);\n if (this.format._options.onMoov) {\n this.writer.startTrackingWrites();\n }\n this.boxWriter.writeBox(movieBox);\n const remainingSpace = this.boxWriter.offsets.get(this.mdat) - this.writer.getPos();\n this.boxWriter.writeBox(free(remainingSpace));\n } else {\n if (this.format._options.onMoov) {\n this.writer.startTrackingWrites();\n }\n this.boxWriter.writeBox(movieBox);\n }\n if (this.format._options.onMoov) {\n const { data, start } = this.writer.stopTrackingWrites();\n this.format._options.onMoov(data, start);\n }\n }\n release();\n }\n};\n\n// node_modules/mediabunny/dist/modules/src/matroska/matroska-muxer.js\nvar MIN_CLUSTER_TIMESTAMP_MS = -(2 ** 15);\nvar MAX_CLUSTER_TIMESTAMP_MS = 2 ** 15 - 1;\nvar APP_NAME = \"Mediabunny\";\nvar SEGMENT_SIZE_BYTES = 6;\nvar CLUSTER_SIZE_BYTES = 5;\nvar TRACK_TYPE_MAP = {\n video: 1,\n audio: 2,\n subtitle: 17\n};\nvar MatroskaMuxer = class extends Muxer {\n constructor(output, format) {\n super(output);\n this.trackDatas = [];\n this.allTracksKnown = promiseWithResolvers();\n this.segment = null;\n this.segmentInfo = null;\n this.seekHead = null;\n this.tracksElement = null;\n this.tagsElement = null;\n this.attachmentsElement = null;\n this.segmentDuration = null;\n this.cues = null;\n this.currentCluster = null;\n this.currentClusterStartMsTimestamp = null;\n this.currentClusterMaxMsTimestamp = null;\n this.trackDatasInCurrentCluster = /* @__PURE__ */ new Map();\n this.startTimestamp = Infinity;\n this.endTimestamp = -Infinity;\n this.format = format;\n }\n async start() {\n const release = await this.mutex.acquire();\n this.writer = await this.output._getRootWriter(!!this.format._options.appendOnly);\n this.ebmlWriter = new EBMLWriter(this.writer);\n this.writeEBMLHeader();\n this.createSegmentInfo();\n this.createCues();\n await this.writer.flush();\n release();\n }\n writeEBMLHeader() {\n if (this.format._options.onEbmlHeader) {\n this.writer.startTrackingWrites();\n }\n const ebmlHeader = { id: EBMLId.EBML, data: [\n { id: EBMLId.EBMLVersion, data: 1 },\n { id: EBMLId.EBMLReadVersion, data: 1 },\n { id: EBMLId.EBMLMaxIDLength, data: 4 },\n { id: EBMLId.EBMLMaxSizeLength, data: 8 },\n { id: EBMLId.DocType, data: this.format instanceof WebMOutputFormat ? \"webm\" : \"matroska\" },\n { id: EBMLId.DocTypeVersion, data: 2 },\n { id: EBMLId.DocTypeReadVersion, data: 2 }\n ] };\n this.ebmlWriter.writeEBML(ebmlHeader);\n if (this.format._options.onEbmlHeader) {\n const { data, start } = this.writer.stopTrackingWrites();\n this.format._options.onEbmlHeader(data, start);\n }\n }\n /**\n * Creates a SeekHead element which is positioned near the start of the file and allows the media player to seek to\n * relevant sections more easily. Since we don't know the positions of those sections yet, we'll set them later.\n */\n maybeCreateSeekHead(writeOffsets) {\n if (this.format._options.appendOnly) {\n return;\n }\n const kaxCues = new Uint8Array([28, 83, 187, 107]);\n const kaxInfo = new Uint8Array([21, 73, 169, 102]);\n const kaxTracks = new Uint8Array([22, 84, 174, 107]);\n const kaxAttachments = new Uint8Array([25, 65, 164, 105]);\n const kaxTags = new Uint8Array([18, 84, 195, 103]);\n const seekHead = { id: EBMLId.SeekHead, data: [\n { id: EBMLId.Seek, data: [\n { id: EBMLId.SeekID, data: kaxCues },\n {\n id: EBMLId.SeekPosition,\n size: 5,\n data: writeOffsets ? this.ebmlWriter.offsets.get(this.cues) - this.segmentDataOffset : 0\n }\n ] },\n { id: EBMLId.Seek, data: [\n { id: EBMLId.SeekID, data: kaxInfo },\n {\n id: EBMLId.SeekPosition,\n size: 5,\n data: writeOffsets ? this.ebmlWriter.offsets.get(this.segmentInfo) - this.segmentDataOffset : 0\n }\n ] },\n { id: EBMLId.Seek, data: [\n { id: EBMLId.SeekID, data: kaxTracks },\n {\n id: EBMLId.SeekPosition,\n size: 5,\n data: writeOffsets ? this.ebmlWriter.offsets.get(this.tracksElement) - this.segmentDataOffset : 0\n }\n ] },\n this.attachmentsElement ? { id: EBMLId.Seek, data: [\n { id: EBMLId.SeekID, data: kaxAttachments },\n {\n id: EBMLId.SeekPosition,\n size: 5,\n data: writeOffsets ? this.ebmlWriter.offsets.get(this.attachmentsElement) - this.segmentDataOffset : 0\n }\n ] } : null,\n this.tagsElement ? { id: EBMLId.Seek, data: [\n { id: EBMLId.SeekID, data: kaxTags },\n {\n id: EBMLId.SeekPosition,\n size: 5,\n data: writeOffsets ? this.ebmlWriter.offsets.get(this.tagsElement) - this.segmentDataOffset : 0\n }\n ] } : null\n ] };\n this.seekHead = seekHead;\n }\n createSegmentInfo() {\n const segmentDuration = { id: EBMLId.Duration, data: new EBMLFloat64(0) };\n this.segmentDuration = segmentDuration;\n const segmentInfo = { id: EBMLId.Info, data: [\n { id: EBMLId.TimestampScale, data: 1e6 },\n { id: EBMLId.MuxingApp, data: APP_NAME },\n { id: EBMLId.WritingApp, data: APP_NAME },\n !this.format._options.appendOnly ? segmentDuration : null\n ] };\n this.segmentInfo = segmentInfo;\n }\n createTracks() {\n const tracksElement = { id: EBMLId.Tracks, data: [] };\n this.tracksElement = tracksElement;\n for (const trackData of this.trackDatas) {\n const codecId = CODEC_STRING_MAP[trackData.track.source._codec];\n assert(codecId);\n let seekPreRollNs = 0;\n if (trackData.type === \"audio\" && trackData.track.source._codec === \"opus\") {\n seekPreRollNs = 1e6 * 80;\n const description = trackData.info.decoderConfig.description;\n if (description) {\n const bytes2 = toUint8Array(description);\n const header = parseOpusIdentificationHeader(bytes2);\n seekPreRollNs = Math.round(1e9 * (header.preSkip / OPUS_SAMPLE_RATE));\n }\n }\n tracksElement.data.push({ id: EBMLId.TrackEntry, data: [\n { id: EBMLId.TrackNumber, data: trackData.track.id },\n { id: EBMLId.TrackUID, data: trackData.track.id },\n { id: EBMLId.TrackType, data: TRACK_TYPE_MAP[trackData.type] },\n trackData.track.metadata.disposition?.default === false ? { id: EBMLId.FlagDefault, data: 0 } : null,\n trackData.track.metadata.disposition?.forced ? { id: EBMLId.FlagForced, data: 1 } : null,\n trackData.track.metadata.disposition?.hearingImpaired ? { id: EBMLId.FlagHearingImpaired, data: 1 } : null,\n trackData.track.metadata.disposition?.visuallyImpaired ? { id: EBMLId.FlagVisualImpaired, data: 1 } : null,\n trackData.track.metadata.disposition?.original ? { id: EBMLId.FlagOriginal, data: 1 } : null,\n trackData.track.metadata.disposition?.commentary ? { id: EBMLId.FlagCommentary, data: 1 } : null,\n { id: EBMLId.FlagLacing, data: 0 },\n { id: EBMLId.Language, data: trackData.track.metadata.languageCode ?? UNDETERMINED_LANGUAGE },\n { id: EBMLId.CodecID, data: codecId },\n { id: EBMLId.CodecDelay, data: 0 },\n { id: EBMLId.SeekPreRoll, data: seekPreRollNs },\n trackData.track.metadata.name !== void 0 ? { id: EBMLId.Name, data: new EBMLUnicodeString(trackData.track.metadata.name) } : null,\n trackData.type === \"video\" ? this.videoSpecificTrackInfo(trackData) : null,\n trackData.type === \"audio\" ? this.audioSpecificTrackInfo(trackData) : null,\n trackData.type === \"subtitle\" ? this.subtitleSpecificTrackInfo(trackData) : null\n ] });\n }\n }\n videoSpecificTrackInfo(trackData) {\n const { frameRate, rotation } = trackData.track.metadata;\n const elements = [\n trackData.info.decoderConfig.description ? {\n id: EBMLId.CodecPrivate,\n data: toUint8Array(trackData.info.decoderConfig.description)\n } : null,\n frameRate ? {\n id: EBMLId.DefaultDuration,\n data: 1e9 / frameRate\n } : null\n ];\n const flippedRotation = rotation ? normalizeRotation(-rotation) : 0;\n const hasNonSquarePixelAspectRatio = !!trackData.info.aspectRatio && trackData.info.aspectRatio.num * trackData.info.height !== trackData.info.aspectRatio.den * trackData.info.width;\n const colorSpace = trackData.info.decoderConfig.colorSpace;\n const videoElement = { id: EBMLId.Video, data: [\n { id: EBMLId.PixelWidth, data: trackData.info.width },\n { id: EBMLId.PixelHeight, data: trackData.info.height },\n hasNonSquarePixelAspectRatio ? { id: EBMLId.DisplayWidth, data: trackData.info.aspectRatio.num } : null,\n hasNonSquarePixelAspectRatio ? { id: EBMLId.DisplayHeight, data: trackData.info.aspectRatio.den } : null,\n hasNonSquarePixelAspectRatio ? { id: EBMLId.DisplayUnit, data: 3 } : null,\n // 3 = display aspect ratio\n trackData.info.alphaMode ? { id: EBMLId.AlphaMode, data: 1 } : null,\n colorSpaceIsComplete(colorSpace) ? {\n id: EBMLId.Colour,\n data: [\n {\n id: EBMLId.MatrixCoefficients,\n data: MATRIX_COEFFICIENTS_MAP[colorSpace.matrix]\n },\n {\n id: EBMLId.TransferCharacteristics,\n data: TRANSFER_CHARACTERISTICS_MAP[colorSpace.transfer]\n },\n {\n id: EBMLId.Primaries,\n data: COLOR_PRIMARIES_MAP[colorSpace.primaries]\n },\n {\n id: EBMLId.Range,\n data: colorSpace.fullRange ? 2 : 1\n }\n ]\n } : null,\n flippedRotation ? {\n id: EBMLId.Projection,\n data: [\n {\n id: EBMLId.ProjectionType,\n data: 0\n // rectangular\n },\n {\n id: EBMLId.ProjectionPoseRoll,\n data: new EBMLFloat32((flippedRotation + 180) % 360 - 180)\n // [0, 270] -> [-180, 90]\n }\n ]\n } : null\n ] };\n elements.push(videoElement);\n return elements;\n }\n audioSpecificTrackInfo(trackData) {\n const pcmInfo = PCM_AUDIO_CODECS.includes(trackData.track.source._codec) ? parsePcmCodec(trackData.track.source._codec) : null;\n return [\n trackData.info.decoderConfig.description ? {\n id: EBMLId.CodecPrivate,\n data: toUint8Array(trackData.info.decoderConfig.description)\n } : null,\n { id: EBMLId.Audio, data: [\n { id: EBMLId.SamplingFrequency, data: new EBMLFloat32(trackData.info.sampleRate) },\n { id: EBMLId.Channels, data: trackData.info.numberOfChannels },\n pcmInfo ? { id: EBMLId.BitDepth, data: 8 * pcmInfo.sampleSize } : null\n ] }\n ];\n }\n subtitleSpecificTrackInfo(trackData) {\n return [\n { id: EBMLId.CodecPrivate, data: textEncoder.encode(trackData.info.config.description) }\n ];\n }\n maybeCreateTags() {\n const simpleTags = [];\n const addSimpleTag = (key, value) => {\n simpleTags.push({ id: EBMLId.SimpleTag, data: [\n { id: EBMLId.TagName, data: new EBMLUnicodeString(key) },\n typeof value === \"string\" ? { id: EBMLId.TagString, data: new EBMLUnicodeString(value) } : { id: EBMLId.TagBinary, data: value }\n ] });\n };\n const metadataTags = this.output._metadataTags;\n const writtenTags = /* @__PURE__ */ new Set();\n for (const { key, value } of keyValueIterator(metadataTags)) {\n switch (key) {\n case \"title\":\n {\n addSimpleTag(\"TITLE\", value);\n writtenTags.add(\"TITLE\");\n }\n ;\n break;\n case \"description\":\n {\n addSimpleTag(\"DESCRIPTION\", value);\n writtenTags.add(\"DESCRIPTION\");\n }\n ;\n break;\n case \"artist\":\n {\n addSimpleTag(\"ARTIST\", value);\n writtenTags.add(\"ARTIST\");\n }\n ;\n break;\n case \"album\":\n {\n addSimpleTag(\"ALBUM\", value);\n writtenTags.add(\"ALBUM\");\n }\n ;\n break;\n case \"albumArtist\":\n {\n addSimpleTag(\"ALBUM_ARTIST\", value);\n writtenTags.add(\"ALBUM_ARTIST\");\n }\n ;\n break;\n case \"genre\":\n {\n addSimpleTag(\"GENRE\", value);\n writtenTags.add(\"GENRE\");\n }\n ;\n break;\n case \"comment\":\n {\n addSimpleTag(\"COMMENT\", value);\n writtenTags.add(\"COMMENT\");\n }\n ;\n break;\n case \"lyrics\":\n {\n addSimpleTag(\"LYRICS\", value);\n writtenTags.add(\"LYRICS\");\n }\n ;\n break;\n case \"date\":\n {\n addSimpleTag(\"DATE\", value.toISOString().slice(0, 10));\n writtenTags.add(\"DATE\");\n }\n ;\n break;\n case \"trackNumber\":\n {\n const string = metadataTags.tracksTotal !== void 0 ? `${value}/${metadataTags.tracksTotal}` : value.toString();\n addSimpleTag(\"PART_NUMBER\", string);\n writtenTags.add(\"PART_NUMBER\");\n }\n ;\n break;\n case \"discNumber\":\n {\n const string = metadataTags.discsTotal !== void 0 ? `${value}/${metadataTags.discsTotal}` : value.toString();\n addSimpleTag(\"DISC\", string);\n writtenTags.add(\"DISC\");\n }\n ;\n break;\n case \"tracksTotal\":\n case \"discsTotal\":\n {\n }\n ;\n break;\n case \"images\":\n case \"raw\":\n {\n }\n ;\n break;\n default:\n assertNever(key);\n }\n }\n if (metadataTags.raw) {\n for (const key in metadataTags.raw) {\n const value = metadataTags.raw[key];\n if (value == null || writtenTags.has(key)) {\n continue;\n }\n if (typeof value === \"string\" || value instanceof Uint8Array) {\n addSimpleTag(key, value);\n }\n }\n }\n if (simpleTags.length === 0) {\n return;\n }\n this.tagsElement = {\n id: EBMLId.Tags,\n data: [{ id: EBMLId.Tag, data: [\n { id: EBMLId.Targets, data: [\n { id: EBMLId.TargetTypeValue, data: 50 },\n { id: EBMLId.TargetType, data: \"MOVIE\" }\n ] },\n ...simpleTags\n ] }]\n };\n }\n maybeCreateAttachments() {\n const metadataTags = this.output._metadataTags;\n const elements = [];\n const existingFileUids = /* @__PURE__ */ new Set();\n const images = metadataTags.images ?? [];\n for (const image of images) {\n let imageName = image.name;\n if (imageName === void 0) {\n const baseName = image.kind === \"coverFront\" ? \"cover\" : image.kind === \"coverBack\" ? \"back\" : \"image\";\n imageName = baseName + (imageMimeTypeToExtension(image.mimeType) ?? \"\");\n }\n let fileUid;\n while (true) {\n fileUid = 0n;\n for (let i2 = 0; i2 < 8; i2++) {\n fileUid <<= 8n;\n fileUid |= BigInt(Math.floor(Math.random() * 256));\n }\n if (fileUid !== 0n && !existingFileUids.has(fileUid)) {\n break;\n }\n }\n existingFileUids.add(fileUid);\n elements.push({\n id: EBMLId.AttachedFile,\n data: [\n image.description !== void 0 ? { id: EBMLId.FileDescription, data: new EBMLUnicodeString(image.description) } : null,\n { id: EBMLId.FileName, data: new EBMLUnicodeString(imageName) },\n { id: EBMLId.FileMediaType, data: image.mimeType },\n { id: EBMLId.FileData, data: image.data },\n { id: EBMLId.FileUID, data: fileUid }\n ]\n });\n }\n for (const [key, value] of Object.entries(metadataTags.raw ?? {})) {\n if (!(value instanceof AttachedFile)) {\n continue;\n }\n const keyIsNumeric = /^\\d+$/.test(key);\n if (!keyIsNumeric) {\n continue;\n }\n if (images.find((x) => x.mimeType === value.mimeType && uint8ArraysAreEqual(x.data, value.data))) {\n continue;\n }\n elements.push({\n id: EBMLId.AttachedFile,\n data: [\n value.description !== void 0 ? { id: EBMLId.FileDescription, data: new EBMLUnicodeString(value.description) } : null,\n { id: EBMLId.FileName, data: new EBMLUnicodeString(value.name ?? \"\") },\n { id: EBMLId.FileMediaType, data: value.mimeType ?? \"\" },\n { id: EBMLId.FileData, data: value.data },\n { id: EBMLId.FileUID, data: BigInt(key) }\n ]\n });\n }\n if (elements.length === 0) {\n return;\n }\n this.attachmentsElement = { id: EBMLId.Attachments, data: elements };\n }\n createSegment() {\n this.createTracks();\n this.maybeCreateTags();\n this.maybeCreateAttachments();\n this.maybeCreateSeekHead(false);\n const segment = {\n id: EBMLId.Segment,\n size: this.format._options.appendOnly ? -1 : SEGMENT_SIZE_BYTES,\n data: [\n this.seekHead,\n // null if append-only\n this.segmentInfo,\n this.tracksElement,\n // Matroska spec says put this at the end of the file, but I think placing it before the first cluster\n // makes more sense, and FFmpeg agrees (argumentum ad ffmpegum fallacy)\n this.attachmentsElement,\n this.tagsElement\n ]\n };\n this.segment = segment;\n if (this.format._options.onSegmentHeader) {\n this.writer.startTrackingWrites();\n }\n this.ebmlWriter.writeEBML(segment);\n if (this.format._options.onSegmentHeader) {\n const { data, start } = this.writer.stopTrackingWrites();\n this.format._options.onSegmentHeader(data, start);\n }\n }\n createCues() {\n this.cues = { id: EBMLId.Cues, data: [] };\n }\n get segmentDataOffset() {\n assert(this.segment);\n return this.ebmlWriter.dataOffsets.get(this.segment);\n }\n allTracksAreKnown() {\n for (const track of this.output._tracks) {\n if (!track.source._closed && !this.trackDatas.some((x) => x.track === track)) {\n return false;\n }\n }\n return true;\n }\n async getMimeType() {\n await this.allTracksKnown.promise;\n const codecStrings = this.trackDatas.map((trackData) => {\n if (trackData.type === \"video\") {\n return trackData.info.decoderConfig.codec;\n } else if (trackData.type === \"audio\") {\n return trackData.info.decoderConfig.codec;\n } else {\n const map = {\n webvtt: \"wvtt\"\n };\n return map[trackData.track.source._codec];\n }\n });\n return buildMatroskaMimeType({\n isWebM: this.format instanceof WebMOutputFormat,\n hasVideo: this.trackDatas.some((x) => x.type === \"video\"),\n hasAudio: this.trackDatas.some((x) => x.type === \"audio\"),\n codecStrings\n });\n }\n getVideoTrackData(track, packet, meta) {\n const existingTrackData = this.trackDatas.find((x) => x.track === track);\n if (existingTrackData) {\n return existingTrackData;\n }\n validateVideoChunkMetadata(meta);\n assert(meta);\n assert(meta.decoderConfig);\n assert(meta.decoderConfig.codedWidth !== void 0);\n assert(meta.decoderConfig.codedHeight !== void 0);\n const displayAspectWidth = meta.decoderConfig.displayAspectWidth;\n const displayAspectHeight = meta.decoderConfig.displayAspectHeight;\n const aspectRatio = displayAspectWidth === void 0 || displayAspectHeight === void 0 ? null : simplifyRational({\n num: displayAspectWidth,\n den: displayAspectHeight\n });\n const newTrackData = {\n track,\n type: \"video\",\n info: {\n width: meta.decoderConfig.codedWidth,\n height: meta.decoderConfig.codedHeight,\n aspectRatio,\n decoderConfig: meta.decoderConfig,\n alphaMode: !!packet.sideData.alpha\n // The first packet determines if this track has alpha or not\n },\n chunkQueue: [],\n lastWrittenMsTimestamp: null,\n closed: false\n };\n if (track.source._codec === \"vp9\") {\n newTrackData.info.decoderConfig = {\n ...newTrackData.info.decoderConfig,\n description: new Uint8Array(generateVp9CodecConfigurationFromCodecString(newTrackData.info.decoderConfig.codec))\n };\n } else if (track.source._codec === \"av1\") {\n newTrackData.info.decoderConfig = {\n ...newTrackData.info.decoderConfig,\n description: new Uint8Array(generateAv1CodecConfigurationFromCodecString(newTrackData.info.decoderConfig.codec))\n };\n }\n this.trackDatas.push(newTrackData);\n this.trackDatas.sort((a2, b) => a2.track.id - b.track.id);\n if (this.allTracksAreKnown()) {\n this.allTracksKnown.resolve();\n }\n return newTrackData;\n }\n getAudioTrackData(track, packet, meta) {\n const existingTrackData = this.trackDatas.find((x) => x.track === track);\n if (existingTrackData) {\n return existingTrackData;\n }\n validateAudioChunkMetadata(meta);\n assert(meta);\n assert(meta.decoderConfig);\n const decoderConfig = { ...meta.decoderConfig };\n let requiresAdtsStripping = false;\n if (track.source._codec === \"aac\" && !decoderConfig.description) {\n const adtsFrame = readAdtsFrameHeader(FileSlice.tempFromBytes(packet.data));\n if (!adtsFrame) {\n 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.\");\n }\n const sampleRate = aacFrequencyTable[adtsFrame.samplingFrequencyIndex];\n const numberOfChannels = aacChannelMap[adtsFrame.channelConfiguration];\n if (sampleRate === void 0 || numberOfChannels === void 0) {\n throw new Error(\"Invalid ADTS frame header.\");\n }\n decoderConfig.description = buildAacAudioSpecificConfig({\n objectType: adtsFrame.objectType,\n sampleRate,\n numberOfChannels\n });\n requiresAdtsStripping = true;\n }\n const newTrackData = {\n track,\n type: \"audio\",\n info: {\n numberOfChannels: meta.decoderConfig.numberOfChannels,\n sampleRate: meta.decoderConfig.sampleRate,\n decoderConfig,\n requiresAdtsStripping\n },\n chunkQueue: [],\n lastWrittenMsTimestamp: null,\n closed: false\n };\n this.trackDatas.push(newTrackData);\n this.trackDatas.sort((a2, b) => a2.track.id - b.track.id);\n if (this.allTracksAreKnown()) {\n this.allTracksKnown.resolve();\n }\n return newTrackData;\n }\n getSubtitleTrackData(track, meta) {\n const existingTrackData = this.trackDatas.find((x) => x.track === track);\n if (existingTrackData) {\n return existingTrackData;\n }\n validateSubtitleMetadata(meta);\n assert(meta);\n assert(meta.config);\n const newTrackData = {\n track,\n type: \"subtitle\",\n info: {\n config: meta.config\n },\n chunkQueue: [],\n lastWrittenMsTimestamp: null,\n closed: false\n };\n this.trackDatas.push(newTrackData);\n this.trackDatas.sort((a2, b) => a2.track.id - b.track.id);\n if (this.allTracksAreKnown()) {\n this.allTracksKnown.resolve();\n }\n return newTrackData;\n }\n async addEncodedVideoPacket(track, packet, meta) {\n const release = await this.mutex.acquire();\n try {\n const trackData = this.getVideoTrackData(track, packet, meta);\n const isKeyFrame = packet.type === \"key\";\n this.validateTimestamp(trackData.track, packet.timestamp, isKeyFrame);\n let timestamp = packet.timestamp;\n let duration = packet.duration;\n if (track.metadata.frameRate !== void 0) {\n timestamp = roundToDivisor(timestamp, track.metadata.frameRate);\n duration = roundToDivisor(duration, track.metadata.frameRate);\n }\n const additions = trackData.info.alphaMode ? packet.sideData.alpha ?? null : null;\n const videoChunk = this.createInternalChunk(packet.data, timestamp, duration, packet.type, additions);\n if (track.source._codec === \"vp9\")\n this.fixVP9ColorSpace(trackData, videoChunk);\n trackData.chunkQueue.push(videoChunk);\n await this.interleaveChunks();\n } finally {\n release();\n }\n }\n async addEncodedAudioPacket(track, packet, meta) {\n const release = await this.mutex.acquire();\n try {\n const trackData = this.getAudioTrackData(track, packet, meta);\n let packetData = packet.data;\n if (trackData.info.requiresAdtsStripping) {\n const adtsFrame = readAdtsFrameHeader(FileSlice.tempFromBytes(packetData));\n if (!adtsFrame) {\n throw new Error(\"Expected ADTS frame, didn't get one.\");\n }\n const headerLength = adtsFrame.crcCheck === null ? MIN_ADTS_FRAME_HEADER_SIZE : MAX_ADTS_FRAME_HEADER_SIZE;\n packetData = packetData.subarray(headerLength);\n }\n const isKeyFrame = packet.type === \"key\";\n this.validateTimestamp(trackData.track, packet.timestamp, isKeyFrame);\n const audioChunk = this.createInternalChunk(packetData, packet.timestamp, packet.duration, packet.type);\n trackData.chunkQueue.push(audioChunk);\n await this.interleaveChunks();\n } finally {\n release();\n }\n }\n async addSubtitleCue(track, cue, meta) {\n const release = await this.mutex.acquire();\n try {\n const trackData = this.getSubtitleTrackData(track, meta);\n this.validateTimestamp(trackData.track, cue.timestamp, true);\n let bodyText = cue.text;\n const timestampMs = Math.round(cue.timestamp * 1e3);\n inlineTimestampRegex.lastIndex = 0;\n bodyText = bodyText.replace(inlineTimestampRegex, (match) => {\n const time = parseSubtitleTimestamp(match.slice(1, -1));\n const offsetTime = time - timestampMs;\n return `<${formatSubtitleTimestamp(offsetTime)}>`;\n });\n const body = textEncoder.encode(bodyText);\n const additions = `${cue.settings ?? \"\"}\n${cue.identifier ?? \"\"}\n${cue.notes ?? \"\"}`;\n const subtitleChunk = this.createInternalChunk(body, cue.timestamp, cue.duration, \"key\", additions.trim() ? textEncoder.encode(additions) : null);\n trackData.chunkQueue.push(subtitleChunk);\n await this.interleaveChunks();\n } finally {\n release();\n }\n }\n async interleaveChunks(isFinalCall = false) {\n if (!isFinalCall && !this.allTracksAreKnown()) {\n return;\n }\n outer: while (true) {\n let trackWithMinTimestamp = null;\n let minTimestamp = Infinity;\n for (const trackData of this.trackDatas) {\n if (!isFinalCall && trackData.chunkQueue.length === 0 && !trackData.closed) {\n break outer;\n }\n if (trackData.chunkQueue.length > 0 && trackData.chunkQueue[0].timestamp < minTimestamp) {\n trackWithMinTimestamp = trackData;\n minTimestamp = trackData.chunkQueue[0].timestamp;\n }\n }\n if (!trackWithMinTimestamp) {\n break;\n }\n const chunk = trackWithMinTimestamp.chunkQueue.shift();\n this.writeBlock(trackWithMinTimestamp, chunk);\n }\n if (!isFinalCall) {\n await this.writer.flush();\n }\n }\n /**\n * Due to [a bug in Chromium](https://bugs.chromium.org/p/chromium/issues/detail?id=1377842), VP9 streams often\n * lack color space information. This method patches in that information.\n */\n fixVP9ColorSpace(trackData, chunk) {\n if (chunk.type !== \"key\")\n return;\n if (!trackData.info.decoderConfig.colorSpace || !trackData.info.decoderConfig.colorSpace.matrix)\n return;\n const bitstream = new Bitstream(chunk.data);\n bitstream.skipBits(2);\n const profileLowBit = bitstream.readBits(1);\n const profileHighBit = bitstream.readBits(1);\n const profile = (profileHighBit << 1) + profileLowBit;\n if (profile === 3)\n bitstream.skipBits(1);\n const showExistingFrame = bitstream.readBits(1);\n if (showExistingFrame)\n return;\n const frameType = bitstream.readBits(1);\n if (frameType !== 0)\n return;\n bitstream.skipBits(2);\n const syncCode = bitstream.readBits(24);\n if (syncCode !== 4817730)\n return;\n if (profile >= 2)\n bitstream.skipBits(1);\n const colorSpaceID = {\n rgb: 7,\n bt709: 2,\n bt470bg: 1,\n smpte170m: 3\n }[trackData.info.decoderConfig.colorSpace.matrix];\n writeBits(chunk.data, bitstream.pos, bitstream.pos + 3, colorSpaceID);\n }\n /** Converts a read-only external chunk into an internal one for easier use. */\n createInternalChunk(data, timestamp, duration, type, additions = null) {\n const internalChunk = {\n data,\n type,\n timestamp,\n duration,\n additions\n };\n return internalChunk;\n }\n /** Writes a block containing media data to the file. */\n writeBlock(trackData, chunk) {\n if (!this.segment) {\n this.createSegment();\n }\n const msTimestamp = Math.round(1e3 * chunk.timestamp);\n const keyFrameQueuedEverywhere = this.trackDatas.every((otherTrackData) => {\n if (trackData === otherTrackData) {\n return chunk.type === \"key\";\n }\n const firstQueuedSample = otherTrackData.chunkQueue[0];\n if (firstQueuedSample) {\n return firstQueuedSample.type === \"key\";\n }\n return otherTrackData.closed;\n });\n let shouldCreateNewCluster = false;\n if (!this.currentCluster) {\n shouldCreateNewCluster = true;\n } else {\n assert(this.currentClusterStartMsTimestamp !== null);\n assert(this.currentClusterMaxMsTimestamp !== null);\n const relativeTimestamp2 = msTimestamp - this.currentClusterStartMsTimestamp;\n shouldCreateNewCluster = keyFrameQueuedEverywhere && msTimestamp > this.currentClusterMaxMsTimestamp && relativeTimestamp2 >= 1e3 * (this.format._options.minimumClusterDuration ?? 1) || relativeTimestamp2 > MAX_CLUSTER_TIMESTAMP_MS;\n }\n if (shouldCreateNewCluster) {\n this.createNewCluster(msTimestamp);\n }\n const relativeTimestamp = msTimestamp - this.currentClusterStartMsTimestamp;\n if (relativeTimestamp < MIN_CLUSTER_TIMESTAMP_MS) {\n return;\n }\n const prelude = new Uint8Array(4);\n const view2 = new DataView(prelude.buffer);\n view2.setUint8(0, 128 | trackData.track.id);\n view2.setInt16(1, relativeTimestamp, false);\n const msDuration = Math.round(1e3 * chunk.duration);\n if (!chunk.additions) {\n view2.setUint8(3, Number(chunk.type === \"key\") << 7);\n const simpleBlock = { id: EBMLId.SimpleBlock, data: [\n prelude,\n chunk.data\n ] };\n this.ebmlWriter.writeEBML(simpleBlock);\n } else {\n const blockGroup = { id: EBMLId.BlockGroup, data: [\n { id: EBMLId.Block, data: [\n prelude,\n chunk.data\n ] },\n chunk.type === \"delta\" ? {\n id: EBMLId.ReferenceBlock,\n data: new EBMLSignedInt(trackData.lastWrittenMsTimestamp - msTimestamp)\n } : null,\n chunk.additions ? { id: EBMLId.BlockAdditions, data: [\n { id: EBMLId.BlockMore, data: [\n { id: EBMLId.BlockAddID, data: 1 },\n // Some players expect BlockAddID to come first\n { id: EBMLId.BlockAdditional, data: chunk.additions }\n ] }\n ] } : null,\n msDuration > 0 ? { id: EBMLId.BlockDuration, data: msDuration } : null\n ] };\n this.ebmlWriter.writeEBML(blockGroup);\n }\n this.startTimestamp = Math.min(this.startTimestamp, msTimestamp);\n this.endTimestamp = Math.max(this.endTimestamp, msTimestamp + msDuration);\n trackData.lastWrittenMsTimestamp = msTimestamp;\n if (!this.trackDatasInCurrentCluster.has(trackData)) {\n this.trackDatasInCurrentCluster.set(trackData, {\n firstMsTimestamp: msTimestamp\n });\n }\n this.currentClusterMaxMsTimestamp = Math.max(this.currentClusterMaxMsTimestamp, msTimestamp);\n }\n /** Creates a new Cluster element to contain media chunks. */\n createNewCluster(msTimestamp) {\n if (this.currentCluster) {\n this.finalizeCurrentCluster();\n }\n if (this.format._options.onCluster) {\n this.writer.startTrackingWrites();\n }\n this.currentCluster = {\n id: EBMLId.Cluster,\n size: this.format._options.appendOnly ? -1 : CLUSTER_SIZE_BYTES,\n data: [\n { id: EBMLId.Timestamp, data: msTimestamp }\n ]\n };\n this.ebmlWriter.writeEBML(this.currentCluster);\n this.currentClusterStartMsTimestamp = msTimestamp;\n this.currentClusterMaxMsTimestamp = msTimestamp;\n this.trackDatasInCurrentCluster.clear();\n }\n finalizeCurrentCluster() {\n assert(this.currentCluster);\n if (!this.format._options.appendOnly) {\n const clusterSize = this.writer.getPos() - this.ebmlWriter.dataOffsets.get(this.currentCluster);\n const endPos = this.writer.getPos();\n this.writer.seek(this.ebmlWriter.offsets.get(this.currentCluster) + 4);\n this.ebmlWriter.writeVarInt(clusterSize, CLUSTER_SIZE_BYTES);\n this.writer.seek(endPos);\n }\n if (this.format._options.onCluster) {\n assert(this.currentClusterStartMsTimestamp !== null);\n const { data, start } = this.writer.stopTrackingWrites();\n this.format._options.onCluster(data, start, this.currentClusterStartMsTimestamp / 1e3);\n }\n const clusterOffsetFromSegment = this.ebmlWriter.offsets.get(this.currentCluster) - this.segmentDataOffset;\n const groupedByTimestamp = /* @__PURE__ */ new Map();\n for (const [trackData, { firstMsTimestamp }] of this.trackDatasInCurrentCluster) {\n if (!groupedByTimestamp.has(firstMsTimestamp)) {\n groupedByTimestamp.set(firstMsTimestamp, []);\n }\n groupedByTimestamp.get(firstMsTimestamp).push(trackData);\n }\n const groupedAndSortedByTimestamp = [...groupedByTimestamp.entries()].sort((a2, b) => a2[0] - b[0]);\n for (const [msTimestamp, trackDatas] of groupedAndSortedByTimestamp) {\n assert(this.cues);\n this.cues.data.push({ id: EBMLId.CuePoint, data: [\n { id: EBMLId.CueTime, data: msTimestamp },\n // Create CueTrackPositions for each track that starts at this timestamp\n ...trackDatas.map((trackData) => {\n return { id: EBMLId.CueTrackPositions, data: [\n { id: EBMLId.CueTrack, data: trackData.track.id },\n { id: EBMLId.CueClusterPosition, data: clusterOffsetFromSegment }\n ] };\n })\n ] });\n }\n }\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n async onTrackClose(track) {\n const release = await this.mutex.acquire();\n const trackData = this.trackDatas.find((x) => x.track === track);\n if (trackData) {\n trackData.closed = true;\n }\n if (this.allTracksAreKnown()) {\n this.allTracksKnown.resolve();\n }\n await this.interleaveChunks();\n release();\n }\n /** Finalizes the file, making it ready for use. Must be called after all media chunks have been added. */\n async finalize() {\n const release = await this.mutex.acquire();\n this.allTracksKnown.resolve();\n for (const trackData of this.trackDatas) {\n trackData.closed = true;\n }\n if (!this.segment) {\n this.createSegment();\n }\n await this.interleaveChunks(true);\n if (this.currentCluster) {\n this.finalizeCurrentCluster();\n }\n assert(this.cues);\n this.ebmlWriter.writeEBML(this.cues);\n if (!this.format._options.appendOnly) {\n const segmentSize = this.writer.getPos() - this.segmentDataOffset;\n this.writer.seek(this.ebmlWriter.offsets.get(this.segment) + 4);\n this.ebmlWriter.writeVarInt(segmentSize, SEGMENT_SIZE_BYTES);\n const duration = this.startTimestamp === Infinity ? 0 : this.endTimestamp - this.startTimestamp;\n this.segmentDuration.data = new EBMLFloat64(duration);\n this.writer.seek(this.ebmlWriter.offsets.get(this.segmentDuration));\n this.ebmlWriter.writeEBML(this.segmentDuration);\n assert(this.seekHead);\n this.writer.seek(this.ebmlWriter.offsets.get(this.seekHead));\n this.maybeCreateSeekHead(true);\n this.ebmlWriter.writeEBML(this.seekHead);\n }\n release();\n }\n};\n\n// node_modules/mediabunny/dist/modules/src/media-source.js\nvar MediaSource = class {\n constructor() {\n this._connectedTrack = null;\n this._closingPromise = null;\n this._closed = false;\n }\n /** @internal */\n _ensureValidAdd() {\n if (!this._connectedTrack) {\n throw new Error(\"Source is not connected to an output track.\");\n }\n if (this._connectedTrack.output.state === \"canceled\") {\n throw new Error(\"Output has been canceled.\");\n }\n if (this._connectedTrack.output.state === \"finalizing\" || this._connectedTrack.output.state === \"finalized\") {\n throw new Error(\"Output has been finalized.\");\n }\n if (this._connectedTrack.output.state === \"pending\") {\n throw new Error(\"Output has not started.\");\n }\n if (this._closed) {\n throw new Error(\"Source is closed.\");\n }\n }\n /** @internal */\n async _start() {\n }\n /** @internal */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n async _flushAndClose(forceClose) {\n }\n /**\n * Closes this source. This prevents future samples from being added and signals to the output file that no further\n * samples will come in for this track. Calling `.close()` is optional but recommended after adding the\n * last sample - for improved performance and reduced memory usage.\n */\n close() {\n if (this._closingPromise) {\n return;\n }\n const connectedTrack = this._connectedTrack;\n if (!connectedTrack) {\n throw new Error(\"Cannot call close without connecting the source to an output track.\");\n }\n if (connectedTrack.output.state === \"pending\") {\n throw new Error(\"Cannot call close before output has been started.\");\n }\n this._closingPromise = (async () => {\n await this._flushAndClose(false);\n this._closed = true;\n if (connectedTrack.output.state === \"finalizing\" || connectedTrack.output.state === \"finalized\") {\n return;\n }\n connectedTrack.output._muxer.onTrackClose(connectedTrack);\n })();\n }\n /** @internal */\n async _flushOrWaitForOngoingClose(forceClose) {\n return this._closingPromise ??= (async () => {\n await this._flushAndClose(forceClose);\n this._closed = true;\n })();\n }\n};\nvar VideoSource = class extends MediaSource {\n /** Internal constructor. */\n constructor(codec) {\n super();\n this._connectedTrack = null;\n if (!VIDEO_CODECS.includes(codec)) {\n throw new TypeError(`Invalid video codec '${codec}'. Must be one of: ${VIDEO_CODECS.join(\", \")}.`);\n }\n this._codec = codec;\n }\n};\nvar maybeEnsureIsKeyPacket = (track, packet) => {\n if (track.metadata.hasOnlyKeyPackets && packet.type !== \"key\") {\n throw new Error(\"Cannot add non-key packets to a hasOnlyKeyPackets video track.\");\n }\n};\nvar VideoEncoderWrapper = class {\n constructor(source, encodingConfig) {\n this.source = source;\n this.encodingConfig = encodingConfig;\n this.ensureEncoderPromise = null;\n this.encoderInitialized = false;\n this.encoder = null;\n this.muxer = null;\n this.lastMultipleOfKeyFrameInterval = -1;\n this.emittedEncoderPackets = 0;\n this.codedWidth = null;\n this.codedHeight = null;\n this.outputWidth = null;\n this.outputHeight = null;\n this.frameRateLastSample = null;\n this.frameRateLastTimestamp = null;\n this.frameRateLastEndTimestamp = null;\n this.preciseTimings = [];\n this.customEncoder = null;\n this.customEncoderCallSerializer = new CallSerializer();\n this.customEncoderQueueSize = 0;\n this.alphaEncoder = null;\n this.splitter = null;\n this.splitterCreationFailed = false;\n this.alphaFrameQueue = [];\n this.error = null;\n this.closed = false;\n this.lastMuxerPromise = Promise.resolve();\n }\n async add(videoSample, shouldClose, encodeOptions) {\n const originalSample = videoSample;\n try {\n this.checkForEncoderError();\n this.source._ensureValidAdd();\n const config = this.encodingConfig;\n const sizeChangeBehavior = config.sizeChangeBehavior ?? \"deny\";\n let isSizeChange = false;\n if (this.codedWidth !== null && this.codedHeight !== null) {\n if (videoSample.codedWidth !== this.codedWidth || videoSample.codedHeight !== this.codedHeight) {\n isSizeChange = true;\n if (sizeChangeBehavior === \"deny\") {\n 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 'deny' in the encoding options.`);\n }\n }\n } else {\n this.codedWidth = videoSample.codedWidth;\n this.codedHeight = videoSample.codedHeight;\n }\n const hasTransformConfig = config.transform?.width !== void 0 || config.transform?.height !== void 0 || config.transform?.rotate !== void 0 || config.transform?.crop !== void 0 || config.transform?.force === true;\n const needsTransform = hasTransformConfig || isSizeChange && sizeChangeBehavior !== \"passThrough\";\n if (needsTransform) {\n let targetWidth = config.transform?.width;\n let targetHeight = config.transform?.height;\n let appliedFit = config.transform?.fit ?? \"fill\";\n if (isSizeChange && sizeChangeBehavior !== \"passThrough\") {\n assert(this.outputWidth);\n assert(this.outputHeight);\n assert(sizeChangeBehavior !== \"deny\");\n targetWidth = this.outputWidth;\n targetHeight = this.outputHeight;\n appliedFit = sizeChangeBehavior;\n }\n const transformed = await videoSample.transform({\n width: targetWidth,\n height: targetHeight,\n roundDimensionsTo: 2,\n crop: config.transform?.crop,\n rotate: config.transform?.rotate,\n fit: appliedFit,\n alpha: config.alpha\n });\n if (this.outputWidth === null || this.outputHeight === null) {\n this.outputWidth = transformed.displayWidth;\n this.outputHeight = transformed.displayHeight;\n }\n if (shouldClose) {\n videoSample.close();\n }\n videoSample = transformed;\n shouldClose = true;\n } else {\n if (this.outputWidth === null || this.outputHeight === null) {\n this.outputWidth = videoSample.codedWidth;\n this.outputHeight = videoSample.codedHeight;\n }\n }\n const frameRate = config.transform?.frameRate;\n if (frameRate !== void 0) {\n const originalEndTimestamp = videoSample.timestamp + videoSample.duration;\n const alignedTimestamp = floorToDivisor(videoSample.timestamp, frameRate);\n if (this.frameRateLastSample !== null) {\n if (alignedTimestamp <= this.frameRateLastTimestamp) {\n this.frameRateLastSample.close();\n this.frameRateLastSample = videoSample.clone();\n this.frameRateLastEndTimestamp = originalEndTimestamp;\n return;\n } else {\n await this.padFrameRate(alignedTimestamp, encodeOptions);\n }\n }\n if (videoSample === originalSample) {\n videoSample = videoSample.clone();\n shouldClose = true;\n }\n videoSample.setTimestamp(alignedTimestamp);\n videoSample.setDuration(1 / frameRate);\n this.frameRateLastSample?.close();\n this.frameRateLastSample = videoSample.clone();\n this.frameRateLastTimestamp = alignedTimestamp;\n this.frameRateLastEndTimestamp = originalEndTimestamp;\n }\n await this.processAndEncode(videoSample, encodeOptions);\n } finally {\n if (shouldClose) {\n videoSample.close();\n }\n }\n }\n /**\n * Runs the process function (if any) and encodes the resulting samples.\n */\n async processAndEncode(videoSample, encodeOptions) {\n const config = this.encodingConfig;\n let samplesToEncode;\n if (config.transform?.process) {\n let processed = config.transform.process(videoSample);\n if (processed instanceof Promise) {\n processed = await processed;\n }\n if (processed === null) {\n return;\n }\n if (!Array.isArray(processed)) {\n processed = [processed];\n }\n samplesToEncode = processed.map((x) => {\n if (x instanceof VideoSample) {\n return x;\n }\n if (typeof VideoFrame !== \"undefined\" && x instanceof VideoFrame) {\n return new VideoSample(x);\n }\n return new VideoSample(x, {\n timestamp: videoSample.timestamp,\n duration: videoSample.duration\n });\n });\n } else {\n samplesToEncode = [videoSample];\n }\n try {\n for (const sampleToEncode of samplesToEncode) {\n if (!this.encoderInitialized) {\n if (!this.ensureEncoderPromise) {\n this.ensureEncoder(sampleToEncode);\n }\n if (!this.encoderInitialized) {\n await this.ensureEncoderPromise;\n }\n }\n assert(this.encoderInitialized);\n if (this.closed) {\n break;\n }\n const keyFrameInterval = this.encodingConfig.keyFrameInterval ?? 2;\n const multipleOfKeyFrameInterval = Math.floor(sampleToEncode.timestamp / keyFrameInterval);\n const mergedEncodeOptions = { ...sampleToEncode.encodeOptions, ...encodeOptions };\n const finalEncodeOptions = {\n ...mergedEncodeOptions,\n keyFrame: mergedEncodeOptions.keyFrame !== void 0 ? mergedEncodeOptions.keyFrame : keyFrameInterval === 0 || multipleOfKeyFrameInterval !== this.lastMultipleOfKeyFrameInterval\n };\n this.lastMultipleOfKeyFrameInterval = multipleOfKeyFrameInterval;\n this.encodingConfig.onEncodedSample?.(sampleToEncode);\n if (this.customEncoder) {\n this.customEncoderQueueSize++;\n const clonedSample = sampleToEncode.clone();\n const promise = this.customEncoderCallSerializer.call(() => this.customEncoder.encode(clonedSample, finalEncodeOptions)).then(() => this.customEncoderQueueSize--).catch((error) => this.error ??= error).finally(() => {\n clonedSample.close();\n });\n if (this.customEncoderQueueSize >= 4) {\n await promise;\n }\n } else {\n assert(this.encoder);\n const videoFrame = sampleToEncode.toVideoFrame();\n const preciseTimingIndex = binarySearchLessOrEqual(this.preciseTimings, videoFrame.timestamp, (x) => x.microsecondTimestamp);\n const existingEntry = preciseTimingIndex !== -1 ? this.preciseTimings[preciseTimingIndex] : null;\n if (existingEntry && existingEntry.microsecondTimestamp === videoFrame.timestamp) {\n if (existingEntry.timestamp !== sampleToEncode.timestamp) {\n existingEntry.timestampIsValid = false;\n }\n if (existingEntry.duration !== sampleToEncode.duration) {\n existingEntry.durationIsValid = false;\n }\n } else {\n this.preciseTimings.splice(preciseTimingIndex + 1, 0, {\n microsecondTimestamp: videoFrame.timestamp,\n timestamp: sampleToEncode.timestamp,\n duration: sampleToEncode.duration,\n timestampIsValid: true,\n durationIsValid: true\n });\n if (this.preciseTimings.length > 128) {\n this.preciseTimings.shift();\n }\n }\n if (!this.alphaEncoder) {\n this.encoder.encode(videoFrame, finalEncodeOptions);\n videoFrame.close();\n } else {\n const frameDefinitelyHasNoAlpha = !!videoFrame.format && !videoFrame.format.includes(\"A\");\n if (frameDefinitelyHasNoAlpha || this.splitterCreationFailed) {\n this.alphaFrameQueue.push(null);\n this.encoder.encode(videoFrame, finalEncodeOptions);\n videoFrame.close();\n } else {\n const width = videoFrame.displayWidth;\n const height = videoFrame.displayHeight;\n if (!this.splitter) {\n this.splitter = new ColorAlphaSplitter(width, height);\n }\n const { colorFrame, alphaFrame } = await this.splitter.update(videoFrame);\n this.alphaFrameQueue.push(alphaFrame);\n this.encoder.encode(colorFrame, finalEncodeOptions);\n colorFrame.close();\n }\n }\n if (this.encoder.encodeQueueSize >= 4) {\n await new Promise((resolve) => this.encoder.addEventListener(\"dequeue\", resolve, { once: true }));\n }\n }\n await this.lastMuxerPromise;\n }\n } finally {\n for (const sample of samplesToEncode) {\n if (sample !== videoSample) {\n sample.close();\n }\n }\n }\n }\n /** Repeats the last frame rate sample to fill the gap up to the given timestamp. */\n async padFrameRate(until, encodeOptions) {\n const frameRate = this.encodingConfig.transform.frameRate;\n assert(this.frameRateLastSample);\n const frameDifference = Math.round((until - this.frameRateLastTimestamp) * frameRate);\n for (let i2 = 1; i2 < frameDifference; i2++) {\n const sample = this.frameRateLastSample.clone();\n sample.setTimestamp(this.frameRateLastTimestamp + i2 / frameRate);\n sample.setDuration(1 / frameRate);\n await this.processAndEncode(sample, encodeOptions);\n sample.close();\n }\n }\n ensureEncoder(videoSample) {\n this.ensureEncoderPromise = (async () => {\n const encoderConfig = buildVideoEncoderConfig({\n ...this.encodingConfig,\n width: videoSample.codedWidth,\n height: videoSample.codedHeight,\n squarePixelWidth: videoSample.squarePixelWidth,\n squarePixelHeight: videoSample.squarePixelHeight,\n framerate: this.source._connectedTrack?.metadata.frameRate\n });\n this.encodingConfig.onEncoderConfig?.(encoderConfig);\n const MatchingCustomEncoder = customVideoEncoders.find((x) => x.supports(this.encodingConfig.codec, encoderConfig));\n if (MatchingCustomEncoder) {\n this.customEncoder = new MatchingCustomEncoder();\n this.customEncoder.codec = this.encodingConfig.codec;\n this.customEncoder.config = encoderConfig;\n this.customEncoder.onPacket = (packet, meta) => {\n if (!(packet instanceof EncodedPacket)) {\n throw new TypeError(\"The first argument passed to onPacket must be an EncodedPacket.\");\n }\n if (meta !== void 0 && (!meta || typeof meta !== \"object\")) {\n throw new TypeError(\"The second argument passed to onPacket must be an object or undefined.\");\n }\n maybeEnsureIsKeyPacket(this.source._connectedTrack, packet);\n this.encodingConfig.onEncodedPacket?.(packet, meta);\n this.lastMuxerPromise = this.muxer.addEncodedVideoPacket(this.source._connectedTrack, packet, meta).catch((error) => {\n this.error ??= error;\n });\n };\n await this.customEncoder.init();\n } else {\n if (typeof VideoEncoder === \"undefined\") {\n throw new Error(\"VideoEncoder is not supported by this browser.\");\n }\n encoderConfig.alpha = \"discard\";\n if (this.encodingConfig.alpha === \"keep\") {\n encoderConfig.latencyMode = \"quality\";\n }\n const hasOddDimension = encoderConfig.width % 2 === 1 || encoderConfig.height % 2 === 1;\n if (hasOddDimension && (this.encodingConfig.codec === \"avc\" || this.encodingConfig.codec === \"hevc\")) {\n 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.`);\n }\n const support = await VideoEncoder.isConfigSupported(encoderConfig);\n if (!support.supported) {\n 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.`);\n }\n const colorChunkQueue = [];\n const nullAlphaChunkQueue = [];\n let encodedAlphaChunkCount = 0;\n let alphaEncoderQueue = 0;\n const addPacket = (colorChunk, alphaChunk, meta) => {\n const sideData = {};\n if (alphaChunk) {\n const alphaData = new Uint8Array(alphaChunk.byteLength);\n alphaChunk.copyTo(alphaData);\n sideData.alpha = alphaData;\n }\n let packet = EncodedPacket.fromEncodedChunk(colorChunk, sideData);\n const preciseTimingIndex = binarySearchLessOrEqual(this.preciseTimings, colorChunk.timestamp, (x) => x.microsecondTimestamp);\n const entry = preciseTimingIndex !== -1 ? this.preciseTimings[preciseTimingIndex] : null;\n let actualType = null;\n if (this.emittedEncoderPackets === 0 && packet.type === \"delta\" && meta?.decoderConfig) {\n actualType = determineVideoPacketType(this.encodingConfig.codec, meta.decoderConfig, packet.data);\n }\n if (entry && entry.microsecondTimestamp === colorChunk.timestamp || actualType !== null) {\n packet = packet.clone({\n timestamp: entry?.timestampIsValid ? entry.timestamp : void 0,\n duration: entry?.durationIsValid ? entry.duration : void 0,\n type: actualType ?? void 0\n });\n }\n maybeEnsureIsKeyPacket(this.source._connectedTrack, packet);\n this.encodingConfig.onEncodedPacket?.(packet, meta);\n this.lastMuxerPromise = this.muxer.addEncodedVideoPacket(this.source._connectedTrack, packet, meta).catch((error) => {\n this.error ??= error;\n });\n this.emittedEncoderPackets++;\n };\n const stack = new Error(\"Encoding error\").stack;\n this.encoder = new VideoEncoder({\n output: (chunk, meta) => {\n if (!this.alphaEncoder) {\n addPacket(chunk, null, meta);\n return;\n }\n const alphaFrame = this.alphaFrameQueue.shift();\n assert(alphaFrame !== void 0);\n if (alphaFrame) {\n this.alphaEncoder.encode(alphaFrame, {\n // Crucial: The alpha frame is forced to be a key frame whenever the color frame\n // also is. Without this, playback can glitch and even crash in some browsers.\n // This is the reason why the two encoders are wired in series and not in parallel.\n keyFrame: chunk.type === \"key\"\n });\n alphaEncoderQueue++;\n alphaFrame.close();\n colorChunkQueue.push({ chunk, meta });\n } else {\n if (alphaEncoderQueue === 0) {\n addPacket(chunk, null, meta);\n } else {\n nullAlphaChunkQueue.push(encodedAlphaChunkCount + alphaEncoderQueue);\n colorChunkQueue.push({ chunk, meta });\n }\n }\n },\n error: (error) => {\n error.stack = stack;\n this.error ??= error;\n }\n });\n this.encoder.configure(encoderConfig);\n if (this.encodingConfig.alpha === \"keep\") {\n const stack2 = new Error(\"Encoding error\").stack;\n this.alphaEncoder = new VideoEncoder({\n // We ignore the alpha chunk's metadata\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n output: (chunk, meta) => {\n alphaEncoderQueue--;\n const colorChunk = colorChunkQueue.shift();\n assert(colorChunk !== void 0);\n addPacket(colorChunk.chunk, chunk, colorChunk.meta);\n encodedAlphaChunkCount++;\n while (nullAlphaChunkQueue.length > 0 && nullAlphaChunkQueue[0] === encodedAlphaChunkCount) {\n nullAlphaChunkQueue.shift();\n const colorChunk2 = colorChunkQueue.shift();\n assert(colorChunk2 !== void 0);\n addPacket(colorChunk2.chunk, null, colorChunk2.meta);\n }\n },\n error: (error) => {\n error.stack = stack2;\n this.error ??= error;\n }\n });\n this.alphaEncoder.configure(encoderConfig);\n }\n }\n assert(this.source._connectedTrack);\n this.muxer = this.source._connectedTrack.output._muxer;\n this.encoderInitialized = true;\n })();\n }\n async flushAndClose(forceClose) {\n if (!forceClose) {\n this.checkForEncoderError();\n }\n if (!forceClose && this.frameRateLastSample) {\n const frameRate = this.encodingConfig.transform.frameRate;\n const alignedEnd = floorToDivisor(this.frameRateLastEndTimestamp, frameRate);\n await this.padFrameRate(alignedEnd);\n }\n this.closed = true;\n this.frameRateLastSample?.close();\n this.frameRateLastSample = null;\n if (this.customEncoder) {\n if (!forceClose) {\n void this.customEncoderCallSerializer.call(() => this.customEncoder.flush());\n }\n await this.customEncoderCallSerializer.call(() => this.customEncoder.close());\n } else if (this.encoder) {\n if (!forceClose) {\n await this.encoder.flush();\n await this.alphaEncoder?.flush();\n }\n if (this.encoder.state !== \"closed\") {\n this.encoder.close();\n }\n if (this.alphaEncoder && this.alphaEncoder.state !== \"closed\") {\n this.alphaEncoder.close();\n }\n this.alphaFrameQueue.forEach((x) => x?.close());\n this.splitter?.close();\n }\n if (!forceClose) {\n this.checkForEncoderError();\n }\n }\n getQueueSize() {\n if (this.customEncoder) {\n return this.customEncoderQueueSize;\n } else {\n return this.encoder?.encodeQueueSize ?? 0;\n }\n }\n checkForEncoderError() {\n if (this.error) {\n throw this.error;\n }\n }\n};\nvar splitterGpuUnavailable = false;\nvar ColorAlphaSplitter = class _ColorAlphaSplitter {\n constructor(initialWidth, initialHeight) {\n this.canvas = null;\n this.gl = null;\n this.colorProgram = null;\n this.alphaProgram = null;\n this.vao = null;\n this.sourceTexture = null;\n this.alphaResolutionLocation = null;\n this.worker = null;\n this.pendingRequests = /* @__PURE__ */ new Map();\n this.nextRequestId = 0;\n const canMakeCanvas = typeof OffscreenCanvas !== \"undefined\" || typeof document !== \"undefined\" && typeof document.createElement === \"function\";\n if (!_ColorAlphaSplitter.forceCpu && canMakeCanvas && !splitterGpuUnavailable) {\n try {\n if (typeof OffscreenCanvas !== \"undefined\") {\n this.canvas = new OffscreenCanvas(initialWidth, initialHeight);\n } else {\n this.canvas = document.createElement(\"canvas\");\n this.canvas.width = initialWidth;\n this.canvas.height = initialHeight;\n }\n const gl = this.canvas.getContext(\"webgl2\", {\n alpha: true\n // Needed due to the YUV thing we do for alpha\n });\n if (!gl) {\n throw new Error(\"Couldn't acquire WebGL 2 context.\");\n }\n this.gl = gl;\n this.colorProgram = this.createColorProgram();\n this.alphaProgram = this.createAlphaProgram();\n this.vao = this.createVAO();\n this.sourceTexture = this.createTexture();\n this.alphaResolutionLocation = this.gl.getUniformLocation(this.alphaProgram, \"u_resolution\");\n this.gl.useProgram(this.colorProgram);\n this.gl.uniform1i(this.gl.getUniformLocation(this.colorProgram, \"u_sourceTexture\"), 0);\n this.gl.useProgram(this.alphaProgram);\n this.gl.uniform1i(this.gl.getUniformLocation(this.alphaProgram, \"u_sourceTexture\"), 0);\n } catch (error) {\n this.gl = null;\n this.canvas = null;\n splitterGpuUnavailable = true;\n Logging._warn(\"Falling back to CPU for color/alpha splitting.\", error);\n }\n }\n }\n async update(sourceFrame) {\n if (this.gl) {\n return this.updateGpu(sourceFrame);\n } else {\n return this.updateCpu(sourceFrame);\n }\n }\n updateGpu(sourceFrame) {\n assert(this.gl);\n assert(this.canvas);\n if (sourceFrame.displayWidth !== this.canvas.width || sourceFrame.displayHeight !== this.canvas.height) {\n this.canvas.width = sourceFrame.displayWidth;\n this.canvas.height = sourceFrame.displayHeight;\n }\n this.gl.activeTexture(this.gl.TEXTURE0);\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.sourceTexture);\n this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, sourceFrame);\n const colorFrame = this.runColorProgram(sourceFrame);\n const alphaFrame = this.runAlphaProgram(sourceFrame);\n sourceFrame.close();\n return { colorFrame, alphaFrame };\n }\n createVertexShader() {\n assert(this.gl);\n return this.createShader(this.gl.VERTEX_SHADER, `#version 300 es\n\t\t\tin vec2 a_position;\n\t\t\tin vec2 a_texCoord;\n\t\t\tout vec2 v_texCoord;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tgl_Position = vec4(a_position, 0.0, 1.0);\n\t\t\t\tv_texCoord = a_texCoord;\n\t\t\t}\n\t\t`);\n }\n createColorProgram() {\n assert(this.gl);\n const vertexShader = this.createVertexShader();\n const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, `#version 300 es\n\t\t\tprecision highp float;\n\t\t\t\n\t\t\tuniform sampler2D u_sourceTexture;\n\t\t\tin vec2 v_texCoord;\n\t\t\tout vec4 fragColor;\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\tvec4 source = texture(u_sourceTexture, v_texCoord);\n\t\t\t\tfragColor = vec4(source.rgb, 1.0);\n\t\t\t}\n\t\t`);\n const program = this.gl.createProgram();\n this.gl.attachShader(program, vertexShader);\n this.gl.attachShader(program, fragmentShader);\n this.gl.linkProgram(program);\n return program;\n }\n createAlphaProgram() {\n assert(this.gl);\n const vertexShader = this.createVertexShader();\n const fragmentShader = this.createShader(this.gl.FRAGMENT_SHADER, `#version 300 es\n\t\t\tprecision highp float;\n\t\t\t\n\t\t\tuniform sampler2D u_sourceTexture;\n\t\t\tuniform vec2 u_resolution; // The width and height of the canvas\n\t\t\tin vec2 v_texCoord;\n\t\t\tout vec4 fragColor;\n\n\t\t\t// This function determines the value for a single byte in the YUV stream\n\t\t\tfloat getByteValue(float byteOffset) {\n\t\t\t\tfloat width = u_resolution.x;\n\t\t\t\tfloat height = u_resolution.y;\n\n\t\t\t\tfloat yPlaneSize = width * height;\n\n\t\t\t\tif (byteOffset < yPlaneSize) {\n\t\t\t\t\t// This byte is in the luma plane. Find the corresponding pixel coordinates to sample from\n\t\t\t\t\tfloat y = floor(byteOffset / width);\n\t\t\t\t\tfloat x = mod(byteOffset, width);\n\t\t\t\t\t\n\t\t\t\t\t// Add 0.5 to sample the center of the texel\n\t\t\t\t\tvec2 sampleCoord = (vec2(x, y) + 0.5) / u_resolution;\n\t\t\t\t\t\n\t\t\t\t\t// The luma value is the alpha from the source texture\n\t\t\t\t\treturn texture(u_sourceTexture, sampleCoord).a;\n\t\t\t\t} else {\n\t\t\t\t\t// Write a fixed value for chroma and beyond\n\t\t\t\t\treturn 128.0 / 255.0;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tvoid main() {\n\t\t\t\t// Each fragment writes 4 bytes (R, G, B, A)\n\t\t\t\tfloat pixelIndex = floor(gl_FragCoord.y) * u_resolution.x + floor(gl_FragCoord.x);\n\t\t\t\tfloat baseByteOffset = pixelIndex * 4.0;\n\n\t\t\t\tvec4 result;\n\t\t\t\tfor (int i = 0; i < 4; i++) {\n\t\t\t\t\tfloat currentByteOffset = baseByteOffset + float(i);\n\t\t\t\t\tresult[i] = getByteValue(currentByteOffset);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tfragColor = result;\n\t\t\t}\n\t\t`);\n const program = this.gl.createProgram();\n this.gl.attachShader(program, vertexShader);\n this.gl.attachShader(program, fragmentShader);\n this.gl.linkProgram(program);\n return program;\n }\n createShader(type, source) {\n assert(this.gl);\n const shader = this.gl.createShader(type);\n this.gl.shaderSource(shader, source);\n this.gl.compileShader(shader);\n if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {\n Logging._error(\"Shader compile error:\", this.gl.getShaderInfoLog(shader));\n }\n return shader;\n }\n createVAO() {\n assert(this.gl);\n assert(this.colorProgram);\n const vao = this.gl.createVertexArray();\n this.gl.bindVertexArray(vao);\n const vertices = new Float32Array([\n -1,\n -1,\n 0,\n 1,\n 1,\n -1,\n 1,\n 1,\n -1,\n 1,\n 0,\n 0,\n 1,\n 1,\n 1,\n 0\n ]);\n const buffer = this.gl.createBuffer();\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);\n this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);\n const positionLocation = this.gl.getAttribLocation(this.colorProgram, \"a_position\");\n const texCoordLocation = this.gl.getAttribLocation(this.colorProgram, \"a_texCoord\");\n this.gl.enableVertexAttribArray(positionLocation);\n this.gl.vertexAttribPointer(positionLocation, 2, this.gl.FLOAT, false, 16, 0);\n this.gl.enableVertexAttribArray(texCoordLocation);\n this.gl.vertexAttribPointer(texCoordLocation, 2, this.gl.FLOAT, false, 16, 8);\n return vao;\n }\n createTexture() {\n assert(this.gl);\n const texture = this.gl.createTexture();\n this.gl.bindTexture(this.gl.TEXTURE_2D, texture);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);\n return texture;\n }\n runColorProgram(sourceFrame) {\n assert(this.gl);\n assert(this.canvas);\n this.gl.useProgram(this.colorProgram);\n this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);\n this.gl.clear(this.gl.COLOR_BUFFER_BIT);\n this.gl.bindVertexArray(this.vao);\n this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);\n return new VideoFrame(this.canvas, {\n timestamp: sourceFrame.timestamp,\n duration: sourceFrame.duration ?? void 0,\n alpha: \"discard\"\n });\n }\n runAlphaProgram(sourceFrame) {\n assert(this.gl);\n assert(this.canvas);\n this.gl.useProgram(this.alphaProgram);\n this.gl.uniform2f(this.alphaResolutionLocation, this.canvas.width, this.canvas.height);\n this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);\n this.gl.clear(this.gl.COLOR_BUFFER_BIT);\n this.gl.bindVertexArray(this.vao);\n this.gl.drawArrays(this.gl.TRIANGLE_STRIP, 0, 4);\n const { width, height } = this.canvas;\n const chromaSamples = Math.ceil(width / 2) * Math.ceil(height / 2);\n const yuvSize = width * height + chromaSamples * 2;\n const requiredHeight = Math.ceil(yuvSize / (width * 4));\n let yuv = new Uint8Array(4 * width * requiredHeight);\n this.gl.readPixels(0, 0, width, requiredHeight, this.gl.RGBA, this.gl.UNSIGNED_BYTE, yuv);\n yuv = yuv.subarray(0, yuvSize);\n assert(yuv[width * height] === 128);\n assert(yuv[yuv.length - 1] === 128);\n const init = {\n format: \"I420\",\n codedWidth: width,\n codedHeight: height,\n timestamp: sourceFrame.timestamp,\n duration: sourceFrame.duration ?? void 0,\n transfer: [yuv.buffer]\n };\n return new VideoFrame(yuv, init);\n }\n updateCpu(sourceFrame) {\n if (!this.worker) {\n const blob = new Blob([`(${colorAlphaSplitterWorkerCode.toString()})()`], { type: \"application/javascript\" });\n const url2 = URL.createObjectURL(blob);\n this.worker = new Worker(url2);\n URL.revokeObjectURL(url2);\n this.worker.addEventListener(\"message\", (event) => {\n const data = event.data;\n const pending2 = this.pendingRequests.get(data.id);\n if (!pending2) {\n return;\n }\n this.pendingRequests.delete(data.id);\n if (\"error\" in data) {\n pending2.reject(new Error(data.error));\n } else {\n pending2.resolve({ colorFrame: data.colorFrame, alphaFrame: data.alphaFrame });\n }\n });\n this.worker.addEventListener(\"error\", (event) => {\n const error = new Error(event.message || \"Color/alpha splitter worker error.\");\n for (const pending2 of this.pendingRequests.values()) {\n pending2.reject(error);\n }\n this.pendingRequests.clear();\n });\n }\n const id = this.nextRequestId++;\n const pending = promiseWithResolvers();\n this.pendingRequests.set(id, pending);\n this.worker.postMessage({ id, sourceFrame }, { transfer: [sourceFrame] });\n return pending.promise;\n }\n close() {\n this.gl?.getExtension(\"WEBGL_lose_context\")?.loseContext();\n this.gl = null;\n this.canvas = null;\n this.worker?.terminate();\n this.worker = null;\n const error = new Error(\"Color/alpha splitter closed.\");\n for (const pending of this.pendingRequests.values()) {\n pending.reject(error);\n }\n this.pendingRequests.clear();\n }\n};\nColorAlphaSplitter.forceCpu = true;\nvar colorAlphaSplitterWorkerCode = () => {\n let cpuSourceBuffer = null;\n let chain = Promise.resolve();\n self.addEventListener(\"message\", (event) => {\n const { id, sourceFrame } = event.data;\n chain = chain.then(async () => {\n try {\n const { colorFrame, alphaFrame } = await split(sourceFrame);\n self.postMessage({ id, colorFrame, alphaFrame }, { transfer: [colorFrame, alphaFrame] });\n } catch (error) {\n self.postMessage({ id, error: error.message });\n } finally {\n sourceFrame.close();\n }\n });\n });\n const split = async (sourceFrame) => {\n const format = sourceFrame.format;\n if (!format) {\n throw new Error(\"CPU color/alpha splitting requires a known VideoFrame format.\");\n }\n const width = sourceFrame.codedWidth;\n const height = sourceFrame.codedHeight;\n const sourceSize = sourceFrame.allocationSize();\n if (!cpuSourceBuffer || cpuSourceBuffer.byteLength !== sourceSize) {\n cpuSourceBuffer = new Uint8Array(sourceSize);\n }\n await sourceFrame.copyTo(cpuSourceBuffer);\n if (format === \"RGBA\" || format === \"BGRA\") {\n return splitInterleavedRgba(cpuSourceBuffer, width, height, format, sourceFrame);\n } else if (format === \"I420A\" || format === \"I420AP10\" || format === \"I420AP12\" || format === \"I422A\" || format === \"I422AP10\" || format === \"I422AP12\" || format === \"I444A\" || format === \"I444AP10\" || format === \"I444AP12\") {\n return splitPlanarYuvA(cpuSourceBuffer, width, height, format, sourceFrame);\n }\n throw new Error(`CPU color/alpha splitting does not support format '${format}'.`);\n };\n const splitInterleavedRgba = (source, width, height, format, sourceFrame) => {\n const pixelCount = width * height;\n const chromaW = Math.ceil(width / 2);\n const chromaH = Math.ceil(height / 2);\n const alphaSize = pixelCount + chromaW * chromaH * 2;\n const alphaBuffer = new Uint8Array(alphaSize);\n for (let i2 = 0, j = 3; i2 < pixelCount; i2++, j += 4) {\n alphaBuffer[i2] = source[j];\n }\n alphaBuffer.fill(128, pixelCount);\n const colorFrame = new VideoFrame(source, {\n format: format === \"RGBA\" ? \"RGBX\" : \"BGRX\",\n codedWidth: width,\n codedHeight: height,\n timestamp: sourceFrame.timestamp,\n duration: sourceFrame.duration ?? void 0\n // No transfer!\n });\n const alphaInit = {\n format: \"I420\",\n codedWidth: width,\n codedHeight: height,\n timestamp: sourceFrame.timestamp,\n duration: sourceFrame.duration ?? void 0,\n transfer: [alphaBuffer.buffer]\n };\n const alphaFrame = new VideoFrame(alphaBuffer, alphaInit);\n return { colorFrame, alphaFrame };\n };\n const splitPlanarYuvA = (source, width, height, format, sourceFrame) => {\n const is10 = format.includes(\"P10\");\n const is12 = format.includes(\"P12\");\n const bytesPerSample = is10 || is12 ? 2 : 1;\n let chromaW;\n let chromaH;\n if (format.startsWith(\"I420\")) {\n chromaW = Math.ceil(width / 2);\n chromaH = Math.ceil(height / 2);\n } else if (format.startsWith(\"I422\")) {\n chromaW = Math.ceil(width / 2);\n chromaH = height;\n } else {\n chromaW = width;\n chromaH = height;\n }\n const ySamples = width * height;\n const uvSamples = chromaW * chromaH;\n const yBytes = ySamples * bytesPerSample;\n const uvBytes = uvSamples * bytesPerSample;\n const aBytes = ySamples * bytesPerSample;\n const colorBytes = yBytes + uvBytes * 2;\n const colorFormat = format.replace(\"A\", \"\");\n const alphaChromaW = Math.ceil(width / 2);\n const alphaChromaH = Math.ceil(height / 2);\n const alphaUvSamples = alphaChromaW * alphaChromaH;\n const alphaUvBytes = alphaUvSamples * bytesPerSample;\n const alphaSize = aBytes + 2 * alphaUvBytes;\n const alphaBuffer = new Uint8Array(alphaSize);\n const aPlaneStart = colorBytes;\n alphaBuffer.set(source.subarray(aPlaneStart, aPlaneStart + aBytes), 0);\n const uvOffset = aBytes;\n const neutralChroma = is10 ? 512 : is12 ? 2048 : 128;\n if (bytesPerSample === 1) {\n alphaBuffer.fill(neutralChroma, uvOffset);\n } else {\n const uvView = new Uint16Array(alphaBuffer.buffer, uvOffset, 2 * alphaUvSamples);\n uvView.fill(neutralChroma);\n }\n const alphaFormat = is10 ? \"I420P10\" : is12 ? \"I420P12\" : \"I420\";\n const colorFrame = new VideoFrame(source.subarray(0, colorBytes), {\n format: colorFormat,\n codedWidth: width,\n codedHeight: height,\n timestamp: sourceFrame.timestamp,\n duration: sourceFrame.duration ?? void 0\n });\n const alphaInit = {\n format: alphaFormat,\n codedWidth: width,\n codedHeight: height,\n timestamp: sourceFrame.timestamp,\n duration: sourceFrame.duration ?? void 0,\n transfer: [alphaBuffer.buffer]\n };\n const alphaFrame = new VideoFrame(alphaBuffer, alphaInit);\n return { colorFrame, alphaFrame };\n };\n};\nvar VideoSampleSource = class extends VideoSource {\n /**\n * Creates a new {@link VideoSampleSource} whose samples are encoded according to the specified\n * {@link VideoEncodingConfig}.\n */\n constructor(encodingConfig) {\n validateVideoEncodingConfig(encodingConfig);\n super(encodingConfig.codec);\n this._encoder = new VideoEncoderWrapper(this, encodingConfig);\n }\n /**\n * Encodes a video sample (frame) and then adds it to the output.\n *\n * @returns A Promise that resolves once the output is ready to receive more samples. You should await this Promise\n * to respect writer and encoder backpressure.\n */\n add(videoSample, encodeOptions) {\n if (!(videoSample instanceof VideoSample)) {\n throw new TypeError(\"videoSample must be a VideoSample.\");\n }\n return this._encoder.add(videoSample, false, encodeOptions);\n }\n /** @internal */\n _flushAndClose(forceClose) {\n return this._encoder.flushAndClose(forceClose);\n }\n};\nvar AudioSource = class extends MediaSource {\n /** Internal constructor. */\n constructor(codec) {\n super();\n this._connectedTrack = null;\n if (!AUDIO_CODECS.includes(codec)) {\n throw new TypeError(`Invalid audio codec '${codec}'. Must be one of: ${AUDIO_CODECS.join(\", \")}.`);\n }\n this._codec = codec;\n }\n};\nvar SubtitleSource = class extends MediaSource {\n /** Internal constructor. */\n constructor(codec) {\n super();\n this._connectedTrack = null;\n if (!SUBTITLE_CODECS.includes(codec)) {\n throw new TypeError(`Invalid subtitle codec '${codec}'. Must be one of: ${SUBTITLE_CODECS.join(\", \")}.`);\n }\n this._codec = codec;\n }\n};\n\n// node_modules/mediabunny/dist/modules/src/output-format.js\nvar OutputFormat = class {\n /** Returns a list of video codecs that this output format can contain. */\n getSupportedVideoCodecs() {\n return this.getSupportedCodecs().filter((codec) => VIDEO_CODECS.includes(codec));\n }\n /** Returns a list of audio codecs that this output format can contain. */\n getSupportedAudioCodecs() {\n return this.getSupportedCodecs().filter((codec) => AUDIO_CODECS.includes(codec));\n }\n /** Returns a list of subtitle codecs that this output format can contain. */\n getSupportedSubtitleCodecs() {\n return this.getSupportedCodecs().filter((codec) => SUBTITLE_CODECS.includes(codec));\n }\n /** @internal */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n _codecUnsupportedHint(codec) {\n return \"\";\n }\n};\nvar IsobmffOutputFormat = class extends OutputFormat {\n /** Internal constructor. */\n constructor(options = {}) {\n if (!options || typeof options !== \"object\") {\n throw new TypeError(\"options must be an object.\");\n }\n if (options.fastStart !== void 0 && ![false, \"in-memory\", \"reserve\", \"fragmented\"].includes(options.fastStart)) {\n throw new TypeError(\"options.fastStart, when provided, must be false, 'in-memory', 'reserve', or 'fragmented'.\");\n }\n if (options.minimumFragmentDuration !== void 0 && (!Number.isFinite(options.minimumFragmentDuration) || options.minimumFragmentDuration < 0)) {\n throw new TypeError(\"options.minimumFragmentDuration, when provided, must be a non-negative number.\");\n }\n if (options.onFtyp !== void 0 && typeof options.onFtyp !== \"function\") {\n throw new TypeError(\"options.onFtyp, when provided, must be a function.\");\n }\n if (options.onMoov !== void 0 && typeof options.onMoov !== \"function\") {\n throw new TypeError(\"options.onMoov, when provided, must be a function.\");\n }\n if (options.onMdat !== void 0 && typeof options.onMdat !== \"function\") {\n throw new TypeError(\"options.onMdat, when provided, must be a function.\");\n }\n if (options.onMoof !== void 0 && typeof options.onMoof !== \"function\") {\n throw new TypeError(\"options.onMoof, when provided, must be a function.\");\n }\n if (options.metadataFormat !== void 0 && ![\"mdir\", \"mdta\", \"udta\", \"auto\"].includes(options.metadataFormat)) {\n throw new TypeError(\"options.metadataFormat, when provided, must be either 'auto', 'mdir', 'mdta', or 'udta'.\");\n }\n super();\n this._options = options;\n }\n getSupportedTrackCounts() {\n const max = 2 ** 32 - 1;\n return {\n video: { min: 0, max },\n audio: { min: 0, max },\n subtitle: { min: 0, max },\n total: { min: 1, max }\n };\n }\n get supportsVideoRotationMetadata() {\n return true;\n }\n get supportsTimestampedMediaData() {\n return true;\n }\n /** @internal */\n _createMuxer(output) {\n return new IsobmffMuxer(output, this);\n }\n};\nvar Mp4OutputFormat = class extends IsobmffOutputFormat {\n /** Creates a new {@link Mp4OutputFormat} configured with the specified `options`. */\n constructor(options) {\n super(options);\n }\n /** @internal */\n get _name() {\n return \"MP4\";\n }\n get fileExtension() {\n return \".mp4\";\n }\n get mimeType() {\n return \"video/mp4\";\n }\n getSupportedCodecs() {\n return [\n ...VIDEO_CODECS,\n ...NON_PCM_AUDIO_CODECS,\n // These are supported via ISO/IEC 23003-5:\n \"pcm-s16\",\n \"pcm-s16be\",\n \"pcm-s24\",\n \"pcm-s24be\",\n \"pcm-s32\",\n \"pcm-s32be\",\n \"pcm-f32\",\n \"pcm-f32be\",\n \"pcm-f64\",\n \"pcm-f64be\",\n ...SUBTITLE_CODECS\n ];\n }\n /** @internal */\n _codecUnsupportedHint(codec) {\n if (new MovOutputFormat().getSupportedCodecs().includes(codec)) {\n return \" Switching to MOV will grant support for this codec.\";\n }\n return \"\";\n }\n};\nvar CmafOutputFormat = class extends IsobmffOutputFormat {\n /** Creates a new {@link CmafOutputFormat} configured with the specified `options`. */\n constructor(options) {\n super(options);\n }\n /** @internal */\n get _name() {\n return \"CMAF\";\n }\n get fileExtension() {\n return \".m4s\";\n }\n get mimeType() {\n return \"video/mp4\";\n }\n getSupportedCodecs() {\n return [\n ...VIDEO_CODECS,\n ...NON_PCM_AUDIO_CODECS,\n // These are supported via ISO/IEC 23003-5:\n \"pcm-s16\",\n \"pcm-s16be\",\n \"pcm-s24\",\n \"pcm-s24be\",\n \"pcm-s32\",\n \"pcm-s32be\",\n \"pcm-f32\",\n \"pcm-f32be\",\n \"pcm-f64\",\n \"pcm-f64be\",\n ...SUBTITLE_CODECS\n ];\n }\n};\nvar MovOutputFormat = class extends IsobmffOutputFormat {\n /** Creates a new {@link MovOutputFormat} configured with the specified `options`. */\n constructor(options) {\n super(options);\n }\n /** @internal */\n get _name() {\n return \"MOV\";\n }\n get fileExtension() {\n return \".mov\";\n }\n get mimeType() {\n return \"video/quicktime\";\n }\n getSupportedCodecs() {\n return [\n ...VIDEO_CODECS,\n ...AUDIO_CODECS\n ];\n }\n /** @internal */\n _codecUnsupportedHint(codec) {\n if (new Mp4OutputFormat().getSupportedCodecs().includes(codec)) {\n return \" Switching to MP4 will grant support for this codec.\";\n }\n return \"\";\n }\n};\nvar MkvOutputFormat = class extends OutputFormat {\n /** Creates a new {@link MkvOutputFormat} configured with the specified `options`. */\n constructor(options = {}) {\n if (!options || typeof options !== \"object\") {\n throw new TypeError(\"options must be an object.\");\n }\n if (options.appendOnly !== void 0 && typeof options.appendOnly !== \"boolean\") {\n throw new TypeError(\"options.appendOnly, when provided, must be a boolean.\");\n }\n if (options.minimumClusterDuration !== void 0 && (!Number.isFinite(options.minimumClusterDuration) || options.minimumClusterDuration < 0)) {\n throw new TypeError(\"options.minimumClusterDuration, when provided, must be a non-negative number.\");\n }\n if (options.onEbmlHeader !== void 0 && typeof options.onEbmlHeader !== \"function\") {\n throw new TypeError(\"options.onEbmlHeader, when provided, must be a function.\");\n }\n if (options.onSegmentHeader !== void 0 && typeof options.onSegmentHeader !== \"function\") {\n throw new TypeError(\"options.onHeader, when provided, must be a function.\");\n }\n if (options.onCluster !== void 0 && typeof options.onCluster !== \"function\") {\n throw new TypeError(\"options.onCluster, when provided, must be a function.\");\n }\n super();\n this._options = options;\n }\n /** @internal */\n _createMuxer(output) {\n return new MatroskaMuxer(output, this);\n }\n /** @internal */\n get _name() {\n return \"Matroska\";\n }\n getSupportedTrackCounts() {\n const max = 127;\n return {\n video: { min: 0, max },\n audio: { min: 0, max },\n subtitle: { min: 0, max },\n total: { min: 1, max }\n };\n }\n get fileExtension() {\n return \".mkv\";\n }\n get mimeType() {\n return \"video/x-matroska\";\n }\n getSupportedCodecs() {\n return [\n ...VIDEO_CODECS,\n ...NON_PCM_AUDIO_CODECS,\n ...PCM_AUDIO_CODECS.filter((codec) => ![\"pcm-s8\", \"pcm-f32be\", \"pcm-f64be\", \"ulaw\", \"alaw\"].includes(codec)),\n ...SUBTITLE_CODECS\n ];\n }\n get supportsVideoRotationMetadata() {\n return false;\n }\n get supportsTimestampedMediaData() {\n return true;\n }\n};\nvar WebMOutputFormat = class extends MkvOutputFormat {\n /** Creates a new {@link WebMOutputFormat} configured with the specified `options`. */\n constructor(options) {\n super(options);\n }\n getSupportedCodecs() {\n return [\n ...VIDEO_CODECS.filter((codec) => [\"vp8\", \"vp9\", \"av1\"].includes(codec)),\n ...AUDIO_CODECS.filter((codec) => [\"opus\", \"vorbis\"].includes(codec)),\n ...SUBTITLE_CODECS\n ];\n }\n /** @internal */\n get _name() {\n return \"WebM\";\n }\n get fileExtension() {\n return \".webm\";\n }\n get mimeType() {\n return \"video/webm\";\n }\n /** @internal */\n _codecUnsupportedHint(codec) {\n if (new MkvOutputFormat().getSupportedCodecs().includes(codec)) {\n return \" Switching to MKV will grant support for this codec.\";\n }\n return \"\";\n }\n};\n\n// node_modules/mediabunny/dist/modules/src/output.js\nvar ALL_TRACK_TYPES = [\"video\", \"audio\", \"subtitle\"];\nvar OutputTrack = class _OutputTrack {\n /** @internal */\n constructor(id, output, type, source, metadata) {\n this.id = id;\n this.output = output;\n this.type = type;\n this.source = source;\n this.metadata = metadata;\n }\n /** Returns true if and only if this track is a video track. */\n isVideoTrack() {\n return this.type === \"video\";\n }\n /** Returns true if and only if this track is an audio track. */\n isAudioTrack() {\n return this.type === \"audio\";\n }\n /** Returns true if and only if this track is a subtitle track. */\n isSubtitleTrack() {\n return this.type === \"subtitle\";\n }\n /**\n * Returns true if and only if this track can be paired with the given other track. Pairability can be set using\n * the {@link BaseTrackMetadata.group} option.\n */\n canBePairedWith(other) {\n if (!(other instanceof _OutputTrack)) {\n throw new TypeError(\"other must be an OutputTrack.\");\n }\n if (this === other) {\n return false;\n }\n const thisGroups = toArray(this.metadata.group);\n const otherGroups = toArray(other.metadata.group);\n for (const aGroup of thisGroups) {\n const pairableInSameGroup = this.type !== other.type && otherGroups.some((bGroup) => aGroup === bGroup);\n if (pairableInSameGroup) {\n return true;\n }\n const pairableAcrossGroups = otherGroups.some((bGroup) => aGroup._pairedGroups.has(bGroup));\n if (pairableAcrossGroups) {\n return true;\n }\n }\n return false;\n }\n};\nvar OutputVideoTrack = class extends OutputTrack {\n /** @internal */\n constructor(id, output, source, metadata) {\n super(id, output, \"video\", source, metadata);\n }\n};\nvar OutputAudioTrack = class extends OutputTrack {\n /** @internal */\n constructor(id, output, source, metadata) {\n super(id, output, \"audio\", source, metadata);\n }\n};\nvar OutputSubtitleTrack = class extends OutputTrack {\n /** @internal */\n constructor(id, output, source, metadata) {\n super(id, output, \"subtitle\", source, metadata);\n }\n};\nvar OutputTrackGroup = class _OutputTrackGroup {\n /** Creates a new {@link OutputTrackGroup}. */\n constructor() {\n this._pairedGroups = /* @__PURE__ */ new Set();\n }\n /**\n * Marks this group as being pairable with another group, symmetrically. Output tracks where each track is assigned\n * to one half of a group pairing are then considered pairable.\n *\n * You cannot pair a group with itself.\n */\n pairWith(other) {\n if (!(other instanceof _OutputTrackGroup)) {\n throw new TypeError(\"other must be an OutputTrackGroup.\");\n }\n if (this === other) {\n throw new TypeError(\"Cannot pair a group with itself.\");\n }\n this._pairedGroups.add(other);\n other._pairedGroups.add(this);\n }\n};\nvar validateBaseTrackMetadata = (metadata) => {\n if (!metadata || typeof metadata !== \"object\") {\n throw new TypeError(\"metadata must be an object.\");\n }\n if (metadata.languageCode !== void 0 && !isIso639Dash2LanguageCode(metadata.languageCode)) {\n throw new TypeError(\"metadata.languageCode, when provided, must be a three-letter, ISO 639-2/T language code.\");\n }\n if (metadata.name !== void 0 && typeof metadata.name !== \"string\") {\n throw new TypeError(\"metadata.name, when provided, must be a string.\");\n }\n if (metadata.disposition !== void 0) {\n validateTrackDisposition(metadata.disposition);\n }\n if (metadata.maximumPacketCount !== void 0 && (!Number.isInteger(metadata.maximumPacketCount) || metadata.maximumPacketCount < 0)) {\n throw new TypeError(\"metadata.maximumPacketCount, when provided, must be a non-negative integer.\");\n }\n if (metadata.group !== void 0 && !(metadata.group instanceof OutputTrackGroup) && (!Array.isArray(metadata.group) || metadata.group.some((group) => !(group instanceof OutputTrackGroup)))) {\n throw new TypeError(\"metadata.group, when provided, must be an OutputTrackGroup instance or an array of OutputTrackGroup instances.\");\n }\n};\nvar Output = class extends EventEmitter {\n /**\n * The target to which the root file will be written. Throws when using {@link PathedTarget} with an async callback;\n * prefer the `'target'` event for those cases.\n */\n get target() {\n const errorMessage = \"Output.target cannot be used when using PathedTarget with an async callback. Use the 'target' event instead.\";\n if (this._rootTargetPromise) {\n throw new TypeError(errorMessage);\n }\n const rootTargetResult = this._getRootTarget();\n if (rootTargetResult instanceof Promise) {\n throw new TypeError(errorMessage);\n }\n return rootTargetResult;\n }\n /**\n * Creates a new instance of {@link Output} which can then be used to create a new media file according to the\n * specified {@link OutputOptions}.\n */\n constructor(options) {\n super();\n this.state = \"pending\";\n this.defaultTrackGroup = new OutputTrackGroup();\n this._onFinalize = null;\n this._unfinalizedTargets = /* @__PURE__ */ new Set();\n this._rootWriterPromise = null;\n this._tracks = [];\n this._startPromise = null;\n this._cancelPromise = null;\n this._finalizePromise = null;\n this._mutex = new AsyncMutex();\n this._metadataTags = {};\n this._rootTarget = null;\n this._rootTargetPromise = null;\n this._firstMediaStreamTimestamp = null;\n if (!options || typeof options !== \"object\") {\n throw new TypeError(\"options must be an object.\");\n }\n if (!(options.format instanceof OutputFormat)) {\n throw new TypeError(\"options.format must be an OutputFormat.\");\n }\n if (!(options.target instanceof Target || options.target instanceof PathedTarget)) {\n throw new TypeError(\"options.target must be a Target or a PathedTarget.\");\n }\n if (options.target instanceof Target) {\n this._rememberTarget(options.target);\n }\n if (options.initTarget !== void 0 && !(options.initTarget instanceof Target) && typeof options.initTarget !== \"function\") {\n throw new Error(\"options.initTarget, when provided, must be a Target or a function that returns or resolves to a Target.\");\n }\n if (options.onFinalize !== void 0 && typeof options.onFinalize !== \"function\") {\n throw new TypeError(\"options.onFinalize, when provided, must be a function.\");\n }\n this.format = options.format;\n this._target = options.target;\n this._onFinalize = options.onFinalize ?? null;\n this._initTarget = options.initTarget ?? null;\n if (this._initTarget instanceof Target) {\n this._rememberTarget(this._initTarget);\n }\n this._muxer = options.format._createMuxer(this);\n }\n /** @internal */\n _getTargetValidated(request) {\n assert(this._target instanceof PathedTarget);\n const result = this._target.getTarget(request);\n const handleResult = (result2) => {\n if (!(result2 instanceof Target)) {\n throw new TypeError(\"getTarget must return a Target.\");\n }\n return result2;\n };\n if (result instanceof Promise) {\n return result.then(handleResult);\n } else {\n return handleResult(result);\n }\n }\n /** @internal */\n async _getTarget(request) {\n assert(this._target instanceof PathedTarget);\n const target = await this._getTargetValidated(request);\n this._emit(\"target\", { target, request, isRoot: request.isRoot });\n if (this.state === \"canceled\") {\n await target._close();\n } else {\n this._rememberTarget(target);\n }\n return target;\n }\n /** @internal */\n _rememberTarget(target) {\n this._unfinalizedTargets.add(target);\n target.on(\"finalized\", () => this._unfinalizedTargets.delete(target), { once: true });\n }\n /** @internal */\n async _getInitTarget() {\n assert(this._initTarget !== null);\n if (this._initTarget instanceof Target) {\n return this._initTarget;\n }\n const target = await this._initTarget();\n if (this.state === \"canceled\") {\n await target._close();\n } else {\n this._rememberTarget(target);\n }\n return target;\n }\n /** @internal */\n _hasInitTarget() {\n return this._initTarget !== null;\n }\n /** @internal */\n _getRootTarget() {\n if (this._rootTarget) {\n return this._rootTarget;\n }\n if (this._rootTargetPromise) {\n return this._rootTargetPromise;\n }\n if (this._target instanceof Target) {\n this._emit(\"target\", { target: this._target, request: null, isRoot: true });\n this._rootTarget = this._target;\n return this._target;\n }\n const request = {\n path: this._target.rootPath,\n isRoot: true,\n mimeType: this.format.mimeType\n };\n const result = this._getTargetValidated(request);\n const handleResult = (target) => {\n if (this.state === \"canceled\") {\n void target._close();\n } else {\n this._rememberTarget(target);\n }\n this._emit(\"target\", { target, request, isRoot: true });\n this._rootTarget = target;\n return target;\n };\n if (result instanceof Promise) {\n return this._rootTargetPromise = result.then(handleResult);\n } else {\n return handleResult(result);\n }\n }\n /** @internal */\n _getRootWriter(isMonotonic) {\n return this._rootWriterPromise ??= (async () => {\n const target = await this._getRootTarget();\n const writer = new Writer(target, typeof isMonotonic === \"boolean\" ? isMonotonic : isMonotonic(target));\n writer.start();\n return writer;\n })();\n }\n /** Adds a video track to the output with the given source. Can only be called before the output is started. */\n addVideoTrack(source, metadata = {}) {\n if (!(source instanceof VideoSource)) {\n throw new TypeError(\"source must be a VideoSource.\");\n }\n validateBaseTrackMetadata(metadata);\n if (metadata.rotation !== void 0 && ![0, 90, 180, 270].includes(metadata.rotation)) {\n throw new TypeError(`Invalid video rotation: ${metadata.rotation}. Has to be 0, 90, 180 or 270.`);\n }\n if (!this.format.supportsVideoRotationMetadata && metadata.rotation) {\n throw new Error(`${this.format._name} does not support video rotation metadata.`);\n }\n if (metadata.frameRate !== void 0 && (!Number.isFinite(metadata.frameRate) || metadata.frameRate <= 0)) {\n throw new TypeError(`Invalid video frame rate: ${metadata.frameRate}. Must be a positive number.`);\n }\n const metadataCopy = { ...metadata };\n metadataCopy.group ??= this.defaultTrackGroup;\n return this._addTrack(new OutputVideoTrack(this._tracks.length + 1, this, source, metadataCopy));\n }\n /** Adds an audio track to the output with the given source. Can only be called before the output is started. */\n addAudioTrack(source, metadata = {}) {\n if (!(source instanceof AudioSource)) {\n throw new TypeError(\"source must be an AudioSource.\");\n }\n validateBaseTrackMetadata(metadata);\n const metadataCopy = { ...metadata };\n metadataCopy.group ??= this.defaultTrackGroup;\n return this._addTrack(new OutputAudioTrack(this._tracks.length + 1, this, source, metadataCopy));\n }\n /** Adds a subtitle track to the output with the given source. Can only be called before the output is started. */\n addSubtitleTrack(source, metadata = {}) {\n if (!(source instanceof SubtitleSource)) {\n throw new TypeError(\"source must be a SubtitleSource.\");\n }\n validateBaseTrackMetadata(metadata);\n const metadataCopy = { ...metadata };\n metadataCopy.group ??= this.defaultTrackGroup;\n return this._addTrack(new OutputSubtitleTrack(this._tracks.length + 1, this, source, metadataCopy));\n }\n /**\n * Sets descriptive metadata tags about the media file, such as title, author, date, or cover art. When called\n * multiple times, only the metadata from the last call will be used.\n *\n * Can only be called before the output is started.\n */\n setMetadataTags(tags) {\n validateMetadataTags(tags);\n if (this.state !== \"pending\") {\n throw new Error(\"Cannot set metadata tags after output has been started or canceled.\");\n }\n this._metadataTags = tags;\n }\n /** @internal */\n _addTrack(track) {\n if (this.state !== \"pending\") {\n throw new Error(\"Cannot add track after output has been started or canceled.\");\n }\n if (track.source._connectedTrack) {\n throw new Error(\"Source is already used for a track.\");\n }\n const supportedTrackCounts = this.format.getSupportedTrackCounts();\n const presentTracksOfThisType = this._tracks.reduce((count, t2) => count + (t2.type === track.type ? 1 : 0), 0);\n const maxCount = supportedTrackCounts[track.type].max;\n if (presentTracksOfThisType === maxCount) {\n throw new Error(maxCount === 0 ? `${this.format._name} does not support ${track.type} tracks.` : `${this.format._name} does not support more than ${maxCount} ${track.type} track${maxCount === 1 ? \"\" : \"s\"}.`);\n }\n const maxTotalCount = supportedTrackCounts.total.max;\n if (this._tracks.length === maxTotalCount) {\n throw new Error(`${this.format._name} does not support more than ${maxTotalCount} tracks${maxTotalCount === 1 ? \"\" : \"s\"} in total.`);\n }\n if (track.isVideoTrack()) {\n const supportedVideoCodecs = this.format.getSupportedVideoCodecs();\n if (supportedVideoCodecs.length === 0) {\n throw new Error(`${this.format._name} does not support video tracks.` + this.format._codecUnsupportedHint(track.source._codec));\n } else if (!supportedVideoCodecs.includes(track.source._codec)) {\n 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));\n }\n } else if (track.isAudioTrack()) {\n const supportedAudioCodecs = this.format.getSupportedAudioCodecs();\n if (supportedAudioCodecs.length === 0) {\n throw new Error(`${this.format._name} does not support audio tracks.` + this.format._codecUnsupportedHint(track.source._codec));\n } else if (!supportedAudioCodecs.includes(track.source._codec)) {\n 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));\n }\n } else if (track.isSubtitleTrack()) {\n const supportedSubtitleCodecs = this.format.getSupportedSubtitleCodecs();\n if (supportedSubtitleCodecs.length === 0) {\n throw new Error(`${this.format._name} does not support subtitle tracks.` + this.format._codecUnsupportedHint(track.source._codec));\n } else if (!supportedSubtitleCodecs.includes(track.source._codec)) {\n 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));\n }\n }\n this._tracks.push(track);\n track.source._connectedTrack = track;\n return track;\n }\n /**\n * Starts the creation of the output file. This method should be called after all tracks have been added. Only after\n * the output has started can media samples be added to the tracks.\n *\n * @returns A promise that resolves when the output has successfully started and is ready to receive media samples.\n */\n async start() {\n const supportedTrackCounts = this.format.getSupportedTrackCounts();\n for (const trackType of ALL_TRACK_TYPES) {\n const presentTracksOfThisType = this._tracks.reduce((count, track) => count + (track.type === trackType ? 1 : 0), 0);\n const minCount = supportedTrackCounts[trackType].min;\n if (presentTracksOfThisType < minCount) {\n 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\"}.`);\n }\n }\n const totalMinCount = supportedTrackCounts.total.min;\n if (this._tracks.length < totalMinCount) {\n 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\"}.`);\n }\n if (this.state === \"canceled\") {\n throw new Error(\"Output has been canceled.\");\n }\n if (this._startPromise) {\n Logging._warn(\"Output has already been started.\");\n return this._startPromise;\n }\n return this._startPromise = (async () => {\n this.state = \"started\";\n const release = await this._mutex.acquire();\n try {\n await this._muxer.start();\n const promises = this._tracks.map((track) => track.source._start());\n await Promise.all(promises);\n } finally {\n release();\n }\n })();\n }\n /**\n * Resolves with the full MIME type of the output file, including track codecs.\n *\n * The returned promise will resolve only once the precise codec strings of all tracks are known.\n */\n getMimeType() {\n return this._muxer.getMimeType();\n }\n /**\n * Cancels the creation of the output file, releasing internal resources like encoders and preventing further\n * samples from being added.\n *\n * @returns A promise that resolves once all internal resources have been released.\n */\n async cancel() {\n if (this._cancelPromise) {\n Logging._warn(\"Output has already been canceled.\");\n return this._cancelPromise;\n } else if (this.state === \"finalizing\" || this.state === \"finalized\") {\n if (this.state === \"finalized\") {\n Logging._warn(\"Output has already been finalized.\");\n }\n return;\n }\n return this._cancelPromise = (async () => {\n this.state = \"canceled\";\n const release = await this._mutex.acquire();\n try {\n const promises = this._tracks.map((x) => x.source._flushOrWaitForOngoingClose(true));\n await Promise.all(promises);\n await Promise.all([...this._unfinalizedTargets].map((target) => target._close()));\n this._unfinalizedTargets.clear();\n } finally {\n release();\n }\n })();\n }\n /**\n * Finalizes the output file. This method must be called after all media samples across all tracks have been added.\n * Once the Promise returned by this method completes, the output file is ready.\n */\n async finalize() {\n if (this.state === \"pending\") {\n throw new Error(\"Cannot finalize before starting.\");\n }\n if (this.state === \"canceled\") {\n throw new Error(\"Cannot finalize after canceling.\");\n }\n if (this._finalizePromise) {\n Logging._warn(\"Output has already been finalized.\");\n return this._finalizePromise;\n }\n return this._finalizePromise = (async () => {\n this.state = \"finalizing\";\n const release = await this._mutex.acquire();\n try {\n const promises = this._tracks.map((x) => x.source._flushOrWaitForOngoingClose(false));\n await Promise.all(promises);\n await this._muxer.finalize();\n if (this._rootWriterPromise) {\n const rootWriter = await this._rootWriterPromise;\n if (!rootWriter.finalized) {\n await rootWriter.flush();\n await rootWriter.finalize();\n }\n }\n if (this._onFinalize) {\n await this._onFinalize();\n }\n this.state = \"finalized\";\n } finally {\n release();\n }\n })();\n }\n};\n\n// node_modules/mediabunny/dist/modules/src/index.js\nvar MEDIABUNNY_LOADED_SYMBOL = /* @__PURE__ */ Symbol.for(\"mediabunny loaded\");\nif (globalThis[MEDIABUNNY_LOADED_SYMBOL]) {\n Logging._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.\");\n}\nglobalThis[MEDIABUNNY_LOADED_SYMBOL] = true;\n\n// packages/video-conversion/src/index.ts\nvar inProgressOperations = /* @__PURE__ */ new Set();\nvar GIF_DEFAULT_FRAME_DURATION_US = 1e5;\nvar UNSUPPORTED_ERROR_PREFIX = \"Unsupported\";\nvar SIZE_LIMIT_ERROR_PREFIX = `${UNSUPPORTED_ERROR_PREFIX}: GIF exceeds maximum conversion size`;\nvar DEFAULT_MAX_TOTAL_PIXELS = 3e8;\nvar operationLock = Promise.resolve();\nasync function cancelOperations(id) {\n return inProgressOperations.delete(id);\n}\nfunction padToEven(value) {\n return value % 2 === 0 ? value : value + 1;\n}\nasync function convertGifToVideo(id, gifSource, outputMimeType, maxDimensions, maxTotalPixels) {\n inProgressOperations.add(id);\n const previousLock = operationLock;\n let releaseLock = () => {\n };\n operationLock = new Promise((resolve) => {\n releaseLock = resolve;\n });\n try {\n await previousLock;\n if (!inProgressOperations.has(id)) {\n throw new Error(\"Operation cancelled\");\n }\n if (typeof ImageDecoder === \"undefined\" || typeof VideoEncoder === \"undefined\") {\n throw new Error(\n `${UNSUPPORTED_ERROR_PREFIX}: WebCodecs unavailable`\n );\n }\n const isWebm = outputMimeType === \"video/webm\";\n const codec = isWebm ? \"vp9\" : \"avc\";\n if (!await canEncodeVideo(codec)) {\n throw new Error(\n `${UNSUPPORTED_ERROR_PREFIX}: encoder codec not supported`\n );\n }\n if (!inProgressOperations.has(id)) {\n throw new Error(\"Operation cancelled\");\n }\n const data = gifSource instanceof ArrayBuffer ? gifSource : await gifSource.arrayBuffer();\n if (!inProgressOperations.has(id)) {\n throw new Error(\"Operation cancelled\");\n }\n const decoder = new ImageDecoder({\n data,\n type: \"image/gif\"\n });\n try {\n await decoder.tracks.ready;\n if (!inProgressOperations.has(id)) {\n throw new Error(\"Operation cancelled\");\n }\n const track = decoder.tracks.selectedTrack;\n const frameCount = track?.frameCount ?? 0;\n if (frameCount === 0) {\n throw new Error(\"GIF contains no decodable frames\");\n }\n const pixelBudget = maxTotalPixels ?? DEFAULT_MAX_TOTAL_PIXELS;\n if (pixelBudget > 0) {\n const { image: probe } = await decoder.decode({\n frameIndex: 0\n });\n const probeWidth = probe.displayWidth;\n const probeHeight = probe.displayHeight;\n probe.close();\n if (!inProgressOperations.has(id)) {\n throw new Error(\"Operation cancelled\");\n }\n const totalPixels = probeWidth * probeHeight * frameCount;\n if (totalPixels > pixelBudget) {\n throw new Error(\n `${SIZE_LIMIT_ERROR_PREFIX} (${probeWidth}x${probeHeight} x ${frameCount} frames = ${totalPixels} pixels; limit is ${pixelBudget})`\n );\n }\n }\n const source = new VideoSampleSource({\n codec,\n bitrate: QUALITY_HIGH,\n /*\n * A sparser key frame cadence than mediabunny's 2s default\n * roughly halves the output size for long GIFs at no\n * encode-time or quality cost. These looping, autoplaying\n * GIF replacements don't need fine seek granularity.\n */\n keyFrameInterval: 10\n });\n const target = new BufferTarget();\n const output = new Output({\n format: isWebm ? new WebMOutputFormat() : new Mp4OutputFormat(),\n target\n });\n output.addVideoTrack(source);\n await output.start();\n let timestampSec = 0;\n for (let i2 = 0; i2 < frameCount; i2++) {\n if (!inProgressOperations.has(id)) {\n throw new Error(\"Operation cancelled\");\n }\n const { image } = await decoder.decode({ frameIndex: i2 });\n const durationUs = image.duration ?? GIF_DEFAULT_FRAME_DURATION_US;\n const durationSec = durationUs / 1e6;\n const srcW = image.displayWidth;\n const srcH = image.displayHeight;\n let targetW = srcW;\n let targetH = srcH;\n if (maxDimensions && (srcW > maxDimensions || srcH > maxDimensions)) {\n const scale = Math.min(\n maxDimensions / srcW,\n maxDimensions / srcH\n );\n targetW = Math.round(srcW * scale);\n targetH = Math.round(srcH * scale);\n }\n targetW = padToEven(targetW);\n targetH = padToEven(targetH);\n let frameForEncode = image;\n if (targetW !== srcW || targetH !== srcH) {\n const canvas = new OffscreenCanvas(targetW, targetH);\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) {\n throw new Error(\"Failed to create 2D canvas context\");\n }\n ctx.drawImage(image, 0, 0, targetW, targetH);\n frameForEncode = new VideoFrame(canvas, {\n timestamp: Math.round(timestampSec * 1e6),\n duration: durationUs\n });\n image.close();\n }\n const sample = new VideoSample(frameForEncode, {\n timestamp: timestampSec,\n duration: durationSec\n });\n try {\n await source.add(sample);\n } finally {\n sample.close();\n frameForEncode.close();\n }\n timestampSec += durationSec;\n }\n await output.finalize();\n const out = target.buffer;\n if (!out || out.byteLength === 0) {\n throw new Error(\"Encoder produced empty output\");\n }\n return out;\n } finally {\n decoder.close();\n }\n } finally {\n inProgressOperations.delete(id);\n releaseLock();\n }\n}\n\n// packages/video-conversion/src/worker.ts\nvar api = {\n cancelOperations,\n convertGifToVideo\n};\nexpose(api);\n/*! Bundled license information:\n\nmediabunny/dist/modules/src/misc.js:\nmediabunny/dist/modules/src/logging.js:\nmediabunny/dist/modules/src/metadata.js:\nmediabunny/dist/modules/shared/bitstream.js:\nmediabunny/dist/modules/shared/aac-misc.js:\nmediabunny/dist/modules/src/codec.js:\nmediabunny/dist/modules/shared/ac3-misc.js:\nmediabunny/dist/modules/src/codec-data.js:\nmediabunny/dist/modules/src/packet.js:\nmediabunny/dist/modules/src/isobmff/isobmff-misc.js:\nmediabunny/dist/modules/src/isobmff/isobmff-reader.js:\nmediabunny/dist/modules/src/matroska/ebml.js:\nmediabunny/dist/modules/src/matroska/matroska-misc.js:\nmediabunny/dist/modules/src/adts/adts-reader.js:\nmediabunny/dist/modules/src/sample.js:\nmediabunny/dist/modules/src/encode.js:\nmediabunny/dist/modules/src/custom-coder.js:\nmediabunny/dist/modules/src/reader.js:\nmediabunny/dist/modules/src/muxer.js:\nmediabunny/dist/modules/src/subtitles.js:\nmediabunny/dist/modules/src/isobmff/isobmff-boxes.js:\nmediabunny/dist/modules/src/writer.js:\nmediabunny/dist/modules/src/target.js:\nmediabunny/dist/modules/src/isobmff/isobmff-muxer.js:\nmediabunny/dist/modules/src/matroska/matroska-muxer.js:\nmediabunny/dist/modules/src/media-source.js:\nmediabunny/dist/modules/src/output-format.js:\nmediabunny/dist/modules/src/output.js:\nmediabunny/dist/modules/src/index.js:\n (*!\n * Copyright (c) 2026-present, Vanilagy and contributors\n *\n * This Source Code Form is subject to the terms of the Mozilla Public\n * License, v. 2.0. If a copy of the MPL was not distributed with this\n * file, You can obtain one at https://mozilla.org/MPL/2.0/.\n *)\n*/\n//# sourceMappingURL=worker.mjs.map\n";