@pulsebeam/peer 0.0.16 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -9
- package/dist/index.cjs +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -9
- package/dist/index.d.ts +9 -9
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
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 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"]}
|
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","../signaling.ts","../signaling.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 \"signaling.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: pulsebeam.v1.Message msg = 1;\n */\n msg?: 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: \"msg\", kind: \"message\", 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.Signaling\n */\nexport const Signaling = new ServiceType(\"pulsebeam.v1.Signaling\", [\n { name: \"Prepare\", options: {}, I: PrepareReq, O: PrepareResp },\n { name: \"Send\", options: {}, I: SendReq, O: SendResp },\n { name: \"Recv\", serverStreaming: true, options: {}, I: RecvReq, O: RecvResp }\n]);\n","// @generated by protobuf-ts 2.9.4 with parameter client_generic\n// @generated from protobuf file \"signaling.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 { Signaling } from \"./signaling.ts\";\nimport type { RecvResp } from \"./signaling.ts\";\nimport type { RecvReq } from \"./signaling.ts\";\nimport type { ServerStreamingCall } from \"@protobuf-ts/runtime-rpc\";\nimport type { SendResp } from \"./signaling.ts\";\nimport type { SendReq } from \"./signaling.ts\";\nimport { stackIntercept } from \"@protobuf-ts/runtime-rpc\";\nimport type { PrepareResp } from \"./signaling.ts\";\nimport type { PrepareReq } from \"./signaling.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.Signaling\n */\nexport interface ISignalingClient {\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 (stream pulsebeam.v1.RecvResp);\n */\n recv(input: RecvReq, options?: RpcOptions): ServerStreamingCall<RecvReq, RecvResp>;\n}\n/**\n * @generated from protobuf service pulsebeam.v1.Signaling\n */\nexport class SignalingClient implements ISignalingClient, ServiceInfo {\n typeName = Signaling.typeName;\n methods = Signaling.methods;\n options = Signaling.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 (stream pulsebeam.v1.RecvResp);\n */\n recv(input: RecvReq, options?: RpcOptions): ServerStreamingCall<RecvReq, RecvResp> {\n const method = this.methods[2], opt = this._transport.mergeOptions(options);\n return stackIntercept<RecvReq, RecvResp>(\"serverStreaming\", 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 \"./signaling.ts\";\nimport { ISignalingClient } from \"./signaling.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: ISignalingClient,\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 await retry(async () => {\n const recvStream = this.client.recv({\n src: this.info,\n }, rpcOpt);\n\n recvStream.responses.onMessage((m) =>\n !!m.msg && this.handleMessages(m.msg)\n );\n await recvStream;\n }, retryOpt);\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 = (msg: Message) => {\n this.logger.debug(\"received\", { msg: msg });\n if (this.abort.signal.aborted) return;\n if (!msg.header) return;\n const src = msg.header.src;\n const dst = msg.header.dst;\n if (!src || !dst) return;\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 return;\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 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 \"./signaling.ts\";\nimport { Logger } from \"./logger.ts\";\nimport type { Stream } from \"./transport.ts\";\nexport type { PeerInfo } from \"./signaling.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 ISignalingClient, SignalingClient } from \"./signaling.client.ts\";\nimport { Transport } from \"./transport.ts\";\nimport type { PeerInfo } from \"./signaling.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 GrpcStatusCode,\n GrpcWebFetchTransport,\n} from \"@protobuf-ts/grpcweb-transport\";\nimport { retry } from \"./util.ts\";\nimport { jwtDecode } from \"jwt-decode\";\n\nexport type { PeerInfo } from \"./signaling.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/grpc\";\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.other.peerId)};`\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: ISignalingClient,\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 GRPCWEB_FATAL_ERRORS: string[] = [\n GrpcStatusCode[GrpcStatusCode.PERMISSION_DENIED],\n GrpcStatusCode[GrpcStatusCode.INVALID_ARGUMENT],\n GrpcStatusCode[GrpcStatusCode.ABORTED],\n GrpcStatusCode[GrpcStatusCode.NOT_FOUND],\n GrpcStatusCode[GrpcStatusCode.UNAUTHENTICATED],\n];\n\nfunction isRecoverable(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 !GRPCWEB_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 GrpcWebFetchTransport({\n baseUrl: opts.baseUrl || BASE_URL,\n sendJson: false,\n format: \"binary\",\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 SignalingClient(twirp);\n\n const resp = await retry(\n async () => await client.prepare({}),\n {\n baseDelay: 50,\n maxDelay: 1000,\n maxRetries: 5,\n isRecoverable: isRecoverable,\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 isRecoverable,\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","index_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","Signaling","import_runtime_rpc","SignalingClient","_transport","Signaling","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","src","dst","stream","s","Stream","STREAM_GC_INTERVAL_MS","rpcOpt","POLL_TIMEOUT_MS","retryOpt","POLL_RETRY_BASE_DELAY_MS","POLL_RETRY_MAX_DELAY_MS","retry","recvStream","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_grpcweb_transport","import_jwt_decode","BASE_URL","Peer","logger","client","opts","isRecoverable","_s","rtcConfig","Transport","s","sess","Session","otherGroupId","otherPeerId","signal","GRPCWEB_FATAL_ERRORS","err","createPeer","token","twirp","BASE_URL","next","method","input","options","SignalingClient","resp","retry","iceServers","decoded","optsFull","Logger","PRETTY_LOG_SINK","adapter_core_default"]}
|