livekit-client 2.5.4 → 2.5.6
Sign up to get free protection for your applications and to get access to all the features.
- package/dist/livekit-client.e2ee.worker.js +1 -1
- package/dist/livekit-client.e2ee.worker.js.map +1 -1
- package/dist/livekit-client.e2ee.worker.mjs +5180 -494
- package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
- package/dist/livekit-client.esm.mjs +10 -8
- package/dist/livekit-client.esm.mjs.map +1 -1
- package/dist/livekit-client.umd.js +1 -1
- package/dist/livekit-client.umd.js.map +1 -1
- package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
- package/dist/src/room/events.d.ts +2 -0
- package/dist/src/room/events.d.ts.map +1 -1
- package/dist/ts4.2/src/room/events.d.ts +2 -0
- package/package.json +1 -1
- package/src/e2ee/E2eeManager.ts +8 -8
- package/src/e2ee/worker/FrameCryptor.ts +10 -4
- package/src/e2ee/worker/e2ee.worker.ts +81 -77
- package/src/room/events.ts +2 -0
- package/src/room/participant/Participant.ts +1 -1
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"livekit-client.e2ee.worker.js","sources":["../node_modules/.pnpm/loglevel@1.9.1/node_modules/loglevel/lib/loglevel.js","../src/logger.ts","../src/e2ee/constants.ts","../src/room/errors.ts","../src/e2ee/errors.ts","../src/e2ee/events.ts","../node_modules/.pnpm/events@3.3.0/node_modules/events/events.js","../src/e2ee/utils.ts","../src/e2ee/worker/SifGuard.ts","../src/e2ee/worker/FrameCryptor.ts","../src/e2ee/worker/ParticipantKeyHandler.ts","../src/e2ee/worker/e2ee.worker.ts"],"sourcesContent":["/*\n* loglevel - https://github.com/pimterry/loglevel\n*\n* Copyright (c) 2013 Tim Perry\n* Licensed under the MIT license.\n*/\n(function (root, definition) {\n \"use strict\";\n if (typeof define === 'function' && define.amd) {\n define(definition);\n } else if (typeof module === 'object' && module.exports) {\n module.exports = definition();\n } else {\n root.log = definition();\n }\n}(this, function () {\n \"use strict\";\n\n // Slightly dubious tricks to cut down minimized file size\n var noop = function() {};\n var undefinedType = \"undefined\";\n var isIE = (typeof window !== undefinedType) && (typeof window.navigator !== undefinedType) && (\n /Trident\\/|MSIE /.test(window.navigator.userAgent)\n );\n\n var logMethods = [\n \"trace\",\n \"debug\",\n \"info\",\n \"warn\",\n \"error\"\n ];\n\n var _loggersByName = {};\n var defaultLogger = null;\n\n // Cross-browser bind equivalent that works at least back to IE6\n function bindMethod(obj, methodName) {\n var method = obj[methodName];\n if (typeof method.bind === 'function') {\n return method.bind(obj);\n } else {\n try {\n return Function.prototype.bind.call(method, obj);\n } catch (e) {\n // Missing bind shim or IE8 + Modernizr, fallback to wrapping\n return function() {\n return Function.prototype.apply.apply(method, [obj, arguments]);\n };\n }\n }\n }\n\n // Trace() doesn't print the message in IE, so for that case we need to wrap it\n function traceForIE() {\n if (console.log) {\n if (console.log.apply) {\n console.log.apply(console, arguments);\n } else {\n // In old IE, native console methods themselves don't have apply().\n Function.prototype.apply.apply(console.log, [console, arguments]);\n }\n }\n if (console.trace) console.trace();\n }\n\n // Build the best logging method possible for this env\n // Wherever possible we want to bind, not wrap, to preserve stack traces\n function realMethod(methodName) {\n if (methodName === 'debug') {\n methodName = 'log';\n }\n\n if (typeof console === undefinedType) {\n return false; // No method possible, for now - fixed later by enableLoggingWhenConsoleArrives\n } else if (methodName === 'trace' && isIE) {\n return traceForIE;\n } else if (console[methodName] !== undefined) {\n return bindMethod(console, methodName);\n } else if (console.log !== undefined) {\n return bindMethod(console, 'log');\n } else {\n return noop;\n }\n }\n\n // These private functions always need `this` to be set properly\n\n function replaceLoggingMethods() {\n /*jshint validthis:true */\n var level = this.getLevel();\n\n // Replace the actual methods.\n for (var i = 0; i < logMethods.length; i++) {\n var methodName = logMethods[i];\n this[methodName] = (i < level) ?\n noop :\n this.methodFactory(methodName, level, this.name);\n }\n\n // Define log.log as an alias for log.debug\n this.log = this.debug;\n\n // Return any important warnings.\n if (typeof console === undefinedType && level < this.levels.SILENT) {\n return \"No console available for logging\";\n }\n }\n\n // In old IE versions, the console isn't present until you first open it.\n // We build realMethod() replacements here that regenerate logging methods\n function enableLoggingWhenConsoleArrives(methodName) {\n return function () {\n if (typeof console !== undefinedType) {\n replaceLoggingMethods.call(this);\n this[methodName].apply(this, arguments);\n }\n };\n }\n\n // By default, we use closely bound real methods wherever possible, and\n // otherwise we wait for a console to appear, and then try again.\n function defaultMethodFactory(methodName, _level, _loggerName) {\n /*jshint validthis:true */\n return realMethod(methodName) ||\n enableLoggingWhenConsoleArrives.apply(this, arguments);\n }\n\n function Logger(name, factory) {\n // Private instance variables.\n var self = this;\n /**\n * The level inherited from a parent logger (or a global default). We\n * cache this here rather than delegating to the parent so that it stays\n * in sync with the actual logging methods that we have installed (the\n * parent could change levels but we might not have rebuilt the loggers\n * in this child yet).\n * @type {number}\n */\n var inheritedLevel;\n /**\n * The default level for this logger, if any. If set, this overrides\n * `inheritedLevel`.\n * @type {number|null}\n */\n var defaultLevel;\n /**\n * A user-specific level for this logger. If set, this overrides\n * `defaultLevel`.\n * @type {number|null}\n */\n var userLevel;\n\n var storageKey = \"loglevel\";\n if (typeof name === \"string\") {\n storageKey += \":\" + name;\n } else if (typeof name === \"symbol\") {\n storageKey = undefined;\n }\n\n function persistLevelIfPossible(levelNum) {\n var levelName = (logMethods[levelNum] || 'silent').toUpperCase();\n\n if (typeof window === undefinedType || !storageKey) return;\n\n // Use localStorage if available\n try {\n window.localStorage[storageKey] = levelName;\n return;\n } catch (ignore) {}\n\n // Use session cookie as fallback\n try {\n window.document.cookie =\n encodeURIComponent(storageKey) + \"=\" + levelName + \";\";\n } catch (ignore) {}\n }\n\n function getPersistedLevel() {\n var storedLevel;\n\n if (typeof window === undefinedType || !storageKey) return;\n\n try {\n storedLevel = window.localStorage[storageKey];\n } catch (ignore) {}\n\n // Fallback to cookies if local storage gives us nothing\n if (typeof storedLevel === undefinedType) {\n try {\n var cookie = window.document.cookie;\n var cookieName = encodeURIComponent(storageKey);\n var location = cookie.indexOf(cookieName + \"=\");\n if (location !== -1) {\n storedLevel = /^([^;]+)/.exec(\n cookie.slice(location + cookieName.length + 1)\n )[1];\n }\n } catch (ignore) {}\n }\n\n // If the stored level is not valid, treat it as if nothing was stored.\n if (self.levels[storedLevel] === undefined) {\n storedLevel = undefined;\n }\n\n return storedLevel;\n }\n\n function clearPersistedLevel() {\n if (typeof window === undefinedType || !storageKey) return;\n\n // Use localStorage if available\n try {\n window.localStorage.removeItem(storageKey);\n } catch (ignore) {}\n\n // Use session cookie as fallback\n try {\n window.document.cookie =\n encodeURIComponent(storageKey) + \"=; expires=Thu, 01 Jan 1970 00:00:00 UTC\";\n } catch (ignore) {}\n }\n\n function normalizeLevel(input) {\n var level = input;\n if (typeof level === \"string\" && self.levels[level.toUpperCase()] !== undefined) {\n level = self.levels[level.toUpperCase()];\n }\n if (typeof level === \"number\" && level >= 0 && level <= self.levels.SILENT) {\n return level;\n } else {\n throw new TypeError(\"log.setLevel() called with invalid level: \" + input);\n }\n }\n\n /*\n *\n * Public logger API - see https://github.com/pimterry/loglevel for details\n *\n */\n\n self.name = name;\n\n self.levels = { \"TRACE\": 0, \"DEBUG\": 1, \"INFO\": 2, \"WARN\": 3,\n \"ERROR\": 4, \"SILENT\": 5};\n\n self.methodFactory = factory || defaultMethodFactory;\n\n self.getLevel = function () {\n if (userLevel != null) {\n return userLevel;\n } else if (defaultLevel != null) {\n return defaultLevel;\n } else {\n return inheritedLevel;\n }\n };\n\n self.setLevel = function (level, persist) {\n userLevel = normalizeLevel(level);\n if (persist !== false) { // defaults to true\n persistLevelIfPossible(userLevel);\n }\n\n // NOTE: in v2, this should call rebuild(), which updates children.\n return replaceLoggingMethods.call(self);\n };\n\n self.setDefaultLevel = function (level) {\n defaultLevel = normalizeLevel(level);\n if (!getPersistedLevel()) {\n self.setLevel(level, false);\n }\n };\n\n self.resetLevel = function () {\n userLevel = null;\n clearPersistedLevel();\n replaceLoggingMethods.call(self);\n };\n\n self.enableAll = function(persist) {\n self.setLevel(self.levels.TRACE, persist);\n };\n\n self.disableAll = function(persist) {\n self.setLevel(self.levels.SILENT, persist);\n };\n\n self.rebuild = function () {\n if (defaultLogger !== self) {\n inheritedLevel = normalizeLevel(defaultLogger.getLevel());\n }\n replaceLoggingMethods.call(self);\n\n if (defaultLogger === self) {\n for (var childName in _loggersByName) {\n _loggersByName[childName].rebuild();\n }\n }\n };\n\n // Initialize all the internal levels.\n inheritedLevel = normalizeLevel(\n defaultLogger ? defaultLogger.getLevel() : \"WARN\"\n );\n var initialLevel = getPersistedLevel();\n if (initialLevel != null) {\n userLevel = normalizeLevel(initialLevel);\n }\n replaceLoggingMethods.call(self);\n }\n\n /*\n *\n * Top-level API\n *\n */\n\n defaultLogger = new Logger();\n\n defaultLogger.getLogger = function getLogger(name) {\n if ((typeof name !== \"symbol\" && typeof name !== \"string\") || name === \"\") {\n throw new TypeError(\"You must supply a name when creating a logger.\");\n }\n\n var logger = _loggersByName[name];\n if (!logger) {\n logger = _loggersByName[name] = new Logger(\n name,\n defaultLogger.methodFactory\n );\n }\n return logger;\n };\n\n // Grab the current global log variable in case of overwrite\n var _log = (typeof window !== undefinedType) ? window.log : undefined;\n defaultLogger.noConflict = function() {\n if (typeof window !== undefinedType &&\n window.log === defaultLogger) {\n window.log = _log;\n }\n\n return defaultLogger;\n };\n\n defaultLogger.getLoggers = function getLoggers() {\n return _loggersByName;\n };\n\n // ES6 default export, for compatibility\n defaultLogger['default'] = defaultLogger;\n\n return defaultLogger;\n}));\n","import * as log from 'loglevel';\n\nexport enum LogLevel {\n trace = 0,\n debug = 1,\n info = 2,\n warn = 3,\n error = 4,\n silent = 5,\n}\n\nexport enum LoggerNames {\n Default = 'livekit',\n Room = 'livekit-room',\n Participant = 'livekit-participant',\n Track = 'livekit-track',\n Publication = 'livekit-track-publication',\n Engine = 'livekit-engine',\n Signal = 'livekit-signal',\n PCManager = 'livekit-pc-manager',\n PCTransport = 'livekit-pc-transport',\n E2EE = 'lk-e2ee',\n}\n\ntype LogLevelString = keyof typeof LogLevel;\n\nexport type StructuredLogger = log.Logger & {\n trace: (msg: string, context?: object) => void;\n debug: (msg: string, context?: object) => void;\n info: (msg: string, context?: object) => void;\n warn: (msg: string, context?: object) => void;\n error: (msg: string, context?: object) => void;\n setDefaultLevel: (level: log.LogLevelDesc) => void;\n setLevel: (level: log.LogLevelDesc) => void;\n getLevel: () => number;\n};\n\nlet livekitLogger = log.getLogger('livekit');\nconst livekitLoggers = Object.values(LoggerNames).map((name) => log.getLogger(name));\n\nlivekitLogger.setDefaultLevel(LogLevel.info);\n\nexport default livekitLogger as StructuredLogger;\n\n/**\n * @internal\n */\nexport function getLogger(name: string) {\n const logger = log.getLogger(name);\n logger.setDefaultLevel(livekitLogger.getLevel());\n return logger as StructuredLogger;\n}\n\nexport function setLogLevel(level: LogLevel | LogLevelString, loggerName?: LoggerNames) {\n if (loggerName) {\n log.getLogger(loggerName).setLevel(level);\n } else {\n for (const logger of livekitLoggers) {\n logger.setLevel(level);\n }\n }\n}\n\nexport type LogExtension = (level: LogLevel, msg: string, context?: object) => void;\n\n/**\n * use this to hook into the logging function to allow sending internal livekit logs to third party services\n * if set, the browser logs will lose their stacktrace information (see https://github.com/pimterry/loglevel#writing-plugins)\n */\nexport function setLogExtension(extension: LogExtension, logger?: StructuredLogger) {\n const loggers = logger ? [logger] : livekitLoggers;\n\n loggers.forEach((logR) => {\n const originalFactory = logR.methodFactory;\n\n logR.methodFactory = (methodName, configLevel, loggerName) => {\n const rawMethod = originalFactory(methodName, configLevel, loggerName);\n\n const logLevel = LogLevel[methodName as LogLevelString];\n const needLog = logLevel >= configLevel && logLevel < LogLevel.silent;\n\n return (msg, context?: [msg: string, context: object]) => {\n if (context) rawMethod(msg, context);\n else rawMethod(msg);\n if (needLog) {\n extension(logLevel, msg, context);\n }\n };\n };\n logR.setLevel(logR.getLevel());\n });\n}\n\nexport const workerLogger = log.getLogger('lk-e2ee') as StructuredLogger;\n","import type { KeyProviderOptions } from './types';\n\nexport const ENCRYPTION_ALGORITHM = 'AES-GCM';\n\n// How many consecutive frames can fail decrypting before a particular key gets marked as invalid\nexport const DECRYPTION_FAILURE_TOLERANCE = 10;\n\n// We copy the first bytes of the VP8 payload unencrypted.\n// For keyframes this is 10 bytes, for non-keyframes (delta) 3. See\n// https://tools.ietf.org/html/rfc6386#section-9.1\n// This allows the bridge to continue detecting keyframes (only one byte needed in the JVB)\n// and is also a bit easier for the VP8 decoder (i.e. it generates funny garbage pictures\n// instead of being unable to decode).\n// This is a bit for show and we might want to reduce to 1 unconditionally in the final version.\n//\n// For audio (where frame.type is not set) we do not encrypt the opus TOC byte:\n// https://tools.ietf.org/html/rfc6716#section-3.1\nexport const UNENCRYPTED_BYTES = {\n key: 10,\n delta: 3,\n audio: 1, // frame.type is not set on audio, so this is set manually\n empty: 0,\n} as const;\n\n/* We use a 12 byte bit IV. This is signalled in plain together with the\n packet. See https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/encrypt#parameters */\nexport const IV_LENGTH = 12;\n\n// flag set to indicate that e2ee has been setup for sender/receiver;\nexport const E2EE_FLAG = 'lk_e2ee';\n\nexport const SALT = 'LKFrameEncryptionKey';\n\nexport const KEY_PROVIDER_DEFAULTS: KeyProviderOptions = {\n sharedKey: false,\n ratchetSalt: SALT,\n ratchetWindowSize: 8,\n failureTolerance: DECRYPTION_FAILURE_TOLERANCE,\n keyringSize: 16,\n} as const;\n\nexport const MAX_SIF_COUNT = 100;\nexport const MAX_SIF_DURATION = 2000;\n","import { RequestResponse_Reason } from '@livekit/protocol';\n\nexport class LivekitError extends Error {\n code: number;\n\n constructor(code: number, message?: string) {\n super(message || 'an error has occured');\n this.code = code;\n }\n}\n\nexport const enum ConnectionErrorReason {\n NotAllowed,\n ServerUnreachable,\n InternalError,\n Cancelled,\n LeaveRequest,\n}\n\nexport class ConnectionError extends LivekitError {\n status?: number;\n\n reason?: ConnectionErrorReason;\n\n constructor(message?: string, reason?: ConnectionErrorReason, status?: number) {\n super(1, message);\n this.status = status;\n this.reason = reason;\n }\n}\n\nexport class DeviceUnsupportedError extends LivekitError {\n constructor(message?: string) {\n super(21, message ?? 'device is unsupported');\n }\n}\n\nexport class TrackInvalidError extends LivekitError {\n constructor(message?: string) {\n super(20, message ?? 'track is invalid');\n }\n}\n\nexport class UnsupportedServer extends LivekitError {\n constructor(message?: string) {\n super(10, message ?? 'unsupported server');\n }\n}\n\nexport class UnexpectedConnectionState extends LivekitError {\n constructor(message?: string) {\n super(12, message ?? 'unexpected connection state');\n }\n}\n\nexport class NegotiationError extends LivekitError {\n constructor(message?: string) {\n super(13, message ?? 'unable to negotiate');\n }\n}\n\nexport class PublishDataError extends LivekitError {\n constructor(message?: string) {\n super(13, message ?? 'unable to publish data');\n }\n}\n\nexport type RequestErrorReason =\n | Exclude<RequestResponse_Reason, RequestResponse_Reason.OK>\n | 'TimeoutError';\n\nexport class SignalRequestError extends LivekitError {\n reason: RequestErrorReason;\n\n constructor(message: string, reason: RequestErrorReason) {\n super(15, message);\n this.reason = reason;\n }\n}\n\nexport enum MediaDeviceFailure {\n // user rejected permissions\n PermissionDenied = 'PermissionDenied',\n // device is not available\n NotFound = 'NotFound',\n // device is in use. On Windows, only a single tab may get access to a device at a time.\n DeviceInUse = 'DeviceInUse',\n Other = 'Other',\n}\n\nexport namespace MediaDeviceFailure {\n export function getFailure(error: any): MediaDeviceFailure | undefined {\n if (error && 'name' in error) {\n if (error.name === 'NotFoundError' || error.name === 'DevicesNotFoundError') {\n return MediaDeviceFailure.NotFound;\n }\n if (error.name === 'NotAllowedError' || error.name === 'PermissionDeniedError') {\n return MediaDeviceFailure.PermissionDenied;\n }\n if (error.name === 'NotReadableError' || error.name === 'TrackStartError') {\n return MediaDeviceFailure.DeviceInUse;\n }\n return MediaDeviceFailure.Other;\n }\n }\n}\n","import { LivekitError } from '../room/errors';\n\nexport enum CryptorErrorReason {\n InvalidKey = 0,\n MissingKey = 1,\n InternalError = 2,\n}\n\nexport class CryptorError extends LivekitError {\n reason: CryptorErrorReason;\n\n participantIdentity?: string;\n\n constructor(\n message?: string,\n reason: CryptorErrorReason = CryptorErrorReason.InternalError,\n participantIdentity?: string,\n ) {\n super(40, message);\n this.reason = reason;\n this.participantIdentity = participantIdentity;\n }\n}\n","import type Participant from '../room/participant/Participant';\nimport type { CryptorError } from './errors';\nimport type { KeyInfo } from './types';\n\nexport enum KeyProviderEvent {\n SetKey = 'setKey',\n RatchetRequest = 'ratchetRequest',\n KeyRatcheted = 'keyRatcheted',\n}\n\nexport type KeyProviderCallbacks = {\n [KeyProviderEvent.SetKey]: (keyInfo: KeyInfo) => void;\n [KeyProviderEvent.RatchetRequest]: (participantIdentity?: string, keyIndex?: number) => void;\n [KeyProviderEvent.KeyRatcheted]: (material: CryptoKey, keyIndex?: number) => void;\n};\n\nexport enum KeyHandlerEvent {\n KeyRatcheted = 'keyRatcheted',\n}\n\nexport type ParticipantKeyHandlerCallbacks = {\n [KeyHandlerEvent.KeyRatcheted]: (\n material: CryptoKey,\n participantIdentity: string,\n keyIndex?: number,\n ) => void;\n};\n\nexport enum EncryptionEvent {\n ParticipantEncryptionStatusChanged = 'participantEncryptionStatusChanged',\n EncryptionError = 'encryptionError',\n}\n\nexport type E2EEManagerCallbacks = {\n [EncryptionEvent.ParticipantEncryptionStatusChanged]: (\n enabled: boolean,\n participant: Participant,\n ) => void;\n [EncryptionEvent.EncryptionError]: (error: Error) => void;\n};\n\nexport type CryptorCallbacks = {\n [CryptorEvent.Error]: (error: CryptorError) => void;\n};\n\nexport enum CryptorEvent {\n Error = 'cryptorError',\n}\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar R = typeof Reflect === 'object' ? Reflect : null\nvar ReflectApply = R && typeof R.apply === 'function'\n ? R.apply\n : function ReflectApply(target, receiver, args) {\n return Function.prototype.apply.call(target, receiver, args);\n }\n\nvar ReflectOwnKeys\nif (R && typeof R.ownKeys === 'function') {\n ReflectOwnKeys = R.ownKeys\n} else if (Object.getOwnPropertySymbols) {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target)\n .concat(Object.getOwnPropertySymbols(target));\n };\n} else {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target);\n };\n}\n\nfunction ProcessEmitWarning(warning) {\n if (console && console.warn) console.warn(warning);\n}\n\nvar NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {\n return value !== value;\n}\n\nfunction EventEmitter() {\n EventEmitter.init.call(this);\n}\nmodule.exports = EventEmitter;\nmodule.exports.once = once;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._eventsCount = 0;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nvar defaultMaxListeners = 10;\n\nfunction checkListener(listener) {\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n}\n\nObject.defineProperty(EventEmitter, 'defaultMaxListeners', {\n enumerable: true,\n get: function() {\n return defaultMaxListeners;\n },\n set: function(arg) {\n if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {\n throw new RangeError('The value of \"defaultMaxListeners\" is out of range. It must be a non-negative number. Received ' + arg + '.');\n }\n defaultMaxListeners = arg;\n }\n});\n\nEventEmitter.init = function() {\n\n if (this._events === undefined ||\n this._events === Object.getPrototypeOf(this)._events) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n }\n\n this._maxListeners = this._maxListeners || undefined;\n};\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {\n if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {\n throw new RangeError('The value of \"n\" is out of range. It must be a non-negative number. Received ' + n + '.');\n }\n this._maxListeners = n;\n return this;\n};\n\nfunction _getMaxListeners(that) {\n if (that._maxListeners === undefined)\n return EventEmitter.defaultMaxListeners;\n return that._maxListeners;\n}\n\nEventEmitter.prototype.getMaxListeners = function getMaxListeners() {\n return _getMaxListeners(this);\n};\n\nEventEmitter.prototype.emit = function emit(type) {\n var args = [];\n for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);\n var doError = (type === 'error');\n\n var events = this._events;\n if (events !== undefined)\n doError = (doError && events.error === undefined);\n else if (!doError)\n return false;\n\n // If there is no 'error' event listener then throw.\n if (doError) {\n var er;\n if (args.length > 0)\n er = args[0];\n if (er instanceof Error) {\n // Note: The comments on the `throw` lines are intentional, they show\n // up in Node's output if this results in an unhandled exception.\n throw er; // Unhandled 'error' event\n }\n // At least give some kind of context to the user\n var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));\n err.context = er;\n throw err; // Unhandled 'error' event\n }\n\n var handler = events[type];\n\n if (handler === undefined)\n return false;\n\n if (typeof handler === 'function') {\n ReflectApply(handler, this, args);\n } else {\n var len = handler.length;\n var listeners = arrayClone(handler, len);\n for (var i = 0; i < len; ++i)\n ReflectApply(listeners[i], this, args);\n }\n\n return true;\n};\n\nfunction _addListener(target, type, listener, prepend) {\n var m;\n var events;\n var existing;\n\n checkListener(listener);\n\n events = target._events;\n if (events === undefined) {\n events = target._events = Object.create(null);\n target._eventsCount = 0;\n } else {\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (events.newListener !== undefined) {\n target.emit('newListener', type,\n listener.listener ? listener.listener : listener);\n\n // Re-assign `events` because a newListener handler could have caused the\n // this._events to be assigned to a new object\n events = target._events;\n }\n existing = events[type];\n }\n\n if (existing === undefined) {\n // Optimize the case of one listener. Don't need the extra array object.\n existing = events[type] = listener;\n ++target._eventsCount;\n } else {\n if (typeof existing === 'function') {\n // Adding the second element, need to change to array.\n existing = events[type] =\n prepend ? [listener, existing] : [existing, listener];\n // If we've already got an array, just append.\n } else if (prepend) {\n existing.unshift(listener);\n } else {\n existing.push(listener);\n }\n\n // Check for listener leak\n m = _getMaxListeners(target);\n if (m > 0 && existing.length > m && !existing.warned) {\n existing.warned = true;\n // No error code for this since it is a Warning\n // eslint-disable-next-line no-restricted-syntax\n var w = new Error('Possible EventEmitter memory leak detected. ' +\n existing.length + ' ' + String(type) + ' listeners ' +\n 'added. Use emitter.setMaxListeners() to ' +\n 'increase limit');\n w.name = 'MaxListenersExceededWarning';\n w.emitter = target;\n w.type = type;\n w.count = existing.length;\n ProcessEmitWarning(w);\n }\n }\n\n return target;\n}\n\nEventEmitter.prototype.addListener = function addListener(type, listener) {\n return _addListener(this, type, listener, false);\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.prependListener =\n function prependListener(type, listener) {\n return _addListener(this, type, listener, true);\n };\n\nfunction onceWrapper() {\n if (!this.fired) {\n this.target.removeListener(this.type, this.wrapFn);\n this.fired = true;\n if (arguments.length === 0)\n return this.listener.call(this.target);\n return this.listener.apply(this.target, arguments);\n }\n}\n\nfunction _onceWrap(target, type, listener) {\n var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };\n var wrapped = onceWrapper.bind(state);\n wrapped.listener = listener;\n state.wrapFn = wrapped;\n return wrapped;\n}\n\nEventEmitter.prototype.once = function once(type, listener) {\n checkListener(listener);\n this.on(type, _onceWrap(this, type, listener));\n return this;\n};\n\nEventEmitter.prototype.prependOnceListener =\n function prependOnceListener(type, listener) {\n checkListener(listener);\n this.prependListener(type, _onceWrap(this, type, listener));\n return this;\n };\n\n// Emits a 'removeListener' event if and only if the listener was removed.\nEventEmitter.prototype.removeListener =\n function removeListener(type, listener) {\n var list, events, position, i, originalListener;\n\n checkListener(listener);\n\n events = this._events;\n if (events === undefined)\n return this;\n\n list = events[type];\n if (list === undefined)\n return this;\n\n if (list === listener || list.listener === listener) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else {\n delete events[type];\n if (events.removeListener)\n this.emit('removeListener', type, list.listener || listener);\n }\n } else if (typeof list !== 'function') {\n position = -1;\n\n for (i = list.length - 1; i >= 0; i--) {\n if (list[i] === listener || list[i].listener === listener) {\n originalListener = list[i].listener;\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (position === 0)\n list.shift();\n else {\n spliceOne(list, position);\n }\n\n if (list.length === 1)\n events[type] = list[0];\n\n if (events.removeListener !== undefined)\n this.emit('removeListener', type, originalListener || listener);\n }\n\n return this;\n };\n\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\n\nEventEmitter.prototype.removeAllListeners =\n function removeAllListeners(type) {\n var listeners, events, i;\n\n events = this._events;\n if (events === undefined)\n return this;\n\n // not listening for removeListener, no need to emit\n if (events.removeListener === undefined) {\n if (arguments.length === 0) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n } else if (events[type] !== undefined) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else\n delete events[type];\n }\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n var keys = Object.keys(events);\n var key;\n for (i = 0; i < keys.length; ++i) {\n key = keys[i];\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = Object.create(null);\n this._eventsCount = 0;\n return this;\n }\n\n listeners = events[type];\n\n if (typeof listeners === 'function') {\n this.removeListener(type, listeners);\n } else if (listeners !== undefined) {\n // LIFO order\n for (i = listeners.length - 1; i >= 0; i--) {\n this.removeListener(type, listeners[i]);\n }\n }\n\n return this;\n };\n\nfunction _listeners(target, type, unwrap) {\n var events = target._events;\n\n if (events === undefined)\n return [];\n\n var evlistener = events[type];\n if (evlistener === undefined)\n return [];\n\n if (typeof evlistener === 'function')\n return unwrap ? [evlistener.listener || evlistener] : [evlistener];\n\n return unwrap ?\n unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);\n}\n\nEventEmitter.prototype.listeners = function listeners(type) {\n return _listeners(this, type, true);\n};\n\nEventEmitter.prototype.rawListeners = function rawListeners(type) {\n return _listeners(this, type, false);\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n if (typeof emitter.listenerCount === 'function') {\n return emitter.listenerCount(type);\n } else {\n return listenerCount.call(emitter, type);\n }\n};\n\nEventEmitter.prototype.listenerCount = listenerCount;\nfunction listenerCount(type) {\n var events = this._events;\n\n if (events !== undefined) {\n var evlistener = events[type];\n\n if (typeof evlistener === 'function') {\n return 1;\n } else if (evlistener !== undefined) {\n return evlistener.length;\n }\n }\n\n return 0;\n}\n\nEventEmitter.prototype.eventNames = function eventNames() {\n return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];\n};\n\nfunction arrayClone(arr, n) {\n var copy = new Array(n);\n for (var i = 0; i < n; ++i)\n copy[i] = arr[i];\n return copy;\n}\n\nfunction spliceOne(list, index) {\n for (; index + 1 < list.length; index++)\n list[index] = list[index + 1];\n list.pop();\n}\n\nfunction unwrapListeners(arr) {\n var ret = new Array(arr.length);\n for (var i = 0; i < ret.length; ++i) {\n ret[i] = arr[i].listener || arr[i];\n }\n return ret;\n}\n\nfunction once(emitter, name) {\n return new Promise(function (resolve, reject) {\n function errorListener(err) {\n emitter.removeListener(name, resolver);\n reject(err);\n }\n\n function resolver() {\n if (typeof emitter.removeListener === 'function') {\n emitter.removeListener('error', errorListener);\n }\n resolve([].slice.call(arguments));\n };\n\n eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });\n if (name !== 'error') {\n addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });\n }\n });\n}\n\nfunction addErrorHandlerIfEventEmitter(emitter, handler, flags) {\n if (typeof emitter.on === 'function') {\n eventTargetAgnosticAddListener(emitter, 'error', handler, flags);\n }\n}\n\nfunction eventTargetAgnosticAddListener(emitter, name, listener, flags) {\n if (typeof emitter.on === 'function') {\n if (flags.once) {\n emitter.once(name, listener);\n } else {\n emitter.on(name, listener);\n }\n } else if (typeof emitter.addEventListener === 'function') {\n // EventTarget does not have `error` event semantics like Node\n // EventEmitters, we do not listen for `error` events here.\n emitter.addEventListener(name, function wrapListener(arg) {\n // IE does not have builtin `{ once: true }` support so we\n // have to do it manually.\n if (flags.once) {\n emitter.removeEventListener(name, wrapListener);\n }\n listener(arg);\n });\n } else {\n throw new TypeError('The \"emitter\" argument must be of type EventEmitter. Received type ' + typeof emitter);\n }\n}\n","import { ENCRYPTION_ALGORITHM } from './constants';\n\nexport function isE2EESupported() {\n return isInsertableStreamSupported() || isScriptTransformSupported();\n}\n\nexport function isScriptTransformSupported() {\n // @ts-ignore\n return typeof window.RTCRtpScriptTransform !== 'undefined';\n}\n\nexport function isInsertableStreamSupported() {\n return (\n typeof window.RTCRtpSender !== 'undefined' &&\n // @ts-ignore\n typeof window.RTCRtpSender.prototype.createEncodedStreams !== 'undefined'\n );\n}\n\nexport function isVideoFrame(\n frame: RTCEncodedAudioFrame | RTCEncodedVideoFrame,\n): frame is RTCEncodedVideoFrame {\n return 'type' in frame;\n}\n\nexport async function importKey(\n keyBytes: Uint8Array | ArrayBuffer,\n algorithm: string | { name: string } = { name: ENCRYPTION_ALGORITHM },\n usage: 'derive' | 'encrypt' = 'encrypt',\n) {\n // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey\n return crypto.subtle.importKey(\n 'raw',\n keyBytes,\n algorithm,\n false,\n usage === 'derive' ? ['deriveBits', 'deriveKey'] : ['encrypt', 'decrypt'],\n );\n}\n\nexport async function createKeyMaterialFromString(password: string) {\n let enc = new TextEncoder();\n\n const keyMaterial = await crypto.subtle.importKey(\n 'raw',\n enc.encode(password),\n {\n name: 'PBKDF2',\n },\n false,\n ['deriveBits', 'deriveKey'],\n );\n\n return keyMaterial;\n}\n\nexport async function createKeyMaterialFromBuffer(cryptoBuffer: ArrayBuffer) {\n const keyMaterial = await crypto.subtle.importKey('raw', cryptoBuffer, 'HKDF', false, [\n 'deriveBits',\n 'deriveKey',\n ]);\n\n return keyMaterial;\n}\n\nfunction getAlgoOptions(algorithmName: string, salt: string) {\n const textEncoder = new TextEncoder();\n const encodedSalt = textEncoder.encode(salt);\n switch (algorithmName) {\n case 'HKDF':\n return {\n name: 'HKDF',\n salt: encodedSalt,\n hash: 'SHA-256',\n info: new ArrayBuffer(128),\n };\n case 'PBKDF2': {\n return {\n name: 'PBKDF2',\n salt: encodedSalt,\n hash: 'SHA-256',\n iterations: 100000,\n };\n }\n default:\n throw new Error(`algorithm ${algorithmName} is currently unsupported`);\n }\n}\n\n/**\n * Derives a set of keys from the master key.\n * See https://tools.ietf.org/html/draft-omara-sframe-00#section-4.3.1\n */\nexport async function deriveKeys(material: CryptoKey, salt: string) {\n const algorithmOptions = getAlgoOptions(material.algorithm.name, salt);\n\n // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey#HKDF\n // https://developer.mozilla.org/en-US/docs/Web/API/HkdfParams\n const encryptionKey = await crypto.subtle.deriveKey(\n algorithmOptions,\n material,\n {\n name: ENCRYPTION_ALGORITHM,\n length: 128,\n },\n false,\n ['encrypt', 'decrypt'],\n );\n\n return { material, encryptionKey };\n}\n\nexport function createE2EEKey(): Uint8Array {\n return window.crypto.getRandomValues(new Uint8Array(32));\n}\n\n/**\n * Ratchets a key. See\n * https://tools.ietf.org/html/draft-omara-sframe-00#section-4.3.5.1\n */\nexport async function ratchet(material: CryptoKey, salt: string): Promise<ArrayBuffer> {\n const algorithmOptions = getAlgoOptions(material.algorithm.name, salt);\n\n // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveBits\n return crypto.subtle.deriveBits(algorithmOptions, material, 256);\n}\n\nexport function needsRbspUnescaping(frameData: Uint8Array) {\n for (var i = 0; i < frameData.length - 3; i++) {\n if (frameData[i] == 0 && frameData[i + 1] == 0 && frameData[i + 2] == 3) return true;\n }\n return false;\n}\n\nexport function parseRbsp(stream: Uint8Array): Uint8Array {\n const dataOut: number[] = [];\n var length = stream.length;\n for (var i = 0; i < stream.length; ) {\n // Be careful about over/underflow here. byte_length_ - 3 can underflow, and\n // i + 3 can overflow, but byte_length_ - i can't, because i < byte_length_\n // above, and that expression will produce the number of bytes left in\n // the stream including the byte at i.\n if (length - i >= 3 && !stream[i] && !stream[i + 1] && stream[i + 2] == 3) {\n // Two rbsp bytes.\n dataOut.push(stream[i++]);\n dataOut.push(stream[i++]);\n // Skip the emulation byte.\n i++;\n } else {\n // Single rbsp byte.\n dataOut.push(stream[i++]);\n }\n }\n return new Uint8Array(dataOut);\n}\n\nconst kZerosInStartSequence = 2;\nconst kEmulationByte = 3;\n\nexport function writeRbsp(data_in: Uint8Array): Uint8Array {\n const dataOut: number[] = [];\n var numConsecutiveZeros = 0;\n for (var i = 0; i < data_in.length; ++i) {\n var byte = data_in[i];\n if (byte <= kEmulationByte && numConsecutiveZeros >= kZerosInStartSequence) {\n // Need to escape.\n dataOut.push(kEmulationByte);\n numConsecutiveZeros = 0;\n }\n dataOut.push(byte);\n if (byte == 0) {\n ++numConsecutiveZeros;\n } else {\n numConsecutiveZeros = 0;\n }\n }\n return new Uint8Array(dataOut);\n}\n","import { MAX_SIF_COUNT, MAX_SIF_DURATION } from '../constants';\n\nexport class SifGuard {\n private consecutiveSifCount = 0;\n\n private sifSequenceStartedAt: number | undefined;\n\n private lastSifReceivedAt: number = 0;\n\n private userFramesSinceSif: number = 0;\n\n recordSif() {\n this.consecutiveSifCount += 1;\n this.sifSequenceStartedAt ??= Date.now();\n this.lastSifReceivedAt = Date.now();\n }\n\n recordUserFrame() {\n if (this.sifSequenceStartedAt === undefined) {\n return;\n } else {\n this.userFramesSinceSif += 1;\n }\n if (\n // reset if we received more user frames than SIFs\n this.userFramesSinceSif > this.consecutiveSifCount ||\n // also reset if we got a new user frame and the latest SIF frame hasn't been updated in a while\n Date.now() - this.lastSifReceivedAt > MAX_SIF_DURATION\n ) {\n this.reset();\n }\n }\n\n isSifAllowed() {\n return (\n this.consecutiveSifCount < MAX_SIF_COUNT &&\n (this.sifSequenceStartedAt === undefined ||\n Date.now() - this.sifSequenceStartedAt < MAX_SIF_DURATION)\n );\n }\n\n reset() {\n this.userFramesSinceSif = 0;\n this.consecutiveSifCount = 0;\n this.sifSequenceStartedAt = undefined;\n }\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\n// TODO code inspired by https://github.com/webrtc/samples/blob/gh-pages/src/content/insertable-streams/endtoend-encryption/js/worker.js\nimport { EventEmitter } from 'events';\nimport type TypedEventEmitter from 'typed-emitter';\nimport { workerLogger } from '../../logger';\nimport type { VideoCodec } from '../../room/track/options';\nimport { ENCRYPTION_ALGORITHM, IV_LENGTH, UNENCRYPTED_BYTES } from '../constants';\nimport { CryptorError, CryptorErrorReason } from '../errors';\nimport { CryptorCallbacks, CryptorEvent } from '../events';\nimport type { DecodeRatchetOptions, KeyProviderOptions, KeySet } from '../types';\nimport { deriveKeys, isVideoFrame, needsRbspUnescaping, parseRbsp, writeRbsp } from '../utils';\nimport type { ParticipantKeyHandler } from './ParticipantKeyHandler';\nimport { SifGuard } from './SifGuard';\n\nexport const encryptionEnabledMap: Map<string, boolean> = new Map();\n\nexport interface FrameCryptorConstructor {\n new (opts?: unknown): BaseFrameCryptor;\n}\n\nexport interface TransformerInfo {\n readable: ReadableStream;\n writable: WritableStream;\n transformer: TransformStream;\n abortController: AbortController;\n}\n\nexport class BaseFrameCryptor extends (EventEmitter as new () => TypedEventEmitter<CryptorCallbacks>) {\n protected encodeFunction(\n encodedFrame: RTCEncodedVideoFrame | RTCEncodedAudioFrame,\n controller: TransformStreamDefaultController,\n ): Promise<any> {\n throw Error('not implemented for subclass');\n }\n\n protected decodeFunction(\n encodedFrame: RTCEncodedVideoFrame | RTCEncodedAudioFrame,\n controller: TransformStreamDefaultController,\n ): Promise<any> {\n throw Error('not implemented for subclass');\n }\n}\n\n/**\n * Cryptor is responsible for en-/decrypting media frames.\n * Each Cryptor instance is responsible for en-/decrypting a single mediaStreamTrack.\n */\nexport class FrameCryptor extends BaseFrameCryptor {\n private sendCounts: Map<number, number>;\n\n private participantIdentity: string | undefined;\n\n private trackId: string | undefined;\n\n private keys: ParticipantKeyHandler;\n\n private videoCodec?: VideoCodec;\n\n private rtpMap: Map<number, VideoCodec>;\n\n private keyProviderOptions: KeyProviderOptions;\n\n /**\n * used for detecting server injected unencrypted frames\n */\n private sifTrailer: Uint8Array;\n\n private sifGuard: SifGuard;\n\n private detectedCodec?: VideoCodec;\n\n constructor(opts: {\n keys: ParticipantKeyHandler;\n participantIdentity: string;\n keyProviderOptions: KeyProviderOptions;\n sifTrailer?: Uint8Array;\n }) {\n super();\n this.sendCounts = new Map();\n this.keys = opts.keys;\n this.participantIdentity = opts.participantIdentity;\n this.rtpMap = new Map();\n this.keyProviderOptions = opts.keyProviderOptions;\n this.sifTrailer = opts.sifTrailer ?? Uint8Array.from([]);\n this.sifGuard = new SifGuard();\n }\n\n private get logContext() {\n return {\n participant: this.participantIdentity,\n mediaTrackId: this.trackId,\n fallbackCodec: this.videoCodec,\n };\n }\n\n /**\n * Assign a different participant to the cryptor.\n * useful for transceiver re-use\n * @param id\n * @param keys\n */\n setParticipant(id: string, keys: ParticipantKeyHandler) {\n workerLogger.debug('setting new participant on cryptor', {\n ...this.logContext,\n participant: id,\n });\n if (this.participantIdentity) {\n workerLogger.error(\n 'cryptor has already a participant set, participant should have been unset before',\n {\n ...this.logContext,\n },\n );\n }\n this.participantIdentity = id;\n this.keys = keys;\n this.sifGuard.reset();\n }\n\n unsetParticipant() {\n workerLogger.debug('unsetting participant', this.logContext);\n this.participantIdentity = undefined;\n }\n\n isEnabled() {\n if (this.participantIdentity) {\n return encryptionEnabledMap.get(this.participantIdentity);\n } else {\n return undefined;\n }\n }\n\n getParticipantIdentity() {\n return this.participantIdentity;\n }\n\n getTrackId() {\n return this.trackId;\n }\n\n /**\n * Update the video codec used by the mediaStreamTrack\n * @param codec\n */\n setVideoCodec(codec: VideoCodec) {\n this.videoCodec = codec;\n }\n\n /**\n * rtp payload type map used for figuring out codec of payload type when encoding\n * @param map\n */\n setRtpMap(map: Map<number, VideoCodec>) {\n this.rtpMap = map;\n }\n\n setupTransform(\n operation: 'encode' | 'decode',\n readable: ReadableStream,\n writable: WritableStream,\n trackId: string,\n codec?: VideoCodec,\n ) {\n if (codec) {\n workerLogger.info('setting codec on cryptor to', { codec });\n this.videoCodec = codec;\n }\n\n workerLogger.debug('Setting up frame cryptor transform', {\n operation,\n passedTrackId: trackId,\n codec,\n ...this.logContext,\n });\n\n const transformFn = operation === 'encode' ? this.encodeFunction : this.decodeFunction;\n const transformStream = new TransformStream({\n transform: transformFn.bind(this),\n });\n\n readable\n .pipeThrough(transformStream)\n .pipeTo(writable)\n .catch((e) => {\n workerLogger.warn(e);\n this.emit(\n CryptorEvent.Error,\n e instanceof CryptorError\n ? e\n : new CryptorError(e.message, undefined, this.participantIdentity),\n );\n });\n this.trackId = trackId;\n }\n\n setSifTrailer(trailer: Uint8Array) {\n workerLogger.debug('setting SIF trailer', { ...this.logContext, trailer });\n this.sifTrailer = trailer;\n }\n\n /**\n * Function that will be injected in a stream and will encrypt the given encoded frames.\n *\n * @param {RTCEncodedVideoFrame|RTCEncodedAudioFrame} encodedFrame - Encoded video frame.\n * @param {TransformStreamDefaultController} controller - TransportStreamController.\n *\n * The VP8 payload descriptor described in\n * https://tools.ietf.org/html/rfc7741#section-4.2\n * is part of the RTP packet and not part of the frame and is not controllable by us.\n * This is fine as the SFU keeps having access to it for routing.\n *\n * The encrypted frame is formed as follows:\n * 1) Find unencrypted byte length, depending on the codec, frame type and kind.\n * 2) Form the GCM IV for the frame as described above.\n * 3) Encrypt the rest of the frame using AES-GCM.\n * 4) Allocate space for the encrypted frame.\n * 5) Copy the unencrypted bytes to the start of the encrypted frame.\n * 6) Append the ciphertext to the encrypted frame.\n * 7) Append the IV.\n * 8) Append a single byte for the key identifier.\n * 9) Enqueue the encrypted frame for sending.\n */\n protected async encodeFunction(\n encodedFrame: RTCEncodedVideoFrame | RTCEncodedAudioFrame,\n controller: TransformStreamDefaultController,\n ) {\n if (\n !this.isEnabled() ||\n // skip for encryption for empty dtx frames\n encodedFrame.data.byteLength === 0\n ) {\n return controller.enqueue(encodedFrame);\n }\n const keySet = this.keys.getKeySet();\n if (!keySet) {\n throw new TypeError(\n `key set not found for ${\n this.participantIdentity\n } at index ${this.keys.getCurrentKeyIndex()}`,\n );\n }\n const { encryptionKey } = keySet;\n const keyIndex = this.keys.getCurrentKeyIndex();\n\n if (encryptionKey) {\n const iv = this.makeIV(\n encodedFrame.getMetadata().synchronizationSource ?? -1,\n encodedFrame.timestamp,\n );\n let frameInfo = this.getUnencryptedBytes(encodedFrame);\n\n // Thіs is not encrypted and contains the VP8 payload descriptor or the Opus TOC byte.\n const frameHeader = new Uint8Array(encodedFrame.data, 0, frameInfo.unencryptedBytes);\n\n // Frame trailer contains the R|IV_LENGTH and key index\n const frameTrailer = new Uint8Array(2);\n\n frameTrailer[0] = IV_LENGTH;\n frameTrailer[1] = keyIndex;\n\n // Construct frame trailer. Similar to the frame header described in\n // https://tools.ietf.org/html/draft-omara-sframe-00#section-4.2\n // but we put it at the end.\n //\n // ---------+-------------------------+-+---------+----\n // payload |IV...(length = IV_LENGTH)|R|IV_LENGTH|KID |\n // ---------+-------------------------+-+---------+----\n try {\n const cipherText = await crypto.subtle.encrypt(\n {\n name: ENCRYPTION_ALGORITHM,\n iv,\n additionalData: new Uint8Array(encodedFrame.data, 0, frameHeader.byteLength),\n },\n encryptionKey,\n new Uint8Array(encodedFrame.data, frameInfo.unencryptedBytes),\n );\n\n let newDataWithoutHeader = new Uint8Array(\n cipherText.byteLength + iv.byteLength + frameTrailer.byteLength,\n );\n newDataWithoutHeader.set(new Uint8Array(cipherText)); // add ciphertext.\n newDataWithoutHeader.set(new Uint8Array(iv), cipherText.byteLength); // append IV.\n newDataWithoutHeader.set(frameTrailer, cipherText.byteLength + iv.byteLength); // append frame trailer.\n\n if (frameInfo.isH264) {\n newDataWithoutHeader = writeRbsp(newDataWithoutHeader);\n }\n\n var newData = new Uint8Array(frameHeader.byteLength + newDataWithoutHeader.byteLength);\n newData.set(frameHeader);\n newData.set(newDataWithoutHeader, frameHeader.byteLength);\n\n encodedFrame.data = newData.buffer;\n\n return controller.enqueue(encodedFrame);\n } catch (e: any) {\n // TODO: surface this to the app.\n workerLogger.error(e);\n }\n } else {\n workerLogger.debug('failed to encrypt, emitting error', this.logContext);\n this.emit(\n CryptorEvent.Error,\n new CryptorError(\n `encryption key missing for encoding`,\n CryptorErrorReason.MissingKey,\n this.participantIdentity,\n ),\n );\n }\n }\n\n /**\n * Function that will be injected in a stream and will decrypt the given encoded frames.\n *\n * @param {RTCEncodedVideoFrame|RTCEncodedAudioFrame} encodedFrame - Encoded video frame.\n * @param {TransformStreamDefaultController} controller - TransportStreamController.\n */\n protected async decodeFunction(\n encodedFrame: RTCEncodedVideoFrame | RTCEncodedAudioFrame,\n controller: TransformStreamDefaultController,\n ) {\n if (\n !this.isEnabled() ||\n // skip for decryption for empty dtx frames\n encodedFrame.data.byteLength === 0\n ) {\n workerLogger.debug('skipping empty frame', this.logContext);\n this.sifGuard.recordUserFrame();\n return controller.enqueue(encodedFrame);\n }\n\n if (isFrameServerInjected(encodedFrame.data, this.sifTrailer)) {\n workerLogger.debug('enqueue SIF', this.logContext);\n this.sifGuard.recordSif();\n\n if (this.sifGuard.isSifAllowed()) {\n encodedFrame.data = encodedFrame.data.slice(\n 0,\n encodedFrame.data.byteLength - this.sifTrailer.byteLength,\n );\n return controller.enqueue(encodedFrame);\n } else {\n workerLogger.warn('SIF limit reached, dropping frame');\n return;\n }\n } else {\n this.sifGuard.recordUserFrame();\n }\n const data = new Uint8Array(encodedFrame.data);\n const keyIndex = data[encodedFrame.data.byteLength - 1];\n\n if (this.keys.getKeySet(keyIndex) && this.keys.hasValidKey) {\n try {\n const decodedFrame = await this.decryptFrame(encodedFrame, keyIndex);\n this.keys.decryptionSuccess();\n if (decodedFrame) {\n return controller.enqueue(decodedFrame);\n }\n } catch (error) {\n if (error instanceof CryptorError && error.reason === CryptorErrorReason.InvalidKey) {\n // emit an error if the key handler thinks we have a valid key\n if (this.keys.hasValidKey) {\n this.emit(CryptorEvent.Error, error);\n this.keys.decryptionFailure();\n }\n } else {\n workerLogger.warn('decoding frame failed', { error });\n }\n }\n } else if (!this.keys.getKeySet(keyIndex) && this.keys.hasValidKey) {\n // emit an error if the key index is out of bounds but the key handler thinks we still have a valid key\n workerLogger.warn(`skipping decryption due to missing key at index ${keyIndex}`);\n this.emit(\n CryptorEvent.Error,\n new CryptorError(\n `missing key at index ${keyIndex} for participant ${this.participantIdentity}`,\n CryptorErrorReason.MissingKey,\n this.participantIdentity,\n ),\n );\n this.keys.decryptionFailure();\n }\n }\n\n /**\n * Function that will decrypt the given encoded frame. If the decryption fails, it will\n * ratchet the key for up to RATCHET_WINDOW_SIZE times.\n */\n private async decryptFrame(\n encodedFrame: RTCEncodedVideoFrame | RTCEncodedAudioFrame,\n keyIndex: number,\n initialMaterial: KeySet | undefined = undefined,\n ratchetOpts: DecodeRatchetOptions = { ratchetCount: 0 },\n ): Promise<RTCEncodedVideoFrame | RTCEncodedAudioFrame | undefined> {\n const keySet = this.keys.getKeySet(keyIndex);\n if (!ratchetOpts.encryptionKey && !keySet) {\n throw new TypeError(`no encryption key found for decryption of ${this.participantIdentity}`);\n }\n let frameInfo = this.getUnencryptedBytes(encodedFrame);\n\n // Construct frame trailer. Similar to the frame header described in\n // https://tools.ietf.org/html/draft-omara-sframe-00#section-4.2\n // but we put it at the end.\n //\n // ---------+-------------------------+-+---------+----\n // payload |IV...(length = IV_LENGTH)|R|IV_LENGTH|KID |\n // ---------+-------------------------+-+---------+----\n\n try {\n const frameHeader = new Uint8Array(encodedFrame.data, 0, frameInfo.unencryptedBytes);\n var encryptedData = new Uint8Array(\n encodedFrame.data,\n frameHeader.length,\n encodedFrame.data.byteLength - frameHeader.length,\n );\n if (frameInfo.isH264 && needsRbspUnescaping(encryptedData)) {\n encryptedData = parseRbsp(encryptedData);\n const newUint8 = new Uint8Array(frameHeader.byteLength + encryptedData.byteLength);\n newUint8.set(frameHeader);\n newUint8.set(encryptedData, frameHeader.byteLength);\n encodedFrame.data = newUint8.buffer;\n }\n\n const frameTrailer = new Uint8Array(encodedFrame.data, encodedFrame.data.byteLength - 2, 2);\n\n const ivLength = frameTrailer[0];\n const iv = new Uint8Array(\n encodedFrame.data,\n encodedFrame.data.byteLength - ivLength - frameTrailer.byteLength,\n ivLength,\n );\n\n const cipherTextStart = frameHeader.byteLength;\n const cipherTextLength =\n encodedFrame.data.byteLength -\n (frameHeader.byteLength + ivLength + frameTrailer.byteLength);\n\n const plainText = await crypto.subtle.decrypt(\n {\n name: ENCRYPTION_ALGORITHM,\n iv,\n additionalData: new Uint8Array(encodedFrame.data, 0, frameHeader.byteLength),\n },\n ratchetOpts.encryptionKey ?? keySet!.encryptionKey,\n new Uint8Array(encodedFrame.data, cipherTextStart, cipherTextLength),\n );\n\n const newData = new ArrayBuffer(frameHeader.byteLength + plainText.byteLength);\n const newUint8 = new Uint8Array(newData);\n\n newUint8.set(new Uint8Array(encodedFrame.data, 0, frameHeader.byteLength));\n newUint8.set(new Uint8Array(plainText), frameHeader.byteLength);\n\n encodedFrame.data = newData;\n\n return encodedFrame;\n } catch (error: any) {\n if (this.keyProviderOptions.ratchetWindowSize > 0) {\n if (ratchetOpts.ratchetCount < this.keyProviderOptions.ratchetWindowSize) {\n workerLogger.debug(\n `ratcheting key attempt ${ratchetOpts.ratchetCount} of ${\n this.keyProviderOptions.ratchetWindowSize\n }, for kind ${encodedFrame instanceof RTCEncodedAudioFrame ? 'audio' : 'video'}`,\n );\n\n let ratchetedKeySet: KeySet | undefined;\n if ((initialMaterial ?? keySet) === this.keys.getKeySet(keyIndex)) {\n // only ratchet if the currently set key is still the same as the one used to decrypt this frame\n // if not, it might be that a different frame has already ratcheted and we try with that one first\n const newMaterial = await this.keys.ratchetKey(keyIndex, false);\n\n ratchetedKeySet = await deriveKeys(newMaterial, this.keyProviderOptions.ratchetSalt);\n }\n\n const frame = await this.decryptFrame(encodedFrame, keyIndex, initialMaterial || keySet, {\n ratchetCount: ratchetOpts.ratchetCount + 1,\n encryptionKey: ratchetedKeySet?.encryptionKey,\n });\n if (frame && ratchetedKeySet) {\n // before updating the keys, make sure that the keySet used for this frame is still the same as the currently set key\n // if it's not, a new key might have been set already, which we don't want to override\n if ((initialMaterial ?? keySet) === this.keys.getKeySet(keyIndex)) {\n this.keys.setKeySet(ratchetedKeySet, keyIndex, true);\n // decryption was successful, set the new key index to reflect the ratcheted key set\n this.keys.setCurrentKeyIndex(keyIndex);\n }\n }\n return frame;\n } else {\n /**\n * Because we only set a new key once decryption has been successful,\n * we can be sure that we don't need to reset the key to the initial material at this point\n * as the key has not been updated on the keyHandler instance\n */\n\n workerLogger.warn('maximum ratchet attempts exceeded');\n throw new CryptorError(\n `valid key missing for participant ${this.participantIdentity}`,\n CryptorErrorReason.InvalidKey,\n this.participantIdentity,\n );\n }\n } else {\n throw new CryptorError(\n `Decryption failed: ${error.message}`,\n CryptorErrorReason.InvalidKey,\n this.participantIdentity,\n );\n }\n }\n }\n\n /**\n * Construct the IV used for AES-GCM and sent (in plain) with the packet similar to\n * https://tools.ietf.org/html/rfc7714#section-8.1\n * It concatenates\n * - the 32 bit synchronization source (SSRC) given on the encoded frame,\n * - the 32 bit rtp timestamp given on the encoded frame,\n * - a send counter that is specific to the SSRC. Starts at a random number.\n * The send counter is essentially the pictureId but we currently have to implement this ourselves.\n * There is no XOR with a salt. Note that this IV leaks the SSRC to the receiver but since this is\n * randomly generated and SFUs may not rewrite this is considered acceptable.\n * The SSRC is used to allow demultiplexing multiple streams with the same key, as described in\n * https://tools.ietf.org/html/rfc3711#section-4.1.1\n * The RTP timestamp is 32 bits and advances by the codec clock rate (90khz for video, 48khz for\n * opus audio) every second. For video it rolls over roughly every 13 hours.\n * The send counter will advance at the frame rate (30fps for video, 50fps for 20ms opus audio)\n * every second. It will take a long time to roll over.\n *\n * See also https://developer.mozilla.org/en-US/docs/Web/API/AesGcmParams\n */\n private makeIV(synchronizationSource: number, timestamp: number) {\n const iv = new ArrayBuffer(IV_LENGTH);\n const ivView = new DataView(iv);\n\n // having to keep our own send count (similar to a picture id) is not ideal.\n if (!this.sendCounts.has(synchronizationSource)) {\n // Initialize with a random offset, similar to the RTP sequence number.\n this.sendCounts.set(synchronizationSource, Math.floor(Math.random() * 0xffff));\n }\n\n const sendCount = this.sendCounts.get(synchronizationSource) ?? 0;\n\n ivView.setUint32(0, synchronizationSource);\n ivView.setUint32(4, timestamp);\n ivView.setUint32(8, timestamp - (sendCount % 0xffff));\n\n this.sendCounts.set(synchronizationSource, sendCount + 1);\n\n return iv;\n }\n\n private getUnencryptedBytes(frame: RTCEncodedVideoFrame | RTCEncodedAudioFrame): {\n unencryptedBytes: number;\n isH264: boolean;\n } {\n var frameInfo = { unencryptedBytes: 0, isH264: false };\n if (isVideoFrame(frame)) {\n let detectedCodec = this.getVideoCodec(frame) ?? this.videoCodec;\n if (detectedCodec !== this.detectedCodec) {\n workerLogger.debug('detected different codec', {\n detectedCodec,\n oldCodec: this.detectedCodec,\n ...this.logContext,\n });\n this.detectedCodec = detectedCodec;\n }\n\n if (detectedCodec === 'av1') {\n throw new Error(`${detectedCodec} is not yet supported for end to end encryption`);\n }\n\n if (detectedCodec === 'vp8') {\n frameInfo.unencryptedBytes = UNENCRYPTED_BYTES[frame.type];\n } else if (detectedCodec === 'vp9') {\n frameInfo.unencryptedBytes = 0;\n return frameInfo;\n }\n\n const data = new Uint8Array(frame.data);\n try {\n const naluIndices = findNALUIndices(data);\n\n // if the detected codec is undefined we test whether it _looks_ like a h264 frame as a best guess\n frameInfo.isH264 =\n detectedCodec === 'h264' ||\n naluIndices.some((naluIndex) =>\n [NALUType.SLICE_IDR, NALUType.SLICE_NON_IDR].includes(parseNALUType(data[naluIndex])),\n );\n\n if (frameInfo.isH264) {\n for (const index of naluIndices) {\n let type = parseNALUType(data[index]);\n switch (type) {\n case NALUType.SLICE_IDR:\n case NALUType.SLICE_NON_IDR:\n frameInfo.unencryptedBytes = index + 2;\n return frameInfo;\n default:\n break;\n }\n }\n throw new TypeError('Could not find NALU');\n }\n } catch (e) {\n // no op, we just continue and fallback to vp8\n }\n\n frameInfo.unencryptedBytes = UNENCRYPTED_BYTES[frame.type];\n return frameInfo;\n } else {\n frameInfo.unencryptedBytes = UNENCRYPTED_BYTES.audio;\n return frameInfo;\n }\n }\n\n /**\n * inspects frame payloadtype if available and maps it to the codec specified in rtpMap\n */\n private getVideoCodec(frame: RTCEncodedVideoFrame): VideoCodec | undefined {\n if (this.rtpMap.size === 0) {\n return undefined;\n }\n const payloadType = frame.getMetadata().payloadType;\n const codec = payloadType ? this.rtpMap.get(payloadType) : undefined;\n return codec;\n }\n}\n\n/**\n * Slice the NALUs present in the supplied buffer, assuming it is already byte-aligned\n * code adapted from https://github.com/medooze/h264-frame-parser/blob/main/lib/NalUnits.ts to return indices only\n */\nexport function findNALUIndices(stream: Uint8Array): number[] {\n const result: number[] = [];\n let start = 0,\n pos = 0,\n searchLength = stream.length - 2;\n while (pos < searchLength) {\n // skip until end of current NALU\n while (\n pos < searchLength &&\n !(stream[pos] === 0 && stream[pos + 1] === 0 && stream[pos + 2] === 1)\n )\n pos++;\n if (pos >= searchLength) pos = stream.length;\n // remove trailing zeros from current NALU\n let end = pos;\n while (end > start && stream[end - 1] === 0) end--;\n // save current NALU\n if (start === 0) {\n if (end !== start) throw TypeError('byte stream contains leading data');\n } else {\n result.push(start);\n }\n // begin new NALU\n start = pos = pos + 3;\n }\n return result;\n}\n\nexport function parseNALUType(startByte: number): NALUType {\n return startByte & kNaluTypeMask;\n}\n\nconst kNaluTypeMask = 0x1f;\n\nexport enum NALUType {\n /** Coded slice of a non-IDR picture */\n SLICE_NON_IDR = 1,\n /** Coded slice data partition A */\n SLICE_PARTITION_A = 2,\n /** Coded slice data partition B */\n SLICE_PARTITION_B = 3,\n /** Coded slice data partition C */\n SLICE_PARTITION_C = 4,\n /** Coded slice of an IDR picture */\n SLICE_IDR = 5,\n /** Supplemental enhancement information */\n SEI = 6,\n /** Sequence parameter set */\n SPS = 7,\n /** Picture parameter set */\n PPS = 8,\n /** Access unit delimiter */\n AUD = 9,\n /** End of sequence */\n END_SEQ = 10,\n /** End of stream */\n END_STREAM = 11,\n /** Filler data */\n FILLER_DATA = 12,\n /** Sequence parameter set extension */\n SPS_EXT = 13,\n /** Prefix NAL unit */\n PREFIX_NALU = 14,\n /** Subset sequence parameter set */\n SUBSET_SPS = 15,\n /** Depth parameter set */\n DPS = 16,\n\n // 17, 18 reserved\n\n /** Coded slice of an auxiliary coded picture without partitioning */\n SLICE_AUX = 19,\n /** Coded slice extension */\n SLICE_EXT = 20,\n /** Coded slice extension for a depth view component or a 3D-AVC texture view component */\n SLICE_LAYER_EXT = 21,\n\n // 22, 23 reserved\n}\n\n/**\n * we use a magic frame trailer to detect whether a frame is injected\n * by the livekit server and thus to be treated as unencrypted\n * @internal\n */\nexport function isFrameServerInjected(frameData: ArrayBuffer, trailerBytes: Uint8Array): boolean {\n if (trailerBytes.byteLength === 0) {\n return false;\n }\n const frameTrailer = new Uint8Array(\n frameData.slice(frameData.byteLength - trailerBytes.byteLength),\n );\n return trailerBytes.every((value, index) => value === frameTrailer[index]);\n}\n","import { EventEmitter } from 'events';\nimport type TypedEventEmitter from 'typed-emitter';\nimport { workerLogger } from '../../logger';\nimport { KeyHandlerEvent, type ParticipantKeyHandlerCallbacks } from '../events';\nimport type { KeyProviderOptions, KeySet } from '../types';\nimport { deriveKeys, importKey, ratchet } from '../utils';\n\n// TODO ParticipantKeyHandlers currently don't get destroyed on participant disconnect\n// we could do this by having a separate worker message on participant disconnected.\n\n/**\n * ParticipantKeyHandler is responsible for providing a cryptor instance with the\n * en-/decryption key of a participant. It assumes that all tracks of a specific participant\n * are encrypted with the same key.\n * Additionally it exposes a method to ratchet a key which can be used by the cryptor either automatically\n * if decryption fails or can be triggered manually on both sender and receiver side.\n *\n */\nexport class ParticipantKeyHandler extends (EventEmitter as new () => TypedEventEmitter<ParticipantKeyHandlerCallbacks>) {\n private currentKeyIndex: number;\n\n private cryptoKeyRing: Array<KeySet | undefined>;\n\n private keyProviderOptions: KeyProviderOptions;\n\n private ratchetPromiseMap: Map<number, Promise<CryptoKey>>;\n\n private participantIdentity: string;\n\n private decryptionFailureCount = 0;\n\n private _hasValidKey: boolean = true;\n\n get hasValidKey() {\n return this._hasValidKey;\n }\n\n constructor(participantIdentity: string, keyProviderOptions: KeyProviderOptions) {\n super();\n this.currentKeyIndex = 0;\n if (keyProviderOptions.keyringSize < 1 || keyProviderOptions.keyringSize > 255) {\n throw new TypeError('Keyring size needs to be between 1 and 256');\n }\n this.cryptoKeyRing = new Array(keyProviderOptions.keyringSize).fill(undefined);\n this.keyProviderOptions = keyProviderOptions;\n this.ratchetPromiseMap = new Map();\n this.participantIdentity = participantIdentity;\n this.resetKeyStatus();\n }\n\n decryptionFailure() {\n if (this.keyProviderOptions.failureTolerance < 0) {\n return;\n }\n this.decryptionFailureCount += 1;\n\n if (this.decryptionFailureCount > this.keyProviderOptions.failureTolerance) {\n workerLogger.warn(`key for ${this.participantIdentity} is being marked as invalid`);\n this._hasValidKey = false;\n }\n }\n\n decryptionSuccess() {\n this.resetKeyStatus();\n }\n\n /**\n * Call this after user initiated ratchet or a new key has been set in order to make sure to mark potentially\n * invalid keys as valid again\n */\n resetKeyStatus() {\n this.decryptionFailureCount = 0;\n this._hasValidKey = true;\n }\n\n /**\n * Ratchets the current key (or the one at keyIndex if provided) and\n * returns the ratcheted material\n * if `setKey` is true (default), it will also set the ratcheted key directly on the crypto key ring\n * @param keyIndex\n * @param setKey\n */\n ratchetKey(keyIndex?: number, setKey = true): Promise<CryptoKey> {\n const currentKeyIndex = keyIndex ?? this.getCurrentKeyIndex();\n\n const existingPromise = this.ratchetPromiseMap.get(currentKeyIndex);\n if (typeof existingPromise !== 'undefined') {\n return existingPromise;\n }\n const ratchetPromise = new Promise<CryptoKey>(async (resolve, reject) => {\n try {\n const keySet = this.getKeySet(currentKeyIndex);\n if (!keySet) {\n throw new TypeError(\n `Cannot ratchet key without a valid keyset of participant ${this.participantIdentity}`,\n );\n }\n const currentMaterial = keySet.material;\n const newMaterial = await importKey(\n await ratchet(currentMaterial, this.keyProviderOptions.ratchetSalt),\n currentMaterial.algorithm.name,\n 'derive',\n );\n\n if (setKey) {\n this.setKeyFromMaterial(newMaterial, currentKeyIndex, true);\n this.emit(\n KeyHandlerEvent.KeyRatcheted,\n newMaterial,\n this.participantIdentity,\n currentKeyIndex,\n );\n }\n resolve(newMaterial);\n } catch (e) {\n reject(e);\n } finally {\n this.ratchetPromiseMap.delete(currentKeyIndex);\n }\n });\n this.ratchetPromiseMap.set(currentKeyIndex, ratchetPromise);\n return ratchetPromise;\n }\n\n /**\n * takes in a key material with `deriveBits` and `deriveKey` set as key usages\n * and derives encryption keys from the material and sets it on the key ring buffer\n * together with the material\n * also resets the valid key property and updates the currentKeyIndex\n */\n async setKey(material: CryptoKey, keyIndex = 0) {\n await this.setKeyFromMaterial(material, keyIndex);\n this.resetKeyStatus();\n }\n\n /**\n * takes in a key material with `deriveBits` and `deriveKey` set as key usages\n * and derives encryption keys from the material and sets it on the key ring buffers\n * together with the material\n * also updates the currentKeyIndex\n */\n async setKeyFromMaterial(material: CryptoKey, keyIndex: number, emitRatchetEvent = false) {\n const keySet = await deriveKeys(material, this.keyProviderOptions.ratchetSalt);\n const newIndex = keyIndex >= 0 ? keyIndex % this.cryptoKeyRing.length : this.currentKeyIndex;\n workerLogger.debug(`setting new key with index ${keyIndex}`, {\n usage: material.usages,\n algorithm: material.algorithm,\n ratchetSalt: this.keyProviderOptions.ratchetSalt,\n });\n this.setKeySet(keySet, newIndex, emitRatchetEvent);\n if (newIndex >= 0) this.currentKeyIndex = newIndex;\n }\n\n setKeySet(keySet: KeySet, keyIndex: number, emitRatchetEvent = false) {\n this.cryptoKeyRing[keyIndex % this.cryptoKeyRing.length] = keySet;\n\n if (emitRatchetEvent) {\n this.emit(KeyHandlerEvent.KeyRatcheted, keySet.material, this.participantIdentity, keyIndex);\n }\n }\n\n async setCurrentKeyIndex(index: number) {\n this.currentKeyIndex = index % this.cryptoKeyRing.length;\n this.resetKeyStatus();\n }\n\n getCurrentKeyIndex() {\n return this.currentKeyIndex;\n }\n\n /**\n * returns currently used KeySet or the one at `keyIndex` if provided\n * @param keyIndex\n * @returns\n */\n getKeySet(keyIndex?: number) {\n return this.cryptoKeyRing[keyIndex ?? this.currentKeyIndex];\n }\n}\n","import { workerLogger } from '../../logger';\nimport { VideoCodec } from '../../room/track/options';\nimport { KEY_PROVIDER_DEFAULTS } from '../constants';\nimport { CryptorErrorReason } from '../errors';\nimport { CryptorEvent, KeyHandlerEvent } from '../events';\nimport type {\n E2EEWorkerMessage,\n ErrorMessage,\n InitAck,\n KeyProviderOptions,\n RatchetMessage,\n RatchetRequestMessage,\n} from '../types';\nimport { FrameCryptor, encryptionEnabledMap } from './FrameCryptor';\nimport { ParticipantKeyHandler } from './ParticipantKeyHandler';\n\nconst participantCryptors: FrameCryptor[] = [];\nconst participantKeys: Map<string, ParticipantKeyHandler> = new Map();\nlet sharedKeyHandler: ParticipantKeyHandler | undefined;\n\nlet isEncryptionEnabled: boolean = false;\n\nlet useSharedKey: boolean = false;\n\nlet sifTrailer: Uint8Array | undefined;\n\nlet keyProviderOptions: KeyProviderOptions = KEY_PROVIDER_DEFAULTS;\n\nlet rtpMap: Map<number, VideoCodec> = new Map();\n\nworkerLogger.setDefaultLevel('info');\n\nonmessage = (ev) => {\n const { kind, data }: E2EEWorkerMessage = ev.data;\n\n switch (kind) {\n case 'init':\n workerLogger.setLevel(data.loglevel);\n workerLogger.info('worker initialized');\n keyProviderOptions = data.keyProviderOptions;\n useSharedKey = !!data.keyProviderOptions.sharedKey;\n // acknowledge init successful\n const ackMsg: InitAck = {\n kind: 'initAck',\n data: { enabled: isEncryptionEnabled },\n };\n postMessage(ackMsg);\n break;\n case 'enable':\n setEncryptionEnabled(data.enabled, data.participantIdentity);\n workerLogger.info(\n `updated e2ee enabled status for ${data.participantIdentity} to ${data.enabled}`,\n );\n // acknowledge enable call successful\n postMessage(ev.data);\n break;\n case 'decode':\n let cryptor = getTrackCryptor(data.participantIdentity, data.trackId);\n cryptor.setupTransform(\n kind,\n data.readableStream,\n data.writableStream,\n data.trackId,\n data.codec,\n );\n break;\n case 'encode':\n let pubCryptor = getTrackCryptor(data.participantIdentity, data.trackId);\n pubCryptor.setupTransform(\n kind,\n data.readableStream,\n data.writableStream,\n data.trackId,\n data.codec,\n );\n break;\n case 'setKey':\n if (useSharedKey) {\n setSharedKey(data.key, data.keyIndex);\n } else if (data.participantIdentity) {\n workerLogger.info(\n `set participant sender key ${data.participantIdentity} index ${data.keyIndex}`,\n );\n getParticipantKeyHandler(data.participantIdentity).setKey(data.key, data.keyIndex);\n } else {\n workerLogger.error('no participant Id was provided and shared key usage is disabled');\n }\n break;\n case 'removeTransform':\n unsetCryptorParticipant(data.trackId, data.participantIdentity);\n break;\n case 'updateCodec':\n getTrackCryptor(data.participantIdentity, data.trackId).setVideoCodec(data.codec);\n break;\n case 'setRTPMap':\n // this is only used for the local participant\n rtpMap = data.map;\n participantCryptors.forEach((cr) => {\n if (cr.getParticipantIdentity() === data.participantIdentity) {\n cr.setRtpMap(data.map);\n }\n });\n break;\n case 'ratchetRequest':\n handleRatchetRequest(data);\n break;\n case 'setSifTrailer':\n handleSifTrailer(data.trailer);\n break;\n default:\n break;\n }\n};\n\nasync function handleRatchetRequest(data: RatchetRequestMessage['data']) {\n if (useSharedKey) {\n const keyHandler = getSharedKeyHandler();\n await keyHandler.ratchetKey(data.keyIndex);\n keyHandler.resetKeyStatus();\n } else if (data.participantIdentity) {\n const keyHandler = getParticipantKeyHandler(data.participantIdentity);\n await keyHandler.ratchetKey(data.keyIndex);\n keyHandler.resetKeyStatus();\n } else {\n workerLogger.error(\n 'no participant Id was provided for ratchet request and shared key usage is disabled',\n );\n }\n}\n\nfunction getTrackCryptor(participantIdentity: string, trackId: string) {\n let cryptors = participantCryptors.filter((c) => c.getTrackId() === trackId);\n if (cryptors.length > 1) {\n const debugInfo = cryptors\n .map((c) => {\n return { participant: c.getParticipantIdentity() };\n })\n .join(',');\n workerLogger.error(\n `Found multiple cryptors for the same trackID ${trackId}. target participant: ${participantIdentity} `,\n { participants: debugInfo },\n );\n }\n let cryptor = cryptors[0];\n if (!cryptor) {\n workerLogger.info('creating new cryptor for', { participantIdentity });\n if (!keyProviderOptions) {\n throw Error('Missing keyProvider options');\n }\n cryptor = new FrameCryptor({\n participantIdentity,\n keys: getParticipantKeyHandler(participantIdentity),\n keyProviderOptions,\n sifTrailer,\n });\n cryptor.setRtpMap(rtpMap);\n setupCryptorErrorEvents(cryptor);\n participantCryptors.push(cryptor);\n } else if (participantIdentity !== cryptor.getParticipantIdentity()) {\n // assign new participant id to track cryptor and pass in correct key handler\n cryptor.setParticipant(participantIdentity, getParticipantKeyHandler(participantIdentity));\n }\n\n return cryptor;\n}\n\nfunction getParticipantKeyHandler(participantIdentity: string) {\n if (useSharedKey) {\n return getSharedKeyHandler();\n }\n let keys = participantKeys.get(participantIdentity);\n if (!keys) {\n keys = new ParticipantKeyHandler(participantIdentity, keyProviderOptions);\n keys.on(KeyHandlerEvent.KeyRatcheted, emitRatchetedKeys);\n participantKeys.set(participantIdentity, keys);\n }\n return keys;\n}\n\nfunction getSharedKeyHandler() {\n if (!sharedKeyHandler) {\n workerLogger.debug('creating new shared key handler');\n sharedKeyHandler = new ParticipantKeyHandler('shared-key', keyProviderOptions);\n }\n return sharedKeyHandler;\n}\n\nfunction unsetCryptorParticipant(trackId: string, participantIdentity: string) {\n const cryptors = participantCryptors.filter(\n (c) => c.getParticipantIdentity() === participantIdentity && c.getTrackId() === trackId,\n );\n if (cryptors.length > 1) {\n workerLogger.error('Found multiple cryptors for the same participant and trackID combination', {\n trackId,\n participantIdentity,\n });\n }\n const cryptor = cryptors[0];\n if (!cryptor) {\n workerLogger.warn('Could not unset participant on cryptor', { trackId, participantIdentity });\n } else {\n cryptor.unsetParticipant();\n }\n}\n\nfunction setEncryptionEnabled(enable: boolean, participantIdentity: string) {\n workerLogger.debug(`setting encryption enabled for all tracks of ${participantIdentity}`, {\n enable,\n });\n encryptionEnabledMap.set(participantIdentity, enable);\n}\n\nfunction setSharedKey(key: CryptoKey, index?: number) {\n workerLogger.info('set shared key', { index });\n getSharedKeyHandler().setKey(key, index);\n}\n\nfunction setupCryptorErrorEvents(cryptor: FrameCryptor) {\n cryptor.on(CryptorEvent.Error, (error) => {\n const msg: ErrorMessage = {\n kind: 'error',\n data: { error: new Error(`${CryptorErrorReason[error.reason]}: ${error.message}`) },\n };\n postMessage(msg);\n });\n}\n\nfunction emitRatchetedKeys(material: CryptoKey, participantIdentity: string, keyIndex?: number) {\n const msg: RatchetMessage = {\n kind: `ratchetKey`,\n data: {\n participantIdentity,\n keyIndex,\n material,\n },\n };\n postMessage(msg);\n}\n\nfunction handleSifTrailer(trailer: Uint8Array) {\n sifTrailer = trailer;\n participantCryptors.forEach((c) => {\n c.setSifTrailer(trailer);\n });\n}\n\n// Operations using RTCRtpScriptTransform.\n// @ts-ignore\nif (self.RTCTransformEvent) {\n workerLogger.debug('setup transform event');\n // @ts-ignore\n self.onrtctransform = (event: RTCTransformEvent) => {\n // @ts-ignore .transformer property is part of RTCTransformEvent\n const transformer = event.transformer;\n workerLogger.debug('transformer', transformer);\n // @ts-ignore monkey patching non standard flag\n transformer.handled = true;\n const { kind, participantIdentity, trackId, codec } = transformer.options;\n const cryptor = getTrackCryptor(participantIdentity, trackId);\n workerLogger.debug('transform', { codec });\n cryptor.setupTransform(kind, transformer.readable, transformer.writable, trackId, codec);\n };\n}\n"],"names":["root","definition","this","noop","undefinedType","isIE","window","navigator","test","userAgent","logMethods","_loggersByName","defaultLogger","bindMethod","obj","methodName","method","bind","Function","prototype","call","e","apply","arguments","traceForIE","console","log","trace","replaceLoggingMethods","level","getLevel","i","length","methodFactory","name","debug","levels","SILENT","enableLoggingWhenConsoleArrives","defaultMethodFactory","_level","_loggerName","undefined","realMethod","Logger","factory","inheritedLevel","defaultLevel","userLevel","self","storageKey","getPersistedLevel","storedLevel","localStorage","ignore","cookie","document","cookieName","encodeURIComponent","location","indexOf","exec","slice","normalizeLevel","input","toUpperCase","TypeError","TRACE","DEBUG","INFO","WARN","ERROR","setLevel","persist","levelNum","levelName","persistLevelIfPossible","setDefaultLevel","resetLevel","removeItem","clearPersistedLevel","enableAll","disableAll","rebuild","childName","initialLevel","getLogger","logger","_log","noConflict","getLoggers","exports","module","LogLevel","LoggerNames","livekitLogger","Object","values","map","info","workerLogger","ENCRYPTION_ALGORITHM","UNENCRYPTED_BYTES","key","delta","audio","empty","KEY_PROVIDER_DEFAULTS","sharedKey","ratchetSalt","ratchetWindowSize","failureTolerance","keyringSize","LivekitError","Error","constructor","code","message","super","MediaDeviceFailure","CryptorErrorReason","KeyProviderEvent","KeyHandlerEvent","EncryptionEvent","CryptorEvent","getFailure","error","NotFound","PermissionDenied","DeviceInUse","Other","CryptorError","reason","InternalError","participantIdentity","ReflectOwnKeys","R","Reflect","ReflectApply","target","receiver","args","ownKeys","getOwnPropertySymbols","getOwnPropertyNames","concat","NumberIsNaN","Number","isNaN","value","EventEmitter","init","eventsModule","once","emitter","Promise","resolve","reject","errorListener","err","removeListener","resolver","eventTargetAgnosticAddListener","handler","flags","on","addErrorHandlerIfEventEmitter","_events","_eventsCount","_maxListeners","defaultMaxListeners","checkListener","listener","_getMaxListeners","that","_addListener","type","prepend","m","events","existing","warning","create","newListener","emit","unshift","push","warned","w","String","count","warn","onceWrapper","fired","wrapFn","_onceWrap","state","wrapped","_listeners","unwrap","evlistener","arr","ret","Array","unwrapListeners","arrayClone","listenerCount","n","copy","addEventListener","wrapListener","arg","removeEventListener","defineProperty","enumerable","get","set","RangeError","getPrototypeOf","setMaxListeners","getMaxListeners","doError","er","context","len","listeners","addListener","prependListener","prependOnceListener","list","position","originalListener","shift","index","pop","spliceOne","off","removeAllListeners","keys","rawListeners","eventNames","getAlgoOptions","algorithmName","salt","encodedSalt","TextEncoder","encode","hash","ArrayBuffer","iterations","deriveKeys","material","algorithmOptions","algorithm","encryptionKey","crypto","subtle","deriveKey","SifGuard","consecutiveSifCount","lastSifReceivedAt","userFramesSinceSif","recordSif","_a","sifSequenceStartedAt","Date","now","recordUserFrame","reset","isSifAllowed","encryptionEnabledMap","Map","BaseFrameCryptor","encodeFunction","encodedFrame","controller","decodeFunction","FrameCryptor","opts","sendCounts","rtpMap","keyProviderOptions","sifTrailer","Uint8Array","from","sifGuard","logContext","participant","mediaTrackId","trackId","fallbackCodec","videoCodec","setParticipant","id","assign","unsetParticipant","isEnabled","getParticipantIdentity","getTrackId","setVideoCodec","codec","setRtpMap","setupTransform","operation","readable","writable","passedTrackId","transformFn","transformStream","TransformStream","transform","pipeThrough","pipeTo","catch","setSifTrailer","trailer","data","byteLength","enqueue","keySet","getKeySet","getCurrentKeyIndex","keyIndex","iv","makeIV","getMetadata","synchronizationSource","timestamp","frameInfo","getUnencryptedBytes","frameHeader","unencryptedBytes","frameTrailer","cipherText","encrypt","additionalData","newDataWithoutHeader","isH264","data_in","dataOut","numConsecutiveZeros","byte","writeRbsp","newData","buffer","MissingKey","frameData","trailerBytes","every","isFrameServerInjected","hasValidKey","decodedFrame","decryptFrame","decryptionSuccess","InvalidKey","decryptionFailure","encodedFrame_1","keyIndex_1","_this","initialMaterial","ratchetOpts","ratchetCount","encryptedData","needsRbspUnescaping","stream","parseRbsp","newUint8","ivLength","cipherTextStart","cipherTextLength","plainText","decrypt","ratchetedKeySet","RTCEncodedAudioFrame","newMaterial","ratchetKey","frame","setKeySet","setCurrentKeyIndex","ivView","DataView","has","Math","floor","random","sendCount","setUint32","isVideoFrame","detectedCodec","getVideoCodec","oldCodec","naluIndices","result","start","pos","searchLength","end","findNALUIndices","some","naluIndex","NALUType","SLICE_IDR","SLICE_NON_IDR","includes","parseNALUType","size","payloadType","startByte","kNaluTypeMask","ParticipantKeyHandler","_hasValidKey","decryptionFailureCount","currentKeyIndex","cryptoKeyRing","fill","ratchetPromiseMap","resetKeyStatus","setKey","existingPromise","ratchetPromise","__awaiter","currentMaterial","keyBytes_1","keyBytes","usage","importKey","deriveBits","ratchet","setKeyFromMaterial","KeyRatcheted","delete","material_1","_this2","emitRatchetEvent","newIndex","usages","participantCryptors","participantKeys","sharedKeyHandler","useSharedKey","getTrackCryptor","cryptors","filter","c","debugInfo","join","participants","cryptor","getParticipantKeyHandler","msg","kind","postMessage","setupCryptorErrorEvents","getSharedKeyHandler","emitRatchetedKeys","onmessage","ev","loglevel","enabled","enable","readableStream","writableStream","unsetCryptorParticipant","forEach","cr","keyHandler","handleRatchetRequest","RTCTransformEvent","onrtctransform","event","transformer","handled","options"],"mappings":"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","x_google_ignoreList":[0,6]}
|
1
|
+
{"version":3,"file":"livekit-client.e2ee.worker.js","sources":["../node_modules/.pnpm/loglevel@1.9.1/node_modules/loglevel/lib/loglevel.js","../src/logger.ts","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/private/assert.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/private/enum.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/message.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/google/varint.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/proto-int64.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/scalar.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/binary-encoding.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/private/scalars.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/private/extensions.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/proto-base64.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/extension-accessor.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/private/reflect.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/is-message.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/private/field-wrapper.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/private/json-format.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/private/binary-format.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/private/util-common.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/private/field-list.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/private/names.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/private/field.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/proto3.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/private/proto-runtime.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/private/field-normalize.js","../node_modules/.pnpm/@bufbuild+protobuf@1.10.0/node_modules/@bufbuild/protobuf/dist/esm/private/message-type.js","../node_modules/.pnpm/@livekit+protocol@1.22.0/node_modules/@livekit/protocol/src/gen/livekit_models_pb.js","../node_modules/.pnpm/@livekit+protocol@1.22.0/node_modules/@livekit/protocol/src/gen/livekit_rtc_pb.js","../src/utils/browserParser.ts","../src/room/track/options.ts","../node_modules/.pnpm/events@3.3.0/node_modules/events/events.js","../src/room/events.ts","../src/room/track/Track.ts","../src/utils/AsyncQueue.ts","../src/room/utils.ts","../src/room/track/utils.ts","../src/e2ee/constants.ts","../src/room/errors.ts","../src/e2ee/errors.ts","../src/e2ee/events.ts","../src/e2ee/utils.ts","../src/e2ee/worker/SifGuard.ts","../src/e2ee/worker/FrameCryptor.ts","../src/e2ee/worker/ParticipantKeyHandler.ts","../src/e2ee/worker/e2ee.worker.ts"],"sourcesContent":["/*\n* loglevel - https://github.com/pimterry/loglevel\n*\n* Copyright (c) 2013 Tim Perry\n* Licensed under the MIT license.\n*/\n(function (root, definition) {\n \"use strict\";\n if (typeof define === 'function' && define.amd) {\n define(definition);\n } else if (typeof module === 'object' && module.exports) {\n module.exports = definition();\n } else {\n root.log = definition();\n }\n}(this, function () {\n \"use strict\";\n\n // Slightly dubious tricks to cut down minimized file size\n var noop = function() {};\n var undefinedType = \"undefined\";\n var isIE = (typeof window !== undefinedType) && (typeof window.navigator !== undefinedType) && (\n /Trident\\/|MSIE /.test(window.navigator.userAgent)\n );\n\n var logMethods = [\n \"trace\",\n \"debug\",\n \"info\",\n \"warn\",\n \"error\"\n ];\n\n var _loggersByName = {};\n var defaultLogger = null;\n\n // Cross-browser bind equivalent that works at least back to IE6\n function bindMethod(obj, methodName) {\n var method = obj[methodName];\n if (typeof method.bind === 'function') {\n return method.bind(obj);\n } else {\n try {\n return Function.prototype.bind.call(method, obj);\n } catch (e) {\n // Missing bind shim or IE8 + Modernizr, fallback to wrapping\n return function() {\n return Function.prototype.apply.apply(method, [obj, arguments]);\n };\n }\n }\n }\n\n // Trace() doesn't print the message in IE, so for that case we need to wrap it\n function traceForIE() {\n if (console.log) {\n if (console.log.apply) {\n console.log.apply(console, arguments);\n } else {\n // In old IE, native console methods themselves don't have apply().\n Function.prototype.apply.apply(console.log, [console, arguments]);\n }\n }\n if (console.trace) console.trace();\n }\n\n // Build the best logging method possible for this env\n // Wherever possible we want to bind, not wrap, to preserve stack traces\n function realMethod(methodName) {\n if (methodName === 'debug') {\n methodName = 'log';\n }\n\n if (typeof console === undefinedType) {\n return false; // No method possible, for now - fixed later by enableLoggingWhenConsoleArrives\n } else if (methodName === 'trace' && isIE) {\n return traceForIE;\n } else if (console[methodName] !== undefined) {\n return bindMethod(console, methodName);\n } else if (console.log !== undefined) {\n return bindMethod(console, 'log');\n } else {\n return noop;\n }\n }\n\n // These private functions always need `this` to be set properly\n\n function replaceLoggingMethods() {\n /*jshint validthis:true */\n var level = this.getLevel();\n\n // Replace the actual methods.\n for (var i = 0; i < logMethods.length; i++) {\n var methodName = logMethods[i];\n this[methodName] = (i < level) ?\n noop :\n this.methodFactory(methodName, level, this.name);\n }\n\n // Define log.log as an alias for log.debug\n this.log = this.debug;\n\n // Return any important warnings.\n if (typeof console === undefinedType && level < this.levels.SILENT) {\n return \"No console available for logging\";\n }\n }\n\n // In old IE versions, the console isn't present until you first open it.\n // We build realMethod() replacements here that regenerate logging methods\n function enableLoggingWhenConsoleArrives(methodName) {\n return function () {\n if (typeof console !== undefinedType) {\n replaceLoggingMethods.call(this);\n this[methodName].apply(this, arguments);\n }\n };\n }\n\n // By default, we use closely bound real methods wherever possible, and\n // otherwise we wait for a console to appear, and then try again.\n function defaultMethodFactory(methodName, _level, _loggerName) {\n /*jshint validthis:true */\n return realMethod(methodName) ||\n enableLoggingWhenConsoleArrives.apply(this, arguments);\n }\n\n function Logger(name, factory) {\n // Private instance variables.\n var self = this;\n /**\n * The level inherited from a parent logger (or a global default). We\n * cache this here rather than delegating to the parent so that it stays\n * in sync with the actual logging methods that we have installed (the\n * parent could change levels but we might not have rebuilt the loggers\n * in this child yet).\n * @type {number}\n */\n var inheritedLevel;\n /**\n * The default level for this logger, if any. If set, this overrides\n * `inheritedLevel`.\n * @type {number|null}\n */\n var defaultLevel;\n /**\n * A user-specific level for this logger. If set, this overrides\n * `defaultLevel`.\n * @type {number|null}\n */\n var userLevel;\n\n var storageKey = \"loglevel\";\n if (typeof name === \"string\") {\n storageKey += \":\" + name;\n } else if (typeof name === \"symbol\") {\n storageKey = undefined;\n }\n\n function persistLevelIfPossible(levelNum) {\n var levelName = (logMethods[levelNum] || 'silent').toUpperCase();\n\n if (typeof window === undefinedType || !storageKey) return;\n\n // Use localStorage if available\n try {\n window.localStorage[storageKey] = levelName;\n return;\n } catch (ignore) {}\n\n // Use session cookie as fallback\n try {\n window.document.cookie =\n encodeURIComponent(storageKey) + \"=\" + levelName + \";\";\n } catch (ignore) {}\n }\n\n function getPersistedLevel() {\n var storedLevel;\n\n if (typeof window === undefinedType || !storageKey) return;\n\n try {\n storedLevel = window.localStorage[storageKey];\n } catch (ignore) {}\n\n // Fallback to cookies if local storage gives us nothing\n if (typeof storedLevel === undefinedType) {\n try {\n var cookie = window.document.cookie;\n var cookieName = encodeURIComponent(storageKey);\n var location = cookie.indexOf(cookieName + \"=\");\n if (location !== -1) {\n storedLevel = /^([^;]+)/.exec(\n cookie.slice(location + cookieName.length + 1)\n )[1];\n }\n } catch (ignore) {}\n }\n\n // If the stored level is not valid, treat it as if nothing was stored.\n if (self.levels[storedLevel] === undefined) {\n storedLevel = undefined;\n }\n\n return storedLevel;\n }\n\n function clearPersistedLevel() {\n if (typeof window === undefinedType || !storageKey) return;\n\n // Use localStorage if available\n try {\n window.localStorage.removeItem(storageKey);\n } catch (ignore) {}\n\n // Use session cookie as fallback\n try {\n window.document.cookie =\n encodeURIComponent(storageKey) + \"=; expires=Thu, 01 Jan 1970 00:00:00 UTC\";\n } catch (ignore) {}\n }\n\n function normalizeLevel(input) {\n var level = input;\n if (typeof level === \"string\" && self.levels[level.toUpperCase()] !== undefined) {\n level = self.levels[level.toUpperCase()];\n }\n if (typeof level === \"number\" && level >= 0 && level <= self.levels.SILENT) {\n return level;\n } else {\n throw new TypeError(\"log.setLevel() called with invalid level: \" + input);\n }\n }\n\n /*\n *\n * Public logger API - see https://github.com/pimterry/loglevel for details\n *\n */\n\n self.name = name;\n\n self.levels = { \"TRACE\": 0, \"DEBUG\": 1, \"INFO\": 2, \"WARN\": 3,\n \"ERROR\": 4, \"SILENT\": 5};\n\n self.methodFactory = factory || defaultMethodFactory;\n\n self.getLevel = function () {\n if (userLevel != null) {\n return userLevel;\n } else if (defaultLevel != null) {\n return defaultLevel;\n } else {\n return inheritedLevel;\n }\n };\n\n self.setLevel = function (level, persist) {\n userLevel = normalizeLevel(level);\n if (persist !== false) { // defaults to true\n persistLevelIfPossible(userLevel);\n }\n\n // NOTE: in v2, this should call rebuild(), which updates children.\n return replaceLoggingMethods.call(self);\n };\n\n self.setDefaultLevel = function (level) {\n defaultLevel = normalizeLevel(level);\n if (!getPersistedLevel()) {\n self.setLevel(level, false);\n }\n };\n\n self.resetLevel = function () {\n userLevel = null;\n clearPersistedLevel();\n replaceLoggingMethods.call(self);\n };\n\n self.enableAll = function(persist) {\n self.setLevel(self.levels.TRACE, persist);\n };\n\n self.disableAll = function(persist) {\n self.setLevel(self.levels.SILENT, persist);\n };\n\n self.rebuild = function () {\n if (defaultLogger !== self) {\n inheritedLevel = normalizeLevel(defaultLogger.getLevel());\n }\n replaceLoggingMethods.call(self);\n\n if (defaultLogger === self) {\n for (var childName in _loggersByName) {\n _loggersByName[childName].rebuild();\n }\n }\n };\n\n // Initialize all the internal levels.\n inheritedLevel = normalizeLevel(\n defaultLogger ? defaultLogger.getLevel() : \"WARN\"\n );\n var initialLevel = getPersistedLevel();\n if (initialLevel != null) {\n userLevel = normalizeLevel(initialLevel);\n }\n replaceLoggingMethods.call(self);\n }\n\n /*\n *\n * Top-level API\n *\n */\n\n defaultLogger = new Logger();\n\n defaultLogger.getLogger = function getLogger(name) {\n if ((typeof name !== \"symbol\" && typeof name !== \"string\") || name === \"\") {\n throw new TypeError(\"You must supply a name when creating a logger.\");\n }\n\n var logger = _loggersByName[name];\n if (!logger) {\n logger = _loggersByName[name] = new Logger(\n name,\n defaultLogger.methodFactory\n );\n }\n return logger;\n };\n\n // Grab the current global log variable in case of overwrite\n var _log = (typeof window !== undefinedType) ? window.log : undefined;\n defaultLogger.noConflict = function() {\n if (typeof window !== undefinedType &&\n window.log === defaultLogger) {\n window.log = _log;\n }\n\n return defaultLogger;\n };\n\n defaultLogger.getLoggers = function getLoggers() {\n return _loggersByName;\n };\n\n // ES6 default export, for compatibility\n defaultLogger['default'] = defaultLogger;\n\n return defaultLogger;\n}));\n","import * as log from 'loglevel';\n\nexport enum LogLevel {\n trace = 0,\n debug = 1,\n info = 2,\n warn = 3,\n error = 4,\n silent = 5,\n}\n\nexport enum LoggerNames {\n Default = 'livekit',\n Room = 'livekit-room',\n Participant = 'livekit-participant',\n Track = 'livekit-track',\n Publication = 'livekit-track-publication',\n Engine = 'livekit-engine',\n Signal = 'livekit-signal',\n PCManager = 'livekit-pc-manager',\n PCTransport = 'livekit-pc-transport',\n E2EE = 'lk-e2ee',\n}\n\ntype LogLevelString = keyof typeof LogLevel;\n\nexport type StructuredLogger = log.Logger & {\n trace: (msg: string, context?: object) => void;\n debug: (msg: string, context?: object) => void;\n info: (msg: string, context?: object) => void;\n warn: (msg: string, context?: object) => void;\n error: (msg: string, context?: object) => void;\n setDefaultLevel: (level: log.LogLevelDesc) => void;\n setLevel: (level: log.LogLevelDesc) => void;\n getLevel: () => number;\n};\n\nlet livekitLogger = log.getLogger('livekit');\nconst livekitLoggers = Object.values(LoggerNames).map((name) => log.getLogger(name));\n\nlivekitLogger.setDefaultLevel(LogLevel.info);\n\nexport default livekitLogger as StructuredLogger;\n\n/**\n * @internal\n */\nexport function getLogger(name: string) {\n const logger = log.getLogger(name);\n logger.setDefaultLevel(livekitLogger.getLevel());\n return logger as StructuredLogger;\n}\n\nexport function setLogLevel(level: LogLevel | LogLevelString, loggerName?: LoggerNames) {\n if (loggerName) {\n log.getLogger(loggerName).setLevel(level);\n } else {\n for (const logger of livekitLoggers) {\n logger.setLevel(level);\n }\n }\n}\n\nexport type LogExtension = (level: LogLevel, msg: string, context?: object) => void;\n\n/**\n * use this to hook into the logging function to allow sending internal livekit logs to third party services\n * if set, the browser logs will lose their stacktrace information (see https://github.com/pimterry/loglevel#writing-plugins)\n */\nexport function setLogExtension(extension: LogExtension, logger?: StructuredLogger) {\n const loggers = logger ? [logger] : livekitLoggers;\n\n loggers.forEach((logR) => {\n const originalFactory = logR.methodFactory;\n\n logR.methodFactory = (methodName, configLevel, loggerName) => {\n const rawMethod = originalFactory(methodName, configLevel, loggerName);\n\n const logLevel = LogLevel[methodName as LogLevelString];\n const needLog = logLevel >= configLevel && logLevel < LogLevel.silent;\n\n return (msg, context?: [msg: string, context: object]) => {\n if (context) rawMethod(msg, context);\n else rawMethod(msg);\n if (needLog) {\n extension(logLevel, msg, context);\n }\n };\n };\n logR.setLevel(logR.getLevel());\n });\n}\n\nexport const workerLogger = log.getLogger('lk-e2ee') as StructuredLogger;\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/**\n * Assert that condition is truthy or throw error (with message)\n */\nexport function assert(condition, msg) {\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions -- we want the implicit conversion to boolean\n if (!condition) {\n throw new Error(msg);\n }\n}\nconst FLOAT32_MAX = 3.4028234663852886e38, FLOAT32_MIN = -3.4028234663852886e38, UINT32_MAX = 0xffffffff, INT32_MAX = 0x7fffffff, INT32_MIN = -0x80000000;\n/**\n * Assert a valid signed protobuf 32-bit integer.\n */\nexport function assertInt32(arg) {\n if (typeof arg !== \"number\")\n throw new Error(\"invalid int 32: \" + typeof arg);\n if (!Number.isInteger(arg) || arg > INT32_MAX || arg < INT32_MIN)\n throw new Error(\"invalid int 32: \" + arg); // eslint-disable-line @typescript-eslint/restrict-plus-operands -- we want the implicit conversion to string\n}\n/**\n * Assert a valid unsigned protobuf 32-bit integer.\n */\nexport function assertUInt32(arg) {\n if (typeof arg !== \"number\")\n throw new Error(\"invalid uint 32: \" + typeof arg);\n if (!Number.isInteger(arg) || arg > UINT32_MAX || arg < 0)\n throw new Error(\"invalid uint 32: \" + arg); // eslint-disable-line @typescript-eslint/restrict-plus-operands -- we want the implicit conversion to string\n}\n/**\n * Assert a valid protobuf float value.\n */\nexport function assertFloat32(arg) {\n if (typeof arg !== \"number\")\n throw new Error(\"invalid float 32: \" + typeof arg);\n if (!Number.isFinite(arg))\n return;\n if (arg > FLOAT32_MAX || arg < FLOAT32_MIN)\n throw new Error(\"invalid float 32: \" + arg); // eslint-disable-line @typescript-eslint/restrict-plus-operands -- we want the implicit conversion to string\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { assert } from \"./assert.js\";\nconst enumTypeSymbol = Symbol(\"@bufbuild/protobuf/enum-type\");\n/**\n * Get reflection information from a generated enum.\n * If this function is called on something other than a generated\n * enum, it raises an error.\n */\nexport function getEnumType(enumObject) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-explicit-any\n const t = enumObject[enumTypeSymbol];\n assert(t, \"missing enum type on enum object\");\n return t; // eslint-disable-line @typescript-eslint/no-unsafe-return\n}\n/**\n * Sets reflection information on a generated enum.\n */\nexport function setEnumType(enumObject, typeName, values, opt) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any\n enumObject[enumTypeSymbol] = makeEnumType(typeName, values.map((v) => ({\n no: v.no,\n name: v.name,\n localName: enumObject[v.no],\n })), opt);\n}\n/**\n * Create a new EnumType with the given values.\n */\nexport function makeEnumType(typeName, values, \n// eslint-disable-next-line @typescript-eslint/no-unused-vars\n_opt) {\n const names = Object.create(null);\n const numbers = Object.create(null);\n const normalValues = [];\n for (const value of values) {\n // We do not surface options at this time\n // const value: EnumValueInfo = {...v, options: v.options ?? emptyReadonlyObject};\n const n = normalizeEnumValue(value);\n normalValues.push(n);\n names[value.name] = n;\n numbers[value.no] = n;\n }\n return {\n typeName,\n values: normalValues,\n // We do not surface options at this time\n // options: opt?.options ?? Object.create(null),\n findName(name) {\n return names[name];\n },\n findNumber(no) {\n return numbers[no];\n },\n };\n}\n/**\n * Create a new enum object with the given values.\n * Sets reflection information.\n */\nexport function makeEnum(typeName, values, opt) {\n const enumObject = {};\n for (const value of values) {\n const n = normalizeEnumValue(value);\n enumObject[n.localName] = n.no;\n enumObject[n.no] = n.localName;\n }\n setEnumType(enumObject, typeName, values, opt);\n return enumObject;\n}\nfunction normalizeEnumValue(value) {\n if (\"localName\" in value) {\n return value;\n }\n return Object.assign(Object.assign({}, value), { localName: value.name });\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/**\n * Message is the base class of every message, generated, or created at\n * runtime.\n *\n * It is _not_ safe to extend this class. If you want to create a message at\n * run time, use proto3.makeMessageType().\n */\nexport class Message {\n /**\n * Compare with a message of the same type.\n * Note that this function disregards extensions and unknown fields.\n */\n equals(other) {\n return this.getType().runtime.util.equals(this.getType(), this, other);\n }\n /**\n * Create a deep copy.\n */\n clone() {\n return this.getType().runtime.util.clone(this);\n }\n /**\n * Parse from binary data, merging fields.\n *\n * Repeated fields are appended. Map entries are added, overwriting\n * existing keys.\n *\n * If a message field is already present, it will be merged with the\n * new data.\n */\n fromBinary(bytes, options) {\n const type = this.getType(), format = type.runtime.bin, opt = format.makeReadOptions(options);\n format.readMessage(this, opt.readerFactory(bytes), bytes.byteLength, opt);\n return this;\n }\n /**\n * Parse a message from a JSON value.\n */\n fromJson(jsonValue, options) {\n const type = this.getType(), format = type.runtime.json, opt = format.makeReadOptions(options);\n format.readMessage(type, jsonValue, opt, this);\n return this;\n }\n /**\n * Parse a message from a JSON string.\n */\n fromJsonString(jsonString, options) {\n let json;\n try {\n json = JSON.parse(jsonString);\n }\n catch (e) {\n throw new Error(`cannot decode ${this.getType().typeName} from JSON: ${e instanceof Error ? e.message : String(e)}`);\n }\n return this.fromJson(json, options);\n }\n /**\n * Serialize the message to binary data.\n */\n toBinary(options) {\n const type = this.getType(), bin = type.runtime.bin, opt = bin.makeWriteOptions(options), writer = opt.writerFactory();\n bin.writeMessage(this, writer, opt);\n return writer.finish();\n }\n /**\n * Serialize the message to a JSON value, a JavaScript value that can be\n * passed to JSON.stringify().\n */\n toJson(options) {\n const type = this.getType(), json = type.runtime.json, opt = json.makeWriteOptions(options);\n return json.writeMessage(this, opt);\n }\n /**\n * Serialize the message to a JSON string.\n */\n toJsonString(options) {\n var _a;\n const value = this.toJson(options);\n return JSON.stringify(value, null, (_a = options === null || options === void 0 ? void 0 : options.prettySpaces) !== null && _a !== void 0 ? _a : 0);\n }\n /**\n * Override for serialization behavior. This will be invoked when calling\n * JSON.stringify on this message (i.e. JSON.stringify(msg)).\n *\n * Note that this will not serialize google.protobuf.Any with a packed\n * message because the protobuf JSON format specifies that it needs to be\n * unpacked, and this is only possible with a type registry to look up the\n * message type. As a result, attempting to serialize a message with this\n * type will throw an Error.\n *\n * This method is protected because you should not need to invoke it\n * directly -- instead use JSON.stringify or toJsonString for\n * stringified JSON. Alternatively, if actual JSON is desired, you should\n * use toJson.\n */\n toJSON() {\n return this.toJson({\n emitDefaultValues: true,\n });\n }\n /**\n * Retrieve the MessageType of this message - a singleton that represents\n * the protobuf message declaration and provides metadata for reflection-\n * based operations.\n */\n getType() {\n // Any class that extends Message _must_ provide a complete static\n // implementation of MessageType.\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-return\n return Object.getPrototypeOf(this).constructor;\n }\n}\n","// Copyright 2008 Google Inc. All rights reserved.\n//\n// Redistribution and use in source and binary forms, with or without\n// modification, are permitted provided that the following conditions are\n// met:\n//\n// * Redistributions of source code must retain the above copyright\n// notice, this list of conditions and the following disclaimer.\n// * Redistributions in binary form must reproduce the above\n// copyright notice, this list of conditions and the following disclaimer\n// in the documentation and/or other materials provided with the\n// distribution.\n// * Neither the name of Google Inc. nor the names of its\n// contributors may be used to endorse or promote products derived from\n// this software without specific prior written permission.\n//\n// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n// \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\n// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\n// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n//\n// Code generated by the Protocol Buffer compiler is owned by the owner\n// of the input file used when generating it. This code is not\n// standalone and requires a support library to be linked with it. This\n// support library is itself covered by the above license.\n/* eslint-disable prefer-const,@typescript-eslint/restrict-plus-operands */\n/**\n * Read a 64 bit varint as two JS numbers.\n *\n * Returns tuple:\n * [0]: low bits\n * [1]: high bits\n *\n * Copyright 2008 Google Inc. All rights reserved.\n *\n * See https://github.com/protocolbuffers/protobuf/blob/8a71927d74a4ce34efe2d8769fda198f52d20d12/js/experimental/runtime/kernel/buffer_decoder.js#L175\n */\nexport function varint64read() {\n let lowBits = 0;\n let highBits = 0;\n for (let shift = 0; shift < 28; shift += 7) {\n let b = this.buf[this.pos++];\n lowBits |= (b & 0x7f) << shift;\n if ((b & 0x80) == 0) {\n this.assertBounds();\n return [lowBits, highBits];\n }\n }\n let middleByte = this.buf[this.pos++];\n // last four bits of the first 32 bit number\n lowBits |= (middleByte & 0x0f) << 28;\n // 3 upper bits are part of the next 32 bit number\n highBits = (middleByte & 0x70) >> 4;\n if ((middleByte & 0x80) == 0) {\n this.assertBounds();\n return [lowBits, highBits];\n }\n for (let shift = 3; shift <= 31; shift += 7) {\n let b = this.buf[this.pos++];\n highBits |= (b & 0x7f) << shift;\n if ((b & 0x80) == 0) {\n this.assertBounds();\n return [lowBits, highBits];\n }\n }\n throw new Error(\"invalid varint\");\n}\n/**\n * Write a 64 bit varint, given as two JS numbers, to the given bytes array.\n *\n * Copyright 2008 Google Inc. All rights reserved.\n *\n * See https://github.com/protocolbuffers/protobuf/blob/8a71927d74a4ce34efe2d8769fda198f52d20d12/js/experimental/runtime/kernel/writer.js#L344\n */\nexport function varint64write(lo, hi, bytes) {\n for (let i = 0; i < 28; i = i + 7) {\n const shift = lo >>> i;\n const hasNext = !(shift >>> 7 == 0 && hi == 0);\n const byte = (hasNext ? shift | 0x80 : shift) & 0xff;\n bytes.push(byte);\n if (!hasNext) {\n return;\n }\n }\n const splitBits = ((lo >>> 28) & 0x0f) | ((hi & 0x07) << 4);\n const hasMoreBits = !(hi >> 3 == 0);\n bytes.push((hasMoreBits ? splitBits | 0x80 : splitBits) & 0xff);\n if (!hasMoreBits) {\n return;\n }\n for (let i = 3; i < 31; i = i + 7) {\n const shift = hi >>> i;\n const hasNext = !(shift >>> 7 == 0);\n const byte = (hasNext ? shift | 0x80 : shift) & 0xff;\n bytes.push(byte);\n if (!hasNext) {\n return;\n }\n }\n bytes.push((hi >>> 31) & 0x01);\n}\n// constants for binary math\nconst TWO_PWR_32_DBL = 0x100000000;\n/**\n * Parse decimal string of 64 bit integer value as two JS numbers.\n *\n * Copyright 2008 Google Inc. All rights reserved.\n *\n * See https://github.com/protocolbuffers/protobuf-javascript/blob/a428c58273abad07c66071d9753bc4d1289de426/experimental/runtime/int64.js#L10\n */\nexport function int64FromString(dec) {\n // Check for minus sign.\n const minus = dec[0] === \"-\";\n if (minus) {\n dec = dec.slice(1);\n }\n // Work 6 decimal digits at a time, acting like we're converting base 1e6\n // digits to binary. This is safe to do with floating point math because\n // Number.isSafeInteger(ALL_32_BITS * 1e6) == true.\n const base = 1e6;\n let lowBits = 0;\n let highBits = 0;\n function add1e6digit(begin, end) {\n // Note: Number('') is 0.\n const digit1e6 = Number(dec.slice(begin, end));\n highBits *= base;\n lowBits = lowBits * base + digit1e6;\n // Carry bits from lowBits to\n if (lowBits >= TWO_PWR_32_DBL) {\n highBits = highBits + ((lowBits / TWO_PWR_32_DBL) | 0);\n lowBits = lowBits % TWO_PWR_32_DBL;\n }\n }\n add1e6digit(-24, -18);\n add1e6digit(-18, -12);\n add1e6digit(-12, -6);\n add1e6digit(-6);\n return minus ? negate(lowBits, highBits) : newBits(lowBits, highBits);\n}\n/**\n * Losslessly converts a 64-bit signed integer in 32:32 split representation\n * into a decimal string.\n *\n * Copyright 2008 Google Inc. All rights reserved.\n *\n * See https://github.com/protocolbuffers/protobuf-javascript/blob/a428c58273abad07c66071d9753bc4d1289de426/experimental/runtime/int64.js#L10\n */\nexport function int64ToString(lo, hi) {\n let bits = newBits(lo, hi);\n // If we're treating the input as a signed value and the high bit is set, do\n // a manual two's complement conversion before the decimal conversion.\n const negative = (bits.hi & 0x80000000);\n if (negative) {\n bits = negate(bits.lo, bits.hi);\n }\n const result = uInt64ToString(bits.lo, bits.hi);\n return negative ? \"-\" + result : result;\n}\n/**\n * Losslessly converts a 64-bit unsigned integer in 32:32 split representation\n * into a decimal string.\n *\n * Copyright 2008 Google Inc. All rights reserved.\n *\n * See https://github.com/protocolbuffers/protobuf-javascript/blob/a428c58273abad07c66071d9753bc4d1289de426/experimental/runtime/int64.js#L10\n */\nexport function uInt64ToString(lo, hi) {\n ({ lo, hi } = toUnsigned(lo, hi));\n // Skip the expensive conversion if the number is small enough to use the\n // built-in conversions.\n // Number.MAX_SAFE_INTEGER = 0x001FFFFF FFFFFFFF, thus any number with\n // highBits <= 0x1FFFFF can be safely expressed with a double and retain\n // integer precision.\n // Proven by: Number.isSafeInteger(0x1FFFFF * 2**32 + 0xFFFFFFFF) == true.\n if (hi <= 0x1FFFFF) {\n return String(TWO_PWR_32_DBL * hi + lo);\n }\n // What this code is doing is essentially converting the input number from\n // base-2 to base-1e7, which allows us to represent the 64-bit range with\n // only 3 (very large) digits. Those digits are then trivial to convert to\n // a base-10 string.\n // The magic numbers used here are -\n // 2^24 = 16777216 = (1,6777216) in base-1e7.\n // 2^48 = 281474976710656 = (2,8147497,6710656) in base-1e7.\n // Split 32:32 representation into 16:24:24 representation so our\n // intermediate digits don't overflow.\n const low = lo & 0xFFFFFF;\n const mid = ((lo >>> 24) | (hi << 8)) & 0xFFFFFF;\n const high = (hi >> 16) & 0xFFFF;\n // Assemble our three base-1e7 digits, ignoring carries. The maximum\n // value in a digit at this step is representable as a 48-bit integer, which\n // can be stored in a 64-bit floating point number.\n let digitA = low + (mid * 6777216) + (high * 6710656);\n let digitB = mid + (high * 8147497);\n let digitC = (high * 2);\n // Apply carries from A to B and from B to C.\n const base = 10000000;\n if (digitA >= base) {\n digitB += Math.floor(digitA / base);\n digitA %= base;\n }\n if (digitB >= base) {\n digitC += Math.floor(digitB / base);\n digitB %= base;\n }\n // If digitC is 0, then we should have returned in the trivial code path\n // at the top for non-safe integers. Given this, we can assume both digitB\n // and digitA need leading zeros.\n return digitC.toString() + decimalFrom1e7WithLeadingZeros(digitB) +\n decimalFrom1e7WithLeadingZeros(digitA);\n}\nfunction toUnsigned(lo, hi) {\n return { lo: lo >>> 0, hi: hi >>> 0 };\n}\nfunction newBits(lo, hi) {\n return { lo: lo | 0, hi: hi | 0 };\n}\n/**\n * Returns two's compliment negation of input.\n * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Signed_32-bit_integers\n */\nfunction negate(lowBits, highBits) {\n highBits = ~highBits;\n if (lowBits) {\n lowBits = ~lowBits + 1;\n }\n else {\n // If lowBits is 0, then bitwise-not is 0xFFFFFFFF,\n // adding 1 to that, results in 0x100000000, which leaves\n // the low bits 0x0 and simply adds one to the high bits.\n highBits += 1;\n }\n return newBits(lowBits, highBits);\n}\n/**\n * Returns decimal representation of digit1e7 with leading zeros.\n */\nconst decimalFrom1e7WithLeadingZeros = (digit1e7) => {\n const partial = String(digit1e7);\n return \"0000000\".slice(partial.length) + partial;\n};\n/**\n * Write a 32 bit varint, signed or unsigned. Same as `varint64write(0, value, bytes)`\n *\n * Copyright 2008 Google Inc. All rights reserved.\n *\n * See https://github.com/protocolbuffers/protobuf/blob/1b18833f4f2a2f681f4e4a25cdf3b0a43115ec26/js/binary/encoder.js#L144\n */\nexport function varint32write(value, bytes) {\n if (value >= 0) {\n // write value as varint 32\n while (value > 0x7f) {\n bytes.push((value & 0x7f) | 0x80);\n value = value >>> 7;\n }\n bytes.push(value);\n }\n else {\n for (let i = 0; i < 9; i++) {\n bytes.push((value & 127) | 128);\n value = value >> 7;\n }\n bytes.push(1);\n }\n}\n/**\n * Read an unsigned 32 bit varint.\n *\n * See https://github.com/protocolbuffers/protobuf/blob/8a71927d74a4ce34efe2d8769fda198f52d20d12/js/experimental/runtime/kernel/buffer_decoder.js#L220\n */\nexport function varint32read() {\n let b = this.buf[this.pos++];\n let result = b & 0x7f;\n if ((b & 0x80) == 0) {\n this.assertBounds();\n return result;\n }\n b = this.buf[this.pos++];\n result |= (b & 0x7f) << 7;\n if ((b & 0x80) == 0) {\n this.assertBounds();\n return result;\n }\n b = this.buf[this.pos++];\n result |= (b & 0x7f) << 14;\n if ((b & 0x80) == 0) {\n this.assertBounds();\n return result;\n }\n b = this.buf[this.pos++];\n result |= (b & 0x7f) << 21;\n if ((b & 0x80) == 0) {\n this.assertBounds();\n return result;\n }\n // Extract only last 4 bits\n b = this.buf[this.pos++];\n result |= (b & 0x0f) << 28;\n for (let readBytes = 5; (b & 0x80) !== 0 && readBytes < 10; readBytes++)\n b = this.buf[this.pos++];\n if ((b & 0x80) != 0)\n throw new Error(\"invalid varint\");\n this.assertBounds();\n // Result can have 32 bits, convert it to unsigned\n return result >>> 0;\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { assert } from \"./private/assert.js\";\nimport { int64FromString, int64ToString, uInt64ToString, } from \"./google/varint.js\";\nfunction makeInt64Support() {\n const dv = new DataView(new ArrayBuffer(8));\n // note that Safari 14 implements BigInt, but not the DataView methods\n const ok = typeof BigInt === \"function\" &&\n typeof dv.getBigInt64 === \"function\" &&\n typeof dv.getBigUint64 === \"function\" &&\n typeof dv.setBigInt64 === \"function\" &&\n typeof dv.setBigUint64 === \"function\" &&\n (typeof process != \"object\" ||\n typeof process.env != \"object\" ||\n process.env.BUF_BIGINT_DISABLE !== \"1\");\n if (ok) {\n const MIN = BigInt(\"-9223372036854775808\"), MAX = BigInt(\"9223372036854775807\"), UMIN = BigInt(\"0\"), UMAX = BigInt(\"18446744073709551615\");\n return {\n zero: BigInt(0),\n supported: true,\n parse(value) {\n const bi = typeof value == \"bigint\" ? value : BigInt(value);\n if (bi > MAX || bi < MIN) {\n throw new Error(`int64 invalid: ${value}`);\n }\n return bi;\n },\n uParse(value) {\n const bi = typeof value == \"bigint\" ? value : BigInt(value);\n if (bi > UMAX || bi < UMIN) {\n throw new Error(`uint64 invalid: ${value}`);\n }\n return bi;\n },\n enc(value) {\n dv.setBigInt64(0, this.parse(value), true);\n return {\n lo: dv.getInt32(0, true),\n hi: dv.getInt32(4, true),\n };\n },\n uEnc(value) {\n dv.setBigInt64(0, this.uParse(value), true);\n return {\n lo: dv.getInt32(0, true),\n hi: dv.getInt32(4, true),\n };\n },\n dec(lo, hi) {\n dv.setInt32(0, lo, true);\n dv.setInt32(4, hi, true);\n return dv.getBigInt64(0, true);\n },\n uDec(lo, hi) {\n dv.setInt32(0, lo, true);\n dv.setInt32(4, hi, true);\n return dv.getBigUint64(0, true);\n },\n };\n }\n const assertInt64String = (value) => assert(/^-?[0-9]+$/.test(value), `int64 invalid: ${value}`);\n const assertUInt64String = (value) => assert(/^[0-9]+$/.test(value), `uint64 invalid: ${value}`);\n return {\n zero: \"0\",\n supported: false,\n parse(value) {\n if (typeof value != \"string\") {\n value = value.toString();\n }\n assertInt64String(value);\n return value;\n },\n uParse(value) {\n if (typeof value != \"string\") {\n value = value.toString();\n }\n assertUInt64String(value);\n return value;\n },\n enc(value) {\n if (typeof value != \"string\") {\n value = value.toString();\n }\n assertInt64String(value);\n return int64FromString(value);\n },\n uEnc(value) {\n if (typeof value != \"string\") {\n value = value.toString();\n }\n assertUInt64String(value);\n return int64FromString(value);\n },\n dec(lo, hi) {\n return int64ToString(lo, hi);\n },\n uDec(lo, hi) {\n return uInt64ToString(lo, hi);\n },\n };\n}\nexport const protoInt64 = makeInt64Support();\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/**\n * Scalar value types. This is a subset of field types declared by protobuf\n * enum google.protobuf.FieldDescriptorProto.Type The types GROUP and MESSAGE\n * are omitted, but the numerical values are identical.\n */\nexport var ScalarType;\n(function (ScalarType) {\n // 0 is reserved for errors.\n // Order is weird for historical reasons.\n ScalarType[ScalarType[\"DOUBLE\"] = 1] = \"DOUBLE\";\n ScalarType[ScalarType[\"FLOAT\"] = 2] = \"FLOAT\";\n // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT64 if\n // negative values are likely.\n ScalarType[ScalarType[\"INT64\"] = 3] = \"INT64\";\n ScalarType[ScalarType[\"UINT64\"] = 4] = \"UINT64\";\n // Not ZigZag encoded. Negative numbers take 10 bytes. Use TYPE_SINT32 if\n // negative values are likely.\n ScalarType[ScalarType[\"INT32\"] = 5] = \"INT32\";\n ScalarType[ScalarType[\"FIXED64\"] = 6] = \"FIXED64\";\n ScalarType[ScalarType[\"FIXED32\"] = 7] = \"FIXED32\";\n ScalarType[ScalarType[\"BOOL\"] = 8] = \"BOOL\";\n ScalarType[ScalarType[\"STRING\"] = 9] = \"STRING\";\n // Tag-delimited aggregate.\n // Group type is deprecated and not supported in proto3. However, Proto3\n // implementations should still be able to parse the group wire format and\n // treat group fields as unknown fields.\n // TYPE_GROUP = 10,\n // TYPE_MESSAGE = 11, // Length-delimited aggregate.\n // New in version 2.\n ScalarType[ScalarType[\"BYTES\"] = 12] = \"BYTES\";\n ScalarType[ScalarType[\"UINT32\"] = 13] = \"UINT32\";\n // TYPE_ENUM = 14,\n ScalarType[ScalarType[\"SFIXED32\"] = 15] = \"SFIXED32\";\n ScalarType[ScalarType[\"SFIXED64\"] = 16] = \"SFIXED64\";\n ScalarType[ScalarType[\"SINT32\"] = 17] = \"SINT32\";\n ScalarType[ScalarType[\"SINT64\"] = 18] = \"SINT64\";\n})(ScalarType || (ScalarType = {}));\n/**\n * JavaScript representation of fields with 64 bit integral types (int64, uint64,\n * sint64, fixed64, sfixed64).\n *\n * This is a subset of google.protobuf.FieldOptions.JSType, which defines JS_NORMAL,\n * JS_STRING, and JS_NUMBER. Protobuf-ES uses BigInt by default, but will use\n * String if `[jstype = JS_STRING]` is specified.\n *\n * ```protobuf\n * uint64 field_a = 1; // BigInt\n * uint64 field_b = 2 [jstype = JS_NORMAL]; // BigInt\n * uint64 field_b = 2 [jstype = JS_NUMBER]; // BigInt\n * uint64 field_b = 2 [jstype = JS_STRING]; // String\n * ```\n */\nexport var LongType;\n(function (LongType) {\n /**\n * Use JavaScript BigInt.\n */\n LongType[LongType[\"BIGINT\"] = 0] = \"BIGINT\";\n /**\n * Use JavaScript String.\n *\n * Field option `[jstype = JS_STRING]`.\n */\n LongType[LongType[\"STRING\"] = 1] = \"STRING\";\n})(LongType || (LongType = {}));\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { varint32read, varint32write, varint64read, varint64write, } from \"./google/varint.js\";\nimport { assertFloat32, assertInt32, assertUInt32 } from \"./private/assert.js\";\nimport { protoInt64 } from \"./proto-int64.js\";\n/* eslint-disable prefer-const,no-case-declarations,@typescript-eslint/restrict-plus-operands */\n/**\n * Protobuf binary format wire types.\n *\n * A wire type provides just enough information to find the length of the\n * following value.\n *\n * See https://developers.google.com/protocol-buffers/docs/encoding#structure\n */\nexport var WireType;\n(function (WireType) {\n /**\n * Used for int32, int64, uint32, uint64, sint32, sint64, bool, enum\n */\n WireType[WireType[\"Varint\"] = 0] = \"Varint\";\n /**\n * Used for fixed64, sfixed64, double.\n * Always 8 bytes with little-endian byte order.\n */\n WireType[WireType[\"Bit64\"] = 1] = \"Bit64\";\n /**\n * Used for string, bytes, embedded messages, packed repeated fields\n *\n * Only repeated numeric types (types which use the varint, 32-bit,\n * or 64-bit wire types) can be packed. In proto3, such fields are\n * packed by default.\n */\n WireType[WireType[\"LengthDelimited\"] = 2] = \"LengthDelimited\";\n /**\n * Start of a tag-delimited aggregate, such as a proto2 group, or a message\n * in editions with message_encoding = DELIMITED.\n */\n WireType[WireType[\"StartGroup\"] = 3] = \"StartGroup\";\n /**\n * End of a tag-delimited aggregate.\n */\n WireType[WireType[\"EndGroup\"] = 4] = \"EndGroup\";\n /**\n * Used for fixed32, sfixed32, float.\n * Always 4 bytes with little-endian byte order.\n */\n WireType[WireType[\"Bit32\"] = 5] = \"Bit32\";\n})(WireType || (WireType = {}));\nexport class BinaryWriter {\n constructor(textEncoder) {\n /**\n * Previous fork states.\n */\n this.stack = [];\n this.textEncoder = textEncoder !== null && textEncoder !== void 0 ? textEncoder : new TextEncoder();\n this.chunks = [];\n this.buf = [];\n }\n /**\n * Return all bytes written and reset this writer.\n */\n finish() {\n this.chunks.push(new Uint8Array(this.buf)); // flush the buffer\n let len = 0;\n for (let i = 0; i < this.chunks.length; i++)\n len += this.chunks[i].length;\n let bytes = new Uint8Array(len);\n let offset = 0;\n for (let i = 0; i < this.chunks.length; i++) {\n bytes.set(this.chunks[i], offset);\n offset += this.chunks[i].length;\n }\n this.chunks = [];\n return bytes;\n }\n /**\n * Start a new fork for length-delimited data like a message\n * or a packed repeated field.\n *\n * Must be joined later with `join()`.\n */\n fork() {\n this.stack.push({ chunks: this.chunks, buf: this.buf });\n this.chunks = [];\n this.buf = [];\n return this;\n }\n /**\n * Join the last fork. Write its length and bytes, then\n * return to the previous state.\n */\n join() {\n // get chunk of fork\n let chunk = this.finish();\n // restore previous state\n let prev = this.stack.pop();\n if (!prev)\n throw new Error(\"invalid state, fork stack empty\");\n this.chunks = prev.chunks;\n this.buf = prev.buf;\n // write length of chunk as varint\n this.uint32(chunk.byteLength);\n return this.raw(chunk);\n }\n /**\n * Writes a tag (field number and wire type).\n *\n * Equivalent to `uint32( (fieldNo << 3 | type) >>> 0 )`.\n *\n * Generated code should compute the tag ahead of time and call `uint32()`.\n */\n tag(fieldNo, type) {\n return this.uint32(((fieldNo << 3) | type) >>> 0);\n }\n /**\n * Write a chunk of raw bytes.\n */\n raw(chunk) {\n if (this.buf.length) {\n this.chunks.push(new Uint8Array(this.buf));\n this.buf = [];\n }\n this.chunks.push(chunk);\n return this;\n }\n /**\n * Write a `uint32` value, an unsigned 32 bit varint.\n */\n uint32(value) {\n assertUInt32(value);\n // write value as varint 32, inlined for speed\n while (value > 0x7f) {\n this.buf.push((value & 0x7f) | 0x80);\n value = value >>> 7;\n }\n this.buf.push(value);\n return this;\n }\n /**\n * Write a `int32` value, a signed 32 bit varint.\n */\n int32(value) {\n assertInt32(value);\n varint32write(value, this.buf);\n return this;\n }\n /**\n * Write a `bool` value, a variant.\n */\n bool(value) {\n this.buf.push(value ? 1 : 0);\n return this;\n }\n /**\n * Write a `bytes` value, length-delimited arbitrary data.\n */\n bytes(value) {\n this.uint32(value.byteLength); // write length of chunk as varint\n return this.raw(value);\n }\n /**\n * Write a `string` value, length-delimited data converted to UTF-8 text.\n */\n string(value) {\n let chunk = this.textEncoder.encode(value);\n this.uint32(chunk.byteLength); // write length of chunk as varint\n return this.raw(chunk);\n }\n /**\n * Write a `float` value, 32-bit floating point number.\n */\n float(value) {\n assertFloat32(value);\n let chunk = new Uint8Array(4);\n new DataView(chunk.buffer).setFloat32(0, value, true);\n return this.raw(chunk);\n }\n /**\n * Write a `double` value, a 64-bit floating point number.\n */\n double(value) {\n let chunk = new Uint8Array(8);\n new DataView(chunk.buffer).setFloat64(0, value, true);\n return this.raw(chunk);\n }\n /**\n * Write a `fixed32` value, an unsigned, fixed-length 32-bit integer.\n */\n fixed32(value) {\n assertUInt32(value);\n let chunk = new Uint8Array(4);\n new DataView(chunk.buffer).setUint32(0, value, true);\n return this.raw(chunk);\n }\n /**\n * Write a `sfixed32` value, a signed, fixed-length 32-bit integer.\n */\n sfixed32(value) {\n assertInt32(value);\n let chunk = new Uint8Array(4);\n new DataView(chunk.buffer).setInt32(0, value, true);\n return this.raw(chunk);\n }\n /**\n * Write a `sint32` value, a signed, zigzag-encoded 32-bit varint.\n */\n sint32(value) {\n assertInt32(value);\n // zigzag encode\n value = ((value << 1) ^ (value >> 31)) >>> 0;\n varint32write(value, this.buf);\n return this;\n }\n /**\n * Write a `fixed64` value, a signed, fixed-length 64-bit integer.\n */\n sfixed64(value) {\n let chunk = new Uint8Array(8), view = new DataView(chunk.buffer), tc = protoInt64.enc(value);\n view.setInt32(0, tc.lo, true);\n view.setInt32(4, tc.hi, true);\n return this.raw(chunk);\n }\n /**\n * Write a `fixed64` value, an unsigned, fixed-length 64 bit integer.\n */\n fixed64(value) {\n let chunk = new Uint8Array(8), view = new DataView(chunk.buffer), tc = protoInt64.uEnc(value);\n view.setInt32(0, tc.lo, true);\n view.setInt32(4, tc.hi, true);\n return this.raw(chunk);\n }\n /**\n * Write a `int64` value, a signed 64-bit varint.\n */\n int64(value) {\n let tc = protoInt64.enc(value);\n varint64write(tc.lo, tc.hi, this.buf);\n return this;\n }\n /**\n * Write a `sint64` value, a signed, zig-zag-encoded 64-bit varint.\n */\n sint64(value) {\n let tc = protoInt64.enc(value), \n // zigzag encode\n sign = tc.hi >> 31, lo = (tc.lo << 1) ^ sign, hi = ((tc.hi << 1) | (tc.lo >>> 31)) ^ sign;\n varint64write(lo, hi, this.buf);\n return this;\n }\n /**\n * Write a `uint64` value, an unsigned 64-bit varint.\n */\n uint64(value) {\n let tc = protoInt64.uEnc(value);\n varint64write(tc.lo, tc.hi, this.buf);\n return this;\n }\n}\nexport class BinaryReader {\n constructor(buf, textDecoder) {\n this.varint64 = varint64read; // dirty cast for `this`\n /**\n * Read a `uint32` field, an unsigned 32 bit varint.\n */\n this.uint32 = varint32read; // dirty cast for `this` and access to protected `buf`\n this.buf = buf;\n this.len = buf.length;\n this.pos = 0;\n this.view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);\n this.textDecoder = textDecoder !== null && textDecoder !== void 0 ? textDecoder : new TextDecoder();\n }\n /**\n * Reads a tag - field number and wire type.\n */\n tag() {\n let tag = this.uint32(), fieldNo = tag >>> 3, wireType = tag & 7;\n if (fieldNo <= 0 || wireType < 0 || wireType > 5)\n throw new Error(\"illegal tag: field no \" + fieldNo + \" wire type \" + wireType);\n return [fieldNo, wireType];\n }\n /**\n * Skip one element and return the skipped data.\n *\n * When skipping StartGroup, provide the tags field number to check for\n * matching field number in the EndGroup tag.\n */\n skip(wireType, fieldNo) {\n let start = this.pos;\n switch (wireType) {\n case WireType.Varint:\n while (this.buf[this.pos++] & 0x80) {\n // ignore\n }\n break;\n // eslint-disable-next-line\n // @ts-ignore TS7029: Fallthrough case in switch\n case WireType.Bit64:\n this.pos += 4;\n // eslint-disable-next-line\n // @ts-ignore TS7029: Fallthrough case in switch\n case WireType.Bit32:\n this.pos += 4;\n break;\n case WireType.LengthDelimited:\n let len = this.uint32();\n this.pos += len;\n break;\n case WireType.StartGroup:\n for (;;) {\n const [fn, wt] = this.tag();\n if (wt === WireType.EndGroup) {\n if (fieldNo !== undefined && fn !== fieldNo) {\n throw new Error(\"invalid end group tag\");\n }\n break;\n }\n this.skip(wt, fn);\n }\n break;\n default:\n throw new Error(\"cant skip wire type \" + wireType);\n }\n this.assertBounds();\n return this.buf.subarray(start, this.pos);\n }\n /**\n * Throws error if position in byte array is out of range.\n */\n assertBounds() {\n if (this.pos > this.len)\n throw new RangeError(\"premature EOF\");\n }\n /**\n * Read a `int32` field, a signed 32 bit varint.\n */\n int32() {\n return this.uint32() | 0;\n }\n /**\n * Read a `sint32` field, a signed, zigzag-encoded 32-bit varint.\n */\n sint32() {\n let zze = this.uint32();\n // decode zigzag\n return (zze >>> 1) ^ -(zze & 1);\n }\n /**\n * Read a `int64` field, a signed 64-bit varint.\n */\n int64() {\n return protoInt64.dec(...this.varint64());\n }\n /**\n * Read a `uint64` field, an unsigned 64-bit varint.\n */\n uint64() {\n return protoInt64.uDec(...this.varint64());\n }\n /**\n * Read a `sint64` field, a signed, zig-zag-encoded 64-bit varint.\n */\n sint64() {\n let [lo, hi] = this.varint64();\n // decode zig zag\n let s = -(lo & 1);\n lo = ((lo >>> 1) | ((hi & 1) << 31)) ^ s;\n hi = (hi >>> 1) ^ s;\n return protoInt64.dec(lo, hi);\n }\n /**\n * Read a `bool` field, a variant.\n */\n bool() {\n let [lo, hi] = this.varint64();\n return lo !== 0 || hi !== 0;\n }\n /**\n * Read a `fixed32` field, an unsigned, fixed-length 32-bit integer.\n */\n fixed32() {\n return this.view.getUint32((this.pos += 4) - 4, true);\n }\n /**\n * Read a `sfixed32` field, a signed, fixed-length 32-bit integer.\n */\n sfixed32() {\n return this.view.getInt32((this.pos += 4) - 4, true);\n }\n /**\n * Read a `fixed64` field, an unsigned, fixed-length 64 bit integer.\n */\n fixed64() {\n return protoInt64.uDec(this.sfixed32(), this.sfixed32());\n }\n /**\n * Read a `fixed64` field, a signed, fixed-length 64-bit integer.\n */\n sfixed64() {\n return protoInt64.dec(this.sfixed32(), this.sfixed32());\n }\n /**\n * Read a `float` field, 32-bit floating point number.\n */\n float() {\n return this.view.getFloat32((this.pos += 4) - 4, true);\n }\n /**\n * Read a `double` field, a 64-bit floating point number.\n */\n double() {\n return this.view.getFloat64((this.pos += 8) - 8, true);\n }\n /**\n * Read a `bytes` field, length-delimited arbitrary data.\n */\n bytes() {\n let len = this.uint32(), start = this.pos;\n this.pos += len;\n this.assertBounds();\n return this.buf.subarray(start, start + len);\n }\n /**\n * Read a `string` field, length-delimited data converted to UTF-8 text.\n */\n string() {\n return this.textDecoder.decode(this.bytes());\n }\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { protoInt64 } from \"../proto-int64.js\";\nimport { LongType, ScalarType } from \"../scalar.js\";\n/**\n * Returns true if both scalar values are equal.\n */\nexport function scalarEquals(type, a, b) {\n if (a === b) {\n // This correctly matches equal values except BYTES and (possibly) 64-bit integers.\n return true;\n }\n // Special case BYTES - we need to compare each byte individually\n if (type == ScalarType.BYTES) {\n if (!(a instanceof Uint8Array) || !(b instanceof Uint8Array)) {\n return false;\n }\n if (a.length !== b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) {\n return false;\n }\n }\n return true;\n }\n // Special case 64-bit integers - we support number, string and bigint representation.\n // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check\n switch (type) {\n case ScalarType.UINT64:\n case ScalarType.FIXED64:\n case ScalarType.INT64:\n case ScalarType.SFIXED64:\n case ScalarType.SINT64:\n // Loose comparison will match between 0n, 0 and \"0\".\n return a == b;\n }\n // Anything that hasn't been caught by strict comparison or special cased\n // BYTES and 64-bit integers is not equal.\n return false;\n}\n/**\n * Returns the zero value for the given scalar type.\n */\nexport function scalarZeroValue(type, longType) {\n switch (type) {\n case ScalarType.BOOL:\n return false;\n case ScalarType.UINT64:\n case ScalarType.FIXED64:\n case ScalarType.INT64:\n case ScalarType.SFIXED64:\n case ScalarType.SINT64:\n // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison -- acceptable since it's covered by tests\n return (longType == 0 ? protoInt64.zero : \"0\");\n case ScalarType.DOUBLE:\n case ScalarType.FLOAT:\n return 0.0;\n case ScalarType.BYTES:\n return new Uint8Array(0);\n case ScalarType.STRING:\n return \"\";\n default:\n // Handles INT32, UINT32, SINT32, FIXED32, SFIXED32.\n // We do not use individual cases to save a few bytes code size.\n return 0;\n }\n}\n/**\n * Returns true for a zero-value. For example, an integer has the zero-value `0`,\n * a boolean is `false`, a string is `\"\"`, and bytes is an empty Uint8Array.\n *\n * In proto3, zero-values are not written to the wire, unless the field is\n * optional or repeated.\n */\nexport function isScalarZeroValue(type, value) {\n switch (type) {\n case ScalarType.BOOL:\n return value === false;\n case ScalarType.STRING:\n return value === \"\";\n case ScalarType.BYTES:\n return value instanceof Uint8Array && !value.byteLength;\n default:\n return value == 0; // Loose comparison matches 0n, 0 and \"0\"\n }\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { scalarZeroValue } from \"./scalars.js\";\nimport { WireType } from \"../binary-encoding.js\";\n/**\n * Create a new extension using the given runtime.\n */\nexport function makeExtension(runtime, typeName, extendee, field) {\n let fi;\n return {\n typeName,\n extendee,\n get field() {\n if (!fi) {\n const i = (typeof field == \"function\" ? field() : field);\n i.name = typeName.split(\".\").pop();\n i.jsonName = `[${typeName}]`;\n fi = runtime.util.newFieldList([i]).list()[0];\n }\n return fi;\n },\n runtime,\n };\n}\n/**\n * Create a container that allows us to read extension fields into it with the\n * same logic as regular fields.\n */\nexport function createExtensionContainer(extension) {\n const localName = extension.field.localName;\n const container = Object.create(null);\n container[localName] = initExtensionField(extension);\n return [container, () => container[localName]];\n}\nfunction initExtensionField(ext) {\n const field = ext.field;\n if (field.repeated) {\n return [];\n }\n if (field.default !== undefined) {\n return field.default;\n }\n switch (field.kind) {\n case \"enum\":\n return field.T.values[0].no;\n case \"scalar\":\n return scalarZeroValue(field.T, field.L);\n case \"message\":\n // eslint-disable-next-line no-case-declarations\n const T = field.T, value = new T();\n return T.fieldWrapper ? T.fieldWrapper.unwrapField(value) : value;\n case \"map\":\n throw \"map fields are not allowed to be extensions\";\n }\n}\n/**\n * Helper to filter unknown fields, optimized based on field type.\n */\nexport function filterUnknownFields(unknownFields, field) {\n if (!field.repeated && (field.kind == \"enum\" || field.kind == \"scalar\")) {\n // singular scalar fields do not merge, we pick the last\n for (let i = unknownFields.length - 1; i >= 0; --i) {\n if (unknownFields[i].no == field.no) {\n return [unknownFields[i]];\n }\n }\n return [];\n }\n return unknownFields.filter((uf) => uf.no === field.no);\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/* eslint-disable @typescript-eslint/ban-ts-comment, @typescript-eslint/no-unnecessary-condition, prefer-const */\n// lookup table from base64 character to byte\nlet encTable = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\".split(\"\");\n// lookup table from base64 character *code* to byte because lookup by number is fast\nlet decTable = [];\nfor (let i = 0; i < encTable.length; i++)\n decTable[encTable[i].charCodeAt(0)] = i;\n// support base64url variants\ndecTable[\"-\".charCodeAt(0)] = encTable.indexOf(\"+\");\ndecTable[\"_\".charCodeAt(0)] = encTable.indexOf(\"/\");\nexport const protoBase64 = {\n /**\n * Decodes a base64 string to a byte array.\n *\n * - ignores white-space, including line breaks and tabs\n * - allows inner padding (can decode concatenated base64 strings)\n * - does not require padding\n * - understands base64url encoding:\n * \"-\" instead of \"+\",\n * \"_\" instead of \"/\",\n * no padding\n */\n dec(base64Str) {\n // estimate byte size, not accounting for inner padding and whitespace\n let es = (base64Str.length * 3) / 4;\n if (base64Str[base64Str.length - 2] == \"=\")\n es -= 2;\n else if (base64Str[base64Str.length - 1] == \"=\")\n es -= 1;\n let bytes = new Uint8Array(es), bytePos = 0, // position in byte array\n groupPos = 0, // position in base64 group\n b, // current byte\n p = 0; // previous byte\n for (let i = 0; i < base64Str.length; i++) {\n b = decTable[base64Str.charCodeAt(i)];\n if (b === undefined) {\n switch (base64Str[i]) {\n // @ts-ignore TS7029: Fallthrough case in switch\n case \"=\":\n groupPos = 0; // reset state when padding found\n // @ts-ignore TS7029: Fallthrough case in switch\n case \"\\n\":\n case \"\\r\":\n case \"\\t\":\n case \" \":\n continue; // skip white-space, and padding\n default:\n throw Error(\"invalid base64 string.\");\n }\n }\n switch (groupPos) {\n case 0:\n p = b;\n groupPos = 1;\n break;\n case 1:\n bytes[bytePos++] = (p << 2) | ((b & 48) >> 4);\n p = b;\n groupPos = 2;\n break;\n case 2:\n bytes[bytePos++] = ((p & 15) << 4) | ((b & 60) >> 2);\n p = b;\n groupPos = 3;\n break;\n case 3:\n bytes[bytePos++] = ((p & 3) << 6) | b;\n groupPos = 0;\n break;\n }\n }\n if (groupPos == 1)\n throw Error(\"invalid base64 string.\");\n return bytes.subarray(0, bytePos);\n },\n /**\n * Encode a byte array to a base64 string.\n */\n enc(bytes) {\n let base64 = \"\", groupPos = 0, // position in base64 group\n b, // current byte\n p = 0; // carry over from previous byte\n for (let i = 0; i < bytes.length; i++) {\n b = bytes[i];\n switch (groupPos) {\n case 0:\n base64 += encTable[b >> 2];\n p = (b & 3) << 4;\n groupPos = 1;\n break;\n case 1:\n base64 += encTable[p | (b >> 4)];\n p = (b & 15) << 2;\n groupPos = 2;\n break;\n case 2:\n base64 += encTable[p | (b >> 6)];\n base64 += encTable[b & 63];\n groupPos = 0;\n break;\n }\n }\n // add output padding\n if (groupPos) {\n base64 += encTable[p];\n base64 += \"=\";\n if (groupPos == 1)\n base64 += \"=\";\n }\n return base64;\n },\n};\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { assert } from \"./private/assert.js\";\nimport { createExtensionContainer, filterUnknownFields, } from \"./private/extensions.js\";\n/**\n * Retrieve an extension value from a message.\n *\n * The function never returns undefined. Use hasExtension() to check whether an\n * extension is set. If the extension is not set, this function returns the\n * default value (if one was specified in the protobuf source), or the zero value\n * (for example `0` for numeric types, `[]` for repeated extension fields, and\n * an empty message instance for message fields).\n *\n * Extensions are stored as unknown fields on a message. To mutate an extension\n * value, make sure to store the new value with setExtension() after mutating.\n *\n * If the extension does not extend the given message, an error is raised.\n */\nexport function getExtension(message, extension, options) {\n assertExtendee(extension, message);\n const opt = extension.runtime.bin.makeReadOptions(options);\n const ufs = filterUnknownFields(message.getType().runtime.bin.listUnknownFields(message), extension.field);\n const [container, get] = createExtensionContainer(extension);\n for (const uf of ufs) {\n extension.runtime.bin.readField(container, opt.readerFactory(uf.data), extension.field, uf.wireType, opt);\n }\n return get();\n}\n/**\n * Set an extension value on a message. If the message already has a value for\n * this extension, the value is replaced.\n *\n * If the extension does not extend the given message, an error is raised.\n */\nexport function setExtension(message, extension, value, options) {\n assertExtendee(extension, message);\n const readOpt = extension.runtime.bin.makeReadOptions(options);\n const writeOpt = extension.runtime.bin.makeWriteOptions(options);\n if (hasExtension(message, extension)) {\n const ufs = message\n .getType()\n .runtime.bin.listUnknownFields(message)\n .filter((uf) => uf.no != extension.field.no);\n message.getType().runtime.bin.discardUnknownFields(message);\n for (const uf of ufs) {\n message\n .getType()\n .runtime.bin.onUnknownField(message, uf.no, uf.wireType, uf.data);\n }\n }\n const writer = writeOpt.writerFactory();\n let f = extension.field;\n // Implicit presence does not apply to extensions, see https://github.com/protocolbuffers/protobuf/issues/8234\n // We patch the field info to use explicit presence:\n if (!f.opt && !f.repeated && (f.kind == \"enum\" || f.kind == \"scalar\")) {\n f = Object.assign(Object.assign({}, extension.field), { opt: true });\n }\n extension.runtime.bin.writeField(f, value, writer, writeOpt);\n const reader = readOpt.readerFactory(writer.finish());\n while (reader.pos < reader.len) {\n const [no, wireType] = reader.tag();\n const data = reader.skip(wireType, no);\n message.getType().runtime.bin.onUnknownField(message, no, wireType, data);\n }\n}\n/**\n * Remove an extension value from a message.\n *\n * If the extension does not extend the given message, an error is raised.\n */\nexport function clearExtension(message, extension) {\n assertExtendee(extension, message);\n if (hasExtension(message, extension)) {\n const bin = message.getType().runtime.bin;\n const ufs = bin\n .listUnknownFields(message)\n .filter((uf) => uf.no != extension.field.no);\n bin.discardUnknownFields(message);\n for (const uf of ufs) {\n bin.onUnknownField(message, uf.no, uf.wireType, uf.data);\n }\n }\n}\n/**\n * Check whether an extension is set on a message.\n */\nexport function hasExtension(message, extension) {\n const messageType = message.getType();\n return (extension.extendee.typeName === messageType.typeName &&\n !!messageType.runtime.bin\n .listUnknownFields(message)\n .find((uf) => uf.no == extension.field.no));\n}\nfunction assertExtendee(extension, message) {\n assert(extension.extendee.typeName == message.getType().typeName, `extension ${extension.typeName} can only be applied to message ${extension.extendee.typeName}`);\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { isScalarZeroValue, scalarZeroValue } from \"./scalars.js\";\n/**\n * Returns true if the field is set.\n */\nexport function isFieldSet(field, target) {\n const localName = field.localName;\n if (field.repeated) {\n return target[localName].length > 0;\n }\n if (field.oneof) {\n return target[field.oneof.localName].case === localName; // eslint-disable-line @typescript-eslint/no-unsafe-member-access\n }\n switch (field.kind) {\n case \"enum\":\n case \"scalar\":\n if (field.opt || field.req) {\n // explicit presence\n return target[localName] !== undefined;\n }\n // implicit presence\n if (field.kind == \"enum\") {\n return target[localName] !== field.T.values[0].no;\n }\n return !isScalarZeroValue(field.T, target[localName]);\n case \"message\":\n return target[localName] !== undefined;\n case \"map\":\n return Object.keys(target[localName]).length > 0; // eslint-disable-line @typescript-eslint/no-unsafe-argument\n }\n}\n/**\n * Resets the field, so that isFieldSet() will return false.\n */\nexport function clearField(field, target) {\n const localName = field.localName;\n const implicitPresence = !field.opt && !field.req;\n if (field.repeated) {\n target[localName] = [];\n }\n else if (field.oneof) {\n target[field.oneof.localName] = { case: undefined };\n }\n else {\n switch (field.kind) {\n case \"map\":\n target[localName] = {};\n break;\n case \"enum\":\n target[localName] = implicitPresence ? field.T.values[0].no : undefined;\n break;\n case \"scalar\":\n target[localName] = implicitPresence\n ? scalarZeroValue(field.T, field.L)\n : undefined;\n break;\n case \"message\":\n target[localName] = undefined;\n break;\n }\n }\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { Message } from \"./message.js\";\n/**\n * Check whether the given object is any subtype of Message or is a specific\n * Message by passing the type.\n *\n * Just like `instanceof`, `isMessage` narrows the type. The advantage of\n * `isMessage` is that it compares identity by the message type name, not by\n * class identity. This makes it robust against the dual package hazard and\n * similar situations, where the same message is duplicated.\n *\n * This function is _mostly_ equivalent to the `instanceof` operator. For\n * example, `isMessage(foo, MyMessage)` is the same as `foo instanceof MyMessage`,\n * and `isMessage(foo)` is the same as `foo instanceof Message`. In most cases,\n * `isMessage` should be preferred over `instanceof`.\n *\n * However, due to the fact that `isMessage` does not use class identity, there\n * are subtle differences between this function and `instanceof`. Notably,\n * calling `isMessage` on an explicit type of Message will return false.\n */\nexport function isMessage(arg, type) {\n if (arg === null || typeof arg != \"object\") {\n return false;\n }\n if (!Object.getOwnPropertyNames(Message.prototype).every((m) => m in arg && typeof arg[m] == \"function\")) {\n return false;\n }\n const actualType = arg.getType();\n if (actualType === null ||\n typeof actualType != \"function\" ||\n !(\"typeName\" in actualType) ||\n typeof actualType.typeName != \"string\") {\n return false;\n }\n return type === undefined ? true : actualType.typeName == type.typeName;\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { Message } from \"../message.js\";\nimport { ScalarType } from \"../scalar.js\";\nimport { isMessage } from \"../is-message.js\";\n/**\n * Wrap a primitive message field value in its corresponding wrapper\n * message. This function is idempotent.\n */\nexport function wrapField(type, value) {\n if (isMessage(value) || !type.fieldWrapper) {\n return value;\n }\n return type.fieldWrapper.wrapField(value);\n}\n/**\n * If the given field uses one of the well-known wrapper types, return\n * the primitive type it wraps.\n */\nexport function getUnwrappedFieldType(field) {\n if (field.fieldKind !== \"message\") {\n return undefined;\n }\n if (field.repeated) {\n return undefined;\n }\n if (field.oneof != undefined) {\n return undefined;\n }\n return wktWrapperToScalarType[field.message.typeName];\n}\nconst wktWrapperToScalarType = {\n \"google.protobuf.DoubleValue\": ScalarType.DOUBLE,\n \"google.protobuf.FloatValue\": ScalarType.FLOAT,\n \"google.protobuf.Int64Value\": ScalarType.INT64,\n \"google.protobuf.UInt64Value\": ScalarType.UINT64,\n \"google.protobuf.Int32Value\": ScalarType.INT32,\n \"google.protobuf.UInt32Value\": ScalarType.UINT32,\n \"google.protobuf.BoolValue\": ScalarType.BOOL,\n \"google.protobuf.StringValue\": ScalarType.STRING,\n \"google.protobuf.BytesValue\": ScalarType.BYTES,\n};\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { Message } from \"../message.js\";\nimport { assert, assertFloat32, assertInt32, assertUInt32 } from \"./assert.js\";\nimport { protoInt64 } from \"../proto-int64.js\";\nimport { protoBase64 } from \"../proto-base64.js\";\nimport { createExtensionContainer } from \"./extensions.js\";\nimport { getExtension, hasExtension, setExtension, } from \"../extension-accessor.js\";\nimport { clearField, isFieldSet } from \"./reflect.js\";\nimport { wrapField } from \"./field-wrapper.js\";\nimport { scalarZeroValue } from \"./scalars.js\";\nimport { isScalarZeroValue } from \"./scalars.js\";\nimport { LongType, ScalarType } from \"../scalar.js\";\nimport { isMessage } from \"../is-message.js\";\n/* eslint-disable no-case-declarations,@typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call */\n// Default options for parsing JSON.\nconst jsonReadDefaults = {\n ignoreUnknownFields: false,\n};\n// Default options for serializing to JSON.\nconst jsonWriteDefaults = {\n emitDefaultValues: false,\n enumAsInteger: false,\n useProtoFieldName: false,\n prettySpaces: 0,\n};\nfunction makeReadOptions(options) {\n return options ? Object.assign(Object.assign({}, jsonReadDefaults), options) : jsonReadDefaults;\n}\nfunction makeWriteOptions(options) {\n return options ? Object.assign(Object.assign({}, jsonWriteDefaults), options) : jsonWriteDefaults;\n}\nconst tokenNull = Symbol();\nconst tokenIgnoredUnknownEnum = Symbol();\nexport function makeJsonFormat() {\n return {\n makeReadOptions,\n makeWriteOptions,\n readMessage(type, json, options, message) {\n if (json == null || Array.isArray(json) || typeof json != \"object\") {\n throw new Error(`cannot decode message ${type.typeName} from JSON: ${debugJsonValue(json)}`);\n }\n message = message !== null && message !== void 0 ? message : new type();\n const oneofSeen = new Map();\n const registry = options.typeRegistry;\n for (const [jsonKey, jsonValue] of Object.entries(json)) {\n const field = type.fields.findJsonName(jsonKey);\n if (field) {\n if (field.oneof) {\n if (jsonValue === null && field.kind == \"scalar\") {\n // see conformance test Required.Proto3.JsonInput.OneofFieldNull{First,Second}\n continue;\n }\n const seen = oneofSeen.get(field.oneof);\n if (seen !== undefined) {\n throw new Error(`cannot decode message ${type.typeName} from JSON: multiple keys for oneof \"${field.oneof.name}\" present: \"${seen}\", \"${jsonKey}\"`);\n }\n oneofSeen.set(field.oneof, jsonKey);\n }\n readField(message, jsonValue, field, options, type);\n }\n else {\n let found = false;\n if ((registry === null || registry === void 0 ? void 0 : registry.findExtension) &&\n jsonKey.startsWith(\"[\") &&\n jsonKey.endsWith(\"]\")) {\n const ext = registry.findExtension(jsonKey.substring(1, jsonKey.length - 1));\n if (ext && ext.extendee.typeName == type.typeName) {\n found = true;\n const [container, get] = createExtensionContainer(ext);\n readField(container, jsonValue, ext.field, options, ext);\n // We pass on the options as BinaryReadOptions/BinaryWriteOptions,\n // so that users can bring their own binary reader and writer factories\n // if necessary.\n setExtension(message, ext, get(), options);\n }\n }\n if (!found && !options.ignoreUnknownFields) {\n throw new Error(`cannot decode message ${type.typeName} from JSON: key \"${jsonKey}\" is unknown`);\n }\n }\n }\n return message;\n },\n writeMessage(message, options) {\n const type = message.getType();\n const json = {};\n let field;\n try {\n for (field of type.fields.byNumber()) {\n if (!isFieldSet(field, message)) {\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n if (field.req) {\n throw `required field not set`;\n }\n if (!options.emitDefaultValues) {\n continue;\n }\n if (!canEmitFieldDefaultValue(field)) {\n continue;\n }\n }\n const value = field.oneof\n ? message[field.oneof.localName].value\n : message[field.localName];\n const jsonValue = writeField(field, value, options);\n if (jsonValue !== undefined) {\n json[options.useProtoFieldName ? field.name : field.jsonName] =\n jsonValue;\n }\n }\n const registry = options.typeRegistry;\n if (registry === null || registry === void 0 ? void 0 : registry.findExtensionFor) {\n for (const uf of type.runtime.bin.listUnknownFields(message)) {\n const ext = registry.findExtensionFor(type.typeName, uf.no);\n if (ext && hasExtension(message, ext)) {\n // We pass on the options as BinaryReadOptions, so that users can bring their own\n // binary reader factory if necessary.\n const value = getExtension(message, ext, options);\n const jsonValue = writeField(ext.field, value, options);\n if (jsonValue !== undefined) {\n json[ext.field.jsonName] = jsonValue;\n }\n }\n }\n }\n }\n catch (e) {\n const m = field\n ? `cannot encode field ${type.typeName}.${field.name} to JSON`\n : `cannot encode message ${type.typeName} to JSON`;\n const r = e instanceof Error ? e.message : String(e);\n throw new Error(m + (r.length > 0 ? `: ${r}` : \"\"));\n }\n return json;\n },\n readScalar(type, json, longType) {\n // The signature of our internal function has changed. For backwards-\n // compatibility, we support the old form that is part of the public API\n // through the interface JsonFormat.\n return readScalar(type, json, longType !== null && longType !== void 0 ? longType : LongType.BIGINT, true);\n },\n writeScalar(type, value, emitDefaultValues) {\n // The signature of our internal function has changed. For backwards-\n // compatibility, we support the old form that is part of the public API\n // through the interface JsonFormat.\n if (value === undefined) {\n return undefined;\n }\n if (emitDefaultValues || isScalarZeroValue(type, value)) {\n return writeScalar(type, value);\n }\n return undefined;\n },\n debug: debugJsonValue,\n };\n}\nfunction debugJsonValue(json) {\n if (json === null) {\n return \"null\";\n }\n switch (typeof json) {\n case \"object\":\n return Array.isArray(json) ? \"array\" : \"object\";\n case \"string\":\n return json.length > 100 ? \"string\" : `\"${json.split('\"').join('\\\\\"')}\"`;\n default:\n return String(json);\n }\n}\n// Read a JSON value for a field.\n// The \"parentType\" argument is only used to provide context in errors.\nfunction readField(target, jsonValue, field, options, parentType) {\n let localName = field.localName;\n if (field.repeated) {\n assert(field.kind != \"map\");\n if (jsonValue === null) {\n return;\n }\n if (!Array.isArray(jsonValue)) {\n throw new Error(`cannot decode field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`);\n }\n const targetArray = target[localName];\n for (const jsonItem of jsonValue) {\n if (jsonItem === null) {\n throw new Error(`cannot decode field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonItem)}`);\n }\n switch (field.kind) {\n case \"message\":\n targetArray.push(field.T.fromJson(jsonItem, options));\n break;\n case \"enum\":\n const enumValue = readEnum(field.T, jsonItem, options.ignoreUnknownFields, true);\n if (enumValue !== tokenIgnoredUnknownEnum) {\n targetArray.push(enumValue);\n }\n break;\n case \"scalar\":\n try {\n targetArray.push(readScalar(field.T, jsonItem, field.L, true));\n }\n catch (e) {\n let m = `cannot decode field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonItem)}`;\n if (e instanceof Error && e.message.length > 0) {\n m += `: ${e.message}`;\n }\n throw new Error(m);\n }\n break;\n }\n }\n }\n else if (field.kind == \"map\") {\n if (jsonValue === null) {\n return;\n }\n if (typeof jsonValue != \"object\" || Array.isArray(jsonValue)) {\n throw new Error(`cannot decode field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`);\n }\n const targetMap = target[localName];\n for (const [jsonMapKey, jsonMapValue] of Object.entries(jsonValue)) {\n if (jsonMapValue === null) {\n throw new Error(`cannot decode field ${parentType.typeName}.${field.name} from JSON: map value null`);\n }\n let key;\n try {\n key = readMapKey(field.K, jsonMapKey);\n }\n catch (e) {\n let m = `cannot decode map key for field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;\n if (e instanceof Error && e.message.length > 0) {\n m += `: ${e.message}`;\n }\n throw new Error(m);\n }\n switch (field.V.kind) {\n case \"message\":\n targetMap[key] = field.V.T.fromJson(jsonMapValue, options);\n break;\n case \"enum\":\n const enumValue = readEnum(field.V.T, jsonMapValue, options.ignoreUnknownFields, true);\n if (enumValue !== tokenIgnoredUnknownEnum) {\n targetMap[key] = enumValue;\n }\n break;\n case \"scalar\":\n try {\n targetMap[key] = readScalar(field.V.T, jsonMapValue, LongType.BIGINT, true);\n }\n catch (e) {\n let m = `cannot decode map value for field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;\n if (e instanceof Error && e.message.length > 0) {\n m += `: ${e.message}`;\n }\n throw new Error(m);\n }\n break;\n }\n }\n }\n else {\n if (field.oneof) {\n target = target[field.oneof.localName] = { case: localName };\n localName = \"value\";\n }\n switch (field.kind) {\n case \"message\":\n const messageType = field.T;\n if (jsonValue === null &&\n messageType.typeName != \"google.protobuf.Value\") {\n return;\n }\n let currentValue = target[localName];\n if (isMessage(currentValue)) {\n currentValue.fromJson(jsonValue, options);\n }\n else {\n target[localName] = currentValue = messageType.fromJson(jsonValue, options);\n if (messageType.fieldWrapper && !field.oneof) {\n target[localName] =\n messageType.fieldWrapper.unwrapField(currentValue);\n }\n }\n break;\n case \"enum\":\n const enumValue = readEnum(field.T, jsonValue, options.ignoreUnknownFields, false);\n switch (enumValue) {\n case tokenNull:\n clearField(field, target);\n break;\n case tokenIgnoredUnknownEnum:\n break;\n default:\n target[localName] = enumValue;\n break;\n }\n break;\n case \"scalar\":\n try {\n const scalarValue = readScalar(field.T, jsonValue, field.L, false);\n switch (scalarValue) {\n case tokenNull:\n clearField(field, target);\n break;\n default:\n target[localName] = scalarValue;\n break;\n }\n }\n catch (e) {\n let m = `cannot decode field ${parentType.typeName}.${field.name} from JSON: ${debugJsonValue(jsonValue)}`;\n if (e instanceof Error && e.message.length > 0) {\n m += `: ${e.message}`;\n }\n throw new Error(m);\n }\n break;\n }\n }\n}\nfunction readMapKey(type, json) {\n if (type === ScalarType.BOOL) {\n // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check\n switch (json) {\n case \"true\":\n json = true;\n break;\n case \"false\":\n json = false;\n break;\n }\n }\n return readScalar(type, json, LongType.BIGINT, true).toString();\n}\nfunction readScalar(type, json, longType, nullAsZeroValue) {\n if (json === null) {\n if (nullAsZeroValue) {\n return scalarZeroValue(type, longType);\n }\n return tokenNull;\n }\n // every valid case in the switch below returns, and every fall\n // through is regarded as a failure.\n switch (type) {\n // float, double: JSON value will be a number or one of the special string values \"NaN\", \"Infinity\", and \"-Infinity\".\n // Either numbers or strings are accepted. Exponent notation is also accepted.\n case ScalarType.DOUBLE:\n case ScalarType.FLOAT:\n if (json === \"NaN\")\n return Number.NaN;\n if (json === \"Infinity\")\n return Number.POSITIVE_INFINITY;\n if (json === \"-Infinity\")\n return Number.NEGATIVE_INFINITY;\n if (json === \"\") {\n // empty string is not a number\n break;\n }\n if (typeof json == \"string\" && json.trim().length !== json.length) {\n // extra whitespace\n break;\n }\n if (typeof json != \"string\" && typeof json != \"number\") {\n break;\n }\n const float = Number(json);\n if (Number.isNaN(float)) {\n // not a number\n break;\n }\n if (!Number.isFinite(float)) {\n // infinity and -infinity are handled by string representation above, so this is an error\n break;\n }\n if (type == ScalarType.FLOAT)\n assertFloat32(float);\n return float;\n // int32, fixed32, uint32: JSON value will be a decimal number. Either numbers or strings are accepted.\n case ScalarType.INT32:\n case ScalarType.FIXED32:\n case ScalarType.SFIXED32:\n case ScalarType.SINT32:\n case ScalarType.UINT32:\n let int32;\n if (typeof json == \"number\")\n int32 = json;\n else if (typeof json == \"string\" && json.length > 0) {\n if (json.trim().length === json.length)\n int32 = Number(json);\n }\n if (int32 === undefined)\n break;\n if (type == ScalarType.UINT32 || type == ScalarType.FIXED32)\n assertUInt32(int32);\n else\n assertInt32(int32);\n return int32;\n // int64, fixed64, uint64: JSON value will be a decimal string. Either numbers or strings are accepted.\n case ScalarType.INT64:\n case ScalarType.SFIXED64:\n case ScalarType.SINT64:\n if (typeof json != \"number\" && typeof json != \"string\")\n break;\n const long = protoInt64.parse(json);\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n return longType ? long.toString() : long;\n case ScalarType.FIXED64:\n case ScalarType.UINT64:\n if (typeof json != \"number\" && typeof json != \"string\")\n break;\n const uLong = protoInt64.uParse(json);\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n return longType ? uLong.toString() : uLong;\n // bool:\n case ScalarType.BOOL:\n if (typeof json !== \"boolean\")\n break;\n return json;\n // string:\n case ScalarType.STRING:\n if (typeof json !== \"string\") {\n break;\n }\n // A string must always contain UTF-8 encoded or 7-bit ASCII.\n // We validate with encodeURIComponent, which appears to be the fastest widely available option.\n try {\n encodeURIComponent(json);\n }\n catch (e) {\n throw new Error(\"invalid UTF8\");\n }\n return json;\n // bytes: JSON value will be the data encoded as a string using standard base64 encoding with paddings.\n // Either standard or URL-safe base64 encoding with/without paddings are accepted.\n case ScalarType.BYTES:\n if (json === \"\")\n return new Uint8Array(0);\n if (typeof json !== \"string\")\n break;\n return protoBase64.dec(json);\n }\n throw new Error();\n}\nfunction readEnum(type, json, ignoreUnknownFields, nullAsZeroValue) {\n if (json === null) {\n if (type.typeName == \"google.protobuf.NullValue\") {\n return 0; // google.protobuf.NullValue.NULL_VALUE = 0\n }\n return nullAsZeroValue ? type.values[0].no : tokenNull;\n }\n // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check\n switch (typeof json) {\n case \"number\":\n if (Number.isInteger(json)) {\n return json;\n }\n break;\n case \"string\":\n const value = type.findName(json);\n if (value !== undefined) {\n return value.no;\n }\n if (ignoreUnknownFields) {\n return tokenIgnoredUnknownEnum;\n }\n break;\n }\n throw new Error(`cannot decode enum ${type.typeName} from JSON: ${debugJsonValue(json)}`);\n}\n// Decide whether an unset field should be emitted with JSON write option `emitDefaultValues`\nfunction canEmitFieldDefaultValue(field) {\n if (field.repeated || field.kind == \"map\") {\n // maps are {}, repeated fields are []\n return true;\n }\n if (field.oneof) {\n // oneof fields are never emitted\n return false;\n }\n if (field.kind == \"message\") {\n // singular message field are allowed to emit JSON null, but we do not\n return false;\n }\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n if (field.opt || field.req) {\n // the field uses explicit presence, so we cannot emit a zero value\n return false;\n }\n return true;\n}\nfunction writeField(field, value, options) {\n if (field.kind == \"map\") {\n assert(typeof value == \"object\" && value != null);\n const jsonObj = {};\n const entries = Object.entries(value);\n switch (field.V.kind) {\n case \"scalar\":\n for (const [entryKey, entryValue] of entries) {\n jsonObj[entryKey.toString()] = writeScalar(field.V.T, entryValue); // JSON standard allows only (double quoted) string as property key\n }\n break;\n case \"message\":\n for (const [entryKey, entryValue] of entries) {\n // JSON standard allows only (double quoted) string as property key\n jsonObj[entryKey.toString()] = entryValue.toJson(options);\n }\n break;\n case \"enum\":\n const enumType = field.V.T;\n for (const [entryKey, entryValue] of entries) {\n // JSON standard allows only (double quoted) string as property key\n jsonObj[entryKey.toString()] = writeEnum(enumType, entryValue, options.enumAsInteger);\n }\n break;\n }\n return options.emitDefaultValues || entries.length > 0\n ? jsonObj\n : undefined;\n }\n if (field.repeated) {\n assert(Array.isArray(value));\n const jsonArr = [];\n switch (field.kind) {\n case \"scalar\":\n for (let i = 0; i < value.length; i++) {\n jsonArr.push(writeScalar(field.T, value[i]));\n }\n break;\n case \"enum\":\n for (let i = 0; i < value.length; i++) {\n jsonArr.push(writeEnum(field.T, value[i], options.enumAsInteger));\n }\n break;\n case \"message\":\n for (let i = 0; i < value.length; i++) {\n jsonArr.push(value[i].toJson(options));\n }\n break;\n }\n return options.emitDefaultValues || jsonArr.length > 0\n ? jsonArr\n : undefined;\n }\n switch (field.kind) {\n case \"scalar\":\n return writeScalar(field.T, value);\n case \"enum\":\n return writeEnum(field.T, value, options.enumAsInteger);\n case \"message\":\n return wrapField(field.T, value).toJson(options);\n }\n}\nfunction writeEnum(type, value, enumAsInteger) {\n var _a;\n assert(typeof value == \"number\");\n if (type.typeName == \"google.protobuf.NullValue\") {\n return null;\n }\n if (enumAsInteger) {\n return value;\n }\n const val = type.findNumber(value);\n return (_a = val === null || val === void 0 ? void 0 : val.name) !== null && _a !== void 0 ? _a : value; // if we don't know the enum value, just return the number\n}\nfunction writeScalar(type, value) {\n switch (type) {\n // int32, fixed32, uint32: JSON value will be a decimal number. Either numbers or strings are accepted.\n case ScalarType.INT32:\n case ScalarType.SFIXED32:\n case ScalarType.SINT32:\n case ScalarType.FIXED32:\n case ScalarType.UINT32:\n assert(typeof value == \"number\");\n return value;\n // float, double: JSON value will be a number or one of the special string values \"NaN\", \"Infinity\", and \"-Infinity\".\n // Either numbers or strings are accepted. Exponent notation is also accepted.\n case ScalarType.FLOAT:\n // assertFloat32(value);\n case ScalarType.DOUBLE: // eslint-disable-line no-fallthrough\n assert(typeof value == \"number\");\n if (Number.isNaN(value))\n return \"NaN\";\n if (value === Number.POSITIVE_INFINITY)\n return \"Infinity\";\n if (value === Number.NEGATIVE_INFINITY)\n return \"-Infinity\";\n return value;\n // string:\n case ScalarType.STRING:\n assert(typeof value == \"string\");\n return value;\n // bool:\n case ScalarType.BOOL:\n assert(typeof value == \"boolean\");\n return value;\n // JSON value will be a decimal string. Either numbers or strings are accepted.\n case ScalarType.UINT64:\n case ScalarType.FIXED64:\n case ScalarType.INT64:\n case ScalarType.SFIXED64:\n case ScalarType.SINT64:\n assert(typeof value == \"bigint\" ||\n typeof value == \"string\" ||\n typeof value == \"number\");\n return value.toString();\n // bytes: JSON value will be the data encoded as a string using standard base64 encoding with paddings.\n // Either standard or URL-safe base64 encoding with/without paddings are accepted.\n case ScalarType.BYTES:\n assert(value instanceof Uint8Array);\n return protoBase64.enc(value);\n }\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { BinaryReader, BinaryWriter, WireType } from \"../binary-encoding.js\";\nimport { Message } from \"../message.js\";\nimport { wrapField } from \"./field-wrapper.js\";\nimport { scalarZeroValue } from \"./scalars.js\";\nimport { assert } from \"./assert.js\";\nimport { isFieldSet } from \"./reflect.js\";\nimport { LongType, ScalarType } from \"../scalar.js\";\nimport { isMessage } from \"../is-message.js\";\n/* eslint-disable prefer-const,no-case-declarations,@typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-return */\nconst unknownFieldsSymbol = Symbol(\"@bufbuild/protobuf/unknown-fields\");\n// Default options for parsing binary data.\nconst readDefaults = {\n readUnknownFields: true,\n readerFactory: (bytes) => new BinaryReader(bytes),\n};\n// Default options for serializing binary data.\nconst writeDefaults = {\n writeUnknownFields: true,\n writerFactory: () => new BinaryWriter(),\n};\nfunction makeReadOptions(options) {\n return options ? Object.assign(Object.assign({}, readDefaults), options) : readDefaults;\n}\nfunction makeWriteOptions(options) {\n return options ? Object.assign(Object.assign({}, writeDefaults), options) : writeDefaults;\n}\nexport function makeBinaryFormat() {\n return {\n makeReadOptions,\n makeWriteOptions,\n listUnknownFields(message) {\n var _a;\n return (_a = message[unknownFieldsSymbol]) !== null && _a !== void 0 ? _a : [];\n },\n discardUnknownFields(message) {\n delete message[unknownFieldsSymbol];\n },\n writeUnknownFields(message, writer) {\n const m = message;\n const c = m[unknownFieldsSymbol];\n if (c) {\n for (const f of c) {\n writer.tag(f.no, f.wireType).raw(f.data);\n }\n }\n },\n onUnknownField(message, no, wireType, data) {\n const m = message;\n if (!Array.isArray(m[unknownFieldsSymbol])) {\n m[unknownFieldsSymbol] = [];\n }\n m[unknownFieldsSymbol].push({ no, wireType, data });\n },\n readMessage(message, reader, lengthOrEndTagFieldNo, options, delimitedMessageEncoding) {\n const type = message.getType();\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n const end = delimitedMessageEncoding\n ? reader.len\n : reader.pos + lengthOrEndTagFieldNo;\n let fieldNo, wireType;\n while (reader.pos < end) {\n [fieldNo, wireType] = reader.tag();\n if (delimitedMessageEncoding === true &&\n wireType == WireType.EndGroup) {\n break;\n }\n const field = type.fields.find(fieldNo);\n if (!field) {\n const data = reader.skip(wireType, fieldNo);\n if (options.readUnknownFields) {\n this.onUnknownField(message, fieldNo, wireType, data);\n }\n continue;\n }\n readField(message, reader, field, wireType, options);\n }\n if (delimitedMessageEncoding && // eslint-disable-line @typescript-eslint/strict-boolean-expressions\n (wireType != WireType.EndGroup || fieldNo !== lengthOrEndTagFieldNo)) {\n throw new Error(`invalid end group tag`);\n }\n },\n readField,\n writeMessage(message, writer, options) {\n const type = message.getType();\n for (const field of type.fields.byNumber()) {\n if (!isFieldSet(field, message)) {\n if (field.req) {\n throw new Error(`cannot encode field ${type.typeName}.${field.name} to binary: required field not set`);\n }\n continue;\n }\n const value = field.oneof\n ? message[field.oneof.localName].value\n : message[field.localName];\n writeField(field, value, writer, options);\n }\n if (options.writeUnknownFields) {\n this.writeUnknownFields(message, writer);\n }\n return writer;\n },\n writeField(field, value, writer, options) {\n // The behavior of our internal function has changed, it does no longer\n // accept `undefined` values for singular scalar and map.\n // For backwards-compatibility, we support the old form that is part of\n // the public API through the interface BinaryFormat.\n if (value === undefined) {\n return undefined;\n }\n writeField(field, value, writer, options);\n },\n };\n}\nfunction readField(target, // eslint-disable-line @typescript-eslint/no-explicit-any -- `any` is the best choice for dynamic access\nreader, field, wireType, options) {\n let { repeated, localName } = field;\n if (field.oneof) {\n target = target[field.oneof.localName];\n if (target.case != localName) {\n delete target.value;\n }\n target.case = localName;\n localName = \"value\";\n }\n switch (field.kind) {\n case \"scalar\":\n case \"enum\":\n const scalarType = field.kind == \"enum\" ? ScalarType.INT32 : field.T;\n let read = readScalar;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison -- acceptable since it's covered by tests\n if (field.kind == \"scalar\" && field.L > 0) {\n read = readScalarLTString;\n }\n if (repeated) {\n let arr = target[localName]; // safe to assume presence of array, oneof cannot contain repeated values\n const isPacked = wireType == WireType.LengthDelimited &&\n scalarType != ScalarType.STRING &&\n scalarType != ScalarType.BYTES;\n if (isPacked) {\n let e = reader.uint32() + reader.pos;\n while (reader.pos < e) {\n arr.push(read(reader, scalarType));\n }\n }\n else {\n arr.push(read(reader, scalarType));\n }\n }\n else {\n target[localName] = read(reader, scalarType);\n }\n break;\n case \"message\":\n const messageType = field.T;\n if (repeated) {\n // safe to assume presence of array, oneof cannot contain repeated values\n target[localName].push(readMessageField(reader, new messageType(), options, field));\n }\n else {\n if (isMessage(target[localName])) {\n readMessageField(reader, target[localName], options, field);\n }\n else {\n target[localName] = readMessageField(reader, new messageType(), options, field);\n if (messageType.fieldWrapper && !field.oneof && !field.repeated) {\n target[localName] = messageType.fieldWrapper.unwrapField(target[localName]);\n }\n }\n }\n break;\n case \"map\":\n let [mapKey, mapVal] = readMapEntry(field, reader, options);\n // safe to assume presence of map object, oneof cannot contain repeated values\n target[localName][mapKey] = mapVal;\n break;\n }\n}\n// Read a message, avoiding MessageType.fromBinary() to re-use the\n// BinaryReadOptions and the IBinaryReader.\nfunction readMessageField(reader, message, options, field) {\n const format = message.getType().runtime.bin;\n const delimited = field === null || field === void 0 ? void 0 : field.delimited;\n format.readMessage(message, reader, delimited ? field.no : reader.uint32(), // eslint-disable-line @typescript-eslint/strict-boolean-expressions\n options, delimited);\n return message;\n}\n// Read a map field, expecting key field = 1, value field = 2\nfunction readMapEntry(field, reader, options) {\n const length = reader.uint32(), end = reader.pos + length;\n let key, val;\n while (reader.pos < end) {\n const [fieldNo] = reader.tag();\n switch (fieldNo) {\n case 1:\n key = readScalar(reader, field.K);\n break;\n case 2:\n switch (field.V.kind) {\n case \"scalar\":\n val = readScalar(reader, field.V.T);\n break;\n case \"enum\":\n val = reader.int32();\n break;\n case \"message\":\n val = readMessageField(reader, new field.V.T(), options, undefined);\n break;\n }\n break;\n }\n }\n if (key === undefined) {\n key = scalarZeroValue(field.K, LongType.BIGINT);\n }\n if (typeof key != \"string\" && typeof key != \"number\") {\n key = key.toString();\n }\n if (val === undefined) {\n switch (field.V.kind) {\n case \"scalar\":\n val = scalarZeroValue(field.V.T, LongType.BIGINT);\n break;\n case \"enum\":\n val = field.V.T.values[0].no;\n break;\n case \"message\":\n val = new field.V.T();\n break;\n }\n }\n return [key, val];\n}\n// Read a scalar value, but return 64 bit integral types (int64, uint64,\n// sint64, fixed64, sfixed64) as string instead of bigint.\nfunction readScalarLTString(reader, type) {\n const v = readScalar(reader, type);\n return typeof v == \"bigint\" ? v.toString() : v;\n}\n// Does not use scalarTypeInfo() for better performance.\nfunction readScalar(reader, type) {\n switch (type) {\n case ScalarType.STRING:\n return reader.string();\n case ScalarType.BOOL:\n return reader.bool();\n case ScalarType.DOUBLE:\n return reader.double();\n case ScalarType.FLOAT:\n return reader.float();\n case ScalarType.INT32:\n return reader.int32();\n case ScalarType.INT64:\n return reader.int64();\n case ScalarType.UINT64:\n return reader.uint64();\n case ScalarType.FIXED64:\n return reader.fixed64();\n case ScalarType.BYTES:\n return reader.bytes();\n case ScalarType.FIXED32:\n return reader.fixed32();\n case ScalarType.SFIXED32:\n return reader.sfixed32();\n case ScalarType.SFIXED64:\n return reader.sfixed64();\n case ScalarType.SINT64:\n return reader.sint64();\n case ScalarType.UINT32:\n return reader.uint32();\n case ScalarType.SINT32:\n return reader.sint32();\n }\n}\nfunction writeField(field, value, writer, options) {\n assert(value !== undefined);\n const repeated = field.repeated;\n switch (field.kind) {\n case \"scalar\":\n case \"enum\":\n let scalarType = field.kind == \"enum\" ? ScalarType.INT32 : field.T;\n if (repeated) {\n assert(Array.isArray(value));\n if (field.packed) {\n writePacked(writer, scalarType, field.no, value);\n }\n else {\n for (const item of value) {\n writeScalar(writer, scalarType, field.no, item);\n }\n }\n }\n else {\n writeScalar(writer, scalarType, field.no, value);\n }\n break;\n case \"message\":\n if (repeated) {\n assert(Array.isArray(value));\n for (const item of value) {\n writeMessageField(writer, options, field, item);\n }\n }\n else {\n writeMessageField(writer, options, field, value);\n }\n break;\n case \"map\":\n assert(typeof value == \"object\" && value != null);\n for (const [key, val] of Object.entries(value)) {\n writeMapEntry(writer, options, field, key, val);\n }\n break;\n }\n}\nexport function writeMapEntry(writer, options, field, key, value) {\n writer.tag(field.no, WireType.LengthDelimited);\n writer.fork();\n // javascript only allows number or string for object properties\n // we convert from our representation to the protobuf type\n let keyValue = key;\n // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- we deliberately handle just the special cases for map keys\n switch (field.K) {\n case ScalarType.INT32:\n case ScalarType.FIXED32:\n case ScalarType.UINT32:\n case ScalarType.SFIXED32:\n case ScalarType.SINT32:\n keyValue = Number.parseInt(key);\n break;\n case ScalarType.BOOL:\n assert(key == \"true\" || key == \"false\");\n keyValue = key == \"true\";\n break;\n }\n // write key, expecting key field number = 1\n writeScalar(writer, field.K, 1, keyValue);\n // write value, expecting value field number = 2\n switch (field.V.kind) {\n case \"scalar\":\n writeScalar(writer, field.V.T, 2, value);\n break;\n case \"enum\":\n writeScalar(writer, ScalarType.INT32, 2, value);\n break;\n case \"message\":\n assert(value !== undefined);\n writer.tag(2, WireType.LengthDelimited).bytes(value.toBinary(options));\n break;\n }\n writer.join();\n}\n// Value must not be undefined\nfunction writeMessageField(writer, options, field, value) {\n const message = wrapField(field.T, value);\n // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions\n if (field.delimited)\n writer\n .tag(field.no, WireType.StartGroup)\n .raw(message.toBinary(options))\n .tag(field.no, WireType.EndGroup);\n else\n writer\n .tag(field.no, WireType.LengthDelimited)\n .bytes(message.toBinary(options));\n}\nfunction writeScalar(writer, type, fieldNo, value) {\n assert(value !== undefined);\n let [wireType, method] = scalarTypeInfo(type);\n writer.tag(fieldNo, wireType)[method](value);\n}\nfunction writePacked(writer, type, fieldNo, value) {\n if (!value.length) {\n return;\n }\n writer.tag(fieldNo, WireType.LengthDelimited).fork();\n let [, method] = scalarTypeInfo(type);\n for (let i = 0; i < value.length; i++) {\n writer[method](value[i]);\n }\n writer.join();\n}\n/**\n * Get information for writing a scalar value.\n *\n * Returns tuple:\n * [0]: appropriate WireType\n * [1]: name of the appropriate method of IBinaryWriter\n * [2]: whether the given value is a default value for proto3 semantics\n *\n * If argument `value` is omitted, [2] is always false.\n */\n// TODO replace call-sites writeScalar() and writePacked(), then remove\nfunction scalarTypeInfo(type) {\n let wireType = WireType.Varint;\n // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- INT32, UINT32, SINT32 are covered by the defaults\n switch (type) {\n case ScalarType.BYTES:\n case ScalarType.STRING:\n wireType = WireType.LengthDelimited;\n break;\n case ScalarType.DOUBLE:\n case ScalarType.FIXED64:\n case ScalarType.SFIXED64:\n wireType = WireType.Bit64;\n break;\n case ScalarType.FIXED32:\n case ScalarType.SFIXED32:\n case ScalarType.FLOAT:\n wireType = WireType.Bit32;\n break;\n }\n const method = ScalarType[type].toLowerCase();\n return [wireType, method];\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { setEnumType } from \"./enum.js\";\nimport { Message } from \"../message.js\";\nimport { scalarEquals } from \"./scalars.js\";\nimport { ScalarType } from \"../scalar.js\";\nimport { isMessage } from \"../is-message.js\";\n/* eslint-disable @typescript-eslint/no-explicit-any,@typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-return,@typescript-eslint/no-unsafe-argument,no-case-declarations */\nexport function makeUtilCommon() {\n return {\n setEnumType,\n initPartial(source, target) {\n if (source === undefined) {\n return;\n }\n const type = target.getType();\n for (const member of type.fields.byMember()) {\n const localName = member.localName, t = target, s = source;\n if (s[localName] == null) {\n // TODO if source is a Message instance, we should use isFieldSet() here to support future field presence\n continue;\n }\n switch (member.kind) {\n case \"oneof\":\n const sk = s[localName].case;\n if (sk === undefined) {\n continue;\n }\n const sourceField = member.findField(sk);\n let val = s[localName].value;\n if (sourceField &&\n sourceField.kind == \"message\" &&\n !isMessage(val, sourceField.T)) {\n val = new sourceField.T(val);\n }\n else if (sourceField &&\n sourceField.kind === \"scalar\" &&\n sourceField.T === ScalarType.BYTES) {\n val = toU8Arr(val);\n }\n t[localName] = { case: sk, value: val };\n break;\n case \"scalar\":\n case \"enum\":\n let copy = s[localName];\n if (member.T === ScalarType.BYTES) {\n copy = member.repeated\n ? copy.map(toU8Arr)\n : toU8Arr(copy);\n }\n t[localName] = copy;\n break;\n case \"map\":\n switch (member.V.kind) {\n case \"scalar\":\n case \"enum\":\n if (member.V.T === ScalarType.BYTES) {\n for (const [k, v] of Object.entries(s[localName])) {\n t[localName][k] = toU8Arr(v);\n }\n }\n else {\n Object.assign(t[localName], s[localName]);\n }\n break;\n case \"message\":\n const messageType = member.V.T;\n for (const k of Object.keys(s[localName])) {\n let val = s[localName][k];\n if (!messageType.fieldWrapper) {\n // We only take partial input for messages that are not a wrapper type.\n // For those messages, we recursively normalize the partial input.\n val = new messageType(val);\n }\n t[localName][k] = val;\n }\n break;\n }\n break;\n case \"message\":\n const mt = member.T;\n if (member.repeated) {\n t[localName] = s[localName].map((val) => isMessage(val, mt) ? val : new mt(val));\n }\n else {\n const val = s[localName];\n if (mt.fieldWrapper) {\n if (\n // We can't use BytesValue.typeName as that will create a circular import\n mt.typeName === \"google.protobuf.BytesValue\") {\n t[localName] = toU8Arr(val);\n }\n else {\n t[localName] = val;\n }\n }\n else {\n t[localName] = isMessage(val, mt) ? val : new mt(val);\n }\n }\n break;\n }\n }\n },\n // TODO use isFieldSet() here to support future field presence\n equals(type, a, b) {\n if (a === b) {\n return true;\n }\n if (!a || !b) {\n return false;\n }\n return type.fields.byMember().every((m) => {\n const va = a[m.localName];\n const vb = b[m.localName];\n if (m.repeated) {\n if (va.length !== vb.length) {\n return false;\n }\n // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- repeated fields are never \"map\"\n switch (m.kind) {\n case \"message\":\n return va.every((a, i) => m.T.equals(a, vb[i]));\n case \"scalar\":\n return va.every((a, i) => scalarEquals(m.T, a, vb[i]));\n case \"enum\":\n return va.every((a, i) => scalarEquals(ScalarType.INT32, a, vb[i]));\n }\n throw new Error(`repeated cannot contain ${m.kind}`);\n }\n switch (m.kind) {\n case \"message\":\n return m.T.equals(va, vb);\n case \"enum\":\n return scalarEquals(ScalarType.INT32, va, vb);\n case \"scalar\":\n return scalarEquals(m.T, va, vb);\n case \"oneof\":\n if (va.case !== vb.case) {\n return false;\n }\n const s = m.findField(va.case);\n if (s === undefined) {\n return true;\n }\n // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- oneof fields are never \"map\"\n switch (s.kind) {\n case \"message\":\n return s.T.equals(va.value, vb.value);\n case \"enum\":\n return scalarEquals(ScalarType.INT32, va.value, vb.value);\n case \"scalar\":\n return scalarEquals(s.T, va.value, vb.value);\n }\n throw new Error(`oneof cannot contain ${s.kind}`);\n case \"map\":\n const keys = Object.keys(va).concat(Object.keys(vb));\n switch (m.V.kind) {\n case \"message\":\n const messageType = m.V.T;\n return keys.every((k) => messageType.equals(va[k], vb[k]));\n case \"enum\":\n return keys.every((k) => scalarEquals(ScalarType.INT32, va[k], vb[k]));\n case \"scalar\":\n const scalarType = m.V.T;\n return keys.every((k) => scalarEquals(scalarType, va[k], vb[k]));\n }\n break;\n }\n });\n },\n // TODO use isFieldSet() here to support future field presence\n clone(message) {\n const type = message.getType(), target = new type(), any = target;\n for (const member of type.fields.byMember()) {\n const source = message[member.localName];\n let copy;\n if (member.repeated) {\n copy = source.map(cloneSingularField);\n }\n else if (member.kind == \"map\") {\n copy = any[member.localName];\n for (const [key, v] of Object.entries(source)) {\n copy[key] = cloneSingularField(v);\n }\n }\n else if (member.kind == \"oneof\") {\n const f = member.findField(source.case);\n copy = f\n ? { case: source.case, value: cloneSingularField(source.value) }\n : { case: undefined };\n }\n else {\n copy = cloneSingularField(source);\n }\n any[member.localName] = copy;\n }\n for (const uf of type.runtime.bin.listUnknownFields(message)) {\n type.runtime.bin.onUnknownField(any, uf.no, uf.wireType, uf.data);\n }\n return target;\n },\n };\n}\n// clone a single field value - i.e. the element type of repeated fields, the value type of maps\nfunction cloneSingularField(value) {\n if (value === undefined) {\n return value;\n }\n if (isMessage(value)) {\n return value.clone();\n }\n if (value instanceof Uint8Array) {\n const c = new Uint8Array(value.byteLength);\n c.set(value);\n return c;\n }\n return value;\n}\n// converts any ArrayLike<number> to Uint8Array if necessary.\nfunction toU8Arr(input) {\n return input instanceof Uint8Array ? input : new Uint8Array(input);\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nexport class InternalFieldList {\n constructor(fields, normalizer) {\n this._fields = fields;\n this._normalizer = normalizer;\n }\n findJsonName(jsonName) {\n if (!this.jsonNames) {\n const t = {};\n for (const f of this.list()) {\n t[f.jsonName] = t[f.name] = f;\n }\n this.jsonNames = t;\n }\n return this.jsonNames[jsonName];\n }\n find(fieldNo) {\n if (!this.numbers) {\n const t = {};\n for (const f of this.list()) {\n t[f.no] = f;\n }\n this.numbers = t;\n }\n return this.numbers[fieldNo];\n }\n list() {\n if (!this.all) {\n this.all = this._normalizer(this._fields);\n }\n return this.all;\n }\n byNumber() {\n if (!this.numbersAsc) {\n this.numbersAsc = this.list()\n .concat()\n .sort((a, b) => a.no - b.no);\n }\n return this.numbersAsc;\n }\n byMember() {\n if (!this.members) {\n this.members = [];\n const a = this.members;\n let o;\n for (const f of this.list()) {\n if (f.oneof) {\n if (f.oneof !== o) {\n o = f.oneof;\n a.push(o);\n }\n }\n else {\n a.push(f);\n }\n }\n }\n return this.members;\n }\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n/**\n * Returns the name of a protobuf element in generated code.\n *\n * Field names - including oneofs - are converted to lowerCamelCase. For\n * messages, enumerations and services, the package name is stripped from\n * the type name. For nested messages and enumerations, the names are joined\n * with an underscore. For methods, the first character is made lowercase.\n */\nexport function localName(desc) {\n switch (desc.kind) {\n case \"field\":\n return localFieldName(desc.name, desc.oneof !== undefined);\n case \"oneof\":\n return localOneofName(desc.name);\n case \"enum\":\n case \"message\":\n case \"service\":\n case \"extension\": {\n const pkg = desc.file.proto.package;\n const offset = pkg === undefined ? 0 : pkg.length + 1;\n const name = desc.typeName.substring(offset).replace(/\\./g, \"_\");\n // For services, we only care about safe identifiers, not safe object properties,\n // but we have shipped v1 with a bug that respected object properties, and we\n // do not want to introduce a breaking change, so we continue to escape for\n // safe object properties.\n // See https://github.com/bufbuild/protobuf-es/pull/391\n return safeObjectProperty(safeIdentifier(name));\n }\n case \"enum_value\": {\n let name = desc.name;\n const sharedPrefix = desc.parent.sharedPrefix;\n if (sharedPrefix !== undefined) {\n name = name.substring(sharedPrefix.length);\n }\n return safeObjectProperty(name);\n }\n case \"rpc\": {\n let name = desc.name;\n if (name.length == 0) {\n return name;\n }\n name = name[0].toLowerCase() + name.substring(1);\n return safeObjectProperty(name);\n }\n }\n}\n/**\n * Returns the name of a field in generated code.\n */\nexport function localFieldName(protoName, inOneof) {\n const name = protoCamelCase(protoName);\n if (inOneof) {\n // oneof member names are not properties, but values of the `case` property.\n return name;\n }\n return safeObjectProperty(safeMessageProperty(name));\n}\n/**\n * Returns the name of a oneof group in generated code.\n */\nexport function localOneofName(protoName) {\n return localFieldName(protoName, false);\n}\n/**\n * Returns the JSON name for a protobuf field, exactly like protoc does.\n */\nexport const fieldJsonName = protoCamelCase;\n/**\n * Finds a prefix shared by enum values, for example `MY_ENUM_` for\n * `enum MyEnum {MY_ENUM_A=0; MY_ENUM_B=1;}`.\n */\nexport function findEnumSharedPrefix(enumName, valueNames) {\n const prefix = camelToSnakeCase(enumName) + \"_\";\n for (const name of valueNames) {\n if (!name.toLowerCase().startsWith(prefix)) {\n return undefined;\n }\n const shortName = name.substring(prefix.length);\n if (shortName.length == 0) {\n return undefined;\n }\n if (/^\\d/.test(shortName)) {\n // identifiers must not start with numbers\n return undefined;\n }\n }\n return prefix;\n}\n/**\n * Converts lowerCamelCase or UpperCamelCase into lower_snake_case.\n * This is used to find shared prefixes in an enum.\n */\nfunction camelToSnakeCase(camel) {\n return (camel.substring(0, 1) + camel.substring(1).replace(/[A-Z]/g, (c) => \"_\" + c)).toLowerCase();\n}\n/**\n * Converts snake_case to protoCamelCase according to the convention\n * used by protoc to convert a field name to a JSON name.\n */\nfunction protoCamelCase(snakeCase) {\n let capNext = false;\n const b = [];\n for (let i = 0; i < snakeCase.length; i++) {\n let c = snakeCase.charAt(i);\n switch (c) {\n case \"_\":\n capNext = true;\n break;\n case \"0\":\n case \"1\":\n case \"2\":\n case \"3\":\n case \"4\":\n case \"5\":\n case \"6\":\n case \"7\":\n case \"8\":\n case \"9\":\n b.push(c);\n capNext = false;\n break;\n default:\n if (capNext) {\n capNext = false;\n c = c.toUpperCase();\n }\n b.push(c);\n break;\n }\n }\n return b.join(\"\");\n}\n/**\n * Names that cannot be used for identifiers, such as class names,\n * but _can_ be used for object properties.\n */\nconst reservedIdentifiers = new Set([\n // ECMAScript 2015 keywords\n \"break\",\n \"case\",\n \"catch\",\n \"class\",\n \"const\",\n \"continue\",\n \"debugger\",\n \"default\",\n \"delete\",\n \"do\",\n \"else\",\n \"export\",\n \"extends\",\n \"false\",\n \"finally\",\n \"for\",\n \"function\",\n \"if\",\n \"import\",\n \"in\",\n \"instanceof\",\n \"new\",\n \"null\",\n \"return\",\n \"super\",\n \"switch\",\n \"this\",\n \"throw\",\n \"true\",\n \"try\",\n \"typeof\",\n \"var\",\n \"void\",\n \"while\",\n \"with\",\n \"yield\",\n // ECMAScript 2015 future reserved keywords\n \"enum\",\n \"implements\",\n \"interface\",\n \"let\",\n \"package\",\n \"private\",\n \"protected\",\n \"public\",\n \"static\",\n // Class name cannot be 'Object' when targeting ES5 with module CommonJS\n \"Object\",\n // TypeScript keywords that cannot be used for types (as opposed to variables)\n \"bigint\",\n \"number\",\n \"boolean\",\n \"string\",\n \"object\",\n // Identifiers reserved for the runtime, so we can generate legible code\n \"globalThis\",\n \"Uint8Array\",\n \"Partial\",\n]);\n/**\n * Names that cannot be used for object properties because they are reserved\n * by built-in JavaScript properties.\n */\nconst reservedObjectProperties = new Set([\n // names reserved by JavaScript\n \"constructor\",\n \"toString\",\n \"toJSON\",\n \"valueOf\",\n]);\n/**\n * Names that cannot be used for object properties because they are reserved\n * by the runtime.\n */\nconst reservedMessageProperties = new Set([\n // names reserved by the runtime\n \"getType\",\n \"clone\",\n \"equals\",\n \"fromBinary\",\n \"fromJson\",\n \"fromJsonString\",\n \"toBinary\",\n \"toJson\",\n \"toJsonString\",\n // names reserved by the runtime for the future\n \"toObject\",\n]);\nconst fallback = (name) => `${name}$`;\n/**\n * Will wrap names that are Object prototype properties or names reserved\n * for `Message`s.\n */\nconst safeMessageProperty = (name) => {\n if (reservedMessageProperties.has(name)) {\n return fallback(name);\n }\n return name;\n};\n/**\n * Names that cannot be used for object properties because they are reserved\n * by built-in JavaScript properties.\n */\nexport const safeObjectProperty = (name) => {\n if (reservedObjectProperties.has(name)) {\n return fallback(name);\n }\n return name;\n};\n/**\n * Names that can be used for identifiers or class properties\n */\nexport const safeIdentifier = (name) => {\n if (reservedIdentifiers.has(name)) {\n return fallback(name);\n }\n return name;\n};\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { localOneofName } from \"./names.js\";\nimport { assert } from \"./assert.js\";\nexport class InternalOneofInfo {\n constructor(name) {\n this.kind = \"oneof\";\n this.repeated = false;\n this.packed = false;\n this.opt = false;\n this.req = false;\n this.default = undefined;\n this.fields = [];\n this.name = name;\n this.localName = localOneofName(name);\n }\n addField(field) {\n assert(field.oneof === this, `field ${field.name} not one of ${this.name}`);\n this.fields.push(field);\n }\n findField(localName) {\n if (!this._lookup) {\n this._lookup = Object.create(null);\n for (let i = 0; i < this.fields.length; i++) {\n this._lookup[this.fields[i].localName] = this.fields[i];\n }\n }\n return this._lookup[localName];\n }\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { makeProtoRuntime } from \"./private/proto-runtime.js\";\nimport { InternalFieldList } from \"./private/field-list.js\";\nimport { scalarZeroValue } from \"./private/scalars.js\";\nimport { normalizeFieldInfos } from \"./private/field-normalize.js\";\n/**\n * Provides functionality for messages defined with the proto3 syntax.\n */\nexport const proto3 = makeProtoRuntime(\"proto3\", (fields) => {\n return new InternalFieldList(fields, (source) => normalizeFieldInfos(source, true));\n}, \n// TODO merge with proto2 and initExtensionField, also see initPartial, equals, clone\n(target) => {\n for (const member of target.getType().fields.byMember()) {\n if (member.opt) {\n continue;\n }\n const name = member.localName, t = target;\n if (member.repeated) {\n t[name] = [];\n continue;\n }\n switch (member.kind) {\n case \"oneof\":\n t[name] = { case: undefined };\n break;\n case \"enum\":\n t[name] = 0;\n break;\n case \"map\":\n t[name] = {};\n break;\n case \"scalar\":\n t[name] = scalarZeroValue(member.T, member.L);\n break;\n case \"message\":\n // message fields are always optional in proto3\n break;\n }\n }\n});\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { getEnumType, makeEnum, makeEnumType } from \"./enum.js\";\nimport { makeMessageType } from \"./message-type.js\";\nimport { makeExtension } from \"./extensions.js\";\nimport { makeJsonFormat } from \"./json-format.js\";\nimport { makeBinaryFormat } from \"./binary-format.js\";\nimport { makeUtilCommon } from \"./util-common.js\";\nexport function makeProtoRuntime(syntax, newFieldList, initFields) {\n return {\n syntax,\n json: makeJsonFormat(),\n bin: makeBinaryFormat(),\n util: Object.assign(Object.assign({}, makeUtilCommon()), { newFieldList,\n initFields }),\n makeMessageType(typeName, fields, opt) {\n return makeMessageType(this, typeName, fields, opt);\n },\n makeEnum,\n makeEnumType,\n getEnumType,\n makeExtension(typeName, extendee, field) {\n return makeExtension(this, typeName, extendee, field);\n },\n };\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { InternalOneofInfo } from \"./field.js\";\nimport { fieldJsonName, localFieldName } from \"./names.js\";\nimport { LongType, ScalarType } from \"../scalar.js\";\n/**\n * Convert a collection of field info to an array of normalized FieldInfo.\n *\n * The argument `packedByDefault` specifies whether fields that do not specify\n * `packed` should be packed (proto3) or unpacked (proto2).\n */\nexport function normalizeFieldInfos(fieldInfos, packedByDefault) {\n var _a, _b, _c, _d, _e, _f;\n const r = [];\n let o;\n for (const field of typeof fieldInfos == \"function\"\n ? fieldInfos()\n : fieldInfos) {\n const f = field;\n f.localName = localFieldName(field.name, field.oneof !== undefined);\n f.jsonName = (_a = field.jsonName) !== null && _a !== void 0 ? _a : fieldJsonName(field.name);\n f.repeated = (_b = field.repeated) !== null && _b !== void 0 ? _b : false;\n if (field.kind == \"scalar\") {\n f.L = (_c = field.L) !== null && _c !== void 0 ? _c : LongType.BIGINT;\n }\n f.delimited = (_d = field.delimited) !== null && _d !== void 0 ? _d : false;\n f.req = (_e = field.req) !== null && _e !== void 0 ? _e : false;\n f.opt = (_f = field.opt) !== null && _f !== void 0 ? _f : false;\n if (field.packed === undefined) {\n if (packedByDefault) {\n f.packed =\n field.kind == \"enum\" ||\n (field.kind == \"scalar\" &&\n field.T != ScalarType.BYTES &&\n field.T != ScalarType.STRING);\n }\n else {\n f.packed = false;\n }\n }\n // We do not surface options at this time\n // f.options = field.options ?? emptyReadonlyObject;\n if (field.oneof !== undefined) {\n const ooname = typeof field.oneof == \"string\" ? field.oneof : field.oneof.name;\n if (!o || o.name != ooname) {\n o = new InternalOneofInfo(ooname);\n }\n f.oneof = o;\n o.addField(f);\n }\n r.push(f);\n }\n return r;\n}\n","// Copyright 2021-2024 Buf Technologies, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\nimport { Message } from \"../message.js\";\n/**\n * Create a new message type using the given runtime.\n */\nexport function makeMessageType(runtime, typeName, fields, opt) {\n var _a;\n const localName = (_a = opt === null || opt === void 0 ? void 0 : opt.localName) !== null && _a !== void 0 ? _a : typeName.substring(typeName.lastIndexOf(\".\") + 1);\n const type = {\n [localName]: function (data) {\n runtime.util.initFields(this);\n runtime.util.initPartial(data, this);\n },\n }[localName];\n Object.setPrototypeOf(type.prototype, new Message());\n Object.assign(type, {\n runtime,\n typeName,\n fields: runtime.util.newFieldList(fields),\n fromBinary(bytes, options) {\n return new type().fromBinary(bytes, options);\n },\n fromJson(jsonValue, options) {\n return new type().fromJson(jsonValue, options);\n },\n fromJsonString(jsonString, options) {\n return new type().fromJsonString(jsonString, options);\n },\n equals(a, b) {\n return runtime.util.equals(type, a, b);\n },\n });\n return type;\n}\n","// Copyright 2023 LiveKit, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// @generated by protoc-gen-es v1.10.0 with parameter \"target=js+dts\"\n// @generated from file livekit_models.proto (package livekit, syntax proto3)\n/* eslint-disable */\n// @ts-nocheck\n\nimport { proto3, Timestamp } from \"@bufbuild/protobuf\";\nimport { MetricsBatch } from \"./livekit_metrics_pb.js\";\n\n/**\n * @generated from enum livekit.AudioCodec\n */\nexport const AudioCodec = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.AudioCodec\",\n [\n {no: 0, name: \"DEFAULT_AC\"},\n {no: 1, name: \"OPUS\"},\n {no: 2, name: \"AAC\"},\n ],\n);\n\n/**\n * @generated from enum livekit.VideoCodec\n */\nexport const VideoCodec = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.VideoCodec\",\n [\n {no: 0, name: \"DEFAULT_VC\"},\n {no: 1, name: \"H264_BASELINE\"},\n {no: 2, name: \"H264_MAIN\"},\n {no: 3, name: \"H264_HIGH\"},\n {no: 4, name: \"VP8\"},\n ],\n);\n\n/**\n * @generated from enum livekit.ImageCodec\n */\nexport const ImageCodec = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.ImageCodec\",\n [\n {no: 0, name: \"IC_DEFAULT\"},\n {no: 1, name: \"IC_JPEG\"},\n ],\n);\n\n/**\n * @generated from enum livekit.TrackType\n */\nexport const TrackType = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.TrackType\",\n [\n {no: 0, name: \"AUDIO\"},\n {no: 1, name: \"VIDEO\"},\n {no: 2, name: \"DATA\"},\n ],\n);\n\n/**\n * @generated from enum livekit.TrackSource\n */\nexport const TrackSource = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.TrackSource\",\n [\n {no: 0, name: \"UNKNOWN\"},\n {no: 1, name: \"CAMERA\"},\n {no: 2, name: \"MICROPHONE\"},\n {no: 3, name: \"SCREEN_SHARE\"},\n {no: 4, name: \"SCREEN_SHARE_AUDIO\"},\n ],\n);\n\n/**\n * @generated from enum livekit.VideoQuality\n */\nexport const VideoQuality = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.VideoQuality\",\n [\n {no: 0, name: \"LOW\"},\n {no: 1, name: \"MEDIUM\"},\n {no: 2, name: \"HIGH\"},\n {no: 3, name: \"OFF\"},\n ],\n);\n\n/**\n * @generated from enum livekit.ConnectionQuality\n */\nexport const ConnectionQuality = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.ConnectionQuality\",\n [\n {no: 0, name: \"POOR\"},\n {no: 1, name: \"GOOD\"},\n {no: 2, name: \"EXCELLENT\"},\n {no: 3, name: \"LOST\"},\n ],\n);\n\n/**\n * @generated from enum livekit.ClientConfigSetting\n */\nexport const ClientConfigSetting = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.ClientConfigSetting\",\n [\n {no: 0, name: \"UNSET\"},\n {no: 1, name: \"DISABLED\"},\n {no: 2, name: \"ENABLED\"},\n ],\n);\n\n/**\n * @generated from enum livekit.DisconnectReason\n */\nexport const DisconnectReason = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.DisconnectReason\",\n [\n {no: 0, name: \"UNKNOWN_REASON\"},\n {no: 1, name: \"CLIENT_INITIATED\"},\n {no: 2, name: \"DUPLICATE_IDENTITY\"},\n {no: 3, name: \"SERVER_SHUTDOWN\"},\n {no: 4, name: \"PARTICIPANT_REMOVED\"},\n {no: 5, name: \"ROOM_DELETED\"},\n {no: 6, name: \"STATE_MISMATCH\"},\n {no: 7, name: \"JOIN_FAILURE\"},\n {no: 8, name: \"MIGRATION\"},\n {no: 9, name: \"SIGNAL_CLOSE\"},\n {no: 10, name: \"ROOM_CLOSED\"},\n ],\n);\n\n/**\n * @generated from enum livekit.ReconnectReason\n */\nexport const ReconnectReason = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.ReconnectReason\",\n [\n {no: 0, name: \"RR_UNKNOWN\"},\n {no: 1, name: \"RR_SIGNAL_DISCONNECTED\"},\n {no: 2, name: \"RR_PUBLISHER_FAILED\"},\n {no: 3, name: \"RR_SUBSCRIBER_FAILED\"},\n {no: 4, name: \"RR_SWITCH_CANDIDATE\"},\n ],\n);\n\n/**\n * @generated from enum livekit.SubscriptionError\n */\nexport const SubscriptionError = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.SubscriptionError\",\n [\n {no: 0, name: \"SE_UNKNOWN\"},\n {no: 1, name: \"SE_CODEC_UNSUPPORTED\"},\n {no: 2, name: \"SE_TRACK_NOTFOUND\"},\n ],\n);\n\n/**\n * @generated from enum livekit.AudioTrackFeature\n */\nexport const AudioTrackFeature = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.AudioTrackFeature\",\n [\n {no: 0, name: \"TF_STEREO\"},\n {no: 1, name: \"TF_NO_DTX\"},\n {no: 2, name: \"TF_AUTO_GAIN_CONTROL\"},\n {no: 3, name: \"TF_ECHO_CANCELLATION\"},\n {no: 4, name: \"TF_NOISE_SUPPRESSION\"},\n {no: 5, name: \"TF_ENHANCED_NOISE_CANCELLATION\"},\n ],\n);\n\n/**\n * @generated from message livekit.Room\n */\nexport const Room = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.Room\",\n () => [\n { no: 1, name: \"sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"name\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 3, name: \"empty_timeout\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 14, name: \"departure_timeout\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 4, name: \"max_participants\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 5, name: \"creation_time\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */ },\n { no: 6, name: \"turn_password\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 7, name: \"enabled_codecs\", kind: \"message\", T: Codec, repeated: true },\n { no: 8, name: \"metadata\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 9, name: \"num_participants\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 11, name: \"num_publishers\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 10, name: \"active_recording\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 13, name: \"version\", kind: \"message\", T: TimedVersion },\n ],\n);\n\n/**\n * @generated from message livekit.Codec\n */\nexport const Codec = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.Codec\",\n () => [\n { no: 1, name: \"mime\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"fmtp_line\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n ],\n);\n\n/**\n * @generated from message livekit.PlayoutDelay\n */\nexport const PlayoutDelay = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.PlayoutDelay\",\n () => [\n { no: 1, name: \"enabled\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 2, name: \"min\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 3, name: \"max\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n ],\n);\n\n/**\n * @generated from message livekit.ParticipantPermission\n */\nexport const ParticipantPermission = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.ParticipantPermission\",\n () => [\n { no: 1, name: \"can_subscribe\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 2, name: \"can_publish\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 3, name: \"can_publish_data\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 9, name: \"can_publish_sources\", kind: \"enum\", T: proto3.getEnumType(TrackSource), repeated: true },\n { no: 7, name: \"hidden\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 8, name: \"recorder\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 10, name: \"can_update_metadata\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 11, name: \"agent\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 12, name: \"can_subscribe_metrics\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n ],\n);\n\n/**\n * @generated from message livekit.ParticipantInfo\n */\nexport const ParticipantInfo = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.ParticipantInfo\",\n () => [\n { no: 1, name: \"sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"identity\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 3, name: \"state\", kind: \"enum\", T: proto3.getEnumType(ParticipantInfo_State) },\n { no: 4, name: \"tracks\", kind: \"message\", T: TrackInfo, repeated: true },\n { no: 5, name: \"metadata\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 6, name: \"joined_at\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */ },\n { no: 9, name: \"name\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 10, name: \"version\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 11, name: \"permission\", kind: \"message\", T: ParticipantPermission },\n { no: 12, name: \"region\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 13, name: \"is_publisher\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 14, name: \"kind\", kind: \"enum\", T: proto3.getEnumType(ParticipantInfo_Kind) },\n { no: 15, name: \"attributes\", kind: \"map\", K: 9 /* ScalarType.STRING */, V: {kind: \"scalar\", T: 9 /* ScalarType.STRING */} },\n { no: 16, name: \"disconnect_reason\", kind: \"enum\", T: proto3.getEnumType(DisconnectReason) },\n ],\n);\n\n/**\n * @generated from enum livekit.ParticipantInfo.State\n */\nexport const ParticipantInfo_State = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.ParticipantInfo.State\",\n [\n {no: 0, name: \"JOINING\"},\n {no: 1, name: \"JOINED\"},\n {no: 2, name: \"ACTIVE\"},\n {no: 3, name: \"DISCONNECTED\"},\n ],\n);\n\n/**\n * @generated from enum livekit.ParticipantInfo.Kind\n */\nexport const ParticipantInfo_Kind = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.ParticipantInfo.Kind\",\n [\n {no: 0, name: \"STANDARD\"},\n {no: 1, name: \"INGRESS\"},\n {no: 2, name: \"EGRESS\"},\n {no: 3, name: \"SIP\"},\n {no: 4, name: \"AGENT\"},\n ],\n);\n\n/**\n * @generated from message livekit.Encryption\n */\nexport const Encryption = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.Encryption\",\n [],\n);\n\n/**\n * @generated from enum livekit.Encryption.Type\n */\nexport const Encryption_Type = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.Encryption.Type\",\n [\n {no: 0, name: \"NONE\"},\n {no: 1, name: \"GCM\"},\n {no: 2, name: \"CUSTOM\"},\n ],\n);\n\n/**\n * @generated from message livekit.SimulcastCodecInfo\n */\nexport const SimulcastCodecInfo = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SimulcastCodecInfo\",\n () => [\n { no: 1, name: \"mime_type\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"mid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 3, name: \"cid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 4, name: \"layers\", kind: \"message\", T: VideoLayer, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.TrackInfo\n */\nexport const TrackInfo = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.TrackInfo\",\n () => [\n { no: 1, name: \"sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"type\", kind: \"enum\", T: proto3.getEnumType(TrackType) },\n { no: 3, name: \"name\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 4, name: \"muted\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 5, name: \"width\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 6, name: \"height\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 7, name: \"simulcast\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 8, name: \"disable_dtx\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 9, name: \"source\", kind: \"enum\", T: proto3.getEnumType(TrackSource) },\n { no: 10, name: \"layers\", kind: \"message\", T: VideoLayer, repeated: true },\n { no: 11, name: \"mime_type\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 12, name: \"mid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 13, name: \"codecs\", kind: \"message\", T: SimulcastCodecInfo, repeated: true },\n { no: 14, name: \"stereo\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 15, name: \"disable_red\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 16, name: \"encryption\", kind: \"enum\", T: proto3.getEnumType(Encryption_Type) },\n { no: 17, name: \"stream\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 18, name: \"version\", kind: \"message\", T: TimedVersion },\n { no: 19, name: \"audio_features\", kind: \"enum\", T: proto3.getEnumType(AudioTrackFeature), repeated: true },\n ],\n);\n\n/**\n * provide information about available spatial layers\n *\n * @generated from message livekit.VideoLayer\n */\nexport const VideoLayer = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.VideoLayer\",\n () => [\n { no: 1, name: \"quality\", kind: \"enum\", T: proto3.getEnumType(VideoQuality) },\n { no: 2, name: \"width\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 3, name: \"height\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 4, name: \"bitrate\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 5, name: \"ssrc\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n ],\n);\n\n/**\n * new DataPacket API\n *\n * @generated from message livekit.DataPacket\n */\nexport const DataPacket = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.DataPacket\",\n () => [\n { no: 1, name: \"kind\", kind: \"enum\", T: proto3.getEnumType(DataPacket_Kind) },\n { no: 4, name: \"participant_identity\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 5, name: \"destination_identities\", kind: \"scalar\", T: 9 /* ScalarType.STRING */, repeated: true },\n { no: 2, name: \"user\", kind: \"message\", T: UserPacket, oneof: \"value\" },\n { no: 3, name: \"speaker\", kind: \"message\", T: ActiveSpeakerUpdate, oneof: \"value\" },\n { no: 6, name: \"sip_dtmf\", kind: \"message\", T: SipDTMF, oneof: \"value\" },\n { no: 7, name: \"transcription\", kind: \"message\", T: Transcription, oneof: \"value\" },\n { no: 8, name: \"metrics\", kind: \"message\", T: MetricsBatch, oneof: \"value\" },\n { no: 9, name: \"chat_message\", kind: \"message\", T: ChatMessage, oneof: \"value\" },\n ],\n);\n\n/**\n * @generated from enum livekit.DataPacket.Kind\n */\nexport const DataPacket_Kind = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.DataPacket.Kind\",\n [\n {no: 0, name: \"RELIABLE\"},\n {no: 1, name: \"LOSSY\"},\n ],\n);\n\n/**\n * @generated from message livekit.ActiveSpeakerUpdate\n */\nexport const ActiveSpeakerUpdate = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.ActiveSpeakerUpdate\",\n () => [\n { no: 1, name: \"speakers\", kind: \"message\", T: SpeakerInfo, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.SpeakerInfo\n */\nexport const SpeakerInfo = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SpeakerInfo\",\n () => [\n { no: 1, name: \"sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"level\", kind: \"scalar\", T: 2 /* ScalarType.FLOAT */ },\n { no: 3, name: \"active\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n ],\n);\n\n/**\n * @generated from message livekit.UserPacket\n */\nexport const UserPacket = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.UserPacket\",\n () => [\n { no: 1, name: \"participant_sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 5, name: \"participant_identity\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"payload\", kind: \"scalar\", T: 12 /* ScalarType.BYTES */ },\n { no: 3, name: \"destination_sids\", kind: \"scalar\", T: 9 /* ScalarType.STRING */, repeated: true },\n { no: 6, name: \"destination_identities\", kind: \"scalar\", T: 9 /* ScalarType.STRING */, repeated: true },\n { no: 4, name: \"topic\", kind: \"scalar\", T: 9 /* ScalarType.STRING */, opt: true },\n { no: 8, name: \"id\", kind: \"scalar\", T: 9 /* ScalarType.STRING */, opt: true },\n { no: 9, name: \"start_time\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */, opt: true },\n { no: 10, name: \"end_time\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */, opt: true },\n ],\n);\n\n/**\n * @generated from message livekit.SipDTMF\n */\nexport const SipDTMF = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SipDTMF\",\n () => [\n { no: 3, name: \"code\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 4, name: \"digit\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n ],\n);\n\n/**\n * @generated from message livekit.Transcription\n */\nexport const Transcription = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.Transcription\",\n () => [\n { no: 2, name: \"transcribed_participant_identity\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 3, name: \"track_id\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 4, name: \"segments\", kind: \"message\", T: TranscriptionSegment, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.TranscriptionSegment\n */\nexport const TranscriptionSegment = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.TranscriptionSegment\",\n () => [\n { no: 1, name: \"id\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"text\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 3, name: \"start_time\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 4, name: \"end_time\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 5, name: \"final\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 6, name: \"language\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n ],\n);\n\n/**\n * @generated from message livekit.ChatMessage\n */\nexport const ChatMessage = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.ChatMessage\",\n () => [\n { no: 1, name: \"id\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"timestamp\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */ },\n { no: 3, name: \"edit_timestamp\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */, opt: true },\n { no: 4, name: \"message\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 5, name: \"deleted\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 6, name: \"generated\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n ],\n);\n\n/**\n * @generated from message livekit.ParticipantTracks\n */\nexport const ParticipantTracks = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.ParticipantTracks\",\n () => [\n { no: 1, name: \"participant_sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"track_sids\", kind: \"scalar\", T: 9 /* ScalarType.STRING */, repeated: true },\n ],\n);\n\n/**\n * details about the server\n *\n * @generated from message livekit.ServerInfo\n */\nexport const ServerInfo = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.ServerInfo\",\n () => [\n { no: 1, name: \"edition\", kind: \"enum\", T: proto3.getEnumType(ServerInfo_Edition) },\n { no: 2, name: \"version\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 3, name: \"protocol\", kind: \"scalar\", T: 5 /* ScalarType.INT32 */ },\n { no: 4, name: \"region\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 5, name: \"node_id\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 6, name: \"debug_info\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 7, name: \"agent_protocol\", kind: \"scalar\", T: 5 /* ScalarType.INT32 */ },\n ],\n);\n\n/**\n * @generated from enum livekit.ServerInfo.Edition\n */\nexport const ServerInfo_Edition = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.ServerInfo.Edition\",\n [\n {no: 0, name: \"Standard\"},\n {no: 1, name: \"Cloud\"},\n ],\n);\n\n/**\n * details about the client\n *\n * @generated from message livekit.ClientInfo\n */\nexport const ClientInfo = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.ClientInfo\",\n () => [\n { no: 1, name: \"sdk\", kind: \"enum\", T: proto3.getEnumType(ClientInfo_SDK) },\n { no: 2, name: \"version\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 3, name: \"protocol\", kind: \"scalar\", T: 5 /* ScalarType.INT32 */ },\n { no: 4, name: \"os\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 5, name: \"os_version\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 6, name: \"device_model\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 7, name: \"browser\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 8, name: \"browser_version\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 9, name: \"address\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 10, name: \"network\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n ],\n);\n\n/**\n * @generated from enum livekit.ClientInfo.SDK\n */\nexport const ClientInfo_SDK = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.ClientInfo.SDK\",\n [\n {no: 0, name: \"UNKNOWN\"},\n {no: 1, name: \"JS\"},\n {no: 2, name: \"SWIFT\"},\n {no: 3, name: \"ANDROID\"},\n {no: 4, name: \"FLUTTER\"},\n {no: 5, name: \"GO\"},\n {no: 6, name: \"UNITY\"},\n {no: 7, name: \"REACT_NATIVE\"},\n {no: 8, name: \"RUST\"},\n {no: 9, name: \"PYTHON\"},\n {no: 10, name: \"CPP\"},\n {no: 11, name: \"UNITY_WEB\"},\n {no: 12, name: \"NODE\"},\n ],\n);\n\n/**\n * server provided client configuration\n *\n * @generated from message livekit.ClientConfiguration\n */\nexport const ClientConfiguration = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.ClientConfiguration\",\n () => [\n { no: 1, name: \"video\", kind: \"message\", T: VideoConfiguration },\n { no: 2, name: \"screen\", kind: \"message\", T: VideoConfiguration },\n { no: 3, name: \"resume_connection\", kind: \"enum\", T: proto3.getEnumType(ClientConfigSetting) },\n { no: 4, name: \"disabled_codecs\", kind: \"message\", T: DisabledCodecs },\n { no: 5, name: \"force_relay\", kind: \"enum\", T: proto3.getEnumType(ClientConfigSetting) },\n ],\n);\n\n/**\n * @generated from message livekit.VideoConfiguration\n */\nexport const VideoConfiguration = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.VideoConfiguration\",\n () => [\n { no: 1, name: \"hardware_encoder\", kind: \"enum\", T: proto3.getEnumType(ClientConfigSetting) },\n ],\n);\n\n/**\n * @generated from message livekit.DisabledCodecs\n */\nexport const DisabledCodecs = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.DisabledCodecs\",\n () => [\n { no: 1, name: \"codecs\", kind: \"message\", T: Codec, repeated: true },\n { no: 2, name: \"publish\", kind: \"message\", T: Codec, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.RTPDrift\n */\nexport const RTPDrift = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.RTPDrift\",\n () => [\n { no: 1, name: \"start_time\", kind: \"message\", T: Timestamp },\n { no: 2, name: \"end_time\", kind: \"message\", T: Timestamp },\n { no: 3, name: \"duration\", kind: \"scalar\", T: 1 /* ScalarType.DOUBLE */ },\n { no: 4, name: \"start_timestamp\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 5, name: \"end_timestamp\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 6, name: \"rtp_clock_ticks\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 7, name: \"drift_samples\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */ },\n { no: 8, name: \"drift_ms\", kind: \"scalar\", T: 1 /* ScalarType.DOUBLE */ },\n { no: 9, name: \"clock_rate\", kind: \"scalar\", T: 1 /* ScalarType.DOUBLE */ },\n ],\n);\n\n/**\n * @generated from message livekit.RTPStats\n */\nexport const RTPStats = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.RTPStats\",\n () => [\n { no: 1, name: \"start_time\", kind: \"message\", T: Timestamp },\n { no: 2, name: \"end_time\", kind: \"message\", T: Timestamp },\n { no: 3, name: \"duration\", kind: \"scalar\", T: 1 /* ScalarType.DOUBLE */ },\n { no: 4, name: \"packets\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 5, name: \"packet_rate\", kind: \"scalar\", T: 1 /* ScalarType.DOUBLE */ },\n { no: 6, name: \"bytes\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 39, name: \"header_bytes\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 7, name: \"bitrate\", kind: \"scalar\", T: 1 /* ScalarType.DOUBLE */ },\n { no: 8, name: \"packets_lost\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 9, name: \"packet_loss_rate\", kind: \"scalar\", T: 1 /* ScalarType.DOUBLE */ },\n { no: 10, name: \"packet_loss_percentage\", kind: \"scalar\", T: 2 /* ScalarType.FLOAT */ },\n { no: 11, name: \"packets_duplicate\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 12, name: \"packet_duplicate_rate\", kind: \"scalar\", T: 1 /* ScalarType.DOUBLE */ },\n { no: 13, name: \"bytes_duplicate\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 40, name: \"header_bytes_duplicate\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 14, name: \"bitrate_duplicate\", kind: \"scalar\", T: 1 /* ScalarType.DOUBLE */ },\n { no: 15, name: \"packets_padding\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 16, name: \"packet_padding_rate\", kind: \"scalar\", T: 1 /* ScalarType.DOUBLE */ },\n { no: 17, name: \"bytes_padding\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 41, name: \"header_bytes_padding\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 18, name: \"bitrate_padding\", kind: \"scalar\", T: 1 /* ScalarType.DOUBLE */ },\n { no: 19, name: \"packets_out_of_order\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 20, name: \"frames\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 21, name: \"frame_rate\", kind: \"scalar\", T: 1 /* ScalarType.DOUBLE */ },\n { no: 22, name: \"jitter_current\", kind: \"scalar\", T: 1 /* ScalarType.DOUBLE */ },\n { no: 23, name: \"jitter_max\", kind: \"scalar\", T: 1 /* ScalarType.DOUBLE */ },\n { no: 24, name: \"gap_histogram\", kind: \"map\", K: 5 /* ScalarType.INT32 */, V: {kind: \"scalar\", T: 13 /* ScalarType.UINT32 */} },\n { no: 25, name: \"nacks\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 37, name: \"nack_acks\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 26, name: \"nack_misses\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 38, name: \"nack_repeated\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 27, name: \"plis\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 28, name: \"last_pli\", kind: \"message\", T: Timestamp },\n { no: 29, name: \"firs\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 30, name: \"last_fir\", kind: \"message\", T: Timestamp },\n { no: 31, name: \"rtt_current\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 32, name: \"rtt_max\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 33, name: \"key_frames\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 34, name: \"last_key_frame\", kind: \"message\", T: Timestamp },\n { no: 35, name: \"layer_lock_plis\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 36, name: \"last_layer_lock_pli\", kind: \"message\", T: Timestamp },\n { no: 44, name: \"packet_drift\", kind: \"message\", T: RTPDrift },\n { no: 45, name: \"ntp_report_drift\", kind: \"message\", T: RTPDrift },\n { no: 46, name: \"rebased_report_drift\", kind: \"message\", T: RTPDrift },\n { no: 47, name: \"received_report_drift\", kind: \"message\", T: RTPDrift },\n ],\n);\n\n/**\n * @generated from message livekit.RTCPSenderReportState\n */\nexport const RTCPSenderReportState = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.RTCPSenderReportState\",\n () => [\n { no: 1, name: \"rtp_timestamp\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 2, name: \"rtp_timestamp_ext\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 3, name: \"ntp_timestamp\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 4, name: \"at\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */ },\n { no: 5, name: \"at_adjusted\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */ },\n { no: 6, name: \"packets\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 7, name: \"octets\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n ],\n);\n\n/**\n * @generated from message livekit.RTPForwarderState\n */\nexport const RTPForwarderState = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.RTPForwarderState\",\n () => [\n { no: 1, name: \"started\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 2, name: \"reference_layer_spatial\", kind: \"scalar\", T: 5 /* ScalarType.INT32 */ },\n { no: 3, name: \"pre_start_time\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */ },\n { no: 4, name: \"ext_first_timestamp\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 5, name: \"dummy_start_timestamp_offset\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 6, name: \"rtp_munger\", kind: \"message\", T: RTPMungerState },\n { no: 7, name: \"vp8_munger\", kind: \"message\", T: VP8MungerState, oneof: \"codec_munger\" },\n { no: 8, name: \"sender_report_state\", kind: \"message\", T: RTCPSenderReportState, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.RTPMungerState\n */\nexport const RTPMungerState = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.RTPMungerState\",\n () => [\n { no: 1, name: \"ext_last_sequence_number\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 2, name: \"ext_second_last_sequence_number\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 3, name: \"ext_last_timestamp\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 4, name: \"ext_second_last_timestamp\", kind: \"scalar\", T: 4 /* ScalarType.UINT64 */ },\n { no: 5, name: \"last_marker\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 6, name: \"second_last_marker\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n ],\n);\n\n/**\n * @generated from message livekit.VP8MungerState\n */\nexport const VP8MungerState = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.VP8MungerState\",\n () => [\n { no: 1, name: \"ext_last_picture_id\", kind: \"scalar\", T: 5 /* ScalarType.INT32 */ },\n { no: 2, name: \"picture_id_used\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 3, name: \"last_tl0_pic_idx\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 4, name: \"tl0_pic_idx_used\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 5, name: \"tid_used\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 6, name: \"last_key_idx\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 7, name: \"key_idx_used\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n ],\n);\n\n/**\n * @generated from message livekit.TimedVersion\n */\nexport const TimedVersion = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.TimedVersion\",\n () => [\n { no: 1, name: \"unix_micro\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */ },\n { no: 2, name: \"ticks\", kind: \"scalar\", T: 5 /* ScalarType.INT32 */ },\n ],\n);\n\n","// Copyright 2023 LiveKit, Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// @generated by protoc-gen-es v1.10.0 with parameter \"target=js+dts\"\n// @generated from file livekit_rtc.proto (package livekit, syntax proto3)\n/* eslint-disable */\n// @ts-nocheck\n\nimport { proto3 } from \"@bufbuild/protobuf\";\nimport { AudioTrackFeature, ClientConfiguration, Codec, ConnectionQuality, DisconnectReason, Encryption_Type, ParticipantInfo, ParticipantTracks, Room, ServerInfo, SpeakerInfo, SubscriptionError, TrackInfo, TrackSource, TrackType, VideoLayer, VideoQuality } from \"./livekit_models_pb.js\";\n\n/**\n * @generated from enum livekit.SignalTarget\n */\nexport const SignalTarget = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.SignalTarget\",\n [\n {no: 0, name: \"PUBLISHER\"},\n {no: 1, name: \"SUBSCRIBER\"},\n ],\n);\n\n/**\n * @generated from enum livekit.StreamState\n */\nexport const StreamState = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.StreamState\",\n [\n {no: 0, name: \"ACTIVE\"},\n {no: 1, name: \"PAUSED\"},\n ],\n);\n\n/**\n * @generated from enum livekit.CandidateProtocol\n */\nexport const CandidateProtocol = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.CandidateProtocol\",\n [\n {no: 0, name: \"UDP\"},\n {no: 1, name: \"TCP\"},\n {no: 2, name: \"TLS\"},\n ],\n);\n\n/**\n * @generated from message livekit.SignalRequest\n */\nexport const SignalRequest = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SignalRequest\",\n () => [\n { no: 1, name: \"offer\", kind: \"message\", T: SessionDescription, oneof: \"message\" },\n { no: 2, name: \"answer\", kind: \"message\", T: SessionDescription, oneof: \"message\" },\n { no: 3, name: \"trickle\", kind: \"message\", T: TrickleRequest, oneof: \"message\" },\n { no: 4, name: \"add_track\", kind: \"message\", T: AddTrackRequest, oneof: \"message\" },\n { no: 5, name: \"mute\", kind: \"message\", T: MuteTrackRequest, oneof: \"message\" },\n { no: 6, name: \"subscription\", kind: \"message\", T: UpdateSubscription, oneof: \"message\" },\n { no: 7, name: \"track_setting\", kind: \"message\", T: UpdateTrackSettings, oneof: \"message\" },\n { no: 8, name: \"leave\", kind: \"message\", T: LeaveRequest, oneof: \"message\" },\n { no: 10, name: \"update_layers\", kind: \"message\", T: UpdateVideoLayers, oneof: \"message\" },\n { no: 11, name: \"subscription_permission\", kind: \"message\", T: SubscriptionPermission, oneof: \"message\" },\n { no: 12, name: \"sync_state\", kind: \"message\", T: SyncState, oneof: \"message\" },\n { no: 13, name: \"simulate\", kind: \"message\", T: SimulateScenario, oneof: \"message\" },\n { no: 14, name: \"ping\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */, oneof: \"message\" },\n { no: 15, name: \"update_metadata\", kind: \"message\", T: UpdateParticipantMetadata, oneof: \"message\" },\n { no: 16, name: \"ping_req\", kind: \"message\", T: Ping, oneof: \"message\" },\n { no: 17, name: \"update_audio_track\", kind: \"message\", T: UpdateLocalAudioTrack, oneof: \"message\" },\n { no: 18, name: \"update_video_track\", kind: \"message\", T: UpdateLocalVideoTrack, oneof: \"message\" },\n ],\n);\n\n/**\n * @generated from message livekit.SignalResponse\n */\nexport const SignalResponse = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SignalResponse\",\n () => [\n { no: 1, name: \"join\", kind: \"message\", T: JoinResponse, oneof: \"message\" },\n { no: 2, name: \"answer\", kind: \"message\", T: SessionDescription, oneof: \"message\" },\n { no: 3, name: \"offer\", kind: \"message\", T: SessionDescription, oneof: \"message\" },\n { no: 4, name: \"trickle\", kind: \"message\", T: TrickleRequest, oneof: \"message\" },\n { no: 5, name: \"update\", kind: \"message\", T: ParticipantUpdate, oneof: \"message\" },\n { no: 6, name: \"track_published\", kind: \"message\", T: TrackPublishedResponse, oneof: \"message\" },\n { no: 8, name: \"leave\", kind: \"message\", T: LeaveRequest, oneof: \"message\" },\n { no: 9, name: \"mute\", kind: \"message\", T: MuteTrackRequest, oneof: \"message\" },\n { no: 10, name: \"speakers_changed\", kind: \"message\", T: SpeakersChanged, oneof: \"message\" },\n { no: 11, name: \"room_update\", kind: \"message\", T: RoomUpdate, oneof: \"message\" },\n { no: 12, name: \"connection_quality\", kind: \"message\", T: ConnectionQualityUpdate, oneof: \"message\" },\n { no: 13, name: \"stream_state_update\", kind: \"message\", T: StreamStateUpdate, oneof: \"message\" },\n { no: 14, name: \"subscribed_quality_update\", kind: \"message\", T: SubscribedQualityUpdate, oneof: \"message\" },\n { no: 15, name: \"subscription_permission_update\", kind: \"message\", T: SubscriptionPermissionUpdate, oneof: \"message\" },\n { no: 16, name: \"refresh_token\", kind: \"scalar\", T: 9 /* ScalarType.STRING */, oneof: \"message\" },\n { no: 17, name: \"track_unpublished\", kind: \"message\", T: TrackUnpublishedResponse, oneof: \"message\" },\n { no: 18, name: \"pong\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */, oneof: \"message\" },\n { no: 19, name: \"reconnect\", kind: \"message\", T: ReconnectResponse, oneof: \"message\" },\n { no: 20, name: \"pong_resp\", kind: \"message\", T: Pong, oneof: \"message\" },\n { no: 21, name: \"subscription_response\", kind: \"message\", T: SubscriptionResponse, oneof: \"message\" },\n { no: 22, name: \"request_response\", kind: \"message\", T: RequestResponse, oneof: \"message\" },\n { no: 23, name: \"track_subscribed\", kind: \"message\", T: TrackSubscribed, oneof: \"message\" },\n ],\n);\n\n/**\n * @generated from message livekit.SimulcastCodec\n */\nexport const SimulcastCodec = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SimulcastCodec\",\n () => [\n { no: 1, name: \"codec\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"cid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n ],\n);\n\n/**\n * @generated from message livekit.AddTrackRequest\n */\nexport const AddTrackRequest = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.AddTrackRequest\",\n () => [\n { no: 1, name: \"cid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"name\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 3, name: \"type\", kind: \"enum\", T: proto3.getEnumType(TrackType) },\n { no: 4, name: \"width\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 5, name: \"height\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 6, name: \"muted\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 7, name: \"disable_dtx\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 8, name: \"source\", kind: \"enum\", T: proto3.getEnumType(TrackSource) },\n { no: 9, name: \"layers\", kind: \"message\", T: VideoLayer, repeated: true },\n { no: 10, name: \"simulcast_codecs\", kind: \"message\", T: SimulcastCodec, repeated: true },\n { no: 11, name: \"sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 12, name: \"stereo\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 13, name: \"disable_red\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 14, name: \"encryption\", kind: \"enum\", T: proto3.getEnumType(Encryption_Type) },\n { no: 15, name: \"stream\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n ],\n);\n\n/**\n * @generated from message livekit.TrickleRequest\n */\nexport const TrickleRequest = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.TrickleRequest\",\n () => [\n { no: 1, name: \"candidateInit\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"target\", kind: \"enum\", T: proto3.getEnumType(SignalTarget) },\n { no: 3, name: \"final\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n ],\n);\n\n/**\n * @generated from message livekit.MuteTrackRequest\n */\nexport const MuteTrackRequest = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.MuteTrackRequest\",\n () => [\n { no: 1, name: \"sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"muted\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n ],\n);\n\n/**\n * @generated from message livekit.JoinResponse\n */\nexport const JoinResponse = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.JoinResponse\",\n () => [\n { no: 1, name: \"room\", kind: \"message\", T: Room },\n { no: 2, name: \"participant\", kind: \"message\", T: ParticipantInfo },\n { no: 3, name: \"other_participants\", kind: \"message\", T: ParticipantInfo, repeated: true },\n { no: 4, name: \"server_version\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 5, name: \"ice_servers\", kind: \"message\", T: ICEServer, repeated: true },\n { no: 6, name: \"subscriber_primary\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 7, name: \"alternative_url\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 8, name: \"client_configuration\", kind: \"message\", T: ClientConfiguration },\n { no: 9, name: \"server_region\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 10, name: \"ping_timeout\", kind: \"scalar\", T: 5 /* ScalarType.INT32 */ },\n { no: 11, name: \"ping_interval\", kind: \"scalar\", T: 5 /* ScalarType.INT32 */ },\n { no: 12, name: \"server_info\", kind: \"message\", T: ServerInfo },\n { no: 13, name: \"sif_trailer\", kind: \"scalar\", T: 12 /* ScalarType.BYTES */ },\n { no: 14, name: \"enabled_publish_codecs\", kind: \"message\", T: Codec, repeated: true },\n { no: 15, name: \"fast_publish\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n ],\n);\n\n/**\n * @generated from message livekit.ReconnectResponse\n */\nexport const ReconnectResponse = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.ReconnectResponse\",\n () => [\n { no: 1, name: \"ice_servers\", kind: \"message\", T: ICEServer, repeated: true },\n { no: 2, name: \"client_configuration\", kind: \"message\", T: ClientConfiguration },\n ],\n);\n\n/**\n * @generated from message livekit.TrackPublishedResponse\n */\nexport const TrackPublishedResponse = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.TrackPublishedResponse\",\n () => [\n { no: 1, name: \"cid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"track\", kind: \"message\", T: TrackInfo },\n ],\n);\n\n/**\n * @generated from message livekit.TrackUnpublishedResponse\n */\nexport const TrackUnpublishedResponse = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.TrackUnpublishedResponse\",\n () => [\n { no: 1, name: \"track_sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n ],\n);\n\n/**\n * @generated from message livekit.SessionDescription\n */\nexport const SessionDescription = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SessionDescription\",\n () => [\n { no: 1, name: \"type\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"sdp\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n ],\n);\n\n/**\n * @generated from message livekit.ParticipantUpdate\n */\nexport const ParticipantUpdate = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.ParticipantUpdate\",\n () => [\n { no: 1, name: \"participants\", kind: \"message\", T: ParticipantInfo, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.UpdateSubscription\n */\nexport const UpdateSubscription = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.UpdateSubscription\",\n () => [\n { no: 1, name: \"track_sids\", kind: \"scalar\", T: 9 /* ScalarType.STRING */, repeated: true },\n { no: 2, name: \"subscribe\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 3, name: \"participant_tracks\", kind: \"message\", T: ParticipantTracks, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.UpdateTrackSettings\n */\nexport const UpdateTrackSettings = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.UpdateTrackSettings\",\n () => [\n { no: 1, name: \"track_sids\", kind: \"scalar\", T: 9 /* ScalarType.STRING */, repeated: true },\n { no: 3, name: \"disabled\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 4, name: \"quality\", kind: \"enum\", T: proto3.getEnumType(VideoQuality) },\n { no: 5, name: \"width\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 6, name: \"height\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 7, name: \"fps\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 8, name: \"priority\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n ],\n);\n\n/**\n * @generated from message livekit.UpdateLocalAudioTrack\n */\nexport const UpdateLocalAudioTrack = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.UpdateLocalAudioTrack\",\n () => [\n { no: 1, name: \"track_sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"features\", kind: \"enum\", T: proto3.getEnumType(AudioTrackFeature), repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.UpdateLocalVideoTrack\n */\nexport const UpdateLocalVideoTrack = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.UpdateLocalVideoTrack\",\n () => [\n { no: 1, name: \"track_sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"width\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 3, name: \"height\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n ],\n);\n\n/**\n * @generated from message livekit.LeaveRequest\n */\nexport const LeaveRequest = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.LeaveRequest\",\n () => [\n { no: 1, name: \"can_reconnect\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 2, name: \"reason\", kind: \"enum\", T: proto3.getEnumType(DisconnectReason) },\n { no: 3, name: \"action\", kind: \"enum\", T: proto3.getEnumType(LeaveRequest_Action) },\n { no: 4, name: \"regions\", kind: \"message\", T: RegionSettings },\n ],\n);\n\n/**\n * indicates action clients should take on receiving this message\n *\n * @generated from enum livekit.LeaveRequest.Action\n */\nexport const LeaveRequest_Action = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.LeaveRequest.Action\",\n [\n {no: 0, name: \"DISCONNECT\"},\n {no: 1, name: \"RESUME\"},\n {no: 2, name: \"RECONNECT\"},\n ],\n);\n\n/**\n * message to indicate published video track dimensions are changing\n *\n * @generated from message livekit.UpdateVideoLayers\n * @deprecated\n */\nexport const UpdateVideoLayers = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.UpdateVideoLayers\",\n () => [\n { no: 1, name: \"track_sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"layers\", kind: \"message\", T: VideoLayer, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.UpdateParticipantMetadata\n */\nexport const UpdateParticipantMetadata = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.UpdateParticipantMetadata\",\n () => [\n { no: 1, name: \"metadata\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"name\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 3, name: \"attributes\", kind: \"map\", K: 9 /* ScalarType.STRING */, V: {kind: \"scalar\", T: 9 /* ScalarType.STRING */} },\n { no: 4, name: \"request_id\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n ],\n);\n\n/**\n * @generated from message livekit.ICEServer\n */\nexport const ICEServer = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.ICEServer\",\n () => [\n { no: 1, name: \"urls\", kind: \"scalar\", T: 9 /* ScalarType.STRING */, repeated: true },\n { no: 2, name: \"username\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 3, name: \"credential\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n ],\n);\n\n/**\n * @generated from message livekit.SpeakersChanged\n */\nexport const SpeakersChanged = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SpeakersChanged\",\n () => [\n { no: 1, name: \"speakers\", kind: \"message\", T: SpeakerInfo, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.RoomUpdate\n */\nexport const RoomUpdate = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.RoomUpdate\",\n () => [\n { no: 1, name: \"room\", kind: \"message\", T: Room },\n ],\n);\n\n/**\n * @generated from message livekit.ConnectionQualityInfo\n */\nexport const ConnectionQualityInfo = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.ConnectionQualityInfo\",\n () => [\n { no: 1, name: \"participant_sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"quality\", kind: \"enum\", T: proto3.getEnumType(ConnectionQuality) },\n { no: 3, name: \"score\", kind: \"scalar\", T: 2 /* ScalarType.FLOAT */ },\n ],\n);\n\n/**\n * @generated from message livekit.ConnectionQualityUpdate\n */\nexport const ConnectionQualityUpdate = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.ConnectionQualityUpdate\",\n () => [\n { no: 1, name: \"updates\", kind: \"message\", T: ConnectionQualityInfo, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.StreamStateInfo\n */\nexport const StreamStateInfo = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.StreamStateInfo\",\n () => [\n { no: 1, name: \"participant_sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"track_sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 3, name: \"state\", kind: \"enum\", T: proto3.getEnumType(StreamState) },\n ],\n);\n\n/**\n * @generated from message livekit.StreamStateUpdate\n */\nexport const StreamStateUpdate = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.StreamStateUpdate\",\n () => [\n { no: 1, name: \"stream_states\", kind: \"message\", T: StreamStateInfo, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.SubscribedQuality\n */\nexport const SubscribedQuality = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SubscribedQuality\",\n () => [\n { no: 1, name: \"quality\", kind: \"enum\", T: proto3.getEnumType(VideoQuality) },\n { no: 2, name: \"enabled\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n ],\n);\n\n/**\n * @generated from message livekit.SubscribedCodec\n */\nexport const SubscribedCodec = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SubscribedCodec\",\n () => [\n { no: 1, name: \"codec\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"qualities\", kind: \"message\", T: SubscribedQuality, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.SubscribedQualityUpdate\n */\nexport const SubscribedQualityUpdate = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SubscribedQualityUpdate\",\n () => [\n { no: 1, name: \"track_sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"subscribed_qualities\", kind: \"message\", T: SubscribedQuality, repeated: true },\n { no: 3, name: \"subscribed_codecs\", kind: \"message\", T: SubscribedCodec, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.TrackPermission\n */\nexport const TrackPermission = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.TrackPermission\",\n () => [\n { no: 1, name: \"participant_sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"all_tracks\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 3, name: \"track_sids\", kind: \"scalar\", T: 9 /* ScalarType.STRING */, repeated: true },\n { no: 4, name: \"participant_identity\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n ],\n);\n\n/**\n * @generated from message livekit.SubscriptionPermission\n */\nexport const SubscriptionPermission = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SubscriptionPermission\",\n () => [\n { no: 1, name: \"all_participants\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n { no: 2, name: \"track_permissions\", kind: \"message\", T: TrackPermission, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.SubscriptionPermissionUpdate\n */\nexport const SubscriptionPermissionUpdate = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SubscriptionPermissionUpdate\",\n () => [\n { no: 1, name: \"participant_sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"track_sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 3, name: \"allowed\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */ },\n ],\n);\n\n/**\n * @generated from message livekit.SyncState\n */\nexport const SyncState = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SyncState\",\n () => [\n { no: 1, name: \"answer\", kind: \"message\", T: SessionDescription },\n { no: 2, name: \"subscription\", kind: \"message\", T: UpdateSubscription },\n { no: 3, name: \"publish_tracks\", kind: \"message\", T: TrackPublishedResponse, repeated: true },\n { no: 4, name: \"data_channels\", kind: \"message\", T: DataChannelInfo, repeated: true },\n { no: 5, name: \"offer\", kind: \"message\", T: SessionDescription },\n { no: 6, name: \"track_sids_disabled\", kind: \"scalar\", T: 9 /* ScalarType.STRING */, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.DataChannelInfo\n */\nexport const DataChannelInfo = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.DataChannelInfo\",\n () => [\n { no: 1, name: \"label\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"id\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 3, name: \"target\", kind: \"enum\", T: proto3.getEnumType(SignalTarget) },\n ],\n);\n\n/**\n * @generated from message livekit.SimulateScenario\n */\nexport const SimulateScenario = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SimulateScenario\",\n () => [\n { no: 1, name: \"speaker_update\", kind: \"scalar\", T: 5 /* ScalarType.INT32 */, oneof: \"scenario\" },\n { no: 2, name: \"node_failure\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */, oneof: \"scenario\" },\n { no: 3, name: \"migration\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */, oneof: \"scenario\" },\n { no: 4, name: \"server_leave\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */, oneof: \"scenario\" },\n { no: 5, name: \"switch_candidate_protocol\", kind: \"enum\", T: proto3.getEnumType(CandidateProtocol), oneof: \"scenario\" },\n { no: 6, name: \"subscriber_bandwidth\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */, oneof: \"scenario\" },\n { no: 7, name: \"disconnect_signal_on_resume\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */, oneof: \"scenario\" },\n { no: 8, name: \"disconnect_signal_on_resume_no_messages\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */, oneof: \"scenario\" },\n { no: 9, name: \"leave_request_full_reconnect\", kind: \"scalar\", T: 8 /* ScalarType.BOOL */, oneof: \"scenario\" },\n ],\n);\n\n/**\n * @generated from message livekit.Ping\n */\nexport const Ping = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.Ping\",\n () => [\n { no: 1, name: \"timestamp\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */ },\n { no: 2, name: \"rtt\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */ },\n ],\n);\n\n/**\n * @generated from message livekit.Pong\n */\nexport const Pong = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.Pong\",\n () => [\n { no: 1, name: \"last_ping_timestamp\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */ },\n { no: 2, name: \"timestamp\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */ },\n ],\n);\n\n/**\n * @generated from message livekit.RegionSettings\n */\nexport const RegionSettings = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.RegionSettings\",\n () => [\n { no: 1, name: \"regions\", kind: \"message\", T: RegionInfo, repeated: true },\n ],\n);\n\n/**\n * @generated from message livekit.RegionInfo\n */\nexport const RegionInfo = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.RegionInfo\",\n () => [\n { no: 1, name: \"region\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"url\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 3, name: \"distance\", kind: \"scalar\", T: 3 /* ScalarType.INT64 */ },\n ],\n);\n\n/**\n * @generated from message livekit.SubscriptionResponse\n */\nexport const SubscriptionResponse = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.SubscriptionResponse\",\n () => [\n { no: 1, name: \"track_sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n { no: 2, name: \"err\", kind: \"enum\", T: proto3.getEnumType(SubscriptionError) },\n ],\n);\n\n/**\n * @generated from message livekit.RequestResponse\n */\nexport const RequestResponse = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.RequestResponse\",\n () => [\n { no: 1, name: \"request_id\", kind: \"scalar\", T: 13 /* ScalarType.UINT32 */ },\n { no: 2, name: \"reason\", kind: \"enum\", T: proto3.getEnumType(RequestResponse_Reason) },\n { no: 3, name: \"message\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n ],\n);\n\n/**\n * @generated from enum livekit.RequestResponse.Reason\n */\nexport const RequestResponse_Reason = /*@__PURE__*/ proto3.makeEnum(\n \"livekit.RequestResponse.Reason\",\n [\n {no: 0, name: \"OK\"},\n {no: 1, name: \"NOT_FOUND\"},\n {no: 2, name: \"NOT_ALLOWED\"},\n {no: 3, name: \"LIMIT_EXCEEDED\"},\n ],\n);\n\n/**\n * @generated from message livekit.TrackSubscribed\n */\nexport const TrackSubscribed = /*@__PURE__*/ proto3.makeMessageType(\n \"livekit.TrackSubscribed\",\n () => [\n { no: 1, name: \"track_sid\", kind: \"scalar\", T: 9 /* ScalarType.STRING */ },\n ],\n);\n\n","// tiny, simplified version of https://github.com/lancedikson/bowser/blob/master/src/parser-browsers.js\n// reduced to only differentiate Chrome(ium) based browsers / Firefox / Safari\n\nconst commonVersionIdentifier = /version\\/(\\d+(\\.?_?\\d+)+)/i;\n\nexport type DetectableBrowser = 'Chrome' | 'Firefox' | 'Safari';\nexport type DetectableOS = 'iOS' | 'macOS';\n\nexport type BrowserDetails = {\n name: DetectableBrowser;\n version: string;\n os?: DetectableOS;\n osVersion?: string;\n};\n\nlet browserDetails: BrowserDetails | undefined;\n\n/**\n * @internal\n */\nexport function getBrowser(userAgent?: string, force = true): BrowserDetails | undefined {\n if (typeof userAgent === 'undefined' && typeof navigator === 'undefined') {\n return;\n }\n const ua = (userAgent ?? navigator.userAgent).toLowerCase();\n if (browserDetails === undefined || force) {\n const browser = browsersList.find(({ test }) => test.test(ua));\n browserDetails = browser?.describe(ua);\n }\n return browserDetails;\n}\n\nconst browsersList = [\n {\n test: /firefox|iceweasel|fxios/i,\n describe(ua: string) {\n const browser: BrowserDetails = {\n name: 'Firefox',\n version: getMatch(/(?:firefox|iceweasel|fxios)[\\s/](\\d+(\\.?_?\\d+)+)/i, ua),\n os: ua.toLowerCase().includes('fxios') ? 'iOS' : undefined,\n osVersion: getOSVersion(ua),\n };\n return browser;\n },\n },\n {\n test: /chrom|crios|crmo/i,\n describe(ua: string) {\n const browser: BrowserDetails = {\n name: 'Chrome',\n version: getMatch(/(?:chrome|chromium|crios|crmo)\\/(\\d+(\\.?_?\\d+)+)/i, ua),\n os: ua.toLowerCase().includes('crios') ? 'iOS' : undefined,\n osVersion: getOSVersion(ua),\n };\n\n return browser;\n },\n },\n /* Safari */\n {\n test: /safari|applewebkit/i,\n describe(ua: string) {\n const browser: BrowserDetails = {\n name: 'Safari',\n version: getMatch(commonVersionIdentifier, ua),\n os: ua.includes('mobile/') ? 'iOS' : 'macOS',\n osVersion: getOSVersion(ua),\n };\n\n return browser;\n },\n },\n];\n\nfunction getMatch(exp: RegExp, ua: string, id = 1) {\n const match = ua.match(exp);\n return (match && match.length >= id && match[id]) || '';\n}\n\nfunction getOSVersion(ua: string) {\n return ua.includes('mac os')\n ? getMatch(/\\(.+?(\\d+_\\d+(:?_\\d+)?)/, ua, 1).replace(/_/g, '.')\n : undefined;\n}\n","import type { Track } from './Track';\nimport type {\n AudioProcessorOptions,\n TrackProcessor,\n VideoProcessorOptions,\n} from './processor/types';\n\nexport interface TrackPublishDefaults {\n /**\n * encoding parameters for camera track\n */\n videoEncoding?: VideoEncoding;\n\n /**\n * Multi-codec Simulcast\n * VP9 and AV1 are not supported by all browser clients. When backupCodec is\n * set, when an incompatible client attempts to subscribe to the track, LiveKit\n * will automatically publish a secondary track encoded with the backup codec.\n *\n * You could customize specific encoding parameters of the backup track by\n * explicitly setting codec and encoding fields.\n *\n * Defaults to `true`\n */\n backupCodec?: true | false | { codec: BackupVideoCodec; encoding?: VideoEncoding };\n\n /**\n * encoding parameters for screen share track\n */\n screenShareEncoding?: VideoEncoding;\n\n /**\n * codec, defaults to vp8; for svc codecs, auto enable vp8\n * as backup. (TBD)\n */\n videoCodec?: VideoCodec;\n\n /**\n * which audio preset should be used for publishing (audio) tracks\n * defaults to [[AudioPresets.music]]\n */\n audioPreset?: AudioPreset;\n\n /**\n * dtx (Discontinuous Transmission of audio), enabled by default for mono tracks.\n */\n dtx?: boolean;\n\n /**\n * red (Redundant Audio Data), enabled by default for mono tracks.\n */\n red?: boolean;\n\n /**\n * publish track in stereo mode (or set to false to disable). defaults determined by capture channel count.\n */\n forceStereo?: boolean;\n\n /**\n * use simulcast, defaults to true.\n * When using simulcast, LiveKit will publish up to three versions of the stream\n * at various resolutions.\n */\n simulcast?: boolean;\n\n /**\n * scalability mode for svc codecs, defaults to 'L3T3_KEY'.\n * for svc codecs, simulcast is disabled.\n */\n scalabilityMode?: ScalabilityMode;\n\n /**\n * degradation preference\n */\n degradationPreference?: RTCDegradationPreference;\n\n /**\n * Up to two additional simulcast layers to publish in addition to the original\n * Track.\n * When left blank, it defaults to h180, h360.\n * If a SVC codec is used (VP9 or AV1), this field has no effect.\n *\n * To publish three total layers, you would specify:\n * {\n * videoEncoding: {...}, // encoding of the primary layer\n * videoSimulcastLayers: [\n * VideoPresets.h540,\n * VideoPresets.h216,\n * ],\n * }\n */\n videoSimulcastLayers?: Array<VideoPreset>;\n\n /**\n * custom video simulcast layers for screen tracks\n * Note: the layers need to be ordered from lowest to highest quality\n */\n screenShareSimulcastLayers?: Array<VideoPreset>;\n\n /**\n * For local tracks, stop the underlying MediaStreamTrack when the track is muted (or paused)\n * on some platforms, this option is necessary to disable the microphone recording indicator.\n * Note: when this is enabled, and BT devices are connected, they will transition between\n * profiles (e.g. HFP to A2DP) and there will be an audible difference in playback.\n *\n * defaults to false\n */\n stopMicTrackOnMute?: boolean;\n}\n\n/**\n * Options when publishing tracks\n */\nexport interface TrackPublishOptions extends TrackPublishDefaults {\n /**\n * set a track name\n */\n name?: string;\n\n /**\n * Source of track, camera, microphone, or screen\n */\n source?: Track.Source;\n\n /**\n * Set stream name for the track. Audio and video tracks with the same stream name\n * will be placed in the same `MediaStream` and offer better synchronization.\n * By default, camera and microphone will be placed in a stream; as would screen_share and screen_share_audio\n */\n stream?: string;\n}\n\nexport interface CreateLocalTracksOptions {\n /**\n * audio track options, true to create with defaults. false if audio shouldn't be created\n * default true\n */\n audio?: boolean | AudioCaptureOptions;\n\n /**\n * video track options, true to create with defaults. false if video shouldn't be created\n * default true\n */\n video?: boolean | VideoCaptureOptions;\n}\n\nexport interface VideoCaptureOptions {\n /**\n * A ConstrainDOMString object specifying a device ID or an array of device\n * IDs which are acceptable and/or required.\n */\n deviceId?: ConstrainDOMString;\n\n /**\n * a facing or an array of facings which are acceptable and/or required.\n */\n facingMode?: 'user' | 'environment' | 'left' | 'right';\n\n resolution?: VideoResolution;\n\n /**\n * initialize the track with a given processor\n */\n processor?: TrackProcessor<Track.Kind.Video, VideoProcessorOptions>;\n}\n\nexport interface ScreenShareCaptureOptions {\n /**\n * true to capture audio shared. browser support for audio capturing in\n * screenshare is limited: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia#browser_compatibility\n */\n audio?: boolean | AudioCaptureOptions;\n\n /**\n * only allows for 'true' and chrome allows for additional options to be passed in\n * https://developer.chrome.com/docs/web-platform/screen-sharing-controls/#displaySurface\n */\n video?: true | { displaySurface?: 'window' | 'browser' | 'monitor' };\n\n /**\n * capture resolution, defaults to 1080 for all browsers other than Safari\n * On Safari 17, default resolution is not capped, due to a bug, specifying\n * any resolution at all would lead to a low-resolution capture.\n * https://bugs.webkit.org/show_bug.cgi?id=263015\n */\n resolution?: VideoResolution;\n\n /** a CaptureController object instance containing methods that can be used to further manipulate the capture session if included. */\n controller?: unknown; // TODO replace type with CaptureController once it lands in TypeScript\n\n /** specifies whether the browser should allow the user to select the current tab for capture */\n selfBrowserSurface?: 'include' | 'exclude';\n\n /** specifies whether the browser should display a control to allow the user to dynamically switch the shared tab during screen-sharing. */\n surfaceSwitching?: 'include' | 'exclude';\n\n /** specifies whether the browser should include the system audio among the possible audio sources offered to the user */\n systemAudio?: 'include' | 'exclude';\n\n /** specify the type of content, see: https://www.w3.org/TR/mst-content-hint/#video-content-hints */\n contentHint?: 'detail' | 'text' | 'motion';\n\n /**\n * Experimental option to control whether the audio playing in a tab will continue to be played out of a user's\n * local speakers when the tab is captured.\n */\n suppressLocalAudioPlayback?: boolean;\n\n /**\n * Experimental option to instruct the browser to offer the current tab as the most prominent capture source\n * @experimental\n * @see https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia#prefercurrenttab\n */\n preferCurrentTab?: boolean;\n}\n\nexport interface AudioCaptureOptions {\n /**\n * specifies whether automatic gain control is preferred and/or required\n */\n autoGainControl?: ConstrainBoolean;\n\n /**\n * the channel count or range of channel counts which are acceptable and/or required\n */\n channelCount?: ConstrainULong;\n\n /**\n * A ConstrainDOMString object specifying a device ID or an array of device\n * IDs which are acceptable and/or required.\n */\n deviceId?: ConstrainDOMString;\n\n /**\n * whether or not echo cancellation is preferred and/or required\n */\n echoCancellation?: ConstrainBoolean;\n\n /**\n * the latency or range of latencies which are acceptable and/or required.\n */\n latency?: ConstrainDouble;\n\n /**\n * whether noise suppression is preferred and/or required.\n */\n noiseSuppression?: ConstrainBoolean;\n\n /**\n * the sample rate or range of sample rates which are acceptable and/or required.\n */\n sampleRate?: ConstrainULong;\n\n /**\n * sample size or range of sample sizes which are acceptable and/or required.\n */\n sampleSize?: ConstrainULong;\n\n /**\n * initialize the track with a given processor\n */\n processor?: TrackProcessor<Track.Kind.Audio, AudioProcessorOptions>;\n}\n\nexport interface AudioOutputOptions {\n /**\n * deviceId to output audio\n *\n * Only supported on browsers where `setSinkId` is available\n */\n deviceId?: string;\n}\n\nexport interface VideoResolution {\n width: number;\n height: number;\n frameRate?: number;\n aspectRatio?: number;\n}\n\nexport interface VideoEncoding {\n maxBitrate: number;\n maxFramerate?: number;\n priority?: RTCPriorityType;\n}\n\nexport interface VideoPresetOptions {\n width: number;\n height: number;\n aspectRatio?: number;\n maxBitrate: number;\n maxFramerate?: number;\n priority?: RTCPriorityType;\n}\n\nexport class VideoPreset {\n encoding: VideoEncoding;\n\n width: number;\n\n height: number;\n\n aspectRatio?: number;\n\n constructor(videoPresetOptions: VideoPresetOptions);\n constructor(\n width: number,\n height: number,\n maxBitrate: number,\n maxFramerate?: number,\n priority?: RTCPriorityType,\n );\n constructor(\n widthOrOptions: number | VideoPresetOptions,\n height?: number,\n maxBitrate?: number,\n maxFramerate?: number,\n priority?: RTCPriorityType,\n ) {\n if (typeof widthOrOptions === 'object') {\n this.width = widthOrOptions.width;\n this.height = widthOrOptions.height;\n this.aspectRatio = widthOrOptions.aspectRatio;\n this.encoding = {\n maxBitrate: widthOrOptions.maxBitrate,\n maxFramerate: widthOrOptions.maxFramerate,\n priority: widthOrOptions.priority,\n };\n } else if (height !== undefined && maxBitrate !== undefined) {\n this.width = widthOrOptions;\n this.height = height;\n this.aspectRatio = widthOrOptions / height;\n this.encoding = {\n maxBitrate,\n maxFramerate,\n priority,\n };\n } else {\n throw new TypeError('Unsupported options: provide at least width, height and maxBitrate');\n }\n }\n\n get resolution(): VideoResolution {\n return {\n width: this.width,\n height: this.height,\n frameRate: this.encoding.maxFramerate,\n aspectRatio: this.aspectRatio,\n };\n }\n}\n\nexport interface AudioPreset {\n maxBitrate: number;\n priority?: RTCPriorityType;\n}\n\nconst backupCodecs = ['vp8', 'h264'] as const;\n\nexport const videoCodecs = ['vp8', 'h264', 'vp9', 'av1'] as const;\n\nexport type VideoCodec = (typeof videoCodecs)[number];\n\nexport type BackupVideoCodec = (typeof backupCodecs)[number];\n\nexport function isBackupCodec(codec: string): codec is BackupVideoCodec {\n return !!backupCodecs.find((backup) => backup === codec);\n}\n\n/**\n * scalability modes for svc.\n */\nexport type ScalabilityMode =\n | 'L1T1'\n | 'L1T2'\n | 'L1T3'\n | 'L2T1'\n | 'L2T1h'\n | 'L2T1_KEY'\n | 'L2T2'\n | 'L2T2h'\n | 'L2T2_KEY'\n | 'L2T3'\n | 'L2T3h'\n | 'L2T3_KEY'\n | 'L3T1'\n | 'L3T1h'\n | 'L3T1_KEY'\n | 'L3T2'\n | 'L3T2h'\n | 'L3T2_KEY'\n | 'L3T3'\n | 'L3T3h'\n | 'L3T3_KEY';\n\nexport namespace AudioPresets {\n export const telephone: AudioPreset = {\n maxBitrate: 12_000,\n };\n export const speech: AudioPreset = {\n maxBitrate: 20_000,\n };\n export const music: AudioPreset = {\n maxBitrate: 32_000,\n };\n export const musicStereo: AudioPreset = {\n maxBitrate: 48_000,\n };\n export const musicHighQuality: AudioPreset = {\n maxBitrate: 64_000,\n };\n export const musicHighQualityStereo: AudioPreset = {\n maxBitrate: 96_000,\n };\n}\n\n/**\n * Sane presets for video resolution/encoding\n */\nexport const VideoPresets = {\n h90: new VideoPreset(160, 90, 90_000, 20),\n h180: new VideoPreset(320, 180, 160_000, 20),\n h216: new VideoPreset(384, 216, 180_000, 20),\n h360: new VideoPreset(640, 360, 450_000, 20),\n h540: new VideoPreset(960, 540, 800_000, 25),\n h720: new VideoPreset(1280, 720, 1_700_000, 30),\n h1080: new VideoPreset(1920, 1080, 3_000_000, 30),\n h1440: new VideoPreset(2560, 1440, 5_000_000, 30),\n h2160: new VideoPreset(3840, 2160, 8_000_000, 30),\n} as const;\n\n/**\n * Four by three presets\n */\nexport const VideoPresets43 = {\n h120: new VideoPreset(160, 120, 70_000, 20),\n h180: new VideoPreset(240, 180, 125_000, 20),\n h240: new VideoPreset(320, 240, 140_000, 20),\n h360: new VideoPreset(480, 360, 330_000, 20),\n h480: new VideoPreset(640, 480, 500_000, 20),\n h540: new VideoPreset(720, 540, 600_000, 25),\n h720: new VideoPreset(960, 720, 1_300_000, 30),\n h1080: new VideoPreset(1440, 1080, 2_300_000, 30),\n h1440: new VideoPreset(1920, 1440, 3_800_000, 30),\n} as const;\n\nexport const ScreenSharePresets = {\n h360fps3: new VideoPreset(640, 360, 200_000, 3, 'medium'),\n h360fps15: new VideoPreset(640, 360, 400_000, 15, 'medium'),\n h720fps5: new VideoPreset(1280, 720, 800_000, 5, 'medium'),\n h720fps15: new VideoPreset(1280, 720, 1_500_000, 15, 'medium'),\n h720fps30: new VideoPreset(1280, 720, 2_000_000, 30, 'medium'),\n h1080fps15: new VideoPreset(1920, 1080, 2_500_000, 15, 'medium'),\n h1080fps30: new VideoPreset(1920, 1080, 5_000_000, 30, 'medium'),\n // original resolution, without resizing\n original: new VideoPreset(0, 0, 7_000_000, 30, 'medium'),\n} as const;\n","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nvar R = typeof Reflect === 'object' ? Reflect : null\nvar ReflectApply = R && typeof R.apply === 'function'\n ? R.apply\n : function ReflectApply(target, receiver, args) {\n return Function.prototype.apply.call(target, receiver, args);\n }\n\nvar ReflectOwnKeys\nif (R && typeof R.ownKeys === 'function') {\n ReflectOwnKeys = R.ownKeys\n} else if (Object.getOwnPropertySymbols) {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target)\n .concat(Object.getOwnPropertySymbols(target));\n };\n} else {\n ReflectOwnKeys = function ReflectOwnKeys(target) {\n return Object.getOwnPropertyNames(target);\n };\n}\n\nfunction ProcessEmitWarning(warning) {\n if (console && console.warn) console.warn(warning);\n}\n\nvar NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {\n return value !== value;\n}\n\nfunction EventEmitter() {\n EventEmitter.init.call(this);\n}\nmodule.exports = EventEmitter;\nmodule.exports.once = once;\n\n// Backwards-compat with node 0.10.x\nEventEmitter.EventEmitter = EventEmitter;\n\nEventEmitter.prototype._events = undefined;\nEventEmitter.prototype._eventsCount = 0;\nEventEmitter.prototype._maxListeners = undefined;\n\n// By default EventEmitters will print a warning if more than 10 listeners are\n// added to it. This is a useful default which helps finding memory leaks.\nvar defaultMaxListeners = 10;\n\nfunction checkListener(listener) {\n if (typeof listener !== 'function') {\n throw new TypeError('The \"listener\" argument must be of type Function. Received type ' + typeof listener);\n }\n}\n\nObject.defineProperty(EventEmitter, 'defaultMaxListeners', {\n enumerable: true,\n get: function() {\n return defaultMaxListeners;\n },\n set: function(arg) {\n if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {\n throw new RangeError('The value of \"defaultMaxListeners\" is out of range. It must be a non-negative number. Received ' + arg + '.');\n }\n defaultMaxListeners = arg;\n }\n});\n\nEventEmitter.init = function() {\n\n if (this._events === undefined ||\n this._events === Object.getPrototypeOf(this)._events) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n }\n\n this._maxListeners = this._maxListeners || undefined;\n};\n\n// Obviously not all Emitters should be limited to 10. This function allows\n// that to be increased. Set to zero for unlimited.\nEventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {\n if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {\n throw new RangeError('The value of \"n\" is out of range. It must be a non-negative number. Received ' + n + '.');\n }\n this._maxListeners = n;\n return this;\n};\n\nfunction _getMaxListeners(that) {\n if (that._maxListeners === undefined)\n return EventEmitter.defaultMaxListeners;\n return that._maxListeners;\n}\n\nEventEmitter.prototype.getMaxListeners = function getMaxListeners() {\n return _getMaxListeners(this);\n};\n\nEventEmitter.prototype.emit = function emit(type) {\n var args = [];\n for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);\n var doError = (type === 'error');\n\n var events = this._events;\n if (events !== undefined)\n doError = (doError && events.error === undefined);\n else if (!doError)\n return false;\n\n // If there is no 'error' event listener then throw.\n if (doError) {\n var er;\n if (args.length > 0)\n er = args[0];\n if (er instanceof Error) {\n // Note: The comments on the `throw` lines are intentional, they show\n // up in Node's output if this results in an unhandled exception.\n throw er; // Unhandled 'error' event\n }\n // At least give some kind of context to the user\n var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));\n err.context = er;\n throw err; // Unhandled 'error' event\n }\n\n var handler = events[type];\n\n if (handler === undefined)\n return false;\n\n if (typeof handler === 'function') {\n ReflectApply(handler, this, args);\n } else {\n var len = handler.length;\n var listeners = arrayClone(handler, len);\n for (var i = 0; i < len; ++i)\n ReflectApply(listeners[i], this, args);\n }\n\n return true;\n};\n\nfunction _addListener(target, type, listener, prepend) {\n var m;\n var events;\n var existing;\n\n checkListener(listener);\n\n events = target._events;\n if (events === undefined) {\n events = target._events = Object.create(null);\n target._eventsCount = 0;\n } else {\n // To avoid recursion in the case that type === \"newListener\"! Before\n // adding it to the listeners, first emit \"newListener\".\n if (events.newListener !== undefined) {\n target.emit('newListener', type,\n listener.listener ? listener.listener : listener);\n\n // Re-assign `events` because a newListener handler could have caused the\n // this._events to be assigned to a new object\n events = target._events;\n }\n existing = events[type];\n }\n\n if (existing === undefined) {\n // Optimize the case of one listener. Don't need the extra array object.\n existing = events[type] = listener;\n ++target._eventsCount;\n } else {\n if (typeof existing === 'function') {\n // Adding the second element, need to change to array.\n existing = events[type] =\n prepend ? [listener, existing] : [existing, listener];\n // If we've already got an array, just append.\n } else if (prepend) {\n existing.unshift(listener);\n } else {\n existing.push(listener);\n }\n\n // Check for listener leak\n m = _getMaxListeners(target);\n if (m > 0 && existing.length > m && !existing.warned) {\n existing.warned = true;\n // No error code for this since it is a Warning\n // eslint-disable-next-line no-restricted-syntax\n var w = new Error('Possible EventEmitter memory leak detected. ' +\n existing.length + ' ' + String(type) + ' listeners ' +\n 'added. Use emitter.setMaxListeners() to ' +\n 'increase limit');\n w.name = 'MaxListenersExceededWarning';\n w.emitter = target;\n w.type = type;\n w.count = existing.length;\n ProcessEmitWarning(w);\n }\n }\n\n return target;\n}\n\nEventEmitter.prototype.addListener = function addListener(type, listener) {\n return _addListener(this, type, listener, false);\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.prependListener =\n function prependListener(type, listener) {\n return _addListener(this, type, listener, true);\n };\n\nfunction onceWrapper() {\n if (!this.fired) {\n this.target.removeListener(this.type, this.wrapFn);\n this.fired = true;\n if (arguments.length === 0)\n return this.listener.call(this.target);\n return this.listener.apply(this.target, arguments);\n }\n}\n\nfunction _onceWrap(target, type, listener) {\n var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };\n var wrapped = onceWrapper.bind(state);\n wrapped.listener = listener;\n state.wrapFn = wrapped;\n return wrapped;\n}\n\nEventEmitter.prototype.once = function once(type, listener) {\n checkListener(listener);\n this.on(type, _onceWrap(this, type, listener));\n return this;\n};\n\nEventEmitter.prototype.prependOnceListener =\n function prependOnceListener(type, listener) {\n checkListener(listener);\n this.prependListener(type, _onceWrap(this, type, listener));\n return this;\n };\n\n// Emits a 'removeListener' event if and only if the listener was removed.\nEventEmitter.prototype.removeListener =\n function removeListener(type, listener) {\n var list, events, position, i, originalListener;\n\n checkListener(listener);\n\n events = this._events;\n if (events === undefined)\n return this;\n\n list = events[type];\n if (list === undefined)\n return this;\n\n if (list === listener || list.listener === listener) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else {\n delete events[type];\n if (events.removeListener)\n this.emit('removeListener', type, list.listener || listener);\n }\n } else if (typeof list !== 'function') {\n position = -1;\n\n for (i = list.length - 1; i >= 0; i--) {\n if (list[i] === listener || list[i].listener === listener) {\n originalListener = list[i].listener;\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (position === 0)\n list.shift();\n else {\n spliceOne(list, position);\n }\n\n if (list.length === 1)\n events[type] = list[0];\n\n if (events.removeListener !== undefined)\n this.emit('removeListener', type, originalListener || listener);\n }\n\n return this;\n };\n\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\n\nEventEmitter.prototype.removeAllListeners =\n function removeAllListeners(type) {\n var listeners, events, i;\n\n events = this._events;\n if (events === undefined)\n return this;\n\n // not listening for removeListener, no need to emit\n if (events.removeListener === undefined) {\n if (arguments.length === 0) {\n this._events = Object.create(null);\n this._eventsCount = 0;\n } else if (events[type] !== undefined) {\n if (--this._eventsCount === 0)\n this._events = Object.create(null);\n else\n delete events[type];\n }\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n var keys = Object.keys(events);\n var key;\n for (i = 0; i < keys.length; ++i) {\n key = keys[i];\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = Object.create(null);\n this._eventsCount = 0;\n return this;\n }\n\n listeners = events[type];\n\n if (typeof listeners === 'function') {\n this.removeListener(type, listeners);\n } else if (listeners !== undefined) {\n // LIFO order\n for (i = listeners.length - 1; i >= 0; i--) {\n this.removeListener(type, listeners[i]);\n }\n }\n\n return this;\n };\n\nfunction _listeners(target, type, unwrap) {\n var events = target._events;\n\n if (events === undefined)\n return [];\n\n var evlistener = events[type];\n if (evlistener === undefined)\n return [];\n\n if (typeof evlistener === 'function')\n return unwrap ? [evlistener.listener || evlistener] : [evlistener];\n\n return unwrap ?\n unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);\n}\n\nEventEmitter.prototype.listeners = function listeners(type) {\n return _listeners(this, type, true);\n};\n\nEventEmitter.prototype.rawListeners = function rawListeners(type) {\n return _listeners(this, type, false);\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n if (typeof emitter.listenerCount === 'function') {\n return emitter.listenerCount(type);\n } else {\n return listenerCount.call(emitter, type);\n }\n};\n\nEventEmitter.prototype.listenerCount = listenerCount;\nfunction listenerCount(type) {\n var events = this._events;\n\n if (events !== undefined) {\n var evlistener = events[type];\n\n if (typeof evlistener === 'function') {\n return 1;\n } else if (evlistener !== undefined) {\n return evlistener.length;\n }\n }\n\n return 0;\n}\n\nEventEmitter.prototype.eventNames = function eventNames() {\n return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];\n};\n\nfunction arrayClone(arr, n) {\n var copy = new Array(n);\n for (var i = 0; i < n; ++i)\n copy[i] = arr[i];\n return copy;\n}\n\nfunction spliceOne(list, index) {\n for (; index + 1 < list.length; index++)\n list[index] = list[index + 1];\n list.pop();\n}\n\nfunction unwrapListeners(arr) {\n var ret = new Array(arr.length);\n for (var i = 0; i < ret.length; ++i) {\n ret[i] = arr[i].listener || arr[i];\n }\n return ret;\n}\n\nfunction once(emitter, name) {\n return new Promise(function (resolve, reject) {\n function errorListener(err) {\n emitter.removeListener(name, resolver);\n reject(err);\n }\n\n function resolver() {\n if (typeof emitter.removeListener === 'function') {\n emitter.removeListener('error', errorListener);\n }\n resolve([].slice.call(arguments));\n };\n\n eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });\n if (name !== 'error') {\n addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });\n }\n });\n}\n\nfunction addErrorHandlerIfEventEmitter(emitter, handler, flags) {\n if (typeof emitter.on === 'function') {\n eventTargetAgnosticAddListener(emitter, 'error', handler, flags);\n }\n}\n\nfunction eventTargetAgnosticAddListener(emitter, name, listener, flags) {\n if (typeof emitter.on === 'function') {\n if (flags.once) {\n emitter.once(name, listener);\n } else {\n emitter.on(name, listener);\n }\n } else if (typeof emitter.addEventListener === 'function') {\n // EventTarget does not have `error` event semantics like Node\n // EventEmitters, we do not listen for `error` events here.\n emitter.addEventListener(name, function wrapListener(arg) {\n // IE does not have builtin `{ once: true }` support so we\n // have to do it manually.\n if (flags.once) {\n emitter.removeEventListener(name, wrapListener);\n }\n listener(arg);\n });\n } else {\n throw new TypeError('The \"emitter\" argument must be of type EventEmitter. Received type ' + typeof emitter);\n }\n}\n","/**\n * Events are the primary way LiveKit notifies your application of changes.\n *\n * The following are events emitted by [[Room]], listen to room events like\n *\n * ```typescript\n * room.on(RoomEvent.TrackPublished, (track, publication, participant) => {})\n * ```\n */\n\nexport enum RoomEvent {\n /**\n * When the connection to the server has been established\n */\n Connected = 'connected',\n\n /**\n * When the connection to the server has been interrupted and it's attempting\n * to reconnect.\n */\n Reconnecting = 'reconnecting',\n\n /**\n * When the signal connection to the server has been interrupted. This isn't noticeable to users most of the time.\n * It will resolve with a `RoomEvent.Reconnected` once the signal connection has been re-established.\n * If media fails additionally it an additional `RoomEvent.Reconnecting` will be emitted.\n */\n SignalReconnecting = 'signalReconnecting',\n\n /**\n * Fires when a reconnection has been successful.\n */\n Reconnected = 'reconnected',\n\n /**\n * When disconnected from room. This fires when room.disconnect() is called or\n * when an unrecoverable connection issue had occured.\n *\n * DisconnectReason can be used to determine why the participant was disconnected. Notable reasons are\n * - DUPLICATE_IDENTITY: another client with the same identity has joined the room\n * - PARTICIPANT_REMOVED: participant was removed by RemoveParticipant API\n * - ROOM_DELETED: the room has ended via DeleteRoom API\n *\n * args: ([[DisconnectReason]])\n */\n Disconnected = 'disconnected',\n\n /**\n * Whenever the connection state of the room changes\n *\n * args: ([[ConnectionState]])\n */\n ConnectionStateChanged = 'connectionStateChanged',\n\n /**\n * When input or output devices on the machine have changed.\n */\n MediaDevicesChanged = 'mediaDevicesChanged',\n\n /**\n * When a [[RemoteParticipant]] joins *after* the local\n * participant. It will not emit events for participants that are already\n * in the room\n *\n * args: ([[RemoteParticipant]])\n */\n ParticipantConnected = 'participantConnected',\n\n /**\n * When a [[RemoteParticipant]] leaves *after* the local\n * participant has joined.\n *\n * args: ([[RemoteParticipant]])\n */\n ParticipantDisconnected = 'participantDisconnected',\n\n /**\n * When a new track is published to room *after* the local\n * participant has joined. It will not fire for tracks that are already published.\n *\n * A track published doesn't mean the participant has subscribed to it. It's\n * simply reflecting the state of the room.\n *\n * args: ([[RemoteTrackPublication]], [[RemoteParticipant]])\n */\n TrackPublished = 'trackPublished',\n\n /**\n * The [[LocalParticipant]] has subscribed to a new track. This event will **always**\n * fire as long as new tracks are ready for use.\n *\n * args: ([[RemoteTrack]], [[RemoteTrackPublication]], [[RemoteParticipant]])\n */\n TrackSubscribed = 'trackSubscribed',\n\n /**\n * Could not subscribe to a track\n *\n * args: (track sid, [[RemoteParticipant]])\n */\n TrackSubscriptionFailed = 'trackSubscriptionFailed',\n\n /**\n * A [[RemoteParticipant]] has unpublished a track\n *\n * args: ([[RemoteTrackPublication]], [[RemoteParticipant]])\n */\n TrackUnpublished = 'trackUnpublished',\n\n /**\n * A subscribed track is no longer available. Clients should listen to this\n * event and ensure they detach tracks.\n *\n * args: ([[Track]], [[RemoteTrackPublication]], [[RemoteParticipant]])\n */\n TrackUnsubscribed = 'trackUnsubscribed',\n\n /**\n * A track that was muted, fires on both [[RemoteParticipant]]s and [[LocalParticipant]]\n *\n * args: ([[TrackPublication]], [[Participant]])\n */\n TrackMuted = 'trackMuted',\n\n /**\n * A track that was unmuted, fires on both [[RemoteParticipant]]s and [[LocalParticipant]]\n *\n * args: ([[TrackPublication]], [[Participant]])\n */\n TrackUnmuted = 'trackUnmuted',\n\n /**\n * A local track was published successfully. This event is helpful to know\n * when to update your local UI with the newly published track.\n *\n * args: ([[LocalTrackPublication]], [[LocalParticipant]])\n */\n LocalTrackPublished = 'localTrackPublished',\n\n /**\n * A local track was unpublished. This event is helpful to know when to remove\n * the local track from your UI.\n *\n * When a user stops sharing their screen by pressing \"End\" on the browser UI,\n * this event will also fire.\n *\n * args: ([[LocalTrackPublication]], [[LocalParticipant]])\n */\n LocalTrackUnpublished = 'localTrackUnpublished',\n\n /**\n * When a local audio track is published the SDK checks whether there is complete silence\n * on that track and emits the LocalAudioSilenceDetected event in that case.\n * This allows for applications to show UI informing users that they might have to\n * reset their audio hardware or check for proper device connectivity.\n */\n LocalAudioSilenceDetected = 'localAudioSilenceDetected',\n\n /**\n * Active speakers changed. List of speakers are ordered by their audio level.\n * loudest speakers first. This will include the LocalParticipant too.\n *\n * Speaker updates are sent only to the publishing participant and their subscribers.\n *\n * args: (Array<[[Participant]]>)\n */\n ActiveSpeakersChanged = 'activeSpeakersChanged',\n\n /**\n * Participant metadata is a simple way for app-specific state to be pushed to\n * all users.\n * When RoomService.UpdateParticipantMetadata is called to change a participant's\n * state, *all* participants in the room will fire this event.\n *\n * args: (prevMetadata: string, [[Participant]])\n *\n */\n ParticipantMetadataChanged = 'participantMetadataChanged',\n\n /**\n * Participant's display name changed\n *\n * args: (name: string, [[Participant]])\n *\n */\n ParticipantNameChanged = 'participantNameChanged',\n\n /**\n * Participant attributes is an app-specific key value state to be pushed to\n * all users.\n * When a participant's attributes changed, this event will be emitted with the changed attributes and the participant\n * args: (changedAttributes: [[Record<string, string]], participant: [[Participant]])\n */\n ParticipantAttributesChanged = 'participantAttributesChanged',\n\n /**\n * Room metadata is a simple way for app-specific state to be pushed to\n * all users.\n * When RoomService.UpdateRoomMetadata is called to change a room's state,\n * *all* participants in the room will fire this event.\n *\n * args: (string)\n */\n RoomMetadataChanged = 'roomMetadataChanged',\n\n /**\n * Data received from another participant.\n * Data packets provides the ability to use LiveKit to send/receive arbitrary payloads.\n * All participants in the room will receive the messages sent to the room.\n *\n * args: (payload: Uint8Array, participant: [[Participant]], kind: [[DataPacket_Kind]], topic?: string)\n */\n DataReceived = 'dataReceived',\n\n /**\n * SIP DTMF tones received from another participant.\n *\n * args: (participant: [[Participant]], dtmf: [[DataPacket_Kind]])\n */\n SipDTMFReceived = 'sipDTMFReceived',\n\n /**\n * Transcription received from a participant's track.\n * @beta\n */\n TranscriptionReceived = 'transcriptionReceived',\n\n /**\n * Connection quality was changed for a Participant. It'll receive updates\n * from the local participant, as well as any [[RemoteParticipant]]s that we are\n * subscribed to.\n *\n * args: (connectionQuality: [[ConnectionQuality]], participant: [[Participant]])\n */\n ConnectionQualityChanged = 'connectionQualityChanged',\n\n /**\n * StreamState indicates if a subscribed (remote) track has been paused by the SFU\n * (typically this happens because of subscriber's bandwidth constraints)\n *\n * When bandwidth conditions allow, the track will be resumed automatically.\n * TrackStreamStateChanged will also be emitted when that happens.\n *\n * args: (pub: [[RemoteTrackPublication]], streamState: [[Track.StreamState]],\n * participant: [[RemoteParticipant]])\n */\n TrackStreamStateChanged = 'trackStreamStateChanged',\n\n /**\n * One of subscribed tracks have changed its permissions for the current\n * participant. If permission was revoked, then the track will no longer\n * be subscribed. If permission was granted, a TrackSubscribed event will\n * be emitted.\n *\n * args: (pub: [[RemoteTrackPublication]],\n * status: [[TrackPublication.PermissionStatus]],\n * participant: [[RemoteParticipant]])\n */\n TrackSubscriptionPermissionChanged = 'trackSubscriptionPermissionChanged',\n\n /**\n * One of subscribed tracks have changed its status for the current\n * participant.\n *\n * args: (pub: [[RemoteTrackPublication]],\n * status: [[TrackPublication.SubscriptionStatus]],\n * participant: [[RemoteParticipant]])\n */\n TrackSubscriptionStatusChanged = 'trackSubscriptionStatusChanged',\n\n /**\n * LiveKit will attempt to autoplay all audio tracks when you attach them to\n * audio elements. However, if that fails, we'll notify you via AudioPlaybackStatusChanged.\n * `Room.canPlaybackAudio` will indicate if audio playback is permitted.\n */\n AudioPlaybackStatusChanged = 'audioPlaybackChanged',\n\n /**\n * LiveKit will attempt to autoplay all video tracks when you attach them to\n * a video element. However, if that fails, we'll notify you via VideoPlaybackStatusChanged.\n * Calling `room.startVideo()` in a user gesture event handler will resume the video playback.\n */\n VideoPlaybackStatusChanged = 'videoPlaybackChanged',\n\n /**\n * When we have encountered an error while attempting to create a track.\n * The errors take place in getUserMedia().\n * Use MediaDeviceFailure.getFailure(error) to get the reason of failure.\n * [[LocalParticipant.lastCameraError]] and [[LocalParticipant.lastMicrophoneError]]\n * will indicate if it had an error while creating the audio or video track respectively.\n *\n * args: (error: Error)\n */\n MediaDevicesError = 'mediaDevicesError',\n\n /**\n * A participant's permission has changed. Currently only fired on LocalParticipant.\n * args: (prevPermissions: [[ParticipantPermission]], participant: [[Participant]])\n */\n ParticipantPermissionsChanged = 'participantPermissionsChanged',\n\n /**\n * Signal connected, can publish tracks.\n */\n SignalConnected = 'signalConnected',\n\n /**\n * Recording of a room has started/stopped. Room.isRecording will be updated too.\n * args: (isRecording: boolean)\n */\n RecordingStatusChanged = 'recordingStatusChanged',\n\n ParticipantEncryptionStatusChanged = 'participantEncryptionStatusChanged',\n\n EncryptionError = 'encryptionError',\n /**\n * Emits whenever the current buffer status of a data channel changes\n * args: (isLow: boolean, kind: [[DataPacket_Kind]])\n */\n DCBufferStatusChanged = 'dcBufferStatusChanged',\n\n /**\n * Triggered by a call to room.switchActiveDevice\n * args: (kind: MediaDeviceKind, deviceId: string)\n */\n ActiveDeviceChanged = 'activeDeviceChanged',\n\n ChatMessage = 'chatMessage',\n /**\n * fired when the first remote participant has subscribed to the localParticipant's track\n */\n LocalTrackSubscribed = 'localTrackSubscribed',\n}\n\nexport enum ParticipantEvent {\n /**\n * When a new track is published to room *after* the local\n * participant has joined. It will not fire for tracks that are already published.\n *\n * A track published doesn't mean the participant has subscribed to it. It's\n * simply reflecting the state of the room.\n *\n * args: ([[RemoteTrackPublication]])\n */\n TrackPublished = 'trackPublished',\n\n /**\n * Successfully subscribed to the [[RemoteParticipant]]'s track.\n * This event will **always** fire as long as new tracks are ready for use.\n *\n * args: ([[RemoteTrack]], [[RemoteTrackPublication]])\n */\n TrackSubscribed = 'trackSubscribed',\n\n /**\n * Could not subscribe to a track\n *\n * args: (track sid)\n */\n TrackSubscriptionFailed = 'trackSubscriptionFailed',\n\n /**\n * A [[RemoteParticipant]] has unpublished a track\n *\n * args: ([[RemoteTrackPublication]])\n */\n TrackUnpublished = 'trackUnpublished',\n\n /**\n * A subscribed track is no longer available. Clients should listen to this\n * event and ensure they detach tracks.\n *\n * args: ([[RemoteTrack]], [[RemoteTrackPublication]])\n */\n TrackUnsubscribed = 'trackUnsubscribed',\n\n /**\n * A track that was muted, fires on both [[RemoteParticipant]]s and [[LocalParticipant]]\n *\n * args: ([[TrackPublication]])\n */\n TrackMuted = 'trackMuted',\n\n /**\n * A track that was unmuted, fires on both [[RemoteParticipant]]s and [[LocalParticipant]]\n *\n * args: ([[TrackPublication]])\n */\n TrackUnmuted = 'trackUnmuted',\n\n /**\n * A local track was published successfully. This event is helpful to know\n * when to update your local UI with the newly published track.\n *\n * args: ([[LocalTrackPublication]])\n */\n LocalTrackPublished = 'localTrackPublished',\n\n /**\n * A local track was unpublished. This event is helpful to know when to remove\n * the local track from your UI.\n *\n * When a user stops sharing their screen by pressing \"End\" on the browser UI,\n * this event will also fire.\n *\n * args: ([[LocalTrackPublication]])\n */\n LocalTrackUnpublished = 'localTrackUnpublished',\n\n /**\n * Participant metadata is a simple way for app-specific state to be pushed to\n * all users.\n * When RoomService.UpdateParticipantMetadata is called to change a participant's\n * state, *all* participants in the room will fire this event.\n * To access the current metadata, see [[Participant.metadata]].\n *\n * args: (prevMetadata: string)\n *\n */\n ParticipantMetadataChanged = 'participantMetadataChanged',\n\n /**\n * Participant's display name changed\n *\n * args: (name: string, [[Participant]])\n *\n */\n ParticipantNameChanged = 'participantNameChanged',\n\n /**\n * Data received from this participant as sender.\n * Data packets provides the ability to use LiveKit to send/receive arbitrary payloads.\n * All participants in the room will receive the messages sent to the room.\n *\n * args: (payload: Uint8Array, kind: [[DataPacket_Kind]])\n */\n DataReceived = 'dataReceived',\n\n /**\n * SIP DTMF tones received from this participant as sender.\n *\n * args: (dtmf: [[DataPacket_Kind]])\n */\n SipDTMFReceived = 'sipDTMFReceived',\n\n /**\n * Transcription received from this participant as data source.\n * @beta\n */\n TranscriptionReceived = 'transcriptionReceived',\n\n /**\n * Has speaking status changed for the current participant\n *\n * args: (speaking: boolean)\n */\n IsSpeakingChanged = 'isSpeakingChanged',\n\n /**\n * Connection quality was changed for a Participant. It'll receive updates\n * from the local participant, as well as any [[RemoteParticipant]]s that we are\n * subscribed to.\n *\n * args: (connectionQuality: [[ConnectionQuality]])\n */\n ConnectionQualityChanged = 'connectionQualityChanged',\n\n /**\n * StreamState indicates if a subscribed track has been paused by the SFU\n * (typically this happens because of subscriber's bandwidth constraints)\n *\n * When bandwidth conditions allow, the track will be resumed automatically.\n * TrackStreamStateChanged will also be emitted when that happens.\n *\n * args: (pub: [[RemoteTrackPublication]], streamState: [[Track.StreamState]])\n */\n TrackStreamStateChanged = 'trackStreamStateChanged',\n\n /**\n * One of subscribed tracks have changed its permissions for the current\n * participant. If permission was revoked, then the track will no longer\n * be subscribed. If permission was granted, a TrackSubscribed event will\n * be emitted.\n *\n * args: (pub: [[RemoteTrackPublication]],\n * status: [[TrackPublication.SubscriptionStatus]])\n */\n TrackSubscriptionPermissionChanged = 'trackSubscriptionPermissionChanged',\n\n /**\n * One of the remote participants publications has changed its subscription status.\n *\n */\n TrackSubscriptionStatusChanged = 'trackSubscriptionStatusChanged',\n\n // fired only on LocalParticipant\n /** @internal */\n MediaDevicesError = 'mediaDevicesError',\n\n // fired only on LocalParticipant\n /** @internal */\n AudioStreamAcquired = 'audioStreamAcquired',\n\n /**\n * A participant's permission has changed. Currently only fired on LocalParticipant.\n * args: (prevPermissions: [[ParticipantPermission]])\n */\n ParticipantPermissionsChanged = 'participantPermissionsChanged',\n\n /** @internal */\n PCTrackAdded = 'pcTrackAdded',\n\n /**\n * Participant attributes is an app-specific key value state to be pushed to\n * all users.\n * When a participant's attributes changed, this event will be emitted with the changed attributes\n * args: (changedAttributes: [[Record<string, string]])\n */\n AttributesChanged = 'attributesChanged',\n\n /**\n * fired on local participant only, when the first remote participant has subscribed to the track specified in the payload\n */\n LocalTrackSubscribed = 'localTrackSubscribed',\n\n /** only emitted on local participant */\n ChatMessage = 'chatMessage',\n}\n\n/** @internal */\nexport enum EngineEvent {\n TransportsCreated = 'transportsCreated',\n Connected = 'connected',\n Disconnected = 'disconnected',\n Resuming = 'resuming',\n Resumed = 'resumed',\n Restarting = 'restarting',\n Restarted = 'restarted',\n SignalResumed = 'signalResumed',\n SignalRestarted = 'signalRestarted',\n Closing = 'closing',\n MediaTrackAdded = 'mediaTrackAdded',\n ActiveSpeakersUpdate = 'activeSpeakersUpdate',\n DataPacketReceived = 'dataPacketReceived',\n RTPVideoMapUpdate = 'rtpVideoMapUpdate',\n DCBufferStatusChanged = 'dcBufferStatusChanged',\n ParticipantUpdate = 'participantUpdate',\n RoomUpdate = 'roomUpdate',\n SpeakersChanged = 'speakersChanged',\n StreamStateChanged = 'streamStateChanged',\n ConnectionQualityUpdate = 'connectionQualityUpdate',\n SubscriptionError = 'subscriptionError',\n SubscriptionPermissionUpdate = 'subscriptionPermissionUpdate',\n RemoteMute = 'remoteMute',\n SubscribedQualityUpdate = 'subscribedQualityUpdate',\n LocalTrackUnpublished = 'localTrackUnpublished',\n LocalTrackSubscribed = 'localTrackSubscribed',\n Offline = 'offline',\n SignalRequestResponse = 'signalRequestResponse',\n}\n\nexport enum TrackEvent {\n Message = 'message',\n Muted = 'muted',\n Unmuted = 'unmuted',\n /**\n * Only fires on LocalTracks\n */\n Restarted = 'restarted',\n Ended = 'ended',\n Subscribed = 'subscribed',\n Unsubscribed = 'unsubscribed',\n /** @internal */\n UpdateSettings = 'updateSettings',\n /** @internal */\n UpdateSubscription = 'updateSubscription',\n /** @internal */\n AudioPlaybackStarted = 'audioPlaybackStarted',\n /** @internal */\n AudioPlaybackFailed = 'audioPlaybackFailed',\n /**\n * @internal\n * Only fires on LocalAudioTrack instances\n */\n AudioSilenceDetected = 'audioSilenceDetected',\n /** @internal */\n VisibilityChanged = 'visibilityChanged',\n /** @internal */\n VideoDimensionsChanged = 'videoDimensionsChanged',\n /** @internal */\n VideoPlaybackStarted = 'videoPlaybackStarted',\n /** @internal */\n VideoPlaybackFailed = 'videoPlaybackFailed',\n /** @internal */\n ElementAttached = 'elementAttached',\n /** @internal */\n ElementDetached = 'elementDetached',\n /**\n * @internal\n * Only fires on LocalTracks\n */\n UpstreamPaused = 'upstreamPaused',\n /**\n * @internal\n * Only fires on LocalTracks\n */\n UpstreamResumed = 'upstreamResumed',\n /**\n * @internal\n * Fires on RemoteTrackPublication\n */\n SubscriptionPermissionChanged = 'subscriptionPermissionChanged',\n /**\n * Fires on RemoteTrackPublication\n */\n SubscriptionStatusChanged = 'subscriptionStatusChanged',\n /**\n * Fires on RemoteTrackPublication\n */\n SubscriptionFailed = 'subscriptionFailed',\n /**\n * @internal\n */\n TrackProcessorUpdate = 'trackProcessorUpdate',\n\n /**\n * @internal\n */\n AudioTrackFeatureUpdate = 'audioTrackFeatureUpdate',\n\n /**\n * @beta\n */\n TranscriptionReceived = 'transcriptionReceived',\n\n /**\n * @experimental\n */\n TimeSyncUpdate = 'timeSyncUpdate',\n}\n","import {\n AudioTrackFeature,\n VideoQuality as ProtoQuality,\n StreamState as ProtoStreamState,\n TrackSource,\n TrackType,\n} from '@livekit/protocol';\nimport { EventEmitter } from 'events';\nimport type TypedEventEmitter from 'typed-emitter';\nimport type { SignalClient } from '../../api/SignalClient';\nimport log, { LoggerNames, StructuredLogger, getLogger } from '../../logger';\nimport { TrackEvent } from '../events';\nimport type { LoggerOptions } from '../types';\nimport { isFireFox, isSafari, isWeb } from '../utils';\nimport type { TrackProcessor } from './processor/types';\nimport { getLogContextFromTrack } from './utils';\n\nconst BACKGROUND_REACTION_DELAY = 5000;\n\n// keep old audio elements when detached, we would re-use them since on iOS\n// Safari tracks which audio elements have been \"blessed\" by the user.\nconst recycledElements: Array<HTMLAudioElement> = [];\n\nexport enum VideoQuality {\n LOW = ProtoQuality.LOW,\n MEDIUM = ProtoQuality.MEDIUM,\n HIGH = ProtoQuality.HIGH,\n}\nexport abstract class Track<\n TrackKind extends Track.Kind = Track.Kind,\n> extends (EventEmitter as new () => TypedEventEmitter<TrackEventCallbacks>) {\n readonly kind: TrackKind;\n\n attachedElements: HTMLMediaElement[] = [];\n\n isMuted: boolean = false;\n\n source: Track.Source;\n\n /**\n * sid is set after track is published to server, or if it's a remote track\n */\n sid?: Track.SID;\n\n /**\n * @internal\n */\n mediaStream?: MediaStream;\n\n /**\n * indicates current state of stream, it'll indicate `paused` if the track\n * has been paused by congestion controller\n */\n streamState: Track.StreamState = Track.StreamState.Active;\n\n /** @internal */\n rtpTimestamp: number | undefined;\n\n protected _mediaStreamTrack: MediaStreamTrack;\n\n protected _mediaStreamID: string;\n\n protected isInBackground: boolean = false;\n\n private backgroundTimeout: ReturnType<typeof setTimeout> | undefined;\n\n private loggerContextCb: LoggerOptions['loggerContextCb'];\n\n protected timeSyncHandle: number | undefined;\n\n protected _currentBitrate: number = 0;\n\n protected monitorInterval?: ReturnType<typeof setInterval>;\n\n protected log: StructuredLogger = log;\n\n protected constructor(\n mediaTrack: MediaStreamTrack,\n kind: TrackKind,\n loggerOptions: LoggerOptions = {},\n ) {\n super();\n this.log = getLogger(loggerOptions.loggerName ?? LoggerNames.Track);\n this.loggerContextCb = loggerOptions.loggerContextCb;\n\n this.setMaxListeners(100);\n this.kind = kind;\n this._mediaStreamTrack = mediaTrack;\n this._mediaStreamID = mediaTrack.id;\n this.source = Track.Source.Unknown;\n }\n\n protected get logContext() {\n return {\n ...this.loggerContextCb?.(),\n ...getLogContextFromTrack(this),\n };\n }\n\n /** current receive bits per second */\n get currentBitrate(): number {\n return this._currentBitrate;\n }\n\n get mediaStreamTrack() {\n return this._mediaStreamTrack;\n }\n\n /**\n * @internal\n * used for keep mediaStream's first id, since it's id might change\n * if we disable/enable a track\n */\n get mediaStreamID(): string {\n return this._mediaStreamID;\n }\n\n /**\n * creates a new HTMLAudioElement or HTMLVideoElement, attaches to it, and returns it\n */\n attach(): HTMLMediaElement;\n\n /**\n * attaches track to an existing HTMLAudioElement or HTMLVideoElement\n */\n attach(element: HTMLMediaElement): HTMLMediaElement;\n attach(element?: HTMLMediaElement): HTMLMediaElement {\n let elementType = 'audio';\n if (this.kind === Track.Kind.Video) {\n elementType = 'video';\n }\n if (this.attachedElements.length === 0 && this.kind === Track.Kind.Video) {\n this.addAppVisibilityListener();\n }\n if (!element) {\n if (elementType === 'audio') {\n recycledElements.forEach((e) => {\n if (e.parentElement === null && !element) {\n element = e;\n }\n });\n if (element) {\n // remove it from pool\n recycledElements.splice(recycledElements.indexOf(element), 1);\n }\n }\n if (!element) {\n element = <HTMLMediaElement>document.createElement(elementType);\n }\n }\n\n if (!this.attachedElements.includes(element)) {\n this.attachedElements.push(element);\n }\n\n // even if we believe it's already attached to the element, it's possible\n // the element's srcObject was set to something else out of band.\n // we'll want to re-attach it in that case\n attachToElement(this.mediaStreamTrack, element);\n\n // handle auto playback failures\n const allMediaStreamTracks = (element.srcObject as MediaStream).getTracks();\n const hasAudio = allMediaStreamTracks.some((tr) => tr.kind === 'audio');\n\n // manually play media to detect auto playback status\n element\n .play()\n .then(() => {\n this.emit(hasAudio ? TrackEvent.AudioPlaybackStarted : TrackEvent.VideoPlaybackStarted);\n })\n .catch((e) => {\n if (e.name === 'NotAllowedError') {\n this.emit(hasAudio ? TrackEvent.AudioPlaybackFailed : TrackEvent.VideoPlaybackFailed, e);\n } else if (e.name === 'AbortError') {\n // commonly triggered by another `play` request, only log for debugging purposes\n log.debug(\n `${hasAudio ? 'audio' : 'video'} playback aborted, likely due to new play request`,\n );\n } else {\n log.warn(`could not playback ${hasAudio ? 'audio' : 'video'}`, e);\n }\n // If audio playback isn't allowed make sure we still play back the video\n if (\n hasAudio &&\n element &&\n allMediaStreamTracks.some((tr) => tr.kind === 'video') &&\n e.name === 'NotAllowedError'\n ) {\n element.muted = true;\n element.play().catch(() => {\n // catch for Safari, exceeded options at this point to automatically play the media element\n });\n }\n });\n\n this.emit(TrackEvent.ElementAttached, element);\n return element;\n }\n\n /**\n * Detaches from all attached elements\n */\n detach(): HTMLMediaElement[];\n\n /**\n * Detach from a single element\n * @param element\n */\n detach(element: HTMLMediaElement): HTMLMediaElement;\n detach(element?: HTMLMediaElement): HTMLMediaElement | HTMLMediaElement[] {\n try {\n // detach from a single element\n if (element) {\n detachTrack(this.mediaStreamTrack, element);\n const idx = this.attachedElements.indexOf(element);\n if (idx >= 0) {\n this.attachedElements.splice(idx, 1);\n this.recycleElement(element);\n this.emit(TrackEvent.ElementDetached, element);\n }\n return element;\n }\n\n const detached: HTMLMediaElement[] = [];\n this.attachedElements.forEach((elm) => {\n detachTrack(this.mediaStreamTrack, elm);\n detached.push(elm);\n this.recycleElement(elm);\n this.emit(TrackEvent.ElementDetached, elm);\n });\n\n // remove all tracks\n this.attachedElements = [];\n return detached;\n } finally {\n if (this.attachedElements.length === 0) {\n this.removeAppVisibilityListener();\n }\n }\n }\n\n stop() {\n this.stopMonitor();\n this._mediaStreamTrack.stop();\n }\n\n protected enable() {\n this._mediaStreamTrack.enabled = true;\n }\n\n protected disable() {\n this._mediaStreamTrack.enabled = false;\n }\n\n /* @internal */\n abstract startMonitor(signalClient?: SignalClient): void;\n\n /* @internal */\n stopMonitor() {\n if (this.monitorInterval) {\n clearInterval(this.monitorInterval);\n }\n if (this.timeSyncHandle) {\n cancelAnimationFrame(this.timeSyncHandle);\n }\n }\n\n /** @internal */\n updateLoggerOptions(loggerOptions: LoggerOptions) {\n if (loggerOptions.loggerName) {\n this.log = getLogger(loggerOptions.loggerName);\n }\n if (loggerOptions.loggerContextCb) {\n this.loggerContextCb = loggerOptions.loggerContextCb;\n }\n }\n\n private recycleElement(element: HTMLMediaElement) {\n if (element instanceof HTMLAudioElement) {\n // we only need to re-use a single element\n let shouldCache = true;\n element.pause();\n recycledElements.forEach((e) => {\n if (!e.parentElement) {\n shouldCache = false;\n }\n });\n if (shouldCache) {\n recycledElements.push(element);\n }\n }\n }\n\n protected appVisibilityChangedListener = () => {\n if (this.backgroundTimeout) {\n clearTimeout(this.backgroundTimeout);\n }\n // delay app visibility update if it goes to hidden\n // update immediately if it comes back to focus\n if (document.visibilityState === 'hidden') {\n this.backgroundTimeout = setTimeout(\n () => this.handleAppVisibilityChanged(),\n BACKGROUND_REACTION_DELAY,\n );\n } else {\n this.handleAppVisibilityChanged();\n }\n };\n\n protected async handleAppVisibilityChanged() {\n this.isInBackground = document.visibilityState === 'hidden';\n if (!this.isInBackground && this.kind === Track.Kind.Video) {\n setTimeout(\n () =>\n this.attachedElements.forEach((el) =>\n el.play().catch(() => {\n /** catch clause necessary for Safari */\n }),\n ),\n 0,\n );\n }\n }\n\n protected addAppVisibilityListener() {\n if (isWeb()) {\n this.isInBackground = document.visibilityState === 'hidden';\n document.addEventListener('visibilitychange', this.appVisibilityChangedListener);\n } else {\n this.isInBackground = false;\n }\n }\n\n protected removeAppVisibilityListener() {\n if (isWeb()) {\n document.removeEventListener('visibilitychange', this.appVisibilityChangedListener);\n }\n }\n}\n\nexport function attachToElement(track: MediaStreamTrack, element: HTMLMediaElement) {\n let mediaStream: MediaStream;\n if (element.srcObject instanceof MediaStream) {\n mediaStream = element.srcObject;\n } else {\n mediaStream = new MediaStream();\n }\n\n // check if track matches existing track\n let existingTracks: MediaStreamTrack[];\n if (track.kind === 'audio') {\n existingTracks = mediaStream.getAudioTracks();\n } else {\n existingTracks = mediaStream.getVideoTracks();\n }\n if (!existingTracks.includes(track)) {\n existingTracks.forEach((et) => {\n mediaStream.removeTrack(et);\n });\n mediaStream.addTrack(track);\n }\n\n if (!isSafari() || !(element instanceof HTMLVideoElement)) {\n // when in low power mode (applies to both macOS and iOS), Safari will show a play/pause overlay\n // when a video starts that has the `autoplay` attribute is set.\n // we work around this by _not_ setting the autoplay attribute on safari and instead call `setTimeout(() => el.play(),0)` further down\n element.autoplay = true;\n }\n // In case there are no audio tracks present on the mediastream, we set the element as muted to ensure autoplay works\n element.muted = mediaStream.getAudioTracks().length === 0;\n if (element instanceof HTMLVideoElement) {\n element.playsInline = true;\n }\n\n // avoid flicker\n if (element.srcObject !== mediaStream) {\n element.srcObject = mediaStream;\n if ((isSafari() || isFireFox()) && element instanceof HTMLVideoElement) {\n // Firefox also has a timing issue where video doesn't actually get attached unless\n // performed out-of-band\n // Safari 15 has a bug where in certain layouts, video element renders\n // black until the page is resized or other changes take place.\n // Resetting the src triggers it to render.\n // https://developer.apple.com/forums/thread/690523\n setTimeout(() => {\n element.srcObject = mediaStream;\n // Safari 15 sometimes fails to start a video\n // when the window is backgrounded before the first frame is drawn\n // manually calling play here seems to fix that\n element.play().catch(() => {\n /** do nothing */\n });\n }, 0);\n }\n }\n}\n\n/** @internal */\nexport function detachTrack(track: MediaStreamTrack, element: HTMLMediaElement) {\n if (element.srcObject instanceof MediaStream) {\n const mediaStream = element.srcObject;\n mediaStream.removeTrack(track);\n if (mediaStream.getTracks().length > 0) {\n element.srcObject = mediaStream;\n } else {\n element.srcObject = null;\n }\n }\n}\n\nexport namespace Track {\n export enum Kind {\n Audio = 'audio',\n Video = 'video',\n Unknown = 'unknown',\n }\n export type SID = string;\n export enum Source {\n Camera = 'camera',\n Microphone = 'microphone',\n ScreenShare = 'screen_share',\n ScreenShareAudio = 'screen_share_audio',\n Unknown = 'unknown',\n }\n\n export enum StreamState {\n Active = 'active',\n Paused = 'paused',\n Unknown = 'unknown',\n }\n\n export interface Dimensions {\n width: number;\n height: number;\n }\n\n /** @internal */\n export function kindToProto(k: Kind): TrackType {\n switch (k) {\n case Kind.Audio:\n return TrackType.AUDIO;\n case Kind.Video:\n return TrackType.VIDEO;\n default:\n // FIXME this was UNRECOGNIZED before\n return TrackType.DATA;\n }\n }\n\n /** @internal */\n export function kindFromProto(t: TrackType): Kind | undefined {\n switch (t) {\n case TrackType.AUDIO:\n return Kind.Audio;\n case TrackType.VIDEO:\n return Kind.Video;\n default:\n return Kind.Unknown;\n }\n }\n\n /** @internal */\n export function sourceToProto(s: Source): TrackSource {\n switch (s) {\n case Source.Camera:\n return TrackSource.CAMERA;\n case Source.Microphone:\n return TrackSource.MICROPHONE;\n case Source.ScreenShare:\n return TrackSource.SCREEN_SHARE;\n case Source.ScreenShareAudio:\n return TrackSource.SCREEN_SHARE_AUDIO;\n default:\n return TrackSource.UNKNOWN;\n }\n }\n\n /** @internal */\n export function sourceFromProto(s: TrackSource): Source {\n switch (s) {\n case TrackSource.CAMERA:\n return Source.Camera;\n case TrackSource.MICROPHONE:\n return Source.Microphone;\n case TrackSource.SCREEN_SHARE:\n return Source.ScreenShare;\n case TrackSource.SCREEN_SHARE_AUDIO:\n return Source.ScreenShareAudio;\n default:\n return Source.Unknown;\n }\n }\n\n /** @internal */\n export function streamStateFromProto(s: ProtoStreamState): StreamState {\n switch (s) {\n case ProtoStreamState.ACTIVE:\n return StreamState.Active;\n case ProtoStreamState.PAUSED:\n return StreamState.Paused;\n default:\n return StreamState.Unknown;\n }\n }\n}\n\nexport type TrackEventCallbacks = {\n message: () => void;\n muted: (track?: any) => void;\n unmuted: (track?: any) => void;\n restarted: (track?: any) => void;\n ended: (track?: any) => void;\n updateSettings: () => void;\n updateSubscription: () => void;\n audioPlaybackStarted: () => void;\n audioPlaybackFailed: (error?: Error) => void;\n audioSilenceDetected: () => void;\n visibilityChanged: (visible: boolean, track?: any) => void;\n videoDimensionsChanged: (dimensions: Track.Dimensions, track?: any) => void;\n videoPlaybackStarted: () => void;\n videoPlaybackFailed: (error?: Error) => void;\n elementAttached: (element: HTMLMediaElement) => void;\n elementDetached: (element: HTMLMediaElement) => void;\n upstreamPaused: (track: any) => void;\n upstreamResumed: (track: any) => void;\n trackProcessorUpdate: (processor?: TrackProcessor<Track.Kind, any>) => void;\n audioTrackFeatureUpdate: (track: any, feature: AudioTrackFeature, enabled: boolean) => void;\n timeSyncUpdate: (update: { timestamp: number; rtpTimestamp: number }) => void;\n};\n","import { Mutex } from '../room/utils';\n\ntype QueueTask<T> = () => PromiseLike<T>;\n\nenum QueueTaskStatus {\n 'WAITING',\n 'RUNNING',\n 'COMPLETED',\n}\n\ntype QueueTaskInfo = {\n id: number;\n enqueuedAt: number;\n executedAt?: number;\n status: QueueTaskStatus;\n};\n\nexport class AsyncQueue {\n private pendingTasks: Map<number, QueueTaskInfo>;\n\n private taskMutex: Mutex;\n\n private nextTaskIndex: number;\n\n constructor() {\n this.pendingTasks = new Map();\n this.taskMutex = new Mutex();\n this.nextTaskIndex = 0;\n }\n\n async run<T>(task: QueueTask<T>) {\n const taskInfo: QueueTaskInfo = {\n id: this.nextTaskIndex++,\n enqueuedAt: Date.now(),\n status: QueueTaskStatus.WAITING,\n };\n this.pendingTasks.set(taskInfo.id, taskInfo);\n const unlock = await this.taskMutex.lock();\n try {\n taskInfo.executedAt = Date.now();\n taskInfo.status = QueueTaskStatus.RUNNING;\n return await task();\n } finally {\n taskInfo.status = QueueTaskStatus.COMPLETED;\n this.pendingTasks.delete(taskInfo.id);\n unlock();\n }\n }\n\n async flush() {\n return this.run(async () => {});\n }\n\n snapshot() {\n return Array.from(this.pendingTasks.values());\n }\n}\n","import {\n ChatMessage as ChatMessageModel,\n ClientInfo,\n ClientInfo_SDK,\n Transcription as TranscriptionModel,\n} from '@livekit/protocol';\nimport { getBrowser } from '../utils/browserParser';\nimport { protocolVersion, version } from '../version';\nimport CriticalTimers from './timers';\nimport type LocalAudioTrack from './track/LocalAudioTrack';\nimport type RemoteAudioTrack from './track/RemoteAudioTrack';\nimport { VideoCodec, videoCodecs } from './track/options';\nimport { getNewAudioContext } from './track/utils';\nimport type { ChatMessage, LiveKitReactNativeInfo, TranscriptionSegment } from './types';\n\nconst separator = '|';\nexport const ddExtensionURI =\n 'https://aomediacodec.github.io/av1-rtp-spec/#dependency-descriptor-rtp-header-extension';\n\nexport function unpackStreamId(packed: string): string[] {\n const parts = packed.split(separator);\n if (parts.length > 1) {\n return [parts[0], packed.substr(parts[0].length + 1)];\n }\n return [packed, ''];\n}\n\nexport async function sleep(duration: number): Promise<void> {\n return new Promise((resolve) => CriticalTimers.setTimeout(resolve, duration));\n}\n\n/** @internal */\nexport function supportsTransceiver() {\n return 'addTransceiver' in RTCPeerConnection.prototype;\n}\n\n/** @internal */\nexport function supportsAddTrack() {\n return 'addTrack' in RTCPeerConnection.prototype;\n}\n\nexport function supportsAdaptiveStream() {\n return typeof ResizeObserver !== undefined && typeof IntersectionObserver !== undefined;\n}\n\nexport function supportsDynacast() {\n return supportsTransceiver();\n}\n\nexport function supportsAV1(): boolean {\n if (!('getCapabilities' in RTCRtpSender)) {\n return false;\n }\n if (isSafari()) {\n // Safari 17 on iPhone14 reports AV1 capability, but does not actually support it\n return false;\n }\n const capabilities = RTCRtpSender.getCapabilities('video');\n let hasAV1 = false;\n if (capabilities) {\n for (const codec of capabilities.codecs) {\n if (codec.mimeType === 'video/AV1') {\n hasAV1 = true;\n break;\n }\n }\n }\n return hasAV1;\n}\n\nexport function supportsVP9(): boolean {\n if (!('getCapabilities' in RTCRtpSender)) {\n return false;\n }\n if (isFireFox()) {\n // technically speaking FireFox supports VP9, but SVC publishing is broken\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1633876\n return false;\n }\n if (isSafari()) {\n const browser = getBrowser();\n if (browser?.version && compareVersions(browser.version, '16') < 0) {\n // Safari 16 and below does not support VP9\n return false;\n }\n }\n const capabilities = RTCRtpSender.getCapabilities('video');\n let hasVP9 = false;\n if (capabilities) {\n for (const codec of capabilities.codecs) {\n if (codec.mimeType === 'video/VP9') {\n hasVP9 = true;\n break;\n }\n }\n }\n return hasVP9;\n}\n\nexport function isSVCCodec(codec?: string): boolean {\n return codec === 'av1' || codec === 'vp9';\n}\n\nexport function supportsSetSinkId(elm?: HTMLMediaElement): boolean {\n if (!document) {\n return false;\n }\n if (!elm) {\n elm = document.createElement('audio');\n }\n return 'setSinkId' in elm;\n}\n\nexport function isBrowserSupported() {\n if (typeof RTCPeerConnection === 'undefined') {\n return false;\n }\n return supportsTransceiver() || supportsAddTrack();\n}\n\nexport function isFireFox(): boolean {\n return getBrowser()?.name === 'Firefox';\n}\n\nexport function isChromiumBased(): boolean {\n return getBrowser()?.name === 'Chrome';\n}\n\nexport function isSafari(): boolean {\n return getBrowser()?.name === 'Safari';\n}\n\nexport function isSafari17(): boolean {\n const b = getBrowser();\n return b?.name === 'Safari' && b.version.startsWith('17.');\n}\n\nexport function isMobile(): boolean {\n if (!isWeb()) return false;\n\n return (\n // @ts-expect-error `userAgentData` is not yet part of typescript\n navigator.userAgentData?.mobile ??\n /Tablet|iPad|Mobile|Android|BlackBerry/.test(navigator.userAgent)\n );\n}\n\nexport function isE2EESimulcastSupported() {\n const browser = getBrowser();\n const supportedSafariVersion = '17.2'; // see https://bugs.webkit.org/show_bug.cgi?id=257803\n if (browser) {\n if (browser.name !== 'Safari' && browser.os !== 'iOS') {\n return true;\n } else if (\n browser.os === 'iOS' &&\n browser.osVersion &&\n compareVersions(supportedSafariVersion, browser.osVersion) >= 0\n ) {\n return true;\n } else if (\n browser.name === 'Safari' &&\n compareVersions(supportedSafariVersion, browser.version) >= 0\n ) {\n return true;\n } else {\n return false;\n }\n }\n}\n\nexport function isWeb(): boolean {\n return typeof document !== 'undefined';\n}\n\nexport function isReactNative(): boolean {\n // navigator.product is deprecated on browsers, but will be set appropriately for react-native.\n return navigator.product == 'ReactNative';\n}\n\nexport function isCloud(serverUrl: URL) {\n return (\n serverUrl.hostname.endsWith('.livekit.cloud') || serverUrl.hostname.endsWith('.livekit.run')\n );\n}\n\nfunction getLKReactNativeInfo(): LiveKitReactNativeInfo | undefined {\n // global defined only for ReactNative.\n // @ts-ignore\n if (global && global.LiveKitReactNativeGlobal) {\n // @ts-ignore\n return global.LiveKitReactNativeGlobal as LiveKitReactNativeInfo;\n }\n\n return undefined;\n}\n\nexport function getReactNativeOs(): string | undefined {\n if (!isReactNative()) {\n return undefined;\n }\n\n let info = getLKReactNativeInfo();\n if (info) {\n return info.platform;\n }\n\n return undefined;\n}\n\nexport function getDevicePixelRatio(): number {\n if (isWeb()) {\n return window.devicePixelRatio;\n }\n\n if (isReactNative()) {\n let info = getLKReactNativeInfo();\n if (info) {\n return info.devicePixelRatio;\n }\n }\n\n return 1;\n}\n\nexport function compareVersions(v1: string, v2: string): number {\n const parts1 = v1.split('.');\n const parts2 = v2.split('.');\n const k = Math.min(parts1.length, parts2.length);\n for (let i = 0; i < k; ++i) {\n const p1 = parseInt(parts1[i], 10);\n const p2 = parseInt(parts2[i], 10);\n if (p1 > p2) return 1;\n if (p1 < p2) return -1;\n if (i === k - 1 && p1 === p2) return 0;\n }\n if (v1 === '' && v2 !== '') {\n return -1;\n } else if (v2 === '') {\n return 1;\n }\n return parts1.length == parts2.length ? 0 : parts1.length < parts2.length ? -1 : 1;\n}\n\nfunction roDispatchCallback(entries: ResizeObserverEntry[]) {\n for (const entry of entries) {\n (entry.target as ObservableMediaElement).handleResize(entry);\n }\n}\n\nfunction ioDispatchCallback(entries: IntersectionObserverEntry[]) {\n for (const entry of entries) {\n (entry.target as ObservableMediaElement).handleVisibilityChanged(entry);\n }\n}\n\nlet resizeObserver: ResizeObserver | null = null;\nexport const getResizeObserver = () => {\n if (!resizeObserver) resizeObserver = new ResizeObserver(roDispatchCallback);\n return resizeObserver;\n};\n\nlet intersectionObserver: IntersectionObserver | null = null;\nexport const getIntersectionObserver = () => {\n if (!intersectionObserver) {\n intersectionObserver = new IntersectionObserver(ioDispatchCallback, {\n root: null,\n rootMargin: '0px',\n });\n }\n return intersectionObserver;\n};\n\nexport interface ObservableMediaElement extends HTMLMediaElement {\n handleResize: (entry: ResizeObserverEntry) => void;\n handleVisibilityChanged: (entry: IntersectionObserverEntry) => void;\n}\n\nexport function getClientInfo(): ClientInfo {\n const info = new ClientInfo({\n sdk: ClientInfo_SDK.JS,\n protocol: protocolVersion,\n version,\n });\n\n if (isReactNative()) {\n info.os = getReactNativeOs() ?? '';\n }\n return info;\n}\n\nlet emptyVideoStreamTrack: MediaStreamTrack | undefined;\n\nexport function getEmptyVideoStreamTrack() {\n if (!emptyVideoStreamTrack) {\n emptyVideoStreamTrack = createDummyVideoStreamTrack();\n }\n return emptyVideoStreamTrack.clone();\n}\n\nexport function createDummyVideoStreamTrack(\n width: number = 16,\n height: number = 16,\n enabled: boolean = false,\n paintContent: boolean = false,\n) {\n const canvas = document.createElement('canvas');\n // the canvas size is set to 16 by default, because electron apps seem to fail with smaller values\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d');\n ctx?.fillRect(0, 0, canvas.width, canvas.height);\n if (paintContent && ctx) {\n ctx.beginPath();\n ctx.arc(width / 2, height / 2, 50, 0, Math.PI * 2, true);\n ctx.closePath();\n ctx.fillStyle = 'grey';\n ctx.fill();\n }\n // @ts-ignore\n const dummyStream = canvas.captureStream();\n const [dummyTrack] = dummyStream.getTracks();\n if (!dummyTrack) {\n throw Error('Could not get empty media stream video track');\n }\n dummyTrack.enabled = enabled;\n\n return dummyTrack;\n}\n\nlet emptyAudioStreamTrack: MediaStreamTrack | undefined;\n\nexport function getEmptyAudioStreamTrack() {\n if (!emptyAudioStreamTrack) {\n // implementation adapted from https://blog.mozilla.org/webrtc/warm-up-with-replacetrack/\n const ctx = new AudioContext();\n const oscillator = ctx.createOscillator();\n const gain = ctx.createGain();\n gain.gain.setValueAtTime(0, 0);\n const dst = ctx.createMediaStreamDestination();\n oscillator.connect(gain);\n gain.connect(dst);\n oscillator.start();\n [emptyAudioStreamTrack] = dst.stream.getAudioTracks();\n if (!emptyAudioStreamTrack) {\n throw Error('Could not get empty media stream audio track');\n }\n emptyAudioStreamTrack.enabled = false;\n }\n return emptyAudioStreamTrack.clone();\n}\n\nexport class Future<T> {\n promise: Promise<T>;\n\n resolve?: (arg: T) => void;\n\n reject?: (e: any) => void;\n\n onFinally?: () => void;\n\n constructor(\n futureBase?: (resolve: (arg: T) => void, reject: (e: any) => void) => void,\n onFinally?: () => void,\n ) {\n this.onFinally = onFinally;\n this.promise = new Promise<T>(async (resolve, reject) => {\n this.resolve = resolve;\n this.reject = reject;\n if (futureBase) {\n await futureBase(resolve, reject);\n }\n }).finally(() => this.onFinally?.());\n }\n}\n\nexport type AudioAnalyserOptions = {\n /**\n * If set to true, the analyser will use a cloned version of the underlying mediastreamtrack, which won't be impacted by muting the track.\n * Useful for local tracks when implementing things like \"seems like you're muted, but trying to speak\".\n * Defaults to false\n */\n cloneTrack?: boolean;\n /**\n * see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/fftSize\n */\n fftSize?: number;\n /**\n * see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/smoothingTimeConstant\n */\n smoothingTimeConstant?: number;\n /**\n * see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/minDecibels\n */\n minDecibels?: number;\n /**\n * see https://developer.mozilla.org/en-US/docs/Web/API/AnalyserNode/maxDecibels\n */\n maxDecibels?: number;\n};\n\n/**\n * Creates and returns an analyser web audio node that is attached to the provided track.\n * Additionally returns a convenience method `calculateVolume` to perform instant volume readings on that track.\n * Call the returned `cleanup` function to close the audioContext that has been created for the instance of this helper\n */\nexport function createAudioAnalyser(\n track: LocalAudioTrack | RemoteAudioTrack,\n options?: AudioAnalyserOptions,\n) {\n const opts = {\n cloneTrack: false,\n fftSize: 2048,\n smoothingTimeConstant: 0.8,\n minDecibels: -100,\n maxDecibels: -80,\n ...options,\n };\n const audioContext = getNewAudioContext();\n\n if (!audioContext) {\n throw new Error('Audio Context not supported on this browser');\n }\n const streamTrack = opts.cloneTrack ? track.mediaStreamTrack.clone() : track.mediaStreamTrack;\n const mediaStreamSource = audioContext.createMediaStreamSource(new MediaStream([streamTrack]));\n const analyser = audioContext.createAnalyser();\n analyser.minDecibels = opts.minDecibels;\n analyser.maxDecibels = opts.maxDecibels;\n analyser.fftSize = opts.fftSize;\n analyser.smoothingTimeConstant = opts.smoothingTimeConstant;\n\n mediaStreamSource.connect(analyser);\n const dataArray = new Uint8Array(analyser.frequencyBinCount);\n\n /**\n * Calculates the current volume of the track in the range from 0 to 1\n */\n const calculateVolume = () => {\n analyser.getByteFrequencyData(dataArray);\n let sum = 0;\n for (const amplitude of dataArray) {\n sum += Math.pow(amplitude / 255, 2);\n }\n const volume = Math.sqrt(sum / dataArray.length);\n return volume;\n };\n\n const cleanup = async () => {\n await audioContext.close();\n if (opts.cloneTrack) {\n streamTrack.stop();\n }\n };\n\n return { calculateVolume, analyser, cleanup };\n}\n\n/**\n * @internal\n */\nexport class Mutex {\n private _locking: Promise<void>;\n\n private _locks: number;\n\n constructor() {\n this._locking = Promise.resolve();\n this._locks = 0;\n }\n\n isLocked() {\n return this._locks > 0;\n }\n\n lock() {\n this._locks += 1;\n\n let unlockNext: () => void;\n\n const willLock = new Promise<void>(\n (resolve) =>\n (unlockNext = () => {\n this._locks -= 1;\n resolve();\n }),\n );\n\n const willUnlock = this._locking.then(() => unlockNext);\n\n this._locking = this._locking.then(() => willLock);\n\n return willUnlock;\n }\n}\n\nexport function isVideoCodec(maybeCodec: string): maybeCodec is VideoCodec {\n return videoCodecs.includes(maybeCodec as VideoCodec);\n}\n\nexport function unwrapConstraint(constraint: ConstrainDOMString): string;\nexport function unwrapConstraint(constraint: ConstrainULong): number;\nexport function unwrapConstraint(constraint: ConstrainDOMString | ConstrainULong): string | number {\n if (typeof constraint === 'string' || typeof constraint === 'number') {\n return constraint;\n }\n\n if (Array.isArray(constraint)) {\n return constraint[0];\n }\n if (constraint.exact) {\n if (Array.isArray(constraint.exact)) {\n return constraint.exact[0];\n }\n return constraint.exact;\n }\n if (constraint.ideal) {\n if (Array.isArray(constraint.ideal)) {\n return constraint.ideal[0];\n }\n return constraint.ideal;\n }\n throw Error('could not unwrap constraint');\n}\n\nexport function toWebsocketUrl(url: string): string {\n if (url.startsWith('http')) {\n return url.replace(/^(http)/, 'ws');\n }\n return url;\n}\n\nexport function toHttpUrl(url: string): string {\n if (url.startsWith('ws')) {\n return url.replace(/^(ws)/, 'http');\n }\n return url;\n}\n\nexport function extractTranscriptionSegments(\n transcription: TranscriptionModel,\n firstReceivedTimesMap: Map<string, number>,\n): TranscriptionSegment[] {\n return transcription.segments.map(({ id, text, language, startTime, endTime, final }) => {\n const firstReceivedTime = firstReceivedTimesMap.get(id) ?? Date.now();\n const lastReceivedTime = Date.now();\n if (final) {\n firstReceivedTimesMap.delete(id);\n } else {\n firstReceivedTimesMap.set(id, firstReceivedTime);\n }\n return {\n id,\n text,\n startTime: Number.parseInt(startTime.toString()),\n endTime: Number.parseInt(endTime.toString()),\n final,\n language,\n firstReceivedTime,\n lastReceivedTime,\n };\n });\n}\n\nexport function extractChatMessage(msg: ChatMessageModel): ChatMessage {\n const { id, timestamp, message, editTimestamp } = msg;\n return {\n id,\n timestamp: Number.parseInt(timestamp.toString()),\n editTimestamp: editTimestamp ? Number.parseInt(editTimestamp.toString()) : undefined,\n message,\n };\n}\n","import { TrackPublishedResponse } from '@livekit/protocol';\nimport { cloneDeep } from '../../utils/cloneDeep';\nimport { isSafari, sleep } from '../utils';\nimport { Track } from './Track';\nimport type { TrackPublication } from './TrackPublication';\nimport {\n type AudioCaptureOptions,\n type CreateLocalTracksOptions,\n type ScreenShareCaptureOptions,\n type VideoCaptureOptions,\n VideoCodec,\n videoCodecs,\n} from './options';\nimport type { AudioTrack } from './types';\n\nexport function mergeDefaultOptions(\n options?: CreateLocalTracksOptions,\n audioDefaults?: AudioCaptureOptions,\n videoDefaults?: VideoCaptureOptions,\n): CreateLocalTracksOptions {\n const opts: CreateLocalTracksOptions = cloneDeep(options) ?? {};\n if (opts.audio === true) opts.audio = {};\n if (opts.video === true) opts.video = {};\n\n // use defaults\n if (opts.audio) {\n mergeObjectWithoutOverwriting(\n opts.audio as Record<string, unknown>,\n audioDefaults as Record<string, unknown>,\n );\n }\n if (opts.video) {\n mergeObjectWithoutOverwriting(\n opts.video as Record<string, unknown>,\n videoDefaults as Record<string, unknown>,\n );\n }\n return opts;\n}\n\nfunction mergeObjectWithoutOverwriting(\n mainObject: Record<string, unknown>,\n objectToMerge: Record<string, unknown>,\n): Record<string, unknown> {\n Object.keys(objectToMerge).forEach((key) => {\n if (mainObject[key] === undefined) mainObject[key] = objectToMerge[key];\n });\n return mainObject;\n}\n\nexport function constraintsForOptions(options: CreateLocalTracksOptions): MediaStreamConstraints {\n const constraints: MediaStreamConstraints = {};\n\n if (options.video) {\n // default video options\n if (typeof options.video === 'object') {\n const videoOptions: MediaTrackConstraints = {};\n const target = videoOptions as Record<string, unknown>;\n const source = options.video as Record<string, unknown>;\n Object.keys(source).forEach((key) => {\n switch (key) {\n case 'resolution':\n // flatten VideoResolution fields\n mergeObjectWithoutOverwriting(target, source.resolution as Record<string, unknown>);\n break;\n default:\n target[key] = source[key];\n }\n });\n constraints.video = videoOptions;\n } else {\n constraints.video = options.video;\n }\n } else {\n constraints.video = false;\n }\n\n if (options.audio) {\n if (typeof options.audio === 'object') {\n constraints.audio = options.audio;\n } else {\n constraints.audio = true;\n }\n } else {\n constraints.audio = false;\n }\n return constraints;\n}\n/**\n * This function detects silence on a given [[Track]] instance.\n * Returns true if the track seems to be entirely silent.\n */\nexport async function detectSilence(track: AudioTrack, timeOffset = 200): Promise<boolean> {\n const ctx = getNewAudioContext();\n if (ctx) {\n const analyser = ctx.createAnalyser();\n analyser.fftSize = 2048;\n\n const bufferLength = analyser.frequencyBinCount;\n const dataArray = new Uint8Array(bufferLength);\n const source = ctx.createMediaStreamSource(new MediaStream([track.mediaStreamTrack]));\n\n source.connect(analyser);\n await sleep(timeOffset);\n analyser.getByteTimeDomainData(dataArray);\n const someNoise = dataArray.some((sample) => sample !== 128 && sample !== 0);\n ctx.close();\n return !someNoise;\n }\n return false;\n}\n\n/**\n * @internal\n */\nexport function getNewAudioContext(): AudioContext | void {\n const AudioContext =\n // @ts-ignore\n typeof window !== 'undefined' && (window.AudioContext || window.webkitAudioContext);\n if (AudioContext) {\n return new AudioContext({ latencyHint: 'interactive' });\n }\n}\n\n/**\n * @internal\n */\nexport function kindToSource(kind: MediaDeviceKind) {\n if (kind === 'audioinput') {\n return Track.Source.Microphone;\n } else if (kind === 'videoinput') {\n return Track.Source.Camera;\n } else {\n return Track.Source.Unknown;\n }\n}\n\n/**\n * @internal\n */\nexport function sourceToKind(source: Track.Source): MediaDeviceKind | undefined {\n if (source === Track.Source.Microphone) {\n return 'audioinput';\n } else if (source === Track.Source.Camera) {\n return 'videoinput';\n } else {\n return undefined;\n }\n}\n\n/**\n * @internal\n */\nexport function screenCaptureToDisplayMediaStreamOptions(\n options: ScreenShareCaptureOptions,\n): DisplayMediaStreamOptions {\n let videoConstraints: MediaTrackConstraints | boolean = options.video ?? true;\n // treat 0 as uncapped\n if (options.resolution && options.resolution.width > 0 && options.resolution.height > 0) {\n videoConstraints = typeof videoConstraints === 'boolean' ? {} : videoConstraints;\n if (isSafari()) {\n videoConstraints = {\n ...videoConstraints,\n width: { max: options.resolution.width },\n height: { max: options.resolution.height },\n frameRate: options.resolution.frameRate,\n };\n } else {\n videoConstraints = {\n ...videoConstraints,\n width: { ideal: options.resolution.width },\n height: { ideal: options.resolution.height },\n frameRate: options.resolution.frameRate,\n };\n }\n }\n\n return {\n audio: options.audio ?? false,\n video: videoConstraints,\n // @ts-expect-error support for experimental display media features\n controller: options.controller,\n selfBrowserSurface: options.selfBrowserSurface,\n surfaceSwitching: options.surfaceSwitching,\n systemAudio: options.systemAudio,\n preferCurrentTab: options.preferCurrentTab,\n };\n}\n\nexport function mimeTypeToVideoCodecString(mimeType: string) {\n const codec = mimeType.split('/')[1].toLowerCase() as VideoCodec;\n if (!videoCodecs.includes(codec)) {\n throw Error(`Video codec not supported: ${codec}`);\n }\n return codec;\n}\n\nexport function getTrackPublicationInfo<T extends TrackPublication>(\n tracks: T[],\n): TrackPublishedResponse[] {\n const infos: TrackPublishedResponse[] = [];\n tracks.forEach((track: TrackPublication) => {\n if (track.track !== undefined) {\n infos.push(\n new TrackPublishedResponse({\n cid: track.track.mediaStreamID,\n track: track.trackInfo,\n }),\n );\n }\n });\n return infos;\n}\n\nexport function getLogContextFromTrack(track: Track | TrackPublication): Record<string, unknown> {\n if (track instanceof Track) {\n return {\n trackID: track.sid,\n source: track.source,\n muted: track.isMuted,\n enabled: track.mediaStreamTrack.enabled,\n kind: track.kind,\n streamID: track.mediaStreamID,\n streamTrackID: track.mediaStreamTrack.id,\n };\n } else {\n return {\n trackID: track.trackSid,\n enabled: track.isEnabled,\n muted: track.isMuted,\n trackInfo: {\n mimeType: track.mimeType,\n name: track.trackName,\n encrypted: track.isEncrypted,\n kind: track.kind,\n source: track.source,\n ...(track.track ? getLogContextFromTrack(track.track) : {}),\n },\n };\n }\n}\n\nexport function supportsSynchronizationSources(): boolean {\n return typeof RTCRtpReceiver !== 'undefined' && 'getSynchronizationSources' in RTCRtpReceiver;\n}\n\nexport function diffAttributes(\n oldValues: Record<string, string> | undefined,\n newValues: Record<string, string> | undefined,\n) {\n if (oldValues === undefined) {\n oldValues = {};\n }\n if (newValues === undefined) {\n newValues = {};\n }\n const allKeys = [...Object.keys(newValues), ...Object.keys(oldValues)];\n const diff: Record<string, string> = {};\n\n for (const key of allKeys) {\n if (oldValues[key] !== newValues[key]) {\n diff[key] = newValues[key] ?? '';\n }\n }\n\n return diff;\n}\n","import type { KeyProviderOptions } from './types';\n\nexport const ENCRYPTION_ALGORITHM = 'AES-GCM';\n\n// How many consecutive frames can fail decrypting before a particular key gets marked as invalid\nexport const DECRYPTION_FAILURE_TOLERANCE = 10;\n\n// We copy the first bytes of the VP8 payload unencrypted.\n// For keyframes this is 10 bytes, for non-keyframes (delta) 3. See\n// https://tools.ietf.org/html/rfc6386#section-9.1\n// This allows the bridge to continue detecting keyframes (only one byte needed in the JVB)\n// and is also a bit easier for the VP8 decoder (i.e. it generates funny garbage pictures\n// instead of being unable to decode).\n// This is a bit for show and we might want to reduce to 1 unconditionally in the final version.\n//\n// For audio (where frame.type is not set) we do not encrypt the opus TOC byte:\n// https://tools.ietf.org/html/rfc6716#section-3.1\nexport const UNENCRYPTED_BYTES = {\n key: 10,\n delta: 3,\n audio: 1, // frame.type is not set on audio, so this is set manually\n empty: 0,\n} as const;\n\n/* We use a 12 byte bit IV. This is signalled in plain together with the\n packet. See https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/encrypt#parameters */\nexport const IV_LENGTH = 12;\n\n// flag set to indicate that e2ee has been setup for sender/receiver;\nexport const E2EE_FLAG = 'lk_e2ee';\n\nexport const SALT = 'LKFrameEncryptionKey';\n\nexport const KEY_PROVIDER_DEFAULTS: KeyProviderOptions = {\n sharedKey: false,\n ratchetSalt: SALT,\n ratchetWindowSize: 8,\n failureTolerance: DECRYPTION_FAILURE_TOLERANCE,\n keyringSize: 16,\n} as const;\n\nexport const MAX_SIF_COUNT = 100;\nexport const MAX_SIF_DURATION = 2000;\n","import { RequestResponse_Reason } from '@livekit/protocol';\n\nexport class LivekitError extends Error {\n code: number;\n\n constructor(code: number, message?: string) {\n super(message || 'an error has occured');\n this.code = code;\n }\n}\n\nexport const enum ConnectionErrorReason {\n NotAllowed,\n ServerUnreachable,\n InternalError,\n Cancelled,\n LeaveRequest,\n}\n\nexport class ConnectionError extends LivekitError {\n status?: number;\n\n reason?: ConnectionErrorReason;\n\n constructor(message?: string, reason?: ConnectionErrorReason, status?: number) {\n super(1, message);\n this.status = status;\n this.reason = reason;\n }\n}\n\nexport class DeviceUnsupportedError extends LivekitError {\n constructor(message?: string) {\n super(21, message ?? 'device is unsupported');\n }\n}\n\nexport class TrackInvalidError extends LivekitError {\n constructor(message?: string) {\n super(20, message ?? 'track is invalid');\n }\n}\n\nexport class UnsupportedServer extends LivekitError {\n constructor(message?: string) {\n super(10, message ?? 'unsupported server');\n }\n}\n\nexport class UnexpectedConnectionState extends LivekitError {\n constructor(message?: string) {\n super(12, message ?? 'unexpected connection state');\n }\n}\n\nexport class NegotiationError extends LivekitError {\n constructor(message?: string) {\n super(13, message ?? 'unable to negotiate');\n }\n}\n\nexport class PublishDataError extends LivekitError {\n constructor(message?: string) {\n super(13, message ?? 'unable to publish data');\n }\n}\n\nexport type RequestErrorReason =\n | Exclude<RequestResponse_Reason, RequestResponse_Reason.OK>\n | 'TimeoutError';\n\nexport class SignalRequestError extends LivekitError {\n reason: RequestErrorReason;\n\n constructor(message: string, reason: RequestErrorReason) {\n super(15, message);\n this.reason = reason;\n }\n}\n\nexport enum MediaDeviceFailure {\n // user rejected permissions\n PermissionDenied = 'PermissionDenied',\n // device is not available\n NotFound = 'NotFound',\n // device is in use. On Windows, only a single tab may get access to a device at a time.\n DeviceInUse = 'DeviceInUse',\n Other = 'Other',\n}\n\nexport namespace MediaDeviceFailure {\n export function getFailure(error: any): MediaDeviceFailure | undefined {\n if (error && 'name' in error) {\n if (error.name === 'NotFoundError' || error.name === 'DevicesNotFoundError') {\n return MediaDeviceFailure.NotFound;\n }\n if (error.name === 'NotAllowedError' || error.name === 'PermissionDeniedError') {\n return MediaDeviceFailure.PermissionDenied;\n }\n if (error.name === 'NotReadableError' || error.name === 'TrackStartError') {\n return MediaDeviceFailure.DeviceInUse;\n }\n return MediaDeviceFailure.Other;\n }\n }\n}\n","import { LivekitError } from '../room/errors';\n\nexport enum CryptorErrorReason {\n InvalidKey = 0,\n MissingKey = 1,\n InternalError = 2,\n}\n\nexport class CryptorError extends LivekitError {\n reason: CryptorErrorReason;\n\n participantIdentity?: string;\n\n constructor(\n message?: string,\n reason: CryptorErrorReason = CryptorErrorReason.InternalError,\n participantIdentity?: string,\n ) {\n super(40, message);\n this.reason = reason;\n this.participantIdentity = participantIdentity;\n }\n}\n","import type Participant from '../room/participant/Participant';\nimport type { CryptorError } from './errors';\nimport type { KeyInfo } from './types';\n\nexport enum KeyProviderEvent {\n SetKey = 'setKey',\n RatchetRequest = 'ratchetRequest',\n KeyRatcheted = 'keyRatcheted',\n}\n\nexport type KeyProviderCallbacks = {\n [KeyProviderEvent.SetKey]: (keyInfo: KeyInfo) => void;\n [KeyProviderEvent.RatchetRequest]: (participantIdentity?: string, keyIndex?: number) => void;\n [KeyProviderEvent.KeyRatcheted]: (material: CryptoKey, keyIndex?: number) => void;\n};\n\nexport enum KeyHandlerEvent {\n KeyRatcheted = 'keyRatcheted',\n}\n\nexport type ParticipantKeyHandlerCallbacks = {\n [KeyHandlerEvent.KeyRatcheted]: (\n material: CryptoKey,\n participantIdentity: string,\n keyIndex?: number,\n ) => void;\n};\n\nexport enum EncryptionEvent {\n ParticipantEncryptionStatusChanged = 'participantEncryptionStatusChanged',\n EncryptionError = 'encryptionError',\n}\n\nexport type E2EEManagerCallbacks = {\n [EncryptionEvent.ParticipantEncryptionStatusChanged]: (\n enabled: boolean,\n participant: Participant,\n ) => void;\n [EncryptionEvent.EncryptionError]: (error: Error) => void;\n};\n\nexport type CryptorCallbacks = {\n [CryptorEvent.Error]: (error: CryptorError) => void;\n};\n\nexport enum CryptorEvent {\n Error = 'cryptorError',\n}\n","import { ENCRYPTION_ALGORITHM } from './constants';\n\nexport function isE2EESupported() {\n return isInsertableStreamSupported() || isScriptTransformSupported();\n}\n\nexport function isScriptTransformSupported() {\n // @ts-ignore\n return typeof window.RTCRtpScriptTransform !== 'undefined';\n}\n\nexport function isInsertableStreamSupported() {\n return (\n typeof window.RTCRtpSender !== 'undefined' &&\n // @ts-ignore\n typeof window.RTCRtpSender.prototype.createEncodedStreams !== 'undefined'\n );\n}\n\nexport function isVideoFrame(\n frame: RTCEncodedAudioFrame | RTCEncodedVideoFrame,\n): frame is RTCEncodedVideoFrame {\n return 'type' in frame;\n}\n\nexport async function importKey(\n keyBytes: Uint8Array | ArrayBuffer,\n algorithm: string | { name: string } = { name: ENCRYPTION_ALGORITHM },\n usage: 'derive' | 'encrypt' = 'encrypt',\n) {\n // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey\n return crypto.subtle.importKey(\n 'raw',\n keyBytes,\n algorithm,\n false,\n usage === 'derive' ? ['deriveBits', 'deriveKey'] : ['encrypt', 'decrypt'],\n );\n}\n\nexport async function createKeyMaterialFromString(password: string) {\n let enc = new TextEncoder();\n\n const keyMaterial = await crypto.subtle.importKey(\n 'raw',\n enc.encode(password),\n {\n name: 'PBKDF2',\n },\n false,\n ['deriveBits', 'deriveKey'],\n );\n\n return keyMaterial;\n}\n\nexport async function createKeyMaterialFromBuffer(cryptoBuffer: ArrayBuffer) {\n const keyMaterial = await crypto.subtle.importKey('raw', cryptoBuffer, 'HKDF', false, [\n 'deriveBits',\n 'deriveKey',\n ]);\n\n return keyMaterial;\n}\n\nfunction getAlgoOptions(algorithmName: string, salt: string) {\n const textEncoder = new TextEncoder();\n const encodedSalt = textEncoder.encode(salt);\n switch (algorithmName) {\n case 'HKDF':\n return {\n name: 'HKDF',\n salt: encodedSalt,\n hash: 'SHA-256',\n info: new ArrayBuffer(128),\n };\n case 'PBKDF2': {\n return {\n name: 'PBKDF2',\n salt: encodedSalt,\n hash: 'SHA-256',\n iterations: 100000,\n };\n }\n default:\n throw new Error(`algorithm ${algorithmName} is currently unsupported`);\n }\n}\n\n/**\n * Derives a set of keys from the master key.\n * See https://tools.ietf.org/html/draft-omara-sframe-00#section-4.3.1\n */\nexport async function deriveKeys(material: CryptoKey, salt: string) {\n const algorithmOptions = getAlgoOptions(material.algorithm.name, salt);\n\n // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey#HKDF\n // https://developer.mozilla.org/en-US/docs/Web/API/HkdfParams\n const encryptionKey = await crypto.subtle.deriveKey(\n algorithmOptions,\n material,\n {\n name: ENCRYPTION_ALGORITHM,\n length: 128,\n },\n false,\n ['encrypt', 'decrypt'],\n );\n\n return { material, encryptionKey };\n}\n\nexport function createE2EEKey(): Uint8Array {\n return window.crypto.getRandomValues(new Uint8Array(32));\n}\n\n/**\n * Ratchets a key. See\n * https://tools.ietf.org/html/draft-omara-sframe-00#section-4.3.5.1\n */\nexport async function ratchet(material: CryptoKey, salt: string): Promise<ArrayBuffer> {\n const algorithmOptions = getAlgoOptions(material.algorithm.name, salt);\n\n // https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveBits\n return crypto.subtle.deriveBits(algorithmOptions, material, 256);\n}\n\nexport function needsRbspUnescaping(frameData: Uint8Array) {\n for (var i = 0; i < frameData.length - 3; i++) {\n if (frameData[i] == 0 && frameData[i + 1] == 0 && frameData[i + 2] == 3) return true;\n }\n return false;\n}\n\nexport function parseRbsp(stream: Uint8Array): Uint8Array {\n const dataOut: number[] = [];\n var length = stream.length;\n for (var i = 0; i < stream.length; ) {\n // Be careful about over/underflow here. byte_length_ - 3 can underflow, and\n // i + 3 can overflow, but byte_length_ - i can't, because i < byte_length_\n // above, and that expression will produce the number of bytes left in\n // the stream including the byte at i.\n if (length - i >= 3 && !stream[i] && !stream[i + 1] && stream[i + 2] == 3) {\n // Two rbsp bytes.\n dataOut.push(stream[i++]);\n dataOut.push(stream[i++]);\n // Skip the emulation byte.\n i++;\n } else {\n // Single rbsp byte.\n dataOut.push(stream[i++]);\n }\n }\n return new Uint8Array(dataOut);\n}\n\nconst kZerosInStartSequence = 2;\nconst kEmulationByte = 3;\n\nexport function writeRbsp(data_in: Uint8Array): Uint8Array {\n const dataOut: number[] = [];\n var numConsecutiveZeros = 0;\n for (var i = 0; i < data_in.length; ++i) {\n var byte = data_in[i];\n if (byte <= kEmulationByte && numConsecutiveZeros >= kZerosInStartSequence) {\n // Need to escape.\n dataOut.push(kEmulationByte);\n numConsecutiveZeros = 0;\n }\n dataOut.push(byte);\n if (byte == 0) {\n ++numConsecutiveZeros;\n } else {\n numConsecutiveZeros = 0;\n }\n }\n return new Uint8Array(dataOut);\n}\n","import { MAX_SIF_COUNT, MAX_SIF_DURATION } from '../constants';\n\nexport class SifGuard {\n private consecutiveSifCount = 0;\n\n private sifSequenceStartedAt: number | undefined;\n\n private lastSifReceivedAt: number = 0;\n\n private userFramesSinceSif: number = 0;\n\n recordSif() {\n this.consecutiveSifCount += 1;\n this.sifSequenceStartedAt ??= Date.now();\n this.lastSifReceivedAt = Date.now();\n }\n\n recordUserFrame() {\n if (this.sifSequenceStartedAt === undefined) {\n return;\n } else {\n this.userFramesSinceSif += 1;\n }\n if (\n // reset if we received more user frames than SIFs\n this.userFramesSinceSif > this.consecutiveSifCount ||\n // also reset if we got a new user frame and the latest SIF frame hasn't been updated in a while\n Date.now() - this.lastSifReceivedAt > MAX_SIF_DURATION\n ) {\n this.reset();\n }\n }\n\n isSifAllowed() {\n return (\n this.consecutiveSifCount < MAX_SIF_COUNT &&\n (this.sifSequenceStartedAt === undefined ||\n Date.now() - this.sifSequenceStartedAt < MAX_SIF_DURATION)\n );\n }\n\n reset() {\n this.userFramesSinceSif = 0;\n this.consecutiveSifCount = 0;\n this.sifSequenceStartedAt = undefined;\n }\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\n// TODO code inspired by https://github.com/webrtc/samples/blob/gh-pages/src/content/insertable-streams/endtoend-encryption/js/worker.js\nimport { EventEmitter } from 'events';\nimport type TypedEventEmitter from 'typed-emitter';\nimport { workerLogger } from '../../logger';\nimport type { VideoCodec } from '../../room/track/options';\nimport { ENCRYPTION_ALGORITHM, IV_LENGTH, UNENCRYPTED_BYTES } from '../constants';\nimport { CryptorError, CryptorErrorReason } from '../errors';\nimport { CryptorCallbacks, CryptorEvent } from '../events';\nimport type { DecodeRatchetOptions, KeyProviderOptions, KeySet } from '../types';\nimport { deriveKeys, isVideoFrame, needsRbspUnescaping, parseRbsp, writeRbsp } from '../utils';\nimport type { ParticipantKeyHandler } from './ParticipantKeyHandler';\nimport { SifGuard } from './SifGuard';\n\nexport const encryptionEnabledMap: Map<string, boolean> = new Map();\n\nexport interface FrameCryptorConstructor {\n new (opts?: unknown): BaseFrameCryptor;\n}\n\nexport interface TransformerInfo {\n readable: ReadableStream;\n writable: WritableStream;\n transformer: TransformStream;\n abortController: AbortController;\n}\n\nexport class BaseFrameCryptor extends (EventEmitter as new () => TypedEventEmitter<CryptorCallbacks>) {\n protected encodeFunction(\n encodedFrame: RTCEncodedVideoFrame | RTCEncodedAudioFrame,\n controller: TransformStreamDefaultController,\n ): Promise<any> {\n throw Error('not implemented for subclass');\n }\n\n protected decodeFunction(\n encodedFrame: RTCEncodedVideoFrame | RTCEncodedAudioFrame,\n controller: TransformStreamDefaultController,\n ): Promise<any> {\n throw Error('not implemented for subclass');\n }\n}\n\n/**\n * Cryptor is responsible for en-/decrypting media frames.\n * Each Cryptor instance is responsible for en-/decrypting a single mediaStreamTrack.\n */\nexport class FrameCryptor extends BaseFrameCryptor {\n private sendCounts: Map<number, number>;\n\n private participantIdentity: string | undefined;\n\n private trackId: string | undefined;\n\n private keys: ParticipantKeyHandler;\n\n private videoCodec?: VideoCodec;\n\n private rtpMap: Map<number, VideoCodec>;\n\n private keyProviderOptions: KeyProviderOptions;\n\n /**\n * used for detecting server injected unencrypted frames\n */\n private sifTrailer: Uint8Array;\n\n private sifGuard: SifGuard;\n\n private detectedCodec?: VideoCodec;\n\n constructor(opts: {\n keys: ParticipantKeyHandler;\n participantIdentity: string;\n keyProviderOptions: KeyProviderOptions;\n sifTrailer?: Uint8Array;\n }) {\n super();\n this.sendCounts = new Map();\n this.keys = opts.keys;\n this.participantIdentity = opts.participantIdentity;\n this.rtpMap = new Map();\n this.keyProviderOptions = opts.keyProviderOptions;\n this.sifTrailer = opts.sifTrailer ?? Uint8Array.from([]);\n this.sifGuard = new SifGuard();\n }\n\n private get logContext() {\n return {\n participant: this.participantIdentity,\n mediaTrackId: this.trackId,\n fallbackCodec: this.videoCodec,\n };\n }\n\n /**\n * Assign a different participant to the cryptor.\n * useful for transceiver re-use\n * @param id\n * @param keys\n */\n setParticipant(id: string, keys: ParticipantKeyHandler) {\n workerLogger.debug('setting new participant on cryptor', {\n ...this.logContext,\n participant: id,\n });\n if (this.participantIdentity) {\n workerLogger.error(\n 'cryptor has already a participant set, participant should have been unset before',\n {\n ...this.logContext,\n },\n );\n }\n this.participantIdentity = id;\n this.keys = keys;\n this.sifGuard.reset();\n }\n\n unsetParticipant() {\n workerLogger.debug('unsetting participant', this.logContext);\n this.participantIdentity = undefined;\n }\n\n isEnabled() {\n if (this.participantIdentity) {\n return encryptionEnabledMap.get(this.participantIdentity);\n } else {\n return undefined;\n }\n }\n\n getParticipantIdentity() {\n return this.participantIdentity;\n }\n\n getTrackId() {\n return this.trackId;\n }\n\n /**\n * Update the video codec used by the mediaStreamTrack\n * @param codec\n */\n setVideoCodec(codec: VideoCodec) {\n this.videoCodec = codec;\n }\n\n /**\n * rtp payload type map used for figuring out codec of payload type when encoding\n * @param map\n */\n setRtpMap(map: Map<number, VideoCodec>) {\n this.rtpMap = map;\n }\n\n setupTransform(\n operation: 'encode' | 'decode',\n readable: ReadableStream,\n writable: WritableStream,\n trackId: string,\n codec?: VideoCodec,\n ) {\n if (codec) {\n workerLogger.info('setting codec on cryptor to', { codec });\n this.videoCodec = codec;\n }\n\n workerLogger.debug('Setting up frame cryptor transform', {\n operation,\n passedTrackId: trackId,\n codec,\n ...this.logContext,\n });\n\n const transformFn = operation === 'encode' ? this.encodeFunction : this.decodeFunction;\n const transformStream = new TransformStream({\n transform: transformFn.bind(this),\n });\n\n readable\n .pipeThrough(transformStream)\n .pipeTo(writable)\n .catch((e) => {\n workerLogger.warn(e);\n this.emit(\n CryptorEvent.Error,\n e instanceof CryptorError\n ? e\n : new CryptorError(e.message, undefined, this.participantIdentity),\n );\n });\n this.trackId = trackId;\n }\n\n setSifTrailer(trailer: Uint8Array) {\n workerLogger.debug('setting SIF trailer', { ...this.logContext, trailer });\n this.sifTrailer = trailer;\n }\n\n /**\n * Function that will be injected in a stream and will encrypt the given encoded frames.\n *\n * @param {RTCEncodedVideoFrame|RTCEncodedAudioFrame} encodedFrame - Encoded video frame.\n * @param {TransformStreamDefaultController} controller - TransportStreamController.\n *\n * The VP8 payload descriptor described in\n * https://tools.ietf.org/html/rfc7741#section-4.2\n * is part of the RTP packet and not part of the frame and is not controllable by us.\n * This is fine as the SFU keeps having access to it for routing.\n *\n * The encrypted frame is formed as follows:\n * 1) Find unencrypted byte length, depending on the codec, frame type and kind.\n * 2) Form the GCM IV for the frame as described above.\n * 3) Encrypt the rest of the frame using AES-GCM.\n * 4) Allocate space for the encrypted frame.\n * 5) Copy the unencrypted bytes to the start of the encrypted frame.\n * 6) Append the ciphertext to the encrypted frame.\n * 7) Append the IV.\n * 8) Append a single byte for the key identifier.\n * 9) Enqueue the encrypted frame for sending.\n */\n protected async encodeFunction(\n encodedFrame: RTCEncodedVideoFrame | RTCEncodedAudioFrame,\n controller: TransformStreamDefaultController,\n ) {\n if (\n !this.isEnabled() ||\n // skip for encryption for empty dtx frames\n encodedFrame.data.byteLength === 0\n ) {\n return controller.enqueue(encodedFrame);\n }\n const keySet = this.keys.getKeySet();\n if (!keySet) {\n this.emit(\n CryptorEvent.Error,\n new CryptorError(\n `key set not found for ${\n this.participantIdentity\n } at index ${this.keys.getCurrentKeyIndex()}`,\n CryptorErrorReason.MissingKey,\n this.participantIdentity,\n ),\n );\n return;\n }\n const { encryptionKey } = keySet;\n const keyIndex = this.keys.getCurrentKeyIndex();\n\n if (encryptionKey) {\n const iv = this.makeIV(\n encodedFrame.getMetadata().synchronizationSource ?? -1,\n encodedFrame.timestamp,\n );\n let frameInfo = this.getUnencryptedBytes(encodedFrame);\n\n // Thіs is not encrypted and contains the VP8 payload descriptor or the Opus TOC byte.\n const frameHeader = new Uint8Array(encodedFrame.data, 0, frameInfo.unencryptedBytes);\n\n // Frame trailer contains the R|IV_LENGTH and key index\n const frameTrailer = new Uint8Array(2);\n\n frameTrailer[0] = IV_LENGTH;\n frameTrailer[1] = keyIndex;\n\n // Construct frame trailer. Similar to the frame header described in\n // https://tools.ietf.org/html/draft-omara-sframe-00#section-4.2\n // but we put it at the end.\n //\n // ---------+-------------------------+-+---------+----\n // payload |IV...(length = IV_LENGTH)|R|IV_LENGTH|KID |\n // ---------+-------------------------+-+---------+----\n try {\n const cipherText = await crypto.subtle.encrypt(\n {\n name: ENCRYPTION_ALGORITHM,\n iv,\n additionalData: new Uint8Array(encodedFrame.data, 0, frameHeader.byteLength),\n },\n encryptionKey,\n new Uint8Array(encodedFrame.data, frameInfo.unencryptedBytes),\n );\n\n let newDataWithoutHeader = new Uint8Array(\n cipherText.byteLength + iv.byteLength + frameTrailer.byteLength,\n );\n newDataWithoutHeader.set(new Uint8Array(cipherText)); // add ciphertext.\n newDataWithoutHeader.set(new Uint8Array(iv), cipherText.byteLength); // append IV.\n newDataWithoutHeader.set(frameTrailer, cipherText.byteLength + iv.byteLength); // append frame trailer.\n\n if (frameInfo.isH264) {\n newDataWithoutHeader = writeRbsp(newDataWithoutHeader);\n }\n\n var newData = new Uint8Array(frameHeader.byteLength + newDataWithoutHeader.byteLength);\n newData.set(frameHeader);\n newData.set(newDataWithoutHeader, frameHeader.byteLength);\n\n encodedFrame.data = newData.buffer;\n\n return controller.enqueue(encodedFrame);\n } catch (e: any) {\n // TODO: surface this to the app.\n workerLogger.error(e);\n }\n } else {\n workerLogger.debug('failed to encrypt, emitting error', this.logContext);\n this.emit(\n CryptorEvent.Error,\n new CryptorError(\n `encryption key missing for encoding`,\n CryptorErrorReason.MissingKey,\n this.participantIdentity,\n ),\n );\n }\n }\n\n /**\n * Function that will be injected in a stream and will decrypt the given encoded frames.\n *\n * @param {RTCEncodedVideoFrame|RTCEncodedAudioFrame} encodedFrame - Encoded video frame.\n * @param {TransformStreamDefaultController} controller - TransportStreamController.\n */\n protected async decodeFunction(\n encodedFrame: RTCEncodedVideoFrame | RTCEncodedAudioFrame,\n controller: TransformStreamDefaultController,\n ) {\n if (\n !this.isEnabled() ||\n // skip for decryption for empty dtx frames\n encodedFrame.data.byteLength === 0\n ) {\n workerLogger.debug('skipping empty frame', this.logContext);\n this.sifGuard.recordUserFrame();\n return controller.enqueue(encodedFrame);\n }\n\n if (isFrameServerInjected(encodedFrame.data, this.sifTrailer)) {\n workerLogger.debug('enqueue SIF', this.logContext);\n this.sifGuard.recordSif();\n\n if (this.sifGuard.isSifAllowed()) {\n encodedFrame.data = encodedFrame.data.slice(\n 0,\n encodedFrame.data.byteLength - this.sifTrailer.byteLength,\n );\n return controller.enqueue(encodedFrame);\n } else {\n workerLogger.warn('SIF limit reached, dropping frame');\n return;\n }\n } else {\n this.sifGuard.recordUserFrame();\n }\n const data = new Uint8Array(encodedFrame.data);\n const keyIndex = data[encodedFrame.data.byteLength - 1];\n\n if (this.keys.getKeySet(keyIndex) && this.keys.hasValidKey) {\n try {\n const decodedFrame = await this.decryptFrame(encodedFrame, keyIndex);\n this.keys.decryptionSuccess();\n if (decodedFrame) {\n return controller.enqueue(decodedFrame);\n }\n } catch (error) {\n if (error instanceof CryptorError && error.reason === CryptorErrorReason.InvalidKey) {\n // emit an error if the key handler thinks we have a valid key\n if (this.keys.hasValidKey) {\n this.emit(CryptorEvent.Error, error);\n this.keys.decryptionFailure();\n }\n } else {\n workerLogger.warn('decoding frame failed', { error });\n }\n }\n } else if (!this.keys.getKeySet(keyIndex) && this.keys.hasValidKey) {\n // emit an error if the key index is out of bounds but the key handler thinks we still have a valid key\n workerLogger.warn(`skipping decryption due to missing key at index ${keyIndex}`);\n this.emit(\n CryptorEvent.Error,\n new CryptorError(\n `missing key at index ${keyIndex} for participant ${this.participantIdentity}`,\n CryptorErrorReason.MissingKey,\n this.participantIdentity,\n ),\n );\n this.keys.decryptionFailure();\n }\n }\n\n /**\n * Function that will decrypt the given encoded frame. If the decryption fails, it will\n * ratchet the key for up to RATCHET_WINDOW_SIZE times.\n */\n private async decryptFrame(\n encodedFrame: RTCEncodedVideoFrame | RTCEncodedAudioFrame,\n keyIndex: number,\n initialMaterial: KeySet | undefined = undefined,\n ratchetOpts: DecodeRatchetOptions = { ratchetCount: 0 },\n ): Promise<RTCEncodedVideoFrame | RTCEncodedAudioFrame | undefined> {\n const keySet = this.keys.getKeySet(keyIndex);\n if (!ratchetOpts.encryptionKey && !keySet) {\n throw new TypeError(`no encryption key found for decryption of ${this.participantIdentity}`);\n }\n let frameInfo = this.getUnencryptedBytes(encodedFrame);\n\n // Construct frame trailer. Similar to the frame header described in\n // https://tools.ietf.org/html/draft-omara-sframe-00#section-4.2\n // but we put it at the end.\n //\n // ---------+-------------------------+-+---------+----\n // payload |IV...(length = IV_LENGTH)|R|IV_LENGTH|KID |\n // ---------+-------------------------+-+---------+----\n\n try {\n const frameHeader = new Uint8Array(encodedFrame.data, 0, frameInfo.unencryptedBytes);\n var encryptedData = new Uint8Array(\n encodedFrame.data,\n frameHeader.length,\n encodedFrame.data.byteLength - frameHeader.length,\n );\n if (frameInfo.isH264 && needsRbspUnescaping(encryptedData)) {\n encryptedData = parseRbsp(encryptedData);\n const newUint8 = new Uint8Array(frameHeader.byteLength + encryptedData.byteLength);\n newUint8.set(frameHeader);\n newUint8.set(encryptedData, frameHeader.byteLength);\n encodedFrame.data = newUint8.buffer;\n }\n\n const frameTrailer = new Uint8Array(encodedFrame.data, encodedFrame.data.byteLength - 2, 2);\n\n const ivLength = frameTrailer[0];\n const iv = new Uint8Array(\n encodedFrame.data,\n encodedFrame.data.byteLength - ivLength - frameTrailer.byteLength,\n ivLength,\n );\n\n const cipherTextStart = frameHeader.byteLength;\n const cipherTextLength =\n encodedFrame.data.byteLength -\n (frameHeader.byteLength + ivLength + frameTrailer.byteLength);\n\n const plainText = await crypto.subtle.decrypt(\n {\n name: ENCRYPTION_ALGORITHM,\n iv,\n additionalData: new Uint8Array(encodedFrame.data, 0, frameHeader.byteLength),\n },\n ratchetOpts.encryptionKey ?? keySet!.encryptionKey,\n new Uint8Array(encodedFrame.data, cipherTextStart, cipherTextLength),\n );\n\n const newData = new ArrayBuffer(frameHeader.byteLength + plainText.byteLength);\n const newUint8 = new Uint8Array(newData);\n\n newUint8.set(new Uint8Array(encodedFrame.data, 0, frameHeader.byteLength));\n newUint8.set(new Uint8Array(plainText), frameHeader.byteLength);\n\n encodedFrame.data = newData;\n\n return encodedFrame;\n } catch (error: any) {\n if (this.keyProviderOptions.ratchetWindowSize > 0) {\n if (ratchetOpts.ratchetCount < this.keyProviderOptions.ratchetWindowSize) {\n workerLogger.debug(\n `ratcheting key attempt ${ratchetOpts.ratchetCount} of ${\n this.keyProviderOptions.ratchetWindowSize\n }, for kind ${encodedFrame instanceof RTCEncodedAudioFrame ? 'audio' : 'video'}`,\n );\n\n let ratchetedKeySet: KeySet | undefined;\n if ((initialMaterial ?? keySet) === this.keys.getKeySet(keyIndex)) {\n // only ratchet if the currently set key is still the same as the one used to decrypt this frame\n // if not, it might be that a different frame has already ratcheted and we try with that one first\n const newMaterial = await this.keys.ratchetKey(keyIndex, false);\n\n ratchetedKeySet = await deriveKeys(newMaterial, this.keyProviderOptions.ratchetSalt);\n }\n\n const frame = await this.decryptFrame(encodedFrame, keyIndex, initialMaterial || keySet, {\n ratchetCount: ratchetOpts.ratchetCount + 1,\n encryptionKey: ratchetedKeySet?.encryptionKey,\n });\n if (frame && ratchetedKeySet) {\n // before updating the keys, make sure that the keySet used for this frame is still the same as the currently set key\n // if it's not, a new key might have been set already, which we don't want to override\n if ((initialMaterial ?? keySet) === this.keys.getKeySet(keyIndex)) {\n this.keys.setKeySet(ratchetedKeySet, keyIndex, true);\n // decryption was successful, set the new key index to reflect the ratcheted key set\n this.keys.setCurrentKeyIndex(keyIndex);\n }\n }\n return frame;\n } else {\n /**\n * Because we only set a new key once decryption has been successful,\n * we can be sure that we don't need to reset the key to the initial material at this point\n * as the key has not been updated on the keyHandler instance\n */\n\n workerLogger.warn('maximum ratchet attempts exceeded');\n throw new CryptorError(\n `valid key missing for participant ${this.participantIdentity}`,\n CryptorErrorReason.InvalidKey,\n this.participantIdentity,\n );\n }\n } else {\n throw new CryptorError(\n `Decryption failed: ${error.message}`,\n CryptorErrorReason.InvalidKey,\n this.participantIdentity,\n );\n }\n }\n }\n\n /**\n * Construct the IV used for AES-GCM and sent (in plain) with the packet similar to\n * https://tools.ietf.org/html/rfc7714#section-8.1\n * It concatenates\n * - the 32 bit synchronization source (SSRC) given on the encoded frame,\n * - the 32 bit rtp timestamp given on the encoded frame,\n * - a send counter that is specific to the SSRC. Starts at a random number.\n * The send counter is essentially the pictureId but we currently have to implement this ourselves.\n * There is no XOR with a salt. Note that this IV leaks the SSRC to the receiver but since this is\n * randomly generated and SFUs may not rewrite this is considered acceptable.\n * The SSRC is used to allow demultiplexing multiple streams with the same key, as described in\n * https://tools.ietf.org/html/rfc3711#section-4.1.1\n * The RTP timestamp is 32 bits and advances by the codec clock rate (90khz for video, 48khz for\n * opus audio) every second. For video it rolls over roughly every 13 hours.\n * The send counter will advance at the frame rate (30fps for video, 50fps for 20ms opus audio)\n * every second. It will take a long time to roll over.\n *\n * See also https://developer.mozilla.org/en-US/docs/Web/API/AesGcmParams\n */\n private makeIV(synchronizationSource: number, timestamp: number) {\n const iv = new ArrayBuffer(IV_LENGTH);\n const ivView = new DataView(iv);\n\n // having to keep our own send count (similar to a picture id) is not ideal.\n if (!this.sendCounts.has(synchronizationSource)) {\n // Initialize with a random offset, similar to the RTP sequence number.\n this.sendCounts.set(synchronizationSource, Math.floor(Math.random() * 0xffff));\n }\n\n const sendCount = this.sendCounts.get(synchronizationSource) ?? 0;\n\n ivView.setUint32(0, synchronizationSource);\n ivView.setUint32(4, timestamp);\n ivView.setUint32(8, timestamp - (sendCount % 0xffff));\n\n this.sendCounts.set(synchronizationSource, sendCount + 1);\n\n return iv;\n }\n\n private getUnencryptedBytes(frame: RTCEncodedVideoFrame | RTCEncodedAudioFrame): {\n unencryptedBytes: number;\n isH264: boolean;\n } {\n var frameInfo = { unencryptedBytes: 0, isH264: false };\n if (isVideoFrame(frame)) {\n let detectedCodec = this.getVideoCodec(frame) ?? this.videoCodec;\n if (detectedCodec !== this.detectedCodec) {\n workerLogger.debug('detected different codec', {\n detectedCodec,\n oldCodec: this.detectedCodec,\n ...this.logContext,\n });\n this.detectedCodec = detectedCodec;\n }\n\n if (detectedCodec === 'av1') {\n throw new Error(`${detectedCodec} is not yet supported for end to end encryption`);\n }\n\n if (detectedCodec === 'vp8') {\n frameInfo.unencryptedBytes = UNENCRYPTED_BYTES[frame.type];\n } else if (detectedCodec === 'vp9') {\n frameInfo.unencryptedBytes = 0;\n return frameInfo;\n }\n\n const data = new Uint8Array(frame.data);\n try {\n const naluIndices = findNALUIndices(data);\n\n // if the detected codec is undefined we test whether it _looks_ like a h264 frame as a best guess\n frameInfo.isH264 =\n detectedCodec === 'h264' ||\n naluIndices.some((naluIndex) =>\n [NALUType.SLICE_IDR, NALUType.SLICE_NON_IDR].includes(parseNALUType(data[naluIndex])),\n );\n\n if (frameInfo.isH264) {\n for (const index of naluIndices) {\n let type = parseNALUType(data[index]);\n switch (type) {\n case NALUType.SLICE_IDR:\n case NALUType.SLICE_NON_IDR:\n frameInfo.unencryptedBytes = index + 2;\n return frameInfo;\n default:\n break;\n }\n }\n throw new TypeError('Could not find NALU');\n }\n } catch (e) {\n // no op, we just continue and fallback to vp8\n }\n\n frameInfo.unencryptedBytes = UNENCRYPTED_BYTES[frame.type];\n return frameInfo;\n } else {\n frameInfo.unencryptedBytes = UNENCRYPTED_BYTES.audio;\n return frameInfo;\n }\n }\n\n /**\n * inspects frame payloadtype if available and maps it to the codec specified in rtpMap\n */\n private getVideoCodec(frame: RTCEncodedVideoFrame): VideoCodec | undefined {\n if (this.rtpMap.size === 0) {\n return undefined;\n }\n const payloadType = frame.getMetadata().payloadType;\n const codec = payloadType ? this.rtpMap.get(payloadType) : undefined;\n return codec;\n }\n}\n\n/**\n * Slice the NALUs present in the supplied buffer, assuming it is already byte-aligned\n * code adapted from https://github.com/medooze/h264-frame-parser/blob/main/lib/NalUnits.ts to return indices only\n */\nexport function findNALUIndices(stream: Uint8Array): number[] {\n const result: number[] = [];\n let start = 0,\n pos = 0,\n searchLength = stream.length - 2;\n while (pos < searchLength) {\n // skip until end of current NALU\n while (\n pos < searchLength &&\n !(stream[pos] === 0 && stream[pos + 1] === 0 && stream[pos + 2] === 1)\n )\n pos++;\n if (pos >= searchLength) pos = stream.length;\n // remove trailing zeros from current NALU\n let end = pos;\n while (end > start && stream[end - 1] === 0) end--;\n // save current NALU\n if (start === 0) {\n if (end !== start) throw TypeError('byte stream contains leading data');\n } else {\n result.push(start);\n }\n // begin new NALU\n start = pos = pos + 3;\n }\n return result;\n}\n\nexport function parseNALUType(startByte: number): NALUType {\n return startByte & kNaluTypeMask;\n}\n\nconst kNaluTypeMask = 0x1f;\n\nexport enum NALUType {\n /** Coded slice of a non-IDR picture */\n SLICE_NON_IDR = 1,\n /** Coded slice data partition A */\n SLICE_PARTITION_A = 2,\n /** Coded slice data partition B */\n SLICE_PARTITION_B = 3,\n /** Coded slice data partition C */\n SLICE_PARTITION_C = 4,\n /** Coded slice of an IDR picture */\n SLICE_IDR = 5,\n /** Supplemental enhancement information */\n SEI = 6,\n /** Sequence parameter set */\n SPS = 7,\n /** Picture parameter set */\n PPS = 8,\n /** Access unit delimiter */\n AUD = 9,\n /** End of sequence */\n END_SEQ = 10,\n /** End of stream */\n END_STREAM = 11,\n /** Filler data */\n FILLER_DATA = 12,\n /** Sequence parameter set extension */\n SPS_EXT = 13,\n /** Prefix NAL unit */\n PREFIX_NALU = 14,\n /** Subset sequence parameter set */\n SUBSET_SPS = 15,\n /** Depth parameter set */\n DPS = 16,\n\n // 17, 18 reserved\n\n /** Coded slice of an auxiliary coded picture without partitioning */\n SLICE_AUX = 19,\n /** Coded slice extension */\n SLICE_EXT = 20,\n /** Coded slice extension for a depth view component or a 3D-AVC texture view component */\n SLICE_LAYER_EXT = 21,\n\n // 22, 23 reserved\n}\n\n/**\n * we use a magic frame trailer to detect whether a frame is injected\n * by the livekit server and thus to be treated as unencrypted\n * @internal\n */\nexport function isFrameServerInjected(frameData: ArrayBuffer, trailerBytes: Uint8Array): boolean {\n if (trailerBytes.byteLength === 0) {\n return false;\n }\n const frameTrailer = new Uint8Array(\n frameData.slice(frameData.byteLength - trailerBytes.byteLength),\n );\n return trailerBytes.every((value, index) => value === frameTrailer[index]);\n}\n","import { EventEmitter } from 'events';\nimport type TypedEventEmitter from 'typed-emitter';\nimport { workerLogger } from '../../logger';\nimport { KeyHandlerEvent, type ParticipantKeyHandlerCallbacks } from '../events';\nimport type { KeyProviderOptions, KeySet } from '../types';\nimport { deriveKeys, importKey, ratchet } from '../utils';\n\n// TODO ParticipantKeyHandlers currently don't get destroyed on participant disconnect\n// we could do this by having a separate worker message on participant disconnected.\n\n/**\n * ParticipantKeyHandler is responsible for providing a cryptor instance with the\n * en-/decryption key of a participant. It assumes that all tracks of a specific participant\n * are encrypted with the same key.\n * Additionally it exposes a method to ratchet a key which can be used by the cryptor either automatically\n * if decryption fails or can be triggered manually on both sender and receiver side.\n *\n */\nexport class ParticipantKeyHandler extends (EventEmitter as new () => TypedEventEmitter<ParticipantKeyHandlerCallbacks>) {\n private currentKeyIndex: number;\n\n private cryptoKeyRing: Array<KeySet | undefined>;\n\n private keyProviderOptions: KeyProviderOptions;\n\n private ratchetPromiseMap: Map<number, Promise<CryptoKey>>;\n\n private participantIdentity: string;\n\n private decryptionFailureCount = 0;\n\n private _hasValidKey: boolean = true;\n\n get hasValidKey() {\n return this._hasValidKey;\n }\n\n constructor(participantIdentity: string, keyProviderOptions: KeyProviderOptions) {\n super();\n this.currentKeyIndex = 0;\n if (keyProviderOptions.keyringSize < 1 || keyProviderOptions.keyringSize > 255) {\n throw new TypeError('Keyring size needs to be between 1 and 256');\n }\n this.cryptoKeyRing = new Array(keyProviderOptions.keyringSize).fill(undefined);\n this.keyProviderOptions = keyProviderOptions;\n this.ratchetPromiseMap = new Map();\n this.participantIdentity = participantIdentity;\n this.resetKeyStatus();\n }\n\n decryptionFailure() {\n if (this.keyProviderOptions.failureTolerance < 0) {\n return;\n }\n this.decryptionFailureCount += 1;\n\n if (this.decryptionFailureCount > this.keyProviderOptions.failureTolerance) {\n workerLogger.warn(`key for ${this.participantIdentity} is being marked as invalid`);\n this._hasValidKey = false;\n }\n }\n\n decryptionSuccess() {\n this.resetKeyStatus();\n }\n\n /**\n * Call this after user initiated ratchet or a new key has been set in order to make sure to mark potentially\n * invalid keys as valid again\n */\n resetKeyStatus() {\n this.decryptionFailureCount = 0;\n this._hasValidKey = true;\n }\n\n /**\n * Ratchets the current key (or the one at keyIndex if provided) and\n * returns the ratcheted material\n * if `setKey` is true (default), it will also set the ratcheted key directly on the crypto key ring\n * @param keyIndex\n * @param setKey\n */\n ratchetKey(keyIndex?: number, setKey = true): Promise<CryptoKey> {\n const currentKeyIndex = keyIndex ?? this.getCurrentKeyIndex();\n\n const existingPromise = this.ratchetPromiseMap.get(currentKeyIndex);\n if (typeof existingPromise !== 'undefined') {\n return existingPromise;\n }\n const ratchetPromise = new Promise<CryptoKey>(async (resolve, reject) => {\n try {\n const keySet = this.getKeySet(currentKeyIndex);\n if (!keySet) {\n throw new TypeError(\n `Cannot ratchet key without a valid keyset of participant ${this.participantIdentity}`,\n );\n }\n const currentMaterial = keySet.material;\n const newMaterial = await importKey(\n await ratchet(currentMaterial, this.keyProviderOptions.ratchetSalt),\n currentMaterial.algorithm.name,\n 'derive',\n );\n\n if (setKey) {\n this.setKeyFromMaterial(newMaterial, currentKeyIndex, true);\n this.emit(\n KeyHandlerEvent.KeyRatcheted,\n newMaterial,\n this.participantIdentity,\n currentKeyIndex,\n );\n }\n resolve(newMaterial);\n } catch (e) {\n reject(e);\n } finally {\n this.ratchetPromiseMap.delete(currentKeyIndex);\n }\n });\n this.ratchetPromiseMap.set(currentKeyIndex, ratchetPromise);\n return ratchetPromise;\n }\n\n /**\n * takes in a key material with `deriveBits` and `deriveKey` set as key usages\n * and derives encryption keys from the material and sets it on the key ring buffer\n * together with the material\n * also resets the valid key property and updates the currentKeyIndex\n */\n async setKey(material: CryptoKey, keyIndex = 0) {\n await this.setKeyFromMaterial(material, keyIndex);\n this.resetKeyStatus();\n }\n\n /**\n * takes in a key material with `deriveBits` and `deriveKey` set as key usages\n * and derives encryption keys from the material and sets it on the key ring buffers\n * together with the material\n * also updates the currentKeyIndex\n */\n async setKeyFromMaterial(material: CryptoKey, keyIndex: number, emitRatchetEvent = false) {\n const keySet = await deriveKeys(material, this.keyProviderOptions.ratchetSalt);\n const newIndex = keyIndex >= 0 ? keyIndex % this.cryptoKeyRing.length : this.currentKeyIndex;\n workerLogger.debug(`setting new key with index ${keyIndex}`, {\n usage: material.usages,\n algorithm: material.algorithm,\n ratchetSalt: this.keyProviderOptions.ratchetSalt,\n });\n this.setKeySet(keySet, newIndex, emitRatchetEvent);\n if (newIndex >= 0) this.currentKeyIndex = newIndex;\n }\n\n setKeySet(keySet: KeySet, keyIndex: number, emitRatchetEvent = false) {\n this.cryptoKeyRing[keyIndex % this.cryptoKeyRing.length] = keySet;\n\n if (emitRatchetEvent) {\n this.emit(KeyHandlerEvent.KeyRatcheted, keySet.material, this.participantIdentity, keyIndex);\n }\n }\n\n async setCurrentKeyIndex(index: number) {\n this.currentKeyIndex = index % this.cryptoKeyRing.length;\n this.resetKeyStatus();\n }\n\n getCurrentKeyIndex() {\n return this.currentKeyIndex;\n }\n\n /**\n * returns currently used KeySet or the one at `keyIndex` if provided\n * @param keyIndex\n * @returns\n */\n getKeySet(keyIndex?: number) {\n return this.cryptoKeyRing[keyIndex ?? this.currentKeyIndex];\n }\n}\n","import { workerLogger } from '../../logger';\nimport { VideoCodec } from '../../room/track/options';\nimport { AsyncQueue } from '../../utils/AsyncQueue';\nimport { KEY_PROVIDER_DEFAULTS } from '../constants';\nimport { CryptorErrorReason } from '../errors';\nimport { CryptorEvent, KeyHandlerEvent } from '../events';\nimport type {\n E2EEWorkerMessage,\n ErrorMessage,\n InitAck,\n KeyProviderOptions,\n RatchetMessage,\n RatchetRequestMessage,\n} from '../types';\nimport { FrameCryptor, encryptionEnabledMap } from './FrameCryptor';\nimport { ParticipantKeyHandler } from './ParticipantKeyHandler';\n\nconst participantCryptors: FrameCryptor[] = [];\nconst participantKeys: Map<string, ParticipantKeyHandler> = new Map();\nlet sharedKeyHandler: ParticipantKeyHandler | undefined;\nlet messageQueue = new AsyncQueue();\n\nlet isEncryptionEnabled: boolean = false;\n\nlet useSharedKey: boolean = false;\n\nlet sifTrailer: Uint8Array | undefined;\n\nlet keyProviderOptions: KeyProviderOptions = KEY_PROVIDER_DEFAULTS;\n\nlet rtpMap: Map<number, VideoCodec> = new Map();\n\nworkerLogger.setDefaultLevel('info');\n\nonmessage = (ev) => {\n messageQueue.run(async () => {\n const { kind, data }: E2EEWorkerMessage = ev.data;\n\n switch (kind) {\n case 'init':\n workerLogger.setLevel(data.loglevel);\n workerLogger.info('worker initialized');\n keyProviderOptions = data.keyProviderOptions;\n useSharedKey = !!data.keyProviderOptions.sharedKey;\n // acknowledge init successful\n const ackMsg: InitAck = {\n kind: 'initAck',\n data: { enabled: isEncryptionEnabled },\n };\n postMessage(ackMsg);\n break;\n case 'enable':\n setEncryptionEnabled(data.enabled, data.participantIdentity);\n workerLogger.info(\n `updated e2ee enabled status for ${data.participantIdentity} to ${data.enabled}`,\n );\n // acknowledge enable call successful\n postMessage(ev.data);\n break;\n case 'decode':\n let cryptor = getTrackCryptor(data.participantIdentity, data.trackId);\n cryptor.setupTransform(\n kind,\n data.readableStream,\n data.writableStream,\n data.trackId,\n data.codec,\n );\n break;\n case 'encode':\n let pubCryptor = getTrackCryptor(data.participantIdentity, data.trackId);\n pubCryptor.setupTransform(\n kind,\n data.readableStream,\n data.writableStream,\n data.trackId,\n data.codec,\n );\n break;\n case 'setKey':\n if (useSharedKey) {\n await setSharedKey(data.key, data.keyIndex);\n } else if (data.participantIdentity) {\n workerLogger.info(\n `set participant sender key ${data.participantIdentity} index ${data.keyIndex}`,\n );\n await getParticipantKeyHandler(data.participantIdentity).setKey(data.key, data.keyIndex);\n } else {\n workerLogger.error('no participant Id was provided and shared key usage is disabled');\n }\n break;\n case 'removeTransform':\n unsetCryptorParticipant(data.trackId, data.participantIdentity);\n break;\n case 'updateCodec':\n getTrackCryptor(data.participantIdentity, data.trackId).setVideoCodec(data.codec);\n break;\n case 'setRTPMap':\n // this is only used for the local participant\n rtpMap = data.map;\n participantCryptors.forEach((cr) => {\n if (cr.getParticipantIdentity() === data.participantIdentity) {\n cr.setRtpMap(data.map);\n }\n });\n break;\n case 'ratchetRequest':\n handleRatchetRequest(data);\n break;\n case 'setSifTrailer':\n handleSifTrailer(data.trailer);\n break;\n default:\n break;\n }\n });\n};\n\nasync function handleRatchetRequest(data: RatchetRequestMessage['data']) {\n if (useSharedKey) {\n const keyHandler = getSharedKeyHandler();\n await keyHandler.ratchetKey(data.keyIndex);\n keyHandler.resetKeyStatus();\n } else if (data.participantIdentity) {\n const keyHandler = getParticipantKeyHandler(data.participantIdentity);\n await keyHandler.ratchetKey(data.keyIndex);\n keyHandler.resetKeyStatus();\n } else {\n workerLogger.error(\n 'no participant Id was provided for ratchet request and shared key usage is disabled',\n );\n }\n}\n\nfunction getTrackCryptor(participantIdentity: string, trackId: string) {\n let cryptors = participantCryptors.filter((c) => c.getTrackId() === trackId);\n if (cryptors.length > 1) {\n const debugInfo = cryptors\n .map((c) => {\n return { participant: c.getParticipantIdentity() };\n })\n .join(',');\n workerLogger.error(\n `Found multiple cryptors for the same trackID ${trackId}. target participant: ${participantIdentity} `,\n { participants: debugInfo },\n );\n }\n let cryptor = cryptors[0];\n if (!cryptor) {\n workerLogger.info('creating new cryptor for', { participantIdentity });\n if (!keyProviderOptions) {\n throw Error('Missing keyProvider options');\n }\n cryptor = new FrameCryptor({\n participantIdentity,\n keys: getParticipantKeyHandler(participantIdentity),\n keyProviderOptions,\n sifTrailer,\n });\n cryptor.setRtpMap(rtpMap);\n setupCryptorErrorEvents(cryptor);\n participantCryptors.push(cryptor);\n } else if (participantIdentity !== cryptor.getParticipantIdentity()) {\n // assign new participant id to track cryptor and pass in correct key handler\n cryptor.setParticipant(participantIdentity, getParticipantKeyHandler(participantIdentity));\n }\n\n return cryptor;\n}\n\nfunction getParticipantKeyHandler(participantIdentity: string) {\n if (useSharedKey) {\n return getSharedKeyHandler();\n }\n let keys = participantKeys.get(participantIdentity);\n if (!keys) {\n keys = new ParticipantKeyHandler(participantIdentity, keyProviderOptions);\n keys.on(KeyHandlerEvent.KeyRatcheted, emitRatchetedKeys);\n participantKeys.set(participantIdentity, keys);\n }\n return keys;\n}\n\nfunction getSharedKeyHandler() {\n if (!sharedKeyHandler) {\n workerLogger.debug('creating new shared key handler');\n sharedKeyHandler = new ParticipantKeyHandler('shared-key', keyProviderOptions);\n }\n return sharedKeyHandler;\n}\n\nfunction unsetCryptorParticipant(trackId: string, participantIdentity: string) {\n const cryptors = participantCryptors.filter(\n (c) => c.getParticipantIdentity() === participantIdentity && c.getTrackId() === trackId,\n );\n if (cryptors.length > 1) {\n workerLogger.error('Found multiple cryptors for the same participant and trackID combination', {\n trackId,\n participantIdentity,\n });\n }\n const cryptor = cryptors[0];\n if (!cryptor) {\n workerLogger.warn('Could not unset participant on cryptor', { trackId, participantIdentity });\n } else {\n cryptor.unsetParticipant();\n }\n}\n\nfunction setEncryptionEnabled(enable: boolean, participantIdentity: string) {\n workerLogger.debug(`setting encryption enabled for all tracks of ${participantIdentity}`, {\n enable,\n });\n encryptionEnabledMap.set(participantIdentity, enable);\n}\n\nasync function setSharedKey(key: CryptoKey, index?: number) {\n workerLogger.info('set shared key', { index });\n await getSharedKeyHandler().setKey(key, index);\n}\n\nfunction setupCryptorErrorEvents(cryptor: FrameCryptor) {\n cryptor.on(CryptorEvent.Error, (error) => {\n const msg: ErrorMessage = {\n kind: 'error',\n data: { error: new Error(`${CryptorErrorReason[error.reason]}: ${error.message}`) },\n };\n postMessage(msg);\n });\n}\n\nfunction emitRatchetedKeys(material: CryptoKey, participantIdentity: string, keyIndex?: number) {\n const msg: RatchetMessage = {\n kind: `ratchetKey`,\n data: {\n participantIdentity,\n keyIndex,\n material,\n },\n };\n postMessage(msg);\n}\n\nfunction handleSifTrailer(trailer: Uint8Array) {\n sifTrailer = trailer;\n participantCryptors.forEach((c) => {\n c.setSifTrailer(trailer);\n });\n}\n\n// Operations using RTCRtpScriptTransform.\n// @ts-ignore\nif (self.RTCTransformEvent) {\n workerLogger.debug('setup transform event');\n // @ts-ignore\n self.onrtctransform = (event: RTCTransformEvent) => {\n // @ts-ignore .transformer property is part of RTCTransformEvent\n const transformer = event.transformer;\n workerLogger.debug('transformer', transformer);\n // @ts-ignore monkey patching non standard flag\n transformer.handled = true;\n const { kind, participantIdentity, trackId, codec } = transformer.options;\n const cryptor = getTrackCryptor(participantIdentity, trackId);\n workerLogger.debug('transform', { codec });\n cryptor.setupTransform(kind, transformer.readable, transformer.writable, trackId, codec);\n };\n}\n"],"names":["root","definition","this","noop","undefinedType","isIE","window","navigator","test","userAgent","logMethods","_loggersByName","defaultLogger","bindMethod","obj","methodName","method","bind","Function","prototype","call","e","apply","arguments","traceForIE","console","log","trace","replaceLoggingMethods","level","getLevel","i","length","methodFactory","name","debug","levels","SILENT","enableLoggingWhenConsoleArrives","defaultMethodFactory","_level","_loggerName","undefined","realMethod","Logger","factory","inheritedLevel","defaultLevel","userLevel","self","storageKey","getPersistedLevel","storedLevel","localStorage","ignore","cookie","document","cookieName","encodeURIComponent","location","indexOf","exec","slice","normalizeLevel","input","toUpperCase","TypeError","TRACE","DEBUG","INFO","WARN","ERROR","setLevel","persist","levelNum","levelName","persistLevelIfPossible","setDefaultLevel","resetLevel","removeItem","clearPersistedLevel","enableAll","disableAll","rebuild","childName","initialLevel","getLogger","logger","_log","noConflict","getLoggers","exports","module","LogLevel","LoggerNames","livekitLogger","Object","values","map","info","workerLogger","assert","condition","msg","Error","FLOAT32_MAX","FLOAT32_MIN","UINT32_MAX","INT32_MAX","INT32_MIN","assertInt32","arg","Number","isInteger","assertUInt32","assertFloat32","isFinite","enumTypeSymbol","Symbol","getEnumType","enumObject","t","setEnumType","typeName","opt","makeEnumType","v","no","localName","_opt","names","create","numbers","normalValues","value","n","normalizeEnumValue","push","findName","findNumber","makeEnum","assign","Message","equals","other","getType","runtime","util","clone","fromBinary","bytes","options","format","bin","makeReadOptions","readMessage","readerFactory","byteLength","fromJson","jsonValue","type","json","fromJsonString","jsonString","JSON","parse","concat","message","String","toBinary","makeWriteOptions","writer","writerFactory","writeMessage","finish","toJson","toJsonString","_a","stringify","prettySpaces","toJSON","emitDefaultValues","getPrototypeOf","constructor","varint64read","lowBits","highBits","shift","b","buf","pos","assertBounds","middleByte","varint64write","lo","hi","hasNext","byte","splitBits","hasMoreBits","TWO_PWR_32_DBL","int64FromString","dec","minus","base","add1e6digit","begin","end","digit1e6","negate","newBits","uInt64ToString","toUnsigned","mid","high","digitA","digitB","digitC","Math","floor","toString","decimalFrom1e7WithLeadingZeros","digit1e7","partial","varint32write","varint32read","result","readBytes","protoInt64","dv","DataView","ArrayBuffer","BigInt","getBigInt64","getBigUint64","setBigInt64","setBigUint64","process","env","BUF_BIGINT_DISABLE","MIN","MAX","UMIN","UMAX","zero","supported","bi","uParse","enc","getInt32","uEnc","setInt32","uDec","assertInt64String","assertUInt64String","bits","negative","int64ToString","makeInt64Support","ScalarType","LongType","WireType","scalarEquals","a","BYTES","Uint8Array","UINT64","FIXED64","INT64","SFIXED64","SINT64","scalarZeroValue","longType","BOOL","DOUBLE","FLOAT","STRING","isScalarZeroValue","BinaryWriter","textEncoder","stack","TextEncoder","chunks","len","offset","set","fork","join","chunk","prev","pop","uint32","raw","tag","fieldNo","int32","bool","string","encode","float","buffer","setFloat32","double","setFloat64","fixed32","setUint32","sfixed32","sint32","sfixed64","view","tc","fixed64","int64","sint64","sign","uint64","BinaryReader","textDecoder","varint64","byteOffset","TextDecoder","wireType","skip","start","Varint","Bit64","Bit32","LengthDelimited","StartGroup","fn","wt","EndGroup","subarray","RangeError","zze","s","getUint32","getFloat32","getFloat64","decode","createExtensionContainer","extension","field","container","ext","repeated","default","kind","T","L","fieldWrapper","unwrapField","initExtensionField","encTable","split","decTable","charCodeAt","protoBase64","base64Str","es","bytePos","groupPos","p","base64","getExtension","assertExtendee","ufs","unknownFields","filter","uf","filterUnknownFields","listUnknownFields","get","readField","data","setExtension","readOpt","writeOpt","hasExtension","discardUnknownFields","onUnknownField","f","writeField","reader","messageType","extendee","find","isFieldSet","target","oneof","case","req","keys","clearField","implicitPresence","isMessage","getOwnPropertyNames","every","m","actualType","wrapField","INT32","UINT32","jsonReadDefaults","ignoreUnknownFields","jsonWriteDefaults","enumAsInteger","useProtoFieldName","tokenNull","tokenIgnoredUnknownEnum","debugJsonValue","Array","isArray","parentType","targetArray","jsonItem","enumValue","readEnum","readScalar","targetMap","jsonMapKey","jsonMapValue","entries","key","readMapKey","K","V","BIGINT","currentValue","scalarValue","nullAsZeroValue","NaN","POSITIVE_INFINITY","NEGATIVE_INFINITY","trim","isNaN","FIXED32","SFIXED32","SINT32","long","uLong","canEmitFieldDefaultValue","jsonObj","entryKey","entryValue","writeScalar","enumType","writeEnum","jsonArr","val","unknownFieldsSymbol","readDefaults","readUnknownFields","writeDefaults","writeUnknownFields","scalarType","read","readScalarLTString","arr","readMessageField","mapKey","mapVal","readMapEntry","delimited","packed","scalarTypeInfo","writePacked","item","writeMessageField","writeMapEntry","keyValue","parseInt","toLowerCase","cloneSingularField","c","toU8Arr","InternalFieldList","fields","normalizer","_fields","_normalizer","findJsonName","jsonName","jsonNames","list","all","byNumber","numbersAsc","sort","byMember","members","o","localFieldName","protoName","inOneof","protoCamelCase","safeObjectProperty","safeMessageProperty","fieldJsonName","snakeCase","capNext","charAt","reservedObjectProperties","Set","reservedMessageProperties","fallback","has","InternalOneofInfo","addField","findField","_lookup","proto3","newFieldList","source","fieldInfos","packedByDefault","_b","_c","_d","_e","_f","r","ooname","normalizeFieldInfos","initFields","member","syntax","oneofSeen","Map","registry","typeRegistry","jsonKey","seen","found","findExtension","startsWith","endsWith","substring","findExtensionFor","lengthOrEndTagFieldNo","delimitedMessageEncoding","initPartial","sk","sourceField","copy","k","mt","va","vb","any","makeMessageType","lastIndexOf","setPrototypeOf","makeExtension","fi","TrackType","TrackSource","StreamState","commonVersionIdentifier","browserDetails","getBrowser","force","ua","browser","browsersList","_ref","describe","version","getMatch","os","includes","osVersion","getOSVersion","exp","id","match","replace","VideoPreset","widthOrOptions","height","maxBitrate","maxFramerate","priority","width","aspectRatio","encoding","resolution","frameRate","AudioPresets","telephone","speech","music","musicStereo","musicHighQuality","musicHighQualityStereo","ReflectOwnKeys","R","Reflect","ReflectApply","receiver","args","ownKeys","getOwnPropertySymbols","NumberIsNaN","EventEmitter","init","eventsModule","once","emitter","Promise","resolve","reject","errorListener","err","removeListener","resolver","eventTargetAgnosticAddListener","handler","flags","on","addErrorHandlerIfEventEmitter","_events","_eventsCount","_maxListeners","defaultMaxListeners","checkListener","listener","_getMaxListeners","that","_addListener","prepend","events","existing","warning","newListener","emit","unshift","warned","w","count","warn","onceWrapper","fired","wrapFn","_onceWrap","state","wrapped","_listeners","unwrap","evlistener","ret","unwrapListeners","arrayClone","listenerCount","addEventListener","wrapListener","removeEventListener","defineProperty","enumerable","setMaxListeners","getMaxListeners","doError","error","er","context","listeners","addListener","prependListener","prependOnceListener","position","originalListener","index","spliceOne","off","removeAllListeners","rawListeners","eventNames","RoomEvent","ParticipantEvent","EngineEvent","TrackEvent","recycledElements","VideoQuality","QueueTaskStatus","Track","mediaTrack","loggerOptions","super","attachedElements","isMuted","streamState","Active","isInBackground","_currentBitrate","appVisibilityChangedListener","backgroundTimeout","clearTimeout","visibilityState","setTimeout","handleAppVisibilityChanged","loggerName","loggerContextCb","_mediaStreamTrack","_mediaStreamID","Source","Unknown","logContext","getLogContextFromTrack","currentBitrate","mediaStreamTrack","mediaStreamID","attach","element","elementType","Kind","Video","addAppVisibilityListener","forEach","parentElement","splice","createElement","track","mediaStream","existingTracks","srcObject","MediaStream","getAudioTracks","getVideoTracks","et","removeTrack","addTrack","isSafari","HTMLVideoElement","autoplay","muted","playsInline","play","catch","attachToElement","allMediaStreamTracks","getTracks","hasAudio","some","tr","then","AudioPlaybackStarted","VideoPlaybackStarted","AudioPlaybackFailed","VideoPlaybackFailed","ElementAttached","detach","detachTrack","idx","recycleElement","ElementDetached","detached","elm","removeAppVisibilityListener","stop","stopMonitor","enable","enabled","disable","monitorInterval","clearInterval","timeSyncHandle","cancelAnimationFrame","updateLoggerOptions","HTMLAudioElement","shouldCache","pause","el","isWeb","trackID","sid","streamID","streamTrackID","trackSid","isEnabled","trackInfo","mimeType","trackName","encrypted","isEncrypted","kindToProto","Audio","AUDIO","VIDEO","DATA","kindFromProto","sourceToProto","Camera","CAMERA","Microphone","MICROPHONE","ScreenShare","SCREEN_SHARE","ScreenShareAudio","SCREEN_SHARE_AUDIO","UNKNOWN","sourceFromProto","streamStateFromProto","ProtoStreamState","ACTIVE","PAUSED","Paused","Mutex","_locking","_locks","isLocked","lock","unlockNext","willLock","willUnlock","ENCRYPTION_ALGORITHM","UNENCRYPTED_BYTES","delta","audio","empty","KEY_PROVIDER_DEFAULTS","sharedKey","ratchetSalt","ratchetWindowSize","failureTolerance","keyringSize","LivekitError","code","MediaDeviceFailure","CryptorErrorReason","KeyProviderEvent","KeyHandlerEvent","EncryptionEvent","CryptorEvent","getFailure","NotFound","PermissionDenied","DeviceInUse","Other","CryptorError","reason","InternalError","participantIdentity","getAlgoOptions","algorithmName","salt","encodedSalt","hash","iterations","deriveKeys","material","algorithmOptions","algorithm","encryptionKey","crypto","subtle","deriveKey","SifGuard","consecutiveSifCount","lastSifReceivedAt","userFramesSinceSif","recordSif","sifSequenceStartedAt","Date","now","recordUserFrame","reset","isSifAllowed","encryptionEnabledMap","BaseFrameCryptor","encodeFunction","encodedFrame","controller","decodeFunction","FrameCryptor","opts","sendCounts","rtpMap","keyProviderOptions","sifTrailer","from","sifGuard","participant","mediaTrackId","trackId","fallbackCodec","videoCodec","setParticipant","unsetParticipant","getParticipantIdentity","getTrackId","setVideoCodec","codec","setRtpMap","setupTransform","operation","readable","writable","passedTrackId","transformFn","transformStream","TransformStream","transform","pipeThrough","pipeTo","setSifTrailer","trailer","enqueue","keySet","getKeySet","getCurrentKeyIndex","MissingKey","keyIndex","iv","makeIV","getMetadata","synchronizationSource","timestamp","frameInfo","getUnencryptedBytes","frameHeader","unencryptedBytes","frameTrailer","cipherText","encrypt","additionalData","newDataWithoutHeader","isH264","data_in","dataOut","numConsecutiveZeros","writeRbsp","newData","frameData","trailerBytes","isFrameServerInjected","hasValidKey","decodedFrame","decryptFrame","decryptionSuccess","InvalidKey","decryptionFailure","encodedFrame_1","keyIndex_1","_this","initialMaterial","ratchetOpts","ratchetCount","encryptedData","needsRbspUnescaping","stream","parseRbsp","newUint8","ivLength","cipherTextStart","cipherTextLength","plainText","decrypt","ratchetedKeySet","RTCEncodedAudioFrame","newMaterial","ratchetKey","frame","setKeySet","setCurrentKeyIndex","ivView","random","sendCount","isVideoFrame","detectedCodec","getVideoCodec","oldCodec","naluIndices","searchLength","findNALUIndices","naluIndex","NALUType","SLICE_IDR","SLICE_NON_IDR","parseNALUType","size","payloadType","startByte","kNaluTypeMask","ParticipantKeyHandler","_hasValidKey","decryptionFailureCount","currentKeyIndex","cryptoKeyRing","fill","ratchetPromiseMap","resetKeyStatus","setKey","existingPromise","ratchetPromise","__awaiter","currentMaterial","keyBytes_1","keyBytes","usage","importKey","deriveBits","ratchet","setKeyFromMaterial","KeyRatcheted","delete","material_1","_this2","emitRatchetEvent","newIndex","usages","participantCryptors","participantKeys","sharedKeyHandler","messageQueue","pendingTasks","taskMutex","nextTaskIndex","run","task","taskInfo","enqueuedAt","status","WAITING","unlock","executedAt","RUNNING","COMPLETED","flush","snapshot","useSharedKey","getTrackCryptor","cryptors","debugInfo","participants","cryptor","getParticipantKeyHandler","postMessage","setupCryptorErrorEvents","getSharedKeyHandler","emitRatchetedKeys","onmessage","ev","loglevel","readableStream","writableStream","setSharedKey","unsetCryptorParticipant","cr","keyHandler","handleRatchetRequest","RTCTransformEvent","onrtctransform","event","transformer","handled"],"mappings":"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","x_google_ignoreList":[0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,30]}
|