@pulsebeam/peer 0.0.15 → 0.0.17
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +44 -9
- package/dist/index.cjs +22 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -38
- package/dist/index.d.ts +23 -38
- package/dist/index.js +22 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../node_modules/sdp/sdp.js","../index.ts","../../node_modules/webrtc-adapter/src/js/utils.js","../../node_modules/webrtc-adapter/src/js/chrome/chrome_shim.js","../../node_modules/webrtc-adapter/src/js/chrome/getusermedia.js","../../node_modules/webrtc-adapter/src/js/firefox/firefox_shim.js","../../node_modules/webrtc-adapter/src/js/firefox/getusermedia.js","../../node_modules/webrtc-adapter/src/js/firefox/getdisplaymedia.js","../../node_modules/webrtc-adapter/src/js/safari/safari_shim.js","../../node_modules/webrtc-adapter/src/js/common_shim.js","../../node_modules/webrtc-adapter/src/js/adapter_factory.js","../../node_modules/webrtc-adapter/src/js/adapter_core.js","../tunnel.ts","../tunnel.client.ts","../util.ts","../transport.ts","../logger.ts","../session.ts","../peer.ts"],"sourcesContent":["/* eslint-env node */\n'use strict';\n\n// SDP helpers.\nconst SDPUtils = {};\n\n// Generate an alphanumeric identifier for cname or mids.\n// TODO: use UUIDs instead? https://gist.github.com/jed/982883\nSDPUtils.generateIdentifier = function() {\n return Math.random().toString(36).substring(2, 12);\n};\n\n// The RTCP CNAME used by all peerconnections from the same JS.\nSDPUtils.localCName = SDPUtils.generateIdentifier();\n\n// Splits SDP into lines, dealing with both CRLF and LF.\nSDPUtils.splitLines = function(blob) {\n return blob.trim().split('\\n').map(line => line.trim());\n};\n// Splits SDP into sessionpart and mediasections. Ensures CRLF.\nSDPUtils.splitSections = function(blob) {\n const parts = blob.split('\\nm=');\n return parts.map((part, index) => (index > 0 ?\n 'm=' + part : part).trim() + '\\r\\n');\n};\n\n// Returns the session description.\nSDPUtils.getDescription = function(blob) {\n const sections = SDPUtils.splitSections(blob);\n return sections && sections[0];\n};\n\n// Returns the individual media sections.\nSDPUtils.getMediaSections = function(blob) {\n const sections = SDPUtils.splitSections(blob);\n sections.shift();\n return sections;\n};\n\n// Returns lines that start with a certain prefix.\nSDPUtils.matchPrefix = function(blob, prefix) {\n return SDPUtils.splitLines(blob).filter(line => line.indexOf(prefix) === 0);\n};\n\n// Parses an ICE candidate line. Sample input:\n// candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8\n// rport 55996\"\n// Input can be prefixed with a=.\nSDPUtils.parseCandidate = function(line) {\n let parts;\n // Parse both variants.\n if (line.indexOf('a=candidate:') === 0) {\n parts = line.substring(12).split(' ');\n } else {\n parts = line.substring(10).split(' ');\n }\n\n const candidate = {\n foundation: parts[0],\n component: {1: 'rtp', 2: 'rtcp'}[parts[1]] || parts[1],\n protocol: parts[2].toLowerCase(),\n priority: parseInt(parts[3], 10),\n ip: parts[4],\n address: parts[4], // address is an alias for ip.\n port: parseInt(parts[5], 10),\n // skip parts[6] == 'typ'\n type: parts[7],\n };\n\n for (let i = 8; i < parts.length; i += 2) {\n switch (parts[i]) {\n case 'raddr':\n candidate.relatedAddress = parts[i + 1];\n break;\n case 'rport':\n candidate.relatedPort = parseInt(parts[i + 1], 10);\n break;\n case 'tcptype':\n candidate.tcpType = parts[i + 1];\n break;\n case 'ufrag':\n candidate.ufrag = parts[i + 1]; // for backward compatibility.\n candidate.usernameFragment = parts[i + 1];\n break;\n default: // extension handling, in particular ufrag. Don't overwrite.\n if (candidate[parts[i]] === undefined) {\n candidate[parts[i]] = parts[i + 1];\n }\n break;\n }\n }\n return candidate;\n};\n\n// Translates a candidate object into SDP candidate attribute.\n// This does not include the a= prefix!\nSDPUtils.writeCandidate = function(candidate) {\n const sdp = [];\n sdp.push(candidate.foundation);\n\n const component = candidate.component;\n if (component === 'rtp') {\n sdp.push(1);\n } else if (component === 'rtcp') {\n sdp.push(2);\n } else {\n sdp.push(component);\n }\n sdp.push(candidate.protocol.toUpperCase());\n sdp.push(candidate.priority);\n sdp.push(candidate.address || candidate.ip);\n sdp.push(candidate.port);\n\n const type = candidate.type;\n sdp.push('typ');\n sdp.push(type);\n if (type !== 'host' && candidate.relatedAddress &&\n candidate.relatedPort) {\n sdp.push('raddr');\n sdp.push(candidate.relatedAddress);\n sdp.push('rport');\n sdp.push(candidate.relatedPort);\n }\n if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {\n sdp.push('tcptype');\n sdp.push(candidate.tcpType);\n }\n if (candidate.usernameFragment || candidate.ufrag) {\n sdp.push('ufrag');\n sdp.push(candidate.usernameFragment || candidate.ufrag);\n }\n return 'candidate:' + sdp.join(' ');\n};\n\n// Parses an ice-options line, returns an array of option tags.\n// Sample input:\n// a=ice-options:foo bar\nSDPUtils.parseIceOptions = function(line) {\n return line.substring(14).split(' ');\n};\n\n// Parses a rtpmap line, returns RTCRtpCoddecParameters. Sample input:\n// a=rtpmap:111 opus/48000/2\nSDPUtils.parseRtpMap = function(line) {\n let parts = line.substring(9).split(' ');\n const parsed = {\n payloadType: parseInt(parts.shift(), 10), // was: id\n };\n\n parts = parts[0].split('/');\n\n parsed.name = parts[0];\n parsed.clockRate = parseInt(parts[1], 10); // was: clockrate\n parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1;\n // legacy alias, got renamed back to channels in ORTC.\n parsed.numChannels = parsed.channels;\n return parsed;\n};\n\n// Generates a rtpmap line from RTCRtpCodecCapability or\n// RTCRtpCodecParameters.\nSDPUtils.writeRtpMap = function(codec) {\n let pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n const channels = codec.channels || codec.numChannels || 1;\n return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate +\n (channels !== 1 ? '/' + channels : '') + '\\r\\n';\n};\n\n// Parses a extmap line (headerextension from RFC 5285). Sample input:\n// a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\n// a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset\nSDPUtils.parseExtmap = function(line) {\n const parts = line.substring(9).split(' ');\n return {\n id: parseInt(parts[0], 10),\n direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv',\n uri: parts[1],\n attributes: parts.slice(2).join(' '),\n };\n};\n\n// Generates an extmap line from RTCRtpHeaderExtensionParameters or\n// RTCRtpHeaderExtension.\nSDPUtils.writeExtmap = function(headerExtension) {\n return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) +\n (headerExtension.direction && headerExtension.direction !== 'sendrecv'\n ? '/' + headerExtension.direction\n : '') +\n ' ' + headerExtension.uri +\n (headerExtension.attributes ? ' ' + headerExtension.attributes : '') +\n '\\r\\n';\n};\n\n// Parses a fmtp line, returns dictionary. Sample input:\n// a=fmtp:96 vbr=on;cng=on\n// Also deals with vbr=on; cng=on\nSDPUtils.parseFmtp = function(line) {\n const parsed = {};\n let kv;\n const parts = line.substring(line.indexOf(' ') + 1).split(';');\n for (let j = 0; j < parts.length; j++) {\n kv = parts[j].trim().split('=');\n parsed[kv[0].trim()] = kv[1];\n }\n return parsed;\n};\n\n// Generates a fmtp line from RTCRtpCodecCapability or RTCRtpCodecParameters.\nSDPUtils.writeFmtp = function(codec) {\n let line = '';\n let pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n if (codec.parameters && Object.keys(codec.parameters).length) {\n const params = [];\n Object.keys(codec.parameters).forEach(param => {\n if (codec.parameters[param] !== undefined) {\n params.push(param + '=' + codec.parameters[param]);\n } else {\n params.push(param);\n }\n });\n line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\\r\\n';\n }\n return line;\n};\n\n// Parses a rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:\n// a=rtcp-fb:98 nack rpsi\nSDPUtils.parseRtcpFb = function(line) {\n const parts = line.substring(line.indexOf(' ') + 1).split(' ');\n return {\n type: parts.shift(),\n parameter: parts.join(' '),\n };\n};\n\n// Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.\nSDPUtils.writeRtcpFb = function(codec) {\n let lines = '';\n let pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n if (codec.rtcpFeedback && codec.rtcpFeedback.length) {\n // FIXME: special handling for trr-int?\n codec.rtcpFeedback.forEach(fb => {\n lines += 'a=rtcp-fb:' + pt + ' ' + fb.type +\n (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') +\n '\\r\\n';\n });\n }\n return lines;\n};\n\n// Parses a RFC 5576 ssrc media attribute. Sample input:\n// a=ssrc:3735928559 cname:something\nSDPUtils.parseSsrcMedia = function(line) {\n const sp = line.indexOf(' ');\n const parts = {\n ssrc: parseInt(line.substring(7, sp), 10),\n };\n const colon = line.indexOf(':', sp);\n if (colon > -1) {\n parts.attribute = line.substring(sp + 1, colon);\n parts.value = line.substring(colon + 1);\n } else {\n parts.attribute = line.substring(sp + 1);\n }\n return parts;\n};\n\n// Parse a ssrc-group line (see RFC 5576). Sample input:\n// a=ssrc-group:semantics 12 34\nSDPUtils.parseSsrcGroup = function(line) {\n const parts = line.substring(13).split(' ');\n return {\n semantics: parts.shift(),\n ssrcs: parts.map(ssrc => parseInt(ssrc, 10)),\n };\n};\n\n// Extracts the MID (RFC 5888) from a media section.\n// Returns the MID or undefined if no mid line was found.\nSDPUtils.getMid = function(mediaSection) {\n const mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0];\n if (mid) {\n return mid.substring(6);\n }\n};\n\n// Parses a fingerprint line for DTLS-SRTP.\nSDPUtils.parseFingerprint = function(line) {\n const parts = line.substring(14).split(' ');\n return {\n algorithm: parts[0].toLowerCase(), // algorithm is case-sensitive in Edge.\n value: parts[1].toUpperCase(), // the definition is upper-case in RFC 4572.\n };\n};\n\n// Extracts DTLS parameters from SDP media section or sessionpart.\n// FIXME: for consistency with other functions this should only\n// get the fingerprint line as input. See also getIceParameters.\nSDPUtils.getDtlsParameters = function(mediaSection, sessionpart) {\n const lines = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=fingerprint:');\n // Note: a=setup line is ignored since we use the 'auto' role in Edge.\n return {\n role: 'auto',\n fingerprints: lines.map(SDPUtils.parseFingerprint),\n };\n};\n\n// Serializes DTLS parameters to SDP.\nSDPUtils.writeDtlsParameters = function(params, setupType) {\n let sdp = 'a=setup:' + setupType + '\\r\\n';\n params.fingerprints.forEach(fp => {\n sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\\r\\n';\n });\n return sdp;\n};\n\n// Parses a=crypto lines into\n// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#dictionary-rtcsrtpsdesparameters-members\nSDPUtils.parseCryptoLine = function(line) {\n const parts = line.substring(9).split(' ');\n return {\n tag: parseInt(parts[0], 10),\n cryptoSuite: parts[1],\n keyParams: parts[2],\n sessionParams: parts.slice(3),\n };\n};\n\nSDPUtils.writeCryptoLine = function(parameters) {\n return 'a=crypto:' + parameters.tag + ' ' +\n parameters.cryptoSuite + ' ' +\n (typeof parameters.keyParams === 'object'\n ? SDPUtils.writeCryptoKeyParams(parameters.keyParams)\n : parameters.keyParams) +\n (parameters.sessionParams ? ' ' + parameters.sessionParams.join(' ') : '') +\n '\\r\\n';\n};\n\n// Parses the crypto key parameters into\n// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#rtcsrtpkeyparam*\nSDPUtils.parseCryptoKeyParams = function(keyParams) {\n if (keyParams.indexOf('inline:') !== 0) {\n return null;\n }\n const parts = keyParams.substring(7).split('|');\n return {\n keyMethod: 'inline',\n keySalt: parts[0],\n lifeTime: parts[1],\n mkiValue: parts[2] ? parts[2].split(':')[0] : undefined,\n mkiLength: parts[2] ? parts[2].split(':')[1] : undefined,\n };\n};\n\nSDPUtils.writeCryptoKeyParams = function(keyParams) {\n return keyParams.keyMethod + ':'\n + keyParams.keySalt +\n (keyParams.lifeTime ? '|' + keyParams.lifeTime : '') +\n (keyParams.mkiValue && keyParams.mkiLength\n ? '|' + keyParams.mkiValue + ':' + keyParams.mkiLength\n : '');\n};\n\n// Extracts all SDES parameters.\nSDPUtils.getCryptoParameters = function(mediaSection, sessionpart) {\n const lines = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=crypto:');\n return lines.map(SDPUtils.parseCryptoLine);\n};\n\n// Parses ICE information from SDP media section or sessionpart.\n// FIXME: for consistency with other functions this should only\n// get the ice-ufrag and ice-pwd lines as input.\nSDPUtils.getIceParameters = function(mediaSection, sessionpart) {\n const ufrag = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=ice-ufrag:')[0];\n const pwd = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=ice-pwd:')[0];\n if (!(ufrag && pwd)) {\n return null;\n }\n return {\n usernameFragment: ufrag.substring(12),\n password: pwd.substring(10),\n };\n};\n\n// Serializes ICE parameters to SDP.\nSDPUtils.writeIceParameters = function(params) {\n let sdp = 'a=ice-ufrag:' + params.usernameFragment + '\\r\\n' +\n 'a=ice-pwd:' + params.password + '\\r\\n';\n if (params.iceLite) {\n sdp += 'a=ice-lite\\r\\n';\n }\n return sdp;\n};\n\n// Parses the SDP media section and returns RTCRtpParameters.\nSDPUtils.parseRtpParameters = function(mediaSection) {\n const description = {\n codecs: [],\n headerExtensions: [],\n fecMechanisms: [],\n rtcp: [],\n };\n const lines = SDPUtils.splitLines(mediaSection);\n const mline = lines[0].split(' ');\n description.profile = mline[2];\n for (let i = 3; i < mline.length; i++) { // find all codecs from mline[3..]\n const pt = mline[i];\n const rtpmapline = SDPUtils.matchPrefix(\n mediaSection, 'a=rtpmap:' + pt + ' ')[0];\n if (rtpmapline) {\n const codec = SDPUtils.parseRtpMap(rtpmapline);\n const fmtps = SDPUtils.matchPrefix(\n mediaSection, 'a=fmtp:' + pt + ' ');\n // Only the first a=fmtp:<pt> is considered.\n codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};\n codec.rtcpFeedback = SDPUtils.matchPrefix(\n mediaSection, 'a=rtcp-fb:' + pt + ' ')\n .map(SDPUtils.parseRtcpFb);\n description.codecs.push(codec);\n // parse FEC mechanisms from rtpmap lines.\n switch (codec.name.toUpperCase()) {\n case 'RED':\n case 'ULPFEC':\n description.fecMechanisms.push(codec.name.toUpperCase());\n break;\n default: // only RED and ULPFEC are recognized as FEC mechanisms.\n break;\n }\n }\n }\n SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(line => {\n description.headerExtensions.push(SDPUtils.parseExtmap(line));\n });\n const wildcardRtcpFb = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:* ')\n .map(SDPUtils.parseRtcpFb);\n description.codecs.forEach(codec => {\n wildcardRtcpFb.forEach(fb=> {\n const duplicate = codec.rtcpFeedback.find(existingFeedback => {\n return existingFeedback.type === fb.type &&\n existingFeedback.parameter === fb.parameter;\n });\n if (!duplicate) {\n codec.rtcpFeedback.push(fb);\n }\n });\n });\n // FIXME: parse rtcp.\n return description;\n};\n\n// Generates parts of the SDP media section describing the capabilities /\n// parameters.\nSDPUtils.writeRtpDescription = function(kind, caps) {\n let sdp = '';\n\n // Build the mline.\n sdp += 'm=' + kind + ' ';\n sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.\n sdp += ' ' + (caps.profile || 'UDP/TLS/RTP/SAVPF') + ' ';\n sdp += caps.codecs.map(codec => {\n if (codec.preferredPayloadType !== undefined) {\n return codec.preferredPayloadType;\n }\n return codec.payloadType;\n }).join(' ') + '\\r\\n';\n\n sdp += 'c=IN IP4 0.0.0.0\\r\\n';\n sdp += 'a=rtcp:9 IN IP4 0.0.0.0\\r\\n';\n\n // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.\n caps.codecs.forEach(codec => {\n sdp += SDPUtils.writeRtpMap(codec);\n sdp += SDPUtils.writeFmtp(codec);\n sdp += SDPUtils.writeRtcpFb(codec);\n });\n let maxptime = 0;\n caps.codecs.forEach(codec => {\n if (codec.maxptime > maxptime) {\n maxptime = codec.maxptime;\n }\n });\n if (maxptime > 0) {\n sdp += 'a=maxptime:' + maxptime + '\\r\\n';\n }\n\n if (caps.headerExtensions) {\n caps.headerExtensions.forEach(extension => {\n sdp += SDPUtils.writeExtmap(extension);\n });\n }\n // FIXME: write fecMechanisms.\n return sdp;\n};\n\n// Parses the SDP media section and returns an array of\n// RTCRtpEncodingParameters.\nSDPUtils.parseRtpEncodingParameters = function(mediaSection) {\n const encodingParameters = [];\n const description = SDPUtils.parseRtpParameters(mediaSection);\n const hasRed = description.fecMechanisms.indexOf('RED') !== -1;\n const hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1;\n\n // filter a=ssrc:... cname:, ignore PlanB-msid\n const ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(line => SDPUtils.parseSsrcMedia(line))\n .filter(parts => parts.attribute === 'cname');\n const primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;\n let secondarySsrc;\n\n const flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID')\n .map(line => {\n const parts = line.substring(17).split(' ');\n return parts.map(part => parseInt(part, 10));\n });\n if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {\n secondarySsrc = flows[0][1];\n }\n\n description.codecs.forEach(codec => {\n if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) {\n let encParam = {\n ssrc: primarySsrc,\n codecPayloadType: parseInt(codec.parameters.apt, 10),\n };\n if (primarySsrc && secondarySsrc) {\n encParam.rtx = {ssrc: secondarySsrc};\n }\n encodingParameters.push(encParam);\n if (hasRed) {\n encParam = JSON.parse(JSON.stringify(encParam));\n encParam.fec = {\n ssrc: primarySsrc,\n mechanism: hasUlpfec ? 'red+ulpfec' : 'red',\n };\n encodingParameters.push(encParam);\n }\n }\n });\n if (encodingParameters.length === 0 && primarySsrc) {\n encodingParameters.push({\n ssrc: primarySsrc,\n });\n }\n\n // we support both b=AS and b=TIAS but interpret AS as TIAS.\n let bandwidth = SDPUtils.matchPrefix(mediaSection, 'b=');\n if (bandwidth.length) {\n if (bandwidth[0].indexOf('b=TIAS:') === 0) {\n bandwidth = parseInt(bandwidth[0].substring(7), 10);\n } else if (bandwidth[0].indexOf('b=AS:') === 0) {\n // use formula from JSEP to convert b=AS to TIAS value.\n bandwidth = parseInt(bandwidth[0].substring(5), 10) * 1000 * 0.95\n - (50 * 40 * 8);\n } else {\n bandwidth = undefined;\n }\n encodingParameters.forEach(params => {\n params.maxBitrate = bandwidth;\n });\n }\n return encodingParameters;\n};\n\n// parses http://draft.ortc.org/#rtcrtcpparameters*\nSDPUtils.parseRtcpParameters = function(mediaSection) {\n const rtcpParameters = {};\n\n // Gets the first SSRC. Note that with RTX there might be multiple\n // SSRCs.\n const remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(line => SDPUtils.parseSsrcMedia(line))\n .filter(obj => obj.attribute === 'cname')[0];\n if (remoteSsrc) {\n rtcpParameters.cname = remoteSsrc.value;\n rtcpParameters.ssrc = remoteSsrc.ssrc;\n }\n\n // Edge uses the compound attribute instead of reducedSize\n // compound is !reducedSize\n const rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize');\n rtcpParameters.reducedSize = rsize.length > 0;\n rtcpParameters.compound = rsize.length === 0;\n\n // parses the rtcp-mux attrіbute.\n // Note that Edge does not support unmuxed RTCP.\n const mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux');\n rtcpParameters.mux = mux.length > 0;\n\n return rtcpParameters;\n};\n\nSDPUtils.writeRtcpParameters = function(rtcpParameters) {\n let sdp = '';\n if (rtcpParameters.reducedSize) {\n sdp += 'a=rtcp-rsize\\r\\n';\n }\n if (rtcpParameters.mux) {\n sdp += 'a=rtcp-mux\\r\\n';\n }\n if (rtcpParameters.ssrc !== undefined && rtcpParameters.cname) {\n sdp += 'a=ssrc:' + rtcpParameters.ssrc +\n ' cname:' + rtcpParameters.cname + '\\r\\n';\n }\n return sdp;\n};\n\n\n// parses either a=msid: or a=ssrc:... msid lines and returns\n// the id of the MediaStream and MediaStreamTrack.\nSDPUtils.parseMsid = function(mediaSection) {\n let parts;\n const spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:');\n if (spec.length === 1) {\n parts = spec[0].substring(7).split(' ');\n return {stream: parts[0], track: parts[1]};\n }\n const planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(line => SDPUtils.parseSsrcMedia(line))\n .filter(msidParts => msidParts.attribute === 'msid');\n if (planB.length > 0) {\n parts = planB[0].value.split(' ');\n return {stream: parts[0], track: parts[1]};\n }\n};\n\n// SCTP\n// parses draft-ietf-mmusic-sctp-sdp-26 first and falls back\n// to draft-ietf-mmusic-sctp-sdp-05\nSDPUtils.parseSctpDescription = function(mediaSection) {\n const mline = SDPUtils.parseMLine(mediaSection);\n const maxSizeLine = SDPUtils.matchPrefix(mediaSection, 'a=max-message-size:');\n let maxMessageSize;\n if (maxSizeLine.length > 0) {\n maxMessageSize = parseInt(maxSizeLine[0].substring(19), 10);\n }\n if (isNaN(maxMessageSize)) {\n maxMessageSize = 65536;\n }\n const sctpPort = SDPUtils.matchPrefix(mediaSection, 'a=sctp-port:');\n if (sctpPort.length > 0) {\n return {\n port: parseInt(sctpPort[0].substring(12), 10),\n protocol: mline.fmt,\n maxMessageSize,\n };\n }\n const sctpMapLines = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:');\n if (sctpMapLines.length > 0) {\n const parts = sctpMapLines[0]\n .substring(10)\n .split(' ');\n return {\n port: parseInt(parts[0], 10),\n protocol: parts[1],\n maxMessageSize,\n };\n }\n};\n\n// SCTP\n// outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers\n// support by now receiving in this format, unless we originally parsed\n// as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line\n// protocol of DTLS/SCTP -- without UDP/ or TCP/)\nSDPUtils.writeSctpDescription = function(media, sctp) {\n let output = [];\n if (media.protocol !== 'DTLS/SCTP') {\n output = [\n 'm=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.protocol + '\\r\\n',\n 'c=IN IP4 0.0.0.0\\r\\n',\n 'a=sctp-port:' + sctp.port + '\\r\\n',\n ];\n } else {\n output = [\n 'm=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.port + '\\r\\n',\n 'c=IN IP4 0.0.0.0\\r\\n',\n 'a=sctpmap:' + sctp.port + ' ' + sctp.protocol + ' 65535\\r\\n',\n ];\n }\n if (sctp.maxMessageSize !== undefined) {\n output.push('a=max-message-size:' + sctp.maxMessageSize + '\\r\\n');\n }\n return output.join('');\n};\n\n// Generate a session ID for SDP.\n// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1\n// recommends using a cryptographically random +ve 64-bit value\n// but right now this should be acceptable and within the right range\nSDPUtils.generateSessionId = function() {\n return Math.random().toString().substr(2, 22);\n};\n\n// Write boiler plate for start of SDP\n// sessId argument is optional - if not supplied it will\n// be generated randomly\n// sessVersion is optional and defaults to 2\n// sessUser is optional and defaults to 'thisisadapterortc'\nSDPUtils.writeSessionBoilerplate = function(sessId, sessVer, sessUser) {\n let sessionId;\n const version = sessVer !== undefined ? sessVer : 2;\n if (sessId) {\n sessionId = sessId;\n } else {\n sessionId = SDPUtils.generateSessionId();\n }\n const user = sessUser || 'thisisadapterortc';\n // FIXME: sess-id should be an NTP timestamp.\n return 'v=0\\r\\n' +\n 'o=' + user + ' ' + sessionId + ' ' + version +\n ' IN IP4 127.0.0.1\\r\\n' +\n 's=-\\r\\n' +\n 't=0 0\\r\\n';\n};\n\n// Gets the direction from the mediaSection or the sessionpart.\nSDPUtils.getDirection = function(mediaSection, sessionpart) {\n // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.\n const lines = SDPUtils.splitLines(mediaSection);\n for (let i = 0; i < lines.length; i++) {\n switch (lines[i]) {\n case 'a=sendrecv':\n case 'a=sendonly':\n case 'a=recvonly':\n case 'a=inactive':\n return lines[i].substring(2);\n default:\n // FIXME: What should happen here?\n }\n }\n if (sessionpart) {\n return SDPUtils.getDirection(sessionpart);\n }\n return 'sendrecv';\n};\n\nSDPUtils.getKind = function(mediaSection) {\n const lines = SDPUtils.splitLines(mediaSection);\n const mline = lines[0].split(' ');\n return mline[0].substring(2);\n};\n\nSDPUtils.isRejected = function(mediaSection) {\n return mediaSection.split(' ', 2)[1] === '0';\n};\n\nSDPUtils.parseMLine = function(mediaSection) {\n const lines = SDPUtils.splitLines(mediaSection);\n const parts = lines[0].substring(2).split(' ');\n return {\n kind: parts[0],\n port: parseInt(parts[1], 10),\n protocol: parts[2],\n fmt: parts.slice(3).join(' '),\n };\n};\n\nSDPUtils.parseOLine = function(mediaSection) {\n const line = SDPUtils.matchPrefix(mediaSection, 'o=')[0];\n const parts = line.substring(2).split(' ');\n return {\n username: parts[0],\n sessionId: parts[1],\n sessionVersion: parseInt(parts[2], 10),\n netType: parts[3],\n addressType: parts[4],\n address: parts[5],\n };\n};\n\n// a very naive interpretation of a valid SDP.\nSDPUtils.isValidSDP = function(blob) {\n if (typeof blob !== 'string' || blob.length === 0) {\n return false;\n }\n const lines = SDPUtils.splitLines(blob);\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].length < 2 || lines[i].charAt(1) !== '=') {\n return false;\n }\n // TODO: check the modifier a bit more.\n }\n return true;\n};\n\n// Expose public methods.\nif (typeof module === 'object') {\n module.exports = SDPUtils;\n}\n","import adapter from \"webrtc-adapter\";\nexport * from \"./peer.ts\";\n\nadapter.disableLog(false);\nadapter.disableWarnings(false);\nconsole.log(\"UA: \", navigator.userAgent);\nconsole.log(\"webrtc-adapter is enabled\", JSON.stringify({ shim: adapter.browserShim, version: adapter.browserDetails }, null, 2));\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n'use strict';\n\nlet logDisabled_ = true;\nlet deprecationWarnings_ = true;\n\n/**\n * Extract browser version out of the provided user agent string.\n *\n * @param {!string} uastring userAgent string.\n * @param {!string} expr Regular expression used as match criteria.\n * @param {!number} pos position in the version string to be returned.\n * @return {!number} browser version.\n */\nexport function extractVersion(uastring, expr, pos) {\n const match = uastring.match(expr);\n return match && match.length >= pos && parseInt(match[pos], 10);\n}\n\n// Wraps the peerconnection event eventNameToWrap in a function\n// which returns the modified event object (or false to prevent\n// the event).\nexport function wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) {\n if (!window.RTCPeerConnection) {\n return;\n }\n const proto = window.RTCPeerConnection.prototype;\n const nativeAddEventListener = proto.addEventListener;\n proto.addEventListener = function(nativeEventName, cb) {\n if (nativeEventName !== eventNameToWrap) {\n return nativeAddEventListener.apply(this, arguments);\n }\n const wrappedCallback = (e) => {\n const modifiedEvent = wrapper(e);\n if (modifiedEvent) {\n if (cb.handleEvent) {\n cb.handleEvent(modifiedEvent);\n } else {\n cb(modifiedEvent);\n }\n }\n };\n this._eventMap = this._eventMap || {};\n if (!this._eventMap[eventNameToWrap]) {\n this._eventMap[eventNameToWrap] = new Map();\n }\n this._eventMap[eventNameToWrap].set(cb, wrappedCallback);\n return nativeAddEventListener.apply(this, [nativeEventName,\n wrappedCallback]);\n };\n\n const nativeRemoveEventListener = proto.removeEventListener;\n proto.removeEventListener = function(nativeEventName, cb) {\n if (nativeEventName !== eventNameToWrap || !this._eventMap\n || !this._eventMap[eventNameToWrap]) {\n return nativeRemoveEventListener.apply(this, arguments);\n }\n if (!this._eventMap[eventNameToWrap].has(cb)) {\n return nativeRemoveEventListener.apply(this, arguments);\n }\n const unwrappedCb = this._eventMap[eventNameToWrap].get(cb);\n this._eventMap[eventNameToWrap].delete(cb);\n if (this._eventMap[eventNameToWrap].size === 0) {\n delete this._eventMap[eventNameToWrap];\n }\n if (Object.keys(this._eventMap).length === 0) {\n delete this._eventMap;\n }\n return nativeRemoveEventListener.apply(this, [nativeEventName,\n unwrappedCb]);\n };\n\n Object.defineProperty(proto, 'on' + eventNameToWrap, {\n get() {\n return this['_on' + eventNameToWrap];\n },\n set(cb) {\n if (this['_on' + eventNameToWrap]) {\n this.removeEventListener(eventNameToWrap,\n this['_on' + eventNameToWrap]);\n delete this['_on' + eventNameToWrap];\n }\n if (cb) {\n this.addEventListener(eventNameToWrap,\n this['_on' + eventNameToWrap] = cb);\n }\n },\n enumerable: true,\n configurable: true\n });\n}\n\nexport function disableLog(bool) {\n if (typeof bool !== 'boolean') {\n return new Error('Argument type: ' + typeof bool +\n '. Please use a boolean.');\n }\n logDisabled_ = bool;\n return (bool) ? 'adapter.js logging disabled' :\n 'adapter.js logging enabled';\n}\n\n/**\n * Disable or enable deprecation warnings\n * @param {!boolean} bool set to true to disable warnings.\n */\nexport function disableWarnings(bool) {\n if (typeof bool !== 'boolean') {\n return new Error('Argument type: ' + typeof bool +\n '. Please use a boolean.');\n }\n deprecationWarnings_ = !bool;\n return 'adapter.js deprecation warnings ' + (bool ? 'disabled' : 'enabled');\n}\n\nexport function log() {\n if (typeof window === 'object') {\n if (logDisabled_) {\n return;\n }\n if (typeof console !== 'undefined' && typeof console.log === 'function') {\n console.log.apply(console, arguments);\n }\n }\n}\n\n/**\n * Shows a deprecation warning suggesting the modern and spec-compatible API.\n */\nexport function deprecated(oldMethod, newMethod) {\n if (!deprecationWarnings_) {\n return;\n }\n console.warn(oldMethod + ' is deprecated, please use ' + newMethod +\n ' instead.');\n}\n\n/**\n * Browser detector.\n *\n * @return {object} result containing browser and version\n * properties.\n */\nexport function detectBrowser(window) {\n // Returned result object.\n const result = {browser: null, version: null};\n\n // Fail early if it's not a browser\n if (typeof window === 'undefined' || !window.navigator ||\n !window.navigator.userAgent) {\n result.browser = 'Not a browser.';\n return result;\n }\n\n const {navigator} = window;\n\n // Prefer navigator.userAgentData.\n if (navigator.userAgentData && navigator.userAgentData.brands) {\n const chromium = navigator.userAgentData.brands.find((brand) => {\n return brand.brand === 'Chromium';\n });\n if (chromium) {\n return {browser: 'chrome', version: parseInt(chromium.version, 10)};\n }\n }\n\n if (navigator.mozGetUserMedia) { // Firefox.\n result.browser = 'firefox';\n result.version = extractVersion(navigator.userAgent,\n /Firefox\\/(\\d+)\\./, 1);\n } else if (navigator.webkitGetUserMedia ||\n (window.isSecureContext === false && window.webkitRTCPeerConnection)) {\n // Chrome, Chromium, Webview, Opera.\n // Version matches Chrome/WebRTC version.\n // Chrome 74 removed webkitGetUserMedia on http as well so we need the\n // more complicated fallback to webkitRTCPeerConnection.\n result.browser = 'chrome';\n result.version = extractVersion(navigator.userAgent,\n /Chrom(e|ium)\\/(\\d+)\\./, 2);\n } else if (window.RTCPeerConnection &&\n navigator.userAgent.match(/AppleWebKit\\/(\\d+)\\./)) { // Safari.\n result.browser = 'safari';\n result.version = extractVersion(navigator.userAgent,\n /AppleWebKit\\/(\\d+)\\./, 1);\n result.supportsUnifiedPlan = window.RTCRtpTransceiver &&\n 'currentDirection' in window.RTCRtpTransceiver.prototype;\n } else { // Default fallthrough: not supported.\n result.browser = 'Not a supported browser.';\n return result;\n }\n\n return result;\n}\n\n/**\n * Checks if something is an object.\n *\n * @param {*} val The something you want to check.\n * @return true if val is an object, false otherwise.\n */\nfunction isObject(val) {\n return Object.prototype.toString.call(val) === '[object Object]';\n}\n\n/**\n * Remove all empty objects and undefined values\n * from a nested object -- an enhanced and vanilla version\n * of Lodash's `compact`.\n */\nexport function compactObject(data) {\n if (!isObject(data)) {\n return data;\n }\n\n return Object.keys(data).reduce(function(accumulator, key) {\n const isObj = isObject(data[key]);\n const value = isObj ? compactObject(data[key]) : data[key];\n const isEmptyObject = isObj && !Object.keys(value).length;\n if (value === undefined || isEmptyObject) {\n return accumulator;\n }\n return Object.assign(accumulator, {[key]: value});\n }, {});\n}\n\n/* iterates the stats graph recursively. */\nexport function walkStats(stats, base, resultSet) {\n if (!base || resultSet.has(base.id)) {\n return;\n }\n resultSet.set(base.id, base);\n Object.keys(base).forEach(name => {\n if (name.endsWith('Id')) {\n walkStats(stats, stats.get(base[name]), resultSet);\n } else if (name.endsWith('Ids')) {\n base[name].forEach(id => {\n walkStats(stats, stats.get(id), resultSet);\n });\n }\n });\n}\n\n/* filter getStats for a sender/receiver track. */\nexport function filterStats(result, track, outbound) {\n const streamStatsType = outbound ? 'outbound-rtp' : 'inbound-rtp';\n const filteredResult = new Map();\n if (track === null) {\n return filteredResult;\n }\n const trackStats = [];\n result.forEach(value => {\n if (value.type === 'track' &&\n value.trackIdentifier === track.id) {\n trackStats.push(value);\n }\n });\n trackStats.forEach(trackStat => {\n result.forEach(stats => {\n if (stats.type === streamStatsType && stats.trackId === trackStat.id) {\n walkStats(result, stats, filteredResult);\n }\n });\n });\n return filteredResult;\n}\n\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n'use strict';\nimport * as utils from '../utils.js';\n\nexport {shimGetUserMedia} from './getusermedia';\n\nexport function shimMediaStream(window) {\n window.MediaStream = window.MediaStream || window.webkitMediaStream;\n}\n\nexport function shimOnTrack(window) {\n if (typeof window === 'object' && window.RTCPeerConnection && !('ontrack' in\n window.RTCPeerConnection.prototype)) {\n Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', {\n get() {\n return this._ontrack;\n },\n set(f) {\n if (this._ontrack) {\n this.removeEventListener('track', this._ontrack);\n }\n this.addEventListener('track', this._ontrack = f);\n },\n enumerable: true,\n configurable: true\n });\n const origSetRemoteDescription =\n window.RTCPeerConnection.prototype.setRemoteDescription;\n window.RTCPeerConnection.prototype.setRemoteDescription =\n function setRemoteDescription() {\n if (!this._ontrackpoly) {\n this._ontrackpoly = (e) => {\n // onaddstream does not fire when a track is added to an existing\n // stream. But stream.onaddtrack is implemented so we use that.\n e.stream.addEventListener('addtrack', te => {\n let receiver;\n if (window.RTCPeerConnection.prototype.getReceivers) {\n receiver = this.getReceivers()\n .find(r => r.track && r.track.id === te.track.id);\n } else {\n receiver = {track: te.track};\n }\n\n const event = new Event('track');\n event.track = te.track;\n event.receiver = receiver;\n event.transceiver = {receiver};\n event.streams = [e.stream];\n this.dispatchEvent(event);\n });\n e.stream.getTracks().forEach(track => {\n let receiver;\n if (window.RTCPeerConnection.prototype.getReceivers) {\n receiver = this.getReceivers()\n .find(r => r.track && r.track.id === track.id);\n } else {\n receiver = {track};\n }\n const event = new Event('track');\n event.track = track;\n event.receiver = receiver;\n event.transceiver = {receiver};\n event.streams = [e.stream];\n this.dispatchEvent(event);\n });\n };\n this.addEventListener('addstream', this._ontrackpoly);\n }\n return origSetRemoteDescription.apply(this, arguments);\n };\n } else {\n // even if RTCRtpTransceiver is in window, it is only used and\n // emitted in unified-plan. Unfortunately this means we need\n // to unconditionally wrap the event.\n utils.wrapPeerConnectionEvent(window, 'track', e => {\n if (!e.transceiver) {\n Object.defineProperty(e, 'transceiver',\n {value: {receiver: e.receiver}});\n }\n return e;\n });\n }\n}\n\nexport function shimGetSendersWithDtmf(window) {\n // Overrides addTrack/removeTrack, depends on shimAddTrackRemoveTrack.\n if (typeof window === 'object' && window.RTCPeerConnection &&\n !('getSenders' in window.RTCPeerConnection.prototype) &&\n 'createDTMFSender' in window.RTCPeerConnection.prototype) {\n const shimSenderWithDtmf = function(pc, track) {\n return {\n track,\n get dtmf() {\n if (this._dtmf === undefined) {\n if (track.kind === 'audio') {\n this._dtmf = pc.createDTMFSender(track);\n } else {\n this._dtmf = null;\n }\n }\n return this._dtmf;\n },\n _pc: pc\n };\n };\n\n // augment addTrack when getSenders is not available.\n if (!window.RTCPeerConnection.prototype.getSenders) {\n window.RTCPeerConnection.prototype.getSenders = function getSenders() {\n this._senders = this._senders || [];\n return this._senders.slice(); // return a copy of the internal state.\n };\n const origAddTrack = window.RTCPeerConnection.prototype.addTrack;\n window.RTCPeerConnection.prototype.addTrack =\n function addTrack(track, stream) {\n let sender = origAddTrack.apply(this, arguments);\n if (!sender) {\n sender = shimSenderWithDtmf(this, track);\n this._senders.push(sender);\n }\n return sender;\n };\n\n const origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;\n window.RTCPeerConnection.prototype.removeTrack =\n function removeTrack(sender) {\n origRemoveTrack.apply(this, arguments);\n const idx = this._senders.indexOf(sender);\n if (idx !== -1) {\n this._senders.splice(idx, 1);\n }\n };\n }\n const origAddStream = window.RTCPeerConnection.prototype.addStream;\n window.RTCPeerConnection.prototype.addStream = function addStream(stream) {\n this._senders = this._senders || [];\n origAddStream.apply(this, [stream]);\n stream.getTracks().forEach(track => {\n this._senders.push(shimSenderWithDtmf(this, track));\n });\n };\n\n const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;\n window.RTCPeerConnection.prototype.removeStream =\n function removeStream(stream) {\n this._senders = this._senders || [];\n origRemoveStream.apply(this, [stream]);\n\n stream.getTracks().forEach(track => {\n const sender = this._senders.find(s => s.track === track);\n if (sender) { // remove sender\n this._senders.splice(this._senders.indexOf(sender), 1);\n }\n });\n };\n } else if (typeof window === 'object' && window.RTCPeerConnection &&\n 'getSenders' in window.RTCPeerConnection.prototype &&\n 'createDTMFSender' in window.RTCPeerConnection.prototype &&\n window.RTCRtpSender &&\n !('dtmf' in window.RTCRtpSender.prototype)) {\n const origGetSenders = window.RTCPeerConnection.prototype.getSenders;\n window.RTCPeerConnection.prototype.getSenders = function getSenders() {\n const senders = origGetSenders.apply(this, []);\n senders.forEach(sender => sender._pc = this);\n return senders;\n };\n\n Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', {\n get() {\n if (this._dtmf === undefined) {\n if (this.track.kind === 'audio') {\n this._dtmf = this._pc.createDTMFSender(this.track);\n } else {\n this._dtmf = null;\n }\n }\n return this._dtmf;\n }\n });\n }\n}\n\nexport function shimSenderReceiverGetStats(window) {\n if (!(typeof window === 'object' && window.RTCPeerConnection &&\n window.RTCRtpSender && window.RTCRtpReceiver)) {\n return;\n }\n\n // shim sender stats.\n if (!('getStats' in window.RTCRtpSender.prototype)) {\n const origGetSenders = window.RTCPeerConnection.prototype.getSenders;\n if (origGetSenders) {\n window.RTCPeerConnection.prototype.getSenders = function getSenders() {\n const senders = origGetSenders.apply(this, []);\n senders.forEach(sender => sender._pc = this);\n return senders;\n };\n }\n\n const origAddTrack = window.RTCPeerConnection.prototype.addTrack;\n if (origAddTrack) {\n window.RTCPeerConnection.prototype.addTrack = function addTrack() {\n const sender = origAddTrack.apply(this, arguments);\n sender._pc = this;\n return sender;\n };\n }\n window.RTCRtpSender.prototype.getStats = function getStats() {\n const sender = this;\n return this._pc.getStats().then(result =>\n /* Note: this will include stats of all senders that\n * send a track with the same id as sender.track as\n * it is not possible to identify the RTCRtpSender.\n */\n utils.filterStats(result, sender.track, true));\n };\n }\n\n // shim receiver stats.\n if (!('getStats' in window.RTCRtpReceiver.prototype)) {\n const origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;\n if (origGetReceivers) {\n window.RTCPeerConnection.prototype.getReceivers =\n function getReceivers() {\n const receivers = origGetReceivers.apply(this, []);\n receivers.forEach(receiver => receiver._pc = this);\n return receivers;\n };\n }\n utils.wrapPeerConnectionEvent(window, 'track', e => {\n e.receiver._pc = e.srcElement;\n return e;\n });\n window.RTCRtpReceiver.prototype.getStats = function getStats() {\n const receiver = this;\n return this._pc.getStats().then(result =>\n utils.filterStats(result, receiver.track, false));\n };\n }\n\n if (!('getStats' in window.RTCRtpSender.prototype &&\n 'getStats' in window.RTCRtpReceiver.prototype)) {\n return;\n }\n\n // shim RTCPeerConnection.getStats(track).\n const origGetStats = window.RTCPeerConnection.prototype.getStats;\n window.RTCPeerConnection.prototype.getStats = function getStats() {\n if (arguments.length > 0 &&\n arguments[0] instanceof window.MediaStreamTrack) {\n const track = arguments[0];\n let sender;\n let receiver;\n let err;\n this.getSenders().forEach(s => {\n if (s.track === track) {\n if (sender) {\n err = true;\n } else {\n sender = s;\n }\n }\n });\n this.getReceivers().forEach(r => {\n if (r.track === track) {\n if (receiver) {\n err = true;\n } else {\n receiver = r;\n }\n }\n return r.track === track;\n });\n if (err || (sender && receiver)) {\n return Promise.reject(new DOMException(\n 'There are more than one sender or receiver for the track.',\n 'InvalidAccessError'));\n } else if (sender) {\n return sender.getStats();\n } else if (receiver) {\n return receiver.getStats();\n }\n return Promise.reject(new DOMException(\n 'There is no sender or receiver for the track.',\n 'InvalidAccessError'));\n }\n return origGetStats.apply(this, arguments);\n };\n}\n\nexport function shimAddTrackRemoveTrackWithNative(window) {\n // shim addTrack/removeTrack with native variants in order to make\n // the interactions with legacy getLocalStreams behave as in other browsers.\n // Keeps a mapping stream.id => [stream, rtpsenders...]\n window.RTCPeerConnection.prototype.getLocalStreams =\n function getLocalStreams() {\n this._shimmedLocalStreams = this._shimmedLocalStreams || {};\n return Object.keys(this._shimmedLocalStreams)\n .map(streamId => this._shimmedLocalStreams[streamId][0]);\n };\n\n const origAddTrack = window.RTCPeerConnection.prototype.addTrack;\n window.RTCPeerConnection.prototype.addTrack =\n function addTrack(track, stream) {\n if (!stream) {\n return origAddTrack.apply(this, arguments);\n }\n this._shimmedLocalStreams = this._shimmedLocalStreams || {};\n\n const sender = origAddTrack.apply(this, arguments);\n if (!this._shimmedLocalStreams[stream.id]) {\n this._shimmedLocalStreams[stream.id] = [stream, sender];\n } else if (this._shimmedLocalStreams[stream.id].indexOf(sender) === -1) {\n this._shimmedLocalStreams[stream.id].push(sender);\n }\n return sender;\n };\n\n const origAddStream = window.RTCPeerConnection.prototype.addStream;\n window.RTCPeerConnection.prototype.addStream = function addStream(stream) {\n this._shimmedLocalStreams = this._shimmedLocalStreams || {};\n\n stream.getTracks().forEach(track => {\n const alreadyExists = this.getSenders().find(s => s.track === track);\n if (alreadyExists) {\n throw new DOMException('Track already exists.',\n 'InvalidAccessError');\n }\n });\n const existingSenders = this.getSenders();\n origAddStream.apply(this, arguments);\n const newSenders = this.getSenders()\n .filter(newSender => existingSenders.indexOf(newSender) === -1);\n this._shimmedLocalStreams[stream.id] = [stream].concat(newSenders);\n };\n\n const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;\n window.RTCPeerConnection.prototype.removeStream =\n function removeStream(stream) {\n this._shimmedLocalStreams = this._shimmedLocalStreams || {};\n delete this._shimmedLocalStreams[stream.id];\n return origRemoveStream.apply(this, arguments);\n };\n\n const origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;\n window.RTCPeerConnection.prototype.removeTrack =\n function removeTrack(sender) {\n this._shimmedLocalStreams = this._shimmedLocalStreams || {};\n if (sender) {\n Object.keys(this._shimmedLocalStreams).forEach(streamId => {\n const idx = this._shimmedLocalStreams[streamId].indexOf(sender);\n if (idx !== -1) {\n this._shimmedLocalStreams[streamId].splice(idx, 1);\n }\n if (this._shimmedLocalStreams[streamId].length === 1) {\n delete this._shimmedLocalStreams[streamId];\n }\n });\n }\n return origRemoveTrack.apply(this, arguments);\n };\n}\n\nexport function shimAddTrackRemoveTrack(window, browserDetails) {\n if (!window.RTCPeerConnection) {\n return;\n }\n // shim addTrack and removeTrack.\n if (window.RTCPeerConnection.prototype.addTrack &&\n browserDetails.version >= 65) {\n return shimAddTrackRemoveTrackWithNative(window);\n }\n\n // also shim pc.getLocalStreams when addTrack is shimmed\n // to return the original streams.\n const origGetLocalStreams = window.RTCPeerConnection.prototype\n .getLocalStreams;\n window.RTCPeerConnection.prototype.getLocalStreams =\n function getLocalStreams() {\n const nativeStreams = origGetLocalStreams.apply(this);\n this._reverseStreams = this._reverseStreams || {};\n return nativeStreams.map(stream => this._reverseStreams[stream.id]);\n };\n\n const origAddStream = window.RTCPeerConnection.prototype.addStream;\n window.RTCPeerConnection.prototype.addStream = function addStream(stream) {\n this._streams = this._streams || {};\n this._reverseStreams = this._reverseStreams || {};\n\n stream.getTracks().forEach(track => {\n const alreadyExists = this.getSenders().find(s => s.track === track);\n if (alreadyExists) {\n throw new DOMException('Track already exists.',\n 'InvalidAccessError');\n }\n });\n // Add identity mapping for consistency with addTrack.\n // Unless this is being used with a stream from addTrack.\n if (!this._reverseStreams[stream.id]) {\n const newStream = new window.MediaStream(stream.getTracks());\n this._streams[stream.id] = newStream;\n this._reverseStreams[newStream.id] = stream;\n stream = newStream;\n }\n origAddStream.apply(this, [stream]);\n };\n\n const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;\n window.RTCPeerConnection.prototype.removeStream =\n function removeStream(stream) {\n this._streams = this._streams || {};\n this._reverseStreams = this._reverseStreams || {};\n\n origRemoveStream.apply(this, [(this._streams[stream.id] || stream)]);\n delete this._reverseStreams[(this._streams[stream.id] ?\n this._streams[stream.id].id : stream.id)];\n delete this._streams[stream.id];\n };\n\n window.RTCPeerConnection.prototype.addTrack =\n function addTrack(track, stream) {\n if (this.signalingState === 'closed') {\n throw new DOMException(\n 'The RTCPeerConnection\\'s signalingState is \\'closed\\'.',\n 'InvalidStateError');\n }\n const streams = [].slice.call(arguments, 1);\n if (streams.length !== 1 ||\n !streams[0].getTracks().find(t => t === track)) {\n // this is not fully correct but all we can manage without\n // [[associated MediaStreams]] internal slot.\n throw new DOMException(\n 'The adapter.js addTrack polyfill only supports a single ' +\n ' stream which is associated with the specified track.',\n 'NotSupportedError');\n }\n\n const alreadyExists = this.getSenders().find(s => s.track === track);\n if (alreadyExists) {\n throw new DOMException('Track already exists.',\n 'InvalidAccessError');\n }\n\n this._streams = this._streams || {};\n this._reverseStreams = this._reverseStreams || {};\n const oldStream = this._streams[stream.id];\n if (oldStream) {\n // this is using odd Chrome behaviour, use with caution:\n // https://bugs.chromium.org/p/webrtc/issues/detail?id=7815\n // Note: we rely on the high-level addTrack/dtmf shim to\n // create the sender with a dtmf sender.\n oldStream.addTrack(track);\n\n // Trigger ONN async.\n Promise.resolve().then(() => {\n this.dispatchEvent(new Event('negotiationneeded'));\n });\n } else {\n const newStream = new window.MediaStream([track]);\n this._streams[stream.id] = newStream;\n this._reverseStreams[newStream.id] = stream;\n this.addStream(newStream);\n }\n return this.getSenders().find(s => s.track === track);\n };\n\n // replace the internal stream id with the external one and\n // vice versa.\n function replaceInternalStreamId(pc, description) {\n let sdp = description.sdp;\n Object.keys(pc._reverseStreams || []).forEach(internalId => {\n const externalStream = pc._reverseStreams[internalId];\n const internalStream = pc._streams[externalStream.id];\n sdp = sdp.replace(new RegExp(internalStream.id, 'g'),\n externalStream.id);\n });\n return new RTCSessionDescription({\n type: description.type,\n sdp\n });\n }\n function replaceExternalStreamId(pc, description) {\n let sdp = description.sdp;\n Object.keys(pc._reverseStreams || []).forEach(internalId => {\n const externalStream = pc._reverseStreams[internalId];\n const internalStream = pc._streams[externalStream.id];\n sdp = sdp.replace(new RegExp(externalStream.id, 'g'),\n internalStream.id);\n });\n return new RTCSessionDescription({\n type: description.type,\n sdp\n });\n }\n ['createOffer', 'createAnswer'].forEach(function(method) {\n const nativeMethod = window.RTCPeerConnection.prototype[method];\n const methodObj = {[method]() {\n const args = arguments;\n const isLegacyCall = arguments.length &&\n typeof arguments[0] === 'function';\n if (isLegacyCall) {\n return nativeMethod.apply(this, [\n (description) => {\n const desc = replaceInternalStreamId(this, description);\n args[0].apply(null, [desc]);\n },\n (err) => {\n if (args[1]) {\n args[1].apply(null, err);\n }\n }, arguments[2]\n ]);\n }\n return nativeMethod.apply(this, arguments)\n .then(description => replaceInternalStreamId(this, description));\n }};\n window.RTCPeerConnection.prototype[method] = methodObj[method];\n });\n\n const origSetLocalDescription =\n window.RTCPeerConnection.prototype.setLocalDescription;\n window.RTCPeerConnection.prototype.setLocalDescription =\n function setLocalDescription() {\n if (!arguments.length || !arguments[0].type) {\n return origSetLocalDescription.apply(this, arguments);\n }\n arguments[0] = replaceExternalStreamId(this, arguments[0]);\n return origSetLocalDescription.apply(this, arguments);\n };\n\n // TODO: mangle getStats: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats-streamidentifier\n\n const origLocalDescription = Object.getOwnPropertyDescriptor(\n window.RTCPeerConnection.prototype, 'localDescription');\n Object.defineProperty(window.RTCPeerConnection.prototype,\n 'localDescription', {\n get() {\n const description = origLocalDescription.get.apply(this);\n if (description.type === '') {\n return description;\n }\n return replaceInternalStreamId(this, description);\n }\n });\n\n window.RTCPeerConnection.prototype.removeTrack =\n function removeTrack(sender) {\n if (this.signalingState === 'closed') {\n throw new DOMException(\n 'The RTCPeerConnection\\'s signalingState is \\'closed\\'.',\n 'InvalidStateError');\n }\n // We can not yet check for sender instanceof RTCRtpSender\n // since we shim RTPSender. So we check if sender._pc is set.\n if (!sender._pc) {\n throw new DOMException('Argument 1 of RTCPeerConnection.removeTrack ' +\n 'does not implement interface RTCRtpSender.', 'TypeError');\n }\n const isLocal = sender._pc === this;\n if (!isLocal) {\n throw new DOMException('Sender was not created by this connection.',\n 'InvalidAccessError');\n }\n\n // Search for the native stream the senders track belongs to.\n this._streams = this._streams || {};\n let stream;\n Object.keys(this._streams).forEach(streamid => {\n const hasTrack = this._streams[streamid].getTracks()\n .find(track => sender.track === track);\n if (hasTrack) {\n stream = this._streams[streamid];\n }\n });\n\n if (stream) {\n if (stream.getTracks().length === 1) {\n // if this is the last track of the stream, remove the stream. This\n // takes care of any shimmed _senders.\n this.removeStream(this._reverseStreams[stream.id]);\n } else {\n // relying on the same odd chrome behaviour as above.\n stream.removeTrack(sender.track);\n }\n this.dispatchEvent(new Event('negotiationneeded'));\n }\n };\n}\n\nexport function shimPeerConnection(window, browserDetails) {\n if (!window.RTCPeerConnection && window.webkitRTCPeerConnection) {\n // very basic support for old versions.\n window.RTCPeerConnection = window.webkitRTCPeerConnection;\n }\n if (!window.RTCPeerConnection) {\n return;\n }\n\n // shim implicit creation of RTCSessionDescription/RTCIceCandidate\n if (browserDetails.version < 53) {\n ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate']\n .forEach(function(method) {\n const nativeMethod = window.RTCPeerConnection.prototype[method];\n const methodObj = {[method]() {\n arguments[0] = new ((method === 'addIceCandidate') ?\n window.RTCIceCandidate :\n window.RTCSessionDescription)(arguments[0]);\n return nativeMethod.apply(this, arguments);\n }};\n window.RTCPeerConnection.prototype[method] = methodObj[method];\n });\n }\n}\n\n// Attempt to fix ONN in plan-b mode.\nexport function fixNegotiationNeeded(window, browserDetails) {\n utils.wrapPeerConnectionEvent(window, 'negotiationneeded', e => {\n const pc = e.target;\n if (browserDetails.version < 72 || (pc.getConfiguration &&\n pc.getConfiguration().sdpSemantics === 'plan-b')) {\n if (pc.signalingState !== 'stable') {\n return;\n }\n }\n return e;\n });\n}\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n'use strict';\nimport * as utils from '../utils.js';\nconst logging = utils.log;\n\nexport function shimGetUserMedia(window, browserDetails) {\n const navigator = window && window.navigator;\n\n if (!navigator.mediaDevices) {\n return;\n }\n\n const constraintsToChrome_ = function(c) {\n if (typeof c !== 'object' || c.mandatory || c.optional) {\n return c;\n }\n const cc = {};\n Object.keys(c).forEach(key => {\n if (key === 'require' || key === 'advanced' || key === 'mediaSource') {\n return;\n }\n const r = (typeof c[key] === 'object') ? c[key] : {ideal: c[key]};\n if (r.exact !== undefined && typeof r.exact === 'number') {\n r.min = r.max = r.exact;\n }\n const oldname_ = function(prefix, name) {\n if (prefix) {\n return prefix + name.charAt(0).toUpperCase() + name.slice(1);\n }\n return (name === 'deviceId') ? 'sourceId' : name;\n };\n if (r.ideal !== undefined) {\n cc.optional = cc.optional || [];\n let oc = {};\n if (typeof r.ideal === 'number') {\n oc[oldname_('min', key)] = r.ideal;\n cc.optional.push(oc);\n oc = {};\n oc[oldname_('max', key)] = r.ideal;\n cc.optional.push(oc);\n } else {\n oc[oldname_('', key)] = r.ideal;\n cc.optional.push(oc);\n }\n }\n if (r.exact !== undefined && typeof r.exact !== 'number') {\n cc.mandatory = cc.mandatory || {};\n cc.mandatory[oldname_('', key)] = r.exact;\n } else {\n ['min', 'max'].forEach(mix => {\n if (r[mix] !== undefined) {\n cc.mandatory = cc.mandatory || {};\n cc.mandatory[oldname_(mix, key)] = r[mix];\n }\n });\n }\n });\n if (c.advanced) {\n cc.optional = (cc.optional || []).concat(c.advanced);\n }\n return cc;\n };\n\n const shimConstraints_ = function(constraints, func) {\n if (browserDetails.version >= 61) {\n return func(constraints);\n }\n constraints = JSON.parse(JSON.stringify(constraints));\n if (constraints && typeof constraints.audio === 'object') {\n const remap = function(obj, a, b) {\n if (a in obj && !(b in obj)) {\n obj[b] = obj[a];\n delete obj[a];\n }\n };\n constraints = JSON.parse(JSON.stringify(constraints));\n remap(constraints.audio, 'autoGainControl', 'googAutoGainControl');\n remap(constraints.audio, 'noiseSuppression', 'googNoiseSuppression');\n constraints.audio = constraintsToChrome_(constraints.audio);\n }\n if (constraints && typeof constraints.video === 'object') {\n // Shim facingMode for mobile & surface pro.\n let face = constraints.video.facingMode;\n face = face && ((typeof face === 'object') ? face : {ideal: face});\n const getSupportedFacingModeLies = browserDetails.version < 66;\n\n if ((face && (face.exact === 'user' || face.exact === 'environment' ||\n face.ideal === 'user' || face.ideal === 'environment')) &&\n !(navigator.mediaDevices.getSupportedConstraints &&\n navigator.mediaDevices.getSupportedConstraints().facingMode &&\n !getSupportedFacingModeLies)) {\n delete constraints.video.facingMode;\n let matches;\n if (face.exact === 'environment' || face.ideal === 'environment') {\n matches = ['back', 'rear'];\n } else if (face.exact === 'user' || face.ideal === 'user') {\n matches = ['front'];\n }\n if (matches) {\n // Look for matches in label, or use last cam for back (typical).\n return navigator.mediaDevices.enumerateDevices()\n .then(devices => {\n devices = devices.filter(d => d.kind === 'videoinput');\n let dev = devices.find(d => matches.some(match =>\n d.label.toLowerCase().includes(match)));\n if (!dev && devices.length && matches.includes('back')) {\n dev = devices[devices.length - 1]; // more likely the back cam\n }\n if (dev) {\n constraints.video.deviceId = face.exact\n ? {exact: dev.deviceId}\n : {ideal: dev.deviceId};\n }\n constraints.video = constraintsToChrome_(constraints.video);\n logging('chrome: ' + JSON.stringify(constraints));\n return func(constraints);\n });\n }\n }\n constraints.video = constraintsToChrome_(constraints.video);\n }\n logging('chrome: ' + JSON.stringify(constraints));\n return func(constraints);\n };\n\n const shimError_ = function(e) {\n if (browserDetails.version >= 64) {\n return e;\n }\n return {\n name: {\n PermissionDeniedError: 'NotAllowedError',\n PermissionDismissedError: 'NotAllowedError',\n InvalidStateError: 'NotAllowedError',\n DevicesNotFoundError: 'NotFoundError',\n ConstraintNotSatisfiedError: 'OverconstrainedError',\n TrackStartError: 'NotReadableError',\n MediaDeviceFailedDueToShutdown: 'NotAllowedError',\n MediaDeviceKillSwitchOn: 'NotAllowedError',\n TabCaptureError: 'AbortError',\n ScreenCaptureError: 'AbortError',\n DeviceCaptureError: 'AbortError'\n }[e.name] || e.name,\n message: e.message,\n constraint: e.constraint || e.constraintName,\n toString() {\n return this.name + (this.message && ': ') + this.message;\n }\n };\n };\n\n const getUserMedia_ = function(constraints, onSuccess, onError) {\n shimConstraints_(constraints, c => {\n navigator.webkitGetUserMedia(c, onSuccess, e => {\n if (onError) {\n onError(shimError_(e));\n }\n });\n });\n };\n navigator.getUserMedia = getUserMedia_.bind(navigator);\n\n // Even though Chrome 45 has navigator.mediaDevices and a getUserMedia\n // function which returns a Promise, it does not accept spec-style\n // constraints.\n if (navigator.mediaDevices.getUserMedia) {\n const origGetUserMedia = navigator.mediaDevices.getUserMedia.\n bind(navigator.mediaDevices);\n navigator.mediaDevices.getUserMedia = function(cs) {\n return shimConstraints_(cs, c => origGetUserMedia(c).then(stream => {\n if (c.audio && !stream.getAudioTracks().length ||\n c.video && !stream.getVideoTracks().length) {\n stream.getTracks().forEach(track => {\n track.stop();\n });\n throw new DOMException('', 'NotFoundError');\n }\n return stream;\n }, e => Promise.reject(shimError_(e))));\n };\n }\n}\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n'use strict';\n\nimport * as utils from '../utils';\nexport {shimGetUserMedia} from './getusermedia';\nexport {shimGetDisplayMedia} from './getdisplaymedia';\n\nexport function shimOnTrack(window) {\n if (typeof window === 'object' && window.RTCTrackEvent &&\n ('receiver' in window.RTCTrackEvent.prototype) &&\n !('transceiver' in window.RTCTrackEvent.prototype)) {\n Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {\n get() {\n return {receiver: this.receiver};\n }\n });\n }\n}\n\nexport function shimPeerConnection(window, browserDetails) {\n if (typeof window !== 'object' ||\n !(window.RTCPeerConnection || window.mozRTCPeerConnection)) {\n return; // probably media.peerconnection.enabled=false in about:config\n }\n if (!window.RTCPeerConnection && window.mozRTCPeerConnection) {\n // very basic support for old versions.\n window.RTCPeerConnection = window.mozRTCPeerConnection;\n }\n\n if (browserDetails.version < 53) {\n // shim away need for obsolete RTCIceCandidate/RTCSessionDescription.\n ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate']\n .forEach(function(method) {\n const nativeMethod = window.RTCPeerConnection.prototype[method];\n const methodObj = {[method]() {\n arguments[0] = new ((method === 'addIceCandidate') ?\n window.RTCIceCandidate :\n window.RTCSessionDescription)(arguments[0]);\n return nativeMethod.apply(this, arguments);\n }};\n window.RTCPeerConnection.prototype[method] = methodObj[method];\n });\n }\n\n const modernStatsTypes = {\n inboundrtp: 'inbound-rtp',\n outboundrtp: 'outbound-rtp',\n candidatepair: 'candidate-pair',\n localcandidate: 'local-candidate',\n remotecandidate: 'remote-candidate'\n };\n\n const nativeGetStats = window.RTCPeerConnection.prototype.getStats;\n window.RTCPeerConnection.prototype.getStats = function getStats() {\n const [selector, onSucc, onErr] = arguments;\n return nativeGetStats.apply(this, [selector || null])\n .then(stats => {\n if (browserDetails.version < 53 && !onSucc) {\n // Shim only promise getStats with spec-hyphens in type names\n // Leave callback version alone; misc old uses of forEach before Map\n try {\n stats.forEach(stat => {\n stat.type = modernStatsTypes[stat.type] || stat.type;\n });\n } catch (e) {\n if (e.name !== 'TypeError') {\n throw e;\n }\n // Avoid TypeError: \"type\" is read-only, in old versions. 34-43ish\n stats.forEach((stat, i) => {\n stats.set(i, Object.assign({}, stat, {\n type: modernStatsTypes[stat.type] || stat.type\n }));\n });\n }\n }\n return stats;\n })\n .then(onSucc, onErr);\n };\n}\n\nexport function shimSenderGetStats(window) {\n if (!(typeof window === 'object' && window.RTCPeerConnection &&\n window.RTCRtpSender)) {\n return;\n }\n if (window.RTCRtpSender && 'getStats' in window.RTCRtpSender.prototype) {\n return;\n }\n const origGetSenders = window.RTCPeerConnection.prototype.getSenders;\n if (origGetSenders) {\n window.RTCPeerConnection.prototype.getSenders = function getSenders() {\n const senders = origGetSenders.apply(this, []);\n senders.forEach(sender => sender._pc = this);\n return senders;\n };\n }\n\n const origAddTrack = window.RTCPeerConnection.prototype.addTrack;\n if (origAddTrack) {\n window.RTCPeerConnection.prototype.addTrack = function addTrack() {\n const sender = origAddTrack.apply(this, arguments);\n sender._pc = this;\n return sender;\n };\n }\n window.RTCRtpSender.prototype.getStats = function getStats() {\n return this.track ? this._pc.getStats(this.track) :\n Promise.resolve(new Map());\n };\n}\n\nexport function shimReceiverGetStats(window) {\n if (!(typeof window === 'object' && window.RTCPeerConnection &&\n window.RTCRtpSender)) {\n return;\n }\n if (window.RTCRtpSender && 'getStats' in window.RTCRtpReceiver.prototype) {\n return;\n }\n const origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;\n if (origGetReceivers) {\n window.RTCPeerConnection.prototype.getReceivers = function getReceivers() {\n const receivers = origGetReceivers.apply(this, []);\n receivers.forEach(receiver => receiver._pc = this);\n return receivers;\n };\n }\n utils.wrapPeerConnectionEvent(window, 'track', e => {\n e.receiver._pc = e.srcElement;\n return e;\n });\n window.RTCRtpReceiver.prototype.getStats = function getStats() {\n return this._pc.getStats(this.track);\n };\n}\n\nexport function shimRemoveStream(window) {\n if (!window.RTCPeerConnection ||\n 'removeStream' in window.RTCPeerConnection.prototype) {\n return;\n }\n window.RTCPeerConnection.prototype.removeStream =\n function removeStream(stream) {\n utils.deprecated('removeStream', 'removeTrack');\n this.getSenders().forEach(sender => {\n if (sender.track && stream.getTracks().includes(sender.track)) {\n this.removeTrack(sender);\n }\n });\n };\n}\n\nexport function shimRTCDataChannel(window) {\n // rename DataChannel to RTCDataChannel (native fix in FF60):\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1173851\n if (window.DataChannel && !window.RTCDataChannel) {\n window.RTCDataChannel = window.DataChannel;\n }\n}\n\nexport function shimAddTransceiver(window) {\n // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647\n // Firefox ignores the init sendEncodings options passed to addTransceiver\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918\n if (!(typeof window === 'object' && window.RTCPeerConnection)) {\n return;\n }\n const origAddTransceiver = window.RTCPeerConnection.prototype.addTransceiver;\n if (origAddTransceiver) {\n window.RTCPeerConnection.prototype.addTransceiver =\n function addTransceiver() {\n this.setParametersPromises = [];\n // WebIDL input coercion and validation\n let sendEncodings = arguments[1] && arguments[1].sendEncodings;\n if (sendEncodings === undefined) {\n sendEncodings = [];\n }\n sendEncodings = [...sendEncodings];\n const shouldPerformCheck = sendEncodings.length > 0;\n if (shouldPerformCheck) {\n // If sendEncodings params are provided, validate grammar\n sendEncodings.forEach((encodingParam) => {\n if ('rid' in encodingParam) {\n const ridRegex = /^[a-z0-9]{0,16}$/i;\n if (!ridRegex.test(encodingParam.rid)) {\n throw new TypeError('Invalid RID value provided.');\n }\n }\n if ('scaleResolutionDownBy' in encodingParam) {\n if (!(parseFloat(encodingParam.scaleResolutionDownBy) >= 1.0)) {\n throw new RangeError('scale_resolution_down_by must be >= 1.0');\n }\n }\n if ('maxFramerate' in encodingParam) {\n if (!(parseFloat(encodingParam.maxFramerate) >= 0)) {\n throw new RangeError('max_framerate must be >= 0.0');\n }\n }\n });\n }\n const transceiver = origAddTransceiver.apply(this, arguments);\n if (shouldPerformCheck) {\n // Check if the init options were applied. If not we do this in an\n // asynchronous way and save the promise reference in a global object.\n // This is an ugly hack, but at the same time is way more robust than\n // checking the sender parameters before and after the createOffer\n // Also note that after the createoffer we are not 100% sure that\n // the params were asynchronously applied so we might miss the\n // opportunity to recreate offer.\n const {sender} = transceiver;\n const params = sender.getParameters();\n if (!('encodings' in params) ||\n // Avoid being fooled by patched getParameters() below.\n (params.encodings.length === 1 &&\n Object.keys(params.encodings[0]).length === 0)) {\n params.encodings = sendEncodings;\n sender.sendEncodings = sendEncodings;\n this.setParametersPromises.push(sender.setParameters(params)\n .then(() => {\n delete sender.sendEncodings;\n }).catch(() => {\n delete sender.sendEncodings;\n })\n );\n }\n }\n return transceiver;\n };\n }\n}\n\nexport function shimGetParameters(window) {\n if (!(typeof window === 'object' && window.RTCRtpSender)) {\n return;\n }\n const origGetParameters = window.RTCRtpSender.prototype.getParameters;\n if (origGetParameters) {\n window.RTCRtpSender.prototype.getParameters =\n function getParameters() {\n const params = origGetParameters.apply(this, arguments);\n if (!('encodings' in params)) {\n params.encodings = [].concat(this.sendEncodings || [{}]);\n }\n return params;\n };\n }\n}\n\nexport function shimCreateOffer(window) {\n // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647\n // Firefox ignores the init sendEncodings options passed to addTransceiver\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918\n if (!(typeof window === 'object' && window.RTCPeerConnection)) {\n return;\n }\n const origCreateOffer = window.RTCPeerConnection.prototype.createOffer;\n window.RTCPeerConnection.prototype.createOffer = function createOffer() {\n if (this.setParametersPromises && this.setParametersPromises.length) {\n return Promise.all(this.setParametersPromises)\n .then(() => {\n return origCreateOffer.apply(this, arguments);\n })\n .finally(() => {\n this.setParametersPromises = [];\n });\n }\n return origCreateOffer.apply(this, arguments);\n };\n}\n\nexport function shimCreateAnswer(window) {\n // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647\n // Firefox ignores the init sendEncodings options passed to addTransceiver\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918\n if (!(typeof window === 'object' && window.RTCPeerConnection)) {\n return;\n }\n const origCreateAnswer = window.RTCPeerConnection.prototype.createAnswer;\n window.RTCPeerConnection.prototype.createAnswer = function createAnswer() {\n if (this.setParametersPromises && this.setParametersPromises.length) {\n return Promise.all(this.setParametersPromises)\n .then(() => {\n return origCreateAnswer.apply(this, arguments);\n })\n .finally(() => {\n this.setParametersPromises = [];\n });\n }\n return origCreateAnswer.apply(this, arguments);\n };\n}\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n'use strict';\n\nimport * as utils from '../utils';\n\nexport function shimGetUserMedia(window, browserDetails) {\n const navigator = window && window.navigator;\n const MediaStreamTrack = window && window.MediaStreamTrack;\n\n navigator.getUserMedia = function(constraints, onSuccess, onError) {\n // Replace Firefox 44+'s deprecation warning with unprefixed version.\n utils.deprecated('navigator.getUserMedia',\n 'navigator.mediaDevices.getUserMedia');\n navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError);\n };\n\n if (!(browserDetails.version > 55 &&\n 'autoGainControl' in navigator.mediaDevices.getSupportedConstraints())) {\n const remap = function(obj, a, b) {\n if (a in obj && !(b in obj)) {\n obj[b] = obj[a];\n delete obj[a];\n }\n };\n\n const nativeGetUserMedia = navigator.mediaDevices.getUserMedia.\n bind(navigator.mediaDevices);\n navigator.mediaDevices.getUserMedia = function(c) {\n if (typeof c === 'object' && typeof c.audio === 'object') {\n c = JSON.parse(JSON.stringify(c));\n remap(c.audio, 'autoGainControl', 'mozAutoGainControl');\n remap(c.audio, 'noiseSuppression', 'mozNoiseSuppression');\n }\n return nativeGetUserMedia(c);\n };\n\n if (MediaStreamTrack && MediaStreamTrack.prototype.getSettings) {\n const nativeGetSettings = MediaStreamTrack.prototype.getSettings;\n MediaStreamTrack.prototype.getSettings = function() {\n const obj = nativeGetSettings.apply(this, arguments);\n remap(obj, 'mozAutoGainControl', 'autoGainControl');\n remap(obj, 'mozNoiseSuppression', 'noiseSuppression');\n return obj;\n };\n }\n\n if (MediaStreamTrack && MediaStreamTrack.prototype.applyConstraints) {\n const nativeApplyConstraints =\n MediaStreamTrack.prototype.applyConstraints;\n MediaStreamTrack.prototype.applyConstraints = function(c) {\n if (this.kind === 'audio' && typeof c === 'object') {\n c = JSON.parse(JSON.stringify(c));\n remap(c, 'autoGainControl', 'mozAutoGainControl');\n remap(c, 'noiseSuppression', 'mozNoiseSuppression');\n }\n return nativeApplyConstraints.apply(this, [c]);\n };\n }\n }\n}\n","/*\n * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n'use strict';\n\nexport function shimGetDisplayMedia(window, preferredMediaSource) {\n if (window.navigator.mediaDevices &&\n 'getDisplayMedia' in window.navigator.mediaDevices) {\n return;\n }\n if (!(window.navigator.mediaDevices)) {\n return;\n }\n window.navigator.mediaDevices.getDisplayMedia =\n function getDisplayMedia(constraints) {\n if (!(constraints && constraints.video)) {\n const err = new DOMException('getDisplayMedia without video ' +\n 'constraints is undefined');\n err.name = 'NotFoundError';\n // from https://heycam.github.io/webidl/#idl-DOMException-error-names\n err.code = 8;\n return Promise.reject(err);\n }\n if (constraints.video === true) {\n constraints.video = {mediaSource: preferredMediaSource};\n } else {\n constraints.video.mediaSource = preferredMediaSource;\n }\n return window.navigator.mediaDevices.getUserMedia(constraints);\n };\n}\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n'use strict';\nimport * as utils from '../utils';\n\nexport function shimLocalStreamsAPI(window) {\n if (typeof window !== 'object' || !window.RTCPeerConnection) {\n return;\n }\n if (!('getLocalStreams' in window.RTCPeerConnection.prototype)) {\n window.RTCPeerConnection.prototype.getLocalStreams =\n function getLocalStreams() {\n if (!this._localStreams) {\n this._localStreams = [];\n }\n return this._localStreams;\n };\n }\n if (!('addStream' in window.RTCPeerConnection.prototype)) {\n const _addTrack = window.RTCPeerConnection.prototype.addTrack;\n window.RTCPeerConnection.prototype.addStream = function addStream(stream) {\n if (!this._localStreams) {\n this._localStreams = [];\n }\n if (!this._localStreams.includes(stream)) {\n this._localStreams.push(stream);\n }\n // Try to emulate Chrome's behaviour of adding in audio-video order.\n // Safari orders by track id.\n stream.getAudioTracks().forEach(track => _addTrack.call(this, track,\n stream));\n stream.getVideoTracks().forEach(track => _addTrack.call(this, track,\n stream));\n };\n\n window.RTCPeerConnection.prototype.addTrack =\n function addTrack(track, ...streams) {\n if (streams) {\n streams.forEach((stream) => {\n if (!this._localStreams) {\n this._localStreams = [stream];\n } else if (!this._localStreams.includes(stream)) {\n this._localStreams.push(stream);\n }\n });\n }\n return _addTrack.apply(this, arguments);\n };\n }\n if (!('removeStream' in window.RTCPeerConnection.prototype)) {\n window.RTCPeerConnection.prototype.removeStream =\n function removeStream(stream) {\n if (!this._localStreams) {\n this._localStreams = [];\n }\n const index = this._localStreams.indexOf(stream);\n if (index === -1) {\n return;\n }\n this._localStreams.splice(index, 1);\n const tracks = stream.getTracks();\n this.getSenders().forEach(sender => {\n if (tracks.includes(sender.track)) {\n this.removeTrack(sender);\n }\n });\n };\n }\n}\n\nexport function shimRemoteStreamsAPI(window) {\n if (typeof window !== 'object' || !window.RTCPeerConnection) {\n return;\n }\n if (!('getRemoteStreams' in window.RTCPeerConnection.prototype)) {\n window.RTCPeerConnection.prototype.getRemoteStreams =\n function getRemoteStreams() {\n return this._remoteStreams ? this._remoteStreams : [];\n };\n }\n if (!('onaddstream' in window.RTCPeerConnection.prototype)) {\n Object.defineProperty(window.RTCPeerConnection.prototype, 'onaddstream', {\n get() {\n return this._onaddstream;\n },\n set(f) {\n if (this._onaddstream) {\n this.removeEventListener('addstream', this._onaddstream);\n this.removeEventListener('track', this._onaddstreampoly);\n }\n this.addEventListener('addstream', this._onaddstream = f);\n this.addEventListener('track', this._onaddstreampoly = (e) => {\n e.streams.forEach(stream => {\n if (!this._remoteStreams) {\n this._remoteStreams = [];\n }\n if (this._remoteStreams.includes(stream)) {\n return;\n }\n this._remoteStreams.push(stream);\n const event = new Event('addstream');\n event.stream = stream;\n this.dispatchEvent(event);\n });\n });\n }\n });\n const origSetRemoteDescription =\n window.RTCPeerConnection.prototype.setRemoteDescription;\n window.RTCPeerConnection.prototype.setRemoteDescription =\n function setRemoteDescription() {\n const pc = this;\n if (!this._onaddstreampoly) {\n this.addEventListener('track', this._onaddstreampoly = function(e) {\n e.streams.forEach(stream => {\n if (!pc._remoteStreams) {\n pc._remoteStreams = [];\n }\n if (pc._remoteStreams.indexOf(stream) >= 0) {\n return;\n }\n pc._remoteStreams.push(stream);\n const event = new Event('addstream');\n event.stream = stream;\n pc.dispatchEvent(event);\n });\n });\n }\n return origSetRemoteDescription.apply(pc, arguments);\n };\n }\n}\n\nexport function shimCallbacksAPI(window) {\n if (typeof window !== 'object' || !window.RTCPeerConnection) {\n return;\n }\n const prototype = window.RTCPeerConnection.prototype;\n const origCreateOffer = prototype.createOffer;\n const origCreateAnswer = prototype.createAnswer;\n const setLocalDescription = prototype.setLocalDescription;\n const setRemoteDescription = prototype.setRemoteDescription;\n const addIceCandidate = prototype.addIceCandidate;\n\n prototype.createOffer =\n function createOffer(successCallback, failureCallback) {\n const options = (arguments.length >= 2) ? arguments[2] : arguments[0];\n const promise = origCreateOffer.apply(this, [options]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n\n prototype.createAnswer =\n function createAnswer(successCallback, failureCallback) {\n const options = (arguments.length >= 2) ? arguments[2] : arguments[0];\n const promise = origCreateAnswer.apply(this, [options]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n\n let withCallback = function(description, successCallback, failureCallback) {\n const promise = setLocalDescription.apply(this, [description]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n prototype.setLocalDescription = withCallback;\n\n withCallback = function(description, successCallback, failureCallback) {\n const promise = setRemoteDescription.apply(this, [description]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n prototype.setRemoteDescription = withCallback;\n\n withCallback = function(candidate, successCallback, failureCallback) {\n const promise = addIceCandidate.apply(this, [candidate]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n prototype.addIceCandidate = withCallback;\n}\n\nexport function shimGetUserMedia(window) {\n const navigator = window && window.navigator;\n\n if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {\n // shim not needed in Safari 12.1\n const mediaDevices = navigator.mediaDevices;\n const _getUserMedia = mediaDevices.getUserMedia.bind(mediaDevices);\n navigator.mediaDevices.getUserMedia = (constraints) => {\n return _getUserMedia(shimConstraints(constraints));\n };\n }\n\n if (!navigator.getUserMedia && navigator.mediaDevices &&\n navigator.mediaDevices.getUserMedia) {\n navigator.getUserMedia = function getUserMedia(constraints, cb, errcb) {\n navigator.mediaDevices.getUserMedia(constraints)\n .then(cb, errcb);\n }.bind(navigator);\n }\n}\n\nexport function shimConstraints(constraints) {\n if (constraints && constraints.video !== undefined) {\n return Object.assign({},\n constraints,\n {video: utils.compactObject(constraints.video)}\n );\n }\n\n return constraints;\n}\n\nexport function shimRTCIceServerUrls(window) {\n if (!window.RTCPeerConnection) {\n return;\n }\n // migrate from non-spec RTCIceServer.url to RTCIceServer.urls\n const OrigPeerConnection = window.RTCPeerConnection;\n window.RTCPeerConnection =\n function RTCPeerConnection(pcConfig, pcConstraints) {\n if (pcConfig && pcConfig.iceServers) {\n const newIceServers = [];\n for (let i = 0; i < pcConfig.iceServers.length; i++) {\n let server = pcConfig.iceServers[i];\n if (server.urls === undefined && server.url) {\n utils.deprecated('RTCIceServer.url', 'RTCIceServer.urls');\n server = JSON.parse(JSON.stringify(server));\n server.urls = server.url;\n delete server.url;\n newIceServers.push(server);\n } else {\n newIceServers.push(pcConfig.iceServers[i]);\n }\n }\n pcConfig.iceServers = newIceServers;\n }\n return new OrigPeerConnection(pcConfig, pcConstraints);\n };\n window.RTCPeerConnection.prototype = OrigPeerConnection.prototype;\n // wrap static methods. Currently just generateCertificate.\n if ('generateCertificate' in OrigPeerConnection) {\n Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', {\n get() {\n return OrigPeerConnection.generateCertificate;\n }\n });\n }\n}\n\nexport function shimTrackEventTransceiver(window) {\n // Add event.transceiver member over deprecated event.receiver\n if (typeof window === 'object' && window.RTCTrackEvent &&\n 'receiver' in window.RTCTrackEvent.prototype &&\n !('transceiver' in window.RTCTrackEvent.prototype)) {\n Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {\n get() {\n return {receiver: this.receiver};\n }\n });\n }\n}\n\nexport function shimCreateOfferLegacy(window) {\n const origCreateOffer = window.RTCPeerConnection.prototype.createOffer;\n window.RTCPeerConnection.prototype.createOffer =\n function createOffer(offerOptions) {\n if (offerOptions) {\n if (typeof offerOptions.offerToReceiveAudio !== 'undefined') {\n // support bit values\n offerOptions.offerToReceiveAudio =\n !!offerOptions.offerToReceiveAudio;\n }\n const audioTransceiver = this.getTransceivers().find(transceiver =>\n transceiver.receiver.track.kind === 'audio');\n if (offerOptions.offerToReceiveAudio === false && audioTransceiver) {\n if (audioTransceiver.direction === 'sendrecv') {\n if (audioTransceiver.setDirection) {\n audioTransceiver.setDirection('sendonly');\n } else {\n audioTransceiver.direction = 'sendonly';\n }\n } else if (audioTransceiver.direction === 'recvonly') {\n if (audioTransceiver.setDirection) {\n audioTransceiver.setDirection('inactive');\n } else {\n audioTransceiver.direction = 'inactive';\n }\n }\n } else if (offerOptions.offerToReceiveAudio === true &&\n !audioTransceiver) {\n this.addTransceiver('audio', {direction: 'recvonly'});\n }\n\n if (typeof offerOptions.offerToReceiveVideo !== 'undefined') {\n // support bit values\n offerOptions.offerToReceiveVideo =\n !!offerOptions.offerToReceiveVideo;\n }\n const videoTransceiver = this.getTransceivers().find(transceiver =>\n transceiver.receiver.track.kind === 'video');\n if (offerOptions.offerToReceiveVideo === false && videoTransceiver) {\n if (videoTransceiver.direction === 'sendrecv') {\n if (videoTransceiver.setDirection) {\n videoTransceiver.setDirection('sendonly');\n } else {\n videoTransceiver.direction = 'sendonly';\n }\n } else if (videoTransceiver.direction === 'recvonly') {\n if (videoTransceiver.setDirection) {\n videoTransceiver.setDirection('inactive');\n } else {\n videoTransceiver.direction = 'inactive';\n }\n }\n } else if (offerOptions.offerToReceiveVideo === true &&\n !videoTransceiver) {\n this.addTransceiver('video', {direction: 'recvonly'});\n }\n }\n return origCreateOffer.apply(this, arguments);\n };\n}\n\nexport function shimAudioContext(window) {\n if (typeof window !== 'object' || window.AudioContext) {\n return;\n }\n window.AudioContext = window.webkitAudioContext;\n}\n\n","/*\n * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n'use strict';\n\nimport SDPUtils from 'sdp';\nimport * as utils from './utils';\n\nexport function shimRTCIceCandidate(window) {\n // foundation is arbitrarily chosen as an indicator for full support for\n // https://w3c.github.io/webrtc-pc/#rtcicecandidate-interface\n if (!window.RTCIceCandidate || (window.RTCIceCandidate && 'foundation' in\n window.RTCIceCandidate.prototype)) {\n return;\n }\n\n const NativeRTCIceCandidate = window.RTCIceCandidate;\n window.RTCIceCandidate = function RTCIceCandidate(args) {\n // Remove the a= which shouldn't be part of the candidate string.\n if (typeof args === 'object' && args.candidate &&\n args.candidate.indexOf('a=') === 0) {\n args = JSON.parse(JSON.stringify(args));\n args.candidate = args.candidate.substring(2);\n }\n\n if (args.candidate && args.candidate.length) {\n // Augment the native candidate with the parsed fields.\n const nativeCandidate = new NativeRTCIceCandidate(args);\n const parsedCandidate = SDPUtils.parseCandidate(args.candidate);\n for (const key in parsedCandidate) {\n if (!(key in nativeCandidate)) {\n Object.defineProperty(nativeCandidate, key,\n {value: parsedCandidate[key]});\n }\n }\n\n // Override serializer to not serialize the extra attributes.\n nativeCandidate.toJSON = function toJSON() {\n return {\n candidate: nativeCandidate.candidate,\n sdpMid: nativeCandidate.sdpMid,\n sdpMLineIndex: nativeCandidate.sdpMLineIndex,\n usernameFragment: nativeCandidate.usernameFragment,\n };\n };\n return nativeCandidate;\n }\n return new NativeRTCIceCandidate(args);\n };\n window.RTCIceCandidate.prototype = NativeRTCIceCandidate.prototype;\n\n // Hook up the augmented candidate in onicecandidate and\n // addEventListener('icecandidate', ...)\n utils.wrapPeerConnectionEvent(window, 'icecandidate', e => {\n if (e.candidate) {\n Object.defineProperty(e, 'candidate', {\n value: new window.RTCIceCandidate(e.candidate),\n writable: 'false'\n });\n }\n return e;\n });\n}\n\nexport function shimRTCIceCandidateRelayProtocol(window) {\n if (!window.RTCIceCandidate || (window.RTCIceCandidate && 'relayProtocol' in\n window.RTCIceCandidate.prototype)) {\n return;\n }\n\n // Hook up the augmented candidate in onicecandidate and\n // addEventListener('icecandidate', ...)\n utils.wrapPeerConnectionEvent(window, 'icecandidate', e => {\n if (e.candidate) {\n const parsedCandidate = SDPUtils.parseCandidate(e.candidate.candidate);\n if (parsedCandidate.type === 'relay') {\n // This is a libwebrtc-specific mapping of local type preference\n // to relayProtocol.\n e.candidate.relayProtocol = {\n 0: 'tls',\n 1: 'tcp',\n 2: 'udp',\n }[parsedCandidate.priority >> 24];\n }\n }\n return e;\n });\n}\n\nexport function shimMaxMessageSize(window, browserDetails) {\n if (!window.RTCPeerConnection) {\n return;\n }\n\n if (!('sctp' in window.RTCPeerConnection.prototype)) {\n Object.defineProperty(window.RTCPeerConnection.prototype, 'sctp', {\n get() {\n return typeof this._sctp === 'undefined' ? null : this._sctp;\n }\n });\n }\n\n const sctpInDescription = function(description) {\n if (!description || !description.sdp) {\n return false;\n }\n const sections = SDPUtils.splitSections(description.sdp);\n sections.shift();\n return sections.some(mediaSection => {\n const mLine = SDPUtils.parseMLine(mediaSection);\n return mLine && mLine.kind === 'application'\n && mLine.protocol.indexOf('SCTP') !== -1;\n });\n };\n\n const getRemoteFirefoxVersion = function(description) {\n // TODO: Is there a better solution for detecting Firefox?\n const match = description.sdp.match(/mozilla...THIS_IS_SDPARTA-(\\d+)/);\n if (match === null || match.length < 2) {\n return -1;\n }\n const version = parseInt(match[1], 10);\n // Test for NaN (yes, this is ugly)\n return version !== version ? -1 : version;\n };\n\n const getCanSendMaxMessageSize = function(remoteIsFirefox) {\n // Every implementation we know can send at least 64 KiB.\n // Note: Although Chrome is technically able to send up to 256 KiB, the\n // data does not reach the other peer reliably.\n // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=8419\n let canSendMaxMessageSize = 65536;\n if (browserDetails.browser === 'firefox') {\n if (browserDetails.version < 57) {\n if (remoteIsFirefox === -1) {\n // FF < 57 will send in 16 KiB chunks using the deprecated PPID\n // fragmentation.\n canSendMaxMessageSize = 16384;\n } else {\n // However, other FF (and RAWRTC) can reassemble PPID-fragmented\n // messages. Thus, supporting ~2 GiB when sending.\n canSendMaxMessageSize = 2147483637;\n }\n } else if (browserDetails.version < 60) {\n // Currently, all FF >= 57 will reset the remote maximum message size\n // to the default value when a data channel is created at a later\n // stage. :(\n // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831\n canSendMaxMessageSize =\n browserDetails.version === 57 ? 65535 : 65536;\n } else {\n // FF >= 60 supports sending ~2 GiB\n canSendMaxMessageSize = 2147483637;\n }\n }\n return canSendMaxMessageSize;\n };\n\n const getMaxMessageSize = function(description, remoteIsFirefox) {\n // Note: 65536 bytes is the default value from the SDP spec. Also,\n // every implementation we know supports receiving 65536 bytes.\n let maxMessageSize = 65536;\n\n // FF 57 has a slightly incorrect default remote max message size, so\n // we need to adjust it here to avoid a failure when sending.\n // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1425697\n if (browserDetails.browser === 'firefox'\n && browserDetails.version === 57) {\n maxMessageSize = 65535;\n }\n\n const match = SDPUtils.matchPrefix(description.sdp,\n 'a=max-message-size:');\n if (match.length > 0) {\n maxMessageSize = parseInt(match[0].substring(19), 10);\n } else if (browserDetails.browser === 'firefox' &&\n remoteIsFirefox !== -1) {\n // If the maximum message size is not present in the remote SDP and\n // both local and remote are Firefox, the remote peer can receive\n // ~2 GiB.\n maxMessageSize = 2147483637;\n }\n return maxMessageSize;\n };\n\n const origSetRemoteDescription =\n window.RTCPeerConnection.prototype.setRemoteDescription;\n window.RTCPeerConnection.prototype.setRemoteDescription =\n function setRemoteDescription() {\n this._sctp = null;\n // Chrome decided to not expose .sctp in plan-b mode.\n // As usual, adapter.js has to do an 'ugly worakaround'\n // to cover up the mess.\n if (browserDetails.browser === 'chrome' && browserDetails.version >= 76) {\n const {sdpSemantics} = this.getConfiguration();\n if (sdpSemantics === 'plan-b') {\n Object.defineProperty(this, 'sctp', {\n get() {\n return typeof this._sctp === 'undefined' ? null : this._sctp;\n },\n enumerable: true,\n configurable: true,\n });\n }\n }\n\n if (sctpInDescription(arguments[0])) {\n // Check if the remote is FF.\n const isFirefox = getRemoteFirefoxVersion(arguments[0]);\n\n // Get the maximum message size the local peer is capable of sending\n const canSendMMS = getCanSendMaxMessageSize(isFirefox);\n\n // Get the maximum message size of the remote peer.\n const remoteMMS = getMaxMessageSize(arguments[0], isFirefox);\n\n // Determine final maximum message size\n let maxMessageSize;\n if (canSendMMS === 0 && remoteMMS === 0) {\n maxMessageSize = Number.POSITIVE_INFINITY;\n } else if (canSendMMS === 0 || remoteMMS === 0) {\n maxMessageSize = Math.max(canSendMMS, remoteMMS);\n } else {\n maxMessageSize = Math.min(canSendMMS, remoteMMS);\n }\n\n // Create a dummy RTCSctpTransport object and the 'maxMessageSize'\n // attribute.\n const sctp = {};\n Object.defineProperty(sctp, 'maxMessageSize', {\n get() {\n return maxMessageSize;\n }\n });\n this._sctp = sctp;\n }\n\n return origSetRemoteDescription.apply(this, arguments);\n };\n}\n\nexport function shimSendThrowTypeError(window) {\n if (!(window.RTCPeerConnection &&\n 'createDataChannel' in window.RTCPeerConnection.prototype)) {\n return;\n }\n\n // Note: Although Firefox >= 57 has a native implementation, the maximum\n // message size can be reset for all data channels at a later stage.\n // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831\n\n function wrapDcSend(dc, pc) {\n const origDataChannelSend = dc.send;\n dc.send = function send() {\n const data = arguments[0];\n const length = data.length || data.size || data.byteLength;\n if (dc.readyState === 'open' &&\n pc.sctp && length > pc.sctp.maxMessageSize) {\n throw new TypeError('Message too large (can send a maximum of ' +\n pc.sctp.maxMessageSize + ' bytes)');\n }\n return origDataChannelSend.apply(dc, arguments);\n };\n }\n const origCreateDataChannel =\n window.RTCPeerConnection.prototype.createDataChannel;\n window.RTCPeerConnection.prototype.createDataChannel =\n function createDataChannel() {\n const dataChannel = origCreateDataChannel.apply(this, arguments);\n wrapDcSend(dataChannel, this);\n return dataChannel;\n };\n utils.wrapPeerConnectionEvent(window, 'datachannel', e => {\n wrapDcSend(e.channel, e.target);\n return e;\n });\n}\n\n\n/* shims RTCConnectionState by pretending it is the same as iceConnectionState.\n * See https://bugs.chromium.org/p/webrtc/issues/detail?id=6145#c12\n * for why this is a valid hack in Chrome. In Firefox it is slightly incorrect\n * since DTLS failures would be hidden. See\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1265827\n * for the Firefox tracking bug.\n */\nexport function shimConnectionState(window) {\n if (!window.RTCPeerConnection ||\n 'connectionState' in window.RTCPeerConnection.prototype) {\n return;\n }\n const proto = window.RTCPeerConnection.prototype;\n Object.defineProperty(proto, 'connectionState', {\n get() {\n return {\n completed: 'connected',\n checking: 'connecting'\n }[this.iceConnectionState] || this.iceConnectionState;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(proto, 'onconnectionstatechange', {\n get() {\n return this._onconnectionstatechange || null;\n },\n set(cb) {\n if (this._onconnectionstatechange) {\n this.removeEventListener('connectionstatechange',\n this._onconnectionstatechange);\n delete this._onconnectionstatechange;\n }\n if (cb) {\n this.addEventListener('connectionstatechange',\n this._onconnectionstatechange = cb);\n }\n },\n enumerable: true,\n configurable: true\n });\n\n ['setLocalDescription', 'setRemoteDescription'].forEach((method) => {\n const origMethod = proto[method];\n proto[method] = function() {\n if (!this._connectionstatechangepoly) {\n this._connectionstatechangepoly = e => {\n const pc = e.target;\n if (pc._lastConnectionState !== pc.connectionState) {\n pc._lastConnectionState = pc.connectionState;\n const newEvent = new Event('connectionstatechange', e);\n pc.dispatchEvent(newEvent);\n }\n return e;\n };\n this.addEventListener('iceconnectionstatechange',\n this._connectionstatechangepoly);\n }\n return origMethod.apply(this, arguments);\n };\n });\n}\n\nexport function removeExtmapAllowMixed(window, browserDetails) {\n /* remove a=extmap-allow-mixed for webrtc.org < M71 */\n if (!window.RTCPeerConnection) {\n return;\n }\n if (browserDetails.browser === 'chrome' && browserDetails.version >= 71) {\n return;\n }\n if (browserDetails.browser === 'safari' && browserDetails.version >= 605) {\n return;\n }\n const nativeSRD = window.RTCPeerConnection.prototype.setRemoteDescription;\n window.RTCPeerConnection.prototype.setRemoteDescription =\n function setRemoteDescription(desc) {\n if (desc && desc.sdp && desc.sdp.indexOf('\\na=extmap-allow-mixed') !== -1) {\n const sdp = desc.sdp.split('\\n').filter((line) => {\n return line.trim() !== 'a=extmap-allow-mixed';\n }).join('\\n');\n // Safari enforces read-only-ness of RTCSessionDescription fields.\n if (window.RTCSessionDescription &&\n desc instanceof window.RTCSessionDescription) {\n arguments[0] = new window.RTCSessionDescription({\n type: desc.type,\n sdp,\n });\n } else {\n desc.sdp = sdp;\n }\n }\n return nativeSRD.apply(this, arguments);\n };\n}\n\nexport function shimAddIceCandidateNullOrEmpty(window, browserDetails) {\n // Support for addIceCandidate(null or undefined)\n // as well as addIceCandidate({candidate: \"\", ...})\n // https://bugs.chromium.org/p/chromium/issues/detail?id=978582\n // Note: must be called before other polyfills which change the signature.\n if (!(window.RTCPeerConnection && window.RTCPeerConnection.prototype)) {\n return;\n }\n const nativeAddIceCandidate =\n window.RTCPeerConnection.prototype.addIceCandidate;\n if (!nativeAddIceCandidate || nativeAddIceCandidate.length === 0) {\n return;\n }\n window.RTCPeerConnection.prototype.addIceCandidate =\n function addIceCandidate() {\n if (!arguments[0]) {\n if (arguments[1]) {\n arguments[1].apply(null);\n }\n return Promise.resolve();\n }\n // Firefox 68+ emits and processes {candidate: \"\", ...}, ignore\n // in older versions.\n // Native support for ignoring exists for Chrome M77+.\n // Safari ignores as well, exact version unknown but works in the same\n // version that also ignores addIceCandidate(null).\n if (((browserDetails.browser === 'chrome' && browserDetails.version < 78)\n || (browserDetails.browser === 'firefox'\n && browserDetails.version < 68)\n || (browserDetails.browser === 'safari'))\n && arguments[0] && arguments[0].candidate === '') {\n return Promise.resolve();\n }\n return nativeAddIceCandidate.apply(this, arguments);\n };\n}\n\n// Note: Make sure to call this ahead of APIs that modify\n// setLocalDescription.length\nexport function shimParameterlessSetLocalDescription(window, browserDetails) {\n if (!(window.RTCPeerConnection && window.RTCPeerConnection.prototype)) {\n return;\n }\n const nativeSetLocalDescription =\n window.RTCPeerConnection.prototype.setLocalDescription;\n if (!nativeSetLocalDescription || nativeSetLocalDescription.length === 0) {\n return;\n }\n window.RTCPeerConnection.prototype.setLocalDescription =\n function setLocalDescription() {\n let desc = arguments[0] || {};\n if (typeof desc !== 'object' || (desc.type && desc.sdp)) {\n return nativeSetLocalDescription.apply(this, arguments);\n }\n // The remaining steps should technically happen when SLD comes off the\n // RTCPeerConnection's operations chain (not ahead of going on it), but\n // this is too difficult to shim. Instead, this shim only covers the\n // common case where the operations chain is empty. This is imperfect, but\n // should cover many cases. Rationale: Even if we can't reduce the glare\n // window to zero on imperfect implementations, there's value in tapping\n // into the perfect negotiation pattern that several browsers support.\n desc = {type: desc.type, sdp: desc.sdp};\n if (!desc.type) {\n switch (this.signalingState) {\n case 'stable':\n case 'have-local-offer':\n case 'have-remote-pranswer':\n desc.type = 'offer';\n break;\n default:\n desc.type = 'answer';\n break;\n }\n }\n if (desc.sdp || (desc.type !== 'offer' && desc.type !== 'answer')) {\n return nativeSetLocalDescription.apply(this, [desc]);\n }\n const func = desc.type === 'offer' ? this.createOffer : this.createAnswer;\n return func.apply(this)\n .then(d => nativeSetLocalDescription.apply(this, [d]));\n };\n}\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\nimport * as utils from './utils';\n\n// Browser shims.\nimport * as chromeShim from './chrome/chrome_shim';\nimport * as firefoxShim from './firefox/firefox_shim';\nimport * as safariShim from './safari/safari_shim';\nimport * as commonShim from './common_shim';\nimport * as sdp from 'sdp';\n\n// Shimming starts here.\nexport function adapterFactory({window} = {}, options = {\n shimChrome: true,\n shimFirefox: true,\n shimSafari: true,\n}) {\n // Utils.\n const logging = utils.log;\n const browserDetails = utils.detectBrowser(window);\n\n const adapter = {\n browserDetails,\n commonShim,\n extractVersion: utils.extractVersion,\n disableLog: utils.disableLog,\n disableWarnings: utils.disableWarnings,\n // Expose sdp as a convenience. For production apps include directly.\n sdp,\n };\n\n // Shim browser if found.\n switch (browserDetails.browser) {\n case 'chrome':\n if (!chromeShim || !chromeShim.shimPeerConnection ||\n !options.shimChrome) {\n logging('Chrome shim is not included in this adapter release.');\n return adapter;\n }\n if (browserDetails.version === null) {\n logging('Chrome shim can not determine version, not shimming.');\n return adapter;\n }\n logging('adapter.js shimming chrome.');\n // Export to the adapter global object visible in the browser.\n adapter.browserShim = chromeShim;\n\n // Must be called before shimPeerConnection.\n commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails);\n commonShim.shimParameterlessSetLocalDescription(window, browserDetails);\n\n chromeShim.shimGetUserMedia(window, browserDetails);\n chromeShim.shimMediaStream(window, browserDetails);\n chromeShim.shimPeerConnection(window, browserDetails);\n chromeShim.shimOnTrack(window, browserDetails);\n chromeShim.shimAddTrackRemoveTrack(window, browserDetails);\n chromeShim.shimGetSendersWithDtmf(window, browserDetails);\n chromeShim.shimSenderReceiverGetStats(window, browserDetails);\n chromeShim.fixNegotiationNeeded(window, browserDetails);\n\n commonShim.shimRTCIceCandidate(window, browserDetails);\n commonShim.shimRTCIceCandidateRelayProtocol(window, browserDetails);\n commonShim.shimConnectionState(window, browserDetails);\n commonShim.shimMaxMessageSize(window, browserDetails);\n commonShim.shimSendThrowTypeError(window, browserDetails);\n commonShim.removeExtmapAllowMixed(window, browserDetails);\n break;\n case 'firefox':\n if (!firefoxShim || !firefoxShim.shimPeerConnection ||\n !options.shimFirefox) {\n logging('Firefox shim is not included in this adapter release.');\n return adapter;\n }\n logging('adapter.js shimming firefox.');\n // Export to the adapter global object visible in the browser.\n adapter.browserShim = firefoxShim;\n\n // Must be called before shimPeerConnection.\n commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails);\n commonShim.shimParameterlessSetLocalDescription(window, browserDetails);\n\n firefoxShim.shimGetUserMedia(window, browserDetails);\n firefoxShim.shimPeerConnection(window, browserDetails);\n firefoxShim.shimOnTrack(window, browserDetails);\n firefoxShim.shimRemoveStream(window, browserDetails);\n firefoxShim.shimSenderGetStats(window, browserDetails);\n firefoxShim.shimReceiverGetStats(window, browserDetails);\n firefoxShim.shimRTCDataChannel(window, browserDetails);\n firefoxShim.shimAddTransceiver(window, browserDetails);\n firefoxShim.shimGetParameters(window, browserDetails);\n firefoxShim.shimCreateOffer(window, browserDetails);\n firefoxShim.shimCreateAnswer(window, browserDetails);\n\n commonShim.shimRTCIceCandidate(window, browserDetails);\n commonShim.shimConnectionState(window, browserDetails);\n commonShim.shimMaxMessageSize(window, browserDetails);\n commonShim.shimSendThrowTypeError(window, browserDetails);\n break;\n case 'safari':\n if (!safariShim || !options.shimSafari) {\n logging('Safari shim is not included in this adapter release.');\n return adapter;\n }\n logging('adapter.js shimming safari.');\n // Export to the adapter global object visible in the browser.\n adapter.browserShim = safariShim;\n\n // Must be called before shimCallbackAPI.\n commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails);\n commonShim.shimParameterlessSetLocalDescription(window, browserDetails);\n\n safariShim.shimRTCIceServerUrls(window, browserDetails);\n safariShim.shimCreateOfferLegacy(window, browserDetails);\n safariShim.shimCallbacksAPI(window, browserDetails);\n safariShim.shimLocalStreamsAPI(window, browserDetails);\n safariShim.shimRemoteStreamsAPI(window, browserDetails);\n safariShim.shimTrackEventTransceiver(window, browserDetails);\n safariShim.shimGetUserMedia(window, browserDetails);\n safariShim.shimAudioContext(window, browserDetails);\n\n commonShim.shimRTCIceCandidate(window, browserDetails);\n commonShim.shimRTCIceCandidateRelayProtocol(window, browserDetails);\n commonShim.shimMaxMessageSize(window, browserDetails);\n commonShim.shimSendThrowTypeError(window, browserDetails);\n commonShim.removeExtmapAllowMixed(window, browserDetails);\n break;\n default:\n logging('Unsupported browser!');\n break;\n }\n\n return adapter;\n}\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n\n'use strict';\n\nimport {adapterFactory} from './adapter_factory.js';\n\nconst adapter =\n adapterFactory({window: typeof window === 'undefined' ? undefined : window});\nexport default adapter;\n","// @generated by protobuf-ts 2.9.4 with parameter client_generic\n// @generated from protobuf file \"tunnel.proto\" (package \"pulsebeam.v1\", syntax proto3)\n// tslint:disable\nimport { ServiceType } from \"@protobuf-ts/runtime-rpc\";\nimport { MessageType } from \"@protobuf-ts/runtime\";\n/**\n * @generated from protobuf message pulsebeam.v1.PrepareReq\n */\nexport interface PrepareReq {\n}\n/**\n * @generated from protobuf message pulsebeam.v1.PrepareResp\n */\nexport interface PrepareResp {\n /**\n * @generated from protobuf field: repeated pulsebeam.v1.IceServer ice_servers = 1;\n */\n iceServers: IceServer[];\n}\n/**\n * @generated from protobuf message pulsebeam.v1.IceServer\n */\nexport interface IceServer {\n /**\n * @generated from protobuf field: repeated string urls = 1;\n */\n urls: string[];\n /**\n * @generated from protobuf field: optional string username = 2;\n */\n username?: string;\n /**\n * @generated from protobuf field: optional string credential = 3;\n */\n credential?: string;\n}\n/**\n * @generated from protobuf message pulsebeam.v1.SendReq\n */\nexport interface SendReq {\n /**\n * @generated from protobuf field: pulsebeam.v1.Message msg = 1;\n */\n msg?: Message;\n}\n/**\n * @generated from protobuf message pulsebeam.v1.SendResp\n */\nexport interface SendResp {\n}\n/**\n * @generated from protobuf message pulsebeam.v1.RecvReq\n */\nexport interface RecvReq {\n /**\n * @generated from protobuf field: pulsebeam.v1.PeerInfo info = 1;\n */\n info?: PeerInfo;\n}\n/**\n * @generated from protobuf message pulsebeam.v1.RecvResp\n */\nexport interface RecvResp {\n /**\n * @generated from protobuf field: repeated pulsebeam.v1.Message msgs = 1;\n */\n msgs: Message[];\n}\n/**\n * @generated from protobuf message pulsebeam.v1.PeerInfo\n */\nexport interface PeerInfo {\n /**\n * @generated from protobuf field: uint32 conn_id = 1;\n */\n connId: number;\n /**\n * @generated from protobuf field: bool enable_discovery = 2;\n */\n enableDiscovery: boolean;\n}\n/**\n * Use small tag numbers (1-15) for fields that are frequently used or are performance-sensitive, even if they are optional.\n * Larger tag numbers (16 and above) can be used for fields that are optional and not frequently included in messages, as they will require more bytes to encode.\n * Avoid the 19000–19999 range, as it's reserved.\n * Consider future-proofing your schema by leaving gaps between field numbers to allow for extensions or new fields later.\n *\n * @generated from protobuf message pulsebeam.v1.Message\n */\nexport interface Message {\n /**\n * @generated from protobuf field: pulsebeam.v1.MessageHeader header = 1;\n */\n header?: MessageHeader;\n /**\n * payload will be treated as opaque in backend. Size limit is 10kB.\n *\n * @generated from protobuf field: pulsebeam.v1.MessagePayload payload = 2;\n */\n payload?: MessagePayload;\n}\n/**\n * @generated from protobuf message pulsebeam.v1.MessagePayload\n */\nexport interface MessagePayload {\n /**\n * @generated from protobuf oneof: payload_type\n */\n payloadType: {\n oneofKind: \"signal\";\n /**\n * @generated from protobuf field: pulsebeam.v1.Signal signal = 1;\n */\n signal: Signal;\n } | {\n oneofKind: \"join\";\n /**\n * @generated from protobuf field: pulsebeam.v1.Join join = 2;\n */\n join: Join;\n } | {\n oneofKind: \"bye\";\n /**\n * @generated from protobuf field: pulsebeam.v1.Bye bye = 3;\n */\n bye: Bye;\n } | {\n oneofKind: \"ack\";\n /**\n * @generated from protobuf field: pulsebeam.v1.Ack ack = 4;\n */\n ack: Ack;\n } | {\n oneofKind: undefined;\n };\n}\n/**\n * @generated from protobuf message pulsebeam.v1.MessageHeader\n */\nexport interface MessageHeader {\n /**\n * @generated from protobuf field: string group_id = 1;\n */\n groupId: string;\n /**\n * @generated from protobuf field: string peer_id = 2;\n */\n peerId: string; // where this message is originated from. Special values: \"SYSTEM\"\n /**\n * @generated from protobuf field: uint32 conn_id = 3;\n */\n connId: number; // used for deciding polite vs impolite. higher id wins. It also is used to detect connection breakages\n /**\n * @generated from protobuf field: string other_group_id = 4;\n */\n otherGroupId: string;\n /**\n * @generated from protobuf field: string other_peer_id = 5;\n */\n otherPeerId: string; // Special values: \"SYSTEM\"\n /**\n * @generated from protobuf field: uint32 other_conn_id = 6;\n */\n otherConnId: number; // Special values: 0-16\n /**\n * @generated from protobuf field: uint32 seqnum = 7;\n */\n seqnum: number;\n /**\n * @generated from protobuf field: bool reliable = 8;\n */\n reliable: boolean; // true: tcp like, false: fire & forget\n}\n/**\n * @generated from protobuf message pulsebeam.v1.Signal\n */\nexport interface Signal {\n /**\n * @generated from protobuf field: uint32 generation_counter = 1;\n */\n generationCounter: number;\n /**\n * @generated from protobuf oneof: data\n */\n data: {\n oneofKind: \"sdp\";\n /**\n * @generated from protobuf field: pulsebeam.v1.Sdp sdp = 9;\n */\n sdp: Sdp;\n } | {\n oneofKind: \"iceCandidate\";\n /**\n * @generated from protobuf field: pulsebeam.v1.ICECandidate ice_candidate = 10;\n */\n iceCandidate: ICECandidate;\n } | {\n oneofKind: undefined;\n };\n}\n/**\n * @generated from protobuf message pulsebeam.v1.Sdp\n */\nexport interface Sdp {\n /**\n * @generated from protobuf field: pulsebeam.v1.SdpKind kind = 1;\n */\n kind: SdpKind;\n /**\n * @generated from protobuf field: string sdp = 2;\n */\n sdp: string;\n}\n/**\n * @generated from protobuf message pulsebeam.v1.ICECandidate\n */\nexport interface ICECandidate {\n /**\n * @generated from protobuf field: string candidate = 1;\n */\n candidate: string;\n /**\n * @generated from protobuf field: optional uint32 sdp_m_line_index = 2;\n */\n sdpMLineIndex?: number;\n /**\n * @generated from protobuf field: optional string sdp_mid = 3;\n */\n sdpMid?: string;\n /**\n * @generated from protobuf field: optional string username = 4;\n */\n username?: string;\n /**\n * @generated from protobuf field: optional string password = 5;\n */\n password?: string;\n}\n/**\n * @generated from protobuf message pulsebeam.v1.Join\n */\nexport interface Join {\n}\n/**\n * @generated from protobuf message pulsebeam.v1.Bye\n */\nexport interface Bye {\n}\n/**\n * @generated from protobuf message pulsebeam.v1.Ack\n */\nexport interface Ack {\n /**\n * @generated from protobuf field: repeated pulsebeam.v1.AckRange ack_ranges = 1;\n */\n ackRanges: AckRange[];\n}\n/**\n * @generated from protobuf message pulsebeam.v1.AckRange\n */\nexport interface AckRange {\n /**\n * @generated from protobuf field: uint32 seqnum_start = 1;\n */\n seqnumStart: number;\n /**\n * @generated from protobuf field: uint32 seqnum_end = 2;\n */\n seqnumEnd: number;\n}\n/**\n * reserved for headers\n *\n * @generated from protobuf message pulsebeam.v1.DataChannel\n */\nexport interface DataChannel {\n /**\n * @generated from protobuf oneof: payload\n */\n payload: {\n oneofKind: \"heartbeat\";\n /**\n * @generated from protobuf field: pulsebeam.v1.DataChannelHeartbeat heartbeat = 10;\n */\n heartbeat: DataChannelHeartbeat;\n } | {\n oneofKind: undefined;\n };\n}\n/**\n * @generated from protobuf message pulsebeam.v1.DataChannelHeartbeat\n */\nexport interface DataChannelHeartbeat {\n}\n/**\n * @generated from protobuf enum pulsebeam.v1.SdpKind\n */\nexport enum SdpKind {\n /**\n * @generated from protobuf enum value: SDP_KIND_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n /**\n * @generated from protobuf enum value: SDP_KIND_OFFER = 1;\n */\n OFFER = 1,\n /**\n * @generated from protobuf enum value: SDP_KIND_ANSWER = 2;\n */\n ANSWER = 2,\n /**\n * @generated from protobuf enum value: SDP_KIND_PRANSWER = 3;\n */\n PRANSWER = 3,\n /**\n * @generated from protobuf enum value: SDP_KIND_ROLLBACK = 4;\n */\n ROLLBACK = 4\n}\n// @generated message type with reflection information, may provide speed optimized methods\nclass PrepareReq$Type extends MessageType<PrepareReq> {\n constructor() {\n super(\"pulsebeam.v1.PrepareReq\", []);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.PrepareReq\n */\nexport const PrepareReq = new PrepareReq$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass PrepareResp$Type extends MessageType<PrepareResp> {\n constructor() {\n super(\"pulsebeam.v1.PrepareResp\", [\n { no: 1, name: \"ice_servers\", kind: \"message\", repeat: 1 /*RepeatType.PACKED*/, T: () => IceServer }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.PrepareResp\n */\nexport const PrepareResp = new PrepareResp$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass IceServer$Type extends MessageType<IceServer> {\n constructor() {\n super(\"pulsebeam.v1.IceServer\", [\n { no: 1, name: \"urls\", kind: \"scalar\", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ },\n { no: 2, name: \"username\", kind: \"scalar\", opt: true, T: 9 /*ScalarType.STRING*/ },\n { no: 3, name: \"credential\", kind: \"scalar\", opt: true, T: 9 /*ScalarType.STRING*/ }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.IceServer\n */\nexport const IceServer = new IceServer$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass SendReq$Type extends MessageType<SendReq> {\n constructor() {\n super(\"pulsebeam.v1.SendReq\", [\n { no: 1, name: \"msg\", kind: \"message\", T: () => Message }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.SendReq\n */\nexport const SendReq = new SendReq$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass SendResp$Type extends MessageType<SendResp> {\n constructor() {\n super(\"pulsebeam.v1.SendResp\", []);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.SendResp\n */\nexport const SendResp = new SendResp$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass RecvReq$Type extends MessageType<RecvReq> {\n constructor() {\n super(\"pulsebeam.v1.RecvReq\", [\n { no: 1, name: \"info\", kind: \"message\", T: () => PeerInfo }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.RecvReq\n */\nexport const RecvReq = new RecvReq$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass RecvResp$Type extends MessageType<RecvResp> {\n constructor() {\n super(\"pulsebeam.v1.RecvResp\", [\n { no: 1, name: \"msgs\", kind: \"message\", repeat: 1 /*RepeatType.PACKED*/, T: () => Message }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.RecvResp\n */\nexport const RecvResp = new RecvResp$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass PeerInfo$Type extends MessageType<PeerInfo> {\n constructor() {\n super(\"pulsebeam.v1.PeerInfo\", [\n { no: 1, name: \"conn_id\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ },\n { no: 2, name: \"enable_discovery\", kind: \"scalar\", T: 8 /*ScalarType.BOOL*/ }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.PeerInfo\n */\nexport const PeerInfo = new PeerInfo$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass Message$Type extends MessageType<Message> {\n constructor() {\n super(\"pulsebeam.v1.Message\", [\n { no: 1, name: \"header\", kind: \"message\", T: () => MessageHeader },\n { no: 2, name: \"payload\", kind: \"message\", T: () => MessagePayload }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.Message\n */\nexport const Message = new Message$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass MessagePayload$Type extends MessageType<MessagePayload> {\n constructor() {\n super(\"pulsebeam.v1.MessagePayload\", [\n { no: 1, name: \"signal\", kind: \"message\", oneof: \"payloadType\", T: () => Signal },\n { no: 2, name: \"join\", kind: \"message\", oneof: \"payloadType\", T: () => Join },\n { no: 3, name: \"bye\", kind: \"message\", oneof: \"payloadType\", T: () => Bye },\n { no: 4, name: \"ack\", kind: \"message\", oneof: \"payloadType\", T: () => Ack }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.MessagePayload\n */\nexport const MessagePayload = new MessagePayload$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass MessageHeader$Type extends MessageType<MessageHeader> {\n constructor() {\n super(\"pulsebeam.v1.MessageHeader\", [\n { no: 1, name: \"group_id\", kind: \"scalar\", T: 9 /*ScalarType.STRING*/ },\n { no: 2, name: \"peer_id\", kind: \"scalar\", T: 9 /*ScalarType.STRING*/ },\n { no: 3, name: \"conn_id\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ },\n { no: 4, name: \"other_group_id\", kind: \"scalar\", T: 9 /*ScalarType.STRING*/ },\n { no: 5, name: \"other_peer_id\", kind: \"scalar\", T: 9 /*ScalarType.STRING*/ },\n { no: 6, name: \"other_conn_id\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ },\n { no: 7, name: \"seqnum\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ },\n { no: 8, name: \"reliable\", kind: \"scalar\", T: 8 /*ScalarType.BOOL*/ }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.MessageHeader\n */\nexport const MessageHeader = new MessageHeader$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass Signal$Type extends MessageType<Signal> {\n constructor() {\n super(\"pulsebeam.v1.Signal\", [\n { no: 1, name: \"generation_counter\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ },\n { no: 9, name: \"sdp\", kind: \"message\", oneof: \"data\", T: () => Sdp },\n { no: 10, name: \"ice_candidate\", kind: \"message\", oneof: \"data\", T: () => ICECandidate }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.Signal\n */\nexport const Signal = new Signal$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass Sdp$Type extends MessageType<Sdp> {\n constructor() {\n super(\"pulsebeam.v1.Sdp\", [\n { no: 1, name: \"kind\", kind: \"enum\", T: () => [\"pulsebeam.v1.SdpKind\", SdpKind, \"SDP_KIND_\"] },\n { no: 2, name: \"sdp\", kind: \"scalar\", T: 9 /*ScalarType.STRING*/ }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.Sdp\n */\nexport const Sdp = new Sdp$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass ICECandidate$Type extends MessageType<ICECandidate> {\n constructor() {\n super(\"pulsebeam.v1.ICECandidate\", [\n { no: 1, name: \"candidate\", kind: \"scalar\", T: 9 /*ScalarType.STRING*/ },\n { no: 2, name: \"sdp_m_line_index\", kind: \"scalar\", opt: true, T: 13 /*ScalarType.UINT32*/ },\n { no: 3, name: \"sdp_mid\", kind: \"scalar\", opt: true, T: 9 /*ScalarType.STRING*/ },\n { no: 4, name: \"username\", kind: \"scalar\", opt: true, T: 9 /*ScalarType.STRING*/ },\n { no: 5, name: \"password\", kind: \"scalar\", opt: true, T: 9 /*ScalarType.STRING*/ }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.ICECandidate\n */\nexport const ICECandidate = new ICECandidate$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass Join$Type extends MessageType<Join> {\n constructor() {\n super(\"pulsebeam.v1.Join\", []);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.Join\n */\nexport const Join = new Join$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass Bye$Type extends MessageType<Bye> {\n constructor() {\n super(\"pulsebeam.v1.Bye\", []);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.Bye\n */\nexport const Bye = new Bye$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass Ack$Type extends MessageType<Ack> {\n constructor() {\n super(\"pulsebeam.v1.Ack\", [\n { no: 1, name: \"ack_ranges\", kind: \"message\", repeat: 1 /*RepeatType.PACKED*/, T: () => AckRange }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.Ack\n */\nexport const Ack = new Ack$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass AckRange$Type extends MessageType<AckRange> {\n constructor() {\n super(\"pulsebeam.v1.AckRange\", [\n { no: 1, name: \"seqnum_start\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ },\n { no: 2, name: \"seqnum_end\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.AckRange\n */\nexport const AckRange = new AckRange$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass DataChannel$Type extends MessageType<DataChannel> {\n constructor() {\n super(\"pulsebeam.v1.DataChannel\", [\n { no: 10, name: \"heartbeat\", kind: \"message\", oneof: \"payload\", T: () => DataChannelHeartbeat }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.DataChannel\n */\nexport const DataChannel = new DataChannel$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass DataChannelHeartbeat$Type extends MessageType<DataChannelHeartbeat> {\n constructor() {\n super(\"pulsebeam.v1.DataChannelHeartbeat\", []);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.DataChannelHeartbeat\n */\nexport const DataChannelHeartbeat = new DataChannelHeartbeat$Type();\n/**\n * @generated ServiceType for protobuf service pulsebeam.v1.Tunnel\n */\nexport const Tunnel = new ServiceType(\"pulsebeam.v1.Tunnel\", [\n { name: \"Prepare\", options: {}, I: PrepareReq, O: PrepareResp },\n { name: \"Send\", options: {}, I: SendReq, O: SendResp },\n { name: \"Recv\", options: {}, I: RecvReq, O: RecvResp }\n]);\n","// @generated by protobuf-ts 2.9.4 with parameter client_generic\n// @generated from protobuf file \"tunnel.proto\" (package \"pulsebeam.v1\", syntax proto3)\n// tslint:disable\nimport type { RpcTransport } from \"@protobuf-ts/runtime-rpc\";\nimport type { ServiceInfo } from \"@protobuf-ts/runtime-rpc\";\nimport { Tunnel } from \"./tunnel.ts\";\nimport type { RecvResp } from \"./tunnel.ts\";\nimport type { RecvReq } from \"./tunnel.ts\";\nimport type { SendResp } from \"./tunnel.ts\";\nimport type { SendReq } from \"./tunnel.ts\";\nimport { stackIntercept } from \"@protobuf-ts/runtime-rpc\";\nimport type { PrepareResp } from \"./tunnel.ts\";\nimport type { PrepareReq } from \"./tunnel.ts\";\nimport type { UnaryCall } from \"@protobuf-ts/runtime-rpc\";\nimport type { RpcOptions } from \"@protobuf-ts/runtime-rpc\";\n/**\n * @generated from protobuf service pulsebeam.v1.Tunnel\n */\nexport interface ITunnelClient {\n /**\n * @generated from protobuf rpc: Prepare(pulsebeam.v1.PrepareReq) returns (pulsebeam.v1.PrepareResp);\n */\n prepare(input: PrepareReq, options?: RpcOptions): UnaryCall<PrepareReq, PrepareResp>;\n /**\n * @generated from protobuf rpc: Send(pulsebeam.v1.SendReq) returns (pulsebeam.v1.SendResp);\n */\n send(input: SendReq, options?: RpcOptions): UnaryCall<SendReq, SendResp>;\n /**\n * @generated from protobuf rpc: Recv(pulsebeam.v1.RecvReq) returns (pulsebeam.v1.RecvResp);\n */\n recv(input: RecvReq, options?: RpcOptions): UnaryCall<RecvReq, RecvResp>;\n}\n/**\n * @generated from protobuf service pulsebeam.v1.Tunnel\n */\nexport class TunnelClient implements ITunnelClient, ServiceInfo {\n typeName = Tunnel.typeName;\n methods = Tunnel.methods;\n options = Tunnel.options;\n constructor(private readonly _transport: RpcTransport) {\n }\n /**\n * @generated from protobuf rpc: Prepare(pulsebeam.v1.PrepareReq) returns (pulsebeam.v1.PrepareResp);\n */\n prepare(input: PrepareReq, options?: RpcOptions): UnaryCall<PrepareReq, PrepareResp> {\n const method = this.methods[0], opt = this._transport.mergeOptions(options);\n return stackIntercept<PrepareReq, PrepareResp>(\"unary\", this._transport, method, opt, input);\n }\n /**\n * @generated from protobuf rpc: Send(pulsebeam.v1.SendReq) returns (pulsebeam.v1.SendResp);\n */\n send(input: SendReq, options?: RpcOptions): UnaryCall<SendReq, SendResp> {\n const method = this.methods[1], opt = this._transport.mergeOptions(options);\n return stackIntercept<SendReq, SendResp>(\"unary\", this._transport, method, opt, input);\n }\n /**\n * @generated from protobuf rpc: Recv(pulsebeam.v1.RecvReq) returns (pulsebeam.v1.RecvResp);\n */\n recv(input: RecvReq, options?: RpcOptions): UnaryCall<RecvReq, RecvResp> {\n const method = this.methods[2], opt = this._transport.mergeOptions(options);\n return stackIntercept<RecvReq, RecvResp>(\"unary\", this._transport, method, opt, input);\n }\n}\n","/**\n * asleep is an async version of setTimeout with abortable signal.\n * the function will resolve to false when aborted, meaning the delay will\n * be less than the expected.\n */\nexport function asleep(ms: number, signal?: AbortSignal): Promise<boolean> {\n return new Promise((resolve) => {\n const timeoutId = setTimeout(() => resolve(true), ms);\n\n // If an AbortSignal is provided, listen for the 'abort' event\n if (signal) {\n signal.addEventListener(\"abort\", () => {\n clearTimeout(timeoutId); // Cancel the delay\n resolve(false);\n });\n }\n });\n}\n\nexport function joinSignals(...signals: AbortSignal[]): AbortSignal {\n const joined = new AbortController();\n\n const joinedAbort = () => {\n joined.abort();\n\n for (const signal of signals) {\n signal.removeEventListener(\"abort\", joinedAbort);\n }\n };\n\n for (const signal of signals) {\n signal.addEventListener(\"abort\", joinedAbort);\n }\n\n return joined.signal;\n}\n\nexport type RetryOptions = {\n maxRetries: number; // Maximum retry attempts. negative means no limit, 0 means 1 try (0 retry)\n baseDelay: number; // Initial delay in milliseconds\n maxDelay: number; // Maximum delay in milliseconds\n jitterFactor?: number; // Jitter percentage (e.g., 0.3 for 30%)\n isRecoverable?: (error: unknown) => boolean; // Function to categorize recoverable errors\n abortSignal?: AbortSignal;\n};\n\nexport async function retry<T>(\n asyncFunction: () => Promise<T>,\n options: RetryOptions,\n): Promise<T | null> {\n const {\n maxRetries,\n baseDelay,\n maxDelay,\n jitterFactor = 0.3,\n isRecoverable = () => true, // Default: all errors are recoverable\n abortSignal,\n } = options;\n\n let attempt = 0;\n\n while ((attempt <= maxRetries || maxRetries < 0) && !abortSignal?.aborted) {\n try {\n return await asyncFunction(); // Execute the function\n } catch (error) {\n // Check if the error is recoverable\n if (!isRecoverable(error)) {\n throw error; // Non-recoverable error, rethrow it\n }\n\n attempt++;\n if (maxRetries >= 0 && attempt > maxRetries) {\n throw error; // Exceeded max retries\n }\n\n // Calculate delay with exponential backoff and jitter\n const delay = calculateDelay(attempt, baseDelay, maxDelay, jitterFactor);\n await asleep(delay, abortSignal).catch(() => { }); // Wait before the next attempt\n }\n }\n\n if (abortSignal?.aborted) {\n return null;\n }\n\n throw new Error(\"Retry failed: max retries exceeded\"); // This is a fallback; should rarely occur\n}\n\n// Helper to calculate exponential backoff with jitter\nfunction calculateDelay(\n attempt: number,\n baseDelay: number,\n maxDelay: number,\n jitterFactor: number,\n): number {\n const exponentialDelay = Math.min(baseDelay * 2 ** (attempt - 1), maxDelay);\n const jitter = Math.random() * jitterFactor * exponentialDelay;\n return exponentialDelay + jitter;\n}\n","import type {\n Ack,\n Message,\n MessageHeader,\n MessagePayload,\n PeerInfo,\n} from \"./tunnel.ts\";\nimport { ITunnelClient } from \"./tunnel.client.ts\";\nimport type { Logger } from \"./logger.ts\";\nimport { asleep, joinSignals, retry, RetryOptions } from \"./util.ts\";\nimport { RpcOptions } from \"@protobuf-ts/runtime-rpc\";\n\nconst POLL_TIMEOUT_MS = 900000;\nconst POLL_RETRY_BASE_DELAY_MS = 50;\nconst POLL_RETRY_MAX_DELAY_MS = 1000;\nconst MAX_RELIABLE_RETRY_COUNT = 5;\nconst STREAM_GC_DELAY_MS = 10_000; // just enough to avoid collision and quick enough to reuse connection\nconst STREAM_GC_INTERVAL_MS = 1_000;\n\nexport enum ReservedConnId {\n Discovery = 0,\n Max = 16,\n}\n\nconst defaultAsleep = asleep;\nconst defaultRandUint32 = (\n reserved: number,\n) => (Math.floor(Math.random() * ((2 ** 32) - reserved)) + reserved);\nconst defaultIsRecoverable = (_err: unknown) => true;\n\n// This is a processing queue that can handle unreliable and reliable messages.\n// The processing prioritizes unreliable messages over reliable messages.\n// Reliable messages will be always deduplicated, unreliable messages will not be deduped.\nclass Queue {\n private map: Map<number, [number, Message]>;\n private emitted: Map<number, [number, Message]>;\n private unreliable: Message[];\n private processing: boolean;\n private readonly logger: Logger;\n public onmsg = async (_: Message) => { };\n\n constructor(logger: Logger) {\n this.logger = logger.sub(\"queue\");\n this.map = new Map();\n this.emitted = new Map();\n this.unreliable = [];\n this.processing = false;\n }\n\n enqueue(msg: Message) {\n if (!msg.header?.reliable) {\n this.unreliable.push(msg);\n } else {\n const seqnum = msg.header!.seqnum;\n if (this.map.has(seqnum) || this.emitted.has(seqnum)) return;\n this.map.set(seqnum, [performance.now(), msg]);\n }\n\n // TODO: control queue size by pruning old messages.\n this.processNext();\n }\n\n async processNext() {\n if (this.processing) return;\n\n let msg = this.unreliable.pop();\n if (!msg) {\n const res = this.map.entries().next().value;\n if (!res) return;\n\n const [key, value] = res;\n this.map.delete(key);\n this.emitted.set(key, value);\n const [_, m] = value;\n if (!m.header) return;\n msg = m;\n }\n\n this.processing = true;\n try {\n await this.onmsg(msg);\n } catch (err) {\n const obj: Record<string, unknown> = { msg };\n if (err instanceof Error) {\n obj[\"err\"] = err;\n }\n this.logger.error(\"error processing message\", obj);\n }\n this.processing = false;\n this.processNext();\n }\n}\n\nexport interface TransportOptions {\n readonly enableDiscovery: boolean;\n readonly groupId: string;\n readonly peerId: string;\n readonly logger: Logger;\n readonly asleep?: typeof defaultAsleep;\n readonly randUint32?: typeof defaultRandUint32;\n readonly isRecoverable?: typeof defaultIsRecoverable;\n}\n\nexport class Transport {\n public readonly groupId: string;\n public readonly peerId: string;\n public readonly connId: number;\n private readonly info: PeerInfo;\n private streams: Stream[];\n private abort: AbortController;\n public readonly logger: Logger;\n public readonly asleep: typeof defaultAsleep;\n private readonly randUint32: typeof defaultRandUint32;\n private readonly isRecoverable: typeof defaultIsRecoverable;\n public onstream = (_: Stream) => { };\n public onclosed = (_reason: string) => { };\n\n constructor(\n private readonly client: ITunnelClient,\n public readonly opts: TransportOptions,\n ) {\n this.asleep = opts.asleep || defaultAsleep;\n this.randUint32 = opts.randUint32 || defaultRandUint32;\n this.isRecoverable = opts.isRecoverable || defaultIsRecoverable;\n\n this.groupId = opts.groupId;\n this.peerId = opts.peerId;\n this.connId = this.randUint32(ReservedConnId.Max);\n this.info = {\n connId: this.connId,\n enableDiscovery: opts.enableDiscovery,\n };\n this.abort = new AbortController();\n this.logger = opts.logger.sub(\"transport\", {\n groupId: this.opts.groupId,\n peerId: this.opts.peerId,\n connId: this.connId,\n });\n this.streams = [];\n }\n\n async listen() {\n await Promise.all([\n this.pollLoop(),\n this.gcLoop(),\n ]);\n }\n\n async gcLoop() {\n while (!this.abort.signal.aborted) {\n // use cooldown period to fully close. Otherwise, there's a chance that the other peer is\n // still sending some messages. In which case, we need to still ignore for some time until completely quiet.\n this.streams = this.streams.filter((s) => !s.isClosed());\n await asleep(STREAM_GC_INTERVAL_MS, this.abort.signal);\n }\n this.logger.debug(\"gc loop is closed\");\n }\n\n async pollLoop() {\n const rpcOpt: RpcOptions = {\n abort: this.abort.signal,\n timeout: POLL_TIMEOUT_MS,\n };\n const retryOpt: RetryOptions = {\n baseDelay: POLL_RETRY_BASE_DELAY_MS,\n maxDelay: POLL_RETRY_MAX_DELAY_MS,\n maxRetries: -1,\n abortSignal: this.abort.signal,\n isRecoverable: this.isRecoverable,\n };\n\n while (!this.abort.signal.aborted) {\n try {\n const resp = await retry(async () =>\n await this.client.recv({\n info: this.info,\n }, rpcOpt), retryOpt);\n if (resp === null) {\n break;\n }\n\n // make sure to not block polling loop\n new Promise(() => this.handleMessages(resp.response.msgs));\n } catch (err) {\n this.logger.error(\"unrecoverable error, force closing\", { err });\n this.close();\n return;\n }\n }\n this.logger.debug(\"poll loop is closed\");\n }\n\n async close(reason?: string) {\n if (this.abort.signal.aborted) return;\n reason = reason || \"transport is closed\";\n await Promise.all(this.streams.map((s) => s.close(reason)));\n // Give a chance for graceful shutdown before aborting the connection\n this.abort.abort(reason);\n this.logger.debug(\"transport is now closed\", { reason });\n this.streams = [];\n this.onclosed(reason);\n }\n\n private handleMessages = (msgs: Message[]) => {\n for (const msg of msgs) {\n this.logger.debug(\"received\", { msg: msg });\n if (this.abort.signal.aborted) return;\n if (!msg.header) continue;\n\n if (\n msg.header.otherConnId >= ReservedConnId.Max &&\n msg.header.otherConnId != this.connId\n ) {\n this.logger.warn(\n \"received messages from a stale connection, ignoring\",\n { receivedConnID: msg.header!.otherConnId },\n );\n continue;\n }\n\n let stream: Stream | null = null;\n for (const s of this.streams) {\n if (\n msg.header.groupId === s.otherGroupId &&\n msg.header.peerId === s.otherPeerId &&\n msg.header.connId === s.otherConnId\n ) {\n stream = s;\n break;\n }\n }\n\n if (!stream) {\n this.logger.debug(\n `session not found, creating one for ${msg.header.peerId}:${msg.header.connId}`,\n );\n\n if (msg.header.peerId == this.peerId) {\n this.logger.warn(\"loopback detected, ignoring messages\");\n return;\n }\n\n stream = new Stream(\n this,\n msg.header.groupId,\n msg.header.peerId,\n msg.header.connId,\n this.logger,\n );\n this.streams.push(stream);\n this.onstream(stream);\n }\n\n stream.enqueue(msg);\n }\n };\n\n async connect(\n otherGroupId: string,\n otherPeerId: string,\n signal: AbortSignal,\n ) {\n const payload: MessagePayload = {\n payloadType: {\n oneofKind: \"join\",\n join: {},\n },\n };\n const header: MessageHeader = {\n groupId: this.groupId,\n peerId: this.peerId,\n connId: this.connId,\n otherGroupId: otherGroupId,\n otherPeerId: otherPeerId,\n otherConnId: ReservedConnId.Discovery,\n seqnum: 0,\n reliable: false,\n };\n\n let found = false;\n const joinedSignal = joinSignals(signal, this.abort.signal);\n while (!joinedSignal.aborted && !found) {\n await this.send(joinedSignal, {\n header,\n payload,\n });\n await this.asleep(POLL_RETRY_MAX_DELAY_MS, joinedSignal).catch(() => { });\n\n found = !!this.streams.find((s) =>\n s.otherGroupId === otherGroupId && s.otherPeerId === otherPeerId\n );\n }\n }\n\n async send(signal: AbortSignal, msg: Message) {\n const joinedSignal = joinSignals(signal, this.abort.signal);\n const rpcOpt: RpcOptions = {\n abort: joinedSignal,\n timeout: POLL_TIMEOUT_MS,\n };\n const retryOpt: RetryOptions = {\n baseDelay: POLL_RETRY_BASE_DELAY_MS,\n maxDelay: POLL_RETRY_MAX_DELAY_MS,\n maxRetries: -1,\n abortSignal: joinedSignal,\n isRecoverable: this.isRecoverable,\n };\n\n try {\n const resp = await retry(async () =>\n await this.client.send(\n { msg },\n rpcOpt,\n ), retryOpt);\n if (resp === null) {\n this.logger.warn(\"aborted, message dropped from sending\", { msg });\n return;\n }\n\n return;\n } catch (err) {\n this.logger.error(\"unrecoverable error, force closing\", { err });\n this.close();\n return;\n }\n }\n}\n\n// Stream allows multiplexing on top of Transport, and\n// configuring order and reliability mode\nexport class Stream {\n public readonly logger: Logger;\n private abort: AbortController;\n public recvq: Queue;\n public ackedbuf: Record<string, boolean>;\n public readonly groupId: string;\n public readonly peerId: string;\n public readonly connId: number;\n private lastSeqnum: number;\n private closedAt: number;\n public onpayload = async (_: MessagePayload) => { };\n public onclosed = (_reason: string) => { };\n\n constructor(\n private readonly transport: Transport,\n public readonly otherGroupId: string,\n public readonly otherPeerId: string,\n public readonly otherConnId: number,\n logger: Logger,\n ) {\n this.logger = logger.sub(\"stream\", {\n otherGroupId,\n otherPeerId,\n otherConnId,\n });\n this.groupId = transport.groupId;\n this.peerId = transport.peerId;\n this.connId = transport.connId;\n this.abort = new AbortController();\n this.ackedbuf = {};\n this.recvq = new Queue(this.logger);\n this.recvq.onmsg = (msg) => this.handleMessage(msg);\n this.lastSeqnum = 0;\n this.closedAt = 0;\n }\n\n createSignal(...signals: AbortSignal[]): AbortSignal {\n return joinSignals(this.abort.signal, ...signals);\n }\n\n isClosed(): boolean {\n const closed = this.abort.signal.aborted &&\n (performance.now() - this.closedAt) > STREAM_GC_DELAY_MS;\n\n if (closed) {\n this.logger.debug(\"stream is ready for GC\");\n }\n return closed;\n }\n\n enqueue(msg: Message) {\n if (this.abort.signal.aborted) {\n this.logger.warn(\n \"received a message in closed state, ignoring new messages.\",\n );\n return;\n }\n\n this.recvq.enqueue(msg);\n }\n\n async send(payload: MessagePayload, reliable: boolean, signal?: AbortSignal) {\n if (!signal) {\n signal = this.abort.signal;\n }\n const msg: Message = {\n header: {\n groupId: this.transport.groupId,\n peerId: this.transport.peerId,\n connId: this.transport.connId,\n otherGroupId: this.otherGroupId,\n otherPeerId: this.otherPeerId,\n otherConnId: this.otherConnId,\n seqnum: 0,\n reliable,\n },\n payload: { ...payload },\n };\n\n if (!reliable) {\n await this.transport.send(signal, msg);\n return;\n }\n\n this.lastSeqnum++;\n msg.header!.seqnum = this.lastSeqnum;\n this.ackedbuf[msg.header!.seqnum] = false; // marked as unacked\n const resendLimit = MAX_RELIABLE_RETRY_COUNT;\n let tryCount = resendLimit;\n const seqnum = msg.header!.seqnum;\n\n // TODO: abort when generation counter doesn't match\n while (!signal.aborted) {\n await this.transport.send(this.abort.signal, msg);\n\n await this.transport.asleep(\n 5 * POLL_RETRY_MAX_DELAY_MS,\n this.abort.signal,\n ).catch(() => { });\n\n // since ackedbuf doesn't delete the seqnum right away, it prevents from racing between\n // resending and acknolwedging\n if (this.ackedbuf[seqnum]) {\n break;\n }\n\n if (tryCount <= 0) {\n const message = \"reached the maximum resend limit, dropping message\";\n this.logger.warn(message, {\n seqnum,\n resendLimit,\n reliable,\n });\n throw new Error(message);\n }\n\n tryCount--;\n this.logger.debug(\"resending\", { ...msg.header });\n }\n }\n\n private async handleMessage(msg: Message) {\n const payload = msg.payload!.payloadType;\n switch (payload.oneofKind) {\n case \"ack\":\n this.handleAck(payload.ack);\n break;\n case \"bye\":\n this.close(\"received bye from other peer\");\n break;\n case undefined:\n break;\n default: {\n if (msg.header!.reliable) {\n const ack: Ack = {\n ackRanges: [{\n seqnumStart: msg.header!.seqnum,\n seqnumEnd: msg.header!.seqnum + 1,\n }],\n };\n const reply: MessagePayload = {\n payloadType: { oneofKind: \"ack\", ack },\n };\n this.logger.debug(\"ack\", { seqnum: msg.header!.seqnum });\n this.send(reply, false);\n }\n\n if (!msg.payload) return;\n await this.onpayload(msg.payload!);\n break;\n }\n }\n }\n\n handleAck(ack: Ack) {\n for (const r of ack.ackRanges) {\n for (let s = r.seqnumStart; s < r.seqnumEnd; s++) {\n this.logger.debug(\"received ack\", { seqnum: s });\n this.ackedbuf[s] = true; // marked as acked\n }\n }\n }\n\n async close(reason?: string) {\n if (this.abort.signal.aborted) return;\n reason = reason || \"session is closed\";\n // make sure to give a chance to send a message\n await this.send({\n payloadType: {\n oneofKind: \"bye\",\n bye: {},\n },\n }, false).catch((err) =>\n this.logger.warn(\"failed to send bye\", { e: err })\n );\n this.abort.abort(reason);\n this.closedAt = performance.now();\n this.onclosed(reason);\n this.logger.debug(\"sent bye to the other peer\", { reason });\n }\n}\n","type LogObj = Record<string, unknown>;\ntype LogHandler = (_obj: LogObj) => void;\ntype LogSink = {\n \"DEBUG\": LogHandler;\n \"INFO\": LogHandler;\n \"WARN\": LogHandler;\n \"ERROR\": LogHandler;\n};\n\nexport const DEFAULT_LOG_SINK: LogSink = {\n DEBUG: console.debug,\n INFO: console.info,\n WARN: console.warn,\n ERROR: console.error,\n};\n\n// inspired by toml format, https://toml.io/en/\n// the main difference is that the fields are appended on the same line\n// to optimize readability in console.\nexport const PRETTY_LOG_SINK: LogSink = {\n DEBUG: (o) => console.debug(pretty(o)),\n INFO: (o) => console.info(pretty(o)),\n WARN: (o) => console.warn(pretty(o)),\n ERROR: (o) => console.error(pretty(o)),\n};\n\nexport function flatten(\n obj: LogObj,\n pairs: Record<string, string[]>,\n parentKey = \"root\",\n visited = new Set<LogObj>(),\n) {\n const sep = \".\";\n if (visited.has(obj)) return; // Stop if already visited\n visited.add(obj);\n\n for (const key in obj) {\n if (typeof obj[key] === \"object\" && obj[key] !== null) {\n const newKey = parentKey + sep + key;\n flatten(obj[key] as LogObj, pairs, newKey, visited);\n } else {\n const p = pairs[parentKey] || [];\n p.push(`${key}=${obj[key]}`);\n pairs[parentKey] = p;\n }\n }\n}\n\nexport function pretty(obj: LogObj) {\n const pairs: Record<string, string[]> = {};\n flatten(obj, pairs);\n\n const lines: string[] = [];\n for (const k in pairs) {\n lines.push(`[${k}] ${pairs[k].join(\" \")}`);\n }\n return lines.join(\"\\n\");\n}\n\nexport class Logger {\n private readonly obj: LogObj;\n private readonly sink: LogSink;\n constructor(public readonly name: string, obj?: LogObj, sink?: LogSink) {\n if (!obj) obj = {};\n if (!sink) sink = DEFAULT_LOG_SINK;\n this.sink = sink;\n this.obj = { ...obj, name };\n }\n\n private log(\n handler: LogHandler,\n message: string,\n obj?: LogObj,\n ): void {\n const o = obj || {};\n handler({\n ts: Date.now(),\n message,\n ...this.obj,\n ...o,\n });\n }\n\n debug(message: string, obj?: LogObj): void {\n this.log(this.sink.DEBUG, message, obj);\n }\n\n info(message: string, obj?: LogObj): void {\n this.log(this.sink.INFO, message, obj);\n }\n\n warn(message: string, obj?: LogObj): void {\n this.log(this.sink.WARN, message, obj);\n }\n\n error(message: string, obj?: LogObj): void {\n this.log(this.sink.ERROR, message, obj);\n }\n\n sub(name: string, obj?: LogObj): Logger {\n if (!obj) obj = {};\n return new Logger(\n this.name + \".\" + name,\n { ...this.obj, ...obj },\n this.sink,\n );\n }\n}\n","import {\n type ICECandidate,\n type MessagePayload,\n SdpKind,\n type Signal,\n} from \"./tunnel.ts\";\nimport { Logger } from \"./logger.ts\";\nimport type { Stream } from \"./transport.ts\";\n\nconst ICE_RESTART_MAX_COUNT = 2;\nconst ICE_RESTART_DEBOUNCE_DELAY_MS = 5000;\n\nfunction toIceCandidate(ice: ICECandidate): RTCIceCandidateInit {\n return {\n candidate: ice.candidate,\n sdpMid: ice.sdpMid,\n sdpMLineIndex: ice.sdpMLineIndex,\n usernameFragment: ice.password,\n };\n}\n\nfunction toSDPType(kind: SdpKind): RTCSdpType {\n switch (kind) {\n case SdpKind.OFFER:\n return \"offer\";\n case SdpKind.ANSWER:\n return \"answer\";\n case SdpKind.PRANSWER:\n return \"pranswer\";\n case SdpKind.ROLLBACK:\n return \"rollback\";\n default:\n throw new Error(`unexpected kind: ${kind}`);\n }\n}\n\nfunction fromSDPType(t: RTCSdpType): SdpKind {\n switch (t) {\n case \"offer\":\n return SdpKind.OFFER;\n case \"answer\":\n return SdpKind.ANSWER;\n case \"pranswer\":\n return SdpKind.PRANSWER;\n case \"rollback\":\n return SdpKind.ROLLBACK;\n default:\n throw new Error(`unexpected sdp type: ${t}`);\n }\n}\n/**\n * The Session class is a wrapper around RTCPeerConnection designed to manage\n * WebRTC connections, signaling, and ICE candidates. It handles negotiation,\n * ICE restarts, signaling messages, and connection lifecycle events.\n */\nexport class Session {\n private pc: RTCPeerConnection;\n private makingOffer: boolean;\n private impolite: boolean;\n private pendingCandidates: RTCIceCandidateInit[];\n private readonly logger: Logger;\n private abort: AbortController;\n private generationCounter: number;\n private iceRestartCount: number;\n private lastIceRestart: number;\n private timers: number[];\n private _closeReason?: string;\n private _connectionState: RTCPeerConnectionState;\n\n /**\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/ondatachannel}\n */\n public ondatachannel: RTCPeerConnection[\"ondatachannel\"] = () => { };\n\n /**\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/onconnectionstatechange}\n */\n public onconnectionstatechange: RTCPeerConnection[\"onconnectionstatechange\"] =\n () => { };\n\n /**\n * Callback invoked when a new media track is added to the connection.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/ontrack}\n */\n public ontrack: RTCPeerConnection[\"ontrack\"] = () => { };\n\n /**\n * Adds a media track to the connection.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack}\n * @returns {RTCRtpSender} the newly created track\n */\n addTrack(...args: Parameters<RTCPeerConnection[\"addTrack\"]>): RTCRtpSender {\n return this.pc.addTrack(...args);\n }\n\n /**\n * Removes a media track from the connection.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/removeTrack}\n * @returns {void}\n */\n removeTrack(...args: Parameters<RTCPeerConnection[\"removeTrack\"]>): void {\n return this.pc.removeTrack(...args);\n }\n\n /**\n * Creates a data channel (useful for sending arbitrary data) through the connection.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createDataChannel}\n */\n createDataChannel(\n ...args: Parameters<RTCPeerConnection[\"createDataChannel\"]>\n ): RTCDataChannel {\n return this.pc.createDataChannel(...args);\n }\n\n /**\n * Returns the current connection state of the underlying RTCPeerConnection\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState}\n * @returns {RTCPeerConnectionState}\n */\n get connectionState(): RTCPeerConnectionState {\n return this.pc.connectionState;\n }\n\n /**\n * If reason is available, returns the reason for the session being closed.\n * @returns {string | undefined}\n */\n get closeReason(): string | undefined {\n return this._closeReason;\n }\n\n /**\n * Retrieves the identifier of the other peer.\n * @returns {string}\n */\n get otherPeerId(): string {\n return this.stream.otherPeerId;\n }\n\n /**\n * Retrieves the connection identifier for the connection to the other peer.\n * Connection ids are usually unique.\n * @returns {number}\n */\n get otherConnId(): number {\n return this.stream.otherConnId;\n }\n\n /**\n * Closes the session, aborts pending tasks, and cleans up resources.\n * Publishes events and logs.\n * @param {string} [reason] - (optional) Your reason for closing the session.\n * @returns {void}\n * @example mysession.close(\"Normal closure\");\n */\n close(reason?: string): void {\n if (this.abort.signal.aborted) return;\n this.abort.abort(reason);\n for (const timer of this.timers) {\n clearTimeout(timer);\n }\n this.timers = [];\n this.stream.close();\n this._closeReason = reason;\n this.pc.close();\n\n // RTCPeerConnection will not emit closed connection. This is a polyfill to get around it.\n // https://stackoverflow.com/questions/66297347/why-does-calling-rtcpeerconnection-close-not-send-closed-event\n const closeEvent = new Event(\"connectionstatechange\");\n this.setConnectionState(\"closed\", closeEvent);\n\n this.logger.debug(\"session closed\", {\n connectionState: this.connectionState,\n });\n }\n\n /**\n * Creates a Session with the provided stream and\n * configs. Sets up event handlers, signaling, and ICE candidate\n * management.\n * See {@link Session} For class responsibilities\n * @param stream Represents the transport stream for signaling messages.\n * @param config Configuration object for the RTCPeerConnection.\n */\n constructor(\n private readonly stream: Stream,\n config: RTCConfiguration,\n ) {\n this.pc = new RTCPeerConnection(config);\n\n this.makingOffer = false;\n this.pendingCandidates = [];\n // Higher is impolite. [0-15] is reserved. One of the reserved value can be used\n // for implementing fixed \"polite\" role for lite ICE.\n if (this.stream.connId === this.stream.otherConnId) {\n this.impolite = this.stream.peerId > this.stream.otherPeerId;\n } else {\n this.impolite = this.stream.connId > this.stream.otherConnId;\n }\n this.abort = new AbortController();\n this.logger = stream.logger.sub(\"session\", {\n role: this.impolite ? \"impolite\" : \"polite\",\n });\n this.generationCounter = 0;\n this.iceRestartCount = 0;\n this.lastIceRestart = 0;\n this.timers = [];\n this._connectionState = \"new\";\n stream.onpayload = (msg) => this.handleMessage(msg);\n stream.onclosed = (reason) => this.close(reason);\n\n this.pc.oniceconnectionstatechange = async () => {\n const stats = await this.pc.getStats();\n const pair: unknown[] = [];\n const local: unknown[] = [];\n const remote: unknown[] = [];\n // https://developer.mozilla.org/en-US/docs/Web/API/RTCStatsReport#the_statistic_types\n stats.forEach((report: RTCStats) => {\n if (report.type === \"candidate-pair\") {\n pair.push(report);\n } else if (report.type === \"local-candidate\") {\n local.push(report);\n } else if (report.type === \"remote-candidate\") {\n remote.push(report);\n }\n });\n\n this.logger.debug(\"iceconnectionstate changed\", {\n \"connectionstate\": this.pc.connectionState,\n \"iceconnectionstate\": this.pc.iceConnectionState,\n local,\n remote,\n pair,\n pending: this.pendingCandidates,\n });\n };\n\n let start = performance.now();\n this.pc.onconnectionstatechange = (ev) => {\n this.logger.debug(\"connectionstate changed\", {\n \"connectionstate\": this.pc.connectionState,\n \"iceconnectionstate\": this.pc.iceConnectionState,\n });\n this.setConnectionState(this.pc.connectionState, ev);\n switch (this.pc.connectionState) {\n case \"connecting\":\n start = performance.now();\n break;\n case \"connected\": {\n const elapsed = performance.now() - start;\n this.logger.debug(`it took ${elapsed}ms to connect`);\n this.iceRestartCount = 0;\n break;\n }\n case \"disconnected\":\n this.triggerIceRestart();\n break;\n case \"failed\":\n this.close(\"detected sustained network failure\");\n break;\n case \"closed\":\n break;\n }\n };\n let firstOffer = true;\n this.pc.onnegotiationneeded = async () => {\n if (firstOffer) {\n if (!this.impolite) {\n // the impolite always initiates with an offer\n this.stream.send({\n payloadType: {\n oneofKind: \"join\",\n join: {},\n },\n }, true);\n return;\n }\n firstOffer = false;\n }\n\n try {\n this.makingOffer = true;\n this.logger.debug(\"creating an offer\");\n await this.pc.setLocalDescription();\n if (!this.pc.localDescription) {\n throw new Error(\"expect localDescription to be not empty\");\n }\n\n this.sendSignal({\n data: {\n oneofKind: \"sdp\",\n sdp: {\n kind: fromSDPType(this.pc.localDescription.type),\n sdp: this.pc.localDescription.sdp,\n },\n },\n });\n } catch (err) {\n if (err instanceof Error) {\n this.logger.error(\"failed in negotiating\", { err });\n }\n } finally {\n this.makingOffer = false;\n }\n };\n\n this.pc.onicecandidate = ({ candidate }) => {\n this.logger.debug(\"onicecandidate\", { candidate });\n const ice: ICECandidate = {\n candidate: \"\",\n sdpMLineIndex: 0,\n sdpMid: \"\",\n };\n if (!candidate || candidate.candidate === \"\") {\n this.logger.debug(\"ice gathering is finished\");\n return;\n }\n\n ice.candidate = candidate.candidate;\n ice.sdpMLineIndex = candidate.sdpMLineIndex ?? undefined;\n ice.sdpMid = candidate.sdpMid ?? undefined;\n ice.username = candidate.usernameFragment ?? undefined;\n\n this.sendSignal({\n data: {\n oneofKind: \"iceCandidate\",\n iceCandidate: ice,\n },\n });\n };\n\n this.pc.ondatachannel = (...args) => {\n if (this.ondatachannel) {\n // @ts-ignore: proxy to RTCPeerConnection\n this.ondatachannel(...args);\n }\n };\n\n this.pc.ontrack = (...args) => {\n if (this.ontrack) {\n // @ts-ignore: proxy to RTCPeerConnection\n this.ontrack(...args);\n }\n };\n }\n\n /** internal @private */\n private setConnectionState(s: RTCPeerConnectionState, ev: Event): void {\n if (s === this._connectionState) return;\n\n if (this.onconnectionstatechange) {\n // @ts-ignore: proxy to RTCPeerConnection\n this.onconnectionstatechange(ev);\n }\n }\n\n private triggerIceRestart = () => {\n // the impolite offer will trigger the polite peer's to also restart Ice\n if (!this.impolite) return;\n\n const elapsed = performance.now() - this.lastIceRestart;\n if (elapsed < ICE_RESTART_DEBOUNCE_DELAY_MS) {\n // schedule ice restart after some delay;\n const delay = ICE_RESTART_DEBOUNCE_DELAY_MS - elapsed;\n const timerId = window.setTimeout(() => {\n this.triggerIceRestart();\n this.timers = this.timers.filter((v) => v === timerId);\n }, delay);\n return;\n }\n\n if (this.pc.connectionState === \"connected\") return;\n if (this.iceRestartCount >= ICE_RESTART_MAX_COUNT) this.close();\n this.logger.debug(\"triggered ICE restart\");\n this.pc.restartIce();\n this.generationCounter++;\n this.iceRestartCount++;\n this.lastIceRestart = performance.now();\n };\n\n private sendSignal = (signal: Omit<Signal, \"generationCounter\">) => {\n this.stream.send({\n payloadType: {\n oneofKind: \"signal\",\n signal: { ...signal, generationCounter: this.generationCounter },\n },\n }, true);\n };\n\n private handleMessage = async (payload: MessagePayload) => {\n if (this.abort.signal.aborted) {\n this.logger.warn(\"session is closed, ignoring message\");\n return;\n }\n switch (payload.payloadType.oneofKind) {\n case \"signal\":\n await this.handleSignal(payload.payloadType.signal);\n break;\n case \"bye\":\n this.close();\n break;\n case \"join\":\n // nothing to do here. SDK consumer needs to manually trigger the start\n break;\n }\n };\n\n private handleSignal = async (signal: Signal) => {\n if (signal.generationCounter < this.generationCounter) {\n this.logger.warn(\"detected staled generationCounter signals, ignoring\");\n return;\n }\n\n const msg = signal.data;\n if (signal.generationCounter > this.generationCounter) {\n // Sync generationCounter so this peer can reset its state machine\n // to start accepting new offers\n this.logger.debug(\"detected new generationCounter\", {\n otherGenerationCounter: signal.generationCounter,\n generationCounter: this.generationCounter,\n msg,\n });\n\n if (msg.oneofKind === \"iceCandidate\") {\n const ice = toIceCandidate(msg.iceCandidate);\n this.pendingCandidates.push(ice);\n this.logger.warn(\n \"expecting an offer but got ice candidates during an ICE restart, adding to pending.\",\n { ice, msg },\n );\n return;\n }\n\n this.generationCounter = signal.generationCounter;\n }\n\n if (msg.oneofKind === \"iceCandidate\") {\n const ice = toIceCandidate(msg.iceCandidate);\n this.pendingCandidates.push(ice);\n this.checkPendingCandidates();\n\n return;\n }\n\n if (msg.oneofKind != \"sdp\") {\n return;\n }\n\n const sdp = msg.sdp;\n this.logger.debug(\"received a SDP signal\", { sdpKind: sdp.kind });\n const offerCollision = sdp.kind === SdpKind.OFFER &&\n (this.makingOffer || this.pc.signalingState !== \"stable\");\n\n const ignoreOffer = this.impolite && offerCollision;\n if (ignoreOffer) {\n this.logger.debug(\"ignored offer\");\n return;\n }\n\n this.logger.debug(\"creating an answer\");\n await this.pc.setRemoteDescription({\n type: toSDPType(sdp.kind),\n sdp: sdp.sdp,\n });\n if (sdp.kind === SdpKind.OFFER) {\n await this.pc.setLocalDescription();\n if (!this.pc.localDescription) {\n this.logger.error(\"unexpected null local description\");\n return;\n }\n\n // when a signal is retried many times and still failing. The failing heartbeat will kick in and close.\n this.sendSignal({\n data: {\n oneofKind: \"sdp\",\n sdp: {\n kind: fromSDPType(this.pc.localDescription.type),\n sdp: this.pc.localDescription.sdp,\n },\n },\n });\n }\n\n this.checkPendingCandidates();\n return;\n };\n\n private checkPendingCandidates = () => {\n const safeStates: RTCSignalingState[] = [\n \"stable\",\n \"have-local-offer\",\n \"have-remote-offer\",\n ];\n if (\n !safeStates.includes(this.pc.signalingState) || !this.pc.remoteDescription\n ) {\n this.logger.debug(\"wait for adding pending candidates\", {\n signalingState: this.pc.signalingState,\n iceConnectionState: this.pc.iceConnectionState,\n connectionState: this.pc.connectionState,\n remoteDescription: this.pc.remoteDescription,\n pendingCandidates: this.pendingCandidates.length,\n });\n return;\n }\n\n for (const candidate of this.pendingCandidates) {\n if (!candidate.candidate || candidate.candidate === \"\") {\n continue;\n }\n\n // intentionally not awaiting, otherwise we might be in a different state than we originally\n // checked.\n this.pc.addIceCandidate(candidate).catch((e) => {\n this.logger.warn(\"failed to add candidate, skipping.\", {\n candidate,\n e,\n });\n });\n this.logger.debug(`added ice: ${candidate.candidate}`);\n }\n this.pendingCandidates = [];\n };\n}\n","import { type ITunnelClient, TunnelClient } from \"./tunnel.client.ts\";\nimport { Transport } from \"./transport.ts\";\nimport { DEFAULT_LOG_SINK, Logger, PRETTY_LOG_SINK } from \"./logger.ts\";\nimport { Session } from \"./session.ts\";\nimport { RpcError, RpcOptions, UnaryCall } from \"@protobuf-ts/runtime-rpc\";\nimport {\n TwirpErrorCode,\n TwirpFetchTransport,\n} from \"@protobuf-ts/twirp-transport\";\nimport { retry } from \"./util.ts\";\nimport { jwtDecode } from \"jwt-decode\";\n\n/**\n * Streamline real-time application development.`@pulsebeam/peer` abstracts\n * networking, connection management, and signaling for applications. Built on\n * WebRTC. PulseBeam handles peer-to-peer communication, media/data transmission,\n * and provides infrastructure.\n *\n * A JavaScript SDK for creating real-time applications with WebRTC.\n *\n * # Features\n * - Flexible connection modes: peer-to-peer or server-relayed.\n * - Support for media (audio/video) and data channels.\n * - Abstracted signaling for establishing WebRTC connections.\n * - Auto-reconnect during disruptions or dropped connections.\n *\n * For more on PulseBeam, see our docs and quickstart guide:\n * {@link https://pulsebeam.dev/docs/getting-started/}\n *\n * For more on WebRTC, see the official documentation:\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API}\n *\n * # Example Usage\n *\n * Request an authentication token, initialize a peer instance, and establish a connection:\n *\n * ```ts\n * import { Peer, createPeer } from \"@pulsebeam/peer\";\n *\n * // Step 1: Obtain an auth token\n * const authResponse = await fetch(\"/auth\");\n * const { groupId, peerId, token } = await authResponse.json();\n *\n * // Step 2: Create a Peer instance\n * const peer = await createPeer({ groupId, peerId, token });\n *\n * peer.onsession = (session) => {\n * session.ontrack = ({ streams }) => console.log(\"New media stream:\", streams);\n * session.ondatachannel = (event) => console.log(\"Data channel:\", event.channel);\n * session.onconnectionstatechange = () => console.log(\"Connection state changed\");\n * };\n *\n * // Step 3: Connect to another peer\n * peer.start();\n *\n * const abortController = new AbortController();\n * await peer.connect(groupId, \"other-peer-id\", abortController.signal);\n * ```\n *\n * This module provides a framework for building WebRTC applications while\n * leaving room for custom implementation details.\n *\n * @module\n */\n\nconst BASE_URL = \"https://cloud.pulsebeam.dev/twirp\";\nconst PREPARE_INITIAL_DELAY_MS = 50;\nconst PREPARE_MAX_RETRY = 3;\n\n/**\n * A high-level API for managing the peer-to-peer WebRTC connection. Provides\n * access to lower-level {@link RTCPeerConnection} functionality. Including\n * access to underlying media tracks, data channels, and connection state.\n *\n * Usage:\n * @example `peer.onsession = (session) => {console.log(session.otherPeerId())};`\n */\nexport interface ISession {\n /**\n * Adds a media track to the connection. Typically used for sending audio or video.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack}\n * @returns {RTCRtpSender}\n */\n addTrack(...args: Parameters<RTCPeerConnection[\"addTrack\"]>): RTCRtpSender;\n\n /**\n * Removes a media track from the connection. Useful for stopping\n * transmission of a specific track.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/removeTrack}\n * @returns {void}\n */\n removeTrack(...args: Parameters<RTCPeerConnection[\"removeTrack\"]>): void;\n\n /**\n * Creates a {@link RTCDataChannel} on the connection for arbitrary data transfer.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createDataChannel}\n */\n createDataChannel(\n ...args: Parameters<RTCPeerConnection[\"createDataChannel\"]>\n ): RTCDataChannel;\n\n /**\n * Retrieves the current connection state of the underlying RTCPeerConnection\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState}\n * @returns {RTCPeerConnectionState}\n */\n get connectionState(): RTCPeerConnectionState;\n\n /**\n * Callback triggered when a {@link RTCDataChannel} is created or received.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/ondatachannel}\n * @example ```peer.onsession = (session) => {\n * session.ondatachannel = (event) => {\n * const channel = event.channel;\n * channel.onmessage = (e) => console.log(\"Received message:\", e.data);\n * };```\n */\n ondatachannel: RTCPeerConnection[\"ondatachannel\"];\n\n /**\n * Callback triggered when the connection state changes.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/onconnectionstatechange}\n */\n onconnectionstatechange: RTCPeerConnection[\"onconnectionstatechange\"];\n\n /**\n * Callback invoked when a new media track is added to the connection.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/ontrack}\n */\n ontrack: RTCPeerConnection[\"ontrack\"];\n\n /**\n * Closes the session, aborting all pending tasks, and cleaning up resources.\n * Publishes events and logs about the closure.\n * @param {string} [reason] - (optional) A reason for closing the session.\n * @returns {void}\n * @example `mysession.close(\"Session ended by user\");`\n */\n close(reason?: string): void;\n\n // Below is PulseBeam specific functionality. Unrelated to\n // the underlying RTCPeerConnection\n\n /**\n * Retrieves the identifier of the other peer in the connection.\n * @returns {string} The peer ID of the connected peer. Valid UTF-8 string of 1-16 characters.\n * @example ```console.log(`Connected to peer: ${session.otherPeerId()}`);```\n */\n get otherPeerId(): string;\n\n /**\n * Retrieves the connection identifier for the current connection.\n * Connection IDs are typically unique and help identify connections.\n * @returns {number} The connection ID for the peer connection.\n * @example\n * ```console.log(`Connection ID: ${mySession.otherConnId()}`);```\n */\n get otherConnId(): number;\n}\n\n/**\n * Intended to be used by for internal and advanced usecases.\n * Options used to configure a Peer.\n * @interface PeerOptionsFull\n * @example```\n * const options: PeerOptionsFull = {\n * groupId: \"group-123\", // Valid UTF-8 strings of 1-16 characters.\n * peerId: \"peer-456\", // Valid UTF-8 strings of 1-16 characters.\n * token: \"eyJhbGc...49nLmBCg\"\n * };```\n */\nexport interface PeerOptionsFull {\n /**\n * Identifier for the group which the peer belongs to. Must be a valid UTF-8\n * string of 1-16 characters.\n * @type {string} groupId\n */\n groupId: string;\n\n /**\n * Identifier for the peer. Must be a valid UTF-8 string of 1-16 characters.\n * @type {string} peerId\n */\n peerId: string;\n\n /**\n * PulseBeam authentication token for the peer. JWT token generated by `jsr:@pulsebeam/server`\n * @type {string} token\n */\n token: string;\n\n /**\n * (Optional) Base URL for API calls. Defaults to using our servers: \"https://cloud.pulsebeam.dev/twirp\".\n * @type {string | undefined} [baseUrl]\n */\n baseUrl?: string;\n\n /**\n * (Optional) If true, enforces relay-only connections, such as those passed through a TURN server. Defaults to allowing all connection types (such as direct peer to peer). For more details see {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection#icetransportpolicy}\n * @type {boolean | undefined} [forceRelay]\n */\n forceRelay?: boolean;\n\n /**\n * (Optional) Add Ice Servers. Defaults to using our servers. For more details see {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection#iceservers}\n * @type {RTCIceServer[] | undefined} [iceServers]\n */\n iceServers?: RTCIceServer[];\n}\n\n/**\n * Options used to configure a Peer. See {@link PeerOptionsFull} for properties.\n * @interface PeerOptions\n * @example```\n * const options: PeerOptions = {\n * token: \"eyJhbGc...49nLmBCg\" // fetch token\n * };```\n */\nexport type PeerOptions = Omit<PeerOptionsFull, \"groupId\" | \"peerId\">;\n\n/**\n * Represents the possible states for a Peer.\n *\n * @readonly\n * @enum {string}\n * Possible values:\n * - `\"new\"`: The peer has been created.\n * - `\"closed\"`: The peer has been closed.\n */\nexport type PeerState = \"new\" | \"closed\";\n\n/**\n * Peer is a mediator for signaling, connecting, and managing sessions.\n */\nexport class Peer {\n private transport: Transport;\n private readonly logger: Logger;\n private sessions: Session[];\n private _state: PeerState;\n\n /**\n * Callback invoked when a new session is established.\n * @param _s Session object\n */\n public onsession = (_s: ISession) => { };\n /**\n * Callback invoked when the peer’s state changes.\n */\n public onstatechange = () => { };\n /**\n * Identifier for the peer. Valid UTF-8 string of 1-16 characters.\n */\n public readonly peerId: string;\n\n /**\n * Construct a Peer. Helper available: see {@link createPeer} function\n * @param logger Logger instance for logging events.\n * @param client Tunnel client for signaling.\n * @param opts Configuration options for the peer.\n * @param isRecoverable Function to determine if an error is recoverable.\n */\n constructor(\n logger: Logger,\n client: ITunnelClient,\n opts: PeerOptionsFull,\n isRecoverable: (_err: unknown) => boolean,\n ) {\n this.peerId = opts.peerId;\n this.logger = logger.sub(\"peer\", { peerId: this.peerId });\n this.sessions = [];\n this._state = \"new\";\n\n const rtcConfig: RTCConfiguration = {\n bundlePolicy: \"balanced\",\n iceTransportPolicy: !!opts.forceRelay ? \"relay\" : \"all\",\n iceCandidatePoolSize: 0,\n iceServers: opts.iceServers,\n };\n this.transport = new Transport(client, {\n enableDiscovery: false,\n groupId: opts.groupId,\n peerId: opts.peerId,\n logger: this.logger,\n isRecoverable,\n });\n this.transport.onstream = (s) => {\n const sess = new Session(s, rtcConfig);\n this.sessions.push(sess);\n this.onsession(sess);\n };\n this.transport.onclosed = () => {\n this.close();\n };\n }\n\n /**\n * Starts the peer, making it ready to establish connections.\n * Peers must be started before a connection can occur.\n *\n * @returns {void}\n * @throws {Error} When the peer was previously closed.\n */\n start() {\n if (this._state === \"closed\") throw new Error(\"peer is already closed\");\n this.transport.listen();\n }\n\n /**\n * Closes the peer. Releases associated resources.\n * Signals to the AbortController passed to connect if connect was called.\n *\n * @async\n * @returns {Promise<void>} Resolves when the peer has been closed.\n */\n async close() {\n this.sessions = [];\n await this.transport.close();\n this.setState(\"closed\");\n }\n\n /**\n * Establishes a connection with another peer in the specified group.\n * Peer should be started before calling connect.\n *\n * Check the log output for troubleshooting information.\n *\n * @async\n * @param {string} otherGroupId The ID of the group the other peer belongs to.\n * Valid UTF-8 string of 1-16 characters.\n * @param {string} otherPeerId The ID of the peer you want to connect to.\n * Valid UTF-8 string of 1-16 characters.\n * @param {AbortSignal} signal Handle cancellations or cancel the connection attempt.\n * @returns {Promise<void>} Resolves when the connection has been established,\n * an unrecoverable error (e.g., network connection issues, internal errors) occurs,\n * or the maximum retry attempts are reached.\n */\n connect(\n otherGroupId: string,\n otherPeerId: string,\n signal: AbortSignal,\n ): Promise<void> {\n return this.transport.connect(otherGroupId, otherPeerId, signal);\n }\n\n /**\n * Gets the current state of the peer. For state info see {@link PeerState}\n * @returns {PeerState} The current state of the peer\n */\n get state(): PeerState {\n return this._state;\n }\n\n /** internal @private */\n private setState(s: PeerState): void {\n if (s === this._state) return;\n\n this._state = s;\n this.onstatechange();\n }\n}\n\nconst TWIRP_FATAL_ERRORS: string[] = [\n TwirpErrorCode[TwirpErrorCode.permission_denied],\n TwirpErrorCode[TwirpErrorCode.invalid_argument],\n TwirpErrorCode[TwirpErrorCode.aborted],\n TwirpErrorCode[TwirpErrorCode.bad_route],\n TwirpErrorCode[TwirpErrorCode.malformed],\n TwirpErrorCode[TwirpErrorCode.not_found],\n TwirpErrorCode[TwirpErrorCode.unauthenticated],\n];\n\nfunction isTwirpRecoverable(err: unknown): boolean {\n if (!(err instanceof Error)) {\n return false;\n }\n\n if (!(err instanceof RpcError)) {\n return true;\n }\n\n return !TWIRP_FATAL_ERRORS.includes(err.code);\n}\n\ninterface JwtClaims {\n gid: string;\n pid: string;\n}\n\n/**\n * Helper to create a new Peer instance\n * @param opts Configuration options for the peer.\n * @returns {Promise<Peer>} Resolves to the newly created Peer\n * @throws {Error} When unable to connect to signaling server. Likely networking issue.\n */\nexport async function createPeer(opts: PeerOptions): Promise<Peer> {\n // TODO: add hook for refresh token\n const token = opts.token;\n const twirp = new TwirpFetchTransport({\n baseUrl: opts.baseUrl || BASE_URL,\n sendJson: false,\n jsonOptions: {\n emitDefaultValues: true, // treat zero values as values instead of undefined.\n enumAsInteger: true,\n ignoreUnknownFields: true,\n },\n interceptors: [\n {\n // adds auth header to unary requests\n interceptUnary(next, method, input, options: RpcOptions): UnaryCall {\n if (!options.meta) {\n options.meta = {};\n }\n options.meta[\"Authorization\"] = `Bearer ${token}`;\n return next(method, input, options);\n },\n },\n ],\n });\n const client = new TunnelClient(twirp);\n\n const resp = await retry(\n async () => await client.prepare({}),\n {\n baseDelay: 50,\n maxDelay: 1000,\n maxRetries: 5,\n isRecoverable: isTwirpRecoverable,\n },\n );\n if (resp === null) {\n throw new Error(\"createPeer aborted\");\n }\n const iceServers = [...(opts.iceServers || [])];\n for (const s of resp.response.iceServers) {\n iceServers.push({\n urls: s.urls,\n username: s.username,\n credential: s.credential,\n });\n }\n const decoded = jwtDecode<JwtClaims>(token);\n const optsFull: PeerOptionsFull = {\n ...opts,\n \"iceServers\": iceServers,\n groupId: decoded.gid,\n peerId: decoded.pid,\n };\n const peer = new Peer(\n new Logger(\"pulsebeam\", undefined, PRETTY_LOG_SINK),\n client,\n optsFull,\n isTwirpRecoverable,\n );\n return peer;\n}\n"],"mappings":"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","names":["require_sdp","__commonJSMin","exports","module","SDPUtils","blob","line","part","index","sections","prefix","parts","candidate","i","sdp","component","type","parsed","codec","pt","channels","headerExtension","kv","j","params","param","lines","fb","sp","colon","ssrc","mediaSection","mid","sessionpart","setupType","fp","parameters","keyParams","ufrag","pwd","description","mline","rtpmapline","fmtps","wildcardRtcpFb","existingFeedback","kind","caps","maxptime","extension","encodingParameters","hasRed","hasUlpfec","ssrcs","primarySsrc","secondarySsrc","flows","encParam","bandwidth","rtcpParameters","remoteSsrc","obj","rsize","mux","spec","planB","msidParts","maxSizeLine","maxMessageSize","sctpPort","sctpMapLines","media","sctp","output","sessId","sessVer","sessUser","sessionId","version","peer_exports","__export","Peer","createPeer","__toCommonJS","logDisabled_","deprecationWarnings_","extractVersion","uastring","expr","pos","match","wrapPeerConnectionEvent","window","eventNameToWrap","wrapper","proto","nativeAddEventListener","nativeEventName","cb","wrappedCallback","e","modifiedEvent","nativeRemoveEventListener","unwrappedCb","disableLog","bool","disableWarnings","log","deprecated","oldMethod","newMethod","detectBrowser","result","navigator","chromium","brand","isObject","val","compactObject","data","accumulator","key","isObj","value","isEmptyObject","walkStats","stats","base","resultSet","name","id","filterStats","track","outbound","streamStatsType","filteredResult","trackStats","trackStat","chrome_shim_exports","__export","fixNegotiationNeeded","shimAddTrackRemoveTrack","shimAddTrackRemoveTrackWithNative","shimGetSendersWithDtmf","shimGetUserMedia","shimMediaStream","shimOnTrack","shimPeerConnection","shimSenderReceiverGetStats","logging","log","shimGetUserMedia","window","browserDetails","navigator","constraintsToChrome_","c","cc","key","r","oldname_","prefix","name","oc","mix","shimConstraints_","constraints","func","remap","obj","a","b","face","getSupportedFacingModeLies","matches","devices","d","dev","match","shimError_","e","getUserMedia_","onSuccess","onError","origGetUserMedia","cs","stream","track","shimMediaStream","window","shimOnTrack","f","origSetRemoteDescription","e","te","receiver","r","event","track","wrapPeerConnectionEvent","shimGetSendersWithDtmf","shimSenderWithDtmf","pc","origAddTrack","stream","sender","origRemoveTrack","idx","origAddStream","origRemoveStream","s","origGetSenders","senders","shimSenderReceiverGetStats","result","filterStats","origGetReceivers","receivers","origGetStats","err","shimAddTrackRemoveTrackWithNative","streamId","existingSenders","newSenders","newSender","shimAddTrackRemoveTrack","browserDetails","origGetLocalStreams","nativeStreams","newStream","streams","t","oldStream","replaceInternalStreamId","description","sdp","internalId","externalStream","internalStream","replaceExternalStreamId","method","nativeMethod","methodObj","args","desc","origSetLocalDescription","origLocalDescription","streamid","shimPeerConnection","fixNegotiationNeeded","firefox_shim_exports","__export","shimAddTransceiver","shimCreateAnswer","shimCreateOffer","shimGetDisplayMedia","shimGetParameters","shimGetUserMedia","shimOnTrack","shimPeerConnection","shimRTCDataChannel","shimReceiverGetStats","shimRemoveStream","shimSenderGetStats","shimGetUserMedia","window","browserDetails","navigator","MediaStreamTrack","constraints","onSuccess","onError","deprecated","remap","obj","b","nativeGetUserMedia","c","nativeGetSettings","nativeApplyConstraints","shimGetDisplayMedia","window","preferredMediaSource","constraints","err","shimOnTrack","window","shimPeerConnection","browserDetails","method","nativeMethod","methodObj","modernStatsTypes","nativeGetStats","selector","onSucc","onErr","stats","stat","e","i","shimSenderGetStats","origGetSenders","senders","sender","origAddTrack","shimReceiverGetStats","origGetReceivers","receivers","receiver","wrapPeerConnectionEvent","shimRemoveStream","stream","deprecated","shimRTCDataChannel","shimAddTransceiver","origAddTransceiver","sendEncodings","shouldPerformCheck","encodingParam","transceiver","params","shimGetParameters","origGetParameters","shimCreateOffer","origCreateOffer","shimCreateAnswer","origCreateAnswer","safari_shim_exports","__export","shimAudioContext","shimCallbacksAPI","shimConstraints","shimCreateOfferLegacy","shimGetUserMedia","shimLocalStreamsAPI","shimRTCIceServerUrls","shimRemoteStreamsAPI","shimTrackEventTransceiver","shimLocalStreamsAPI","window","_addTrack","stream","track","streams","index","tracks","sender","shimRemoteStreamsAPI","f","e","event","origSetRemoteDescription","pc","shimCallbacksAPI","prototype","origCreateOffer","origCreateAnswer","setLocalDescription","setRemoteDescription","addIceCandidate","successCallback","failureCallback","options","promise","withCallback","description","candidate","shimGetUserMedia","navigator","mediaDevices","_getUserMedia","constraints","shimConstraints","cb","errcb","compactObject","shimRTCIceServerUrls","OrigPeerConnection","pcConfig","pcConstraints","newIceServers","i","server","deprecated","shimTrackEventTransceiver","shimCreateOfferLegacy","offerOptions","audioTransceiver","transceiver","videoTransceiver","shimAudioContext","common_shim_exports","__export","removeExtmapAllowMixed","shimAddIceCandidateNullOrEmpty","shimConnectionState","shimMaxMessageSize","shimParameterlessSetLocalDescription","shimRTCIceCandidate","shimRTCIceCandidateRelayProtocol","shimSendThrowTypeError","import_sdp","shimRTCIceCandidate","window","NativeRTCIceCandidate","args","nativeCandidate","parsedCandidate","SDPUtils","key","wrapPeerConnectionEvent","e","shimRTCIceCandidateRelayProtocol","shimMaxMessageSize","browserDetails","sctpInDescription","description","sections","mediaSection","mLine","getRemoteFirefoxVersion","match","version","getCanSendMaxMessageSize","remoteIsFirefox","canSendMaxMessageSize","getMaxMessageSize","maxMessageSize","origSetRemoteDescription","sdpSemantics","isFirefox","canSendMMS","remoteMMS","sctp","shimSendThrowTypeError","wrapDcSend","dc","pc","origDataChannelSend","data","length","origCreateDataChannel","dataChannel","shimConnectionState","proto","cb","method","origMethod","newEvent","removeExtmapAllowMixed","nativeSRD","desc","sdp","line","shimAddIceCandidateNullOrEmpty","nativeAddIceCandidate","shimParameterlessSetLocalDescription","nativeSetLocalDescription","d","sdp","adapterFactory","window","options","logging","log","browserDetails","detectBrowser","adapter","common_shim_exports","extractVersion","disableLog","disableWarnings","chrome_shim_exports","shimPeerConnection","shimAddIceCandidateNullOrEmpty","shimParameterlessSetLocalDescription","shimGetUserMedia","shimMediaStream","shimOnTrack","shimAddTrackRemoveTrack","shimGetSendersWithDtmf","shimSenderReceiverGetStats","fixNegotiationNeeded","shimRTCIceCandidate","shimRTCIceCandidateRelayProtocol","shimConnectionState","shimMaxMessageSize","shimSendThrowTypeError","removeExtmapAllowMixed","firefox_shim_exports","shimRemoveStream","shimSenderGetStats","shimReceiverGetStats","shimRTCDataChannel","shimAddTransceiver","shimGetParameters","shimCreateOffer","shimCreateAnswer","safari_shim_exports","shimRTCIceServerUrls","shimCreateOfferLegacy","shimCallbacksAPI","shimLocalStreamsAPI","shimRemoteStreamsAPI","shimTrackEventTransceiver","shimAudioContext","adapter","adapterFactory","adapter_core_default","import_runtime_rpc","import_runtime","SdpKind","PrepareReq$Type","PrepareReq","PrepareResp$Type","IceServer","PrepareResp","IceServer$Type","SendReq$Type","Message","SendReq","SendResp$Type","SendResp","RecvReq$Type","PeerInfo","RecvReq","RecvResp$Type","RecvResp","PeerInfo$Type","Message$Type","MessageHeader","MessagePayload","MessagePayload$Type","Signal","Join","Bye","Ack","MessageHeader$Type","Signal$Type","Sdp","ICECandidate","Sdp$Type","ICECandidate$Type","Join$Type","Bye$Type","Ack$Type","AckRange","AckRange$Type","DataChannel$Type","DataChannelHeartbeat","DataChannel","DataChannelHeartbeat$Type","Tunnel","import_runtime_rpc","TunnelClient","_transport","Tunnel","input","options","method","opt","asleep","ms","signal","resolve","timeoutId","joinSignals","signals","joined","joinedAbort","retry","asyncFunction","options","maxRetries","baseDelay","maxDelay","jitterFactor","isRecoverable","abortSignal","attempt","error","delay","calculateDelay","exponentialDelay","jitter","POLL_TIMEOUT_MS","POLL_RETRY_BASE_DELAY_MS","POLL_RETRY_MAX_DELAY_MS","MAX_RELIABLE_RETRY_COUNT","STREAM_GC_DELAY_MS","STREAM_GC_INTERVAL_MS","defaultAsleep","asleep","defaultRandUint32","reserved","defaultIsRecoverable","_err","Queue","logger","_","msg","seqnum","res","key","value","m","err","obj","Transport","client","opts","_reason","msgs","stream","Stream","s","STREAM_GC_INTERVAL_MS","rpcOpt","POLL_TIMEOUT_MS","retryOpt","POLL_RETRY_BASE_DELAY_MS","POLL_RETRY_MAX_DELAY_MS","resp","retry","reason","otherGroupId","otherPeerId","signal","payload","header","found","joinedSignal","joinSignals","transport","otherConnId","signals","closed","STREAM_GC_DELAY_MS","reliable","resendLimit","MAX_RELIABLE_RETRY_COUNT","tryCount","message","reply","ack","DEFAULT_LOG_SINK","PRETTY_LOG_SINK","o","pretty","flatten","obj","pairs","parentKey","visited","sep","key","newKey","p","lines","k","Logger","_Logger","name","sink","handler","message","ICE_RESTART_MAX_COUNT","ICE_RESTART_DEBOUNCE_DELAY_MS","toIceCandidate","ice","toSDPType","kind","fromSDPType","t","Session","stream","config","elapsed","delay","timerId","v","signal","payload","msg","sdp","offerCollision","candidate","e","reason","stats","pair","local","remote","report","start","ev","firstOffer","err","args","timer","closeEvent","s","import_runtime_rpc","import_twirp_transport","import_jwt_decode","BASE_URL","Peer","logger","client","opts","isRecoverable","_s","rtcConfig","Transport","s","sess","Session","otherGroupId","otherPeerId","signal","TWIRP_FATAL_ERRORS","isTwirpRecoverable","err","createPeer","token","twirp","BASE_URL","next","method","input","options","TunnelClient","resp","retry","iceServers","decoded","optsFull","Logger","PRETTY_LOG_SINK","adapter_core_default"]}
|
1
|
+
{"version":3,"sources":["../../node_modules/sdp/sdp.js","../index.ts","../../node_modules/webrtc-adapter/src/js/utils.js","../../node_modules/webrtc-adapter/src/js/chrome/chrome_shim.js","../../node_modules/webrtc-adapter/src/js/chrome/getusermedia.js","../../node_modules/webrtc-adapter/src/js/firefox/firefox_shim.js","../../node_modules/webrtc-adapter/src/js/firefox/getusermedia.js","../../node_modules/webrtc-adapter/src/js/firefox/getdisplaymedia.js","../../node_modules/webrtc-adapter/src/js/safari/safari_shim.js","../../node_modules/webrtc-adapter/src/js/common_shim.js","../../node_modules/webrtc-adapter/src/js/adapter_factory.js","../../node_modules/webrtc-adapter/src/js/adapter_core.js","../tunnel.ts","../tunnel.client.ts","../util.ts","../transport.ts","../logger.ts","../session.ts","../peer.ts"],"sourcesContent":["/* eslint-env node */\n'use strict';\n\n// SDP helpers.\nconst SDPUtils = {};\n\n// Generate an alphanumeric identifier for cname or mids.\n// TODO: use UUIDs instead? https://gist.github.com/jed/982883\nSDPUtils.generateIdentifier = function() {\n return Math.random().toString(36).substring(2, 12);\n};\n\n// The RTCP CNAME used by all peerconnections from the same JS.\nSDPUtils.localCName = SDPUtils.generateIdentifier();\n\n// Splits SDP into lines, dealing with both CRLF and LF.\nSDPUtils.splitLines = function(blob) {\n return blob.trim().split('\\n').map(line => line.trim());\n};\n// Splits SDP into sessionpart and mediasections. Ensures CRLF.\nSDPUtils.splitSections = function(blob) {\n const parts = blob.split('\\nm=');\n return parts.map((part, index) => (index > 0 ?\n 'm=' + part : part).trim() + '\\r\\n');\n};\n\n// Returns the session description.\nSDPUtils.getDescription = function(blob) {\n const sections = SDPUtils.splitSections(blob);\n return sections && sections[0];\n};\n\n// Returns the individual media sections.\nSDPUtils.getMediaSections = function(blob) {\n const sections = SDPUtils.splitSections(blob);\n sections.shift();\n return sections;\n};\n\n// Returns lines that start with a certain prefix.\nSDPUtils.matchPrefix = function(blob, prefix) {\n return SDPUtils.splitLines(blob).filter(line => line.indexOf(prefix) === 0);\n};\n\n// Parses an ICE candidate line. Sample input:\n// candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8\n// rport 55996\"\n// Input can be prefixed with a=.\nSDPUtils.parseCandidate = function(line) {\n let parts;\n // Parse both variants.\n if (line.indexOf('a=candidate:') === 0) {\n parts = line.substring(12).split(' ');\n } else {\n parts = line.substring(10).split(' ');\n }\n\n const candidate = {\n foundation: parts[0],\n component: {1: 'rtp', 2: 'rtcp'}[parts[1]] || parts[1],\n protocol: parts[2].toLowerCase(),\n priority: parseInt(parts[3], 10),\n ip: parts[4],\n address: parts[4], // address is an alias for ip.\n port: parseInt(parts[5], 10),\n // skip parts[6] == 'typ'\n type: parts[7],\n };\n\n for (let i = 8; i < parts.length; i += 2) {\n switch (parts[i]) {\n case 'raddr':\n candidate.relatedAddress = parts[i + 1];\n break;\n case 'rport':\n candidate.relatedPort = parseInt(parts[i + 1], 10);\n break;\n case 'tcptype':\n candidate.tcpType = parts[i + 1];\n break;\n case 'ufrag':\n candidate.ufrag = parts[i + 1]; // for backward compatibility.\n candidate.usernameFragment = parts[i + 1];\n break;\n default: // extension handling, in particular ufrag. Don't overwrite.\n if (candidate[parts[i]] === undefined) {\n candidate[parts[i]] = parts[i + 1];\n }\n break;\n }\n }\n return candidate;\n};\n\n// Translates a candidate object into SDP candidate attribute.\n// This does not include the a= prefix!\nSDPUtils.writeCandidate = function(candidate) {\n const sdp = [];\n sdp.push(candidate.foundation);\n\n const component = candidate.component;\n if (component === 'rtp') {\n sdp.push(1);\n } else if (component === 'rtcp') {\n sdp.push(2);\n } else {\n sdp.push(component);\n }\n sdp.push(candidate.protocol.toUpperCase());\n sdp.push(candidate.priority);\n sdp.push(candidate.address || candidate.ip);\n sdp.push(candidate.port);\n\n const type = candidate.type;\n sdp.push('typ');\n sdp.push(type);\n if (type !== 'host' && candidate.relatedAddress &&\n candidate.relatedPort) {\n sdp.push('raddr');\n sdp.push(candidate.relatedAddress);\n sdp.push('rport');\n sdp.push(candidate.relatedPort);\n }\n if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {\n sdp.push('tcptype');\n sdp.push(candidate.tcpType);\n }\n if (candidate.usernameFragment || candidate.ufrag) {\n sdp.push('ufrag');\n sdp.push(candidate.usernameFragment || candidate.ufrag);\n }\n return 'candidate:' + sdp.join(' ');\n};\n\n// Parses an ice-options line, returns an array of option tags.\n// Sample input:\n// a=ice-options:foo bar\nSDPUtils.parseIceOptions = function(line) {\n return line.substring(14).split(' ');\n};\n\n// Parses a rtpmap line, returns RTCRtpCoddecParameters. Sample input:\n// a=rtpmap:111 opus/48000/2\nSDPUtils.parseRtpMap = function(line) {\n let parts = line.substring(9).split(' ');\n const parsed = {\n payloadType: parseInt(parts.shift(), 10), // was: id\n };\n\n parts = parts[0].split('/');\n\n parsed.name = parts[0];\n parsed.clockRate = parseInt(parts[1], 10); // was: clockrate\n parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1;\n // legacy alias, got renamed back to channels in ORTC.\n parsed.numChannels = parsed.channels;\n return parsed;\n};\n\n// Generates a rtpmap line from RTCRtpCodecCapability or\n// RTCRtpCodecParameters.\nSDPUtils.writeRtpMap = function(codec) {\n let pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n const channels = codec.channels || codec.numChannels || 1;\n return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate +\n (channels !== 1 ? '/' + channels : '') + '\\r\\n';\n};\n\n// Parses a extmap line (headerextension from RFC 5285). Sample input:\n// a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\n// a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset\nSDPUtils.parseExtmap = function(line) {\n const parts = line.substring(9).split(' ');\n return {\n id: parseInt(parts[0], 10),\n direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv',\n uri: parts[1],\n attributes: parts.slice(2).join(' '),\n };\n};\n\n// Generates an extmap line from RTCRtpHeaderExtensionParameters or\n// RTCRtpHeaderExtension.\nSDPUtils.writeExtmap = function(headerExtension) {\n return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) +\n (headerExtension.direction && headerExtension.direction !== 'sendrecv'\n ? '/' + headerExtension.direction\n : '') +\n ' ' + headerExtension.uri +\n (headerExtension.attributes ? ' ' + headerExtension.attributes : '') +\n '\\r\\n';\n};\n\n// Parses a fmtp line, returns dictionary. Sample input:\n// a=fmtp:96 vbr=on;cng=on\n// Also deals with vbr=on; cng=on\nSDPUtils.parseFmtp = function(line) {\n const parsed = {};\n let kv;\n const parts = line.substring(line.indexOf(' ') + 1).split(';');\n for (let j = 0; j < parts.length; j++) {\n kv = parts[j].trim().split('=');\n parsed[kv[0].trim()] = kv[1];\n }\n return parsed;\n};\n\n// Generates a fmtp line from RTCRtpCodecCapability or RTCRtpCodecParameters.\nSDPUtils.writeFmtp = function(codec) {\n let line = '';\n let pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n if (codec.parameters && Object.keys(codec.parameters).length) {\n const params = [];\n Object.keys(codec.parameters).forEach(param => {\n if (codec.parameters[param] !== undefined) {\n params.push(param + '=' + codec.parameters[param]);\n } else {\n params.push(param);\n }\n });\n line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\\r\\n';\n }\n return line;\n};\n\n// Parses a rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:\n// a=rtcp-fb:98 nack rpsi\nSDPUtils.parseRtcpFb = function(line) {\n const parts = line.substring(line.indexOf(' ') + 1).split(' ');\n return {\n type: parts.shift(),\n parameter: parts.join(' '),\n };\n};\n\n// Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.\nSDPUtils.writeRtcpFb = function(codec) {\n let lines = '';\n let pt = codec.payloadType;\n if (codec.preferredPayloadType !== undefined) {\n pt = codec.preferredPayloadType;\n }\n if (codec.rtcpFeedback && codec.rtcpFeedback.length) {\n // FIXME: special handling for trr-int?\n codec.rtcpFeedback.forEach(fb => {\n lines += 'a=rtcp-fb:' + pt + ' ' + fb.type +\n (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') +\n '\\r\\n';\n });\n }\n return lines;\n};\n\n// Parses a RFC 5576 ssrc media attribute. Sample input:\n// a=ssrc:3735928559 cname:something\nSDPUtils.parseSsrcMedia = function(line) {\n const sp = line.indexOf(' ');\n const parts = {\n ssrc: parseInt(line.substring(7, sp), 10),\n };\n const colon = line.indexOf(':', sp);\n if (colon > -1) {\n parts.attribute = line.substring(sp + 1, colon);\n parts.value = line.substring(colon + 1);\n } else {\n parts.attribute = line.substring(sp + 1);\n }\n return parts;\n};\n\n// Parse a ssrc-group line (see RFC 5576). Sample input:\n// a=ssrc-group:semantics 12 34\nSDPUtils.parseSsrcGroup = function(line) {\n const parts = line.substring(13).split(' ');\n return {\n semantics: parts.shift(),\n ssrcs: parts.map(ssrc => parseInt(ssrc, 10)),\n };\n};\n\n// Extracts the MID (RFC 5888) from a media section.\n// Returns the MID or undefined if no mid line was found.\nSDPUtils.getMid = function(mediaSection) {\n const mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0];\n if (mid) {\n return mid.substring(6);\n }\n};\n\n// Parses a fingerprint line for DTLS-SRTP.\nSDPUtils.parseFingerprint = function(line) {\n const parts = line.substring(14).split(' ');\n return {\n algorithm: parts[0].toLowerCase(), // algorithm is case-sensitive in Edge.\n value: parts[1].toUpperCase(), // the definition is upper-case in RFC 4572.\n };\n};\n\n// Extracts DTLS parameters from SDP media section or sessionpart.\n// FIXME: for consistency with other functions this should only\n// get the fingerprint line as input. See also getIceParameters.\nSDPUtils.getDtlsParameters = function(mediaSection, sessionpart) {\n const lines = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=fingerprint:');\n // Note: a=setup line is ignored since we use the 'auto' role in Edge.\n return {\n role: 'auto',\n fingerprints: lines.map(SDPUtils.parseFingerprint),\n };\n};\n\n// Serializes DTLS parameters to SDP.\nSDPUtils.writeDtlsParameters = function(params, setupType) {\n let sdp = 'a=setup:' + setupType + '\\r\\n';\n params.fingerprints.forEach(fp => {\n sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\\r\\n';\n });\n return sdp;\n};\n\n// Parses a=crypto lines into\n// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#dictionary-rtcsrtpsdesparameters-members\nSDPUtils.parseCryptoLine = function(line) {\n const parts = line.substring(9).split(' ');\n return {\n tag: parseInt(parts[0], 10),\n cryptoSuite: parts[1],\n keyParams: parts[2],\n sessionParams: parts.slice(3),\n };\n};\n\nSDPUtils.writeCryptoLine = function(parameters) {\n return 'a=crypto:' + parameters.tag + ' ' +\n parameters.cryptoSuite + ' ' +\n (typeof parameters.keyParams === 'object'\n ? SDPUtils.writeCryptoKeyParams(parameters.keyParams)\n : parameters.keyParams) +\n (parameters.sessionParams ? ' ' + parameters.sessionParams.join(' ') : '') +\n '\\r\\n';\n};\n\n// Parses the crypto key parameters into\n// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#rtcsrtpkeyparam*\nSDPUtils.parseCryptoKeyParams = function(keyParams) {\n if (keyParams.indexOf('inline:') !== 0) {\n return null;\n }\n const parts = keyParams.substring(7).split('|');\n return {\n keyMethod: 'inline',\n keySalt: parts[0],\n lifeTime: parts[1],\n mkiValue: parts[2] ? parts[2].split(':')[0] : undefined,\n mkiLength: parts[2] ? parts[2].split(':')[1] : undefined,\n };\n};\n\nSDPUtils.writeCryptoKeyParams = function(keyParams) {\n return keyParams.keyMethod + ':'\n + keyParams.keySalt +\n (keyParams.lifeTime ? '|' + keyParams.lifeTime : '') +\n (keyParams.mkiValue && keyParams.mkiLength\n ? '|' + keyParams.mkiValue + ':' + keyParams.mkiLength\n : '');\n};\n\n// Extracts all SDES parameters.\nSDPUtils.getCryptoParameters = function(mediaSection, sessionpart) {\n const lines = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=crypto:');\n return lines.map(SDPUtils.parseCryptoLine);\n};\n\n// Parses ICE information from SDP media section or sessionpart.\n// FIXME: for consistency with other functions this should only\n// get the ice-ufrag and ice-pwd lines as input.\nSDPUtils.getIceParameters = function(mediaSection, sessionpart) {\n const ufrag = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=ice-ufrag:')[0];\n const pwd = SDPUtils.matchPrefix(mediaSection + sessionpart,\n 'a=ice-pwd:')[0];\n if (!(ufrag && pwd)) {\n return null;\n }\n return {\n usernameFragment: ufrag.substring(12),\n password: pwd.substring(10),\n };\n};\n\n// Serializes ICE parameters to SDP.\nSDPUtils.writeIceParameters = function(params) {\n let sdp = 'a=ice-ufrag:' + params.usernameFragment + '\\r\\n' +\n 'a=ice-pwd:' + params.password + '\\r\\n';\n if (params.iceLite) {\n sdp += 'a=ice-lite\\r\\n';\n }\n return sdp;\n};\n\n// Parses the SDP media section and returns RTCRtpParameters.\nSDPUtils.parseRtpParameters = function(mediaSection) {\n const description = {\n codecs: [],\n headerExtensions: [],\n fecMechanisms: [],\n rtcp: [],\n };\n const lines = SDPUtils.splitLines(mediaSection);\n const mline = lines[0].split(' ');\n description.profile = mline[2];\n for (let i = 3; i < mline.length; i++) { // find all codecs from mline[3..]\n const pt = mline[i];\n const rtpmapline = SDPUtils.matchPrefix(\n mediaSection, 'a=rtpmap:' + pt + ' ')[0];\n if (rtpmapline) {\n const codec = SDPUtils.parseRtpMap(rtpmapline);\n const fmtps = SDPUtils.matchPrefix(\n mediaSection, 'a=fmtp:' + pt + ' ');\n // Only the first a=fmtp:<pt> is considered.\n codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};\n codec.rtcpFeedback = SDPUtils.matchPrefix(\n mediaSection, 'a=rtcp-fb:' + pt + ' ')\n .map(SDPUtils.parseRtcpFb);\n description.codecs.push(codec);\n // parse FEC mechanisms from rtpmap lines.\n switch (codec.name.toUpperCase()) {\n case 'RED':\n case 'ULPFEC':\n description.fecMechanisms.push(codec.name.toUpperCase());\n break;\n default: // only RED and ULPFEC are recognized as FEC mechanisms.\n break;\n }\n }\n }\n SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(line => {\n description.headerExtensions.push(SDPUtils.parseExtmap(line));\n });\n const wildcardRtcpFb = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:* ')\n .map(SDPUtils.parseRtcpFb);\n description.codecs.forEach(codec => {\n wildcardRtcpFb.forEach(fb=> {\n const duplicate = codec.rtcpFeedback.find(existingFeedback => {\n return existingFeedback.type === fb.type &&\n existingFeedback.parameter === fb.parameter;\n });\n if (!duplicate) {\n codec.rtcpFeedback.push(fb);\n }\n });\n });\n // FIXME: parse rtcp.\n return description;\n};\n\n// Generates parts of the SDP media section describing the capabilities /\n// parameters.\nSDPUtils.writeRtpDescription = function(kind, caps) {\n let sdp = '';\n\n // Build the mline.\n sdp += 'm=' + kind + ' ';\n sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.\n sdp += ' ' + (caps.profile || 'UDP/TLS/RTP/SAVPF') + ' ';\n sdp += caps.codecs.map(codec => {\n if (codec.preferredPayloadType !== undefined) {\n return codec.preferredPayloadType;\n }\n return codec.payloadType;\n }).join(' ') + '\\r\\n';\n\n sdp += 'c=IN IP4 0.0.0.0\\r\\n';\n sdp += 'a=rtcp:9 IN IP4 0.0.0.0\\r\\n';\n\n // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.\n caps.codecs.forEach(codec => {\n sdp += SDPUtils.writeRtpMap(codec);\n sdp += SDPUtils.writeFmtp(codec);\n sdp += SDPUtils.writeRtcpFb(codec);\n });\n let maxptime = 0;\n caps.codecs.forEach(codec => {\n if (codec.maxptime > maxptime) {\n maxptime = codec.maxptime;\n }\n });\n if (maxptime > 0) {\n sdp += 'a=maxptime:' + maxptime + '\\r\\n';\n }\n\n if (caps.headerExtensions) {\n caps.headerExtensions.forEach(extension => {\n sdp += SDPUtils.writeExtmap(extension);\n });\n }\n // FIXME: write fecMechanisms.\n return sdp;\n};\n\n// Parses the SDP media section and returns an array of\n// RTCRtpEncodingParameters.\nSDPUtils.parseRtpEncodingParameters = function(mediaSection) {\n const encodingParameters = [];\n const description = SDPUtils.parseRtpParameters(mediaSection);\n const hasRed = description.fecMechanisms.indexOf('RED') !== -1;\n const hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1;\n\n // filter a=ssrc:... cname:, ignore PlanB-msid\n const ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(line => SDPUtils.parseSsrcMedia(line))\n .filter(parts => parts.attribute === 'cname');\n const primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;\n let secondarySsrc;\n\n const flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID')\n .map(line => {\n const parts = line.substring(17).split(' ');\n return parts.map(part => parseInt(part, 10));\n });\n if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {\n secondarySsrc = flows[0][1];\n }\n\n description.codecs.forEach(codec => {\n if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) {\n let encParam = {\n ssrc: primarySsrc,\n codecPayloadType: parseInt(codec.parameters.apt, 10),\n };\n if (primarySsrc && secondarySsrc) {\n encParam.rtx = {ssrc: secondarySsrc};\n }\n encodingParameters.push(encParam);\n if (hasRed) {\n encParam = JSON.parse(JSON.stringify(encParam));\n encParam.fec = {\n ssrc: primarySsrc,\n mechanism: hasUlpfec ? 'red+ulpfec' : 'red',\n };\n encodingParameters.push(encParam);\n }\n }\n });\n if (encodingParameters.length === 0 && primarySsrc) {\n encodingParameters.push({\n ssrc: primarySsrc,\n });\n }\n\n // we support both b=AS and b=TIAS but interpret AS as TIAS.\n let bandwidth = SDPUtils.matchPrefix(mediaSection, 'b=');\n if (bandwidth.length) {\n if (bandwidth[0].indexOf('b=TIAS:') === 0) {\n bandwidth = parseInt(bandwidth[0].substring(7), 10);\n } else if (bandwidth[0].indexOf('b=AS:') === 0) {\n // use formula from JSEP to convert b=AS to TIAS value.\n bandwidth = parseInt(bandwidth[0].substring(5), 10) * 1000 * 0.95\n - (50 * 40 * 8);\n } else {\n bandwidth = undefined;\n }\n encodingParameters.forEach(params => {\n params.maxBitrate = bandwidth;\n });\n }\n return encodingParameters;\n};\n\n// parses http://draft.ortc.org/#rtcrtcpparameters*\nSDPUtils.parseRtcpParameters = function(mediaSection) {\n const rtcpParameters = {};\n\n // Gets the first SSRC. Note that with RTX there might be multiple\n // SSRCs.\n const remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(line => SDPUtils.parseSsrcMedia(line))\n .filter(obj => obj.attribute === 'cname')[0];\n if (remoteSsrc) {\n rtcpParameters.cname = remoteSsrc.value;\n rtcpParameters.ssrc = remoteSsrc.ssrc;\n }\n\n // Edge uses the compound attribute instead of reducedSize\n // compound is !reducedSize\n const rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize');\n rtcpParameters.reducedSize = rsize.length > 0;\n rtcpParameters.compound = rsize.length === 0;\n\n // parses the rtcp-mux attrіbute.\n // Note that Edge does not support unmuxed RTCP.\n const mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux');\n rtcpParameters.mux = mux.length > 0;\n\n return rtcpParameters;\n};\n\nSDPUtils.writeRtcpParameters = function(rtcpParameters) {\n let sdp = '';\n if (rtcpParameters.reducedSize) {\n sdp += 'a=rtcp-rsize\\r\\n';\n }\n if (rtcpParameters.mux) {\n sdp += 'a=rtcp-mux\\r\\n';\n }\n if (rtcpParameters.ssrc !== undefined && rtcpParameters.cname) {\n sdp += 'a=ssrc:' + rtcpParameters.ssrc +\n ' cname:' + rtcpParameters.cname + '\\r\\n';\n }\n return sdp;\n};\n\n\n// parses either a=msid: or a=ssrc:... msid lines and returns\n// the id of the MediaStream and MediaStreamTrack.\nSDPUtils.parseMsid = function(mediaSection) {\n let parts;\n const spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:');\n if (spec.length === 1) {\n parts = spec[0].substring(7).split(' ');\n return {stream: parts[0], track: parts[1]};\n }\n const planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:')\n .map(line => SDPUtils.parseSsrcMedia(line))\n .filter(msidParts => msidParts.attribute === 'msid');\n if (planB.length > 0) {\n parts = planB[0].value.split(' ');\n return {stream: parts[0], track: parts[1]};\n }\n};\n\n// SCTP\n// parses draft-ietf-mmusic-sctp-sdp-26 first and falls back\n// to draft-ietf-mmusic-sctp-sdp-05\nSDPUtils.parseSctpDescription = function(mediaSection) {\n const mline = SDPUtils.parseMLine(mediaSection);\n const maxSizeLine = SDPUtils.matchPrefix(mediaSection, 'a=max-message-size:');\n let maxMessageSize;\n if (maxSizeLine.length > 0) {\n maxMessageSize = parseInt(maxSizeLine[0].substring(19), 10);\n }\n if (isNaN(maxMessageSize)) {\n maxMessageSize = 65536;\n }\n const sctpPort = SDPUtils.matchPrefix(mediaSection, 'a=sctp-port:');\n if (sctpPort.length > 0) {\n return {\n port: parseInt(sctpPort[0].substring(12), 10),\n protocol: mline.fmt,\n maxMessageSize,\n };\n }\n const sctpMapLines = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:');\n if (sctpMapLines.length > 0) {\n const parts = sctpMapLines[0]\n .substring(10)\n .split(' ');\n return {\n port: parseInt(parts[0], 10),\n protocol: parts[1],\n maxMessageSize,\n };\n }\n};\n\n// SCTP\n// outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers\n// support by now receiving in this format, unless we originally parsed\n// as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line\n// protocol of DTLS/SCTP -- without UDP/ or TCP/)\nSDPUtils.writeSctpDescription = function(media, sctp) {\n let output = [];\n if (media.protocol !== 'DTLS/SCTP') {\n output = [\n 'm=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.protocol + '\\r\\n',\n 'c=IN IP4 0.0.0.0\\r\\n',\n 'a=sctp-port:' + sctp.port + '\\r\\n',\n ];\n } else {\n output = [\n 'm=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.port + '\\r\\n',\n 'c=IN IP4 0.0.0.0\\r\\n',\n 'a=sctpmap:' + sctp.port + ' ' + sctp.protocol + ' 65535\\r\\n',\n ];\n }\n if (sctp.maxMessageSize !== undefined) {\n output.push('a=max-message-size:' + sctp.maxMessageSize + '\\r\\n');\n }\n return output.join('');\n};\n\n// Generate a session ID for SDP.\n// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1\n// recommends using a cryptographically random +ve 64-bit value\n// but right now this should be acceptable and within the right range\nSDPUtils.generateSessionId = function() {\n return Math.random().toString().substr(2, 22);\n};\n\n// Write boiler plate for start of SDP\n// sessId argument is optional - if not supplied it will\n// be generated randomly\n// sessVersion is optional and defaults to 2\n// sessUser is optional and defaults to 'thisisadapterortc'\nSDPUtils.writeSessionBoilerplate = function(sessId, sessVer, sessUser) {\n let sessionId;\n const version = sessVer !== undefined ? sessVer : 2;\n if (sessId) {\n sessionId = sessId;\n } else {\n sessionId = SDPUtils.generateSessionId();\n }\n const user = sessUser || 'thisisadapterortc';\n // FIXME: sess-id should be an NTP timestamp.\n return 'v=0\\r\\n' +\n 'o=' + user + ' ' + sessionId + ' ' + version +\n ' IN IP4 127.0.0.1\\r\\n' +\n 's=-\\r\\n' +\n 't=0 0\\r\\n';\n};\n\n// Gets the direction from the mediaSection or the sessionpart.\nSDPUtils.getDirection = function(mediaSection, sessionpart) {\n // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.\n const lines = SDPUtils.splitLines(mediaSection);\n for (let i = 0; i < lines.length; i++) {\n switch (lines[i]) {\n case 'a=sendrecv':\n case 'a=sendonly':\n case 'a=recvonly':\n case 'a=inactive':\n return lines[i].substring(2);\n default:\n // FIXME: What should happen here?\n }\n }\n if (sessionpart) {\n return SDPUtils.getDirection(sessionpart);\n }\n return 'sendrecv';\n};\n\nSDPUtils.getKind = function(mediaSection) {\n const lines = SDPUtils.splitLines(mediaSection);\n const mline = lines[0].split(' ');\n return mline[0].substring(2);\n};\n\nSDPUtils.isRejected = function(mediaSection) {\n return mediaSection.split(' ', 2)[1] === '0';\n};\n\nSDPUtils.parseMLine = function(mediaSection) {\n const lines = SDPUtils.splitLines(mediaSection);\n const parts = lines[0].substring(2).split(' ');\n return {\n kind: parts[0],\n port: parseInt(parts[1], 10),\n protocol: parts[2],\n fmt: parts.slice(3).join(' '),\n };\n};\n\nSDPUtils.parseOLine = function(mediaSection) {\n const line = SDPUtils.matchPrefix(mediaSection, 'o=')[0];\n const parts = line.substring(2).split(' ');\n return {\n username: parts[0],\n sessionId: parts[1],\n sessionVersion: parseInt(parts[2], 10),\n netType: parts[3],\n addressType: parts[4],\n address: parts[5],\n };\n};\n\n// a very naive interpretation of a valid SDP.\nSDPUtils.isValidSDP = function(blob) {\n if (typeof blob !== 'string' || blob.length === 0) {\n return false;\n }\n const lines = SDPUtils.splitLines(blob);\n for (let i = 0; i < lines.length; i++) {\n if (lines[i].length < 2 || lines[i].charAt(1) !== '=') {\n return false;\n }\n // TODO: check the modifier a bit more.\n }\n return true;\n};\n\n// Expose public methods.\nif (typeof module === 'object') {\n module.exports = SDPUtils;\n}\n","import adapter from \"webrtc-adapter\";\nexport * from \"./peer.ts\";\n\nadapter.disableLog(false);\nadapter.disableWarnings(false);\nconsole.log(\"UA: \", navigator.userAgent);\nconsole.log(\"webrtc-adapter is enabled\", JSON.stringify({ shim: adapter.browserShim, version: adapter.browserDetails }, null, 2));\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n'use strict';\n\nlet logDisabled_ = true;\nlet deprecationWarnings_ = true;\n\n/**\n * Extract browser version out of the provided user agent string.\n *\n * @param {!string} uastring userAgent string.\n * @param {!string} expr Regular expression used as match criteria.\n * @param {!number} pos position in the version string to be returned.\n * @return {!number} browser version.\n */\nexport function extractVersion(uastring, expr, pos) {\n const match = uastring.match(expr);\n return match && match.length >= pos && parseInt(match[pos], 10);\n}\n\n// Wraps the peerconnection event eventNameToWrap in a function\n// which returns the modified event object (or false to prevent\n// the event).\nexport function wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) {\n if (!window.RTCPeerConnection) {\n return;\n }\n const proto = window.RTCPeerConnection.prototype;\n const nativeAddEventListener = proto.addEventListener;\n proto.addEventListener = function(nativeEventName, cb) {\n if (nativeEventName !== eventNameToWrap) {\n return nativeAddEventListener.apply(this, arguments);\n }\n const wrappedCallback = (e) => {\n const modifiedEvent = wrapper(e);\n if (modifiedEvent) {\n if (cb.handleEvent) {\n cb.handleEvent(modifiedEvent);\n } else {\n cb(modifiedEvent);\n }\n }\n };\n this._eventMap = this._eventMap || {};\n if (!this._eventMap[eventNameToWrap]) {\n this._eventMap[eventNameToWrap] = new Map();\n }\n this._eventMap[eventNameToWrap].set(cb, wrappedCallback);\n return nativeAddEventListener.apply(this, [nativeEventName,\n wrappedCallback]);\n };\n\n const nativeRemoveEventListener = proto.removeEventListener;\n proto.removeEventListener = function(nativeEventName, cb) {\n if (nativeEventName !== eventNameToWrap || !this._eventMap\n || !this._eventMap[eventNameToWrap]) {\n return nativeRemoveEventListener.apply(this, arguments);\n }\n if (!this._eventMap[eventNameToWrap].has(cb)) {\n return nativeRemoveEventListener.apply(this, arguments);\n }\n const unwrappedCb = this._eventMap[eventNameToWrap].get(cb);\n this._eventMap[eventNameToWrap].delete(cb);\n if (this._eventMap[eventNameToWrap].size === 0) {\n delete this._eventMap[eventNameToWrap];\n }\n if (Object.keys(this._eventMap).length === 0) {\n delete this._eventMap;\n }\n return nativeRemoveEventListener.apply(this, [nativeEventName,\n unwrappedCb]);\n };\n\n Object.defineProperty(proto, 'on' + eventNameToWrap, {\n get() {\n return this['_on' + eventNameToWrap];\n },\n set(cb) {\n if (this['_on' + eventNameToWrap]) {\n this.removeEventListener(eventNameToWrap,\n this['_on' + eventNameToWrap]);\n delete this['_on' + eventNameToWrap];\n }\n if (cb) {\n this.addEventListener(eventNameToWrap,\n this['_on' + eventNameToWrap] = cb);\n }\n },\n enumerable: true,\n configurable: true\n });\n}\n\nexport function disableLog(bool) {\n if (typeof bool !== 'boolean') {\n return new Error('Argument type: ' + typeof bool +\n '. Please use a boolean.');\n }\n logDisabled_ = bool;\n return (bool) ? 'adapter.js logging disabled' :\n 'adapter.js logging enabled';\n}\n\n/**\n * Disable or enable deprecation warnings\n * @param {!boolean} bool set to true to disable warnings.\n */\nexport function disableWarnings(bool) {\n if (typeof bool !== 'boolean') {\n return new Error('Argument type: ' + typeof bool +\n '. Please use a boolean.');\n }\n deprecationWarnings_ = !bool;\n return 'adapter.js deprecation warnings ' + (bool ? 'disabled' : 'enabled');\n}\n\nexport function log() {\n if (typeof window === 'object') {\n if (logDisabled_) {\n return;\n }\n if (typeof console !== 'undefined' && typeof console.log === 'function') {\n console.log.apply(console, arguments);\n }\n }\n}\n\n/**\n * Shows a deprecation warning suggesting the modern and spec-compatible API.\n */\nexport function deprecated(oldMethod, newMethod) {\n if (!deprecationWarnings_) {\n return;\n }\n console.warn(oldMethod + ' is deprecated, please use ' + newMethod +\n ' instead.');\n}\n\n/**\n * Browser detector.\n *\n * @return {object} result containing browser and version\n * properties.\n */\nexport function detectBrowser(window) {\n // Returned result object.\n const result = {browser: null, version: null};\n\n // Fail early if it's not a browser\n if (typeof window === 'undefined' || !window.navigator ||\n !window.navigator.userAgent) {\n result.browser = 'Not a browser.';\n return result;\n }\n\n const {navigator} = window;\n\n // Prefer navigator.userAgentData.\n if (navigator.userAgentData && navigator.userAgentData.brands) {\n const chromium = navigator.userAgentData.brands.find((brand) => {\n return brand.brand === 'Chromium';\n });\n if (chromium) {\n return {browser: 'chrome', version: parseInt(chromium.version, 10)};\n }\n }\n\n if (navigator.mozGetUserMedia) { // Firefox.\n result.browser = 'firefox';\n result.version = extractVersion(navigator.userAgent,\n /Firefox\\/(\\d+)\\./, 1);\n } else if (navigator.webkitGetUserMedia ||\n (window.isSecureContext === false && window.webkitRTCPeerConnection)) {\n // Chrome, Chromium, Webview, Opera.\n // Version matches Chrome/WebRTC version.\n // Chrome 74 removed webkitGetUserMedia on http as well so we need the\n // more complicated fallback to webkitRTCPeerConnection.\n result.browser = 'chrome';\n result.version = extractVersion(navigator.userAgent,\n /Chrom(e|ium)\\/(\\d+)\\./, 2);\n } else if (window.RTCPeerConnection &&\n navigator.userAgent.match(/AppleWebKit\\/(\\d+)\\./)) { // Safari.\n result.browser = 'safari';\n result.version = extractVersion(navigator.userAgent,\n /AppleWebKit\\/(\\d+)\\./, 1);\n result.supportsUnifiedPlan = window.RTCRtpTransceiver &&\n 'currentDirection' in window.RTCRtpTransceiver.prototype;\n } else { // Default fallthrough: not supported.\n result.browser = 'Not a supported browser.';\n return result;\n }\n\n return result;\n}\n\n/**\n * Checks if something is an object.\n *\n * @param {*} val The something you want to check.\n * @return true if val is an object, false otherwise.\n */\nfunction isObject(val) {\n return Object.prototype.toString.call(val) === '[object Object]';\n}\n\n/**\n * Remove all empty objects and undefined values\n * from a nested object -- an enhanced and vanilla version\n * of Lodash's `compact`.\n */\nexport function compactObject(data) {\n if (!isObject(data)) {\n return data;\n }\n\n return Object.keys(data).reduce(function(accumulator, key) {\n const isObj = isObject(data[key]);\n const value = isObj ? compactObject(data[key]) : data[key];\n const isEmptyObject = isObj && !Object.keys(value).length;\n if (value === undefined || isEmptyObject) {\n return accumulator;\n }\n return Object.assign(accumulator, {[key]: value});\n }, {});\n}\n\n/* iterates the stats graph recursively. */\nexport function walkStats(stats, base, resultSet) {\n if (!base || resultSet.has(base.id)) {\n return;\n }\n resultSet.set(base.id, base);\n Object.keys(base).forEach(name => {\n if (name.endsWith('Id')) {\n walkStats(stats, stats.get(base[name]), resultSet);\n } else if (name.endsWith('Ids')) {\n base[name].forEach(id => {\n walkStats(stats, stats.get(id), resultSet);\n });\n }\n });\n}\n\n/* filter getStats for a sender/receiver track. */\nexport function filterStats(result, track, outbound) {\n const streamStatsType = outbound ? 'outbound-rtp' : 'inbound-rtp';\n const filteredResult = new Map();\n if (track === null) {\n return filteredResult;\n }\n const trackStats = [];\n result.forEach(value => {\n if (value.type === 'track' &&\n value.trackIdentifier === track.id) {\n trackStats.push(value);\n }\n });\n trackStats.forEach(trackStat => {\n result.forEach(stats => {\n if (stats.type === streamStatsType && stats.trackId === trackStat.id) {\n walkStats(result, stats, filteredResult);\n }\n });\n });\n return filteredResult;\n}\n\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n'use strict';\nimport * as utils from '../utils.js';\n\nexport {shimGetUserMedia} from './getusermedia';\n\nexport function shimMediaStream(window) {\n window.MediaStream = window.MediaStream || window.webkitMediaStream;\n}\n\nexport function shimOnTrack(window) {\n if (typeof window === 'object' && window.RTCPeerConnection && !('ontrack' in\n window.RTCPeerConnection.prototype)) {\n Object.defineProperty(window.RTCPeerConnection.prototype, 'ontrack', {\n get() {\n return this._ontrack;\n },\n set(f) {\n if (this._ontrack) {\n this.removeEventListener('track', this._ontrack);\n }\n this.addEventListener('track', this._ontrack = f);\n },\n enumerable: true,\n configurable: true\n });\n const origSetRemoteDescription =\n window.RTCPeerConnection.prototype.setRemoteDescription;\n window.RTCPeerConnection.prototype.setRemoteDescription =\n function setRemoteDescription() {\n if (!this._ontrackpoly) {\n this._ontrackpoly = (e) => {\n // onaddstream does not fire when a track is added to an existing\n // stream. But stream.onaddtrack is implemented so we use that.\n e.stream.addEventListener('addtrack', te => {\n let receiver;\n if (window.RTCPeerConnection.prototype.getReceivers) {\n receiver = this.getReceivers()\n .find(r => r.track && r.track.id === te.track.id);\n } else {\n receiver = {track: te.track};\n }\n\n const event = new Event('track');\n event.track = te.track;\n event.receiver = receiver;\n event.transceiver = {receiver};\n event.streams = [e.stream];\n this.dispatchEvent(event);\n });\n e.stream.getTracks().forEach(track => {\n let receiver;\n if (window.RTCPeerConnection.prototype.getReceivers) {\n receiver = this.getReceivers()\n .find(r => r.track && r.track.id === track.id);\n } else {\n receiver = {track};\n }\n const event = new Event('track');\n event.track = track;\n event.receiver = receiver;\n event.transceiver = {receiver};\n event.streams = [e.stream];\n this.dispatchEvent(event);\n });\n };\n this.addEventListener('addstream', this._ontrackpoly);\n }\n return origSetRemoteDescription.apply(this, arguments);\n };\n } else {\n // even if RTCRtpTransceiver is in window, it is only used and\n // emitted in unified-plan. Unfortunately this means we need\n // to unconditionally wrap the event.\n utils.wrapPeerConnectionEvent(window, 'track', e => {\n if (!e.transceiver) {\n Object.defineProperty(e, 'transceiver',\n {value: {receiver: e.receiver}});\n }\n return e;\n });\n }\n}\n\nexport function shimGetSendersWithDtmf(window) {\n // Overrides addTrack/removeTrack, depends on shimAddTrackRemoveTrack.\n if (typeof window === 'object' && window.RTCPeerConnection &&\n !('getSenders' in window.RTCPeerConnection.prototype) &&\n 'createDTMFSender' in window.RTCPeerConnection.prototype) {\n const shimSenderWithDtmf = function(pc, track) {\n return {\n track,\n get dtmf() {\n if (this._dtmf === undefined) {\n if (track.kind === 'audio') {\n this._dtmf = pc.createDTMFSender(track);\n } else {\n this._dtmf = null;\n }\n }\n return this._dtmf;\n },\n _pc: pc\n };\n };\n\n // augment addTrack when getSenders is not available.\n if (!window.RTCPeerConnection.prototype.getSenders) {\n window.RTCPeerConnection.prototype.getSenders = function getSenders() {\n this._senders = this._senders || [];\n return this._senders.slice(); // return a copy of the internal state.\n };\n const origAddTrack = window.RTCPeerConnection.prototype.addTrack;\n window.RTCPeerConnection.prototype.addTrack =\n function addTrack(track, stream) {\n let sender = origAddTrack.apply(this, arguments);\n if (!sender) {\n sender = shimSenderWithDtmf(this, track);\n this._senders.push(sender);\n }\n return sender;\n };\n\n const origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;\n window.RTCPeerConnection.prototype.removeTrack =\n function removeTrack(sender) {\n origRemoveTrack.apply(this, arguments);\n const idx = this._senders.indexOf(sender);\n if (idx !== -1) {\n this._senders.splice(idx, 1);\n }\n };\n }\n const origAddStream = window.RTCPeerConnection.prototype.addStream;\n window.RTCPeerConnection.prototype.addStream = function addStream(stream) {\n this._senders = this._senders || [];\n origAddStream.apply(this, [stream]);\n stream.getTracks().forEach(track => {\n this._senders.push(shimSenderWithDtmf(this, track));\n });\n };\n\n const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;\n window.RTCPeerConnection.prototype.removeStream =\n function removeStream(stream) {\n this._senders = this._senders || [];\n origRemoveStream.apply(this, [stream]);\n\n stream.getTracks().forEach(track => {\n const sender = this._senders.find(s => s.track === track);\n if (sender) { // remove sender\n this._senders.splice(this._senders.indexOf(sender), 1);\n }\n });\n };\n } else if (typeof window === 'object' && window.RTCPeerConnection &&\n 'getSenders' in window.RTCPeerConnection.prototype &&\n 'createDTMFSender' in window.RTCPeerConnection.prototype &&\n window.RTCRtpSender &&\n !('dtmf' in window.RTCRtpSender.prototype)) {\n const origGetSenders = window.RTCPeerConnection.prototype.getSenders;\n window.RTCPeerConnection.prototype.getSenders = function getSenders() {\n const senders = origGetSenders.apply(this, []);\n senders.forEach(sender => sender._pc = this);\n return senders;\n };\n\n Object.defineProperty(window.RTCRtpSender.prototype, 'dtmf', {\n get() {\n if (this._dtmf === undefined) {\n if (this.track.kind === 'audio') {\n this._dtmf = this._pc.createDTMFSender(this.track);\n } else {\n this._dtmf = null;\n }\n }\n return this._dtmf;\n }\n });\n }\n}\n\nexport function shimSenderReceiverGetStats(window) {\n if (!(typeof window === 'object' && window.RTCPeerConnection &&\n window.RTCRtpSender && window.RTCRtpReceiver)) {\n return;\n }\n\n // shim sender stats.\n if (!('getStats' in window.RTCRtpSender.prototype)) {\n const origGetSenders = window.RTCPeerConnection.prototype.getSenders;\n if (origGetSenders) {\n window.RTCPeerConnection.prototype.getSenders = function getSenders() {\n const senders = origGetSenders.apply(this, []);\n senders.forEach(sender => sender._pc = this);\n return senders;\n };\n }\n\n const origAddTrack = window.RTCPeerConnection.prototype.addTrack;\n if (origAddTrack) {\n window.RTCPeerConnection.prototype.addTrack = function addTrack() {\n const sender = origAddTrack.apply(this, arguments);\n sender._pc = this;\n return sender;\n };\n }\n window.RTCRtpSender.prototype.getStats = function getStats() {\n const sender = this;\n return this._pc.getStats().then(result =>\n /* Note: this will include stats of all senders that\n * send a track with the same id as sender.track as\n * it is not possible to identify the RTCRtpSender.\n */\n utils.filterStats(result, sender.track, true));\n };\n }\n\n // shim receiver stats.\n if (!('getStats' in window.RTCRtpReceiver.prototype)) {\n const origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;\n if (origGetReceivers) {\n window.RTCPeerConnection.prototype.getReceivers =\n function getReceivers() {\n const receivers = origGetReceivers.apply(this, []);\n receivers.forEach(receiver => receiver._pc = this);\n return receivers;\n };\n }\n utils.wrapPeerConnectionEvent(window, 'track', e => {\n e.receiver._pc = e.srcElement;\n return e;\n });\n window.RTCRtpReceiver.prototype.getStats = function getStats() {\n const receiver = this;\n return this._pc.getStats().then(result =>\n utils.filterStats(result, receiver.track, false));\n };\n }\n\n if (!('getStats' in window.RTCRtpSender.prototype &&\n 'getStats' in window.RTCRtpReceiver.prototype)) {\n return;\n }\n\n // shim RTCPeerConnection.getStats(track).\n const origGetStats = window.RTCPeerConnection.prototype.getStats;\n window.RTCPeerConnection.prototype.getStats = function getStats() {\n if (arguments.length > 0 &&\n arguments[0] instanceof window.MediaStreamTrack) {\n const track = arguments[0];\n let sender;\n let receiver;\n let err;\n this.getSenders().forEach(s => {\n if (s.track === track) {\n if (sender) {\n err = true;\n } else {\n sender = s;\n }\n }\n });\n this.getReceivers().forEach(r => {\n if (r.track === track) {\n if (receiver) {\n err = true;\n } else {\n receiver = r;\n }\n }\n return r.track === track;\n });\n if (err || (sender && receiver)) {\n return Promise.reject(new DOMException(\n 'There are more than one sender or receiver for the track.',\n 'InvalidAccessError'));\n } else if (sender) {\n return sender.getStats();\n } else if (receiver) {\n return receiver.getStats();\n }\n return Promise.reject(new DOMException(\n 'There is no sender or receiver for the track.',\n 'InvalidAccessError'));\n }\n return origGetStats.apply(this, arguments);\n };\n}\n\nexport function shimAddTrackRemoveTrackWithNative(window) {\n // shim addTrack/removeTrack with native variants in order to make\n // the interactions with legacy getLocalStreams behave as in other browsers.\n // Keeps a mapping stream.id => [stream, rtpsenders...]\n window.RTCPeerConnection.prototype.getLocalStreams =\n function getLocalStreams() {\n this._shimmedLocalStreams = this._shimmedLocalStreams || {};\n return Object.keys(this._shimmedLocalStreams)\n .map(streamId => this._shimmedLocalStreams[streamId][0]);\n };\n\n const origAddTrack = window.RTCPeerConnection.prototype.addTrack;\n window.RTCPeerConnection.prototype.addTrack =\n function addTrack(track, stream) {\n if (!stream) {\n return origAddTrack.apply(this, arguments);\n }\n this._shimmedLocalStreams = this._shimmedLocalStreams || {};\n\n const sender = origAddTrack.apply(this, arguments);\n if (!this._shimmedLocalStreams[stream.id]) {\n this._shimmedLocalStreams[stream.id] = [stream, sender];\n } else if (this._shimmedLocalStreams[stream.id].indexOf(sender) === -1) {\n this._shimmedLocalStreams[stream.id].push(sender);\n }\n return sender;\n };\n\n const origAddStream = window.RTCPeerConnection.prototype.addStream;\n window.RTCPeerConnection.prototype.addStream = function addStream(stream) {\n this._shimmedLocalStreams = this._shimmedLocalStreams || {};\n\n stream.getTracks().forEach(track => {\n const alreadyExists = this.getSenders().find(s => s.track === track);\n if (alreadyExists) {\n throw new DOMException('Track already exists.',\n 'InvalidAccessError');\n }\n });\n const existingSenders = this.getSenders();\n origAddStream.apply(this, arguments);\n const newSenders = this.getSenders()\n .filter(newSender => existingSenders.indexOf(newSender) === -1);\n this._shimmedLocalStreams[stream.id] = [stream].concat(newSenders);\n };\n\n const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;\n window.RTCPeerConnection.prototype.removeStream =\n function removeStream(stream) {\n this._shimmedLocalStreams = this._shimmedLocalStreams || {};\n delete this._shimmedLocalStreams[stream.id];\n return origRemoveStream.apply(this, arguments);\n };\n\n const origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;\n window.RTCPeerConnection.prototype.removeTrack =\n function removeTrack(sender) {\n this._shimmedLocalStreams = this._shimmedLocalStreams || {};\n if (sender) {\n Object.keys(this._shimmedLocalStreams).forEach(streamId => {\n const idx = this._shimmedLocalStreams[streamId].indexOf(sender);\n if (idx !== -1) {\n this._shimmedLocalStreams[streamId].splice(idx, 1);\n }\n if (this._shimmedLocalStreams[streamId].length === 1) {\n delete this._shimmedLocalStreams[streamId];\n }\n });\n }\n return origRemoveTrack.apply(this, arguments);\n };\n}\n\nexport function shimAddTrackRemoveTrack(window, browserDetails) {\n if (!window.RTCPeerConnection) {\n return;\n }\n // shim addTrack and removeTrack.\n if (window.RTCPeerConnection.prototype.addTrack &&\n browserDetails.version >= 65) {\n return shimAddTrackRemoveTrackWithNative(window);\n }\n\n // also shim pc.getLocalStreams when addTrack is shimmed\n // to return the original streams.\n const origGetLocalStreams = window.RTCPeerConnection.prototype\n .getLocalStreams;\n window.RTCPeerConnection.prototype.getLocalStreams =\n function getLocalStreams() {\n const nativeStreams = origGetLocalStreams.apply(this);\n this._reverseStreams = this._reverseStreams || {};\n return nativeStreams.map(stream => this._reverseStreams[stream.id]);\n };\n\n const origAddStream = window.RTCPeerConnection.prototype.addStream;\n window.RTCPeerConnection.prototype.addStream = function addStream(stream) {\n this._streams = this._streams || {};\n this._reverseStreams = this._reverseStreams || {};\n\n stream.getTracks().forEach(track => {\n const alreadyExists = this.getSenders().find(s => s.track === track);\n if (alreadyExists) {\n throw new DOMException('Track already exists.',\n 'InvalidAccessError');\n }\n });\n // Add identity mapping for consistency with addTrack.\n // Unless this is being used with a stream from addTrack.\n if (!this._reverseStreams[stream.id]) {\n const newStream = new window.MediaStream(stream.getTracks());\n this._streams[stream.id] = newStream;\n this._reverseStreams[newStream.id] = stream;\n stream = newStream;\n }\n origAddStream.apply(this, [stream]);\n };\n\n const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;\n window.RTCPeerConnection.prototype.removeStream =\n function removeStream(stream) {\n this._streams = this._streams || {};\n this._reverseStreams = this._reverseStreams || {};\n\n origRemoveStream.apply(this, [(this._streams[stream.id] || stream)]);\n delete this._reverseStreams[(this._streams[stream.id] ?\n this._streams[stream.id].id : stream.id)];\n delete this._streams[stream.id];\n };\n\n window.RTCPeerConnection.prototype.addTrack =\n function addTrack(track, stream) {\n if (this.signalingState === 'closed') {\n throw new DOMException(\n 'The RTCPeerConnection\\'s signalingState is \\'closed\\'.',\n 'InvalidStateError');\n }\n const streams = [].slice.call(arguments, 1);\n if (streams.length !== 1 ||\n !streams[0].getTracks().find(t => t === track)) {\n // this is not fully correct but all we can manage without\n // [[associated MediaStreams]] internal slot.\n throw new DOMException(\n 'The adapter.js addTrack polyfill only supports a single ' +\n ' stream which is associated with the specified track.',\n 'NotSupportedError');\n }\n\n const alreadyExists = this.getSenders().find(s => s.track === track);\n if (alreadyExists) {\n throw new DOMException('Track already exists.',\n 'InvalidAccessError');\n }\n\n this._streams = this._streams || {};\n this._reverseStreams = this._reverseStreams || {};\n const oldStream = this._streams[stream.id];\n if (oldStream) {\n // this is using odd Chrome behaviour, use with caution:\n // https://bugs.chromium.org/p/webrtc/issues/detail?id=7815\n // Note: we rely on the high-level addTrack/dtmf shim to\n // create the sender with a dtmf sender.\n oldStream.addTrack(track);\n\n // Trigger ONN async.\n Promise.resolve().then(() => {\n this.dispatchEvent(new Event('negotiationneeded'));\n });\n } else {\n const newStream = new window.MediaStream([track]);\n this._streams[stream.id] = newStream;\n this._reverseStreams[newStream.id] = stream;\n this.addStream(newStream);\n }\n return this.getSenders().find(s => s.track === track);\n };\n\n // replace the internal stream id with the external one and\n // vice versa.\n function replaceInternalStreamId(pc, description) {\n let sdp = description.sdp;\n Object.keys(pc._reverseStreams || []).forEach(internalId => {\n const externalStream = pc._reverseStreams[internalId];\n const internalStream = pc._streams[externalStream.id];\n sdp = sdp.replace(new RegExp(internalStream.id, 'g'),\n externalStream.id);\n });\n return new RTCSessionDescription({\n type: description.type,\n sdp\n });\n }\n function replaceExternalStreamId(pc, description) {\n let sdp = description.sdp;\n Object.keys(pc._reverseStreams || []).forEach(internalId => {\n const externalStream = pc._reverseStreams[internalId];\n const internalStream = pc._streams[externalStream.id];\n sdp = sdp.replace(new RegExp(externalStream.id, 'g'),\n internalStream.id);\n });\n return new RTCSessionDescription({\n type: description.type,\n sdp\n });\n }\n ['createOffer', 'createAnswer'].forEach(function(method) {\n const nativeMethod = window.RTCPeerConnection.prototype[method];\n const methodObj = {[method]() {\n const args = arguments;\n const isLegacyCall = arguments.length &&\n typeof arguments[0] === 'function';\n if (isLegacyCall) {\n return nativeMethod.apply(this, [\n (description) => {\n const desc = replaceInternalStreamId(this, description);\n args[0].apply(null, [desc]);\n },\n (err) => {\n if (args[1]) {\n args[1].apply(null, err);\n }\n }, arguments[2]\n ]);\n }\n return nativeMethod.apply(this, arguments)\n .then(description => replaceInternalStreamId(this, description));\n }};\n window.RTCPeerConnection.prototype[method] = methodObj[method];\n });\n\n const origSetLocalDescription =\n window.RTCPeerConnection.prototype.setLocalDescription;\n window.RTCPeerConnection.prototype.setLocalDescription =\n function setLocalDescription() {\n if (!arguments.length || !arguments[0].type) {\n return origSetLocalDescription.apply(this, arguments);\n }\n arguments[0] = replaceExternalStreamId(this, arguments[0]);\n return origSetLocalDescription.apply(this, arguments);\n };\n\n // TODO: mangle getStats: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats-streamidentifier\n\n const origLocalDescription = Object.getOwnPropertyDescriptor(\n window.RTCPeerConnection.prototype, 'localDescription');\n Object.defineProperty(window.RTCPeerConnection.prototype,\n 'localDescription', {\n get() {\n const description = origLocalDescription.get.apply(this);\n if (description.type === '') {\n return description;\n }\n return replaceInternalStreamId(this, description);\n }\n });\n\n window.RTCPeerConnection.prototype.removeTrack =\n function removeTrack(sender) {\n if (this.signalingState === 'closed') {\n throw new DOMException(\n 'The RTCPeerConnection\\'s signalingState is \\'closed\\'.',\n 'InvalidStateError');\n }\n // We can not yet check for sender instanceof RTCRtpSender\n // since we shim RTPSender. So we check if sender._pc is set.\n if (!sender._pc) {\n throw new DOMException('Argument 1 of RTCPeerConnection.removeTrack ' +\n 'does not implement interface RTCRtpSender.', 'TypeError');\n }\n const isLocal = sender._pc === this;\n if (!isLocal) {\n throw new DOMException('Sender was not created by this connection.',\n 'InvalidAccessError');\n }\n\n // Search for the native stream the senders track belongs to.\n this._streams = this._streams || {};\n let stream;\n Object.keys(this._streams).forEach(streamid => {\n const hasTrack = this._streams[streamid].getTracks()\n .find(track => sender.track === track);\n if (hasTrack) {\n stream = this._streams[streamid];\n }\n });\n\n if (stream) {\n if (stream.getTracks().length === 1) {\n // if this is the last track of the stream, remove the stream. This\n // takes care of any shimmed _senders.\n this.removeStream(this._reverseStreams[stream.id]);\n } else {\n // relying on the same odd chrome behaviour as above.\n stream.removeTrack(sender.track);\n }\n this.dispatchEvent(new Event('negotiationneeded'));\n }\n };\n}\n\nexport function shimPeerConnection(window, browserDetails) {\n if (!window.RTCPeerConnection && window.webkitRTCPeerConnection) {\n // very basic support for old versions.\n window.RTCPeerConnection = window.webkitRTCPeerConnection;\n }\n if (!window.RTCPeerConnection) {\n return;\n }\n\n // shim implicit creation of RTCSessionDescription/RTCIceCandidate\n if (browserDetails.version < 53) {\n ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate']\n .forEach(function(method) {\n const nativeMethod = window.RTCPeerConnection.prototype[method];\n const methodObj = {[method]() {\n arguments[0] = new ((method === 'addIceCandidate') ?\n window.RTCIceCandidate :\n window.RTCSessionDescription)(arguments[0]);\n return nativeMethod.apply(this, arguments);\n }};\n window.RTCPeerConnection.prototype[method] = methodObj[method];\n });\n }\n}\n\n// Attempt to fix ONN in plan-b mode.\nexport function fixNegotiationNeeded(window, browserDetails) {\n utils.wrapPeerConnectionEvent(window, 'negotiationneeded', e => {\n const pc = e.target;\n if (browserDetails.version < 72 || (pc.getConfiguration &&\n pc.getConfiguration().sdpSemantics === 'plan-b')) {\n if (pc.signalingState !== 'stable') {\n return;\n }\n }\n return e;\n });\n}\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n'use strict';\nimport * as utils from '../utils.js';\nconst logging = utils.log;\n\nexport function shimGetUserMedia(window, browserDetails) {\n const navigator = window && window.navigator;\n\n if (!navigator.mediaDevices) {\n return;\n }\n\n const constraintsToChrome_ = function(c) {\n if (typeof c !== 'object' || c.mandatory || c.optional) {\n return c;\n }\n const cc = {};\n Object.keys(c).forEach(key => {\n if (key === 'require' || key === 'advanced' || key === 'mediaSource') {\n return;\n }\n const r = (typeof c[key] === 'object') ? c[key] : {ideal: c[key]};\n if (r.exact !== undefined && typeof r.exact === 'number') {\n r.min = r.max = r.exact;\n }\n const oldname_ = function(prefix, name) {\n if (prefix) {\n return prefix + name.charAt(0).toUpperCase() + name.slice(1);\n }\n return (name === 'deviceId') ? 'sourceId' : name;\n };\n if (r.ideal !== undefined) {\n cc.optional = cc.optional || [];\n let oc = {};\n if (typeof r.ideal === 'number') {\n oc[oldname_('min', key)] = r.ideal;\n cc.optional.push(oc);\n oc = {};\n oc[oldname_('max', key)] = r.ideal;\n cc.optional.push(oc);\n } else {\n oc[oldname_('', key)] = r.ideal;\n cc.optional.push(oc);\n }\n }\n if (r.exact !== undefined && typeof r.exact !== 'number') {\n cc.mandatory = cc.mandatory || {};\n cc.mandatory[oldname_('', key)] = r.exact;\n } else {\n ['min', 'max'].forEach(mix => {\n if (r[mix] !== undefined) {\n cc.mandatory = cc.mandatory || {};\n cc.mandatory[oldname_(mix, key)] = r[mix];\n }\n });\n }\n });\n if (c.advanced) {\n cc.optional = (cc.optional || []).concat(c.advanced);\n }\n return cc;\n };\n\n const shimConstraints_ = function(constraints, func) {\n if (browserDetails.version >= 61) {\n return func(constraints);\n }\n constraints = JSON.parse(JSON.stringify(constraints));\n if (constraints && typeof constraints.audio === 'object') {\n const remap = function(obj, a, b) {\n if (a in obj && !(b in obj)) {\n obj[b] = obj[a];\n delete obj[a];\n }\n };\n constraints = JSON.parse(JSON.stringify(constraints));\n remap(constraints.audio, 'autoGainControl', 'googAutoGainControl');\n remap(constraints.audio, 'noiseSuppression', 'googNoiseSuppression');\n constraints.audio = constraintsToChrome_(constraints.audio);\n }\n if (constraints && typeof constraints.video === 'object') {\n // Shim facingMode for mobile & surface pro.\n let face = constraints.video.facingMode;\n face = face && ((typeof face === 'object') ? face : {ideal: face});\n const getSupportedFacingModeLies = browserDetails.version < 66;\n\n if ((face && (face.exact === 'user' || face.exact === 'environment' ||\n face.ideal === 'user' || face.ideal === 'environment')) &&\n !(navigator.mediaDevices.getSupportedConstraints &&\n navigator.mediaDevices.getSupportedConstraints().facingMode &&\n !getSupportedFacingModeLies)) {\n delete constraints.video.facingMode;\n let matches;\n if (face.exact === 'environment' || face.ideal === 'environment') {\n matches = ['back', 'rear'];\n } else if (face.exact === 'user' || face.ideal === 'user') {\n matches = ['front'];\n }\n if (matches) {\n // Look for matches in label, or use last cam for back (typical).\n return navigator.mediaDevices.enumerateDevices()\n .then(devices => {\n devices = devices.filter(d => d.kind === 'videoinput');\n let dev = devices.find(d => matches.some(match =>\n d.label.toLowerCase().includes(match)));\n if (!dev && devices.length && matches.includes('back')) {\n dev = devices[devices.length - 1]; // more likely the back cam\n }\n if (dev) {\n constraints.video.deviceId = face.exact\n ? {exact: dev.deviceId}\n : {ideal: dev.deviceId};\n }\n constraints.video = constraintsToChrome_(constraints.video);\n logging('chrome: ' + JSON.stringify(constraints));\n return func(constraints);\n });\n }\n }\n constraints.video = constraintsToChrome_(constraints.video);\n }\n logging('chrome: ' + JSON.stringify(constraints));\n return func(constraints);\n };\n\n const shimError_ = function(e) {\n if (browserDetails.version >= 64) {\n return e;\n }\n return {\n name: {\n PermissionDeniedError: 'NotAllowedError',\n PermissionDismissedError: 'NotAllowedError',\n InvalidStateError: 'NotAllowedError',\n DevicesNotFoundError: 'NotFoundError',\n ConstraintNotSatisfiedError: 'OverconstrainedError',\n TrackStartError: 'NotReadableError',\n MediaDeviceFailedDueToShutdown: 'NotAllowedError',\n MediaDeviceKillSwitchOn: 'NotAllowedError',\n TabCaptureError: 'AbortError',\n ScreenCaptureError: 'AbortError',\n DeviceCaptureError: 'AbortError'\n }[e.name] || e.name,\n message: e.message,\n constraint: e.constraint || e.constraintName,\n toString() {\n return this.name + (this.message && ': ') + this.message;\n }\n };\n };\n\n const getUserMedia_ = function(constraints, onSuccess, onError) {\n shimConstraints_(constraints, c => {\n navigator.webkitGetUserMedia(c, onSuccess, e => {\n if (onError) {\n onError(shimError_(e));\n }\n });\n });\n };\n navigator.getUserMedia = getUserMedia_.bind(navigator);\n\n // Even though Chrome 45 has navigator.mediaDevices and a getUserMedia\n // function which returns a Promise, it does not accept spec-style\n // constraints.\n if (navigator.mediaDevices.getUserMedia) {\n const origGetUserMedia = navigator.mediaDevices.getUserMedia.\n bind(navigator.mediaDevices);\n navigator.mediaDevices.getUserMedia = function(cs) {\n return shimConstraints_(cs, c => origGetUserMedia(c).then(stream => {\n if (c.audio && !stream.getAudioTracks().length ||\n c.video && !stream.getVideoTracks().length) {\n stream.getTracks().forEach(track => {\n track.stop();\n });\n throw new DOMException('', 'NotFoundError');\n }\n return stream;\n }, e => Promise.reject(shimError_(e))));\n };\n }\n}\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n'use strict';\n\nimport * as utils from '../utils';\nexport {shimGetUserMedia} from './getusermedia';\nexport {shimGetDisplayMedia} from './getdisplaymedia';\n\nexport function shimOnTrack(window) {\n if (typeof window === 'object' && window.RTCTrackEvent &&\n ('receiver' in window.RTCTrackEvent.prototype) &&\n !('transceiver' in window.RTCTrackEvent.prototype)) {\n Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {\n get() {\n return {receiver: this.receiver};\n }\n });\n }\n}\n\nexport function shimPeerConnection(window, browserDetails) {\n if (typeof window !== 'object' ||\n !(window.RTCPeerConnection || window.mozRTCPeerConnection)) {\n return; // probably media.peerconnection.enabled=false in about:config\n }\n if (!window.RTCPeerConnection && window.mozRTCPeerConnection) {\n // very basic support for old versions.\n window.RTCPeerConnection = window.mozRTCPeerConnection;\n }\n\n if (browserDetails.version < 53) {\n // shim away need for obsolete RTCIceCandidate/RTCSessionDescription.\n ['setLocalDescription', 'setRemoteDescription', 'addIceCandidate']\n .forEach(function(method) {\n const nativeMethod = window.RTCPeerConnection.prototype[method];\n const methodObj = {[method]() {\n arguments[0] = new ((method === 'addIceCandidate') ?\n window.RTCIceCandidate :\n window.RTCSessionDescription)(arguments[0]);\n return nativeMethod.apply(this, arguments);\n }};\n window.RTCPeerConnection.prototype[method] = methodObj[method];\n });\n }\n\n const modernStatsTypes = {\n inboundrtp: 'inbound-rtp',\n outboundrtp: 'outbound-rtp',\n candidatepair: 'candidate-pair',\n localcandidate: 'local-candidate',\n remotecandidate: 'remote-candidate'\n };\n\n const nativeGetStats = window.RTCPeerConnection.prototype.getStats;\n window.RTCPeerConnection.prototype.getStats = function getStats() {\n const [selector, onSucc, onErr] = arguments;\n return nativeGetStats.apply(this, [selector || null])\n .then(stats => {\n if (browserDetails.version < 53 && !onSucc) {\n // Shim only promise getStats with spec-hyphens in type names\n // Leave callback version alone; misc old uses of forEach before Map\n try {\n stats.forEach(stat => {\n stat.type = modernStatsTypes[stat.type] || stat.type;\n });\n } catch (e) {\n if (e.name !== 'TypeError') {\n throw e;\n }\n // Avoid TypeError: \"type\" is read-only, in old versions. 34-43ish\n stats.forEach((stat, i) => {\n stats.set(i, Object.assign({}, stat, {\n type: modernStatsTypes[stat.type] || stat.type\n }));\n });\n }\n }\n return stats;\n })\n .then(onSucc, onErr);\n };\n}\n\nexport function shimSenderGetStats(window) {\n if (!(typeof window === 'object' && window.RTCPeerConnection &&\n window.RTCRtpSender)) {\n return;\n }\n if (window.RTCRtpSender && 'getStats' in window.RTCRtpSender.prototype) {\n return;\n }\n const origGetSenders = window.RTCPeerConnection.prototype.getSenders;\n if (origGetSenders) {\n window.RTCPeerConnection.prototype.getSenders = function getSenders() {\n const senders = origGetSenders.apply(this, []);\n senders.forEach(sender => sender._pc = this);\n return senders;\n };\n }\n\n const origAddTrack = window.RTCPeerConnection.prototype.addTrack;\n if (origAddTrack) {\n window.RTCPeerConnection.prototype.addTrack = function addTrack() {\n const sender = origAddTrack.apply(this, arguments);\n sender._pc = this;\n return sender;\n };\n }\n window.RTCRtpSender.prototype.getStats = function getStats() {\n return this.track ? this._pc.getStats(this.track) :\n Promise.resolve(new Map());\n };\n}\n\nexport function shimReceiverGetStats(window) {\n if (!(typeof window === 'object' && window.RTCPeerConnection &&\n window.RTCRtpSender)) {\n return;\n }\n if (window.RTCRtpSender && 'getStats' in window.RTCRtpReceiver.prototype) {\n return;\n }\n const origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;\n if (origGetReceivers) {\n window.RTCPeerConnection.prototype.getReceivers = function getReceivers() {\n const receivers = origGetReceivers.apply(this, []);\n receivers.forEach(receiver => receiver._pc = this);\n return receivers;\n };\n }\n utils.wrapPeerConnectionEvent(window, 'track', e => {\n e.receiver._pc = e.srcElement;\n return e;\n });\n window.RTCRtpReceiver.prototype.getStats = function getStats() {\n return this._pc.getStats(this.track);\n };\n}\n\nexport function shimRemoveStream(window) {\n if (!window.RTCPeerConnection ||\n 'removeStream' in window.RTCPeerConnection.prototype) {\n return;\n }\n window.RTCPeerConnection.prototype.removeStream =\n function removeStream(stream) {\n utils.deprecated('removeStream', 'removeTrack');\n this.getSenders().forEach(sender => {\n if (sender.track && stream.getTracks().includes(sender.track)) {\n this.removeTrack(sender);\n }\n });\n };\n}\n\nexport function shimRTCDataChannel(window) {\n // rename DataChannel to RTCDataChannel (native fix in FF60):\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1173851\n if (window.DataChannel && !window.RTCDataChannel) {\n window.RTCDataChannel = window.DataChannel;\n }\n}\n\nexport function shimAddTransceiver(window) {\n // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647\n // Firefox ignores the init sendEncodings options passed to addTransceiver\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918\n if (!(typeof window === 'object' && window.RTCPeerConnection)) {\n return;\n }\n const origAddTransceiver = window.RTCPeerConnection.prototype.addTransceiver;\n if (origAddTransceiver) {\n window.RTCPeerConnection.prototype.addTransceiver =\n function addTransceiver() {\n this.setParametersPromises = [];\n // WebIDL input coercion and validation\n let sendEncodings = arguments[1] && arguments[1].sendEncodings;\n if (sendEncodings === undefined) {\n sendEncodings = [];\n }\n sendEncodings = [...sendEncodings];\n const shouldPerformCheck = sendEncodings.length > 0;\n if (shouldPerformCheck) {\n // If sendEncodings params are provided, validate grammar\n sendEncodings.forEach((encodingParam) => {\n if ('rid' in encodingParam) {\n const ridRegex = /^[a-z0-9]{0,16}$/i;\n if (!ridRegex.test(encodingParam.rid)) {\n throw new TypeError('Invalid RID value provided.');\n }\n }\n if ('scaleResolutionDownBy' in encodingParam) {\n if (!(parseFloat(encodingParam.scaleResolutionDownBy) >= 1.0)) {\n throw new RangeError('scale_resolution_down_by must be >= 1.0');\n }\n }\n if ('maxFramerate' in encodingParam) {\n if (!(parseFloat(encodingParam.maxFramerate) >= 0)) {\n throw new RangeError('max_framerate must be >= 0.0');\n }\n }\n });\n }\n const transceiver = origAddTransceiver.apply(this, arguments);\n if (shouldPerformCheck) {\n // Check if the init options were applied. If not we do this in an\n // asynchronous way and save the promise reference in a global object.\n // This is an ugly hack, but at the same time is way more robust than\n // checking the sender parameters before and after the createOffer\n // Also note that after the createoffer we are not 100% sure that\n // the params were asynchronously applied so we might miss the\n // opportunity to recreate offer.\n const {sender} = transceiver;\n const params = sender.getParameters();\n if (!('encodings' in params) ||\n // Avoid being fooled by patched getParameters() below.\n (params.encodings.length === 1 &&\n Object.keys(params.encodings[0]).length === 0)) {\n params.encodings = sendEncodings;\n sender.sendEncodings = sendEncodings;\n this.setParametersPromises.push(sender.setParameters(params)\n .then(() => {\n delete sender.sendEncodings;\n }).catch(() => {\n delete sender.sendEncodings;\n })\n );\n }\n }\n return transceiver;\n };\n }\n}\n\nexport function shimGetParameters(window) {\n if (!(typeof window === 'object' && window.RTCRtpSender)) {\n return;\n }\n const origGetParameters = window.RTCRtpSender.prototype.getParameters;\n if (origGetParameters) {\n window.RTCRtpSender.prototype.getParameters =\n function getParameters() {\n const params = origGetParameters.apply(this, arguments);\n if (!('encodings' in params)) {\n params.encodings = [].concat(this.sendEncodings || [{}]);\n }\n return params;\n };\n }\n}\n\nexport function shimCreateOffer(window) {\n // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647\n // Firefox ignores the init sendEncodings options passed to addTransceiver\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918\n if (!(typeof window === 'object' && window.RTCPeerConnection)) {\n return;\n }\n const origCreateOffer = window.RTCPeerConnection.prototype.createOffer;\n window.RTCPeerConnection.prototype.createOffer = function createOffer() {\n if (this.setParametersPromises && this.setParametersPromises.length) {\n return Promise.all(this.setParametersPromises)\n .then(() => {\n return origCreateOffer.apply(this, arguments);\n })\n .finally(() => {\n this.setParametersPromises = [];\n });\n }\n return origCreateOffer.apply(this, arguments);\n };\n}\n\nexport function shimCreateAnswer(window) {\n // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647\n // Firefox ignores the init sendEncodings options passed to addTransceiver\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918\n if (!(typeof window === 'object' && window.RTCPeerConnection)) {\n return;\n }\n const origCreateAnswer = window.RTCPeerConnection.prototype.createAnswer;\n window.RTCPeerConnection.prototype.createAnswer = function createAnswer() {\n if (this.setParametersPromises && this.setParametersPromises.length) {\n return Promise.all(this.setParametersPromises)\n .then(() => {\n return origCreateAnswer.apply(this, arguments);\n })\n .finally(() => {\n this.setParametersPromises = [];\n });\n }\n return origCreateAnswer.apply(this, arguments);\n };\n}\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n'use strict';\n\nimport * as utils from '../utils';\n\nexport function shimGetUserMedia(window, browserDetails) {\n const navigator = window && window.navigator;\n const MediaStreamTrack = window && window.MediaStreamTrack;\n\n navigator.getUserMedia = function(constraints, onSuccess, onError) {\n // Replace Firefox 44+'s deprecation warning with unprefixed version.\n utils.deprecated('navigator.getUserMedia',\n 'navigator.mediaDevices.getUserMedia');\n navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError);\n };\n\n if (!(browserDetails.version > 55 &&\n 'autoGainControl' in navigator.mediaDevices.getSupportedConstraints())) {\n const remap = function(obj, a, b) {\n if (a in obj && !(b in obj)) {\n obj[b] = obj[a];\n delete obj[a];\n }\n };\n\n const nativeGetUserMedia = navigator.mediaDevices.getUserMedia.\n bind(navigator.mediaDevices);\n navigator.mediaDevices.getUserMedia = function(c) {\n if (typeof c === 'object' && typeof c.audio === 'object') {\n c = JSON.parse(JSON.stringify(c));\n remap(c.audio, 'autoGainControl', 'mozAutoGainControl');\n remap(c.audio, 'noiseSuppression', 'mozNoiseSuppression');\n }\n return nativeGetUserMedia(c);\n };\n\n if (MediaStreamTrack && MediaStreamTrack.prototype.getSettings) {\n const nativeGetSettings = MediaStreamTrack.prototype.getSettings;\n MediaStreamTrack.prototype.getSettings = function() {\n const obj = nativeGetSettings.apply(this, arguments);\n remap(obj, 'mozAutoGainControl', 'autoGainControl');\n remap(obj, 'mozNoiseSuppression', 'noiseSuppression');\n return obj;\n };\n }\n\n if (MediaStreamTrack && MediaStreamTrack.prototype.applyConstraints) {\n const nativeApplyConstraints =\n MediaStreamTrack.prototype.applyConstraints;\n MediaStreamTrack.prototype.applyConstraints = function(c) {\n if (this.kind === 'audio' && typeof c === 'object') {\n c = JSON.parse(JSON.stringify(c));\n remap(c, 'autoGainControl', 'mozAutoGainControl');\n remap(c, 'noiseSuppression', 'mozNoiseSuppression');\n }\n return nativeApplyConstraints.apply(this, [c]);\n };\n }\n }\n}\n","/*\n * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n'use strict';\n\nexport function shimGetDisplayMedia(window, preferredMediaSource) {\n if (window.navigator.mediaDevices &&\n 'getDisplayMedia' in window.navigator.mediaDevices) {\n return;\n }\n if (!(window.navigator.mediaDevices)) {\n return;\n }\n window.navigator.mediaDevices.getDisplayMedia =\n function getDisplayMedia(constraints) {\n if (!(constraints && constraints.video)) {\n const err = new DOMException('getDisplayMedia without video ' +\n 'constraints is undefined');\n err.name = 'NotFoundError';\n // from https://heycam.github.io/webidl/#idl-DOMException-error-names\n err.code = 8;\n return Promise.reject(err);\n }\n if (constraints.video === true) {\n constraints.video = {mediaSource: preferredMediaSource};\n } else {\n constraints.video.mediaSource = preferredMediaSource;\n }\n return window.navigator.mediaDevices.getUserMedia(constraints);\n };\n}\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n'use strict';\nimport * as utils from '../utils';\n\nexport function shimLocalStreamsAPI(window) {\n if (typeof window !== 'object' || !window.RTCPeerConnection) {\n return;\n }\n if (!('getLocalStreams' in window.RTCPeerConnection.prototype)) {\n window.RTCPeerConnection.prototype.getLocalStreams =\n function getLocalStreams() {\n if (!this._localStreams) {\n this._localStreams = [];\n }\n return this._localStreams;\n };\n }\n if (!('addStream' in window.RTCPeerConnection.prototype)) {\n const _addTrack = window.RTCPeerConnection.prototype.addTrack;\n window.RTCPeerConnection.prototype.addStream = function addStream(stream) {\n if (!this._localStreams) {\n this._localStreams = [];\n }\n if (!this._localStreams.includes(stream)) {\n this._localStreams.push(stream);\n }\n // Try to emulate Chrome's behaviour of adding in audio-video order.\n // Safari orders by track id.\n stream.getAudioTracks().forEach(track => _addTrack.call(this, track,\n stream));\n stream.getVideoTracks().forEach(track => _addTrack.call(this, track,\n stream));\n };\n\n window.RTCPeerConnection.prototype.addTrack =\n function addTrack(track, ...streams) {\n if (streams) {\n streams.forEach((stream) => {\n if (!this._localStreams) {\n this._localStreams = [stream];\n } else if (!this._localStreams.includes(stream)) {\n this._localStreams.push(stream);\n }\n });\n }\n return _addTrack.apply(this, arguments);\n };\n }\n if (!('removeStream' in window.RTCPeerConnection.prototype)) {\n window.RTCPeerConnection.prototype.removeStream =\n function removeStream(stream) {\n if (!this._localStreams) {\n this._localStreams = [];\n }\n const index = this._localStreams.indexOf(stream);\n if (index === -1) {\n return;\n }\n this._localStreams.splice(index, 1);\n const tracks = stream.getTracks();\n this.getSenders().forEach(sender => {\n if (tracks.includes(sender.track)) {\n this.removeTrack(sender);\n }\n });\n };\n }\n}\n\nexport function shimRemoteStreamsAPI(window) {\n if (typeof window !== 'object' || !window.RTCPeerConnection) {\n return;\n }\n if (!('getRemoteStreams' in window.RTCPeerConnection.prototype)) {\n window.RTCPeerConnection.prototype.getRemoteStreams =\n function getRemoteStreams() {\n return this._remoteStreams ? this._remoteStreams : [];\n };\n }\n if (!('onaddstream' in window.RTCPeerConnection.prototype)) {\n Object.defineProperty(window.RTCPeerConnection.prototype, 'onaddstream', {\n get() {\n return this._onaddstream;\n },\n set(f) {\n if (this._onaddstream) {\n this.removeEventListener('addstream', this._onaddstream);\n this.removeEventListener('track', this._onaddstreampoly);\n }\n this.addEventListener('addstream', this._onaddstream = f);\n this.addEventListener('track', this._onaddstreampoly = (e) => {\n e.streams.forEach(stream => {\n if (!this._remoteStreams) {\n this._remoteStreams = [];\n }\n if (this._remoteStreams.includes(stream)) {\n return;\n }\n this._remoteStreams.push(stream);\n const event = new Event('addstream');\n event.stream = stream;\n this.dispatchEvent(event);\n });\n });\n }\n });\n const origSetRemoteDescription =\n window.RTCPeerConnection.prototype.setRemoteDescription;\n window.RTCPeerConnection.prototype.setRemoteDescription =\n function setRemoteDescription() {\n const pc = this;\n if (!this._onaddstreampoly) {\n this.addEventListener('track', this._onaddstreampoly = function(e) {\n e.streams.forEach(stream => {\n if (!pc._remoteStreams) {\n pc._remoteStreams = [];\n }\n if (pc._remoteStreams.indexOf(stream) >= 0) {\n return;\n }\n pc._remoteStreams.push(stream);\n const event = new Event('addstream');\n event.stream = stream;\n pc.dispatchEvent(event);\n });\n });\n }\n return origSetRemoteDescription.apply(pc, arguments);\n };\n }\n}\n\nexport function shimCallbacksAPI(window) {\n if (typeof window !== 'object' || !window.RTCPeerConnection) {\n return;\n }\n const prototype = window.RTCPeerConnection.prototype;\n const origCreateOffer = prototype.createOffer;\n const origCreateAnswer = prototype.createAnswer;\n const setLocalDescription = prototype.setLocalDescription;\n const setRemoteDescription = prototype.setRemoteDescription;\n const addIceCandidate = prototype.addIceCandidate;\n\n prototype.createOffer =\n function createOffer(successCallback, failureCallback) {\n const options = (arguments.length >= 2) ? arguments[2] : arguments[0];\n const promise = origCreateOffer.apply(this, [options]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n\n prototype.createAnswer =\n function createAnswer(successCallback, failureCallback) {\n const options = (arguments.length >= 2) ? arguments[2] : arguments[0];\n const promise = origCreateAnswer.apply(this, [options]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n\n let withCallback = function(description, successCallback, failureCallback) {\n const promise = setLocalDescription.apply(this, [description]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n prototype.setLocalDescription = withCallback;\n\n withCallback = function(description, successCallback, failureCallback) {\n const promise = setRemoteDescription.apply(this, [description]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n prototype.setRemoteDescription = withCallback;\n\n withCallback = function(candidate, successCallback, failureCallback) {\n const promise = addIceCandidate.apply(this, [candidate]);\n if (!failureCallback) {\n return promise;\n }\n promise.then(successCallback, failureCallback);\n return Promise.resolve();\n };\n prototype.addIceCandidate = withCallback;\n}\n\nexport function shimGetUserMedia(window) {\n const navigator = window && window.navigator;\n\n if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {\n // shim not needed in Safari 12.1\n const mediaDevices = navigator.mediaDevices;\n const _getUserMedia = mediaDevices.getUserMedia.bind(mediaDevices);\n navigator.mediaDevices.getUserMedia = (constraints) => {\n return _getUserMedia(shimConstraints(constraints));\n };\n }\n\n if (!navigator.getUserMedia && navigator.mediaDevices &&\n navigator.mediaDevices.getUserMedia) {\n navigator.getUserMedia = function getUserMedia(constraints, cb, errcb) {\n navigator.mediaDevices.getUserMedia(constraints)\n .then(cb, errcb);\n }.bind(navigator);\n }\n}\n\nexport function shimConstraints(constraints) {\n if (constraints && constraints.video !== undefined) {\n return Object.assign({},\n constraints,\n {video: utils.compactObject(constraints.video)}\n );\n }\n\n return constraints;\n}\n\nexport function shimRTCIceServerUrls(window) {\n if (!window.RTCPeerConnection) {\n return;\n }\n // migrate from non-spec RTCIceServer.url to RTCIceServer.urls\n const OrigPeerConnection = window.RTCPeerConnection;\n window.RTCPeerConnection =\n function RTCPeerConnection(pcConfig, pcConstraints) {\n if (pcConfig && pcConfig.iceServers) {\n const newIceServers = [];\n for (let i = 0; i < pcConfig.iceServers.length; i++) {\n let server = pcConfig.iceServers[i];\n if (server.urls === undefined && server.url) {\n utils.deprecated('RTCIceServer.url', 'RTCIceServer.urls');\n server = JSON.parse(JSON.stringify(server));\n server.urls = server.url;\n delete server.url;\n newIceServers.push(server);\n } else {\n newIceServers.push(pcConfig.iceServers[i]);\n }\n }\n pcConfig.iceServers = newIceServers;\n }\n return new OrigPeerConnection(pcConfig, pcConstraints);\n };\n window.RTCPeerConnection.prototype = OrigPeerConnection.prototype;\n // wrap static methods. Currently just generateCertificate.\n if ('generateCertificate' in OrigPeerConnection) {\n Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', {\n get() {\n return OrigPeerConnection.generateCertificate;\n }\n });\n }\n}\n\nexport function shimTrackEventTransceiver(window) {\n // Add event.transceiver member over deprecated event.receiver\n if (typeof window === 'object' && window.RTCTrackEvent &&\n 'receiver' in window.RTCTrackEvent.prototype &&\n !('transceiver' in window.RTCTrackEvent.prototype)) {\n Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {\n get() {\n return {receiver: this.receiver};\n }\n });\n }\n}\n\nexport function shimCreateOfferLegacy(window) {\n const origCreateOffer = window.RTCPeerConnection.prototype.createOffer;\n window.RTCPeerConnection.prototype.createOffer =\n function createOffer(offerOptions) {\n if (offerOptions) {\n if (typeof offerOptions.offerToReceiveAudio !== 'undefined') {\n // support bit values\n offerOptions.offerToReceiveAudio =\n !!offerOptions.offerToReceiveAudio;\n }\n const audioTransceiver = this.getTransceivers().find(transceiver =>\n transceiver.receiver.track.kind === 'audio');\n if (offerOptions.offerToReceiveAudio === false && audioTransceiver) {\n if (audioTransceiver.direction === 'sendrecv') {\n if (audioTransceiver.setDirection) {\n audioTransceiver.setDirection('sendonly');\n } else {\n audioTransceiver.direction = 'sendonly';\n }\n } else if (audioTransceiver.direction === 'recvonly') {\n if (audioTransceiver.setDirection) {\n audioTransceiver.setDirection('inactive');\n } else {\n audioTransceiver.direction = 'inactive';\n }\n }\n } else if (offerOptions.offerToReceiveAudio === true &&\n !audioTransceiver) {\n this.addTransceiver('audio', {direction: 'recvonly'});\n }\n\n if (typeof offerOptions.offerToReceiveVideo !== 'undefined') {\n // support bit values\n offerOptions.offerToReceiveVideo =\n !!offerOptions.offerToReceiveVideo;\n }\n const videoTransceiver = this.getTransceivers().find(transceiver =>\n transceiver.receiver.track.kind === 'video');\n if (offerOptions.offerToReceiveVideo === false && videoTransceiver) {\n if (videoTransceiver.direction === 'sendrecv') {\n if (videoTransceiver.setDirection) {\n videoTransceiver.setDirection('sendonly');\n } else {\n videoTransceiver.direction = 'sendonly';\n }\n } else if (videoTransceiver.direction === 'recvonly') {\n if (videoTransceiver.setDirection) {\n videoTransceiver.setDirection('inactive');\n } else {\n videoTransceiver.direction = 'inactive';\n }\n }\n } else if (offerOptions.offerToReceiveVideo === true &&\n !videoTransceiver) {\n this.addTransceiver('video', {direction: 'recvonly'});\n }\n }\n return origCreateOffer.apply(this, arguments);\n };\n}\n\nexport function shimAudioContext(window) {\n if (typeof window !== 'object' || window.AudioContext) {\n return;\n }\n window.AudioContext = window.webkitAudioContext;\n}\n\n","/*\n * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n'use strict';\n\nimport SDPUtils from 'sdp';\nimport * as utils from './utils';\n\nexport function shimRTCIceCandidate(window) {\n // foundation is arbitrarily chosen as an indicator for full support for\n // https://w3c.github.io/webrtc-pc/#rtcicecandidate-interface\n if (!window.RTCIceCandidate || (window.RTCIceCandidate && 'foundation' in\n window.RTCIceCandidate.prototype)) {\n return;\n }\n\n const NativeRTCIceCandidate = window.RTCIceCandidate;\n window.RTCIceCandidate = function RTCIceCandidate(args) {\n // Remove the a= which shouldn't be part of the candidate string.\n if (typeof args === 'object' && args.candidate &&\n args.candidate.indexOf('a=') === 0) {\n args = JSON.parse(JSON.stringify(args));\n args.candidate = args.candidate.substring(2);\n }\n\n if (args.candidate && args.candidate.length) {\n // Augment the native candidate with the parsed fields.\n const nativeCandidate = new NativeRTCIceCandidate(args);\n const parsedCandidate = SDPUtils.parseCandidate(args.candidate);\n for (const key in parsedCandidate) {\n if (!(key in nativeCandidate)) {\n Object.defineProperty(nativeCandidate, key,\n {value: parsedCandidate[key]});\n }\n }\n\n // Override serializer to not serialize the extra attributes.\n nativeCandidate.toJSON = function toJSON() {\n return {\n candidate: nativeCandidate.candidate,\n sdpMid: nativeCandidate.sdpMid,\n sdpMLineIndex: nativeCandidate.sdpMLineIndex,\n usernameFragment: nativeCandidate.usernameFragment,\n };\n };\n return nativeCandidate;\n }\n return new NativeRTCIceCandidate(args);\n };\n window.RTCIceCandidate.prototype = NativeRTCIceCandidate.prototype;\n\n // Hook up the augmented candidate in onicecandidate and\n // addEventListener('icecandidate', ...)\n utils.wrapPeerConnectionEvent(window, 'icecandidate', e => {\n if (e.candidate) {\n Object.defineProperty(e, 'candidate', {\n value: new window.RTCIceCandidate(e.candidate),\n writable: 'false'\n });\n }\n return e;\n });\n}\n\nexport function shimRTCIceCandidateRelayProtocol(window) {\n if (!window.RTCIceCandidate || (window.RTCIceCandidate && 'relayProtocol' in\n window.RTCIceCandidate.prototype)) {\n return;\n }\n\n // Hook up the augmented candidate in onicecandidate and\n // addEventListener('icecandidate', ...)\n utils.wrapPeerConnectionEvent(window, 'icecandidate', e => {\n if (e.candidate) {\n const parsedCandidate = SDPUtils.parseCandidate(e.candidate.candidate);\n if (parsedCandidate.type === 'relay') {\n // This is a libwebrtc-specific mapping of local type preference\n // to relayProtocol.\n e.candidate.relayProtocol = {\n 0: 'tls',\n 1: 'tcp',\n 2: 'udp',\n }[parsedCandidate.priority >> 24];\n }\n }\n return e;\n });\n}\n\nexport function shimMaxMessageSize(window, browserDetails) {\n if (!window.RTCPeerConnection) {\n return;\n }\n\n if (!('sctp' in window.RTCPeerConnection.prototype)) {\n Object.defineProperty(window.RTCPeerConnection.prototype, 'sctp', {\n get() {\n return typeof this._sctp === 'undefined' ? null : this._sctp;\n }\n });\n }\n\n const sctpInDescription = function(description) {\n if (!description || !description.sdp) {\n return false;\n }\n const sections = SDPUtils.splitSections(description.sdp);\n sections.shift();\n return sections.some(mediaSection => {\n const mLine = SDPUtils.parseMLine(mediaSection);\n return mLine && mLine.kind === 'application'\n && mLine.protocol.indexOf('SCTP') !== -1;\n });\n };\n\n const getRemoteFirefoxVersion = function(description) {\n // TODO: Is there a better solution for detecting Firefox?\n const match = description.sdp.match(/mozilla...THIS_IS_SDPARTA-(\\d+)/);\n if (match === null || match.length < 2) {\n return -1;\n }\n const version = parseInt(match[1], 10);\n // Test for NaN (yes, this is ugly)\n return version !== version ? -1 : version;\n };\n\n const getCanSendMaxMessageSize = function(remoteIsFirefox) {\n // Every implementation we know can send at least 64 KiB.\n // Note: Although Chrome is technically able to send up to 256 KiB, the\n // data does not reach the other peer reliably.\n // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=8419\n let canSendMaxMessageSize = 65536;\n if (browserDetails.browser === 'firefox') {\n if (browserDetails.version < 57) {\n if (remoteIsFirefox === -1) {\n // FF < 57 will send in 16 KiB chunks using the deprecated PPID\n // fragmentation.\n canSendMaxMessageSize = 16384;\n } else {\n // However, other FF (and RAWRTC) can reassemble PPID-fragmented\n // messages. Thus, supporting ~2 GiB when sending.\n canSendMaxMessageSize = 2147483637;\n }\n } else if (browserDetails.version < 60) {\n // Currently, all FF >= 57 will reset the remote maximum message size\n // to the default value when a data channel is created at a later\n // stage. :(\n // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831\n canSendMaxMessageSize =\n browserDetails.version === 57 ? 65535 : 65536;\n } else {\n // FF >= 60 supports sending ~2 GiB\n canSendMaxMessageSize = 2147483637;\n }\n }\n return canSendMaxMessageSize;\n };\n\n const getMaxMessageSize = function(description, remoteIsFirefox) {\n // Note: 65536 bytes is the default value from the SDP spec. Also,\n // every implementation we know supports receiving 65536 bytes.\n let maxMessageSize = 65536;\n\n // FF 57 has a slightly incorrect default remote max message size, so\n // we need to adjust it here to avoid a failure when sending.\n // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1425697\n if (browserDetails.browser === 'firefox'\n && browserDetails.version === 57) {\n maxMessageSize = 65535;\n }\n\n const match = SDPUtils.matchPrefix(description.sdp,\n 'a=max-message-size:');\n if (match.length > 0) {\n maxMessageSize = parseInt(match[0].substring(19), 10);\n } else if (browserDetails.browser === 'firefox' &&\n remoteIsFirefox !== -1) {\n // If the maximum message size is not present in the remote SDP and\n // both local and remote are Firefox, the remote peer can receive\n // ~2 GiB.\n maxMessageSize = 2147483637;\n }\n return maxMessageSize;\n };\n\n const origSetRemoteDescription =\n window.RTCPeerConnection.prototype.setRemoteDescription;\n window.RTCPeerConnection.prototype.setRemoteDescription =\n function setRemoteDescription() {\n this._sctp = null;\n // Chrome decided to not expose .sctp in plan-b mode.\n // As usual, adapter.js has to do an 'ugly worakaround'\n // to cover up the mess.\n if (browserDetails.browser === 'chrome' && browserDetails.version >= 76) {\n const {sdpSemantics} = this.getConfiguration();\n if (sdpSemantics === 'plan-b') {\n Object.defineProperty(this, 'sctp', {\n get() {\n return typeof this._sctp === 'undefined' ? null : this._sctp;\n },\n enumerable: true,\n configurable: true,\n });\n }\n }\n\n if (sctpInDescription(arguments[0])) {\n // Check if the remote is FF.\n const isFirefox = getRemoteFirefoxVersion(arguments[0]);\n\n // Get the maximum message size the local peer is capable of sending\n const canSendMMS = getCanSendMaxMessageSize(isFirefox);\n\n // Get the maximum message size of the remote peer.\n const remoteMMS = getMaxMessageSize(arguments[0], isFirefox);\n\n // Determine final maximum message size\n let maxMessageSize;\n if (canSendMMS === 0 && remoteMMS === 0) {\n maxMessageSize = Number.POSITIVE_INFINITY;\n } else if (canSendMMS === 0 || remoteMMS === 0) {\n maxMessageSize = Math.max(canSendMMS, remoteMMS);\n } else {\n maxMessageSize = Math.min(canSendMMS, remoteMMS);\n }\n\n // Create a dummy RTCSctpTransport object and the 'maxMessageSize'\n // attribute.\n const sctp = {};\n Object.defineProperty(sctp, 'maxMessageSize', {\n get() {\n return maxMessageSize;\n }\n });\n this._sctp = sctp;\n }\n\n return origSetRemoteDescription.apply(this, arguments);\n };\n}\n\nexport function shimSendThrowTypeError(window) {\n if (!(window.RTCPeerConnection &&\n 'createDataChannel' in window.RTCPeerConnection.prototype)) {\n return;\n }\n\n // Note: Although Firefox >= 57 has a native implementation, the maximum\n // message size can be reset for all data channels at a later stage.\n // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831\n\n function wrapDcSend(dc, pc) {\n const origDataChannelSend = dc.send;\n dc.send = function send() {\n const data = arguments[0];\n const length = data.length || data.size || data.byteLength;\n if (dc.readyState === 'open' &&\n pc.sctp && length > pc.sctp.maxMessageSize) {\n throw new TypeError('Message too large (can send a maximum of ' +\n pc.sctp.maxMessageSize + ' bytes)');\n }\n return origDataChannelSend.apply(dc, arguments);\n };\n }\n const origCreateDataChannel =\n window.RTCPeerConnection.prototype.createDataChannel;\n window.RTCPeerConnection.prototype.createDataChannel =\n function createDataChannel() {\n const dataChannel = origCreateDataChannel.apply(this, arguments);\n wrapDcSend(dataChannel, this);\n return dataChannel;\n };\n utils.wrapPeerConnectionEvent(window, 'datachannel', e => {\n wrapDcSend(e.channel, e.target);\n return e;\n });\n}\n\n\n/* shims RTCConnectionState by pretending it is the same as iceConnectionState.\n * See https://bugs.chromium.org/p/webrtc/issues/detail?id=6145#c12\n * for why this is a valid hack in Chrome. In Firefox it is slightly incorrect\n * since DTLS failures would be hidden. See\n * https://bugzilla.mozilla.org/show_bug.cgi?id=1265827\n * for the Firefox tracking bug.\n */\nexport function shimConnectionState(window) {\n if (!window.RTCPeerConnection ||\n 'connectionState' in window.RTCPeerConnection.prototype) {\n return;\n }\n const proto = window.RTCPeerConnection.prototype;\n Object.defineProperty(proto, 'connectionState', {\n get() {\n return {\n completed: 'connected',\n checking: 'connecting'\n }[this.iceConnectionState] || this.iceConnectionState;\n },\n enumerable: true,\n configurable: true\n });\n Object.defineProperty(proto, 'onconnectionstatechange', {\n get() {\n return this._onconnectionstatechange || null;\n },\n set(cb) {\n if (this._onconnectionstatechange) {\n this.removeEventListener('connectionstatechange',\n this._onconnectionstatechange);\n delete this._onconnectionstatechange;\n }\n if (cb) {\n this.addEventListener('connectionstatechange',\n this._onconnectionstatechange = cb);\n }\n },\n enumerable: true,\n configurable: true\n });\n\n ['setLocalDescription', 'setRemoteDescription'].forEach((method) => {\n const origMethod = proto[method];\n proto[method] = function() {\n if (!this._connectionstatechangepoly) {\n this._connectionstatechangepoly = e => {\n const pc = e.target;\n if (pc._lastConnectionState !== pc.connectionState) {\n pc._lastConnectionState = pc.connectionState;\n const newEvent = new Event('connectionstatechange', e);\n pc.dispatchEvent(newEvent);\n }\n return e;\n };\n this.addEventListener('iceconnectionstatechange',\n this._connectionstatechangepoly);\n }\n return origMethod.apply(this, arguments);\n };\n });\n}\n\nexport function removeExtmapAllowMixed(window, browserDetails) {\n /* remove a=extmap-allow-mixed for webrtc.org < M71 */\n if (!window.RTCPeerConnection) {\n return;\n }\n if (browserDetails.browser === 'chrome' && browserDetails.version >= 71) {\n return;\n }\n if (browserDetails.browser === 'safari' && browserDetails.version >= 605) {\n return;\n }\n const nativeSRD = window.RTCPeerConnection.prototype.setRemoteDescription;\n window.RTCPeerConnection.prototype.setRemoteDescription =\n function setRemoteDescription(desc) {\n if (desc && desc.sdp && desc.sdp.indexOf('\\na=extmap-allow-mixed') !== -1) {\n const sdp = desc.sdp.split('\\n').filter((line) => {\n return line.trim() !== 'a=extmap-allow-mixed';\n }).join('\\n');\n // Safari enforces read-only-ness of RTCSessionDescription fields.\n if (window.RTCSessionDescription &&\n desc instanceof window.RTCSessionDescription) {\n arguments[0] = new window.RTCSessionDescription({\n type: desc.type,\n sdp,\n });\n } else {\n desc.sdp = sdp;\n }\n }\n return nativeSRD.apply(this, arguments);\n };\n}\n\nexport function shimAddIceCandidateNullOrEmpty(window, browserDetails) {\n // Support for addIceCandidate(null or undefined)\n // as well as addIceCandidate({candidate: \"\", ...})\n // https://bugs.chromium.org/p/chromium/issues/detail?id=978582\n // Note: must be called before other polyfills which change the signature.\n if (!(window.RTCPeerConnection && window.RTCPeerConnection.prototype)) {\n return;\n }\n const nativeAddIceCandidate =\n window.RTCPeerConnection.prototype.addIceCandidate;\n if (!nativeAddIceCandidate || nativeAddIceCandidate.length === 0) {\n return;\n }\n window.RTCPeerConnection.prototype.addIceCandidate =\n function addIceCandidate() {\n if (!arguments[0]) {\n if (arguments[1]) {\n arguments[1].apply(null);\n }\n return Promise.resolve();\n }\n // Firefox 68+ emits and processes {candidate: \"\", ...}, ignore\n // in older versions.\n // Native support for ignoring exists for Chrome M77+.\n // Safari ignores as well, exact version unknown but works in the same\n // version that also ignores addIceCandidate(null).\n if (((browserDetails.browser === 'chrome' && browserDetails.version < 78)\n || (browserDetails.browser === 'firefox'\n && browserDetails.version < 68)\n || (browserDetails.browser === 'safari'))\n && arguments[0] && arguments[0].candidate === '') {\n return Promise.resolve();\n }\n return nativeAddIceCandidate.apply(this, arguments);\n };\n}\n\n// Note: Make sure to call this ahead of APIs that modify\n// setLocalDescription.length\nexport function shimParameterlessSetLocalDescription(window, browserDetails) {\n if (!(window.RTCPeerConnection && window.RTCPeerConnection.prototype)) {\n return;\n }\n const nativeSetLocalDescription =\n window.RTCPeerConnection.prototype.setLocalDescription;\n if (!nativeSetLocalDescription || nativeSetLocalDescription.length === 0) {\n return;\n }\n window.RTCPeerConnection.prototype.setLocalDescription =\n function setLocalDescription() {\n let desc = arguments[0] || {};\n if (typeof desc !== 'object' || (desc.type && desc.sdp)) {\n return nativeSetLocalDescription.apply(this, arguments);\n }\n // The remaining steps should technically happen when SLD comes off the\n // RTCPeerConnection's operations chain (not ahead of going on it), but\n // this is too difficult to shim. Instead, this shim only covers the\n // common case where the operations chain is empty. This is imperfect, but\n // should cover many cases. Rationale: Even if we can't reduce the glare\n // window to zero on imperfect implementations, there's value in tapping\n // into the perfect negotiation pattern that several browsers support.\n desc = {type: desc.type, sdp: desc.sdp};\n if (!desc.type) {\n switch (this.signalingState) {\n case 'stable':\n case 'have-local-offer':\n case 'have-remote-pranswer':\n desc.type = 'offer';\n break;\n default:\n desc.type = 'answer';\n break;\n }\n }\n if (desc.sdp || (desc.type !== 'offer' && desc.type !== 'answer')) {\n return nativeSetLocalDescription.apply(this, [desc]);\n }\n const func = desc.type === 'offer' ? this.createOffer : this.createAnswer;\n return func.apply(this)\n .then(d => nativeSetLocalDescription.apply(this, [d]));\n };\n}\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\nimport * as utils from './utils';\n\n// Browser shims.\nimport * as chromeShim from './chrome/chrome_shim';\nimport * as firefoxShim from './firefox/firefox_shim';\nimport * as safariShim from './safari/safari_shim';\nimport * as commonShim from './common_shim';\nimport * as sdp from 'sdp';\n\n// Shimming starts here.\nexport function adapterFactory({window} = {}, options = {\n shimChrome: true,\n shimFirefox: true,\n shimSafari: true,\n}) {\n // Utils.\n const logging = utils.log;\n const browserDetails = utils.detectBrowser(window);\n\n const adapter = {\n browserDetails,\n commonShim,\n extractVersion: utils.extractVersion,\n disableLog: utils.disableLog,\n disableWarnings: utils.disableWarnings,\n // Expose sdp as a convenience. For production apps include directly.\n sdp,\n };\n\n // Shim browser if found.\n switch (browserDetails.browser) {\n case 'chrome':\n if (!chromeShim || !chromeShim.shimPeerConnection ||\n !options.shimChrome) {\n logging('Chrome shim is not included in this adapter release.');\n return adapter;\n }\n if (browserDetails.version === null) {\n logging('Chrome shim can not determine version, not shimming.');\n return adapter;\n }\n logging('adapter.js shimming chrome.');\n // Export to the adapter global object visible in the browser.\n adapter.browserShim = chromeShim;\n\n // Must be called before shimPeerConnection.\n commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails);\n commonShim.shimParameterlessSetLocalDescription(window, browserDetails);\n\n chromeShim.shimGetUserMedia(window, browserDetails);\n chromeShim.shimMediaStream(window, browserDetails);\n chromeShim.shimPeerConnection(window, browserDetails);\n chromeShim.shimOnTrack(window, browserDetails);\n chromeShim.shimAddTrackRemoveTrack(window, browserDetails);\n chromeShim.shimGetSendersWithDtmf(window, browserDetails);\n chromeShim.shimSenderReceiverGetStats(window, browserDetails);\n chromeShim.fixNegotiationNeeded(window, browserDetails);\n\n commonShim.shimRTCIceCandidate(window, browserDetails);\n commonShim.shimRTCIceCandidateRelayProtocol(window, browserDetails);\n commonShim.shimConnectionState(window, browserDetails);\n commonShim.shimMaxMessageSize(window, browserDetails);\n commonShim.shimSendThrowTypeError(window, browserDetails);\n commonShim.removeExtmapAllowMixed(window, browserDetails);\n break;\n case 'firefox':\n if (!firefoxShim || !firefoxShim.shimPeerConnection ||\n !options.shimFirefox) {\n logging('Firefox shim is not included in this adapter release.');\n return adapter;\n }\n logging('adapter.js shimming firefox.');\n // Export to the adapter global object visible in the browser.\n adapter.browserShim = firefoxShim;\n\n // Must be called before shimPeerConnection.\n commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails);\n commonShim.shimParameterlessSetLocalDescription(window, browserDetails);\n\n firefoxShim.shimGetUserMedia(window, browserDetails);\n firefoxShim.shimPeerConnection(window, browserDetails);\n firefoxShim.shimOnTrack(window, browserDetails);\n firefoxShim.shimRemoveStream(window, browserDetails);\n firefoxShim.shimSenderGetStats(window, browserDetails);\n firefoxShim.shimReceiverGetStats(window, browserDetails);\n firefoxShim.shimRTCDataChannel(window, browserDetails);\n firefoxShim.shimAddTransceiver(window, browserDetails);\n firefoxShim.shimGetParameters(window, browserDetails);\n firefoxShim.shimCreateOffer(window, browserDetails);\n firefoxShim.shimCreateAnswer(window, browserDetails);\n\n commonShim.shimRTCIceCandidate(window, browserDetails);\n commonShim.shimConnectionState(window, browserDetails);\n commonShim.shimMaxMessageSize(window, browserDetails);\n commonShim.shimSendThrowTypeError(window, browserDetails);\n break;\n case 'safari':\n if (!safariShim || !options.shimSafari) {\n logging('Safari shim is not included in this adapter release.');\n return adapter;\n }\n logging('adapter.js shimming safari.');\n // Export to the adapter global object visible in the browser.\n adapter.browserShim = safariShim;\n\n // Must be called before shimCallbackAPI.\n commonShim.shimAddIceCandidateNullOrEmpty(window, browserDetails);\n commonShim.shimParameterlessSetLocalDescription(window, browserDetails);\n\n safariShim.shimRTCIceServerUrls(window, browserDetails);\n safariShim.shimCreateOfferLegacy(window, browserDetails);\n safariShim.shimCallbacksAPI(window, browserDetails);\n safariShim.shimLocalStreamsAPI(window, browserDetails);\n safariShim.shimRemoteStreamsAPI(window, browserDetails);\n safariShim.shimTrackEventTransceiver(window, browserDetails);\n safariShim.shimGetUserMedia(window, browserDetails);\n safariShim.shimAudioContext(window, browserDetails);\n\n commonShim.shimRTCIceCandidate(window, browserDetails);\n commonShim.shimRTCIceCandidateRelayProtocol(window, browserDetails);\n commonShim.shimMaxMessageSize(window, browserDetails);\n commonShim.shimSendThrowTypeError(window, browserDetails);\n commonShim.removeExtmapAllowMixed(window, browserDetails);\n break;\n default:\n logging('Unsupported browser!');\n break;\n }\n\n return adapter;\n}\n","/*\n * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.\n *\n * Use of this source code is governed by a BSD-style license\n * that can be found in the LICENSE file in the root of the source\n * tree.\n */\n/* eslint-env node */\n\n'use strict';\n\nimport {adapterFactory} from './adapter_factory.js';\n\nconst adapter =\n adapterFactory({window: typeof window === 'undefined' ? undefined : window});\nexport default adapter;\n","// @generated by protobuf-ts 2.9.4 with parameter client_generic\n// @generated from protobuf file \"tunnel.proto\" (package \"pulsebeam.v1\", syntax proto3)\n// tslint:disable\nimport { ServiceType } from \"@protobuf-ts/runtime-rpc\";\nimport { MessageType } from \"@protobuf-ts/runtime\";\n/**\n * @generated from protobuf message pulsebeam.v1.PrepareReq\n */\nexport interface PrepareReq {\n}\n/**\n * @generated from protobuf message pulsebeam.v1.PrepareResp\n */\nexport interface PrepareResp {\n /**\n * @generated from protobuf field: repeated pulsebeam.v1.IceServer ice_servers = 1;\n */\n iceServers: IceServer[];\n}\n/**\n * @generated from protobuf message pulsebeam.v1.IceServer\n */\nexport interface IceServer {\n /**\n * @generated from protobuf field: repeated string urls = 1;\n */\n urls: string[];\n /**\n * @generated from protobuf field: optional string username = 2;\n */\n username?: string;\n /**\n * @generated from protobuf field: optional string credential = 3;\n */\n credential?: string;\n}\n/**\n * @generated from protobuf message pulsebeam.v1.SendReq\n */\nexport interface SendReq {\n /**\n * @generated from protobuf field: pulsebeam.v1.Message msg = 1;\n */\n msg?: Message;\n}\n/**\n * @generated from protobuf message pulsebeam.v1.SendResp\n */\nexport interface SendResp {\n}\n/**\n * @generated from protobuf message pulsebeam.v1.RecvReq\n */\nexport interface RecvReq {\n /**\n * @generated from protobuf field: pulsebeam.v1.PeerInfo src = 1;\n */\n src?: PeerInfo;\n}\n/**\n * @generated from protobuf message pulsebeam.v1.RecvResp\n */\nexport interface RecvResp {\n /**\n * @generated from protobuf field: repeated pulsebeam.v1.Message msgs = 1;\n */\n msgs: Message[];\n}\n/**\n * @generated from protobuf message pulsebeam.v1.PeerInfo\n */\nexport interface PeerInfo {\n /**\n * @generated from protobuf field: string group_id = 1;\n */\n groupId: string;\n /**\n * where this message is originated from. Special values: \"SYSTEM\"\n *\n * @generated from protobuf field: string peer_id = 2;\n */\n peerId: string;\n /**\n * used for deciding polite vs impolite. higher id wins. It also is used to detect connection breakages\n * WARNING, reserved values: 0-16\n *\n * @generated from protobuf field: uint32 conn_id = 3;\n */\n connId: number;\n}\n/**\n * Use small tag numbers (1-15) for fields that are frequently used or are performance-sensitive, even if they are optional.\n * Larger tag numbers (16 and above) can be used for fields that are optional and not frequently included in messages, as they will require more bytes to encode.\n * Avoid the 19000–19999 range, as it's reserved.\n * Consider future-proofing your schema by leaving gaps between field numbers to allow for extensions or new fields later.\n *\n * @generated from protobuf message pulsebeam.v1.Message\n */\nexport interface Message {\n /**\n * @generated from protobuf field: pulsebeam.v1.MessageHeader header = 1;\n */\n header?: MessageHeader;\n /**\n * payload will be treated as opaque in backend. Size limit is 10kB.\n *\n * @generated from protobuf field: pulsebeam.v1.MessagePayload payload = 2;\n */\n payload?: MessagePayload;\n}\n/**\n * @generated from protobuf message pulsebeam.v1.MessagePayload\n */\nexport interface MessagePayload {\n /**\n * @generated from protobuf oneof: payload_type\n */\n payloadType: {\n oneofKind: \"signal\";\n /**\n * @generated from protobuf field: pulsebeam.v1.Signal signal = 1;\n */\n signal: Signal;\n } | {\n oneofKind: \"join\";\n /**\n * @generated from protobuf field: pulsebeam.v1.Join join = 2;\n */\n join: Join;\n } | {\n oneofKind: \"bye\";\n /**\n * @generated from protobuf field: pulsebeam.v1.Bye bye = 3;\n */\n bye: Bye;\n } | {\n oneofKind: \"ack\";\n /**\n * @generated from protobuf field: pulsebeam.v1.Ack ack = 4;\n */\n ack: Ack;\n } | {\n oneofKind: undefined;\n };\n}\n/**\n * @generated from protobuf message pulsebeam.v1.MessageHeader\n */\nexport interface MessageHeader {\n /**\n * @generated from protobuf field: pulsebeam.v1.PeerInfo src = 1;\n */\n src?: PeerInfo;\n /**\n * @generated from protobuf field: pulsebeam.v1.PeerInfo dst = 2;\n */\n dst?: PeerInfo;\n /**\n * @generated from protobuf field: uint32 seqnum = 7;\n */\n seqnum: number;\n /**\n * @generated from protobuf field: bool reliable = 8;\n */\n reliable: boolean; // true: tcp like, false: fire & forget\n}\n/**\n * @generated from protobuf message pulsebeam.v1.Signal\n */\nexport interface Signal {\n /**\n * @generated from protobuf field: uint32 generation_counter = 1;\n */\n generationCounter: number;\n /**\n * @generated from protobuf oneof: data\n */\n data: {\n oneofKind: \"sdp\";\n /**\n * @generated from protobuf field: pulsebeam.v1.Sdp sdp = 9;\n */\n sdp: Sdp;\n } | {\n oneofKind: \"iceCandidate\";\n /**\n * @generated from protobuf field: pulsebeam.v1.ICECandidate ice_candidate = 10;\n */\n iceCandidate: ICECandidate;\n } | {\n oneofKind: undefined;\n };\n}\n/**\n * @generated from protobuf message pulsebeam.v1.Sdp\n */\nexport interface Sdp {\n /**\n * @generated from protobuf field: pulsebeam.v1.SdpKind kind = 1;\n */\n kind: SdpKind;\n /**\n * @generated from protobuf field: string sdp = 2;\n */\n sdp: string;\n}\n/**\n * @generated from protobuf message pulsebeam.v1.ICECandidate\n */\nexport interface ICECandidate {\n /**\n * @generated from protobuf field: string candidate = 1;\n */\n candidate: string;\n /**\n * @generated from protobuf field: optional uint32 sdp_m_line_index = 2;\n */\n sdpMLineIndex?: number;\n /**\n * @generated from protobuf field: optional string sdp_mid = 3;\n */\n sdpMid?: string;\n /**\n * @generated from protobuf field: optional string username = 4;\n */\n username?: string;\n /**\n * @generated from protobuf field: optional string password = 5;\n */\n password?: string;\n}\n/**\n * @generated from protobuf message pulsebeam.v1.Join\n */\nexport interface Join {\n}\n/**\n * @generated from protobuf message pulsebeam.v1.Bye\n */\nexport interface Bye {\n}\n/**\n * @generated from protobuf message pulsebeam.v1.Ack\n */\nexport interface Ack {\n /**\n * @generated from protobuf field: repeated pulsebeam.v1.AckRange ack_ranges = 1;\n */\n ackRanges: AckRange[];\n}\n/**\n * @generated from protobuf message pulsebeam.v1.AckRange\n */\nexport interface AckRange {\n /**\n * @generated from protobuf field: uint32 seqnum_start = 1;\n */\n seqnumStart: number;\n /**\n * @generated from protobuf field: uint32 seqnum_end = 2;\n */\n seqnumEnd: number;\n}\n/**\n * reserved for headers\n *\n * @generated from protobuf message pulsebeam.v1.DataChannel\n */\nexport interface DataChannel {\n /**\n * @generated from protobuf oneof: payload\n */\n payload: {\n oneofKind: \"heartbeat\";\n /**\n * @generated from protobuf field: pulsebeam.v1.DataChannelHeartbeat heartbeat = 10;\n */\n heartbeat: DataChannelHeartbeat;\n } | {\n oneofKind: undefined;\n };\n}\n/**\n * @generated from protobuf message pulsebeam.v1.DataChannelHeartbeat\n */\nexport interface DataChannelHeartbeat {\n}\n/**\n * @generated from protobuf enum pulsebeam.v1.SdpKind\n */\nexport enum SdpKind {\n /**\n * @generated from protobuf enum value: SDP_KIND_UNSPECIFIED = 0;\n */\n UNSPECIFIED = 0,\n /**\n * @generated from protobuf enum value: SDP_KIND_OFFER = 1;\n */\n OFFER = 1,\n /**\n * @generated from protobuf enum value: SDP_KIND_ANSWER = 2;\n */\n ANSWER = 2,\n /**\n * @generated from protobuf enum value: SDP_KIND_PRANSWER = 3;\n */\n PRANSWER = 3,\n /**\n * @generated from protobuf enum value: SDP_KIND_ROLLBACK = 4;\n */\n ROLLBACK = 4\n}\n// @generated message type with reflection information, may provide speed optimized methods\nclass PrepareReq$Type extends MessageType<PrepareReq> {\n constructor() {\n super(\"pulsebeam.v1.PrepareReq\", []);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.PrepareReq\n */\nexport const PrepareReq = new PrepareReq$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass PrepareResp$Type extends MessageType<PrepareResp> {\n constructor() {\n super(\"pulsebeam.v1.PrepareResp\", [\n { no: 1, name: \"ice_servers\", kind: \"message\", repeat: 1 /*RepeatType.PACKED*/, T: () => IceServer }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.PrepareResp\n */\nexport const PrepareResp = new PrepareResp$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass IceServer$Type extends MessageType<IceServer> {\n constructor() {\n super(\"pulsebeam.v1.IceServer\", [\n { no: 1, name: \"urls\", kind: \"scalar\", repeat: 2 /*RepeatType.UNPACKED*/, T: 9 /*ScalarType.STRING*/ },\n { no: 2, name: \"username\", kind: \"scalar\", opt: true, T: 9 /*ScalarType.STRING*/ },\n { no: 3, name: \"credential\", kind: \"scalar\", opt: true, T: 9 /*ScalarType.STRING*/ }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.IceServer\n */\nexport const IceServer = new IceServer$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass SendReq$Type extends MessageType<SendReq> {\n constructor() {\n super(\"pulsebeam.v1.SendReq\", [\n { no: 1, name: \"msg\", kind: \"message\", T: () => Message }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.SendReq\n */\nexport const SendReq = new SendReq$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass SendResp$Type extends MessageType<SendResp> {\n constructor() {\n super(\"pulsebeam.v1.SendResp\", []);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.SendResp\n */\nexport const SendResp = new SendResp$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass RecvReq$Type extends MessageType<RecvReq> {\n constructor() {\n super(\"pulsebeam.v1.RecvReq\", [\n { no: 1, name: \"src\", kind: \"message\", T: () => PeerInfo }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.RecvReq\n */\nexport const RecvReq = new RecvReq$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass RecvResp$Type extends MessageType<RecvResp> {\n constructor() {\n super(\"pulsebeam.v1.RecvResp\", [\n { no: 1, name: \"msgs\", kind: \"message\", repeat: 1 /*RepeatType.PACKED*/, T: () => Message }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.RecvResp\n */\nexport const RecvResp = new RecvResp$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass PeerInfo$Type extends MessageType<PeerInfo> {\n constructor() {\n super(\"pulsebeam.v1.PeerInfo\", [\n { no: 1, name: \"group_id\", kind: \"scalar\", T: 9 /*ScalarType.STRING*/ },\n { no: 2, name: \"peer_id\", kind: \"scalar\", T: 9 /*ScalarType.STRING*/ },\n { no: 3, name: \"conn_id\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.PeerInfo\n */\nexport const PeerInfo = new PeerInfo$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass Message$Type extends MessageType<Message> {\n constructor() {\n super(\"pulsebeam.v1.Message\", [\n { no: 1, name: \"header\", kind: \"message\", T: () => MessageHeader },\n { no: 2, name: \"payload\", kind: \"message\", T: () => MessagePayload }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.Message\n */\nexport const Message = new Message$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass MessagePayload$Type extends MessageType<MessagePayload> {\n constructor() {\n super(\"pulsebeam.v1.MessagePayload\", [\n { no: 1, name: \"signal\", kind: \"message\", oneof: \"payloadType\", T: () => Signal },\n { no: 2, name: \"join\", kind: \"message\", oneof: \"payloadType\", T: () => Join },\n { no: 3, name: \"bye\", kind: \"message\", oneof: \"payloadType\", T: () => Bye },\n { no: 4, name: \"ack\", kind: \"message\", oneof: \"payloadType\", T: () => Ack }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.MessagePayload\n */\nexport const MessagePayload = new MessagePayload$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass MessageHeader$Type extends MessageType<MessageHeader> {\n constructor() {\n super(\"pulsebeam.v1.MessageHeader\", [\n { no: 1, name: \"src\", kind: \"message\", T: () => PeerInfo },\n { no: 2, name: \"dst\", kind: \"message\", T: () => PeerInfo },\n { no: 7, name: \"seqnum\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ },\n { no: 8, name: \"reliable\", kind: \"scalar\", T: 8 /*ScalarType.BOOL*/ }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.MessageHeader\n */\nexport const MessageHeader = new MessageHeader$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass Signal$Type extends MessageType<Signal> {\n constructor() {\n super(\"pulsebeam.v1.Signal\", [\n { no: 1, name: \"generation_counter\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ },\n { no: 9, name: \"sdp\", kind: \"message\", oneof: \"data\", T: () => Sdp },\n { no: 10, name: \"ice_candidate\", kind: \"message\", oneof: \"data\", T: () => ICECandidate }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.Signal\n */\nexport const Signal = new Signal$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass Sdp$Type extends MessageType<Sdp> {\n constructor() {\n super(\"pulsebeam.v1.Sdp\", [\n { no: 1, name: \"kind\", kind: \"enum\", T: () => [\"pulsebeam.v1.SdpKind\", SdpKind, \"SDP_KIND_\"] },\n { no: 2, name: \"sdp\", kind: \"scalar\", T: 9 /*ScalarType.STRING*/ }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.Sdp\n */\nexport const Sdp = new Sdp$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass ICECandidate$Type extends MessageType<ICECandidate> {\n constructor() {\n super(\"pulsebeam.v1.ICECandidate\", [\n { no: 1, name: \"candidate\", kind: \"scalar\", T: 9 /*ScalarType.STRING*/ },\n { no: 2, name: \"sdp_m_line_index\", kind: \"scalar\", opt: true, T: 13 /*ScalarType.UINT32*/ },\n { no: 3, name: \"sdp_mid\", kind: \"scalar\", opt: true, T: 9 /*ScalarType.STRING*/ },\n { no: 4, name: \"username\", kind: \"scalar\", opt: true, T: 9 /*ScalarType.STRING*/ },\n { no: 5, name: \"password\", kind: \"scalar\", opt: true, T: 9 /*ScalarType.STRING*/ }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.ICECandidate\n */\nexport const ICECandidate = new ICECandidate$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass Join$Type extends MessageType<Join> {\n constructor() {\n super(\"pulsebeam.v1.Join\", []);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.Join\n */\nexport const Join = new Join$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass Bye$Type extends MessageType<Bye> {\n constructor() {\n super(\"pulsebeam.v1.Bye\", []);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.Bye\n */\nexport const Bye = new Bye$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass Ack$Type extends MessageType<Ack> {\n constructor() {\n super(\"pulsebeam.v1.Ack\", [\n { no: 1, name: \"ack_ranges\", kind: \"message\", repeat: 1 /*RepeatType.PACKED*/, T: () => AckRange }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.Ack\n */\nexport const Ack = new Ack$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass AckRange$Type extends MessageType<AckRange> {\n constructor() {\n super(\"pulsebeam.v1.AckRange\", [\n { no: 1, name: \"seqnum_start\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ },\n { no: 2, name: \"seqnum_end\", kind: \"scalar\", T: 13 /*ScalarType.UINT32*/ }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.AckRange\n */\nexport const AckRange = new AckRange$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass DataChannel$Type extends MessageType<DataChannel> {\n constructor() {\n super(\"pulsebeam.v1.DataChannel\", [\n { no: 10, name: \"heartbeat\", kind: \"message\", oneof: \"payload\", T: () => DataChannelHeartbeat }\n ]);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.DataChannel\n */\nexport const DataChannel = new DataChannel$Type();\n// @generated message type with reflection information, may provide speed optimized methods\nclass DataChannelHeartbeat$Type extends MessageType<DataChannelHeartbeat> {\n constructor() {\n super(\"pulsebeam.v1.DataChannelHeartbeat\", []);\n }\n}\n/**\n * @generated MessageType for protobuf message pulsebeam.v1.DataChannelHeartbeat\n */\nexport const DataChannelHeartbeat = new DataChannelHeartbeat$Type();\n/**\n * @generated ServiceType for protobuf service pulsebeam.v1.Tunnel\n */\nexport const Tunnel = new ServiceType(\"pulsebeam.v1.Tunnel\", [\n { name: \"Prepare\", options: {}, I: PrepareReq, O: PrepareResp },\n { name: \"Send\", options: {}, I: SendReq, O: SendResp },\n { name: \"Recv\", options: {}, I: RecvReq, O: RecvResp }\n]);\n","// @generated by protobuf-ts 2.9.4 with parameter client_generic\n// @generated from protobuf file \"tunnel.proto\" (package \"pulsebeam.v1\", syntax proto3)\n// tslint:disable\nimport type { RpcTransport } from \"@protobuf-ts/runtime-rpc\";\nimport type { ServiceInfo } from \"@protobuf-ts/runtime-rpc\";\nimport { Tunnel } from \"./tunnel.ts\";\nimport type { RecvResp } from \"./tunnel.ts\";\nimport type { RecvReq } from \"./tunnel.ts\";\nimport type { SendResp } from \"./tunnel.ts\";\nimport type { SendReq } from \"./tunnel.ts\";\nimport { stackIntercept } from \"@protobuf-ts/runtime-rpc\";\nimport type { PrepareResp } from \"./tunnel.ts\";\nimport type { PrepareReq } from \"./tunnel.ts\";\nimport type { UnaryCall } from \"@protobuf-ts/runtime-rpc\";\nimport type { RpcOptions } from \"@protobuf-ts/runtime-rpc\";\n/**\n * @generated from protobuf service pulsebeam.v1.Tunnel\n */\nexport interface ITunnelClient {\n /**\n * @generated from protobuf rpc: Prepare(pulsebeam.v1.PrepareReq) returns (pulsebeam.v1.PrepareResp);\n */\n prepare(input: PrepareReq, options?: RpcOptions): UnaryCall<PrepareReq, PrepareResp>;\n /**\n * @generated from protobuf rpc: Send(pulsebeam.v1.SendReq) returns (pulsebeam.v1.SendResp);\n */\n send(input: SendReq, options?: RpcOptions): UnaryCall<SendReq, SendResp>;\n /**\n * @generated from protobuf rpc: Recv(pulsebeam.v1.RecvReq) returns (pulsebeam.v1.RecvResp);\n */\n recv(input: RecvReq, options?: RpcOptions): UnaryCall<RecvReq, RecvResp>;\n}\n/**\n * @generated from protobuf service pulsebeam.v1.Tunnel\n */\nexport class TunnelClient implements ITunnelClient, ServiceInfo {\n typeName = Tunnel.typeName;\n methods = Tunnel.methods;\n options = Tunnel.options;\n constructor(private readonly _transport: RpcTransport) {\n }\n /**\n * @generated from protobuf rpc: Prepare(pulsebeam.v1.PrepareReq) returns (pulsebeam.v1.PrepareResp);\n */\n prepare(input: PrepareReq, options?: RpcOptions): UnaryCall<PrepareReq, PrepareResp> {\n const method = this.methods[0], opt = this._transport.mergeOptions(options);\n return stackIntercept<PrepareReq, PrepareResp>(\"unary\", this._transport, method, opt, input);\n }\n /**\n * @generated from protobuf rpc: Send(pulsebeam.v1.SendReq) returns (pulsebeam.v1.SendResp);\n */\n send(input: SendReq, options?: RpcOptions): UnaryCall<SendReq, SendResp> {\n const method = this.methods[1], opt = this._transport.mergeOptions(options);\n return stackIntercept<SendReq, SendResp>(\"unary\", this._transport, method, opt, input);\n }\n /**\n * @generated from protobuf rpc: Recv(pulsebeam.v1.RecvReq) returns (pulsebeam.v1.RecvResp);\n */\n recv(input: RecvReq, options?: RpcOptions): UnaryCall<RecvReq, RecvResp> {\n const method = this.methods[2], opt = this._transport.mergeOptions(options);\n return stackIntercept<RecvReq, RecvResp>(\"unary\", this._transport, method, opt, input);\n }\n}\n","/**\n * asleep is an async version of setTimeout with abortable signal.\n * the function will resolve to false when aborted, meaning the delay will\n * be less than the expected.\n */\nexport function asleep(ms: number, signal?: AbortSignal): Promise<boolean> {\n return new Promise((resolve) => {\n const timeoutId = setTimeout(() => resolve(true), ms);\n\n // If an AbortSignal is provided, listen for the 'abort' event\n if (signal) {\n signal.addEventListener(\"abort\", () => {\n clearTimeout(timeoutId); // Cancel the delay\n resolve(false);\n });\n }\n });\n}\n\nexport function joinSignals(...signals: AbortSignal[]): AbortSignal {\n const joined = new AbortController();\n\n const joinedAbort = () => {\n joined.abort();\n\n for (const signal of signals) {\n signal.removeEventListener(\"abort\", joinedAbort);\n }\n };\n\n for (const signal of signals) {\n signal.addEventListener(\"abort\", joinedAbort);\n }\n\n return joined.signal;\n}\n\nexport type RetryOptions = {\n maxRetries: number; // Maximum retry attempts. negative means no limit, 0 means 1 try (0 retry)\n baseDelay: number; // Initial delay in milliseconds\n maxDelay: number; // Maximum delay in milliseconds\n jitterFactor?: number; // Jitter percentage (e.g., 0.3 for 30%)\n isRecoverable?: (error: unknown) => boolean; // Function to categorize recoverable errors\n abortSignal?: AbortSignal;\n};\n\nexport async function retry<T>(\n asyncFunction: () => Promise<T>,\n options: RetryOptions,\n): Promise<T | null> {\n const {\n maxRetries,\n baseDelay,\n maxDelay,\n jitterFactor = 0.3,\n isRecoverable = () => true, // Default: all errors are recoverable\n abortSignal,\n } = options;\n\n let attempt = 0;\n\n while ((attempt <= maxRetries || maxRetries < 0) && !abortSignal?.aborted) {\n try {\n return await asyncFunction(); // Execute the function\n } catch (error) {\n // Check if the error is recoverable\n if (!isRecoverable(error)) {\n throw error; // Non-recoverable error, rethrow it\n }\n\n attempt++;\n if (maxRetries >= 0 && attempt > maxRetries) {\n throw error; // Exceeded max retries\n }\n\n // Calculate delay with exponential backoff and jitter\n const delay = calculateDelay(attempt, baseDelay, maxDelay, jitterFactor);\n await asleep(delay, abortSignal).catch(() => { }); // Wait before the next attempt\n }\n }\n\n if (abortSignal?.aborted) {\n return null;\n }\n\n throw new Error(\"Retry failed: max retries exceeded\"); // This is a fallback; should rarely occur\n}\n\n// Helper to calculate exponential backoff with jitter\nfunction calculateDelay(\n attempt: number,\n baseDelay: number,\n maxDelay: number,\n jitterFactor: number,\n): number {\n const exponentialDelay = Math.min(baseDelay * 2 ** (attempt - 1), maxDelay);\n const jitter = Math.random() * jitterFactor * exponentialDelay;\n return exponentialDelay + jitter;\n}\n","import type {\n Ack,\n Message,\n MessageHeader,\n MessagePayload,\n PeerInfo,\n} from \"./tunnel.ts\";\nimport { ITunnelClient } from \"./tunnel.client.ts\";\nimport type { Logger } from \"./logger.ts\";\nimport { asleep, joinSignals, retry, RetryOptions } from \"./util.ts\";\nimport { RpcOptions } from \"@protobuf-ts/runtime-rpc\";\n\nconst POLL_TIMEOUT_MS = 900000;\nconst POLL_RETRY_BASE_DELAY_MS = 50;\nconst POLL_RETRY_MAX_DELAY_MS = 1000;\nconst MAX_RELIABLE_RETRY_COUNT = 5;\nconst STREAM_GC_DELAY_MS = 10_000; // just enough to avoid collision and quick enough to reuse connection\nconst STREAM_GC_INTERVAL_MS = 1_000;\n\nexport enum ReservedConnId {\n Discovery = 0,\n Max = 16,\n}\n\nconst defaultAsleep = asleep;\nconst defaultRandUint32 = (\n reserved: number,\n) => (Math.floor(Math.random() * ((2 ** 32) - reserved)) + reserved);\nconst defaultIsRecoverable = (_err: unknown) => true;\n\n// This is a processing queue that can handle unreliable and reliable messages.\n// The processing prioritizes unreliable messages over reliable messages.\n// Reliable messages will be always deduplicated, unreliable messages will not be deduped.\nclass Queue {\n private map: Map<number, [number, Message]>;\n private emitted: Map<number, [number, Message]>;\n private unreliable: Message[];\n private processing: boolean;\n private readonly logger: Logger;\n public onmsg = async (_: Message) => {};\n\n constructor(logger: Logger) {\n this.logger = logger.sub(\"queue\");\n this.map = new Map();\n this.emitted = new Map();\n this.unreliable = [];\n this.processing = false;\n }\n\n enqueue(msg: Message) {\n if (!msg.header?.reliable) {\n this.unreliable.push(msg);\n } else {\n const seqnum = msg.header!.seqnum;\n if (this.map.has(seqnum) || this.emitted.has(seqnum)) return;\n this.map.set(seqnum, [performance.now(), msg]);\n }\n\n // TODO: control queue size by pruning old messages.\n this.processNext();\n }\n\n async processNext() {\n if (this.processing) return;\n\n let msg = this.unreliable.pop();\n if (!msg) {\n const res = this.map.entries().next().value;\n if (!res) return;\n\n const [key, value] = res;\n this.map.delete(key);\n this.emitted.set(key, value);\n const [_, m] = value;\n if (!m.header) return;\n msg = m;\n }\n\n this.processing = true;\n try {\n await this.onmsg(msg);\n } catch (err) {\n const obj: Record<string, unknown> = { msg };\n if (err instanceof Error) {\n obj[\"err\"] = err;\n }\n this.logger.error(\"error processing message\", obj);\n }\n this.processing = false;\n this.processNext();\n }\n}\n\nexport interface TransportOptions {\n readonly enableDiscovery: boolean;\n readonly groupId: string;\n readonly peerId: string;\n readonly logger: Logger;\n readonly asleep?: typeof defaultAsleep;\n readonly randUint32?: typeof defaultRandUint32;\n readonly isRecoverable?: typeof defaultIsRecoverable;\n}\n\nexport class Transport {\n public readonly info: PeerInfo;\n private streams: Stream[];\n private abort: AbortController;\n public readonly logger: Logger;\n public readonly asleep: typeof defaultAsleep;\n private readonly randUint32: typeof defaultRandUint32;\n private readonly isRecoverable: typeof defaultIsRecoverable;\n public onstream = (_: Stream) => {};\n public onclosed = (_reason: string) => {};\n\n constructor(\n private readonly client: ITunnelClient,\n public readonly opts: TransportOptions,\n ) {\n this.asleep = opts.asleep || defaultAsleep;\n this.randUint32 = opts.randUint32 || defaultRandUint32;\n this.isRecoverable = opts.isRecoverable || defaultIsRecoverable;\n\n this.info = {\n groupId: opts.groupId,\n peerId: opts.peerId,\n connId: this.randUint32(ReservedConnId.Max),\n };\n this.abort = new AbortController();\n this.logger = opts.logger.sub(\"transport\", {\n info: this.info,\n });\n this.streams = [];\n }\n\n async listen() {\n await Promise.all([\n this.pollLoop(),\n this.gcLoop(),\n ]);\n }\n\n async gcLoop() {\n while (!this.abort.signal.aborted) {\n // use cooldown period to fully close. Otherwise, there's a chance that the other peer is\n // still sending some messages. In which case, we need to still ignore for some time until completely quiet.\n this.streams = this.streams.filter((s) => !s.isClosed());\n await asleep(STREAM_GC_INTERVAL_MS, this.abort.signal);\n }\n this.logger.debug(\"gc loop is closed\");\n }\n\n async pollLoop() {\n const rpcOpt: RpcOptions = {\n abort: this.abort.signal,\n timeout: POLL_TIMEOUT_MS,\n };\n const retryOpt: RetryOptions = {\n baseDelay: POLL_RETRY_BASE_DELAY_MS,\n maxDelay: POLL_RETRY_MAX_DELAY_MS,\n maxRetries: -1,\n abortSignal: this.abort.signal,\n isRecoverable: this.isRecoverable,\n };\n\n while (!this.abort.signal.aborted) {\n try {\n const resp = await retry(async () =>\n await this.client.recv({\n src: this.info,\n }, rpcOpt), retryOpt);\n if (resp === null) {\n break;\n }\n\n // make sure to not block polling loop\n new Promise(() => this.handleMessages(resp.response.msgs));\n } catch (err) {\n this.logger.error(\"unrecoverable error, force closing\", { err });\n this.close();\n return;\n }\n }\n this.logger.debug(\"poll loop is closed\");\n }\n\n async close(reason?: string) {\n if (this.abort.signal.aborted) return;\n reason = reason || \"transport is closed\";\n await Promise.all(this.streams.map((s) => s.close(reason)));\n // Give a chance for graceful shutdown before aborting the connection\n this.abort.abort(reason);\n this.logger.debug(\"transport is now closed\", { reason });\n this.streams = [];\n this.onclosed(reason);\n }\n\n private handleMessages = (msgs: Message[]) => {\n for (const msg of msgs) {\n this.logger.debug(\"received\", { msg: msg });\n if (this.abort.signal.aborted) return;\n if (!msg.header) continue;\n const src = msg.header.src;\n const dst = msg.header.dst;\n if (!src || !dst) continue;\n\n if (\n dst.connId >= ReservedConnId.Max &&\n dst.connId != this.info.connId\n ) {\n this.logger.warn(\n \"received messages from a stale connection, ignoring\",\n { receivedConnID: dst.connId },\n );\n continue;\n }\n\n let stream: Stream | null = null;\n for (const s of this.streams) {\n if (\n src.groupId === s.other.groupId &&\n src.peerId === s.other.peerId &&\n src.connId === s.other.connId\n ) {\n stream = s;\n break;\n }\n }\n\n if (!stream) {\n this.logger.debug(\n `session not found, creating one for ${src.peerId}:${src.connId}`,\n );\n\n if (src.peerId == this.info.peerId) {\n this.logger.warn(\"loopback detected, ignoring messages\");\n return;\n }\n\n stream = new Stream(\n this,\n this.info,\n src,\n this.logger,\n );\n this.streams.push(stream);\n this.onstream(stream);\n }\n\n stream.enqueue(msg);\n }\n };\n\n async connect(\n otherGroupId: string,\n otherPeerId: string,\n signal: AbortSignal,\n ) {\n const payload: MessagePayload = {\n payloadType: {\n oneofKind: \"join\",\n join: {},\n },\n };\n const header: MessageHeader = {\n src: this.info,\n dst: {\n groupId: otherGroupId,\n peerId: otherPeerId,\n connId: ReservedConnId.Discovery,\n },\n seqnum: 0,\n reliable: false,\n };\n\n let found = false;\n const joinedSignal = joinSignals(signal, this.abort.signal);\n while (!joinedSignal.aborted && !found) {\n await this.send(joinedSignal, {\n header,\n payload,\n });\n await this.asleep(POLL_RETRY_MAX_DELAY_MS, joinedSignal).catch(() => {});\n\n found = !!this.streams.find((s) =>\n s.other.groupId === otherGroupId && s.other.peerId === otherPeerId\n );\n }\n }\n\n async send(signal: AbortSignal, msg: Message) {\n const joinedSignal = joinSignals(signal, this.abort.signal);\n const rpcOpt: RpcOptions = {\n abort: joinedSignal,\n timeout: POLL_TIMEOUT_MS,\n };\n const retryOpt: RetryOptions = {\n baseDelay: POLL_RETRY_BASE_DELAY_MS,\n maxDelay: POLL_RETRY_MAX_DELAY_MS,\n maxRetries: -1,\n abortSignal: joinedSignal,\n isRecoverable: this.isRecoverable,\n };\n\n try {\n const resp = await retry(async () =>\n await this.client.send(\n { msg },\n rpcOpt,\n ), retryOpt);\n if (resp === null) {\n this.logger.warn(\"aborted, message dropped from sending\", { msg });\n return;\n }\n\n return;\n } catch (err) {\n this.logger.error(\"unrecoverable error, force closing\", { err });\n this.close();\n return;\n }\n }\n}\n\n// Stream allows multiplexing on top of Transport, and\n// configuring order and reliability mode\nexport class Stream {\n public readonly logger: Logger;\n private abort: AbortController;\n public recvq: Queue;\n public ackedbuf: Record<string, boolean>;\n private lastSeqnum: number;\n private closedAt: number;\n public onpayload = async (_: MessagePayload) => {};\n public onclosed = (_reason: string) => {};\n\n constructor(\n private readonly transport: Transport,\n public readonly info: PeerInfo,\n public readonly other: PeerInfo,\n logger: Logger,\n ) {\n this.logger = logger.sub(\"stream\", {\n other,\n });\n this.abort = new AbortController();\n this.ackedbuf = {};\n this.recvq = new Queue(this.logger);\n this.recvq.onmsg = (msg) => this.handleMessage(msg);\n this.lastSeqnum = 0;\n this.closedAt = 0;\n }\n\n createSignal(...signals: AbortSignal[]): AbortSignal {\n return joinSignals(this.abort.signal, ...signals);\n }\n\n isClosed(): boolean {\n const closed = this.abort.signal.aborted &&\n (performance.now() - this.closedAt) > STREAM_GC_DELAY_MS;\n\n if (closed) {\n this.logger.debug(\"stream is ready for GC\");\n }\n return closed;\n }\n\n enqueue(msg: Message) {\n if (this.abort.signal.aborted) {\n this.logger.warn(\n \"received a message in closed state, ignoring new messages.\",\n );\n return;\n }\n\n this.recvq.enqueue(msg);\n }\n\n async send(payload: MessagePayload, reliable: boolean, signal?: AbortSignal) {\n if (!signal) {\n signal = this.abort.signal;\n }\n const msg: Message = {\n header: {\n src: this.transport.info,\n dst: this.other,\n seqnum: 0,\n reliable,\n },\n payload: { ...payload },\n };\n\n if (!reliable) {\n await this.transport.send(signal, msg);\n return;\n }\n\n this.lastSeqnum++;\n msg.header!.seqnum = this.lastSeqnum;\n this.ackedbuf[msg.header!.seqnum] = false; // marked as unacked\n const resendLimit = MAX_RELIABLE_RETRY_COUNT;\n let tryCount = resendLimit;\n const seqnum = msg.header!.seqnum;\n\n // TODO: abort when generation counter doesn't match\n while (!signal.aborted) {\n await this.transport.send(this.abort.signal, msg);\n\n await this.transport.asleep(\n 5 * POLL_RETRY_MAX_DELAY_MS,\n this.abort.signal,\n ).catch(() => {});\n\n // since ackedbuf doesn't delete the seqnum right away, it prevents from racing between\n // resending and acknolwedging\n if (this.ackedbuf[seqnum]) {\n break;\n }\n\n if (tryCount <= 0) {\n const message = \"reached the maximum resend limit, dropping message\";\n this.logger.warn(message, {\n seqnum,\n resendLimit,\n reliable,\n });\n throw new Error(message);\n }\n\n tryCount--;\n this.logger.debug(\"resending\", { ...msg.header });\n }\n }\n\n private async handleMessage(msg: Message) {\n const payload = msg.payload!.payloadType;\n switch (payload.oneofKind) {\n case \"ack\":\n this.handleAck(payload.ack);\n break;\n case \"bye\":\n this.close(\"received bye from other peer\");\n break;\n case undefined:\n break;\n default: {\n if (msg.header!.reliable) {\n const ack: Ack = {\n ackRanges: [{\n seqnumStart: msg.header!.seqnum,\n seqnumEnd: msg.header!.seqnum + 1,\n }],\n };\n const reply: MessagePayload = {\n payloadType: { oneofKind: \"ack\", ack },\n };\n this.logger.debug(\"ack\", { seqnum: msg.header!.seqnum });\n this.send(reply, false);\n }\n\n if (!msg.payload) return;\n await this.onpayload(msg.payload!);\n break;\n }\n }\n }\n\n handleAck(ack: Ack) {\n for (const r of ack.ackRanges) {\n for (let s = r.seqnumStart; s < r.seqnumEnd; s++) {\n this.logger.debug(\"received ack\", { seqnum: s });\n this.ackedbuf[s] = true; // marked as acked\n }\n }\n }\n\n async close(reason?: string) {\n if (this.abort.signal.aborted) return;\n reason = reason || \"session is closed\";\n // make sure to give a chance to send a message\n await this.send({\n payloadType: {\n oneofKind: \"bye\",\n bye: {},\n },\n }, false).catch((err) =>\n this.logger.warn(\"failed to send bye\", { e: err })\n );\n this.abort.abort(reason);\n this.closedAt = performance.now();\n this.onclosed(reason);\n this.logger.debug(\"sent bye to the other peer\", { reason });\n }\n}\n","type LogObj = Record<string, unknown>;\ntype LogHandler = (_obj: LogObj) => void;\ntype LogSink = {\n \"DEBUG\": LogHandler;\n \"INFO\": LogHandler;\n \"WARN\": LogHandler;\n \"ERROR\": LogHandler;\n};\n\nexport const DEFAULT_LOG_SINK: LogSink = {\n DEBUG: console.debug,\n INFO: console.info,\n WARN: console.warn,\n ERROR: console.error,\n};\n\n// inspired by toml format, https://toml.io/en/\n// the main difference is that the fields are appended on the same line\n// to optimize readability in console.\nexport const PRETTY_LOG_SINK: LogSink = {\n DEBUG: (o) => console.debug(pretty(o)),\n INFO: (o) => console.info(pretty(o)),\n WARN: (o) => console.warn(pretty(o)),\n ERROR: (o) => console.error(pretty(o)),\n};\n\nexport function flatten(\n obj: LogObj,\n pairs: Record<string, string[]>,\n parentKey = \"root\",\n visited = new Set<LogObj>(),\n) {\n const sep = \".\";\n if (visited.has(obj)) return; // Stop if already visited\n visited.add(obj);\n\n for (const key in obj) {\n if (typeof obj[key] === \"object\" && obj[key] !== null) {\n const newKey = parentKey + sep + key;\n flatten(obj[key] as LogObj, pairs, newKey, visited);\n } else {\n const p = pairs[parentKey] || [];\n p.push(`${key}=${obj[key]}`);\n pairs[parentKey] = p;\n }\n }\n}\n\nexport function pretty(obj: LogObj) {\n const pairs: Record<string, string[]> = {};\n flatten(obj, pairs);\n\n const lines: string[] = [];\n for (const k in pairs) {\n lines.push(`[${k}] ${pairs[k].join(\" \")}`);\n }\n return lines.join(\"\\n\");\n}\n\nexport class Logger {\n private readonly obj: LogObj;\n private readonly sink: LogSink;\n constructor(public readonly name: string, obj?: LogObj, sink?: LogSink) {\n if (!obj) obj = {};\n if (!sink) sink = DEFAULT_LOG_SINK;\n this.sink = sink;\n this.obj = { ...obj, name };\n }\n\n private log(\n handler: LogHandler,\n message: string,\n obj?: LogObj,\n ): void {\n const o = obj || {};\n handler({\n ts: Date.now(),\n message,\n ...this.obj,\n ...o,\n });\n }\n\n debug(message: string, obj?: LogObj): void {\n this.log(this.sink.DEBUG, message, obj);\n }\n\n info(message: string, obj?: LogObj): void {\n this.log(this.sink.INFO, message, obj);\n }\n\n warn(message: string, obj?: LogObj): void {\n this.log(this.sink.WARN, message, obj);\n }\n\n error(message: string, obj?: LogObj): void {\n this.log(this.sink.ERROR, message, obj);\n }\n\n sub(name: string, obj?: LogObj): Logger {\n if (!obj) obj = {};\n return new Logger(\n this.name + \".\" + name,\n { ...this.obj, ...obj },\n this.sink,\n );\n }\n}\n","import {\n type ICECandidate,\n type MessagePayload,\n PeerInfo,\n SdpKind,\n type Signal,\n} from \"./tunnel.ts\";\nimport { Logger } from \"./logger.ts\";\nimport type { Stream } from \"./transport.ts\";\nexport type { PeerInfo } from \"./tunnel.ts\";\n\nconst ICE_RESTART_MAX_COUNT = 2;\nconst ICE_RESTART_DEBOUNCE_DELAY_MS = 5000;\n\nfunction toIceCandidate(ice: ICECandidate): RTCIceCandidateInit {\n return {\n candidate: ice.candidate,\n sdpMid: ice.sdpMid,\n sdpMLineIndex: ice.sdpMLineIndex,\n usernameFragment: ice.password,\n };\n}\n\nfunction toSDPType(kind: SdpKind): RTCSdpType {\n switch (kind) {\n case SdpKind.OFFER:\n return \"offer\";\n case SdpKind.ANSWER:\n return \"answer\";\n case SdpKind.PRANSWER:\n return \"pranswer\";\n case SdpKind.ROLLBACK:\n return \"rollback\";\n default:\n throw new Error(`unexpected kind: ${kind}`);\n }\n}\n\nfunction fromSDPType(t: RTCSdpType): SdpKind {\n switch (t) {\n case \"offer\":\n return SdpKind.OFFER;\n case \"answer\":\n return SdpKind.ANSWER;\n case \"pranswer\":\n return SdpKind.PRANSWER;\n case \"rollback\":\n return SdpKind.ROLLBACK;\n default:\n throw new Error(`unexpected sdp type: ${t}`);\n }\n}\n/**\n * The Session class is a wrapper around RTCPeerConnection designed to manage\n * WebRTC connections, signaling, and ICE candidates. It handles negotiation,\n * ICE restarts, signaling messages, and connection lifecycle events.\n */\nexport class Session {\n private pc: RTCPeerConnection;\n private makingOffer: boolean;\n private impolite: boolean;\n private pendingCandidates: RTCIceCandidateInit[];\n private readonly logger: Logger;\n private abort: AbortController;\n private generationCounter: number;\n private iceRestartCount: number;\n private lastIceRestart: number;\n private timers: number[];\n private _closeReason?: string;\n private _connectionState: RTCPeerConnectionState;\n\n /**\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/ondatachannel}\n */\n public ondatachannel: RTCPeerConnection[\"ondatachannel\"] = () => {};\n\n /**\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/onconnectionstatechange}\n */\n public onconnectionstatechange: RTCPeerConnection[\"onconnectionstatechange\"] =\n () => {};\n\n /**\n * Callback invoked when a new media track is added to the connection.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/ontrack}\n */\n public ontrack: RTCPeerConnection[\"ontrack\"] = () => {};\n\n /**\n * Adds a media track to the connection.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack}\n * @returns {RTCRtpSender} the newly created track\n */\n addTrack(...args: Parameters<RTCPeerConnection[\"addTrack\"]>): RTCRtpSender {\n return this.pc.addTrack(...args);\n }\n\n /**\n * Removes a media track from the connection.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/removeTrack}\n * @returns {void}\n */\n removeTrack(...args: Parameters<RTCPeerConnection[\"removeTrack\"]>): void {\n return this.pc.removeTrack(...args);\n }\n\n /**\n * Creates a data channel (useful for sending arbitrary data) through the connection.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createDataChannel}\n */\n createDataChannel(\n ...args: Parameters<RTCPeerConnection[\"createDataChannel\"]>\n ): RTCDataChannel {\n return this.pc.createDataChannel(...args);\n }\n\n /**\n * Returns the current connection state of the underlying RTCPeerConnection\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState}\n * @returns {RTCPeerConnectionState}\n */\n get connectionState(): RTCPeerConnectionState {\n return this.pc.connectionState;\n }\n\n /**\n * If reason is available, returns the reason for the session being closed.\n * @returns {string | undefined}\n */\n get closeReason(): string | undefined {\n return this._closeReason;\n }\n\n /**\n * Retrieves the identifier of the other peer.\n * @returns {string}\n */\n get other(): PeerInfo {\n return {\n groupId: this.stream.other.groupId,\n peerId: this.stream.other.peerId,\n connId: this.stream.other.connId,\n };\n }\n\n /**\n * Closes the session, aborts pending tasks, and cleans up resources.\n * Publishes events and logs.\n * @param {string} [reason] - (optional) Your reason for closing the session.\n * @returns {void}\n * @example mysession.close(\"Normal closure\");\n */\n close(reason?: string): void {\n if (this.abort.signal.aborted) return;\n this.abort.abort(reason);\n for (const timer of this.timers) {\n clearTimeout(timer);\n }\n this.timers = [];\n this.stream.close();\n this._closeReason = reason;\n this.pc.close();\n\n // RTCPeerConnection will not emit closed connection. This is a polyfill to get around it.\n // https://stackoverflow.com/questions/66297347/why-does-calling-rtcpeerconnection-close-not-send-closed-event\n const closeEvent = new Event(\"connectionstatechange\");\n this.setConnectionState(\"closed\", closeEvent);\n\n this.logger.debug(\"session closed\", {\n connectionState: this.connectionState,\n });\n }\n\n /**\n * Creates a Session with the provided stream and\n * configs. Sets up event handlers, signaling, and ICE candidate\n * management.\n * See {@link Session} For class responsibilities\n * @param stream Represents the transport stream for signaling messages.\n * @param config Configuration object for the RTCPeerConnection.\n */\n constructor(\n private readonly stream: Stream,\n config: RTCConfiguration,\n ) {\n this.pc = new RTCPeerConnection(config);\n\n this.makingOffer = false;\n this.pendingCandidates = [];\n // Higher is impolite. [0-15] is reserved. One of the reserved value can be used\n // for implementing fixed \"polite\" role for lite ICE.\n if (this.stream.info.connId === this.stream.other.connId) {\n this.impolite = this.stream.info.peerId > this.stream.other.peerId;\n } else {\n this.impolite = this.stream.info.connId > this.stream.other.connId;\n }\n this.abort = new AbortController();\n this.logger = stream.logger.sub(\"session\", {\n role: this.impolite ? \"impolite\" : \"polite\",\n });\n this.generationCounter = 0;\n this.iceRestartCount = 0;\n this.lastIceRestart = 0;\n this.timers = [];\n this._connectionState = \"new\";\n stream.onpayload = (msg) => this.handleMessage(msg);\n stream.onclosed = (reason) => this.close(reason);\n\n this.pc.oniceconnectionstatechange = async () => {\n const stats = await this.pc.getStats();\n const pair: unknown[] = [];\n const local: unknown[] = [];\n const remote: unknown[] = [];\n // https://developer.mozilla.org/en-US/docs/Web/API/RTCStatsReport#the_statistic_types\n stats.forEach((report: RTCStats) => {\n if (report.type === \"candidate-pair\") {\n pair.push(report);\n } else if (report.type === \"local-candidate\") {\n local.push(report);\n } else if (report.type === \"remote-candidate\") {\n remote.push(report);\n }\n });\n\n this.logger.debug(\"iceconnectionstate changed\", {\n \"connectionstate\": this.pc.connectionState,\n \"iceconnectionstate\": this.pc.iceConnectionState,\n local,\n remote,\n pair,\n pending: this.pendingCandidates,\n });\n };\n\n let start = performance.now();\n this.pc.onconnectionstatechange = (ev) => {\n this.logger.debug(\"connectionstate changed\", {\n \"connectionstate\": this.pc.connectionState,\n \"iceconnectionstate\": this.pc.iceConnectionState,\n });\n this.setConnectionState(this.pc.connectionState, ev);\n switch (this.pc.connectionState) {\n case \"connecting\":\n start = performance.now();\n break;\n case \"connected\": {\n const elapsed = performance.now() - start;\n this.logger.debug(`it took ${elapsed}ms to connect`);\n this.iceRestartCount = 0;\n break;\n }\n case \"disconnected\":\n this.triggerIceRestart();\n break;\n case \"failed\":\n this.close(\"detected sustained network failure\");\n break;\n case \"closed\":\n break;\n }\n };\n let firstOffer = true;\n this.pc.onnegotiationneeded = async () => {\n if (firstOffer) {\n if (!this.impolite) {\n // the impolite always initiates with an offer\n this.stream.send({\n payloadType: {\n oneofKind: \"join\",\n join: {},\n },\n }, true);\n return;\n }\n firstOffer = false;\n }\n\n try {\n this.makingOffer = true;\n this.logger.debug(\"creating an offer\");\n await this.pc.setLocalDescription();\n if (!this.pc.localDescription) {\n throw new Error(\"expect localDescription to be not empty\");\n }\n\n this.sendSignal({\n data: {\n oneofKind: \"sdp\",\n sdp: {\n kind: fromSDPType(this.pc.localDescription.type),\n sdp: this.pc.localDescription.sdp,\n },\n },\n });\n } catch (err) {\n if (err instanceof Error) {\n this.logger.error(\"failed in negotiating\", { err });\n }\n } finally {\n this.makingOffer = false;\n }\n };\n\n this.pc.onicecandidate = ({ candidate }) => {\n this.logger.debug(\"onicecandidate\", { candidate });\n const ice: ICECandidate = {\n candidate: \"\",\n sdpMLineIndex: 0,\n sdpMid: \"\",\n };\n if (!candidate || candidate.candidate === \"\") {\n this.logger.debug(\"ice gathering is finished\");\n return;\n }\n\n ice.candidate = candidate.candidate;\n ice.sdpMLineIndex = candidate.sdpMLineIndex ?? undefined;\n ice.sdpMid = candidate.sdpMid ?? undefined;\n ice.username = candidate.usernameFragment ?? undefined;\n\n this.sendSignal({\n data: {\n oneofKind: \"iceCandidate\",\n iceCandidate: ice,\n },\n });\n };\n\n this.pc.ondatachannel = (...args) => {\n if (this.ondatachannel) {\n // @ts-ignore: proxy to RTCPeerConnection\n this.ondatachannel(...args);\n }\n };\n\n this.pc.ontrack = (...args) => {\n if (this.ontrack) {\n // @ts-ignore: proxy to RTCPeerConnection\n this.ontrack(...args);\n }\n };\n }\n\n /** internal @private */\n private setConnectionState(s: RTCPeerConnectionState, ev: Event): void {\n if (s === this._connectionState) return;\n\n if (this.onconnectionstatechange) {\n // @ts-ignore: proxy to RTCPeerConnection\n this.onconnectionstatechange(ev);\n }\n }\n\n private triggerIceRestart = () => {\n // the impolite offer will trigger the polite peer's to also restart Ice\n if (!this.impolite) return;\n\n const elapsed = performance.now() - this.lastIceRestart;\n if (elapsed < ICE_RESTART_DEBOUNCE_DELAY_MS) {\n // schedule ice restart after some delay;\n const delay = ICE_RESTART_DEBOUNCE_DELAY_MS - elapsed;\n const timerId = window.setTimeout(() => {\n this.triggerIceRestart();\n this.timers = this.timers.filter((v) => v === timerId);\n }, delay);\n return;\n }\n\n if (this.pc.connectionState === \"connected\") return;\n if (this.iceRestartCount >= ICE_RESTART_MAX_COUNT) this.close();\n this.logger.debug(\"triggered ICE restart\");\n this.pc.restartIce();\n this.generationCounter++;\n this.iceRestartCount++;\n this.lastIceRestart = performance.now();\n };\n\n private sendSignal = (signal: Omit<Signal, \"generationCounter\">) => {\n this.stream.send({\n payloadType: {\n oneofKind: \"signal\",\n signal: { ...signal, generationCounter: this.generationCounter },\n },\n }, true);\n };\n\n private handleMessage = async (payload: MessagePayload) => {\n if (this.abort.signal.aborted) {\n this.logger.warn(\"session is closed, ignoring message\");\n return;\n }\n switch (payload.payloadType.oneofKind) {\n case \"signal\":\n await this.handleSignal(payload.payloadType.signal);\n break;\n case \"bye\":\n this.close();\n break;\n case \"join\":\n // nothing to do here. SDK consumer needs to manually trigger the start\n break;\n }\n };\n\n private handleSignal = async (signal: Signal) => {\n if (signal.generationCounter < this.generationCounter) {\n this.logger.warn(\"detected staled generationCounter signals, ignoring\");\n return;\n }\n\n const msg = signal.data;\n if (signal.generationCounter > this.generationCounter) {\n // Sync generationCounter so this peer can reset its state machine\n // to start accepting new offers\n this.logger.debug(\"detected new generationCounter\", {\n otherGenerationCounter: signal.generationCounter,\n generationCounter: this.generationCounter,\n msg,\n });\n\n if (msg.oneofKind === \"iceCandidate\") {\n const ice = toIceCandidate(msg.iceCandidate);\n this.pendingCandidates.push(ice);\n this.logger.warn(\n \"expecting an offer but got ice candidates during an ICE restart, adding to pending.\",\n { ice, msg },\n );\n return;\n }\n\n this.generationCounter = signal.generationCounter;\n }\n\n if (msg.oneofKind === \"iceCandidate\") {\n const ice = toIceCandidate(msg.iceCandidate);\n this.pendingCandidates.push(ice);\n this.checkPendingCandidates();\n\n return;\n }\n\n if (msg.oneofKind != \"sdp\") {\n return;\n }\n\n const sdp = msg.sdp;\n this.logger.debug(\"received a SDP signal\", { sdpKind: sdp.kind });\n const offerCollision = sdp.kind === SdpKind.OFFER &&\n (this.makingOffer || this.pc.signalingState !== \"stable\");\n\n const ignoreOffer = this.impolite && offerCollision;\n if (ignoreOffer) {\n this.logger.debug(\"ignored offer\");\n return;\n }\n\n this.logger.debug(\"creating an answer\");\n await this.pc.setRemoteDescription({\n type: toSDPType(sdp.kind),\n sdp: sdp.sdp,\n });\n if (sdp.kind === SdpKind.OFFER) {\n await this.pc.setLocalDescription();\n if (!this.pc.localDescription) {\n this.logger.error(\"unexpected null local description\");\n return;\n }\n\n // when a signal is retried many times and still failing. The failing heartbeat will kick in and close.\n this.sendSignal({\n data: {\n oneofKind: \"sdp\",\n sdp: {\n kind: fromSDPType(this.pc.localDescription.type),\n sdp: this.pc.localDescription.sdp,\n },\n },\n });\n }\n\n this.checkPendingCandidates();\n return;\n };\n\n private checkPendingCandidates = () => {\n const safeStates: RTCSignalingState[] = [\n \"stable\",\n \"have-local-offer\",\n \"have-remote-offer\",\n ];\n if (\n !safeStates.includes(this.pc.signalingState) || !this.pc.remoteDescription\n ) {\n this.logger.debug(\"wait for adding pending candidates\", {\n signalingState: this.pc.signalingState,\n iceConnectionState: this.pc.iceConnectionState,\n connectionState: this.pc.connectionState,\n remoteDescription: this.pc.remoteDescription,\n pendingCandidates: this.pendingCandidates.length,\n });\n return;\n }\n\n for (const candidate of this.pendingCandidates) {\n if (!candidate.candidate || candidate.candidate === \"\") {\n continue;\n }\n\n // intentionally not awaiting, otherwise we might be in a different state than we originally\n // checked.\n this.pc.addIceCandidate(candidate).catch((e) => {\n this.logger.warn(\"failed to add candidate, skipping.\", {\n candidate,\n e,\n });\n });\n this.logger.debug(`added ice: ${candidate.candidate}`);\n }\n this.pendingCandidates = [];\n };\n}\n","import { type ITunnelClient, TunnelClient } from \"./tunnel.client.ts\";\nimport { Transport } from \"./transport.ts\";\nimport type { PeerInfo } from \"./tunnel.ts\";\nimport { DEFAULT_LOG_SINK, Logger, PRETTY_LOG_SINK } from \"./logger.ts\";\nimport { Session } from \"./session.ts\";\nimport { RpcError, RpcOptions, UnaryCall } from \"@protobuf-ts/runtime-rpc\";\nimport {\n TwirpErrorCode,\n TwirpFetchTransport,\n} from \"@protobuf-ts/twirp-transport\";\nimport { retry } from \"./util.ts\";\nimport { jwtDecode } from \"jwt-decode\";\n\nexport type { PeerInfo } from \"./tunnel.ts\";\n\n/**\n * Streamline real-time application development.`@pulsebeam/peer` abstracts\n * networking, connection management, and signaling for applications. Built on\n * WebRTC. PulseBeam handles peer-to-peer communication, media/data transmission,\n * and provides infrastructure.\n *\n * A JavaScript SDK for creating real-time applications with WebRTC.\n *\n * # Features\n * - Flexible connection modes: peer-to-peer or server-relayed.\n * - Support for media (audio/video) and data channels.\n * - Abstracted signaling for establishing WebRTC connections.\n * - Auto-reconnect during disruptions or dropped connections.\n *\n * For more on PulseBeam, see our docs and quickstart guide:\n * {@link https://pulsebeam.dev/docs/getting-started/}\n *\n * For more on WebRTC, see the official documentation:\n * {@link https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API}\n *\n * # Example Usage\n *\n * Request an authentication token, initialize a peer instance, and establish a connection:\n *\n * ```ts\n * import { Peer, createPeer } from \"@pulsebeam/peer\";\n *\n * // Step 1: Obtain an auth token\n * const authResponse = await fetch(\"/auth\");\n * const { groupId, peerId, token } = await authResponse.json();\n *\n * // Step 2: Create a Peer instance\n * const peer = await createPeer({ groupId, peerId, token });\n *\n * peer.onsession = (session) => {\n * session.ontrack = ({ streams }) => console.log(\"New media stream:\", streams);\n * session.ondatachannel = (event) => console.log(\"Data channel:\", event.channel);\n * session.onconnectionstatechange = () => console.log(\"Connection state changed\");\n * };\n *\n * // Step 3: Connect to another peer\n * peer.start();\n *\n * const abortController = new AbortController();\n * await peer.connect(groupId, \"other-peer-id\", abortController.signal);\n * ```\n *\n * This module provides a framework for building WebRTC applications while\n * leaving room for custom implementation details.\n *\n * @module\n */\n\nconst BASE_URL = \"https://cloud.pulsebeam.dev/twirp\";\nconst PREPARE_INITIAL_DELAY_MS = 50;\nconst PREPARE_MAX_RETRY = 3;\n\n/**\n * A high-level API for managing the peer-to-peer WebRTC connection. Provides\n * access to lower-level {@link RTCPeerConnection} functionality. Including\n * access to underlying media tracks, data channels, and connection state.\n *\n * Usage:\n * @example `peer.onsession = (session) => {console.log(session.otherPeerId())};`\n */\nexport interface ISession {\n /**\n * Adds a media track to the connection. Typically used for sending audio or video.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack}\n * @returns {RTCRtpSender}\n */\n addTrack(...args: Parameters<RTCPeerConnection[\"addTrack\"]>): RTCRtpSender;\n\n /**\n * Removes a media track from the connection. Useful for stopping\n * transmission of a specific track.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/removeTrack}\n * @returns {void}\n */\n removeTrack(...args: Parameters<RTCPeerConnection[\"removeTrack\"]>): void;\n\n /**\n * Creates a {@link RTCDataChannel} on the connection for arbitrary data transfer.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/createDataChannel}\n */\n createDataChannel(\n ...args: Parameters<RTCPeerConnection[\"createDataChannel\"]>\n ): RTCDataChannel;\n\n /**\n * Retrieves the current connection state of the underlying RTCPeerConnection\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/connectionState}\n * @returns {RTCPeerConnectionState}\n */\n get connectionState(): RTCPeerConnectionState;\n\n /**\n * Callback triggered when a {@link RTCDataChannel} is created or received.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/ondatachannel}\n * @example ```peer.onsession = (session) => {\n * session.ondatachannel = (event) => {\n * const channel = event.channel;\n * channel.onmessage = (e) => console.log(\"Received message:\", e.data);\n * };```\n */\n ondatachannel: RTCPeerConnection[\"ondatachannel\"];\n\n /**\n * Callback triggered when the connection state changes.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/onconnectionstatechange}\n */\n onconnectionstatechange: RTCPeerConnection[\"onconnectionstatechange\"];\n\n /**\n * Callback invoked when a new media track is added to the connection.\n * See {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/ontrack}\n */\n ontrack: RTCPeerConnection[\"ontrack\"];\n\n /**\n * Closes the session, aborting all pending tasks, and cleaning up resources.\n * Publishes events and logs about the closure.\n * @param {string} [reason] - (optional) A reason for closing the session.\n * @returns {void}\n * @example `mysession.close(\"Session ended by user\");`\n */\n close(reason?: string): void;\n\n // Below is PulseBeam specific functionality. Unrelated to\n // the underlying RTCPeerConnection\n\n /**\n * Retrieves the identifier of the other peer in the connection.\n * @returns {PeerInfo} The peer identity of the connected peer. Valid UTF-8 string of 1-16 characters.\n * @example ```console.log(`Connected to peer: ${session.other.peerId()}`);```\n */\n get other(): PeerInfo;\n}\n\n/**\n * Intended to be used by for internal and advanced usecases.\n * Options used to configure a Peer.\n * @interface PeerOptionsFull\n * @example```\n * const options: PeerOptionsFull = {\n * groupId: \"group-123\", // Valid UTF-8 strings of 1-16 characters.\n * peerId: \"peer-456\", // Valid UTF-8 strings of 1-16 characters.\n * token: \"eyJhbGc...49nLmBCg\"\n * };```\n */\nexport interface PeerOptionsFull {\n /**\n * Identifier for the group which the peer belongs to. Must be a valid UTF-8\n * string of 1-16 characters.\n * @type {string} groupId\n */\n groupId: string;\n\n /**\n * Identifier for the peer. Must be a valid UTF-8 string of 1-16 characters.\n * @type {string} peerId\n */\n peerId: string;\n\n /**\n * PulseBeam authentication token for the peer. JWT token generated by `jsr:@pulsebeam/server`\n * @type {string} token\n */\n token: string;\n\n /**\n * (Optional) Base URL for API calls. Defaults to using our servers: \"https://cloud.pulsebeam.dev/twirp\".\n * @type {string | undefined} [baseUrl]\n */\n baseUrl?: string;\n\n /**\n * (Optional) If true, enforces relay-only connections, such as those passed through a TURN server. Defaults to allowing all connection types (such as direct peer to peer). For more details see {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection#icetransportpolicy}\n * @type {boolean | undefined} [forceRelay]\n */\n forceRelay?: boolean;\n\n /**\n * (Optional) Add Ice Servers. Defaults to using our servers. For more details see {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection#iceservers}\n * @type {RTCIceServer[] | undefined} [iceServers]\n */\n iceServers?: RTCIceServer[];\n}\n\n/**\n * Options used to configure a Peer. See {@link PeerOptionsFull} for properties.\n * @interface PeerOptions\n * @example```\n * const options: PeerOptions = {\n * token: \"eyJhbGc...49nLmBCg\" // fetch token\n * };```\n */\nexport type PeerOptions = Omit<PeerOptionsFull, \"groupId\" | \"peerId\">;\n\n/**\n * Represents the possible states for a Peer.\n *\n * @readonly\n * @enum {string}\n * Possible values:\n * - `\"new\"`: The peer has been created.\n * - `\"closed\"`: The peer has been closed.\n */\nexport type PeerState = \"new\" | \"closed\";\n\n/**\n * Peer is a mediator for signaling, connecting, and managing sessions.\n */\nexport class Peer {\n private transport: Transport;\n private readonly logger: Logger;\n private sessions: Session[];\n private _state: PeerState;\n\n /**\n * Callback invoked when a new session is established.\n * @param _s Session object\n */\n public onsession = (_s: ISession) => {};\n /**\n * Callback invoked when the peer’s state changes.\n */\n public onstatechange = () => {};\n /**\n * Identifier for the peer. Valid UTF-8 string of 1-16 characters.\n */\n public readonly peerId: string;\n\n /**\n * Construct a Peer. Helper available: see {@link createPeer} function\n * @param logger Logger instance for logging events.\n * @param client Tunnel client for signaling.\n * @param opts Configuration options for the peer.\n * @param isRecoverable Function to determine if an error is recoverable.\n */\n constructor(\n logger: Logger,\n client: ITunnelClient,\n opts: PeerOptionsFull,\n isRecoverable: (_err: unknown) => boolean,\n ) {\n this.peerId = opts.peerId;\n this.logger = logger.sub(\"peer\", { peerId: this.peerId });\n this.sessions = [];\n this._state = \"new\";\n\n const rtcConfig: RTCConfiguration = {\n bundlePolicy: \"balanced\",\n iceTransportPolicy: !!opts.forceRelay ? \"relay\" : \"all\",\n iceCandidatePoolSize: 0,\n iceServers: opts.iceServers,\n };\n this.transport = new Transport(client, {\n enableDiscovery: false,\n groupId: opts.groupId,\n peerId: opts.peerId,\n logger: this.logger,\n isRecoverable,\n });\n this.transport.onstream = (s) => {\n const sess = new Session(s, rtcConfig);\n this.sessions.push(sess);\n this.onsession(sess);\n };\n this.transport.onclosed = () => {\n this.close();\n };\n }\n\n /**\n * Starts the peer, making it ready to establish connections.\n * Peers must be started before a connection can occur.\n *\n * @returns {void}\n * @throws {Error} When the peer was previously closed.\n */\n start() {\n if (this._state === \"closed\") throw new Error(\"peer is already closed\");\n this.transport.listen();\n }\n\n /**\n * Closes the peer. Releases associated resources.\n * Signals to the AbortController passed to connect if connect was called.\n *\n * @async\n * @returns {Promise<void>} Resolves when the peer has been closed.\n */\n async close() {\n this.sessions = [];\n await this.transport.close();\n this.setState(\"closed\");\n }\n\n /**\n * Establishes a connection with another peer in the specified group.\n * Peer should be started before calling connect.\n *\n * Check the log output for troubleshooting information.\n *\n * @async\n * @param {string} otherGroupId The ID of the group the other peer belongs to.\n * Valid UTF-8 string of 1-16 characters.\n * @param {string} otherPeerId The ID of the peer you want to connect to.\n * Valid UTF-8 string of 1-16 characters.\n * @param {AbortSignal} signal Handle cancellations or cancel the connection attempt.\n * @returns {Promise<void>} Resolves when the connection has been established,\n * an unrecoverable error (e.g., network connection issues, internal errors) occurs,\n * or the maximum retry attempts are reached.\n */\n connect(\n otherGroupId: string,\n otherPeerId: string,\n signal: AbortSignal,\n ): Promise<void> {\n return this.transport.connect(otherGroupId, otherPeerId, signal);\n }\n\n /**\n * Gets the current state of the peer. For state info see {@link PeerState}\n * @returns {PeerState} The current state of the peer\n */\n get state(): PeerState {\n return this._state;\n }\n\n /** internal @private */\n private setState(s: PeerState): void {\n if (s === this._state) return;\n\n this._state = s;\n this.onstatechange();\n }\n}\n\nconst TWIRP_FATAL_ERRORS: string[] = [\n TwirpErrorCode[TwirpErrorCode.permission_denied],\n TwirpErrorCode[TwirpErrorCode.invalid_argument],\n TwirpErrorCode[TwirpErrorCode.aborted],\n TwirpErrorCode[TwirpErrorCode.bad_route],\n TwirpErrorCode[TwirpErrorCode.malformed],\n TwirpErrorCode[TwirpErrorCode.not_found],\n TwirpErrorCode[TwirpErrorCode.unauthenticated],\n];\n\nfunction isTwirpRecoverable(err: unknown): boolean {\n if (!(err instanceof Error)) {\n return false;\n }\n\n if (!(err instanceof RpcError)) {\n return true;\n }\n\n return !TWIRP_FATAL_ERRORS.includes(err.code);\n}\n\ninterface JwtClaims {\n gid: string;\n pid: string;\n}\n\n/**\n * Helper to create a new Peer instance\n * @param opts Configuration options for the peer.\n * @returns {Promise<Peer>} Resolves to the newly created Peer\n * @throws {Error} When unable to connect to signaling server. Likely networking issue.\n */\nexport async function createPeer(opts: PeerOptions): Promise<Peer> {\n // TODO: add hook for refresh token\n const token = opts.token;\n const twirp = new TwirpFetchTransport({\n baseUrl: opts.baseUrl || BASE_URL,\n sendJson: false,\n jsonOptions: {\n emitDefaultValues: true, // treat zero values as values instead of undefined.\n enumAsInteger: true,\n ignoreUnknownFields: true,\n },\n interceptors: [\n {\n // adds auth header to unary requests\n interceptUnary(next, method, input, options: RpcOptions): UnaryCall {\n if (!options.meta) {\n options.meta = {};\n }\n options.meta[\"Authorization\"] = `Bearer ${token}`;\n return next(method, input, options);\n },\n },\n ],\n });\n const client = new TunnelClient(twirp);\n\n const resp = await retry(\n async () => await client.prepare({}),\n {\n baseDelay: 50,\n maxDelay: 1000,\n maxRetries: 5,\n isRecoverable: isTwirpRecoverable,\n },\n );\n if (resp === null) {\n throw new Error(\"createPeer aborted\");\n }\n const iceServers = [...(opts.iceServers || [])];\n for (const s of resp.response.iceServers) {\n iceServers.push({\n urls: s.urls,\n username: s.username,\n credential: s.credential,\n });\n }\n const decoded = jwtDecode<JwtClaims>(token);\n const optsFull: PeerOptionsFull = {\n ...opts,\n \"iceServers\": iceServers,\n groupId: decoded.gid,\n peerId: decoded.pid,\n };\n const peer = new Peer(\n new Logger(\"pulsebeam\", undefined, PRETTY_LOG_SINK),\n client,\n optsFull,\n isTwirpRecoverable,\n );\n return peer;\n}\n"],"mappings":"ooBAAA,IAAAA,GAAAC,GAAA,CAAAC,GAAAC,KAAA,cAIA,IAAMC,EAAW,CAAC,EAIlBA,EAAS,mBAAqB,UAAW,CACvC,OAAO,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,EAAG,EAAE,CACnD,EAGAA,EAAS,WAAaA,EAAS,mBAAmB,EAGlDA,EAAS,WAAa,SAASC,EAAM,CACnC,OAAOA,EAAK,KAAK,EAAE,MAAM;AAAA,CAAI,EAAE,IAAIC,GAAQA,EAAK,KAAK,CAAC,CACxD,EAEAF,EAAS,cAAgB,SAASC,EAAM,CAEtC,OADcA,EAAK,MAAM;AAAA,GAAM,EAClB,IAAI,CAACE,EAAMC,KAAWA,EAAQ,EACzC,KAAOD,EAAOA,GAAM,KAAK,EAAI;AAAA,CAAM,CACvC,EAGAH,EAAS,eAAiB,SAASC,EAAM,CACvC,IAAMI,EAAWL,EAAS,cAAcC,CAAI,EAC5C,OAAOI,GAAYA,EAAS,CAAC,CAC/B,EAGAL,EAAS,iBAAmB,SAASC,EAAM,CACzC,IAAMI,EAAWL,EAAS,cAAcC,CAAI,EAC5C,OAAAI,EAAS,MAAM,EACRA,CACT,EAGAL,EAAS,YAAc,SAASC,EAAMK,EAAQ,CAC5C,OAAON,EAAS,WAAWC,CAAI,EAAE,OAAOC,GAAQA,EAAK,QAAQI,CAAM,IAAM,CAAC,CAC5E,EAMAN,EAAS,eAAiB,SAASE,EAAM,CACvC,IAAIK,EAEAL,EAAK,QAAQ,cAAc,IAAM,EACnCK,EAAQL,EAAK,UAAU,EAAE,EAAE,MAAM,GAAG,EAEpCK,EAAQL,EAAK,UAAU,EAAE,EAAE,MAAM,GAAG,EAGtC,IAAMM,EAAY,CAChB,WAAYD,EAAM,CAAC,EACnB,UAAW,CAAC,EAAG,MAAO,EAAG,MAAM,EAAEA,EAAM,CAAC,CAAC,GAAKA,EAAM,CAAC,EACrD,SAAUA,EAAM,CAAC,EAAE,YAAY,EAC/B,SAAU,SAASA,EAAM,CAAC,EAAG,EAAE,EAC/B,GAAIA,EAAM,CAAC,EACX,QAASA,EAAM,CAAC,EAChB,KAAM,SAASA,EAAM,CAAC,EAAG,EAAE,EAE3B,KAAMA,EAAM,CAAC,CACf,EAEA,QAASE,EAAI,EAAGA,EAAIF,EAAM,OAAQE,GAAK,EACrC,OAAQF,EAAME,CAAC,EAAG,CAChB,IAAK,QACHD,EAAU,eAAiBD,EAAME,EAAI,CAAC,EACtC,MACF,IAAK,QACHD,EAAU,YAAc,SAASD,EAAME,EAAI,CAAC,EAAG,EAAE,EACjD,MACF,IAAK,UACHD,EAAU,QAAUD,EAAME,EAAI,CAAC,EAC/B,MACF,IAAK,QACHD,EAAU,MAAQD,EAAME,EAAI,CAAC,EAC7BD,EAAU,iBAAmBD,EAAME,EAAI,CAAC,EACxC,MACF,QACMD,EAAUD,EAAME,CAAC,CAAC,IAAM,SAC1BD,EAAUD,EAAME,CAAC,CAAC,EAAIF,EAAME,EAAI,CAAC,GAEnC,KACJ,CAEF,OAAOD,CACT,EAIAR,EAAS,eAAiB,SAASQ,EAAW,CAC5C,IAAME,EAAM,CAAC,EACbA,EAAI,KAAKF,EAAU,UAAU,EAE7B,IAAMG,EAAYH,EAAU,UACxBG,IAAc,MAChBD,EAAI,KAAK,CAAC,EACDC,IAAc,OACvBD,EAAI,KAAK,CAAC,EAEVA,EAAI,KAAKC,CAAS,EAEpBD,EAAI,KAAKF,EAAU,SAAS,YAAY,CAAC,EACzCE,EAAI,KAAKF,EAAU,QAAQ,EAC3BE,EAAI,KAAKF,EAAU,SAAWA,EAAU,EAAE,EAC1CE,EAAI,KAAKF,EAAU,IAAI,EAEvB,IAAMI,EAAOJ,EAAU,KACvB,OAAAE,EAAI,KAAK,KAAK,EACdA,EAAI,KAAKE,CAAI,EACTA,IAAS,QAAUJ,EAAU,gBAC7BA,EAAU,cACZE,EAAI,KAAK,OAAO,EAChBA,EAAI,KAAKF,EAAU,cAAc,EACjCE,EAAI,KAAK,OAAO,EAChBA,EAAI,KAAKF,EAAU,WAAW,GAE5BA,EAAU,SAAWA,EAAU,SAAS,YAAY,IAAM,QAC5DE,EAAI,KAAK,SAAS,EAClBA,EAAI,KAAKF,EAAU,OAAO,IAExBA,EAAU,kBAAoBA,EAAU,SAC1CE,EAAI,KAAK,OAAO,EAChBA,EAAI,KAAKF,EAAU,kBAAoBA,EAAU,KAAK,GAEjD,aAAeE,EAAI,KAAK,GAAG,CACpC,EAKAV,EAAS,gBAAkB,SAASE,EAAM,CACxC,OAAOA,EAAK,UAAU,EAAE,EAAE,MAAM,GAAG,CACrC,EAIAF,EAAS,YAAc,SAASE,EAAM,CACpC,IAAIK,EAAQL,EAAK,UAAU,CAAC,EAAE,MAAM,GAAG,EACjCW,EAAS,CACb,YAAa,SAASN,EAAM,MAAM,EAAG,EAAE,CACzC,EAEA,OAAAA,EAAQA,EAAM,CAAC,EAAE,MAAM,GAAG,EAE1BM,EAAO,KAAON,EAAM,CAAC,EACrBM,EAAO,UAAY,SAASN,EAAM,CAAC,EAAG,EAAE,EACxCM,EAAO,SAAWN,EAAM,SAAW,EAAI,SAASA,EAAM,CAAC,EAAG,EAAE,EAAI,EAEhEM,EAAO,YAAcA,EAAO,SACrBA,CACT,EAIAb,EAAS,YAAc,SAASc,EAAO,CACrC,IAAIC,EAAKD,EAAM,YACXA,EAAM,uBAAyB,SACjCC,EAAKD,EAAM,sBAEb,IAAME,EAAWF,EAAM,UAAYA,EAAM,aAAe,EACxD,MAAO,YAAcC,EAAK,IAAMD,EAAM,KAAO,IAAMA,EAAM,WACpDE,IAAa,EAAI,IAAMA,EAAW,IAAM;AAAA,CAC/C,EAKAhB,EAAS,YAAc,SAASE,EAAM,CACpC,IAAMK,EAAQL,EAAK,UAAU,CAAC,EAAE,MAAM,GAAG,EACzC,MAAO,CACL,GAAI,SAASK,EAAM,CAAC,EAAG,EAAE,EACzB,UAAWA,EAAM,CAAC,EAAE,QAAQ,GAAG,EAAI,EAAIA,EAAM,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,EAAI,WAChE,IAAKA,EAAM,CAAC,EACZ,WAAYA,EAAM,MAAM,CAAC,EAAE,KAAK,GAAG,CACrC,CACF,EAIAP,EAAS,YAAc,SAASiB,EAAiB,CAC/C,MAAO,aAAeA,EAAgB,IAAMA,EAAgB,cACvDA,EAAgB,WAAaA,EAAgB,YAAc,WACxD,IAAMA,EAAgB,UACtB,IACJ,IAAMA,EAAgB,KACrBA,EAAgB,WAAa,IAAMA,EAAgB,WAAa,IACjE;AAAA,CACN,EAKAjB,EAAS,UAAY,SAASE,EAAM,CAClC,IAAMW,EAAS,CAAC,EACZK,EACEX,EAAQL,EAAK,UAAUA,EAAK,QAAQ,GAAG,EAAI,CAAC,EAAE,MAAM,GAAG,EAC7D,QAASiB,EAAI,EAAGA,EAAIZ,EAAM,OAAQY,IAChCD,EAAKX,EAAMY,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,EAC9BN,EAAOK,EAAG,CAAC,EAAE,KAAK,CAAC,EAAIA,EAAG,CAAC,EAE7B,OAAOL,CACT,EAGAb,EAAS,UAAY,SAASc,EAAO,CACnC,IAAIZ,EAAO,GACPa,EAAKD,EAAM,YAIf,GAHIA,EAAM,uBAAyB,SACjCC,EAAKD,EAAM,sBAETA,EAAM,YAAc,OAAO,KAAKA,EAAM,UAAU,EAAE,OAAQ,CAC5D,IAAMM,EAAS,CAAC,EAChB,OAAO,KAAKN,EAAM,UAAU,EAAE,QAAQO,GAAS,CACzCP,EAAM,WAAWO,CAAK,IAAM,OAC9BD,EAAO,KAAKC,EAAQ,IAAMP,EAAM,WAAWO,CAAK,CAAC,EAEjDD,EAAO,KAAKC,CAAK,CAErB,CAAC,EACDnB,GAAQ,UAAYa,EAAK,IAAMK,EAAO,KAAK,GAAG,EAAI;AAAA,CACpD,CACA,OAAOlB,CACT,EAIAF,EAAS,YAAc,SAASE,EAAM,CACpC,IAAMK,EAAQL,EAAK,UAAUA,EAAK,QAAQ,GAAG,EAAI,CAAC,EAAE,MAAM,GAAG,EAC7D,MAAO,CACL,KAAMK,EAAM,MAAM,EAClB,UAAWA,EAAM,KAAK,GAAG,CAC3B,CACF,EAGAP,EAAS,YAAc,SAASc,EAAO,CACrC,IAAIQ,EAAQ,GACRP,EAAKD,EAAM,YACf,OAAIA,EAAM,uBAAyB,SACjCC,EAAKD,EAAM,sBAETA,EAAM,cAAgBA,EAAM,aAAa,QAE3CA,EAAM,aAAa,QAAQS,GAAM,CAC/BD,GAAS,aAAeP,EAAK,IAAMQ,EAAG,MACrCA,EAAG,WAAaA,EAAG,UAAU,OAAS,IAAMA,EAAG,UAAY,IACxD;AAAA,CACN,CAAC,EAEID,CACT,EAIAtB,EAAS,eAAiB,SAASE,EAAM,CACvC,IAAMsB,EAAKtB,EAAK,QAAQ,GAAG,EACrBK,EAAQ,CACZ,KAAM,SAASL,EAAK,UAAU,EAAGsB,CAAE,EAAG,EAAE,CAC1C,EACMC,EAAQvB,EAAK,QAAQ,IAAKsB,CAAE,EAClC,OAAIC,EAAQ,IACVlB,EAAM,UAAYL,EAAK,UAAUsB,EAAK,EAAGC,CAAK,EAC9ClB,EAAM,MAAQL,EAAK,UAAUuB,EAAQ,CAAC,GAEtClB,EAAM,UAAYL,EAAK,UAAUsB,EAAK,CAAC,EAElCjB,CACT,EAIAP,EAAS,eAAiB,SAASE,EAAM,CACvC,IAAMK,EAAQL,EAAK,UAAU,EAAE,EAAE,MAAM,GAAG,EAC1C,MAAO,CACL,UAAWK,EAAM,MAAM,EACvB,MAAOA,EAAM,IAAImB,GAAQ,SAASA,EAAM,EAAE,CAAC,CAC7C,CACF,EAIA1B,EAAS,OAAS,SAAS2B,EAAc,CACvC,IAAMC,EAAM5B,EAAS,YAAY2B,EAAc,QAAQ,EAAE,CAAC,EAC1D,GAAIC,EACF,OAAOA,EAAI,UAAU,CAAC,CAE1B,EAGA5B,EAAS,iBAAmB,SAASE,EAAM,CACzC,IAAMK,EAAQL,EAAK,UAAU,EAAE,EAAE,MAAM,GAAG,EAC1C,MAAO,CACL,UAAWK,EAAM,CAAC,EAAE,YAAY,EAChC,MAAOA,EAAM,CAAC,EAAE,YAAY,CAC9B,CACF,EAKAP,EAAS,kBAAoB,SAAS2B,EAAcE,EAAa,CAI/D,MAAO,CACL,KAAM,OACN,aALY7B,EAAS,YAAY2B,EAAeE,EAChD,gBAAgB,EAII,IAAI7B,EAAS,gBAAgB,CACnD,CACF,EAGAA,EAAS,oBAAsB,SAASoB,EAAQU,EAAW,CACzD,IAAIpB,EAAM,WAAaoB,EAAY;AAAA,EACnC,OAAAV,EAAO,aAAa,QAAQW,GAAM,CAChCrB,GAAO,iBAAmBqB,EAAG,UAAY,IAAMA,EAAG,MAAQ;AAAA,CAC5D,CAAC,EACMrB,CACT,EAIAV,EAAS,gBAAkB,SAASE,EAAM,CACxC,IAAMK,EAAQL,EAAK,UAAU,CAAC,EAAE,MAAM,GAAG,EACzC,MAAO,CACL,IAAK,SAASK,EAAM,CAAC,EAAG,EAAE,EAC1B,YAAaA,EAAM,CAAC,EACpB,UAAWA,EAAM,CAAC,EAClB,cAAeA,EAAM,MAAM,CAAC,CAC9B,CACF,EAEAP,EAAS,gBAAkB,SAASgC,EAAY,CAC9C,MAAO,YAAcA,EAAW,IAAM,IACpCA,EAAW,YAAc,KACxB,OAAOA,EAAW,WAAc,SAC7BhC,EAAS,qBAAqBgC,EAAW,SAAS,EAClDA,EAAW,YACdA,EAAW,cAAgB,IAAMA,EAAW,cAAc,KAAK,GAAG,EAAI,IACvE;AAAA,CACJ,EAIAhC,EAAS,qBAAuB,SAASiC,EAAW,CAClD,GAAIA,EAAU,QAAQ,SAAS,IAAM,EACnC,OAAO,KAET,IAAM1B,EAAQ0B,EAAU,UAAU,CAAC,EAAE,MAAM,GAAG,EAC9C,MAAO,CACL,UAAW,SACX,QAAS1B,EAAM,CAAC,EAChB,SAAUA,EAAM,CAAC,EACjB,SAAUA,EAAM,CAAC,EAAIA,EAAM,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,EAAI,OAC9C,UAAWA,EAAM,CAAC,EAAIA,EAAM,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,EAAI,MACjD,CACF,EAEAP,EAAS,qBAAuB,SAASiC,EAAW,CAClD,OAAOA,EAAU,UAAY,IACzBA,EAAU,SACXA,EAAU,SAAW,IAAMA,EAAU,SAAW,KAChDA,EAAU,UAAYA,EAAU,UAC7B,IAAMA,EAAU,SAAW,IAAMA,EAAU,UAC3C,GACR,EAGAjC,EAAS,oBAAsB,SAAS2B,EAAcE,EAAa,CAGjE,OAFc7B,EAAS,YAAY2B,EAAeE,EAChD,WAAW,EACA,IAAI7B,EAAS,eAAe,CAC3C,EAKAA,EAAS,iBAAmB,SAAS2B,EAAcE,EAAa,CAC9D,IAAMK,EAAQlC,EAAS,YAAY2B,EAAeE,EAChD,cAAc,EAAE,CAAC,EACbM,EAAMnC,EAAS,YAAY2B,EAAeE,EAC9C,YAAY,EAAE,CAAC,EACjB,OAAMK,GAASC,EAGR,CACL,iBAAkBD,EAAM,UAAU,EAAE,EACpC,SAAUC,EAAI,UAAU,EAAE,CAC5B,EALS,IAMX,EAGAnC,EAAS,mBAAqB,SAASoB,EAAQ,CAC7C,IAAIV,EAAM,eAAiBU,EAAO,iBAAmB;AAAA,YAClCA,EAAO,SAAW;AAAA,EACrC,OAAIA,EAAO,UACTV,GAAO;AAAA,GAEFA,CACT,EAGAV,EAAS,mBAAqB,SAAS2B,EAAc,CACnD,IAAMS,EAAc,CAClB,OAAQ,CAAC,EACT,iBAAkB,CAAC,EACnB,cAAe,CAAC,EAChB,KAAM,CAAC,CACT,EAEMC,EADQrC,EAAS,WAAW2B,CAAY,EAC1B,CAAC,EAAE,MAAM,GAAG,EAChCS,EAAY,QAAUC,EAAM,CAAC,EAC7B,QAAS,EAAI,EAAG,EAAIA,EAAM,OAAQ,IAAK,CACrC,IAAMtB,EAAKsB,EAAM,CAAC,EACZC,EAAatC,EAAS,YAC1B2B,EAAc,YAAcZ,EAAK,GAAG,EAAE,CAAC,EACzC,GAAIuB,EAAY,CACd,IAAMxB,EAAQd,EAAS,YAAYsC,CAAU,EACvCC,EAAQvC,EAAS,YACrB2B,EAAc,UAAYZ,EAAK,GAAG,EAQpC,OANAD,EAAM,WAAayB,EAAM,OAASvC,EAAS,UAAUuC,EAAM,CAAC,CAAC,EAAI,CAAC,EAClEzB,EAAM,aAAed,EAAS,YAC5B2B,EAAc,aAAeZ,EAAK,GAAG,EACpC,IAAIf,EAAS,WAAW,EAC3BoC,EAAY,OAAO,KAAKtB,CAAK,EAErBA,EAAM,KAAK,YAAY,EAAG,CAChC,IAAK,MACL,IAAK,SACHsB,EAAY,cAAc,KAAKtB,EAAM,KAAK,YAAY,CAAC,EACvD,MACF,QACE,KACJ,CACF,CACF,CACAd,EAAS,YAAY2B,EAAc,WAAW,EAAE,QAAQzB,GAAQ,CAC9DkC,EAAY,iBAAiB,KAAKpC,EAAS,YAAYE,CAAI,CAAC,CAC9D,CAAC,EACD,IAAMsC,EAAiBxC,EAAS,YAAY2B,EAAc,cAAc,EACrE,IAAI3B,EAAS,WAAW,EAC3B,OAAAoC,EAAY,OAAO,QAAQtB,GAAS,CAClC0B,EAAe,QAAQjB,GAAK,CACRT,EAAM,aAAa,KAAK2B,GACjCA,EAAiB,OAASlB,EAAG,MAClCkB,EAAiB,YAAclB,EAAG,SACrC,GAECT,EAAM,aAAa,KAAKS,CAAE,CAE9B,CAAC,CACH,CAAC,EAEMa,CACT,EAIApC,EAAS,oBAAsB,SAAS0C,EAAMC,EAAM,CAClD,IAAIjC,EAAM,GAGVA,GAAO,KAAOgC,EAAO,IACrBhC,GAAOiC,EAAK,OAAO,OAAS,EAAI,IAAM,IACtCjC,GAAO,KAAOiC,EAAK,SAAW,qBAAuB,IACrDjC,GAAOiC,EAAK,OAAO,IAAI7B,GACjBA,EAAM,uBAAyB,OAC1BA,EAAM,qBAERA,EAAM,WACd,EAAE,KAAK,GAAG,EAAI;AAAA,EAEfJ,GAAO;AAAA,EACPA,GAAO;AAAA,EAGPiC,EAAK,OAAO,QAAQ7B,GAAS,CAC3BJ,GAAOV,EAAS,YAAYc,CAAK,EACjCJ,GAAOV,EAAS,UAAUc,CAAK,EAC/BJ,GAAOV,EAAS,YAAYc,CAAK,CACnC,CAAC,EACD,IAAI8B,EAAW,EACf,OAAAD,EAAK,OAAO,QAAQ7B,GAAS,CACvBA,EAAM,SAAW8B,IACnBA,EAAW9B,EAAM,SAErB,CAAC,EACG8B,EAAW,IACblC,GAAO,cAAgBkC,EAAW;AAAA,GAGhCD,EAAK,kBACPA,EAAK,iBAAiB,QAAQE,GAAa,CACzCnC,GAAOV,EAAS,YAAY6C,CAAS,CACvC,CAAC,EAGInC,CACT,EAIAV,EAAS,2BAA6B,SAAS2B,EAAc,CAC3D,IAAMmB,EAAqB,CAAC,EACtBV,EAAcpC,EAAS,mBAAmB2B,CAAY,EACtDoB,EAASX,EAAY,cAAc,QAAQ,KAAK,IAAM,GACtDY,EAAYZ,EAAY,cAAc,QAAQ,QAAQ,IAAM,GAG5Da,EAAQjD,EAAS,YAAY2B,EAAc,SAAS,EACvD,IAAIzB,GAAQF,EAAS,eAAeE,CAAI,CAAC,EACzC,OAAOK,GAASA,EAAM,YAAc,OAAO,EACxC2C,EAAcD,EAAM,OAAS,GAAKA,EAAM,CAAC,EAAE,KAC7CE,EAEEC,EAAQpD,EAAS,YAAY2B,EAAc,kBAAkB,EAChE,IAAIzB,GACWA,EAAK,UAAU,EAAE,EAAE,MAAM,GAAG,EAC7B,IAAIC,GAAQ,SAASA,EAAM,EAAE,CAAC,CAC5C,EACCiD,EAAM,OAAS,GAAKA,EAAM,CAAC,EAAE,OAAS,GAAKA,EAAM,CAAC,EAAE,CAAC,IAAMF,IAC7DC,EAAgBC,EAAM,CAAC,EAAE,CAAC,GAG5BhB,EAAY,OAAO,QAAQtB,GAAS,CAClC,GAAIA,EAAM,KAAK,YAAY,IAAM,OAASA,EAAM,WAAW,IAAK,CAC9D,IAAIuC,EAAW,CACb,KAAMH,EACN,iBAAkB,SAASpC,EAAM,WAAW,IAAK,EAAE,CACrD,EACIoC,GAAeC,IACjBE,EAAS,IAAM,CAAC,KAAMF,CAAa,GAErCL,EAAmB,KAAKO,CAAQ,EAC5BN,IACFM,EAAW,KAAK,MAAM,KAAK,UAAUA,CAAQ,CAAC,EAC9CA,EAAS,IAAM,CACb,KAAMH,EACN,UAAWF,EAAY,aAAe,KACxC,EACAF,EAAmB,KAAKO,CAAQ,EAEpC,CACF,CAAC,EACGP,EAAmB,SAAW,GAAKI,GACrCJ,EAAmB,KAAK,CACtB,KAAMI,CACR,CAAC,EAIH,IAAII,EAAYtD,EAAS,YAAY2B,EAAc,IAAI,EACvD,OAAI2B,EAAU,SACRA,EAAU,CAAC,EAAE,QAAQ,SAAS,IAAM,EACtCA,EAAY,SAASA,EAAU,CAAC,EAAE,UAAU,CAAC,EAAG,EAAE,EACzCA,EAAU,CAAC,EAAE,QAAQ,OAAO,IAAM,EAE3CA,EAAY,SAASA,EAAU,CAAC,EAAE,UAAU,CAAC,EAAG,EAAE,EAAI,IAAO,IACtD,GAAK,GAAK,EAEjBA,EAAY,OAEdR,EAAmB,QAAQ1B,GAAU,CACnCA,EAAO,WAAakC,CACtB,CAAC,GAEIR,CACT,EAGA9C,EAAS,oBAAsB,SAAS2B,EAAc,CACpD,IAAM4B,EAAiB,CAAC,EAIlBC,EAAaxD,EAAS,YAAY2B,EAAc,SAAS,EAC5D,IAAIzB,GAAQF,EAAS,eAAeE,CAAI,CAAC,EACzC,OAAOuD,GAAOA,EAAI,YAAc,OAAO,EAAE,CAAC,EACzCD,IACFD,EAAe,MAAQC,EAAW,MAClCD,EAAe,KAAOC,EAAW,MAKnC,IAAME,EAAQ1D,EAAS,YAAY2B,EAAc,cAAc,EAC/D4B,EAAe,YAAcG,EAAM,OAAS,EAC5CH,EAAe,SAAWG,EAAM,SAAW,EAI3C,IAAMC,EAAM3D,EAAS,YAAY2B,EAAc,YAAY,EAC3D,OAAA4B,EAAe,IAAMI,EAAI,OAAS,EAE3BJ,CACT,EAEAvD,EAAS,oBAAsB,SAASuD,EAAgB,CACtD,IAAI7C,EAAM,GACV,OAAI6C,EAAe,cACjB7C,GAAO;AAAA,GAEL6C,EAAe,MACjB7C,GAAO;AAAA,GAEL6C,EAAe,OAAS,QAAaA,EAAe,QACtD7C,GAAO,UAAY6C,EAAe,KAChC,UAAYA,EAAe,MAAQ;AAAA,GAEhC7C,CACT,EAKAV,EAAS,UAAY,SAAS2B,EAAc,CAC1C,IAAIpB,EACEqD,EAAO5D,EAAS,YAAY2B,EAAc,SAAS,EACzD,GAAIiC,EAAK,SAAW,EAClB,OAAArD,EAAQqD,EAAK,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,EAC/B,CAAC,OAAQrD,EAAM,CAAC,EAAG,MAAOA,EAAM,CAAC,CAAC,EAE3C,IAAMsD,EAAQ7D,EAAS,YAAY2B,EAAc,SAAS,EACvD,IAAIzB,GAAQF,EAAS,eAAeE,CAAI,CAAC,EACzC,OAAO4D,GAAaA,EAAU,YAAc,MAAM,EACrD,GAAID,EAAM,OAAS,EACjB,OAAAtD,EAAQsD,EAAM,CAAC,EAAE,MAAM,MAAM,GAAG,EACzB,CAAC,OAAQtD,EAAM,CAAC,EAAG,MAAOA,EAAM,CAAC,CAAC,CAE7C,EAKAP,EAAS,qBAAuB,SAAS2B,EAAc,CACrD,IAAMU,EAAQrC,EAAS,WAAW2B,CAAY,EACxCoC,EAAc/D,EAAS,YAAY2B,EAAc,qBAAqB,EACxEqC,EACAD,EAAY,OAAS,IACvBC,EAAiB,SAASD,EAAY,CAAC,EAAE,UAAU,EAAE,EAAG,EAAE,GAExD,MAAMC,CAAc,IACtBA,EAAiB,OAEnB,IAAMC,EAAWjE,EAAS,YAAY2B,EAAc,cAAc,EAClE,GAAIsC,EAAS,OAAS,EACpB,MAAO,CACL,KAAM,SAASA,EAAS,CAAC,EAAE,UAAU,EAAE,EAAG,EAAE,EAC5C,SAAU5B,EAAM,IAChB,eAAA2B,CACF,EAEF,IAAME,EAAelE,EAAS,YAAY2B,EAAc,YAAY,EACpE,GAAIuC,EAAa,OAAS,EAAG,CAC3B,IAAM3D,EAAQ2D,EAAa,CAAC,EACzB,UAAU,EAAE,EACZ,MAAM,GAAG,EACZ,MAAO,CACL,KAAM,SAAS3D,EAAM,CAAC,EAAG,EAAE,EAC3B,SAAUA,EAAM,CAAC,EACjB,eAAAyD,CACF,CACF,CACF,EAOAhE,EAAS,qBAAuB,SAASmE,EAAOC,EAAM,CACpD,IAAIC,EAAS,CAAC,EACd,OAAIF,EAAM,WAAa,YACrBE,EAAS,CACP,KAAOF,EAAM,KAAO,MAAQA,EAAM,SAAW,IAAMC,EAAK,SAAW;AAAA,EACnE;AAAA,EACA,eAAiBA,EAAK,KAAO;AAAA,CAC/B,EAEAC,EAAS,CACP,KAAOF,EAAM,KAAO,MAAQA,EAAM,SAAW,IAAMC,EAAK,KAAO;AAAA,EAC/D;AAAA,EACA,aAAeA,EAAK,KAAO,IAAMA,EAAK,SAAW;AAAA,CACnD,EAEEA,EAAK,iBAAmB,QAC1BC,EAAO,KAAK,sBAAwBD,EAAK,eAAiB;AAAA,CAAM,EAE3DC,EAAO,KAAK,EAAE,CACvB,EAMArE,EAAS,kBAAoB,UAAW,CACtC,OAAO,KAAK,OAAO,EAAE,SAAS,EAAE,OAAO,EAAG,EAAE,CAC9C,EAOAA,EAAS,wBAA0B,SAASsE,EAAQC,EAASC,EAAU,CACrE,IAAIC,EACEC,EAAUH,IAAY,OAAYA,EAAU,EAClD,OAAID,EACFG,EAAYH,EAEZG,EAAYzE,EAAS,kBAAkB,EAIlC;AAAA,KAFMwE,GAAY,qBAGP,IAAMC,EAAY,IAAMC,EACpC;AAAA;AAAA;AAAA,CAGR,EAGA1E,EAAS,aAAe,SAAS2B,EAAcE,EAAa,CAE1D,IAAMP,EAAQtB,EAAS,WAAW2B,CAAY,EAC9C,QAASlB,EAAI,EAAGA,EAAIa,EAAM,OAAQb,IAChC,OAAQa,EAAMb,CAAC,EAAG,CAChB,IAAK,aACL,IAAK,aACL,IAAK,aACL,IAAK,aACH,OAAOa,EAAMb,CAAC,EAAE,UAAU,CAAC,EAC7B,QAEF,CAEF,OAAIoB,EACK7B,EAAS,aAAa6B,CAAW,EAEnC,UACT,EAEA7B,EAAS,QAAU,SAAS2B,EAAc,CAGxC,OAFc3B,EAAS,WAAW2B,CAAY,EAC1B,CAAC,EAAE,MAAM,GAAG,EACnB,CAAC,EAAE,UAAU,CAAC,CAC7B,EAEA3B,EAAS,WAAa,SAAS2B,EAAc,CAC3C,OAAOA,EAAa,MAAM,IAAK,CAAC,EAAE,CAAC,IAAM,GAC3C,EAEA3B,EAAS,WAAa,SAAS2B,EAAc,CAE3C,IAAMpB,EADQP,EAAS,WAAW2B,CAAY,EAC1B,CAAC,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,EAC7C,MAAO,CACL,KAAMpB,EAAM,CAAC,EACb,KAAM,SAASA,EAAM,CAAC,EAAG,EAAE,EAC3B,SAAUA,EAAM,CAAC,EACjB,IAAKA,EAAM,MAAM,CAAC,EAAE,KAAK,GAAG,CAC9B,CACF,EAEAP,EAAS,WAAa,SAAS2B,EAAc,CAE3C,IAAMpB,EADOP,EAAS,YAAY2B,EAAc,IAAI,EAAE,CAAC,EACpC,UAAU,CAAC,EAAE,MAAM,GAAG,EACzC,MAAO,CACL,SAAUpB,EAAM,CAAC,EACjB,UAAWA,EAAM,CAAC,EAClB,eAAgB,SAASA,EAAM,CAAC,EAAG,EAAE,EACrC,QAASA,EAAM,CAAC,EAChB,YAAaA,EAAM,CAAC,EACpB,QAASA,EAAM,CAAC,CAClB,CACF,EAGAP,EAAS,WAAa,SAASC,EAAM,CACnC,GAAI,OAAOA,GAAS,UAAYA,EAAK,SAAW,EAC9C,MAAO,GAET,IAAMqB,EAAQtB,EAAS,WAAWC,CAAI,EACtC,QAASQ,EAAI,EAAGA,EAAIa,EAAM,OAAQb,IAChC,GAAIa,EAAMb,CAAC,EAAE,OAAS,GAAKa,EAAMb,CAAC,EAAE,OAAO,CAAC,IAAM,IAChD,MAAO,GAIX,MAAO,EACT,EAGI,OAAOV,IAAW,WACpBA,GAAO,QAAUC,KChyBnB,IAAA2E,GAAA,GAAAC,EAAAD,GAAA,UAAAE,GAAA,eAAAC,KAAA,eAAAC,GAAAJ,ICUA,IAAIK,GAAe,GACfC,GAAuB,GAUpB,SAASC,EAAeC,EAAUC,EAAMC,EAAK,CAClD,IAAMC,EAAQH,EAAS,MAAMC,CAAI,EACjC,OAAOE,GAASA,EAAM,QAAUD,GAAO,SAASC,EAAMD,CAAG,EAAG,EAAE,CAChE,CAKO,SAASE,EAAwBC,EAAQC,EAAiBC,EAAS,CACxE,GAAI,CAACF,EAAO,kBACV,OAEF,IAAMG,EAAQH,EAAO,kBAAkB,UACjCI,EAAyBD,EAAM,iBACrCA,EAAM,iBAAmB,SAASE,EAAiBC,EAAI,CACrD,GAAID,IAAoBJ,EACtB,OAAOG,EAAuB,MAAM,KAAM,SAAS,EAErD,IAAMG,EAAmBC,GAAM,CAC7B,IAAMC,EAAgBP,EAAQM,CAAC,EAC3BC,IACEH,EAAG,YACLA,EAAG,YAAYG,CAAa,EAE5BH,EAAGG,CAAa,EAGtB,EACA,YAAK,UAAY,KAAK,WAAa,CAAC,EAC/B,KAAK,UAAUR,CAAe,IACjC,KAAK,UAAUA,CAAe,EAAI,IAAI,KAExC,KAAK,UAAUA,CAAe,EAAE,IAAIK,EAAIC,CAAe,EAChDH,EAAuB,MAAM,KAAM,CAACC,EACzCE,CAAe,CAAC,CACpB,EAEA,IAAMG,EAA4BP,EAAM,oBACxCA,EAAM,oBAAsB,SAASE,EAAiBC,EAAI,CACxD,GAAID,IAAoBJ,GAAmB,CAAC,KAAK,WAC1C,CAAC,KAAK,UAAUA,CAAe,EACpC,OAAOS,EAA0B,MAAM,KAAM,SAAS,EAExD,GAAI,CAAC,KAAK,UAAUT,CAAe,EAAE,IAAIK,CAAE,EACzC,OAAOI,EAA0B,MAAM,KAAM,SAAS,EAExD,IAAMC,EAAc,KAAK,UAAUV,CAAe,EAAE,IAAIK,CAAE,EAC1D,YAAK,UAAUL,CAAe,EAAE,OAAOK,CAAE,EACrC,KAAK,UAAUL,CAAe,EAAE,OAAS,GAC3C,OAAO,KAAK,UAAUA,CAAe,EAEnC,OAAO,KAAK,KAAK,SAAS,EAAE,SAAW,GACzC,OAAO,KAAK,UAEPS,EAA0B,MAAM,KAAM,CAACL,EAC5CM,CAAW,CAAC,CAChB,EAEA,OAAO,eAAeR,EAAO,KAAOF,EAAiB,CACnD,KAAM,CACJ,OAAO,KAAK,MAAQA,CAAe,CACrC,EACA,IAAIK,EAAI,CACF,KAAK,MAAQL,CAAe,IAC9B,KAAK,oBAAoBA,EACvB,KAAK,MAAQA,CAAe,CAAC,EAC/B,OAAO,KAAK,MAAQA,CAAe,GAEjCK,GACF,KAAK,iBAAiBL,EACpB,KAAK,MAAQA,CAAe,EAAIK,CAAE,CAExC,EACA,WAAY,GACZ,aAAc,EAChB,CAAC,CACH,CAEO,SAASM,GAAWC,EAAM,CAC/B,OAAI,OAAOA,GAAS,UACX,IAAI,MAAM,kBAAoB,OAAOA,EACxC,yBAAyB,GAE/BrB,GAAeqB,EACPA,EAAQ,8BACd,6BACJ,CAMO,SAASC,GAAgBD,EAAM,CACpC,OAAI,OAAOA,GAAS,UACX,IAAI,MAAM,kBAAoB,OAAOA,EACxC,yBAAyB,GAE/BpB,GAAuB,CAACoB,EACjB,oCAAsCA,EAAO,WAAa,WACnE,CAEO,SAASE,GAAM,CACpB,GAAI,OAAO,QAAW,SAAU,CAC9B,GAAIvB,GACF,OAEE,OAAO,QAAY,KAAe,OAAO,QAAQ,KAAQ,YAC3D,QAAQ,IAAI,MAAM,QAAS,SAAS,CAExC,CACF,CAKO,SAASwB,EAAWC,EAAWC,EAAW,CAC1CzB,IAGL,QAAQ,KAAKwB,EAAY,8BAAgCC,EACrD,WAAW,CACjB,CAQO,SAASC,GAAcnB,EAAQ,CAEpC,IAAMoB,EAAS,CAAC,QAAS,KAAM,QAAS,IAAI,EAG5C,GAAI,OAAOpB,EAAW,KAAe,CAACA,EAAO,WACzC,CAACA,EAAO,UAAU,UACpB,OAAAoB,EAAO,QAAU,iBACVA,EAGT,GAAM,CAAC,UAAAC,CAAS,EAAIrB,EAGpB,GAAIqB,EAAU,eAAiBA,EAAU,cAAc,OAAQ,CAC7D,IAAMC,EAAWD,EAAU,cAAc,OAAO,KAAME,GAC7CA,EAAM,QAAU,UACxB,EACD,GAAID,EACF,MAAO,CAAC,QAAS,SAAU,QAAS,SAASA,EAAS,QAAS,EAAE,CAAC,CAEtE,CAEA,GAAID,EAAU,gBACZD,EAAO,QAAU,UACjBA,EAAO,QAAU1B,EAAe2B,EAAU,UACxC,mBAAoB,CAAC,UACdA,EAAU,oBAChBrB,EAAO,kBAAoB,IAASA,EAAO,wBAK9CoB,EAAO,QAAU,SACjBA,EAAO,QAAU1B,EAAe2B,EAAU,UACxC,wBAAyB,CAAC,UACnBrB,EAAO,mBACdqB,EAAU,UAAU,MAAM,sBAAsB,EAClDD,EAAO,QAAU,SACjBA,EAAO,QAAU1B,EAAe2B,EAAU,UACxC,uBAAwB,CAAC,EAC3BD,EAAO,oBAAsBpB,EAAO,mBAChC,qBAAsBA,EAAO,kBAAkB,cAEnD,QAAAoB,EAAO,QAAU,2BACVA,EAGT,OAAOA,CACT,CAQA,SAASI,GAASC,EAAK,CACrB,OAAO,OAAO,UAAU,SAAS,KAAKA,CAAG,IAAM,iBACjD,CAOO,SAASC,GAAcC,EAAM,CAClC,OAAKH,GAASG,CAAI,EAIX,OAAO,KAAKA,CAAI,EAAE,OAAO,SAASC,EAAaC,EAAK,CACzD,IAAMC,EAAQN,GAASG,EAAKE,CAAG,CAAC,EAC1BE,EAAQD,EAAQJ,GAAcC,EAAKE,CAAG,CAAC,EAAIF,EAAKE,CAAG,EACnDG,EAAgBF,GAAS,CAAC,OAAO,KAAKC,CAAK,EAAE,OACnD,OAAIA,IAAU,QAAaC,EAClBJ,EAEF,OAAO,OAAOA,EAAa,CAAC,CAACC,CAAG,EAAGE,CAAK,CAAC,CAClD,EAAG,CAAC,CAAC,EAXIJ,CAYX,CAGO,SAASM,GAAUC,EAAOC,EAAMC,EAAW,CAC5C,CAACD,GAAQC,EAAU,IAAID,EAAK,EAAE,IAGlCC,EAAU,IAAID,EAAK,GAAIA,CAAI,EAC3B,OAAO,KAAKA,CAAI,EAAE,QAAQE,GAAQ,CAC5BA,EAAK,SAAS,IAAI,EACpBJ,GAAUC,EAAOA,EAAM,IAAIC,EAAKE,CAAI,CAAC,EAAGD,CAAS,EACxCC,EAAK,SAAS,KAAK,GAC5BF,EAAKE,CAAI,EAAE,QAAQC,GAAM,CACvBL,GAAUC,EAAOA,EAAM,IAAII,CAAE,EAAGF,CAAS,CAC3C,CAAC,CAEL,CAAC,EACH,CAGO,SAASG,GAAYnB,EAAQoB,EAAOC,EAAU,CACnD,IAAMC,EAAkBD,EAAW,eAAiB,cAC9CE,EAAiB,IAAI,IAC3B,GAAIH,IAAU,KACZ,OAAOG,EAET,IAAMC,EAAa,CAAC,EACpB,OAAAxB,EAAO,QAAQW,GAAS,CAClBA,EAAM,OAAS,SACfA,EAAM,kBAAoBS,EAAM,IAClCI,EAAW,KAAKb,CAAK,CAEzB,CAAC,EACDa,EAAW,QAAQC,GAAa,CAC9BzB,EAAO,QAAQc,GAAS,CAClBA,EAAM,OAASQ,GAAmBR,EAAM,UAAYW,EAAU,IAChEZ,GAAUb,EAAQc,EAAOS,CAAc,CAE3C,CAAC,CACH,CAAC,EACMA,CACT,CC/QA,IAAAG,EAAA,GAAAC,EAAAD,EAAA,0BAAAE,GAAA,4BAAAC,GAAA,sCAAAC,GAAA,2BAAAC,GAAA,qBAAAC,EAAA,oBAAAC,GAAA,gBAAAC,GAAA,uBAAAC,EAAA,+BAAAC,KCUA,IAAMC,GAAgBC,EAEf,SAASC,EAAiBC,EAAQC,EAAgB,CACvD,IAAMC,EAAYF,GAAUA,EAAO,UAEnC,GAAI,CAACE,EAAU,aACb,OAGF,IAAMC,EAAuB,SAASC,EAAG,CACvC,GAAI,OAAOA,GAAM,UAAYA,EAAE,WAAaA,EAAE,SAC5C,OAAOA,EAET,IAAMC,EAAK,CAAC,EACZ,cAAO,KAAKD,CAAC,EAAE,QAAQE,GAAO,CAC5B,GAAIA,IAAQ,WAAaA,IAAQ,YAAcA,IAAQ,cACrD,OAEF,IAAMC,EAAK,OAAOH,EAAEE,CAAG,GAAM,SAAYF,EAAEE,CAAG,EAAI,CAAC,MAAOF,EAAEE,CAAG,CAAC,EAC5DC,EAAE,QAAU,QAAa,OAAOA,EAAE,OAAU,WAC9CA,EAAE,IAAMA,EAAE,IAAMA,EAAE,OAEpB,IAAMC,EAAW,SAASC,EAAQC,EAAM,CACtC,OAAID,EACKA,EAASC,EAAK,OAAO,CAAC,EAAE,YAAY,EAAIA,EAAK,MAAM,CAAC,EAErDA,IAAS,WAAc,WAAaA,CAC9C,EACA,GAAIH,EAAE,QAAU,OAAW,CACzBF,EAAG,SAAWA,EAAG,UAAY,CAAC,EAC9B,IAAIM,EAAK,CAAC,EACN,OAAOJ,EAAE,OAAU,UACrBI,EAAGH,EAAS,MAAOF,CAAG,CAAC,EAAIC,EAAE,MAC7BF,EAAG,SAAS,KAAKM,CAAE,EACnBA,EAAK,CAAC,EACNA,EAAGH,EAAS,MAAOF,CAAG,CAAC,EAAIC,EAAE,MAC7BF,EAAG,SAAS,KAAKM,CAAE,IAEnBA,EAAGH,EAAS,GAAIF,CAAG,CAAC,EAAIC,EAAE,MAC1BF,EAAG,SAAS,KAAKM,CAAE,EAEvB,CACIJ,EAAE,QAAU,QAAa,OAAOA,EAAE,OAAU,UAC9CF,EAAG,UAAYA,EAAG,WAAa,CAAC,EAChCA,EAAG,UAAUG,EAAS,GAAIF,CAAG,CAAC,EAAIC,EAAE,OAEpC,CAAC,MAAO,KAAK,EAAE,QAAQK,GAAO,CACxBL,EAAEK,CAAG,IAAM,SACbP,EAAG,UAAYA,EAAG,WAAa,CAAC,EAChCA,EAAG,UAAUG,EAASI,EAAKN,CAAG,CAAC,EAAIC,EAAEK,CAAG,EAE5C,CAAC,CAEL,CAAC,EACGR,EAAE,WACJC,EAAG,UAAYA,EAAG,UAAY,CAAC,GAAG,OAAOD,EAAE,QAAQ,GAE9CC,CACT,EAEMQ,EAAmB,SAASC,EAAaC,EAAM,CACnD,GAAId,EAAe,SAAW,GAC5B,OAAOc,EAAKD,CAAW,EAGzB,GADAA,EAAc,KAAK,MAAM,KAAK,UAAUA,CAAW,CAAC,EAChDA,GAAe,OAAOA,EAAY,OAAU,SAAU,CACxD,IAAME,EAAQ,SAASC,EAAKC,EAAGC,EAAG,CAC5BD,KAAKD,GAAO,EAAEE,KAAKF,KACrBA,EAAIE,CAAC,EAAIF,EAAIC,CAAC,EACd,OAAOD,EAAIC,CAAC,EAEhB,EACAJ,EAAc,KAAK,MAAM,KAAK,UAAUA,CAAW,CAAC,EACpDE,EAAMF,EAAY,MAAO,kBAAmB,qBAAqB,EACjEE,EAAMF,EAAY,MAAO,mBAAoB,sBAAsB,EACnEA,EAAY,MAAQX,EAAqBW,EAAY,KAAK,CAC5D,CACA,GAAIA,GAAe,OAAOA,EAAY,OAAU,SAAU,CAExD,IAAIM,EAAON,EAAY,MAAM,WAC7BM,EAAOA,IAAU,OAAOA,GAAS,SAAYA,EAAO,CAAC,MAAOA,CAAI,GAChE,IAAMC,EAA6BpB,EAAe,QAAU,GAE5D,GAAKmB,IAASA,EAAK,QAAU,QAAUA,EAAK,QAAU,eACxCA,EAAK,QAAU,QAAUA,EAAK,QAAU,gBAClD,EAAElB,EAAU,aAAa,yBACvBA,EAAU,aAAa,wBAAwB,EAAE,YACjD,CAACmB,GAA6B,CAClC,OAAOP,EAAY,MAAM,WACzB,IAAIQ,EAMJ,GALIF,EAAK,QAAU,eAAiBA,EAAK,QAAU,cACjDE,EAAU,CAAC,OAAQ,MAAM,GAChBF,EAAK,QAAU,QAAUA,EAAK,QAAU,UACjDE,EAAU,CAAC,OAAO,GAEhBA,EAEF,OAAOpB,EAAU,aAAa,iBAAiB,EAC5C,KAAKqB,GAAW,CACfA,EAAUA,EAAQ,OAAOC,GAAKA,EAAE,OAAS,YAAY,EACrD,IAAIC,EAAMF,EAAQ,KAAKC,GAAKF,EAAQ,KAAKI,GACvCF,EAAE,MAAM,YAAY,EAAE,SAASE,CAAK,CAAC,CAAC,EACxC,MAAI,CAACD,GAAOF,EAAQ,QAAUD,EAAQ,SAAS,MAAM,IACnDG,EAAMF,EAAQA,EAAQ,OAAS,CAAC,GAE9BE,IACFX,EAAY,MAAM,SAAWM,EAAK,MAC9B,CAAC,MAAOK,EAAI,QAAQ,EACpB,CAAC,MAAOA,EAAI,QAAQ,GAE1BX,EAAY,MAAQX,EAAqBW,EAAY,KAAK,EAC1DjB,GAAQ,WAAa,KAAK,UAAUiB,CAAW,CAAC,EACzCC,EAAKD,CAAW,CACzB,CAAC,CAEP,CACAA,EAAY,MAAQX,EAAqBW,EAAY,KAAK,CAC5D,CACA,OAAAjB,GAAQ,WAAa,KAAK,UAAUiB,CAAW,CAAC,EACzCC,EAAKD,CAAW,CACzB,EAEMa,EAAa,SAASC,EAAG,CAC7B,OAAI3B,EAAe,SAAW,GACrB2B,EAEF,CACL,KAAM,CACJ,sBAAuB,kBACvB,yBAA0B,kBAC1B,kBAAmB,kBACnB,qBAAsB,gBACtB,4BAA6B,uBAC7B,gBAAiB,mBACjB,+BAAgC,kBAChC,wBAAyB,kBACzB,gBAAiB,aACjB,mBAAoB,aACpB,mBAAoB,YACtB,EAAEA,EAAE,IAAI,GAAKA,EAAE,KACf,QAASA,EAAE,QACX,WAAYA,EAAE,YAAcA,EAAE,eAC9B,UAAW,CACT,OAAO,KAAK,MAAQ,KAAK,SAAW,MAAQ,KAAK,OACnD,CACF,CACF,EAEMC,EAAgB,SAASf,EAAagB,EAAWC,EAAS,CAC9DlB,EAAiBC,EAAaV,GAAK,CACjCF,EAAU,mBAAmBE,EAAG0B,EAAWF,GAAK,CAC1CG,GACFA,EAAQJ,EAAWC,CAAC,CAAC,CAEzB,CAAC,CACH,CAAC,CACH,EAMA,GALA1B,EAAU,aAAe2B,EAAc,KAAK3B,CAAS,EAKjDA,EAAU,aAAa,aAAc,CACvC,IAAM8B,EAAmB9B,EAAU,aAAa,aAC9C,KAAKA,EAAU,YAAY,EAC7BA,EAAU,aAAa,aAAe,SAAS+B,EAAI,CACjD,OAAOpB,EAAiBoB,EAAI,GAAKD,EAAiB,CAAC,EAAE,KAAKE,GAAU,CAClE,GAAI,EAAE,OAAS,CAACA,EAAO,eAAe,EAAE,QACpC,EAAE,OAAS,CAACA,EAAO,eAAe,EAAE,OACtC,MAAAA,EAAO,UAAU,EAAE,QAAQC,GAAS,CAClCA,EAAM,KAAK,CACb,CAAC,EACK,IAAI,aAAa,GAAI,eAAe,EAE5C,OAAOD,CACT,EAAGN,GAAK,QAAQ,OAAOD,EAAWC,CAAC,CAAC,CAAC,CAAC,CACxC,CACF,CACF,CD/KO,SAASQ,GAAgBC,EAAQ,CACtCA,EAAO,YAAcA,EAAO,aAAeA,EAAO,iBACpD,CAEO,SAASC,GAAYD,EAAQ,CAClC,GAAI,OAAOA,GAAW,UAAYA,EAAO,mBAAqB,EAAE,YAC5DA,EAAO,kBAAkB,WAAY,CACvC,OAAO,eAAeA,EAAO,kBAAkB,UAAW,UAAW,CACnE,KAAM,CACJ,OAAO,KAAK,QACd,EACA,IAAIE,EAAG,CACD,KAAK,UACP,KAAK,oBAAoB,QAAS,KAAK,QAAQ,EAEjD,KAAK,iBAAiB,QAAS,KAAK,SAAWA,CAAC,CAClD,EACA,WAAY,GACZ,aAAc,EAChB,CAAC,EACD,IAAMC,EACFH,EAAO,kBAAkB,UAAU,qBACvCA,EAAO,kBAAkB,UAAU,qBACjC,UAAgC,CAC9B,OAAK,KAAK,eACR,KAAK,aAAgBI,GAAM,CAGzBA,EAAE,OAAO,iBAAiB,WAAYC,GAAM,CAC1C,IAAIC,EACAN,EAAO,kBAAkB,UAAU,aACrCM,EAAW,KAAK,aAAa,EAC1B,KAAKC,GAAKA,EAAE,OAASA,EAAE,MAAM,KAAOF,EAAG,MAAM,EAAE,EAElDC,EAAW,CAAC,MAAOD,EAAG,KAAK,EAG7B,IAAMG,EAAQ,IAAI,MAAM,OAAO,EAC/BA,EAAM,MAAQH,EAAG,MACjBG,EAAM,SAAWF,EACjBE,EAAM,YAAc,CAAC,SAAAF,CAAQ,EAC7BE,EAAM,QAAU,CAACJ,EAAE,MAAM,EACzB,KAAK,cAAcI,CAAK,CAC1B,CAAC,EACDJ,EAAE,OAAO,UAAU,EAAE,QAAQK,GAAS,CACpC,IAAIH,EACAN,EAAO,kBAAkB,UAAU,aACrCM,EAAW,KAAK,aAAa,EAC1B,KAAKC,GAAKA,EAAE,OAASA,EAAE,MAAM,KAAOE,EAAM,EAAE,EAE/CH,EAAW,CAAC,MAAAG,CAAK,EAEnB,IAAMD,EAAQ,IAAI,MAAM,OAAO,EAC/BA,EAAM,MAAQC,EACdD,EAAM,SAAWF,EACjBE,EAAM,YAAc,CAAC,SAAAF,CAAQ,EAC7BE,EAAM,QAAU,CAACJ,EAAE,MAAM,EACzB,KAAK,cAAcI,CAAK,CAC1B,CAAC,CACH,EACA,KAAK,iBAAiB,YAAa,KAAK,YAAY,GAE/CL,EAAyB,MAAM,KAAM,SAAS,CACvD,CACJ,MAIQO,EAAwBV,EAAQ,QAASI,IACxCA,EAAE,aACL,OAAO,eAAeA,EAAG,cACvB,CAAC,MAAO,CAAC,SAAUA,EAAE,QAAQ,CAAC,CAAC,EAE5BA,EACR,CAEL,CAEO,SAASO,GAAuBX,EAAQ,CAE7C,GAAI,OAAOA,GAAW,UAAYA,EAAO,mBACrC,EAAE,eAAgBA,EAAO,kBAAkB,YAC3C,qBAAsBA,EAAO,kBAAkB,UAAW,CAC5D,IAAMY,EAAqB,SAASC,EAAIJ,EAAO,CAC7C,MAAO,CACL,MAAAA,EACA,IAAI,MAAO,CACT,OAAI,KAAK,QAAU,SACbA,EAAM,OAAS,QACjB,KAAK,MAAQI,EAAG,iBAAiBJ,CAAK,EAEtC,KAAK,MAAQ,MAGV,KAAK,KACd,EACA,IAAKI,CACP,CACF,EAGA,GAAI,CAACb,EAAO,kBAAkB,UAAU,WAAY,CAClDA,EAAO,kBAAkB,UAAU,WAAa,UAAsB,CACpE,YAAK,SAAW,KAAK,UAAY,CAAC,EAC3B,KAAK,SAAS,MAAM,CAC7B,EACA,IAAMc,EAAed,EAAO,kBAAkB,UAAU,SACxDA,EAAO,kBAAkB,UAAU,SACjC,SAAkBS,EAAOM,EAAQ,CAC/B,IAAIC,EAASF,EAAa,MAAM,KAAM,SAAS,EAC/C,OAAKE,IACHA,EAASJ,EAAmB,KAAMH,CAAK,EACvC,KAAK,SAAS,KAAKO,CAAM,GAEpBA,CACT,EAEF,IAAMC,EAAkBjB,EAAO,kBAAkB,UAAU,YAC3DA,EAAO,kBAAkB,UAAU,YACjC,SAAqBgB,EAAQ,CAC3BC,EAAgB,MAAM,KAAM,SAAS,EACrC,IAAMC,EAAM,KAAK,SAAS,QAAQF,CAAM,EACpCE,IAAQ,IACV,KAAK,SAAS,OAAOA,EAAK,CAAC,CAE/B,CACJ,CACA,IAAMC,EAAgBnB,EAAO,kBAAkB,UAAU,UACzDA,EAAO,kBAAkB,UAAU,UAAY,SAAmBe,EAAQ,CACxE,KAAK,SAAW,KAAK,UAAY,CAAC,EAClCI,EAAc,MAAM,KAAM,CAACJ,CAAM,CAAC,EAClCA,EAAO,UAAU,EAAE,QAAQN,GAAS,CAClC,KAAK,SAAS,KAAKG,EAAmB,KAAMH,CAAK,CAAC,CACpD,CAAC,CACH,EAEA,IAAMW,EAAmBpB,EAAO,kBAAkB,UAAU,aAC5DA,EAAO,kBAAkB,UAAU,aACjC,SAAsBe,EAAQ,CAC5B,KAAK,SAAW,KAAK,UAAY,CAAC,EAClCK,EAAiB,MAAM,KAAM,CAACL,CAAM,CAAC,EAErCA,EAAO,UAAU,EAAE,QAAQN,GAAS,CAClC,IAAMO,EAAS,KAAK,SAAS,KAAKK,GAAKA,EAAE,QAAUZ,CAAK,EACpDO,GACF,KAAK,SAAS,OAAO,KAAK,SAAS,QAAQA,CAAM,EAAG,CAAC,CAEzD,CAAC,CACH,CACJ,SAAW,OAAOhB,GAAW,UAAYA,EAAO,mBACrC,eAAgBA,EAAO,kBAAkB,WACzC,qBAAsBA,EAAO,kBAAkB,WAC/CA,EAAO,cACP,EAAE,SAAUA,EAAO,aAAa,WAAY,CACrD,IAAMsB,EAAiBtB,EAAO,kBAAkB,UAAU,WAC1DA,EAAO,kBAAkB,UAAU,WAAa,UAAsB,CACpE,IAAMuB,EAAUD,EAAe,MAAM,KAAM,CAAC,CAAC,EAC7C,OAAAC,EAAQ,QAAQP,GAAUA,EAAO,IAAM,IAAI,EACpCO,CACT,EAEA,OAAO,eAAevB,EAAO,aAAa,UAAW,OAAQ,CAC3D,KAAM,CACJ,OAAI,KAAK,QAAU,SACb,KAAK,MAAM,OAAS,QACtB,KAAK,MAAQ,KAAK,IAAI,iBAAiB,KAAK,KAAK,EAEjD,KAAK,MAAQ,MAGV,KAAK,KACd,CACF,CAAC,CACH,CACF,CAEO,SAASwB,GAA2BxB,EAAQ,CACjD,GAAI,EAAE,OAAOA,GAAW,UAAYA,EAAO,mBACvCA,EAAO,cAAgBA,EAAO,gBAChC,OAIF,GAAI,EAAE,aAAcA,EAAO,aAAa,WAAY,CAClD,IAAMsB,EAAiBtB,EAAO,kBAAkB,UAAU,WACtDsB,IACFtB,EAAO,kBAAkB,UAAU,WAAa,UAAsB,CACpE,IAAMuB,EAAUD,EAAe,MAAM,KAAM,CAAC,CAAC,EAC7C,OAAAC,EAAQ,QAAQP,GAAUA,EAAO,IAAM,IAAI,EACpCO,CACT,GAGF,IAAMT,EAAed,EAAO,kBAAkB,UAAU,SACpDc,IACFd,EAAO,kBAAkB,UAAU,SAAW,UAAoB,CAChE,IAAMgB,EAASF,EAAa,MAAM,KAAM,SAAS,EACjD,OAAAE,EAAO,IAAM,KACNA,CACT,GAEFhB,EAAO,aAAa,UAAU,SAAW,UAAoB,CAC3D,IAAMgB,EAAS,KACf,OAAO,KAAK,IAAI,SAAS,EAAE,KAAKS,GAKxBC,GAAYD,EAAQT,EAAO,MAAO,EAAI,CAAC,CACjD,CACF,CAGA,GAAI,EAAE,aAAchB,EAAO,eAAe,WAAY,CACpD,IAAM2B,EAAmB3B,EAAO,kBAAkB,UAAU,aACxD2B,IACF3B,EAAO,kBAAkB,UAAU,aACjC,UAAwB,CACtB,IAAM4B,EAAYD,EAAiB,MAAM,KAAM,CAAC,CAAC,EACjD,OAAAC,EAAU,QAAQtB,GAAYA,EAAS,IAAM,IAAI,EAC1CsB,CACT,GAEElB,EAAwBV,EAAQ,QAASI,IAC7CA,EAAE,SAAS,IAAMA,EAAE,WACZA,EACR,EACDJ,EAAO,eAAe,UAAU,SAAW,UAAoB,CAC7D,IAAMM,EAAW,KACjB,OAAO,KAAK,IAAI,SAAS,EAAE,KAAKmB,GACxBC,GAAYD,EAAQnB,EAAS,MAAO,EAAK,CAAC,CACpD,CACF,CAEA,GAAI,EAAE,aAAcN,EAAO,aAAa,WACpC,aAAcA,EAAO,eAAe,WACtC,OAIF,IAAM6B,EAAe7B,EAAO,kBAAkB,UAAU,SACxDA,EAAO,kBAAkB,UAAU,SAAW,UAAoB,CAChE,GAAI,UAAU,OAAS,GACnB,UAAU,CAAC,YAAaA,EAAO,iBAAkB,CACnD,IAAMS,EAAQ,UAAU,CAAC,EACrBO,EACAV,EACAwB,EAoBJ,OAnBA,KAAK,WAAW,EAAE,QAAQT,GAAK,CACzBA,EAAE,QAAUZ,IACVO,EACFc,EAAM,GAENd,EAASK,EAGf,CAAC,EACD,KAAK,aAAa,EAAE,QAAQd,IACtBA,EAAE,QAAUE,IACVH,EACFwB,EAAM,GAENxB,EAAWC,GAGRA,EAAE,QAAUE,EACpB,EACGqB,GAAQd,GAAUV,EACb,QAAQ,OAAO,IAAI,aACxB,4DACA,oBAAoB,CAAC,EACdU,EACFA,EAAO,SAAS,EACdV,EACFA,EAAS,SAAS,EAEpB,QAAQ,OAAO,IAAI,aACxB,gDACA,oBAAoB,CAAC,CACzB,CACA,OAAOuB,EAAa,MAAM,KAAM,SAAS,CAC3C,CACF,CAEO,SAASE,GAAkC/B,EAAQ,CAIxDA,EAAO,kBAAkB,UAAU,gBACjC,UAA2B,CACzB,YAAK,qBAAuB,KAAK,sBAAwB,CAAC,EACnD,OAAO,KAAK,KAAK,oBAAoB,EACzC,IAAIgC,GAAY,KAAK,qBAAqBA,CAAQ,EAAE,CAAC,CAAC,CAC3D,EAEF,IAAMlB,EAAed,EAAO,kBAAkB,UAAU,SACxDA,EAAO,kBAAkB,UAAU,SACjC,SAAkBS,EAAOM,EAAQ,CAC/B,GAAI,CAACA,EACH,OAAOD,EAAa,MAAM,KAAM,SAAS,EAE3C,KAAK,qBAAuB,KAAK,sBAAwB,CAAC,EAE1D,IAAME,EAASF,EAAa,MAAM,KAAM,SAAS,EACjD,OAAK,KAAK,qBAAqBC,EAAO,EAAE,EAE7B,KAAK,qBAAqBA,EAAO,EAAE,EAAE,QAAQC,CAAM,IAAM,IAClE,KAAK,qBAAqBD,EAAO,EAAE,EAAE,KAAKC,CAAM,EAFhD,KAAK,qBAAqBD,EAAO,EAAE,EAAI,CAACA,EAAQC,CAAM,EAIjDA,CACT,EAEF,IAAMG,EAAgBnB,EAAO,kBAAkB,UAAU,UACzDA,EAAO,kBAAkB,UAAU,UAAY,SAAmBe,EAAQ,CACxE,KAAK,qBAAuB,KAAK,sBAAwB,CAAC,EAE1DA,EAAO,UAAU,EAAE,QAAQN,GAAS,CAElC,GADsB,KAAK,WAAW,EAAE,KAAKY,GAAKA,EAAE,QAAUZ,CAAK,EAEjE,MAAM,IAAI,aAAa,wBACrB,oBAAoB,CAE1B,CAAC,EACD,IAAMwB,EAAkB,KAAK,WAAW,EACxCd,EAAc,MAAM,KAAM,SAAS,EACnC,IAAMe,EAAa,KAAK,WAAW,EAChC,OAAOC,GAAaF,EAAgB,QAAQE,CAAS,IAAM,EAAE,EAChE,KAAK,qBAAqBpB,EAAO,EAAE,EAAI,CAACA,CAAM,EAAE,OAAOmB,CAAU,CACnE,EAEA,IAAMd,EAAmBpB,EAAO,kBAAkB,UAAU,aAC5DA,EAAO,kBAAkB,UAAU,aACjC,SAAsBe,EAAQ,CAC5B,YAAK,qBAAuB,KAAK,sBAAwB,CAAC,EAC1D,OAAO,KAAK,qBAAqBA,EAAO,EAAE,EACnCK,EAAiB,MAAM,KAAM,SAAS,CAC/C,EAEF,IAAMH,EAAkBjB,EAAO,kBAAkB,UAAU,YAC3DA,EAAO,kBAAkB,UAAU,YACjC,SAAqBgB,EAAQ,CAC3B,YAAK,qBAAuB,KAAK,sBAAwB,CAAC,EACtDA,GACF,OAAO,KAAK,KAAK,oBAAoB,EAAE,QAAQgB,GAAY,CACzD,IAAMd,EAAM,KAAK,qBAAqBc,CAAQ,EAAE,QAAQhB,CAAM,EAC1DE,IAAQ,IACV,KAAK,qBAAqBc,CAAQ,EAAE,OAAOd,EAAK,CAAC,EAE/C,KAAK,qBAAqBc,CAAQ,EAAE,SAAW,GACjD,OAAO,KAAK,qBAAqBA,CAAQ,CAE7C,CAAC,EAEIf,EAAgB,MAAM,KAAM,SAAS,CAC9C,CACJ,CAEO,SAASmB,GAAwBpC,EAAQqC,EAAgB,CAC9D,GAAI,CAACrC,EAAO,kBACV,OAGF,GAAIA,EAAO,kBAAkB,UAAU,UACnCqC,EAAe,SAAW,GAC5B,OAAON,GAAkC/B,CAAM,EAKjD,IAAMsC,EAAsBtC,EAAO,kBAAkB,UAClD,gBACHA,EAAO,kBAAkB,UAAU,gBACjC,UAA2B,CACzB,IAAMuC,EAAgBD,EAAoB,MAAM,IAAI,EACpD,YAAK,gBAAkB,KAAK,iBAAmB,CAAC,EACzCC,EAAc,IAAIxB,GAAU,KAAK,gBAAgBA,EAAO,EAAE,CAAC,CACpE,EAEF,IAAMI,EAAgBnB,EAAO,kBAAkB,UAAU,UACzDA,EAAO,kBAAkB,UAAU,UAAY,SAAmBe,EAAQ,CAaxE,GAZA,KAAK,SAAW,KAAK,UAAY,CAAC,EAClC,KAAK,gBAAkB,KAAK,iBAAmB,CAAC,EAEhDA,EAAO,UAAU,EAAE,QAAQN,GAAS,CAElC,GADsB,KAAK,WAAW,EAAE,KAAKY,GAAKA,EAAE,QAAUZ,CAAK,EAEjE,MAAM,IAAI,aAAa,wBACrB,oBAAoB,CAE1B,CAAC,EAGG,CAAC,KAAK,gBAAgBM,EAAO,EAAE,EAAG,CACpC,IAAMyB,EAAY,IAAIxC,EAAO,YAAYe,EAAO,UAAU,CAAC,EAC3D,KAAK,SAASA,EAAO,EAAE,EAAIyB,EAC3B,KAAK,gBAAgBA,EAAU,EAAE,EAAIzB,EACrCA,EAASyB,CACX,CACArB,EAAc,MAAM,KAAM,CAACJ,CAAM,CAAC,CACpC,EAEA,IAAMK,EAAmBpB,EAAO,kBAAkB,UAAU,aAC5DA,EAAO,kBAAkB,UAAU,aACjC,SAAsBe,EAAQ,CAC5B,KAAK,SAAW,KAAK,UAAY,CAAC,EAClC,KAAK,gBAAkB,KAAK,iBAAmB,CAAC,EAEhDK,EAAiB,MAAM,KAAM,CAAE,KAAK,SAASL,EAAO,EAAE,GAAKA,CAAO,CAAC,EACnE,OAAO,KAAK,gBAAiB,KAAK,SAASA,EAAO,EAAE,EAClD,KAAK,SAASA,EAAO,EAAE,EAAE,GAAKA,EAAO,EAAG,EAC1C,OAAO,KAAK,SAASA,EAAO,EAAE,CAChC,EAEFf,EAAO,kBAAkB,UAAU,SACjC,SAAkBS,EAAOM,EAAQ,CAC/B,GAAI,KAAK,iBAAmB,SAC1B,MAAM,IAAI,aACR,sDACA,mBAAmB,EAEvB,IAAM0B,EAAU,CAAC,EAAE,MAAM,KAAK,UAAW,CAAC,EAC1C,GAAIA,EAAQ,SAAW,GACnB,CAACA,EAAQ,CAAC,EAAE,UAAU,EAAE,KAAKC,GAAKA,IAAMjC,CAAK,EAG/C,MAAM,IAAI,aACR,gHAEA,mBAAmB,EAIvB,GADsB,KAAK,WAAW,EAAE,KAAKY,GAAKA,EAAE,QAAUZ,CAAK,EAEjE,MAAM,IAAI,aAAa,wBACrB,oBAAoB,EAGxB,KAAK,SAAW,KAAK,UAAY,CAAC,EAClC,KAAK,gBAAkB,KAAK,iBAAmB,CAAC,EAChD,IAAMkC,EAAY,KAAK,SAAS5B,EAAO,EAAE,EACzC,GAAI4B,EAKFA,EAAU,SAASlC,CAAK,EAGxB,QAAQ,QAAQ,EAAE,KAAK,IAAM,CAC3B,KAAK,cAAc,IAAI,MAAM,mBAAmB,CAAC,CACnD,CAAC,MACI,CACL,IAAM+B,EAAY,IAAIxC,EAAO,YAAY,CAACS,CAAK,CAAC,EAChD,KAAK,SAASM,EAAO,EAAE,EAAIyB,EAC3B,KAAK,gBAAgBA,EAAU,EAAE,EAAIzB,EACrC,KAAK,UAAUyB,CAAS,CAC1B,CACA,OAAO,KAAK,WAAW,EAAE,KAAKnB,GAAKA,EAAE,QAAUZ,CAAK,CACtD,EAIF,SAASmC,EAAwB/B,EAAIgC,EAAa,CAChD,IAAIC,EAAMD,EAAY,IACtB,cAAO,KAAKhC,EAAG,iBAAmB,CAAC,CAAC,EAAE,QAAQkC,GAAc,CAC1D,IAAMC,EAAiBnC,EAAG,gBAAgBkC,CAAU,EAC9CE,EAAiBpC,EAAG,SAASmC,EAAe,EAAE,EACpDF,EAAMA,EAAI,QAAQ,IAAI,OAAOG,EAAe,GAAI,GAAG,EACjDD,EAAe,EAAE,CACrB,CAAC,EACM,IAAI,sBAAsB,CAC/B,KAAMH,EAAY,KAClB,IAAAC,CACF,CAAC,CACH,CACA,SAASI,EAAwBrC,EAAIgC,EAAa,CAChD,IAAIC,EAAMD,EAAY,IACtB,cAAO,KAAKhC,EAAG,iBAAmB,CAAC,CAAC,EAAE,QAAQkC,GAAc,CAC1D,IAAMC,EAAiBnC,EAAG,gBAAgBkC,CAAU,EAC9CE,EAAiBpC,EAAG,SAASmC,EAAe,EAAE,EACpDF,EAAMA,EAAI,QAAQ,IAAI,OAAOE,EAAe,GAAI,GAAG,EACjDC,EAAe,EAAE,CACrB,CAAC,EACM,IAAI,sBAAsB,CAC/B,KAAMJ,EAAY,KAClB,IAAAC,CACF,CAAC,CACH,CACA,CAAC,cAAe,cAAc,EAAE,QAAQ,SAASK,EAAQ,CACvD,IAAMC,EAAepD,EAAO,kBAAkB,UAAUmD,CAAM,EACxDE,EAAY,CAAC,CAACF,CAAM,GAAI,CAC5B,IAAMG,EAAO,UAGb,OAFqB,UAAU,QAC3B,OAAO,UAAU,CAAC,GAAM,WAEnBF,EAAa,MAAM,KAAM,CAC7BP,GAAgB,CACf,IAAMU,EAAOX,EAAwB,KAAMC,CAAW,EACtDS,EAAK,CAAC,EAAE,MAAM,KAAM,CAACC,CAAI,CAAC,CAC5B,EACCzB,GAAQ,CACHwB,EAAK,CAAC,GACRA,EAAK,CAAC,EAAE,MAAM,KAAMxB,CAAG,CAE3B,EAAG,UAAU,CAAC,CAChB,CAAC,EAEIsB,EAAa,MAAM,KAAM,SAAS,EACtC,KAAKP,GAAeD,EAAwB,KAAMC,CAAW,CAAC,CACnE,CAAC,EACD7C,EAAO,kBAAkB,UAAUmD,CAAM,EAAIE,EAAUF,CAAM,CAC/D,CAAC,EAED,IAAMK,EACFxD,EAAO,kBAAkB,UAAU,oBACvCA,EAAO,kBAAkB,UAAU,oBACjC,UAA+B,CAC7B,MAAI,CAAC,UAAU,QAAU,CAAC,UAAU,CAAC,EAAE,KAC9BwD,EAAwB,MAAM,KAAM,SAAS,GAEtD,UAAU,CAAC,EAAIN,EAAwB,KAAM,UAAU,CAAC,CAAC,EAClDM,EAAwB,MAAM,KAAM,SAAS,EACtD,EAIF,IAAMC,EAAuB,OAAO,yBAClCzD,EAAO,kBAAkB,UAAW,kBAAkB,EACxD,OAAO,eAAeA,EAAO,kBAAkB,UAC7C,mBAAoB,CAClB,KAAM,CACJ,IAAM6C,EAAcY,EAAqB,IAAI,MAAM,IAAI,EACvD,OAAIZ,EAAY,OAAS,GAChBA,EAEFD,EAAwB,KAAMC,CAAW,CAClD,CACF,CAAC,EAEH7C,EAAO,kBAAkB,UAAU,YACjC,SAAqBgB,EAAQ,CAC3B,GAAI,KAAK,iBAAmB,SAC1B,MAAM,IAAI,aACR,sDACA,mBAAmB,EAIvB,GAAI,CAACA,EAAO,IACV,MAAM,IAAI,aAAa,yFAC2B,WAAW,EAG/D,GAAI,EADYA,EAAO,MAAQ,MAE7B,MAAM,IAAI,aAAa,6CACrB,oBAAoB,EAIxB,KAAK,SAAW,KAAK,UAAY,CAAC,EAClC,IAAID,EACJ,OAAO,KAAK,KAAK,QAAQ,EAAE,QAAQ2C,GAAY,CAC5B,KAAK,SAASA,CAAQ,EAAE,UAAU,EAChD,KAAKjD,GAASO,EAAO,QAAUP,CAAK,IAErCM,EAAS,KAAK,SAAS2C,CAAQ,EAEnC,CAAC,EAEG3C,IACEA,EAAO,UAAU,EAAE,SAAW,EAGhC,KAAK,aAAa,KAAK,gBAAgBA,EAAO,EAAE,CAAC,EAGjDA,EAAO,YAAYC,EAAO,KAAK,EAEjC,KAAK,cAAc,IAAI,MAAM,mBAAmB,CAAC,EAErD,CACJ,CAEO,SAAS2C,EAAmB3D,EAAQqC,EAAgB,CACrD,CAACrC,EAAO,mBAAqBA,EAAO,0BAEtCA,EAAO,kBAAoBA,EAAO,yBAE/BA,EAAO,mBAKRqC,EAAe,QAAU,IAC3B,CAAC,sBAAuB,uBAAwB,iBAAiB,EAC9D,QAAQ,SAASc,EAAQ,CACxB,IAAMC,EAAepD,EAAO,kBAAkB,UAAUmD,CAAM,EACxDE,EAAY,CAAC,CAACF,CAAM,GAAI,CAC5B,iBAAU,CAAC,EAAI,IAAMA,IAAW,kBAC9BnD,EAAO,gBACPA,EAAO,uBAAuB,UAAU,CAAC,CAAC,EACrCoD,EAAa,MAAM,KAAM,SAAS,CAC3C,CAAC,EACDpD,EAAO,kBAAkB,UAAUmD,CAAM,EAAIE,EAAUF,CAAM,CAC/D,CAAC,CAEP,CAGO,SAASS,GAAqB5D,EAAQqC,EAAgB,CACrD3B,EAAwBV,EAAQ,oBAAqBI,GAAK,CAC9D,IAAMS,EAAKT,EAAE,OACb,GAAI,GAAAiC,EAAe,QAAU,IAAOxB,EAAG,kBACnCA,EAAG,iBAAiB,EAAE,eAAiB,WACrCA,EAAG,iBAAmB,UAI5B,OAAOT,CACT,CAAC,CACH,CEznBA,IAAAyD,EAAA,GAAAC,EAAAD,EAAA,wBAAAE,GAAA,qBAAAC,GAAA,oBAAAC,GAAA,wBAAAC,GAAA,sBAAAC,GAAA,qBAAAC,EAAA,gBAAAC,GAAA,uBAAAC,EAAA,uBAAAC,GAAA,yBAAAC,GAAA,qBAAAC,GAAA,uBAAAC,KCYO,SAASC,EAAiBC,EAAQC,EAAgB,CACvD,IAAMC,EAAYF,GAAUA,EAAO,UAC7BG,EAAmBH,GAAUA,EAAO,iBAS1C,GAPAE,EAAU,aAAe,SAASE,EAAaC,EAAWC,EAAS,CAE3DC,EAAW,yBACf,qCAAqC,EACvCL,EAAU,aAAa,aAAaE,CAAW,EAAE,KAAKC,EAAWC,CAAO,CAC1E,EAEI,EAAEL,EAAe,QAAU,IAC3B,oBAAqBC,EAAU,aAAa,wBAAwB,GAAI,CAC1E,IAAMM,EAAQ,SAASC,EAAK,EAAGC,EAAG,CAC5B,KAAKD,GAAO,EAAEC,KAAKD,KACrBA,EAAIC,CAAC,EAAID,EAAI,CAAC,EACd,OAAOA,EAAI,CAAC,EAEhB,EAEME,EAAqBT,EAAU,aAAa,aAChD,KAAKA,EAAU,YAAY,EAU7B,GATAA,EAAU,aAAa,aAAe,SAASU,EAAG,CAChD,OAAI,OAAOA,GAAM,UAAY,OAAOA,EAAE,OAAU,WAC9CA,EAAI,KAAK,MAAM,KAAK,UAAUA,CAAC,CAAC,EAChCJ,EAAMI,EAAE,MAAO,kBAAmB,oBAAoB,EACtDJ,EAAMI,EAAE,MAAO,mBAAoB,qBAAqB,GAEnDD,EAAmBC,CAAC,CAC7B,EAEIT,GAAoBA,EAAiB,UAAU,YAAa,CAC9D,IAAMU,EAAoBV,EAAiB,UAAU,YACrDA,EAAiB,UAAU,YAAc,UAAW,CAClD,IAAMM,EAAMI,EAAkB,MAAM,KAAM,SAAS,EACnD,OAAAL,EAAMC,EAAK,qBAAsB,iBAAiB,EAClDD,EAAMC,EAAK,sBAAuB,kBAAkB,EAC7CA,CACT,CACF,CAEA,GAAIN,GAAoBA,EAAiB,UAAU,iBAAkB,CACnE,IAAMW,EACJX,EAAiB,UAAU,iBAC7BA,EAAiB,UAAU,iBAAmB,SAASS,EAAG,CACxD,OAAI,KAAK,OAAS,SAAW,OAAOA,GAAM,WACxCA,EAAI,KAAK,MAAM,KAAK,UAAUA,CAAC,CAAC,EAChCJ,EAAMI,EAAG,kBAAmB,oBAAoB,EAChDJ,EAAMI,EAAG,mBAAoB,qBAAqB,GAE7CE,EAAuB,MAAM,KAAM,CAACF,CAAC,CAAC,CAC/C,CACF,CACF,CACF,CCxDO,SAASG,GAAoBC,EAAQC,EAAsB,CAC5DD,EAAO,UAAU,cACnB,oBAAqBA,EAAO,UAAU,cAGlCA,EAAO,UAAU,eAGvBA,EAAO,UAAU,aAAa,gBAC5B,SAAyBE,EAAa,CACpC,GAAI,EAAEA,GAAeA,EAAY,OAAQ,CACvC,IAAMC,EAAM,IAAI,aAAa,wDACC,EAC9B,OAAAA,EAAI,KAAO,gBAEXA,EAAI,KAAO,EACJ,QAAQ,OAAOA,CAAG,CAC3B,CACA,OAAID,EAAY,QAAU,GACxBA,EAAY,MAAQ,CAAC,YAAaD,CAAoB,EAEtDC,EAAY,MAAM,YAAcD,EAE3BD,EAAO,UAAU,aAAa,aAAaE,CAAW,CAC/D,EACJ,CFrBO,SAASE,GAAYC,EAAQ,CAC9B,OAAOA,GAAW,UAAYA,EAAO,eACpC,aAAcA,EAAO,cAAc,WACpC,EAAE,gBAAiBA,EAAO,cAAc,YAC1C,OAAO,eAAeA,EAAO,cAAc,UAAW,cAAe,CACnE,KAAM,CACJ,MAAO,CAAC,SAAU,KAAK,QAAQ,CACjC,CACF,CAAC,CAEL,CAEO,SAASC,EAAmBD,EAAQE,EAAgB,CACzD,GAAI,OAAOF,GAAW,UAClB,EAAEA,EAAO,mBAAqBA,EAAO,sBACvC,OAEE,CAACA,EAAO,mBAAqBA,EAAO,uBAEtCA,EAAO,kBAAoBA,EAAO,sBAGhCE,EAAe,QAAU,IAE3B,CAAC,sBAAuB,uBAAwB,iBAAiB,EAC9D,QAAQ,SAASC,EAAQ,CACxB,IAAMC,EAAeJ,EAAO,kBAAkB,UAAUG,CAAM,EACxDE,EAAY,CAAC,CAACF,CAAM,GAAI,CAC5B,iBAAU,CAAC,EAAI,IAAMA,IAAW,kBAC9BH,EAAO,gBACPA,EAAO,uBAAuB,UAAU,CAAC,CAAC,EACrCI,EAAa,MAAM,KAAM,SAAS,CAC3C,CAAC,EACDJ,EAAO,kBAAkB,UAAUG,CAAM,EAAIE,EAAUF,CAAM,CAC/D,CAAC,EAGL,IAAMG,EAAmB,CACvB,WAAY,cACZ,YAAa,eACb,cAAe,iBACf,eAAgB,kBAChB,gBAAiB,kBACnB,EAEMC,EAAiBP,EAAO,kBAAkB,UAAU,SAC1DA,EAAO,kBAAkB,UAAU,SAAW,UAAoB,CAChE,GAAM,CAACQ,EAAUC,EAAQC,CAAK,EAAI,UAClC,OAAOH,EAAe,MAAM,KAAM,CAACC,GAAY,IAAI,CAAC,EACjD,KAAKG,GAAS,CACb,GAAIT,EAAe,QAAU,IAAM,CAACO,EAGlC,GAAI,CACFE,EAAM,QAAQC,GAAQ,CACpBA,EAAK,KAAON,EAAiBM,EAAK,IAAI,GAAKA,EAAK,IAClD,CAAC,CACH,OAASC,EAAG,CACV,GAAIA,EAAE,OAAS,YACb,MAAMA,EAGRF,EAAM,QAAQ,CAACC,EAAME,IAAM,CACzBH,EAAM,IAAIG,EAAG,OAAO,OAAO,CAAC,EAAGF,EAAM,CACnC,KAAMN,EAAiBM,EAAK,IAAI,GAAKA,EAAK,IAC5C,CAAC,CAAC,CACJ,CAAC,CACH,CAEF,OAAOD,CACT,CAAC,EACA,KAAKF,EAAQC,CAAK,CACvB,CACF,CAEO,SAASK,GAAmBf,EAAQ,CAKzC,GAJI,EAAE,OAAOA,GAAW,UAAYA,EAAO,mBACvCA,EAAO,eAGPA,EAAO,cAAgB,aAAcA,EAAO,aAAa,UAC3D,OAEF,IAAMgB,EAAiBhB,EAAO,kBAAkB,UAAU,WACtDgB,IACFhB,EAAO,kBAAkB,UAAU,WAAa,UAAsB,CACpE,IAAMiB,EAAUD,EAAe,MAAM,KAAM,CAAC,CAAC,EAC7C,OAAAC,EAAQ,QAAQC,GAAUA,EAAO,IAAM,IAAI,EACpCD,CACT,GAGF,IAAME,EAAenB,EAAO,kBAAkB,UAAU,SACpDmB,IACFnB,EAAO,kBAAkB,UAAU,SAAW,UAAoB,CAChE,IAAMkB,EAASC,EAAa,MAAM,KAAM,SAAS,EACjD,OAAAD,EAAO,IAAM,KACNA,CACT,GAEFlB,EAAO,aAAa,UAAU,SAAW,UAAoB,CAC3D,OAAO,KAAK,MAAQ,KAAK,IAAI,SAAS,KAAK,KAAK,EAC9C,QAAQ,QAAQ,IAAI,GAAK,CAC7B,CACF,CAEO,SAASoB,GAAqBpB,EAAQ,CAK3C,GAJI,EAAE,OAAOA,GAAW,UAAYA,EAAO,mBACvCA,EAAO,eAGPA,EAAO,cAAgB,aAAcA,EAAO,eAAe,UAC7D,OAEF,IAAMqB,EAAmBrB,EAAO,kBAAkB,UAAU,aACxDqB,IACFrB,EAAO,kBAAkB,UAAU,aAAe,UAAwB,CACxE,IAAMsB,EAAYD,EAAiB,MAAM,KAAM,CAAC,CAAC,EACjD,OAAAC,EAAU,QAAQC,GAAYA,EAAS,IAAM,IAAI,EAC1CD,CACT,GAEIE,EAAwBxB,EAAQ,QAASa,IAC7CA,EAAE,SAAS,IAAMA,EAAE,WACZA,EACR,EACDb,EAAO,eAAe,UAAU,SAAW,UAAoB,CAC7D,OAAO,KAAK,IAAI,SAAS,KAAK,KAAK,CACrC,CACF,CAEO,SAASyB,GAAiBzB,EAAQ,CACnC,CAACA,EAAO,mBACR,iBAAkBA,EAAO,kBAAkB,YAG/CA,EAAO,kBAAkB,UAAU,aACjC,SAAsB0B,EAAQ,CACtBC,EAAW,eAAgB,aAAa,EAC9C,KAAK,WAAW,EAAE,QAAQT,GAAU,CAC9BA,EAAO,OAASQ,EAAO,UAAU,EAAE,SAASR,EAAO,KAAK,GAC1D,KAAK,YAAYA,CAAM,CAE3B,CAAC,CACH,EACJ,CAEO,SAASU,GAAmB5B,EAAQ,CAGrCA,EAAO,aAAe,CAACA,EAAO,iBAChCA,EAAO,eAAiBA,EAAO,YAEnC,CAEO,SAAS6B,GAAmB7B,EAAQ,CAIzC,GAAI,EAAE,OAAOA,GAAW,UAAYA,EAAO,mBACzC,OAEF,IAAM8B,EAAqB9B,EAAO,kBAAkB,UAAU,eAC1D8B,IACF9B,EAAO,kBAAkB,UAAU,eACjC,UAA0B,CACxB,KAAK,sBAAwB,CAAC,EAE9B,IAAI+B,EAAgB,UAAU,CAAC,GAAK,UAAU,CAAC,EAAE,cAC7CA,IAAkB,SACpBA,EAAgB,CAAC,GAEnBA,EAAgB,CAAC,GAAGA,CAAa,EACjC,IAAMC,EAAqBD,EAAc,OAAS,EAC9CC,GAEFD,EAAc,QAASE,GAAkB,CACvC,GAAI,QAASA,GAEP,CADa,oBACH,KAAKA,EAAc,GAAG,EAClC,MAAM,IAAI,UAAU,6BAA6B,EAGrD,GAAI,0BAA2BA,GACzB,EAAE,WAAWA,EAAc,qBAAqB,GAAK,GACvD,MAAM,IAAI,WAAW,yCAAyC,EAGlE,GAAI,iBAAkBA,GAChB,EAAE,WAAWA,EAAc,YAAY,GAAK,GAC9C,MAAM,IAAI,WAAW,8BAA8B,CAGzD,CAAC,EAEH,IAAMC,EAAcJ,EAAmB,MAAM,KAAM,SAAS,EAC5D,GAAIE,EAAoB,CAQtB,GAAM,CAAC,OAAAd,CAAM,EAAIgB,EACXC,EAASjB,EAAO,cAAc,GAChC,EAAE,cAAeiB,IAEhBA,EAAO,UAAU,SAAW,GAC5B,OAAO,KAAKA,EAAO,UAAU,CAAC,CAAC,EAAE,SAAW,KAC/CA,EAAO,UAAYJ,EACnBb,EAAO,cAAgBa,EACvB,KAAK,sBAAsB,KAAKb,EAAO,cAAciB,CAAM,EACxD,KAAK,IAAM,CACV,OAAOjB,EAAO,aAChB,CAAC,EAAE,MAAM,IAAM,CACb,OAAOA,EAAO,aAChB,CAAC,CACH,EAEJ,CACA,OAAOgB,CACT,EAEN,CAEO,SAASE,GAAkBpC,EAAQ,CACxC,GAAI,EAAE,OAAOA,GAAW,UAAYA,EAAO,cACzC,OAEF,IAAMqC,EAAoBrC,EAAO,aAAa,UAAU,cACpDqC,IACFrC,EAAO,aAAa,UAAU,cAC5B,UAAyB,CACvB,IAAMmC,EAASE,EAAkB,MAAM,KAAM,SAAS,EACtD,MAAM,cAAeF,IACnBA,EAAO,UAAY,CAAC,EAAE,OAAO,KAAK,eAAiB,CAAC,CAAC,CAAC,CAAC,GAElDA,CACT,EAEN,CAEO,SAASG,GAAgBtC,EAAQ,CAItC,GAAI,EAAE,OAAOA,GAAW,UAAYA,EAAO,mBACzC,OAEF,IAAMuC,EAAkBvC,EAAO,kBAAkB,UAAU,YAC3DA,EAAO,kBAAkB,UAAU,YAAc,UAAuB,CACtE,OAAI,KAAK,uBAAyB,KAAK,sBAAsB,OACpD,QAAQ,IAAI,KAAK,qBAAqB,EAC1C,KAAK,IACGuC,EAAgB,MAAM,KAAM,SAAS,CAC7C,EACA,QAAQ,IAAM,CACb,KAAK,sBAAwB,CAAC,CAChC,CAAC,EAEEA,EAAgB,MAAM,KAAM,SAAS,CAC9C,CACF,CAEO,SAASC,GAAiBxC,EAAQ,CAIvC,GAAI,EAAE,OAAOA,GAAW,UAAYA,EAAO,mBACzC,OAEF,IAAMyC,EAAmBzC,EAAO,kBAAkB,UAAU,aAC5DA,EAAO,kBAAkB,UAAU,aAAe,UAAwB,CACxE,OAAI,KAAK,uBAAyB,KAAK,sBAAsB,OACpD,QAAQ,IAAI,KAAK,qBAAqB,EAC1C,KAAK,IACGyC,EAAiB,MAAM,KAAM,SAAS,CAC9C,EACA,QAAQ,IAAM,CACb,KAAK,sBAAwB,CAAC,CAChC,CAAC,EAEEA,EAAiB,MAAM,KAAM,SAAS,CAC/C,CACF,CG3SA,IAAAC,EAAA,GAAAC,EAAAD,EAAA,sBAAAE,GAAA,qBAAAC,GAAA,oBAAAC,GAAA,0BAAAC,GAAA,qBAAAC,GAAA,wBAAAC,GAAA,yBAAAC,GAAA,yBAAAC,GAAA,8BAAAC,KAUO,SAASC,GAAoBC,EAAQ,CAC1C,GAAI,SAAOA,GAAW,UAAY,CAACA,EAAO,mBAY1C,IATM,oBAAqBA,EAAO,kBAAkB,YAClDA,EAAO,kBAAkB,UAAU,gBACjC,UAA2B,CACzB,OAAK,KAAK,gBACR,KAAK,cAAgB,CAAC,GAEjB,KAAK,aACd,GAEA,EAAE,cAAeA,EAAO,kBAAkB,WAAY,CACxD,IAAMC,EAAYD,EAAO,kBAAkB,UAAU,SACrDA,EAAO,kBAAkB,UAAU,UAAY,SAAmBE,EAAQ,CACnE,KAAK,gBACR,KAAK,cAAgB,CAAC,GAEnB,KAAK,cAAc,SAASA,CAAM,GACrC,KAAK,cAAc,KAAKA,CAAM,EAIhCA,EAAO,eAAe,EAAE,QAAQC,GAASF,EAAU,KAAK,KAAME,EAC5DD,CAAM,CAAC,EACTA,EAAO,eAAe,EAAE,QAAQC,GAASF,EAAU,KAAK,KAAME,EAC5DD,CAAM,CAAC,CACX,EAEAF,EAAO,kBAAkB,UAAU,SACjC,SAAkBG,KAAUC,EAAS,CACnC,OAAIA,GACFA,EAAQ,QAASF,GAAW,CACrB,KAAK,cAEE,KAAK,cAAc,SAASA,CAAM,GAC5C,KAAK,cAAc,KAAKA,CAAM,EAF9B,KAAK,cAAgB,CAACA,CAAM,CAIhC,CAAC,EAEID,EAAU,MAAM,KAAM,SAAS,CACxC,CACJ,CACM,iBAAkBD,EAAO,kBAAkB,YAC/CA,EAAO,kBAAkB,UAAU,aACjC,SAAsBE,EAAQ,CACvB,KAAK,gBACR,KAAK,cAAgB,CAAC,GAExB,IAAMG,EAAQ,KAAK,cAAc,QAAQH,CAAM,EAC/C,GAAIG,IAAU,GACZ,OAEF,KAAK,cAAc,OAAOA,EAAO,CAAC,EAClC,IAAMC,EAASJ,EAAO,UAAU,EAChC,KAAK,WAAW,EAAE,QAAQK,GAAU,CAC9BD,EAAO,SAASC,EAAO,KAAK,GAC9B,KAAK,YAAYA,CAAM,CAE3B,CAAC,CACH,GAEN,CAEO,SAASC,GAAqBR,EAAQ,CAC3C,GAAI,SAAOA,GAAW,UAAY,CAACA,EAAO,qBAGpC,qBAAsBA,EAAO,kBAAkB,YACnDA,EAAO,kBAAkB,UAAU,iBACjC,UAA4B,CAC1B,OAAO,KAAK,eAAiB,KAAK,eAAiB,CAAC,CACtD,GAEA,EAAE,gBAAiBA,EAAO,kBAAkB,YAAY,CAC1D,OAAO,eAAeA,EAAO,kBAAkB,UAAW,cAAe,CACvE,KAAM,CACJ,OAAO,KAAK,YACd,EACA,IAAIS,EAAG,CACD,KAAK,eACP,KAAK,oBAAoB,YAAa,KAAK,YAAY,EACvD,KAAK,oBAAoB,QAAS,KAAK,gBAAgB,GAEzD,KAAK,iBAAiB,YAAa,KAAK,aAAeA,CAAC,EACxD,KAAK,iBAAiB,QAAS,KAAK,iBAAoBC,GAAM,CAC5DA,EAAE,QAAQ,QAAQR,GAAU,CAI1B,GAHK,KAAK,iBACR,KAAK,eAAiB,CAAC,GAErB,KAAK,eAAe,SAASA,CAAM,EACrC,OAEF,KAAK,eAAe,KAAKA,CAAM,EAC/B,IAAMS,EAAQ,IAAI,MAAM,WAAW,EACnCA,EAAM,OAAST,EACf,KAAK,cAAcS,CAAK,CAC1B,CAAC,CACH,CAAC,CACH,CACF,CAAC,EACD,IAAMC,EACJZ,EAAO,kBAAkB,UAAU,qBACrCA,EAAO,kBAAkB,UAAU,qBACjC,UAAgC,CAC9B,IAAMa,EAAK,KACX,OAAK,KAAK,kBACR,KAAK,iBAAiB,QAAS,KAAK,iBAAmB,SAASH,EAAG,CACjEA,EAAE,QAAQ,QAAQR,GAAU,CAI1B,GAHKW,EAAG,iBACNA,EAAG,eAAiB,CAAC,GAEnBA,EAAG,eAAe,QAAQX,CAAM,GAAK,EACvC,OAEFW,EAAG,eAAe,KAAKX,CAAM,EAC7B,IAAMS,EAAQ,IAAI,MAAM,WAAW,EACnCA,EAAM,OAAST,EACfW,EAAG,cAAcF,CAAK,CACxB,CAAC,CACH,CAAC,EAEIC,EAAyB,MAAMC,EAAI,SAAS,CACrD,CACJ,CACF,CAEO,SAASC,GAAiBd,EAAQ,CACvC,GAAI,OAAOA,GAAW,UAAY,CAACA,EAAO,kBACxC,OAEF,IAAMe,EAAYf,EAAO,kBAAkB,UACrCgB,EAAkBD,EAAU,YAC5BE,EAAmBF,EAAU,aAC7BG,EAAsBH,EAAU,oBAChCI,EAAuBJ,EAAU,qBACjCK,EAAkBL,EAAU,gBAElCA,EAAU,YACR,SAAqBM,EAAiBC,EAAiB,CACrD,IAAMC,EAAW,UAAU,QAAU,EAAK,UAAU,CAAC,EAAI,UAAU,CAAC,EAC9DC,EAAUR,EAAgB,MAAM,KAAM,CAACO,CAAO,CAAC,EACrD,OAAKD,GAGLE,EAAQ,KAAKH,EAAiBC,CAAe,EACtC,QAAQ,QAAQ,GAHdE,CAIX,EAEFT,EAAU,aACR,SAAsBM,EAAiBC,EAAiB,CACtD,IAAMC,EAAW,UAAU,QAAU,EAAK,UAAU,CAAC,EAAI,UAAU,CAAC,EAC9DC,EAAUP,EAAiB,MAAM,KAAM,CAACM,CAAO,CAAC,EACtD,OAAKD,GAGLE,EAAQ,KAAKH,EAAiBC,CAAe,EACtC,QAAQ,QAAQ,GAHdE,CAIX,EAEF,IAAIC,EAAe,SAASC,EAAaL,EAAiBC,EAAiB,CACzE,IAAME,EAAUN,EAAoB,MAAM,KAAM,CAACQ,CAAW,CAAC,EAC7D,OAAKJ,GAGLE,EAAQ,KAAKH,EAAiBC,CAAe,EACtC,QAAQ,QAAQ,GAHdE,CAIX,EACAT,EAAU,oBAAsBU,EAEhCA,EAAe,SAASC,EAAaL,EAAiBC,EAAiB,CACrE,IAAME,EAAUL,EAAqB,MAAM,KAAM,CAACO,CAAW,CAAC,EAC9D,OAAKJ,GAGLE,EAAQ,KAAKH,EAAiBC,CAAe,EACtC,QAAQ,QAAQ,GAHdE,CAIX,EACAT,EAAU,qBAAuBU,EAEjCA,EAAe,SAASE,EAAWN,EAAiBC,EAAiB,CACnE,IAAME,EAAUJ,EAAgB,MAAM,KAAM,CAACO,CAAS,CAAC,EACvD,OAAKL,GAGLE,EAAQ,KAAKH,EAAiBC,CAAe,EACtC,QAAQ,QAAQ,GAHdE,CAIX,EACAT,EAAU,gBAAkBU,CAC9B,CAEO,SAASG,GAAiB5B,EAAQ,CACvC,IAAM6B,EAAY7B,GAAUA,EAAO,UAEnC,GAAI6B,EAAU,cAAgBA,EAAU,aAAa,aAAc,CAEjE,IAAMC,EAAeD,EAAU,aACzBE,EAAgBD,EAAa,aAAa,KAAKA,CAAY,EACjED,EAAU,aAAa,aAAgBG,GAC9BD,EAAcE,GAAgBD,CAAW,CAAC,CAErD,CAEI,CAACH,EAAU,cAAgBA,EAAU,cACvCA,EAAU,aAAa,eACvBA,EAAU,aAAe,SAAsBG,EAAaE,EAAIC,EAAO,CACrEN,EAAU,aAAa,aAAaG,CAAW,EAC5C,KAAKE,EAAIC,CAAK,CACnB,EAAE,KAAKN,CAAS,EAEpB,CAEO,SAASI,GAAgBD,EAAa,CAC3C,OAAIA,GAAeA,EAAY,QAAU,OAChC,OAAO,OAAO,CAAC,EACpBA,EACA,CAAC,MAAaI,GAAcJ,EAAY,KAAK,CAAC,CAChD,EAGKA,CACT,CAEO,SAASK,GAAqBrC,EAAQ,CAC3C,GAAI,CAACA,EAAO,kBACV,OAGF,IAAMsC,EAAqBtC,EAAO,kBAClCA,EAAO,kBACL,SAA2BuC,EAAUC,EAAe,CAClD,GAAID,GAAYA,EAAS,WAAY,CACnC,IAAME,EAAgB,CAAC,EACvB,QAASC,EAAI,EAAGA,EAAIH,EAAS,WAAW,OAAQG,IAAK,CACnD,IAAIC,EAASJ,EAAS,WAAWG,CAAC,EAC9BC,EAAO,OAAS,QAAaA,EAAO,KAChCC,EAAW,mBAAoB,mBAAmB,EACxDD,EAAS,KAAK,MAAM,KAAK,UAAUA,CAAM,CAAC,EAC1CA,EAAO,KAAOA,EAAO,IACrB,OAAOA,EAAO,IACdF,EAAc,KAAKE,CAAM,GAEzBF,EAAc,KAAKF,EAAS,WAAWG,CAAC,CAAC,CAE7C,CACAH,EAAS,WAAaE,CACxB,CACA,OAAO,IAAIH,EAAmBC,EAAUC,CAAa,CACvD,EACFxC,EAAO,kBAAkB,UAAYsC,EAAmB,UAEpD,wBAAyBA,GAC3B,OAAO,eAAetC,EAAO,kBAAmB,sBAAuB,CACrE,KAAM,CACJ,OAAOsC,EAAmB,mBAC5B,CACF,CAAC,CAEL,CAEO,SAASO,GAA0B7C,EAAQ,CAE5C,OAAOA,GAAW,UAAYA,EAAO,eACrC,aAAcA,EAAO,cAAc,WACnC,EAAE,gBAAiBA,EAAO,cAAc,YAC1C,OAAO,eAAeA,EAAO,cAAc,UAAW,cAAe,CACnE,KAAM,CACJ,MAAO,CAAC,SAAU,KAAK,QAAQ,CACjC,CACF,CAAC,CAEL,CAEO,SAAS8C,GAAsB9C,EAAQ,CAC5C,IAAMgB,EAAkBhB,EAAO,kBAAkB,UAAU,YAC3DA,EAAO,kBAAkB,UAAU,YACjC,SAAqB+C,EAAc,CACjC,GAAIA,EAAc,CACZ,OAAOA,EAAa,oBAAwB,MAE9CA,EAAa,oBACX,CAAC,CAACA,EAAa,qBAEnB,IAAMC,EAAmB,KAAK,gBAAgB,EAAE,KAAKC,GACnDA,EAAY,SAAS,MAAM,OAAS,OAAO,EACzCF,EAAa,sBAAwB,IAASC,EAC5CA,EAAiB,YAAc,WAC7BA,EAAiB,aACnBA,EAAiB,aAAa,UAAU,EAExCA,EAAiB,UAAY,WAEtBA,EAAiB,YAAc,aACpCA,EAAiB,aACnBA,EAAiB,aAAa,UAAU,EAExCA,EAAiB,UAAY,YAGxBD,EAAa,sBAAwB,IAC5C,CAACC,GACH,KAAK,eAAe,QAAS,CAAC,UAAW,UAAU,CAAC,EAGlD,OAAOD,EAAa,oBAAwB,MAE9CA,EAAa,oBACX,CAAC,CAACA,EAAa,qBAEnB,IAAMG,EAAmB,KAAK,gBAAgB,EAAE,KAAKD,GACnDA,EAAY,SAAS,MAAM,OAAS,OAAO,EACzCF,EAAa,sBAAwB,IAASG,EAC5CA,EAAiB,YAAc,WAC7BA,EAAiB,aACnBA,EAAiB,aAAa,UAAU,EAExCA,EAAiB,UAAY,WAEtBA,EAAiB,YAAc,aACpCA,EAAiB,aACnBA,EAAiB,aAAa,UAAU,EAExCA,EAAiB,UAAY,YAGxBH,EAAa,sBAAwB,IAC5C,CAACG,GACH,KAAK,eAAe,QAAS,CAAC,UAAW,UAAU,CAAC,CAExD,CACA,OAAOlC,EAAgB,MAAM,KAAM,SAAS,CAC9C,CACJ,CAEO,SAASmC,GAAiBnD,EAAQ,CACnC,OAAOA,GAAW,UAAYA,EAAO,eAGzCA,EAAO,aAAeA,EAAO,mBAC/B,CC9VA,IAAAoD,GAAA,GAAAC,EAAAD,GAAA,4BAAAE,EAAA,mCAAAC,EAAA,wBAAAC,EAAA,uBAAAC,EAAA,yCAAAC,EAAA,wBAAAC,EAAA,qCAAAC,EAAA,2BAAAC,IAUA,IAAAC,EAAqB,SAGd,SAASC,EAAoBC,EAAQ,CAG1C,GAAI,CAACA,EAAO,iBAAoBA,EAAO,iBAAmB,eACtDA,EAAO,gBAAgB,UACzB,OAGF,IAAMC,EAAwBD,EAAO,gBACrCA,EAAO,gBAAkB,SAAyBE,EAAM,CAQtD,GANI,OAAOA,GAAS,UAAYA,EAAK,WACjCA,EAAK,UAAU,QAAQ,IAAI,IAAM,IACnCA,EAAO,KAAK,MAAM,KAAK,UAAUA,CAAI,CAAC,EACtCA,EAAK,UAAYA,EAAK,UAAU,UAAU,CAAC,GAGzCA,EAAK,WAAaA,EAAK,UAAU,OAAQ,CAE3C,IAAMC,EAAkB,IAAIF,EAAsBC,CAAI,EAChDE,EAAkB,EAAAC,QAAS,eAAeH,EAAK,SAAS,EAC9D,QAAWI,KAAOF,EACVE,KAAOH,GACX,OAAO,eAAeA,EAAiBG,EACrC,CAAC,MAAOF,EAAgBE,CAAG,CAAC,CAAC,EAKnC,OAAAH,EAAgB,OAAS,UAAkB,CACzC,MAAO,CACL,UAAWA,EAAgB,UAC3B,OAAQA,EAAgB,OACxB,cAAeA,EAAgB,cAC/B,iBAAkBA,EAAgB,gBACpC,CACF,EACOA,CACT,CACA,OAAO,IAAIF,EAAsBC,CAAI,CACvC,EACAF,EAAO,gBAAgB,UAAYC,EAAsB,UAInDM,EAAwBP,EAAQ,eAAgBQ,IAChDA,EAAE,WACJ,OAAO,eAAeA,EAAG,YAAa,CACpC,MAAO,IAAIR,EAAO,gBAAgBQ,EAAE,SAAS,EAC7C,SAAU,OACZ,CAAC,EAEIA,EACR,CACH,CAEO,SAASC,EAAiCT,EAAQ,CACnD,CAACA,EAAO,iBAAoBA,EAAO,iBAAmB,kBACtDA,EAAO,gBAAgB,WAMrBO,EAAwBP,EAAQ,eAAgBQ,GAAK,CACzD,GAAIA,EAAE,UAAW,CACf,IAAMJ,EAAkB,EAAAC,QAAS,eAAeG,EAAE,UAAU,SAAS,EACjEJ,EAAgB,OAAS,UAG3BI,EAAE,UAAU,cAAgB,CAC1B,EAAG,MACH,EAAG,MACH,EAAG,KACL,EAAEJ,EAAgB,UAAY,EAAE,EAEpC,CACA,OAAOI,CACT,CAAC,CACH,CAEO,SAASE,EAAmBV,EAAQW,EAAgB,CACzD,GAAI,CAACX,EAAO,kBACV,OAGI,SAAUA,EAAO,kBAAkB,WACvC,OAAO,eAAeA,EAAO,kBAAkB,UAAW,OAAQ,CAChE,KAAM,CACJ,OAAO,OAAO,KAAK,MAAU,IAAc,KAAO,KAAK,KACzD,CACF,CAAC,EAGH,IAAMY,EAAoB,SAASC,EAAa,CAC9C,GAAI,CAACA,GAAe,CAACA,EAAY,IAC/B,MAAO,GAET,IAAMC,EAAW,EAAAT,QAAS,cAAcQ,EAAY,GAAG,EACvD,OAAAC,EAAS,MAAM,EACRA,EAAS,KAAKC,GAAgB,CACnC,IAAMC,EAAQ,EAAAX,QAAS,WAAWU,CAAY,EAC9C,OAAOC,GAASA,EAAM,OAAS,eACxBA,EAAM,SAAS,QAAQ,MAAM,IAAM,EAC5C,CAAC,CACH,EAEMC,EAA0B,SAASJ,EAAa,CAEpD,IAAMK,EAAQL,EAAY,IAAI,MAAM,iCAAiC,EACrE,GAAIK,IAAU,MAAQA,EAAM,OAAS,EACnC,MAAO,GAET,IAAMC,EAAU,SAASD,EAAM,CAAC,EAAG,EAAE,EAErC,OAAOC,IAAYA,EAAU,GAAKA,CACpC,EAEMC,EAA2B,SAASC,EAAiB,CAKzD,IAAIC,EAAwB,MAC5B,OAAIX,EAAe,UAAY,YACzBA,EAAe,QAAU,GACvBU,IAAoB,GAGtBC,EAAwB,MAIxBA,EAAwB,WAEjBX,EAAe,QAAU,GAKlCW,EACEX,EAAe,UAAY,GAAK,MAAQ,MAG1CW,EAAwB,YAGrBA,CACT,EAEMC,EAAoB,SAASV,EAAaQ,EAAiB,CAG/D,IAAIG,EAAiB,MAKjBb,EAAe,UAAY,WACvBA,EAAe,UAAY,KACjCa,EAAiB,OAGnB,IAAMN,EAAQ,EAAAb,QAAS,YAAYQ,EAAY,IAC7C,qBAAqB,EACvB,OAAIK,EAAM,OAAS,EACjBM,EAAiB,SAASN,EAAM,CAAC,EAAE,UAAU,EAAE,EAAG,EAAE,EAC3CP,EAAe,UAAY,WAC1BU,IAAoB,KAI9BG,EAAiB,YAEZA,CACT,EAEMC,EACFzB,EAAO,kBAAkB,UAAU,qBACvCA,EAAO,kBAAkB,UAAU,qBACjC,UAAgC,CAK9B,GAJA,KAAK,MAAQ,KAITW,EAAe,UAAY,UAAYA,EAAe,SAAW,GAAI,CACvE,GAAM,CAAC,aAAAe,CAAY,EAAI,KAAK,iBAAiB,EACzCA,IAAiB,UACnB,OAAO,eAAe,KAAM,OAAQ,CAClC,KAAM,CACJ,OAAO,OAAO,KAAK,MAAU,IAAc,KAAO,KAAK,KACzD,EACA,WAAY,GACZ,aAAc,EAChB,CAAC,CAEL,CAEA,GAAId,EAAkB,UAAU,CAAC,CAAC,EAAG,CAEnC,IAAMe,EAAYV,EAAwB,UAAU,CAAC,CAAC,EAGhDW,EAAaR,EAAyBO,CAAS,EAG/CE,EAAYN,EAAkB,UAAU,CAAC,EAAGI,CAAS,EAGvDH,EACAI,IAAe,GAAKC,IAAc,EACpCL,EAAiB,OAAO,kBACfI,IAAe,GAAKC,IAAc,EAC3CL,EAAiB,KAAK,IAAII,EAAYC,CAAS,EAE/CL,EAAiB,KAAK,IAAII,EAAYC,CAAS,EAKjD,IAAMC,EAAO,CAAC,EACd,OAAO,eAAeA,EAAM,iBAAkB,CAC5C,KAAM,CACJ,OAAON,CACT,CACF,CAAC,EACD,KAAK,MAAQM,CACf,CAEA,OAAOL,EAAyB,MAAM,KAAM,SAAS,CACvD,CACJ,CAEO,SAASM,EAAuB/B,EAAQ,CAC7C,GAAI,EAAEA,EAAO,mBACT,sBAAuBA,EAAO,kBAAkB,WAClD,OAOF,SAASgC,EAAWC,EAAIC,EAAI,CAC1B,IAAMC,EAAsBF,EAAG,KAC/BA,EAAG,KAAO,UAAgB,CACxB,IAAMG,EAAO,UAAU,CAAC,EAClBC,EAASD,EAAK,QAAUA,EAAK,MAAQA,EAAK,WAChD,GAAIH,EAAG,aAAe,QAClBC,EAAG,MAAQG,EAASH,EAAG,KAAK,eAC9B,MAAM,IAAI,UAAU,4CAClBA,EAAG,KAAK,eAAiB,SAAS,EAEtC,OAAOC,EAAoB,MAAMF,EAAI,SAAS,CAChD,CACF,CACA,IAAMK,EACJtC,EAAO,kBAAkB,UAAU,kBACrCA,EAAO,kBAAkB,UAAU,kBACjC,UAA6B,CAC3B,IAAMuC,EAAcD,EAAsB,MAAM,KAAM,SAAS,EAC/D,OAAAN,EAAWO,EAAa,IAAI,EACrBA,CACT,EACIhC,EAAwBP,EAAQ,cAAeQ,IACnDwB,EAAWxB,EAAE,QAASA,EAAE,MAAM,EACvBA,EACR,CACH,CAUO,SAASgC,EAAoBxC,EAAQ,CAC1C,GAAI,CAACA,EAAO,mBACR,oBAAqBA,EAAO,kBAAkB,UAChD,OAEF,IAAMyC,EAAQzC,EAAO,kBAAkB,UACvC,OAAO,eAAeyC,EAAO,kBAAmB,CAC9C,KAAM,CACJ,MAAO,CACL,UAAW,YACX,SAAU,YACZ,EAAE,KAAK,kBAAkB,GAAK,KAAK,kBACrC,EACA,WAAY,GACZ,aAAc,EAChB,CAAC,EACD,OAAO,eAAeA,EAAO,0BAA2B,CACtD,KAAM,CACJ,OAAO,KAAK,0BAA4B,IAC1C,EACA,IAAIC,EAAI,CACF,KAAK,2BACP,KAAK,oBAAoB,wBACvB,KAAK,wBAAwB,EAC/B,OAAO,KAAK,0BAEVA,GACF,KAAK,iBAAiB,wBACpB,KAAK,yBAA2BA,CAAE,CAExC,EACA,WAAY,GACZ,aAAc,EAChB,CAAC,EAED,CAAC,sBAAuB,sBAAsB,EAAE,QAASC,GAAW,CAClE,IAAMC,EAAaH,EAAME,CAAM,EAC/BF,EAAME,CAAM,EAAI,UAAW,CACzB,OAAK,KAAK,6BACR,KAAK,2BAA6BnC,GAAK,CACrC,IAAM0B,EAAK1B,EAAE,OACb,GAAI0B,EAAG,uBAAyBA,EAAG,gBAAiB,CAClDA,EAAG,qBAAuBA,EAAG,gBAC7B,IAAMW,EAAW,IAAI,MAAM,wBAAyBrC,CAAC,EACrD0B,EAAG,cAAcW,CAAQ,CAC3B,CACA,OAAOrC,CACT,EACA,KAAK,iBAAiB,2BACpB,KAAK,0BAA0B,GAE5BoC,EAAW,MAAM,KAAM,SAAS,CACzC,CACF,CAAC,CACH,CAEO,SAASE,EAAuB9C,EAAQW,EAAgB,CAQ7D,GANI,CAACX,EAAO,mBAGRW,EAAe,UAAY,UAAYA,EAAe,SAAW,IAGjEA,EAAe,UAAY,UAAYA,EAAe,SAAW,IACnE,OAEF,IAAMoC,EAAY/C,EAAO,kBAAkB,UAAU,qBACrDA,EAAO,kBAAkB,UAAU,qBACnC,SAA8BgD,EAAM,CAClC,GAAIA,GAAQA,EAAK,KAAOA,EAAK,IAAI,QAAQ;AAAA,qBAAwB,IAAM,GAAI,CACzE,IAAMC,EAAMD,EAAK,IAAI,MAAM;AAAA,CAAI,EAAE,OAAQE,GAChCA,EAAK,KAAK,IAAM,sBACxB,EAAE,KAAK;AAAA,CAAI,EAERlD,EAAO,uBACPgD,aAAgBhD,EAAO,sBACzB,UAAU,CAAC,EAAI,IAAIA,EAAO,sBAAsB,CAC9C,KAAMgD,EAAK,KACX,IAAAC,CACF,CAAC,EAEDD,EAAK,IAAMC,CAEf,CACA,OAAOF,EAAU,MAAM,KAAM,SAAS,CACxC,CACF,CAEO,SAASI,EAA+BnD,EAAQW,EAAgB,CAKrE,GAAI,EAAEX,EAAO,mBAAqBA,EAAO,kBAAkB,WACzD,OAEF,IAAMoD,EACFpD,EAAO,kBAAkB,UAAU,gBACnC,CAACoD,GAAyBA,EAAsB,SAAW,IAG/DpD,EAAO,kBAAkB,UAAU,gBACjC,UAA2B,CACzB,OAAK,UAAU,CAAC,GAWVW,EAAe,UAAY,UAAYA,EAAe,QAAU,IAC7DA,EAAe,UAAY,WACxBA,EAAe,QAAU,IAC5BA,EAAe,UAAY,WAC7B,UAAU,CAAC,GAAK,UAAU,CAAC,EAAE,YAAc,GACzC,QAAQ,QAAQ,EAElByC,EAAsB,MAAM,KAAM,SAAS,GAjB5C,UAAU,CAAC,GACb,UAAU,CAAC,EAAE,MAAM,IAAI,EAElB,QAAQ,QAAQ,EAe3B,EACJ,CAIO,SAASC,EAAqCrD,EAAQW,EAAgB,CAC3E,GAAI,EAAEX,EAAO,mBAAqBA,EAAO,kBAAkB,WACzD,OAEF,IAAMsD,EACFtD,EAAO,kBAAkB,UAAU,oBACnC,CAACsD,GAA6BA,EAA0B,SAAW,IAGvEtD,EAAO,kBAAkB,UAAU,oBACjC,UAA+B,CAC7B,IAAIgD,EAAO,UAAU,CAAC,GAAK,CAAC,EAC5B,GAAI,OAAOA,GAAS,UAAaA,EAAK,MAAQA,EAAK,IACjD,OAAOM,EAA0B,MAAM,KAAM,SAAS,EAUxD,GADAN,EAAO,CAAC,KAAMA,EAAK,KAAM,IAAKA,EAAK,GAAG,EAClC,CAACA,EAAK,KACR,OAAQ,KAAK,eAAgB,CAC3B,IAAK,SACL,IAAK,mBACL,IAAK,uBACHA,EAAK,KAAO,QACZ,MACF,QACEA,EAAK,KAAO,SACZ,KACJ,CAEF,OAAIA,EAAK,KAAQA,EAAK,OAAS,SAAWA,EAAK,OAAS,SAC/CM,EAA0B,MAAM,KAAM,CAACN,CAAI,CAAC,GAExCA,EAAK,OAAS,QAAU,KAAK,YAAc,KAAK,cACjD,MAAM,IAAI,EACnB,KAAKO,GAAKD,EAA0B,MAAM,KAAM,CAACC,CAAC,CAAC,CAAC,CACzD,EACJ,CC/bA,IAAAC,GAAqB,SAGd,SAASC,GAAe,CAAC,OAAAC,CAAM,EAAI,CAAC,EAAGC,EAAU,CACtD,WAAY,GACZ,YAAa,GACb,WAAY,EACd,EAAG,CAED,IAAMC,EAAgBC,EAChBC,EAAuBC,GAAcL,CAAM,EAE3CM,EAAU,CACd,eAAAF,EACA,WAAAG,GACA,eAAsBC,EACtB,WAAkBC,GAClB,gBAAuBC,GAEvB,IAAAZ,EACF,EAGA,OAAQM,EAAe,QAAS,CAC9B,IAAK,SACH,GAAI,CAACO,GAAc,CAAYC,GAC3B,CAACX,EAAQ,WACX,OAAAC,EAAQ,sDAAsD,EACvDI,EAET,GAAIF,EAAe,UAAY,KAC7B,OAAAF,EAAQ,sDAAsD,EACvDI,EAETJ,EAAQ,6BAA6B,EAErCI,EAAQ,YAAcK,EAGXE,EAA+Bb,EAAQI,CAAc,EACrDU,EAAqCd,EAAQI,CAAc,EAE3DW,EAAiBf,EAAQI,CAAc,EACvCY,GAAgBhB,EAAQI,CAAc,EACtCQ,EAAmBZ,EAAQI,CAAc,EACzCa,GAAYjB,EAAQI,CAAc,EAClCc,GAAwBlB,EAAQI,CAAc,EAC9Ce,GAAuBnB,EAAQI,CAAc,EAC7CgB,GAA2BpB,EAAQI,CAAc,EACjDiB,GAAqBrB,EAAQI,CAAc,EAE3CkB,EAAoBtB,EAAQI,CAAc,EAC1CmB,EAAiCvB,EAAQI,CAAc,EACvDoB,EAAoBxB,EAAQI,CAAc,EAC1CqB,EAAmBzB,EAAQI,CAAc,EACzCsB,EAAuB1B,EAAQI,CAAc,EAC7CuB,EAAuB3B,EAAQI,CAAc,EACxD,MACF,IAAK,UACH,GAAI,CAACwB,GAAe,CAAahB,GAC7B,CAACX,EAAQ,YACX,OAAAC,EAAQ,uDAAuD,EACxDI,EAETJ,EAAQ,8BAA8B,EAEtCI,EAAQ,YAAcsB,EAGXf,EAA+Bb,EAAQI,CAAc,EACrDU,EAAqCd,EAAQI,CAAc,EAE1DW,EAAiBf,EAAQI,CAAc,EACvCQ,EAAmBZ,EAAQI,CAAc,EACzCa,GAAYjB,EAAQI,CAAc,EAClCyB,GAAiB7B,EAAQI,CAAc,EACvC0B,GAAmB9B,EAAQI,CAAc,EACzC2B,GAAqB/B,EAAQI,CAAc,EAC3C4B,GAAmBhC,EAAQI,CAAc,EACzC6B,GAAmBjC,EAAQI,CAAc,EACzC8B,GAAkBlC,EAAQI,CAAc,EACxC+B,GAAgBnC,EAAQI,CAAc,EACtCgC,GAAiBpC,EAAQI,CAAc,EAExCkB,EAAoBtB,EAAQI,CAAc,EAC1CoB,EAAoBxB,EAAQI,CAAc,EAC1CqB,EAAmBzB,EAAQI,CAAc,EACzCsB,EAAuB1B,EAAQI,CAAc,EACxD,MACF,IAAK,SACH,GAAI,CAACiC,GAAc,CAACpC,EAAQ,WAC1B,OAAAC,EAAQ,sDAAsD,EACvDI,EAETJ,EAAQ,6BAA6B,EAErCI,EAAQ,YAAc+B,EAGXxB,EAA+Bb,EAAQI,CAAc,EACrDU,EAAqCd,EAAQI,CAAc,EAE3DkC,GAAqBtC,EAAQI,CAAc,EAC3CmC,GAAsBvC,EAAQI,CAAc,EAC5CoC,GAAiBxC,EAAQI,CAAc,EACvCqC,GAAoBzC,EAAQI,CAAc,EAC1CsC,GAAqB1C,EAAQI,CAAc,EAC3CuC,GAA0B3C,EAAQI,CAAc,EAChDW,GAAiBf,EAAQI,CAAc,EACvCwC,GAAiB5C,EAAQI,CAAc,EAEvCkB,EAAoBtB,EAAQI,CAAc,EAC1CmB,EAAiCvB,EAAQI,CAAc,EACvDqB,EAAmBzB,EAAQI,CAAc,EACzCsB,EAAuB1B,EAAQI,CAAc,EAC7CuB,EAAuB3B,EAAQI,CAAc,EACxD,MACF,QACEF,EAAQ,sBAAsB,EAC9B,KACJ,CAEA,OAAOI,CACT,CC5HA,IAAMuC,GACJC,GAAe,CAAC,OAAQ,OAAO,OAAW,IAAc,OAAY,MAAM,CAAC,EACtEC,EAAQF,GCZf,IAAAG,GAA4B,oCAC5BC,EAA4B,gCA8RhBC,QAIRA,IAAA,YAAc,GAAd,cAIAA,IAAA,MAAQ,GAAR,QAIAA,IAAA,OAAS,GAAT,SAIAA,IAAA,SAAW,GAAX,WAIAA,IAAA,SAAW,GAAX,WApBQA,QAAA,IAuBNC,GAAN,cAA8B,aAAwB,CAClD,aAAc,CACV,MAAM,0BAA2B,CAAC,CAAC,CACvC,CACJ,EAIaC,GAAa,IAAID,GAExBE,GAAN,cAA+B,aAAyB,CACpD,aAAc,CACV,MAAM,2BAA4B,CAC9B,CAAE,GAAI,EAAG,KAAM,cAAe,KAAM,UAAW,OAAQ,EAAyB,EAAG,IAAMC,EAAU,CACvG,CAAC,CACL,CACJ,EAIaC,GAAc,IAAIF,GAEzBG,GAAN,cAA6B,aAAuB,CAChD,aAAc,CACV,MAAM,yBAA0B,CAC5B,CAAE,GAAI,EAAG,KAAM,OAAQ,KAAM,SAAU,OAAQ,EAA2B,EAAG,CAAwB,EACrG,CAAE,GAAI,EAAG,KAAM,WAAY,KAAM,SAAU,IAAK,GAAM,EAAG,CAAwB,EACjF,CAAE,GAAI,EAAG,KAAM,aAAc,KAAM,SAAU,IAAK,GAAM,EAAG,CAAwB,CACvF,CAAC,CACL,CACJ,EAIaF,GAAY,IAAIE,GAEvBC,GAAN,cAA2B,aAAqB,CAC5C,aAAc,CACV,MAAM,uBAAwB,CAC1B,CAAE,GAAI,EAAG,KAAM,MAAO,KAAM,UAAW,EAAG,IAAMC,EAAQ,CAC5D,CAAC,CACL,CACJ,EAIaC,GAAU,IAAIF,GAErBG,GAAN,cAA4B,aAAsB,CAC9C,aAAc,CACV,MAAM,wBAAyB,CAAC,CAAC,CACrC,CACJ,EAIaC,GAAW,IAAID,GAEtBE,GAAN,cAA2B,aAAqB,CAC5C,aAAc,CACV,MAAM,uBAAwB,CAC1B,CAAE,GAAI,EAAG,KAAM,MAAO,KAAM,UAAW,EAAG,IAAMC,EAAS,CAC7D,CAAC,CACL,CACJ,EAIaC,GAAU,IAAIF,GAErBG,GAAN,cAA4B,aAAsB,CAC9C,aAAc,CACV,MAAM,wBAAyB,CAC3B,CAAE,GAAI,EAAG,KAAM,OAAQ,KAAM,UAAW,OAAQ,EAAyB,EAAG,IAAMP,EAAQ,CAC9F,CAAC,CACL,CACJ,EAIaQ,GAAW,IAAID,GAEtBE,GAAN,cAA4B,aAAsB,CAC9C,aAAc,CACV,MAAM,wBAAyB,CAC3B,CAAE,GAAI,EAAG,KAAM,WAAY,KAAM,SAAU,EAAG,CAAwB,EACtE,CAAE,GAAI,EAAG,KAAM,UAAW,KAAM,SAAU,EAAG,CAAwB,EACrE,CAAE,GAAI,EAAG,KAAM,UAAW,KAAM,SAAU,EAAG,EAAyB,CAC1E,CAAC,CACL,CACJ,EAIaJ,GAAW,IAAII,GAEtBC,GAAN,cAA2B,aAAqB,CAC5C,aAAc,CACV,MAAM,uBAAwB,CAC1B,CAAE,GAAI,EAAG,KAAM,SAAU,KAAM,UAAW,EAAG,IAAMC,EAAc,EACjE,CAAE,GAAI,EAAG,KAAM,UAAW,KAAM,UAAW,EAAG,IAAMC,EAAe,CACvE,CAAC,CACL,CACJ,EAIaZ,GAAU,IAAIU,GAErBG,GAAN,cAAkC,aAA4B,CAC1D,aAAc,CACV,MAAM,8BAA+B,CACjC,CAAE,GAAI,EAAG,KAAM,SAAU,KAAM,UAAW,MAAO,cAAe,EAAG,IAAMC,EAAO,EAChF,CAAE,GAAI,EAAG,KAAM,OAAQ,KAAM,UAAW,MAAO,cAAe,EAAG,IAAMC,EAAK,EAC5E,CAAE,GAAI,EAAG,KAAM,MAAO,KAAM,UAAW,MAAO,cAAe,EAAG,IAAMC,EAAI,EAC1E,CAAE,GAAI,EAAG,KAAM,MAAO,KAAM,UAAW,MAAO,cAAe,EAAG,IAAMC,EAAI,CAC9E,CAAC,CACL,CACJ,EAIaL,GAAiB,IAAIC,GAE5BK,GAAN,cAAiC,aAA2B,CACxD,aAAc,CACV,MAAM,6BAA8B,CAChC,CAAE,GAAI,EAAG,KAAM,MAAO,KAAM,UAAW,EAAG,IAAMb,EAAS,EACzD,CAAE,GAAI,EAAG,KAAM,MAAO,KAAM,UAAW,EAAG,IAAMA,EAAS,EACzD,CAAE,GAAI,EAAG,KAAM,SAAU,KAAM,SAAU,EAAG,EAAyB,EACrE,CAAE,GAAI,EAAG,KAAM,WAAY,KAAM,SAAU,EAAG,CAAsB,CACxE,CAAC,CACL,CACJ,EAIaM,GAAgB,IAAIO,GAE3BC,GAAN,cAA0B,aAAoB,CAC1C,aAAc,CACV,MAAM,sBAAuB,CACzB,CAAE,GAAI,EAAG,KAAM,qBAAsB,KAAM,SAAU,EAAG,EAAyB,EACjF,CAAE,GAAI,EAAG,KAAM,MAAO,KAAM,UAAW,MAAO,OAAQ,EAAG,IAAMC,EAAI,EACnE,CAAE,GAAI,GAAI,KAAM,gBAAiB,KAAM,UAAW,MAAO,OAAQ,EAAG,IAAMC,EAAa,CAC3F,CAAC,CACL,CACJ,EAIaP,GAAS,IAAIK,GAEpBG,GAAN,cAAuB,aAAiB,CACpC,aAAc,CACV,MAAM,mBAAoB,CACtB,CAAE,GAAI,EAAG,KAAM,OAAQ,KAAM,OAAQ,EAAG,IAAM,CAAC,uBAAwB9B,GAAS,WAAW,CAAE,EAC7F,CAAE,GAAI,EAAG,KAAM,MAAO,KAAM,SAAU,EAAG,CAAwB,CACrE,CAAC,CACL,CACJ,EAIa4B,GAAM,IAAIE,GAEjBC,GAAN,cAAgC,aAA0B,CACtD,aAAc,CACV,MAAM,4BAA6B,CAC/B,CAAE,GAAI,EAAG,KAAM,YAAa,KAAM,SAAU,EAAG,CAAwB,EACvE,CAAE,GAAI,EAAG,KAAM,mBAAoB,KAAM,SAAU,IAAK,GAAM,EAAG,EAAyB,EAC1F,CAAE,GAAI,EAAG,KAAM,UAAW,KAAM,SAAU,IAAK,GAAM,EAAG,CAAwB,EAChF,CAAE,GAAI,EAAG,KAAM,WAAY,KAAM,SAAU,IAAK,GAAM,EAAG,CAAwB,EACjF,CAAE,GAAI,EAAG,KAAM,WAAY,KAAM,SAAU,IAAK,GAAM,EAAG,CAAwB,CACrF,CAAC,CACL,CACJ,EAIaF,GAAe,IAAIE,GAE1BC,GAAN,cAAwB,aAAkB,CACtC,aAAc,CACV,MAAM,oBAAqB,CAAC,CAAC,CACjC,CACJ,EAIaT,GAAO,IAAIS,GAElBC,GAAN,cAAuB,aAAiB,CACpC,aAAc,CACV,MAAM,mBAAoB,CAAC,CAAC,CAChC,CACJ,EAIaT,GAAM,IAAIS,GAEjBC,GAAN,cAAuB,aAAiB,CACpC,aAAc,CACV,MAAM,mBAAoB,CACtB,CAAE,GAAI,EAAG,KAAM,aAAc,KAAM,UAAW,OAAQ,EAAyB,EAAG,IAAMC,EAAS,CACrG,CAAC,CACL,CACJ,EAIaV,GAAM,IAAIS,GAEjBE,GAAN,cAA4B,aAAsB,CAC9C,aAAc,CACV,MAAM,wBAAyB,CAC3B,CAAE,GAAI,EAAG,KAAM,eAAgB,KAAM,SAAU,EAAG,EAAyB,EAC3E,CAAE,GAAI,EAAG,KAAM,aAAc,KAAM,SAAU,EAAG,EAAyB,CAC7E,CAAC,CACL,CACJ,EAIaD,GAAW,IAAIC,GAEtBC,GAAN,cAA+B,aAAyB,CACpD,aAAc,CACV,MAAM,2BAA4B,CAC9B,CAAE,GAAI,GAAI,KAAM,YAAa,KAAM,UAAW,MAAO,UAAW,EAAG,IAAMC,EAAqB,CAClG,CAAC,CACL,CACJ,EAIaC,GAAc,IAAIF,GAEzBG,GAAN,cAAwC,aAAkC,CACtE,aAAc,CACV,MAAM,oCAAqC,CAAC,CAAC,CACjD,CACJ,EAIaF,GAAuB,IAAIE,GAI3BC,EAAS,IAAI,eAAY,sBAAuB,CACzD,CAAE,KAAM,UAAW,QAAS,CAAC,EAAG,EAAGvC,GAAY,EAAGG,EAAY,EAC9D,CAAE,KAAM,OAAQ,QAAS,CAAC,EAAG,EAAGI,GAAS,EAAGE,EAAS,EACrD,CAAE,KAAM,OAAQ,QAAS,CAAC,EAAG,EAAGG,GAAS,EAAGE,EAAS,CACzD,CAAC,EC9iBD,IAAA0B,EAA+B,oCAyBlBC,EAAN,KAAyD,CAI5D,YAA6BC,EAA0B,CAA1B,gBAAAA,EAH7B,cAAWC,EAAO,SAClB,aAAUA,EAAO,QACjB,aAAUA,EAAO,OAEjB,CAIA,QAAQC,EAAmBC,EAA0D,CACjF,IAAMC,EAAS,KAAK,QAAQ,CAAC,EAAGC,EAAM,KAAK,WAAW,aAAaF,CAAO,EAC1E,SAAO,kBAAwC,QAAS,KAAK,WAAYC,EAAQC,EAAKH,CAAK,CAC/F,CAIA,KAAKA,EAAgBC,EAAoD,CACrE,IAAMC,EAAS,KAAK,QAAQ,CAAC,EAAGC,EAAM,KAAK,WAAW,aAAaF,CAAO,EAC1E,SAAO,kBAAkC,QAAS,KAAK,WAAYC,EAAQC,EAAKH,CAAK,CACzF,CAIA,KAAKA,EAAgBC,EAAoD,CACrE,IAAMC,EAAS,KAAK,QAAQ,CAAC,EAAGC,EAAM,KAAK,WAAW,aAAaF,CAAO,EAC1E,SAAO,kBAAkC,QAAS,KAAK,WAAYC,EAAQC,EAAKH,CAAK,CACzF,CACJ,ECzDO,SAASI,EAAOC,EAAYC,EAAwC,CACzE,OAAO,IAAI,QAASC,GAAY,CAC9B,IAAMC,EAAY,WAAW,IAAMD,EAAQ,EAAI,EAAGF,CAAE,EAGhDC,GACFA,EAAO,iBAAiB,QAAS,IAAM,CACrC,aAAaE,CAAS,EACtBD,EAAQ,EAAK,CACf,CAAC,CAEL,CAAC,CACH,CAEO,SAASE,KAAeC,EAAqC,CAClE,IAAMC,EAAS,IAAI,gBAEbC,EAAc,IAAM,CACxBD,EAAO,MAAM,EAEb,QAAWL,KAAUI,EACnBJ,EAAO,oBAAoB,QAASM,CAAW,CAEnD,EAEA,QAAWN,KAAUI,EACnBJ,EAAO,iBAAiB,QAASM,CAAW,EAG9C,OAAOD,EAAO,MAChB,CAWA,eAAsBE,EACpBC,EACAC,EACmB,CACnB,GAAM,CACJ,WAAAC,EACA,UAAAC,EACA,SAAAC,EACA,aAAAC,EAAe,GACf,cAAAC,EAAgB,IAAM,GACtB,YAAAC,CACF,EAAIN,EAEAO,EAAU,EAEd,MAAQA,GAAWN,GAAcA,EAAa,IAAM,CAACK,GAAa,SAChE,GAAI,CACF,OAAO,MAAMP,EAAc,CAC7B,OAASS,EAAO,CAOd,GALI,CAACH,EAAcG,CAAK,IAIxBD,IACIN,GAAc,GAAKM,EAAUN,GAC/B,MAAMO,EAIR,IAAMC,EAAQC,GAAeH,EAASL,EAAWC,EAAUC,CAAY,EACvE,MAAMf,EAAOoB,EAAOH,CAAW,EAAE,MAAM,IAAM,CAAE,CAAC,CAClD,CAGF,GAAIA,GAAa,QACf,OAAO,KAGT,MAAM,IAAI,MAAM,oCAAoC,CACtD,CAGA,SAASI,GACPH,EACAL,EACAC,EACAC,EACQ,CACR,IAAMO,EAAmB,KAAK,IAAIT,EAAY,IAAMK,EAAU,GAAIJ,CAAQ,EACpES,EAAS,KAAK,OAAO,EAAIR,EAAeO,EAC9C,OAAOA,EAAmBC,CAC5B,CCtFA,IAAMC,GAAkB,IAClBC,GAA2B,GAC3BC,EAA0B,IAC1BC,GAA2B,EAC3BC,GAAqB,IACrBC,GAAwB,IAO9B,IAAMC,GAAgBC,EAChBC,GACJC,GACI,KAAK,MAAM,KAAK,OAAO,GAAM,GAAK,GAAMA,EAAS,EAAIA,EACrDC,GAAwBC,GAAkB,GAK1CC,GAAN,KAAY,CAQV,YAAYC,EAAgB,CAF5B,KAAO,MAAQ,MAAOC,GAAe,CAAC,EAGpC,KAAK,OAASD,EAAO,IAAI,OAAO,EAChC,KAAK,IAAM,IAAI,IACf,KAAK,QAAU,IAAI,IACnB,KAAK,WAAa,CAAC,EACnB,KAAK,WAAa,EACpB,CAEA,QAAQE,EAAc,CACpB,GAAI,CAACA,EAAI,QAAQ,SACf,KAAK,WAAW,KAAKA,CAAG,MACnB,CACL,IAAMC,EAASD,EAAI,OAAQ,OAC3B,GAAI,KAAK,IAAI,IAAIC,CAAM,GAAK,KAAK,QAAQ,IAAIA,CAAM,EAAG,OACtD,KAAK,IAAI,IAAIA,EAAQ,CAAC,YAAY,IAAI,EAAGD,CAAG,CAAC,CAC/C,CAGA,KAAK,YAAY,CACnB,CAEA,MAAM,aAAc,CAClB,GAAI,KAAK,WAAY,OAErB,IAAIA,EAAM,KAAK,WAAW,IAAI,EAC9B,GAAI,CAACA,EAAK,CACR,IAAME,EAAM,KAAK,IAAI,QAAQ,EAAE,KAAK,EAAE,MACtC,GAAI,CAACA,EAAK,OAEV,GAAM,CAACC,EAAKC,CAAK,EAAIF,EACrB,KAAK,IAAI,OAAOC,CAAG,EACnB,KAAK,QAAQ,IAAIA,EAAKC,CAAK,EAC3B,GAAM,CAACL,EAAGM,CAAC,EAAID,EACf,GAAI,CAACC,EAAE,OAAQ,OACfL,EAAMK,CACR,CAEA,KAAK,WAAa,GAClB,GAAI,CACF,MAAM,KAAK,MAAML,CAAG,CACtB,OAASM,EAAK,CACZ,IAAMC,EAA+B,CAAE,IAAAP,CAAI,EACvCM,aAAe,QACjBC,EAAI,IAASD,GAEf,KAAK,OAAO,MAAM,2BAA4BC,CAAG,CACnD,CACA,KAAK,WAAa,GAClB,KAAK,YAAY,CACnB,CACF,EAYaC,EAAN,KAAgB,CAWrB,YACmBC,EACDC,EAChB,CAFiB,YAAAD,EACD,UAAAC,EALlB,KAAO,SAAYX,GAAc,CAAC,EAClC,KAAO,SAAYY,GAAoB,CAAC,EAoFxC,KAAQ,eAAkBC,GAAoB,CAC5C,QAAWZ,KAAOY,EAAM,CAEtB,GADA,KAAK,OAAO,MAAM,WAAY,CAAE,IAAKZ,CAAI,CAAC,EACtC,KAAK,MAAM,OAAO,QAAS,OAC/B,GAAI,CAACA,EAAI,OAAQ,SACjB,IAAMa,EAAMb,EAAI,OAAO,IACjBc,EAAMd,EAAI,OAAO,IACvB,GAAI,CAACa,GAAO,CAACC,EAAK,SAElB,GACEA,EAAI,QAAU,IACdA,EAAI,QAAU,KAAK,KAAK,OACxB,CACA,KAAK,OAAO,KACV,sDACA,CAAE,eAAgBA,EAAI,MAAO,CAC/B,EACA,QACF,CAEA,IAAIC,EAAwB,KAC5B,QAAWC,KAAK,KAAK,QACnB,GACEH,EAAI,UAAYG,EAAE,MAAM,SACxBH,EAAI,SAAWG,EAAE,MAAM,QACvBH,EAAI,SAAWG,EAAE,MAAM,OACvB,CACAD,EAASC,EACT,KACF,CAGF,GAAI,CAACD,EAAQ,CAKX,GAJA,KAAK,OAAO,MACV,uCAAuCF,EAAI,MAAM,IAAIA,EAAI,MAAM,EACjE,EAEIA,EAAI,QAAU,KAAK,KAAK,OAAQ,CAClC,KAAK,OAAO,KAAK,sCAAsC,EACvD,MACF,CAEAE,EAAS,IAAIE,GACX,KACA,KAAK,KACLJ,EACA,KAAK,MACP,EACA,KAAK,QAAQ,KAAKE,CAAM,EACxB,KAAK,SAASA,CAAM,CACtB,CAEAA,EAAO,QAAQf,CAAG,CACpB,CACF,EApIE,KAAK,OAASU,EAAK,QAAUnB,GAC7B,KAAK,WAAamB,EAAK,YAAcjB,GACrC,KAAK,cAAgBiB,EAAK,eAAiBf,GAE3C,KAAK,KAAO,CACV,QAASe,EAAK,QACd,OAAQA,EAAK,OACb,OAAQ,KAAK,WAAW,EAAkB,CAC5C,EACA,KAAK,MAAQ,IAAI,gBACjB,KAAK,OAASA,EAAK,OAAO,IAAI,YAAa,CACzC,KAAM,KAAK,IACb,CAAC,EACD,KAAK,QAAU,CAAC,CAClB,CAEA,MAAM,QAAS,CACb,MAAM,QAAQ,IAAI,CAChB,KAAK,SAAS,EACd,KAAK,OAAO,CACd,CAAC,CACH,CAEA,MAAM,QAAS,CACb,KAAO,CAAC,KAAK,MAAM,OAAO,SAGxB,KAAK,QAAU,KAAK,QAAQ,OAAQM,GAAM,CAACA,EAAE,SAAS,CAAC,EACvD,MAAMxB,EAAO0B,GAAuB,KAAK,MAAM,MAAM,EAEvD,KAAK,OAAO,MAAM,mBAAmB,CACvC,CAEA,MAAM,UAAW,CACf,IAAMC,EAAqB,CACzB,MAAO,KAAK,MAAM,OAClB,QAASC,EACX,EACMC,EAAyB,CAC7B,UAAWC,GACX,SAAUC,EACV,WAAY,GACZ,YAAa,KAAK,MAAM,OACxB,cAAe,KAAK,aACtB,EAEA,KAAO,CAAC,KAAK,MAAM,OAAO,SACxB,GAAI,CACF,IAAMC,EAAO,MAAMC,EAAM,SACvB,MAAM,KAAK,OAAO,KAAK,CACrB,IAAK,KAAK,IACZ,EAAGN,CAAM,EAAGE,CAAQ,EACtB,GAAIG,IAAS,KACX,MAIF,IAAI,QAAQ,IAAM,KAAK,eAAeA,EAAK,SAAS,IAAI,CAAC,CAC3D,OAASlB,EAAK,CACZ,KAAK,OAAO,MAAM,qCAAsC,CAAE,IAAAA,CAAI,CAAC,EAC/D,KAAK,MAAM,EACX,MACF,CAEF,KAAK,OAAO,MAAM,qBAAqB,CACzC,CAEA,MAAM,MAAMoB,EAAiB,CACvB,KAAK,MAAM,OAAO,UACtBA,EAASA,GAAU,sBACnB,MAAM,QAAQ,IAAI,KAAK,QAAQ,IAAKV,GAAMA,EAAE,MAAMU,CAAM,CAAC,CAAC,EAE1D,KAAK,MAAM,MAAMA,CAAM,EACvB,KAAK,OAAO,MAAM,0BAA2B,CAAE,OAAAA,CAAO,CAAC,EACvD,KAAK,QAAU,CAAC,EAChB,KAAK,SAASA,CAAM,EACtB,CA0DA,MAAM,QACJC,EACAC,EACAC,EACA,CACA,IAAMC,EAA0B,CAC9B,YAAa,CACX,UAAW,OACX,KAAM,CAAC,CACT,CACF,EACMC,EAAwB,CAC5B,IAAK,KAAK,KACV,IAAK,CACH,QAASJ,EACT,OAAQC,EACR,OAAQ,CACV,EACA,OAAQ,EACR,SAAU,EACZ,EAEII,EAAQ,GACNC,EAAeC,EAAYL,EAAQ,KAAK,MAAM,MAAM,EAC1D,KAAO,CAACI,EAAa,SAAW,CAACD,GAC/B,MAAM,KAAK,KAAKC,EAAc,CAC5B,OAAAF,EACA,QAAAD,CACF,CAAC,EACD,MAAM,KAAK,OAAOP,EAAyBU,CAAY,EAAE,MAAM,IAAM,CAAC,CAAC,EAEvED,EAAQ,CAAC,CAAC,KAAK,QAAQ,KAAMhB,GAC3BA,EAAE,MAAM,UAAYW,GAAgBX,EAAE,MAAM,SAAWY,CACzD,CAEJ,CAEA,MAAM,KAAKC,EAAqB7B,EAAc,CAC5C,IAAMiC,EAAeC,EAAYL,EAAQ,KAAK,MAAM,MAAM,EACpDV,EAAqB,CACzB,MAAOc,EACP,QAASb,EACX,EACMC,EAAyB,CAC7B,UAAWC,GACX,SAAUC,EACV,WAAY,GACZ,YAAaU,EACb,cAAe,KAAK,aACtB,EAEA,GAAI,CAMF,GALa,MAAMR,EAAM,SACvB,MAAM,KAAK,OAAO,KAChB,CAAE,IAAAzB,CAAI,EACNmB,CACF,EAAGE,CAAQ,IACA,KAAM,CACjB,KAAK,OAAO,KAAK,wCAAyC,CAAE,IAAArB,CAAI,CAAC,EACjE,MACF,CAEA,MACF,OAASM,EAAK,CACZ,KAAK,OAAO,MAAM,qCAAsC,CAAE,IAAAA,CAAI,CAAC,EAC/D,KAAK,MAAM,EACX,MACF,CACF,CACF,EAIaW,GAAN,KAAa,CAUlB,YACmBkB,EACDC,EACAC,EAChBvC,EACA,CAJiB,eAAAqC,EACD,UAAAC,EACA,WAAAC,EANlB,KAAO,UAAY,MAAOtC,GAAsB,CAAC,EACjD,KAAO,SAAYY,GAAoB,CAAC,EAQtC,KAAK,OAASb,EAAO,IAAI,SAAU,CACjC,MAAAuC,CACF,CAAC,EACD,KAAK,MAAQ,IAAI,gBACjB,KAAK,SAAW,CAAC,EACjB,KAAK,MAAQ,IAAIxC,GAAM,KAAK,MAAM,EAClC,KAAK,MAAM,MAASG,GAAQ,KAAK,cAAcA,CAAG,EAClD,KAAK,WAAa,EAClB,KAAK,SAAW,CAClB,CAEA,gBAAgBsC,EAAqC,CACnD,OAAOJ,EAAY,KAAK,MAAM,OAAQ,GAAGI,CAAO,CAClD,CAEA,UAAoB,CAClB,IAAMC,EAAS,KAAK,MAAM,OAAO,SAC9B,YAAY,IAAI,EAAI,KAAK,SAAYC,GAExC,OAAID,GACF,KAAK,OAAO,MAAM,wBAAwB,EAErCA,CACT,CAEA,QAAQvC,EAAc,CACpB,GAAI,KAAK,MAAM,OAAO,QAAS,CAC7B,KAAK,OAAO,KACV,4DACF,EACA,MACF,CAEA,KAAK,MAAM,QAAQA,CAAG,CACxB,CAEA,MAAM,KAAK8B,EAAyBW,EAAmBZ,EAAsB,CACtEA,IACHA,EAAS,KAAK,MAAM,QAEtB,IAAM7B,EAAe,CACnB,OAAQ,CACN,IAAK,KAAK,UAAU,KACpB,IAAK,KAAK,MACV,OAAQ,EACR,SAAAyC,CACF,EACA,QAAS,CAAE,GAAGX,CAAQ,CACxB,EAEA,GAAI,CAACW,EAAU,CACb,MAAM,KAAK,UAAU,KAAKZ,EAAQ7B,CAAG,EACrC,MACF,CAEA,KAAK,aACLA,EAAI,OAAQ,OAAS,KAAK,WAC1B,KAAK,SAASA,EAAI,OAAQ,MAAM,EAAI,GACpC,IAAM0C,EAAcC,GAChBC,EAAWF,EACTzC,EAASD,EAAI,OAAQ,OAG3B,KAAO,CAAC6B,EAAO,UACb,MAAM,KAAK,UAAU,KAAK,KAAK,MAAM,OAAQ7B,CAAG,EAEhD,MAAM,KAAK,UAAU,OACnB,EAAIuB,EACJ,KAAK,MAAM,MACb,EAAE,MAAM,IAAM,CAAC,CAAC,EAIZ,MAAK,SAAStB,CAAM,IAVF,CActB,GAAI2C,GAAY,EAAG,CACjB,IAAMC,EAAU,qDAChB,WAAK,OAAO,KAAKA,EAAS,CACxB,OAAA5C,EACA,YAAAyC,EACA,SAAAD,CACF,CAAC,EACK,IAAI,MAAMI,CAAO,CACzB,CAEAD,IACA,KAAK,OAAO,MAAM,YAAa,CAAE,GAAG5C,EAAI,MAAO,CAAC,CAClD,CACF,CAEA,MAAc,cAAcA,EAAc,CACxC,IAAM8B,EAAU9B,EAAI,QAAS,YAC7B,OAAQ8B,EAAQ,UAAW,CACzB,IAAK,MACH,KAAK,UAAUA,EAAQ,GAAG,EAC1B,MACF,IAAK,MACH,KAAK,MAAM,8BAA8B,EACzC,MACF,KAAK,OACH,MACF,QAAS,CACP,GAAI9B,EAAI,OAAQ,SAAU,CAOxB,IAAM8C,EAAwB,CAC5B,YAAa,CAAE,UAAW,MAAO,IAPlB,CACf,UAAW,CAAC,CACV,YAAa9C,EAAI,OAAQ,OACzB,UAAWA,EAAI,OAAQ,OAAS,CAClC,CAAC,CACH,CAEuC,CACvC,EACA,KAAK,OAAO,MAAM,MAAO,CAAE,OAAQA,EAAI,OAAQ,MAAO,CAAC,EACvD,KAAK,KAAK8C,EAAO,EAAK,CACxB,CAEA,GAAI,CAAC9C,EAAI,QAAS,OAClB,MAAM,KAAK,UAAUA,EAAI,OAAQ,EACjC,KACF,CACF,CACF,CAEA,UAAU+C,EAAU,CAClB,QAAWC,KAAKD,EAAI,UAClB,QAAS/B,EAAIgC,EAAE,YAAahC,EAAIgC,EAAE,UAAWhC,IAC3C,KAAK,OAAO,MAAM,eAAgB,CAAE,OAAQA,CAAE,CAAC,EAC/C,KAAK,SAASA,CAAC,EAAI,EAGzB,CAEA,MAAM,MAAMU,EAAiB,CACvB,KAAK,MAAM,OAAO,UACtBA,EAASA,GAAU,oBAEnB,MAAM,KAAK,KAAK,CACd,YAAa,CACX,UAAW,MACX,IAAK,CAAC,CACR,CACF,EAAG,EAAK,EAAE,MAAOpB,GACf,KAAK,OAAO,KAAK,qBAAsB,CAAE,EAAGA,CAAI,CAAC,CACnD,EACA,KAAK,MAAM,MAAMoB,CAAM,EACvB,KAAK,SAAW,YAAY,IAAI,EAChC,KAAK,SAASA,CAAM,EACpB,KAAK,OAAO,MAAM,6BAA8B,CAAE,OAAAA,CAAO,CAAC,EAC5D,CACF,ECneO,IAAMuB,GAA4B,CACvC,MAAO,QAAQ,MACf,KAAM,QAAQ,KACd,KAAM,QAAQ,KACd,MAAO,QAAQ,KACjB,EAKaC,GAA2B,CACtC,MAAQC,GAAM,QAAQ,MAAMC,EAAOD,CAAC,CAAC,EACrC,KAAOA,GAAM,QAAQ,KAAKC,EAAOD,CAAC,CAAC,EACnC,KAAOA,GAAM,QAAQ,KAAKC,EAAOD,CAAC,CAAC,EACnC,MAAQA,GAAM,QAAQ,MAAMC,EAAOD,CAAC,CAAC,CACvC,EAEO,SAASE,GACdC,EACAC,EACAC,EAAY,OACZC,EAAU,IAAI,IACd,CACA,IAAMC,EAAM,IACZ,GAAI,CAAAD,EAAQ,IAAIH,CAAG,EACnB,CAAAG,EAAQ,IAAIH,CAAG,EAEf,QAAWK,KAAOL,EAChB,GAAI,OAAOA,EAAIK,CAAG,GAAM,UAAYL,EAAIK,CAAG,IAAM,KAAM,CACrD,IAAMC,EAASJ,EAAYE,EAAMC,EACjCN,GAAQC,EAAIK,CAAG,EAAaJ,EAAOK,EAAQH,CAAO,CACpD,KAAO,CACL,IAAMI,EAAIN,EAAMC,CAAS,GAAK,CAAC,EAC/BK,EAAE,KAAK,GAAGF,CAAG,IAAIL,EAAIK,CAAG,CAAC,EAAE,EAC3BJ,EAAMC,CAAS,EAAIK,CACrB,EAEJ,CAEO,SAAST,EAAOE,EAAa,CAClC,IAAMC,EAAkC,CAAC,EACzCF,GAAQC,EAAKC,CAAK,EAElB,IAAMO,EAAkB,CAAC,EACzB,QAAWC,KAAKR,EACdO,EAAM,KAAK,IAAIC,CAAC,KAAKR,EAAMQ,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,EAE3C,OAAOD,EAAM,KAAK;AAAA,CAAI,CACxB,CAEO,IAAME,EAAN,MAAMC,CAAO,CAGlB,YAA4BC,EAAcZ,EAAca,EAAgB,CAA5C,UAAAD,EACrBZ,IAAKA,EAAM,CAAC,GACZa,IAAMA,EAAOlB,IAClB,KAAK,KAAOkB,EACZ,KAAK,IAAM,CAAE,GAAGb,EAAK,KAAAY,CAAK,CAC5B,CAEQ,IACNE,EACAC,EACAf,EACM,CACN,IAAMH,EAAIG,GAAO,CAAC,EAClBc,EAAQ,CACN,GAAI,KAAK,IAAI,EACb,QAAAC,EACA,GAAG,KAAK,IACR,GAAGlB,CACL,CAAC,CACH,CAEA,MAAMkB,EAAiBf,EAAoB,CACzC,KAAK,IAAI,KAAK,KAAK,MAAOe,EAASf,CAAG,CACxC,CAEA,KAAKe,EAAiBf,EAAoB,CACxC,KAAK,IAAI,KAAK,KAAK,KAAMe,EAASf,CAAG,CACvC,CAEA,KAAKe,EAAiBf,EAAoB,CACxC,KAAK,IAAI,KAAK,KAAK,KAAMe,EAASf,CAAG,CACvC,CAEA,MAAMe,EAAiBf,EAAoB,CACzC,KAAK,IAAI,KAAK,KAAK,MAAOe,EAASf,CAAG,CACxC,CAEA,IAAIY,EAAcZ,EAAsB,CACtC,OAAKA,IAAKA,EAAM,CAAC,GACV,IAAIW,EACT,KAAK,KAAO,IAAMC,EAClB,CAAE,GAAG,KAAK,IAAK,GAAGZ,CAAI,EACtB,KAAK,IACP,CACF,CACF,EChGA,IAAMgB,GAAwB,EACxBC,GAAgC,IAEtC,SAASC,GAAeC,EAAwC,CAC9D,MAAO,CACL,UAAWA,EAAI,UACf,OAAQA,EAAI,OACZ,cAAeA,EAAI,cACnB,iBAAkBA,EAAI,QACxB,CACF,CAEA,SAASC,GAAUC,EAA2B,CAC5C,OAAQA,EAAM,CACZ,OACE,MAAO,QACT,OACE,MAAO,SACT,OACE,MAAO,WACT,OACE,MAAO,WACT,QACE,MAAM,IAAI,MAAM,oBAAoBA,CAAI,EAAE,CAC9C,CACF,CAEA,SAASC,GAAYC,EAAwB,CAC3C,OAAQA,EAAG,CACT,IAAK,QACH,SACF,IAAK,SACH,SACF,IAAK,WACH,SACF,IAAK,WACH,SACF,QACE,MAAM,IAAI,MAAM,wBAAwBA,CAAC,EAAE,CAC/C,CACF,CAMO,IAAMC,EAAN,KAAc,CA4HnB,YACmBC,EACjBC,EACA,CAFiB,YAAAD,EA5GnB,KAAO,cAAoD,IAAM,CAAC,EAKlE,KAAO,wBACL,IAAM,CAAC,EAMT,KAAO,QAAwC,IAAM,CAAC,EA2QtD,KAAQ,kBAAoB,IAAM,CAEhC,GAAI,CAAC,KAAK,SAAU,OAEpB,IAAME,EAAU,YAAY,IAAI,EAAI,KAAK,eACzC,GAAIA,EAAUV,GAA+B,CAE3C,IAAMW,EAAQX,GAAgCU,EACxCE,EAAU,OAAO,WAAW,IAAM,CACtC,KAAK,kBAAkB,EACvB,KAAK,OAAS,KAAK,OAAO,OAAQC,GAAMA,IAAMD,CAAO,CACvD,EAAGD,CAAK,EACR,MACF,CAEI,KAAK,GAAG,kBAAoB,cAC5B,KAAK,iBAAmBZ,IAAuB,KAAK,MAAM,EAC9D,KAAK,OAAO,MAAM,uBAAuB,EACzC,KAAK,GAAG,WAAW,EACnB,KAAK,oBACL,KAAK,kBACL,KAAK,eAAiB,YAAY,IAAI,EACxC,EAEA,KAAQ,WAAce,GAA8C,CAClE,KAAK,OAAO,KAAK,CACf,YAAa,CACX,UAAW,SACX,OAAQ,CAAE,GAAGA,EAAQ,kBAAmB,KAAK,iBAAkB,CACjE,CACF,EAAG,EAAI,CACT,EAEA,KAAQ,cAAgB,MAAOC,GAA4B,CACzD,GAAI,KAAK,MAAM,OAAO,QAAS,CAC7B,KAAK,OAAO,KAAK,qCAAqC,EACtD,MACF,CACA,OAAQA,EAAQ,YAAY,UAAW,CACrC,IAAK,SACH,MAAM,KAAK,aAAaA,EAAQ,YAAY,MAAM,EAClD,MACF,IAAK,MACH,KAAK,MAAM,EACX,MACF,IAAK,OAEH,KACJ,CACF,EAEA,KAAQ,aAAe,MAAOD,GAAmB,CAC/C,GAAIA,EAAO,kBAAoB,KAAK,kBAAmB,CACrD,KAAK,OAAO,KAAK,qDAAqD,EACtE,MACF,CAEA,IAAME,EAAMF,EAAO,KACnB,GAAIA,EAAO,kBAAoB,KAAK,kBAAmB,CASrD,GANA,KAAK,OAAO,MAAM,iCAAkC,CAClD,uBAAwBA,EAAO,kBAC/B,kBAAmB,KAAK,kBACxB,IAAAE,CACF,CAAC,EAEGA,EAAI,YAAc,eAAgB,CACpC,IAAMd,EAAMD,GAAee,EAAI,YAAY,EAC3C,KAAK,kBAAkB,KAAKd,CAAG,EAC/B,KAAK,OAAO,KACV,sFACA,CAAE,IAAAA,EAAK,IAAAc,CAAI,CACb,EACA,MACF,CAEA,KAAK,kBAAoBF,EAAO,iBAClC,CAEA,GAAIE,EAAI,YAAc,eAAgB,CACpC,IAAMd,EAAMD,GAAee,EAAI,YAAY,EAC3C,KAAK,kBAAkB,KAAKd,CAAG,EAC/B,KAAK,uBAAuB,EAE5B,MACF,CAEA,GAAIc,EAAI,WAAa,MACnB,OAGF,IAAMC,EAAMD,EAAI,IAChB,KAAK,OAAO,MAAM,wBAAyB,CAAE,QAASC,EAAI,IAAK,CAAC,EAChE,IAAMC,EAAiBD,EAAI,OAAS,IACjC,KAAK,aAAe,KAAK,GAAG,iBAAmB,UAGlD,GADoB,KAAK,UAAYC,EACpB,CACf,KAAK,OAAO,MAAM,eAAe,EACjC,MACF,CAOA,GALA,KAAK,OAAO,MAAM,oBAAoB,EACtC,MAAM,KAAK,GAAG,qBAAqB,CACjC,KAAMf,GAAUc,EAAI,IAAI,EACxB,IAAKA,EAAI,GACX,CAAC,EACGA,EAAI,OAAS,EAAe,CAE9B,GADA,MAAM,KAAK,GAAG,oBAAoB,EAC9B,CAAC,KAAK,GAAG,iBAAkB,CAC7B,KAAK,OAAO,MAAM,mCAAmC,EACrD,MACF,CAGA,KAAK,WAAW,CACd,KAAM,CACJ,UAAW,MACX,IAAK,CACH,KAAMZ,GAAY,KAAK,GAAG,iBAAiB,IAAI,EAC/C,IAAK,KAAK,GAAG,iBAAiB,GAChC,CACF,CACF,CAAC,CACH,CAEA,KAAK,uBAAuB,CAE9B,EAEA,KAAQ,uBAAyB,IAAM,CAMrC,GACE,CANsC,CACtC,SACA,mBACA,mBACF,EAEc,SAAS,KAAK,GAAG,cAAc,GAAK,CAAC,KAAK,GAAG,kBACzD,CACA,KAAK,OAAO,MAAM,qCAAsC,CACtD,eAAgB,KAAK,GAAG,eACxB,mBAAoB,KAAK,GAAG,mBAC5B,gBAAiB,KAAK,GAAG,gBACzB,kBAAmB,KAAK,GAAG,kBAC3B,kBAAmB,KAAK,kBAAkB,MAC5C,CAAC,EACD,MACF,CAEA,QAAWc,KAAa,KAAK,kBACvB,CAACA,EAAU,WAAaA,EAAU,YAAc,KAMpD,KAAK,GAAG,gBAAgBA,CAAS,EAAE,MAAOC,GAAM,CAC9C,KAAK,OAAO,KAAK,qCAAsC,CACrD,UAAAD,EACA,EAAAC,CACF,CAAC,CACH,CAAC,EACD,KAAK,OAAO,MAAM,cAAcD,EAAU,SAAS,EAAE,GAEvD,KAAK,kBAAoB,CAAC,CAC5B,EA9UE,KAAK,GAAK,IAAI,kBAAkBV,CAAM,EAEtC,KAAK,YAAc,GACnB,KAAK,kBAAoB,CAAC,EAGtB,KAAK,OAAO,KAAK,SAAW,KAAK,OAAO,MAAM,OAChD,KAAK,SAAW,KAAK,OAAO,KAAK,OAAS,KAAK,OAAO,MAAM,OAE5D,KAAK,SAAW,KAAK,OAAO,KAAK,OAAS,KAAK,OAAO,MAAM,OAE9D,KAAK,MAAQ,IAAI,gBACjB,KAAK,OAASD,EAAO,OAAO,IAAI,UAAW,CACzC,KAAM,KAAK,SAAW,WAAa,QACrC,CAAC,EACD,KAAK,kBAAoB,EACzB,KAAK,gBAAkB,EACvB,KAAK,eAAiB,EACtB,KAAK,OAAS,CAAC,EACf,KAAK,iBAAmB,MACxBA,EAAO,UAAaQ,GAAQ,KAAK,cAAcA,CAAG,EAClDR,EAAO,SAAYa,GAAW,KAAK,MAAMA,CAAM,EAE/C,KAAK,GAAG,2BAA6B,SAAY,CAC/C,IAAMC,EAAQ,MAAM,KAAK,GAAG,SAAS,EAC/BC,EAAkB,CAAC,EACnBC,EAAmB,CAAC,EACpBC,EAAoB,CAAC,EAE3BH,EAAM,QAASI,GAAqB,CAC9BA,EAAO,OAAS,iBAClBH,EAAK,KAAKG,CAAM,EACPA,EAAO,OAAS,kBACzBF,EAAM,KAAKE,CAAM,EACRA,EAAO,OAAS,oBACzBD,EAAO,KAAKC,CAAM,CAEtB,CAAC,EAED,KAAK,OAAO,MAAM,6BAA8B,CAC9C,gBAAmB,KAAK,GAAG,gBAC3B,mBAAsB,KAAK,GAAG,mBAC9B,MAAAF,EACA,OAAAC,EACA,KAAAF,EACA,QAAS,KAAK,iBAChB,CAAC,CACH,EAEA,IAAII,EAAQ,YAAY,IAAI,EAC5B,KAAK,GAAG,wBAA2BC,GAAO,CAMxC,OALA,KAAK,OAAO,MAAM,0BAA2B,CAC3C,gBAAmB,KAAK,GAAG,gBAC3B,mBAAsB,KAAK,GAAG,kBAChC,CAAC,EACD,KAAK,mBAAmB,KAAK,GAAG,gBAAiBA,CAAE,EAC3C,KAAK,GAAG,gBAAiB,CAC/B,IAAK,aACHD,EAAQ,YAAY,IAAI,EACxB,MACF,IAAK,YAAa,CAChB,IAAMjB,EAAU,YAAY,IAAI,EAAIiB,EACpC,KAAK,OAAO,MAAM,WAAWjB,CAAO,eAAe,EACnD,KAAK,gBAAkB,EACvB,KACF,CACA,IAAK,eACH,KAAK,kBAAkB,EACvB,MACF,IAAK,SACH,KAAK,MAAM,oCAAoC,EAC/C,MACF,IAAK,SACH,KACJ,CACF,EACA,IAAImB,EAAa,GACjB,KAAK,GAAG,oBAAsB,SAAY,CACxC,GAAIA,EAAY,CACd,GAAI,CAAC,KAAK,SAAU,CAElB,KAAK,OAAO,KAAK,CACf,YAAa,CACX,UAAW,OACX,KAAM,CAAC,CACT,CACF,EAAG,EAAI,EACP,MACF,CACAA,EAAa,EACf,CAEA,GAAI,CAIF,GAHA,KAAK,YAAc,GACnB,KAAK,OAAO,MAAM,mBAAmB,EACrC,MAAM,KAAK,GAAG,oBAAoB,EAC9B,CAAC,KAAK,GAAG,iBACX,MAAM,IAAI,MAAM,yCAAyC,EAG3D,KAAK,WAAW,CACd,KAAM,CACJ,UAAW,MACX,IAAK,CACH,KAAMxB,GAAY,KAAK,GAAG,iBAAiB,IAAI,EAC/C,IAAK,KAAK,GAAG,iBAAiB,GAChC,CACF,CACF,CAAC,CACH,OAASyB,EAAK,CACRA,aAAe,OACjB,KAAK,OAAO,MAAM,wBAAyB,CAAE,IAAAA,CAAI,CAAC,CAEtD,QAAE,CACA,KAAK,YAAc,EACrB,CACF,EAEA,KAAK,GAAG,eAAiB,CAAC,CAAE,UAAAX,CAAU,IAAM,CAC1C,KAAK,OAAO,MAAM,iBAAkB,CAAE,UAAAA,CAAU,CAAC,EACjD,IAAMjB,EAAoB,CACxB,UAAW,GACX,cAAe,EACf,OAAQ,EACV,EACA,GAAI,CAACiB,GAAaA,EAAU,YAAc,GAAI,CAC5C,KAAK,OAAO,MAAM,2BAA2B,EAC7C,MACF,CAEAjB,EAAI,UAAYiB,EAAU,UAC1BjB,EAAI,cAAgBiB,EAAU,eAAiB,OAC/CjB,EAAI,OAASiB,EAAU,QAAU,OACjCjB,EAAI,SAAWiB,EAAU,kBAAoB,OAE7C,KAAK,WAAW,CACd,KAAM,CACJ,UAAW,eACX,aAAcjB,CAChB,CACF,CAAC,CACH,EAEA,KAAK,GAAG,cAAgB,IAAI6B,IAAS,CAC/B,KAAK,eAEP,KAAK,cAAc,GAAGA,CAAI,CAE9B,EAEA,KAAK,GAAG,QAAU,IAAIA,IAAS,CACzB,KAAK,SAEP,KAAK,QAAQ,GAAGA,CAAI,CAExB,CACF,CAxPA,YAAYA,EAA+D,CACzE,OAAO,KAAK,GAAG,SAAS,GAAGA,CAAI,CACjC,CAOA,eAAeA,EAA0D,CACvE,OAAO,KAAK,GAAG,YAAY,GAAGA,CAAI,CACpC,CAMA,qBACKA,EACa,CAChB,OAAO,KAAK,GAAG,kBAAkB,GAAGA,CAAI,CAC1C,CAOA,IAAI,iBAA0C,CAC5C,OAAO,KAAK,GAAG,eACjB,CAMA,IAAI,aAAkC,CACpC,OAAO,KAAK,YACd,CAMA,IAAI,OAAkB,CACpB,MAAO,CACL,QAAS,KAAK,OAAO,MAAM,QAC3B,OAAQ,KAAK,OAAO,MAAM,OAC1B,OAAQ,KAAK,OAAO,MAAM,MAC5B,CACF,CASA,MAAMV,EAAuB,CAC3B,GAAI,KAAK,MAAM,OAAO,QAAS,OAC/B,KAAK,MAAM,MAAMA,CAAM,EACvB,QAAWW,KAAS,KAAK,OACvB,aAAaA,CAAK,EAEpB,KAAK,OAAS,CAAC,EACf,KAAK,OAAO,MAAM,EAClB,KAAK,aAAeX,EACpB,KAAK,GAAG,MAAM,EAId,IAAMY,EAAa,IAAI,MAAM,uBAAuB,EACpD,KAAK,mBAAmB,SAAUA,CAAU,EAE5C,KAAK,OAAO,MAAM,iBAAkB,CAClC,gBAAiB,KAAK,eACxB,CAAC,CACH,CA6KQ,mBAAmBC,EAA2BN,EAAiB,CACjEM,IAAM,KAAK,kBAEX,KAAK,yBAEP,KAAK,wBAAwBN,CAAE,CAEnC,CAyKF,ECngBA,IAAAO,GAAgD,oCAChDC,EAGO,wCAEP,IAAAC,GAA0B,sBAyDpBC,GAAW,oCAgKV,IAAMC,GAAN,KAAW,CA2BhB,YACEC,EACAC,EACAC,EACAC,EACA,CAtBF,KAAO,UAAaC,GAAiB,CAAC,EAItC,KAAO,cAAgB,IAAM,CAAC,EAmB5B,KAAK,OAASF,EAAK,OACnB,KAAK,OAASF,EAAO,IAAI,OAAQ,CAAE,OAAQ,KAAK,MAAO,CAAC,EACxD,KAAK,SAAW,CAAC,EACjB,KAAK,OAAS,MAEd,IAAMK,EAA8B,CAClC,aAAc,WACd,mBAAsBH,EAAK,WAAa,QAAU,MAClD,qBAAsB,EACtB,WAAYA,EAAK,UACnB,EACA,KAAK,UAAY,IAAII,EAAUL,EAAQ,CACrC,gBAAiB,GACjB,QAASC,EAAK,QACd,OAAQA,EAAK,OACb,OAAQ,KAAK,OACb,cAAAC,CACF,CAAC,EACD,KAAK,UAAU,SAAYI,GAAM,CAC/B,IAAMC,EAAO,IAAIC,EAAQF,EAAGF,CAAS,EACrC,KAAK,SAAS,KAAKG,CAAI,EACvB,KAAK,UAAUA,CAAI,CACrB,EACA,KAAK,UAAU,SAAW,IAAM,CAC9B,KAAK,MAAM,CACb,CACF,CASA,OAAQ,CACN,GAAI,KAAK,SAAW,SAAU,MAAM,IAAI,MAAM,wBAAwB,EACtE,KAAK,UAAU,OAAO,CACxB,CASA,MAAM,OAAQ,CACZ,KAAK,SAAW,CAAC,EACjB,MAAM,KAAK,UAAU,MAAM,EAC3B,KAAK,SAAS,QAAQ,CACxB,CAkBA,QACEE,EACAC,EACAC,EACe,CACf,OAAO,KAAK,UAAU,QAAQF,EAAcC,EAAaC,CAAM,CACjE,CAMA,IAAI,OAAmB,CACrB,OAAO,KAAK,MACd,CAGQ,SAASL,EAAoB,CAC/BA,IAAM,KAAK,SAEf,KAAK,OAASA,EACd,KAAK,cAAc,EACrB,CACF,EAEMM,GAA+B,CACnC,iBAAe,iBAAe,iBAAiB,EAC/C,iBAAe,iBAAe,gBAAgB,EAC9C,iBAAe,iBAAe,OAAO,EACrC,iBAAe,iBAAe,SAAS,EACvC,iBAAe,iBAAe,SAAS,EACvC,iBAAe,iBAAe,SAAS,EACvC,iBAAe,iBAAe,eAAe,CAC/C,EAEA,SAASC,GAAmBC,EAAuB,CACjD,OAAMA,aAAe,MAIfA,aAAe,YAId,CAACF,GAAmB,SAASE,EAAI,IAAI,EAHnC,GAJA,EAQX,CAaA,eAAsBC,GAAWd,EAAkC,CAEjE,IAAMe,EAAQf,EAAK,MACbgB,EAAQ,IAAI,sBAAoB,CACpC,QAAShB,EAAK,SAAWiB,GACzB,SAAU,GACV,YAAa,CACX,kBAAmB,GACnB,cAAe,GACf,oBAAqB,EACvB,EACA,aAAc,CACZ,CAEE,eAAeC,EAAMC,EAAQC,EAAOC,EAAgC,CAClE,OAAKA,EAAQ,OACXA,EAAQ,KAAO,CAAC,GAElBA,EAAQ,KAAK,cAAmB,UAAUN,CAAK,GACxCG,EAAKC,EAAQC,EAAOC,CAAO,CACpC,CACF,CACF,CACF,CAAC,EACKtB,EAAS,IAAIuB,EAAaN,CAAK,EAE/BO,EAAO,MAAMC,EACjB,SAAY,MAAMzB,EAAO,QAAQ,CAAC,CAAC,EACnC,CACE,UAAW,GACX,SAAU,IACV,WAAY,EACZ,cAAea,EACjB,CACF,EACA,GAAIW,IAAS,KACX,MAAM,IAAI,MAAM,oBAAoB,EAEtC,IAAME,EAAa,CAAC,GAAIzB,EAAK,YAAc,CAAC,CAAE,EAC9C,QAAWK,KAAKkB,EAAK,SAAS,WAC5BE,EAAW,KAAK,CACd,KAAMpB,EAAE,KACR,SAAUA,EAAE,SACZ,WAAYA,EAAE,UAChB,CAAC,EAEH,IAAMqB,KAAU,cAAqBX,CAAK,EACpCY,EAA4B,CAChC,GAAG3B,EACH,WAAcyB,EACd,QAASC,EAAQ,IACjB,OAAQA,EAAQ,GAClB,EAOA,OANa,IAAI7B,GACf,IAAI+B,EAAO,YAAa,OAAWC,EAAe,EAClD9B,EACA4B,EACAf,EACF,CAEF,CjB7bAkB,EAAQ,WAAW,EAAK,EACxBA,EAAQ,gBAAgB,EAAK,EAC7B,QAAQ,IAAI,OAAQ,UAAU,SAAS,EACvC,QAAQ,IAAI,4BAA6B,KAAK,UAAU,CAAE,KAAMA,EAAQ,YAAa,QAASA,EAAQ,cAAe,EAAG,KAAM,CAAC,CAAC","names":["require_sdp","__commonJSMin","exports","module","SDPUtils","blob","line","part","index","sections","prefix","parts","candidate","i","sdp","component","type","parsed","codec","pt","channels","headerExtension","kv","j","params","param","lines","fb","sp","colon","ssrc","mediaSection","mid","sessionpart","setupType","fp","parameters","keyParams","ufrag","pwd","description","mline","rtpmapline","fmtps","wildcardRtcpFb","existingFeedback","kind","caps","maxptime","extension","encodingParameters","hasRed","hasUlpfec","ssrcs","primarySsrc","secondarySsrc","flows","encParam","bandwidth","rtcpParameters","remoteSsrc","obj","rsize","mux","spec","planB","msidParts","maxSizeLine","maxMessageSize","sctpPort","sctpMapLines","media","sctp","output","sessId","sessVer","sessUser","sessionId","version","peer_exports","__export","Peer","createPeer","__toCommonJS","logDisabled_","deprecationWarnings_","extractVersion","uastring","expr","pos","match","wrapPeerConnectionEvent","window","eventNameToWrap","wrapper","proto","nativeAddEventListener","nativeEventName","cb","wrappedCallback","e","modifiedEvent","nativeRemoveEventListener","unwrappedCb","disableLog","bool","disableWarnings","log","deprecated","oldMethod","newMethod","detectBrowser","result","navigator","chromium","brand","isObject","val","compactObject","data","accumulator","key","isObj","value","isEmptyObject","walkStats","stats","base","resultSet","name","id","filterStats","track","outbound","streamStatsType","filteredResult","trackStats","trackStat","chrome_shim_exports","__export","fixNegotiationNeeded","shimAddTrackRemoveTrack","shimAddTrackRemoveTrackWithNative","shimGetSendersWithDtmf","shimGetUserMedia","shimMediaStream","shimOnTrack","shimPeerConnection","shimSenderReceiverGetStats","logging","log","shimGetUserMedia","window","browserDetails","navigator","constraintsToChrome_","c","cc","key","r","oldname_","prefix","name","oc","mix","shimConstraints_","constraints","func","remap","obj","a","b","face","getSupportedFacingModeLies","matches","devices","d","dev","match","shimError_","e","getUserMedia_","onSuccess","onError","origGetUserMedia","cs","stream","track","shimMediaStream","window","shimOnTrack","f","origSetRemoteDescription","e","te","receiver","r","event","track","wrapPeerConnectionEvent","shimGetSendersWithDtmf","shimSenderWithDtmf","pc","origAddTrack","stream","sender","origRemoveTrack","idx","origAddStream","origRemoveStream","s","origGetSenders","senders","shimSenderReceiverGetStats","result","filterStats","origGetReceivers","receivers","origGetStats","err","shimAddTrackRemoveTrackWithNative","streamId","existingSenders","newSenders","newSender","shimAddTrackRemoveTrack","browserDetails","origGetLocalStreams","nativeStreams","newStream","streams","t","oldStream","replaceInternalStreamId","description","sdp","internalId","externalStream","internalStream","replaceExternalStreamId","method","nativeMethod","methodObj","args","desc","origSetLocalDescription","origLocalDescription","streamid","shimPeerConnection","fixNegotiationNeeded","firefox_shim_exports","__export","shimAddTransceiver","shimCreateAnswer","shimCreateOffer","shimGetDisplayMedia","shimGetParameters","shimGetUserMedia","shimOnTrack","shimPeerConnection","shimRTCDataChannel","shimReceiverGetStats","shimRemoveStream","shimSenderGetStats","shimGetUserMedia","window","browserDetails","navigator","MediaStreamTrack","constraints","onSuccess","onError","deprecated","remap","obj","b","nativeGetUserMedia","c","nativeGetSettings","nativeApplyConstraints","shimGetDisplayMedia","window","preferredMediaSource","constraints","err","shimOnTrack","window","shimPeerConnection","browserDetails","method","nativeMethod","methodObj","modernStatsTypes","nativeGetStats","selector","onSucc","onErr","stats","stat","e","i","shimSenderGetStats","origGetSenders","senders","sender","origAddTrack","shimReceiverGetStats","origGetReceivers","receivers","receiver","wrapPeerConnectionEvent","shimRemoveStream","stream","deprecated","shimRTCDataChannel","shimAddTransceiver","origAddTransceiver","sendEncodings","shouldPerformCheck","encodingParam","transceiver","params","shimGetParameters","origGetParameters","shimCreateOffer","origCreateOffer","shimCreateAnswer","origCreateAnswer","safari_shim_exports","__export","shimAudioContext","shimCallbacksAPI","shimConstraints","shimCreateOfferLegacy","shimGetUserMedia","shimLocalStreamsAPI","shimRTCIceServerUrls","shimRemoteStreamsAPI","shimTrackEventTransceiver","shimLocalStreamsAPI","window","_addTrack","stream","track","streams","index","tracks","sender","shimRemoteStreamsAPI","f","e","event","origSetRemoteDescription","pc","shimCallbacksAPI","prototype","origCreateOffer","origCreateAnswer","setLocalDescription","setRemoteDescription","addIceCandidate","successCallback","failureCallback","options","promise","withCallback","description","candidate","shimGetUserMedia","navigator","mediaDevices","_getUserMedia","constraints","shimConstraints","cb","errcb","compactObject","shimRTCIceServerUrls","OrigPeerConnection","pcConfig","pcConstraints","newIceServers","i","server","deprecated","shimTrackEventTransceiver","shimCreateOfferLegacy","offerOptions","audioTransceiver","transceiver","videoTransceiver","shimAudioContext","common_shim_exports","__export","removeExtmapAllowMixed","shimAddIceCandidateNullOrEmpty","shimConnectionState","shimMaxMessageSize","shimParameterlessSetLocalDescription","shimRTCIceCandidate","shimRTCIceCandidateRelayProtocol","shimSendThrowTypeError","import_sdp","shimRTCIceCandidate","window","NativeRTCIceCandidate","args","nativeCandidate","parsedCandidate","SDPUtils","key","wrapPeerConnectionEvent","e","shimRTCIceCandidateRelayProtocol","shimMaxMessageSize","browserDetails","sctpInDescription","description","sections","mediaSection","mLine","getRemoteFirefoxVersion","match","version","getCanSendMaxMessageSize","remoteIsFirefox","canSendMaxMessageSize","getMaxMessageSize","maxMessageSize","origSetRemoteDescription","sdpSemantics","isFirefox","canSendMMS","remoteMMS","sctp","shimSendThrowTypeError","wrapDcSend","dc","pc","origDataChannelSend","data","length","origCreateDataChannel","dataChannel","shimConnectionState","proto","cb","method","origMethod","newEvent","removeExtmapAllowMixed","nativeSRD","desc","sdp","line","shimAddIceCandidateNullOrEmpty","nativeAddIceCandidate","shimParameterlessSetLocalDescription","nativeSetLocalDescription","d","sdp","adapterFactory","window","options","logging","log","browserDetails","detectBrowser","adapter","common_shim_exports","extractVersion","disableLog","disableWarnings","chrome_shim_exports","shimPeerConnection","shimAddIceCandidateNullOrEmpty","shimParameterlessSetLocalDescription","shimGetUserMedia","shimMediaStream","shimOnTrack","shimAddTrackRemoveTrack","shimGetSendersWithDtmf","shimSenderReceiverGetStats","fixNegotiationNeeded","shimRTCIceCandidate","shimRTCIceCandidateRelayProtocol","shimConnectionState","shimMaxMessageSize","shimSendThrowTypeError","removeExtmapAllowMixed","firefox_shim_exports","shimRemoveStream","shimSenderGetStats","shimReceiverGetStats","shimRTCDataChannel","shimAddTransceiver","shimGetParameters","shimCreateOffer","shimCreateAnswer","safari_shim_exports","shimRTCIceServerUrls","shimCreateOfferLegacy","shimCallbacksAPI","shimLocalStreamsAPI","shimRemoteStreamsAPI","shimTrackEventTransceiver","shimAudioContext","adapter","adapterFactory","adapter_core_default","import_runtime_rpc","import_runtime","SdpKind","PrepareReq$Type","PrepareReq","PrepareResp$Type","IceServer","PrepareResp","IceServer$Type","SendReq$Type","Message","SendReq","SendResp$Type","SendResp","RecvReq$Type","PeerInfo","RecvReq","RecvResp$Type","RecvResp","PeerInfo$Type","Message$Type","MessageHeader","MessagePayload","MessagePayload$Type","Signal","Join","Bye","Ack","MessageHeader$Type","Signal$Type","Sdp","ICECandidate","Sdp$Type","ICECandidate$Type","Join$Type","Bye$Type","Ack$Type","AckRange","AckRange$Type","DataChannel$Type","DataChannelHeartbeat","DataChannel","DataChannelHeartbeat$Type","Tunnel","import_runtime_rpc","TunnelClient","_transport","Tunnel","input","options","method","opt","asleep","ms","signal","resolve","timeoutId","joinSignals","signals","joined","joinedAbort","retry","asyncFunction","options","maxRetries","baseDelay","maxDelay","jitterFactor","isRecoverable","abortSignal","attempt","error","delay","calculateDelay","exponentialDelay","jitter","POLL_TIMEOUT_MS","POLL_RETRY_BASE_DELAY_MS","POLL_RETRY_MAX_DELAY_MS","MAX_RELIABLE_RETRY_COUNT","STREAM_GC_DELAY_MS","STREAM_GC_INTERVAL_MS","defaultAsleep","asleep","defaultRandUint32","reserved","defaultIsRecoverable","_err","Queue","logger","_","msg","seqnum","res","key","value","m","err","obj","Transport","client","opts","_reason","msgs","src","dst","stream","s","Stream","STREAM_GC_INTERVAL_MS","rpcOpt","POLL_TIMEOUT_MS","retryOpt","POLL_RETRY_BASE_DELAY_MS","POLL_RETRY_MAX_DELAY_MS","resp","retry","reason","otherGroupId","otherPeerId","signal","payload","header","found","joinedSignal","joinSignals","transport","info","other","signals","closed","STREAM_GC_DELAY_MS","reliable","resendLimit","MAX_RELIABLE_RETRY_COUNT","tryCount","message","reply","ack","r","DEFAULT_LOG_SINK","PRETTY_LOG_SINK","o","pretty","flatten","obj","pairs","parentKey","visited","sep","key","newKey","p","lines","k","Logger","_Logger","name","sink","handler","message","ICE_RESTART_MAX_COUNT","ICE_RESTART_DEBOUNCE_DELAY_MS","toIceCandidate","ice","toSDPType","kind","fromSDPType","t","Session","stream","config","elapsed","delay","timerId","v","signal","payload","msg","sdp","offerCollision","candidate","e","reason","stats","pair","local","remote","report","start","ev","firstOffer","err","args","timer","closeEvent","s","import_runtime_rpc","import_twirp_transport","import_jwt_decode","BASE_URL","Peer","logger","client","opts","isRecoverable","_s","rtcConfig","Transport","s","sess","Session","otherGroupId","otherPeerId","signal","TWIRP_FATAL_ERRORS","isTwirpRecoverable","err","createPeer","token","twirp","BASE_URL","next","method","input","options","TunnelClient","resp","retry","iceServers","decoded","optsFull","Logger","PRETTY_LOG_SINK","adapter_core_default"]}
|