UNPKG

229 kBJavaScriptView Raw
1(() => {
2
3function $parcel$export(e, n, v, s) {
4 Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
5}
6
7function $parcel$interopDefault(a) {
8 return a && a.__esModule ? a.default : a;
9}
10class $616ebdf1c4998439$export$f1c5f4c9cb95390b {
11 constructor(){
12 this.chunkedMTU = 16300 // The original 60000 bytes setting does not work when sending data from Firefox to Chrome, which is "cut off" after 16384 bytes and delivered individually.
13 ;
14 // Binary stuff
15 this._dataCount = 1;
16 this.chunk = (blob)=>{
17 const chunks = [];
18 const size = blob.byteLength;
19 const total = Math.ceil(size / this.chunkedMTU);
20 let index = 0;
21 let start = 0;
22 while(start < size){
23 const end = Math.min(size, start + this.chunkedMTU);
24 const b = blob.slice(start, end);
25 const chunk = {
26 __peerData: this._dataCount,
27 n: index,
28 data: b,
29 total: total
30 };
31 chunks.push(chunk);
32 start = end;
33 index++;
34 }
35 this._dataCount++;
36 return chunks;
37 };
38 }
39}
40function $616ebdf1c4998439$export$52c89ebcdc4f53f2(bufs) {
41 let size = 0;
42 for (const buf of bufs)size += buf.byteLength;
43 const result = new Uint8Array(size);
44 let offset = 0;
45 for (const buf of bufs){
46 result.set(buf, offset);
47 offset += buf.byteLength;
48 }
49 return result;
50}
51
52
53class $bf7fb46c6d68ead7$var$$e8379818650e2442$export$93654d4f2d6cd524 {
54 append_buffer(data) {
55 this.flush();
56 this._parts.push(data);
57 }
58 append(data) {
59 this._pieces.push(data);
60 }
61 flush() {
62 if (this._pieces.length > 0) {
63 const buf = new Uint8Array(this._pieces);
64 this._parts.push(buf);
65 this._pieces = [];
66 }
67 }
68 toArrayBuffer() {
69 const buffer = [];
70 for (const part of this._parts)buffer.push(part);
71 return $bf7fb46c6d68ead7$var$$e8379818650e2442$var$concatArrayBuffers(buffer).buffer;
72 }
73 constructor(){
74 this.encoder = new TextEncoder();
75 this._pieces = [];
76 this._parts = [];
77 }
78}
79function $bf7fb46c6d68ead7$var$$e8379818650e2442$var$concatArrayBuffers(bufs) {
80 let size = 0;
81 for (const buf of bufs)size += buf.byteLength;
82 const result = new Uint8Array(size);
83 let offset = 0;
84 for (const buf of bufs){
85 const view = new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
86 result.set(view, offset);
87 offset += buf.byteLength;
88 }
89 return result;
90}
91function $bf7fb46c6d68ead7$export$417857010dc9287f(data) {
92 const unpacker = new $bf7fb46c6d68ead7$var$$0cfd7828ad59115f$var$Unpacker(data);
93 return unpacker.unpack();
94}
95function $bf7fb46c6d68ead7$export$2a703dbb0cb35339(data) {
96 const packer = new $bf7fb46c6d68ead7$export$b9ec4b114aa40074();
97 const res = packer.pack(data);
98 if (res instanceof Promise) return res.then(()=>packer.getBuffer());
99 return packer.getBuffer();
100}
101class $bf7fb46c6d68ead7$var$$0cfd7828ad59115f$var$Unpacker {
102 unpack() {
103 const type = this.unpack_uint8();
104 if (type < 0x80) return type;
105 else if ((type ^ 0xe0) < 0x20) return (type ^ 0xe0) - 0x20;
106 let size;
107 if ((size = type ^ 0xa0) <= 0x0f) return this.unpack_raw(size);
108 else if ((size = type ^ 0xb0) <= 0x0f) return this.unpack_string(size);
109 else if ((size = type ^ 0x90) <= 0x0f) return this.unpack_array(size);
110 else if ((size = type ^ 0x80) <= 0x0f) return this.unpack_map(size);
111 switch(type){
112 case 0xc0:
113 return null;
114 case 0xc1:
115 return undefined;
116 case 0xc2:
117 return false;
118 case 0xc3:
119 return true;
120 case 0xca:
121 return this.unpack_float();
122 case 0xcb:
123 return this.unpack_double();
124 case 0xcc:
125 return this.unpack_uint8();
126 case 0xcd:
127 return this.unpack_uint16();
128 case 0xce:
129 return this.unpack_uint32();
130 case 0xcf:
131 return this.unpack_uint64();
132 case 0xd0:
133 return this.unpack_int8();
134 case 0xd1:
135 return this.unpack_int16();
136 case 0xd2:
137 return this.unpack_int32();
138 case 0xd3:
139 return this.unpack_int64();
140 case 0xd4:
141 return undefined;
142 case 0xd5:
143 return undefined;
144 case 0xd6:
145 return undefined;
146 case 0xd7:
147 return undefined;
148 case 0xd8:
149 size = this.unpack_uint16();
150 return this.unpack_string(size);
151 case 0xd9:
152 size = this.unpack_uint32();
153 return this.unpack_string(size);
154 case 0xda:
155 size = this.unpack_uint16();
156 return this.unpack_raw(size);
157 case 0xdb:
158 size = this.unpack_uint32();
159 return this.unpack_raw(size);
160 case 0xdc:
161 size = this.unpack_uint16();
162 return this.unpack_array(size);
163 case 0xdd:
164 size = this.unpack_uint32();
165 return this.unpack_array(size);
166 case 0xde:
167 size = this.unpack_uint16();
168 return this.unpack_map(size);
169 case 0xdf:
170 size = this.unpack_uint32();
171 return this.unpack_map(size);
172 }
173 }
174 unpack_uint8() {
175 const byte = this.dataView[this.index] & 0xff;
176 this.index++;
177 return byte;
178 }
179 unpack_uint16() {
180 const bytes = this.read(2);
181 const uint16 = (bytes[0] & 0xff) * 256 + (bytes[1] & 0xff);
182 this.index += 2;
183 return uint16;
184 }
185 unpack_uint32() {
186 const bytes = this.read(4);
187 const uint32 = ((bytes[0] * 256 + bytes[1]) * 256 + bytes[2]) * 256 + bytes[3];
188 this.index += 4;
189 return uint32;
190 }
191 unpack_uint64() {
192 const bytes = this.read(8);
193 const uint64 = ((((((bytes[0] * 256 + bytes[1]) * 256 + bytes[2]) * 256 + bytes[3]) * 256 + bytes[4]) * 256 + bytes[5]) * 256 + bytes[6]) * 256 + bytes[7];
194 this.index += 8;
195 return uint64;
196 }
197 unpack_int8() {
198 const uint8 = this.unpack_uint8();
199 return uint8 < 0x80 ? uint8 : uint8 - 256;
200 }
201 unpack_int16() {
202 const uint16 = this.unpack_uint16();
203 return uint16 < 0x8000 ? uint16 : uint16 - 65536;
204 }
205 unpack_int32() {
206 const uint32 = this.unpack_uint32();
207 return uint32 < 2 ** 31 ? uint32 : uint32 - 2 ** 32;
208 }
209 unpack_int64() {
210 const uint64 = this.unpack_uint64();
211 return uint64 < 2 ** 63 ? uint64 : uint64 - 2 ** 64;
212 }
213 unpack_raw(size) {
214 if (this.length < this.index + size) throw new Error(`BinaryPackFailure: index is out of range ${this.index} ${size} ${this.length}`);
215 const buf = this.dataBuffer.slice(this.index, this.index + size);
216 this.index += size;
217 return buf;
218 }
219 unpack_string(size) {
220 const bytes = this.read(size);
221 let i = 0;
222 let str = "";
223 let c;
224 let code;
225 while(i < size){
226 c = bytes[i];
227 // The length of a UTF-8 sequence is specified in the first byte:
228 // 0xxxxxxx means length 1,
229 // 110xxxxx means length 2,
230 // 1110xxxx means length 3,
231 // 11110xxx means length 4.
232 // 10xxxxxx is for non-initial bytes.
233 if (c < 0xa0) {
234 // One-byte sequence: bits 0xxxxxxx
235 code = c;
236 i++;
237 } else if ((c ^ 0xc0) < 0x20) {
238 // Two-byte sequence: bits 110xxxxx 10xxxxxx
239 code = (c & 0x1f) << 6 | bytes[i + 1] & 0x3f;
240 i += 2;
241 } else if ((c ^ 0xe0) < 0x10) {
242 // Three-byte sequence: bits 1110xxxx 10xxxxxx 10xxxxxx
243 code = (c & 0x0f) << 12 | (bytes[i + 1] & 0x3f) << 6 | bytes[i + 2] & 0x3f;
244 i += 3;
245 } else {
246 // Four-byte sequence: bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
247 code = (c & 0x07) << 18 | (bytes[i + 1] & 0x3f) << 12 | (bytes[i + 2] & 0x3f) << 6 | bytes[i + 3] & 0x3f;
248 i += 4;
249 }
250 str += String.fromCodePoint(code);
251 }
252 this.index += size;
253 return str;
254 }
255 unpack_array(size) {
256 const objects = new Array(size);
257 for(let i = 0; i < size; i++)objects[i] = this.unpack();
258 return objects;
259 }
260 unpack_map(size) {
261 const map = {};
262 for(let i = 0; i < size; i++){
263 const key = this.unpack();
264 map[key] = this.unpack();
265 }
266 return map;
267 }
268 unpack_float() {
269 const uint32 = this.unpack_uint32();
270 const sign = uint32 >> 31;
271 const exp = (uint32 >> 23 & 0xff) - 127;
272 const fraction = uint32 & 0x7fffff | 0x800000;
273 return (sign === 0 ? 1 : -1) * fraction * 2 ** (exp - 23);
274 }
275 unpack_double() {
276 const h32 = this.unpack_uint32();
277 const l32 = this.unpack_uint32();
278 const sign = h32 >> 31;
279 const exp = (h32 >> 20 & 0x7ff) - 1023;
280 const hfrac = h32 & 0xfffff | 0x100000;
281 const frac = hfrac * 2 ** (exp - 20) + l32 * 2 ** (exp - 52);
282 return (sign === 0 ? 1 : -1) * frac;
283 }
284 read(length) {
285 const j = this.index;
286 if (j + length <= this.length) return this.dataView.subarray(j, j + length);
287 else throw new Error("BinaryPackFailure: read index out of range");
288 }
289 constructor(data){
290 this.index = 0;
291 this.dataBuffer = data;
292 this.dataView = new Uint8Array(this.dataBuffer);
293 this.length = this.dataBuffer.byteLength;
294 }
295}
296class $bf7fb46c6d68ead7$export$b9ec4b114aa40074 {
297 getBuffer() {
298 return this._bufferBuilder.toArrayBuffer();
299 }
300 pack(value) {
301 if (typeof value === "string") this.pack_string(value);
302 else if (typeof value === "number") {
303 if (Math.floor(value) === value) this.pack_integer(value);
304 else this.pack_double(value);
305 } else if (typeof value === "boolean") {
306 if (value === true) this._bufferBuilder.append(0xc3);
307 else if (value === false) this._bufferBuilder.append(0xc2);
308 } else if (value === undefined) this._bufferBuilder.append(0xc0);
309 else if (typeof value === "object") {
310 if (value === null) this._bufferBuilder.append(0xc0);
311 else {
312 const constructor = value.constructor;
313 if (value instanceof Array) {
314 const res = this.pack_array(value);
315 if (res instanceof Promise) return res.then(()=>this._bufferBuilder.flush());
316 } else if (value instanceof ArrayBuffer) this.pack_bin(new Uint8Array(value));
317 else if ("BYTES_PER_ELEMENT" in value) {
318 const v = value;
319 this.pack_bin(new Uint8Array(v.buffer, v.byteOffset, v.byteLength));
320 } else if (value instanceof Date) this.pack_string(value.toString());
321 else if (value instanceof Blob) return value.arrayBuffer().then((buffer)=>{
322 this.pack_bin(new Uint8Array(buffer));
323 this._bufferBuilder.flush();
324 });
325 else if (constructor == Object || constructor.toString().startsWith("class")) {
326 const res = this.pack_object(value);
327 if (res instanceof Promise) return res.then(()=>this._bufferBuilder.flush());
328 } else throw new Error(`Type "${constructor.toString()}" not yet supported`);
329 }
330 } else throw new Error(`Type "${typeof value}" not yet supported`);
331 this._bufferBuilder.flush();
332 }
333 pack_bin(blob) {
334 const length = blob.length;
335 if (length <= 0x0f) this.pack_uint8(0xa0 + length);
336 else if (length <= 0xffff) {
337 this._bufferBuilder.append(0xda);
338 this.pack_uint16(length);
339 } else if (length <= 0xffffffff) {
340 this._bufferBuilder.append(0xdb);
341 this.pack_uint32(length);
342 } else throw new Error("Invalid length");
343 this._bufferBuilder.append_buffer(blob);
344 }
345 pack_string(str) {
346 const encoded = this._textEncoder.encode(str);
347 const length = encoded.length;
348 if (length <= 0x0f) this.pack_uint8(0xb0 + length);
349 else if (length <= 0xffff) {
350 this._bufferBuilder.append(0xd8);
351 this.pack_uint16(length);
352 } else if (length <= 0xffffffff) {
353 this._bufferBuilder.append(0xd9);
354 this.pack_uint32(length);
355 } else throw new Error("Invalid length");
356 this._bufferBuilder.append_buffer(encoded);
357 }
358 pack_array(ary) {
359 const length = ary.length;
360 if (length <= 0x0f) this.pack_uint8(0x90 + length);
361 else if (length <= 0xffff) {
362 this._bufferBuilder.append(0xdc);
363 this.pack_uint16(length);
364 } else if (length <= 0xffffffff) {
365 this._bufferBuilder.append(0xdd);
366 this.pack_uint32(length);
367 } else throw new Error("Invalid length");
368 const packNext = (index)=>{
369 if (index < length) {
370 const res = this.pack(ary[index]);
371 if (res instanceof Promise) return res.then(()=>packNext(index + 1));
372 return packNext(index + 1);
373 }
374 };
375 return packNext(0);
376 }
377 pack_integer(num) {
378 if (num >= -32 && num <= 0x7f) this._bufferBuilder.append(num & 0xff);
379 else if (num >= 0x00 && num <= 0xff) {
380 this._bufferBuilder.append(0xcc);
381 this.pack_uint8(num);
382 } else if (num >= -128 && num <= 0x7f) {
383 this._bufferBuilder.append(0xd0);
384 this.pack_int8(num);
385 } else if (num >= 0x0000 && num <= 0xffff) {
386 this._bufferBuilder.append(0xcd);
387 this.pack_uint16(num);
388 } else if (num >= -32768 && num <= 0x7fff) {
389 this._bufferBuilder.append(0xd1);
390 this.pack_int16(num);
391 } else if (num >= 0x00000000 && num <= 0xffffffff) {
392 this._bufferBuilder.append(0xce);
393 this.pack_uint32(num);
394 } else if (num >= -2147483648 && num <= 0x7fffffff) {
395 this._bufferBuilder.append(0xd2);
396 this.pack_int32(num);
397 } else if (num >= -9223372036854776000 && num <= 0x7fffffffffffffff) {
398 this._bufferBuilder.append(0xd3);
399 this.pack_int64(num);
400 } else if (num >= 0x0000000000000000 && num <= 0xffffffffffffffff) {
401 this._bufferBuilder.append(0xcf);
402 this.pack_uint64(num);
403 } else throw new Error("Invalid integer");
404 }
405 pack_double(num) {
406 let sign = 0;
407 if (num < 0) {
408 sign = 1;
409 num = -num;
410 }
411 const exp = Math.floor(Math.log(num) / Math.LN2);
412 const frac0 = num / 2 ** exp - 1;
413 const frac1 = Math.floor(frac0 * 2 ** 52);
414 const b32 = 2 ** 32;
415 const h32 = sign << 31 | exp + 1023 << 20 | frac1 / b32 & 0x0fffff;
416 const l32 = frac1 % b32;
417 this._bufferBuilder.append(0xcb);
418 this.pack_int32(h32);
419 this.pack_int32(l32);
420 }
421 pack_object(obj) {
422 const keys = Object.keys(obj);
423 const length = keys.length;
424 if (length <= 0x0f) this.pack_uint8(0x80 + length);
425 else if (length <= 0xffff) {
426 this._bufferBuilder.append(0xde);
427 this.pack_uint16(length);
428 } else if (length <= 0xffffffff) {
429 this._bufferBuilder.append(0xdf);
430 this.pack_uint32(length);
431 } else throw new Error("Invalid length");
432 const packNext = (index)=>{
433 if (index < keys.length) {
434 const prop = keys[index];
435 // eslint-disable-next-line no-prototype-builtins
436 if (obj.hasOwnProperty(prop)) {
437 this.pack(prop);
438 const res = this.pack(obj[prop]);
439 if (res instanceof Promise) return res.then(()=>packNext(index + 1));
440 }
441 return packNext(index + 1);
442 }
443 };
444 return packNext(0);
445 }
446 pack_uint8(num) {
447 this._bufferBuilder.append(num);
448 }
449 pack_uint16(num) {
450 this._bufferBuilder.append(num >> 8);
451 this._bufferBuilder.append(num & 0xff);
452 }
453 pack_uint32(num) {
454 const n = num & 0xffffffff;
455 this._bufferBuilder.append((n & 0xff000000) >>> 24);
456 this._bufferBuilder.append((n & 0x00ff0000) >>> 16);
457 this._bufferBuilder.append((n & 0x0000ff00) >>> 8);
458 this._bufferBuilder.append(n & 0x000000ff);
459 }
460 pack_uint64(num) {
461 const high = num / 2 ** 32;
462 const low = num % 2 ** 32;
463 this._bufferBuilder.append((high & 0xff000000) >>> 24);
464 this._bufferBuilder.append((high & 0x00ff0000) >>> 16);
465 this._bufferBuilder.append((high & 0x0000ff00) >>> 8);
466 this._bufferBuilder.append(high & 0x000000ff);
467 this._bufferBuilder.append((low & 0xff000000) >>> 24);
468 this._bufferBuilder.append((low & 0x00ff0000) >>> 16);
469 this._bufferBuilder.append((low & 0x0000ff00) >>> 8);
470 this._bufferBuilder.append(low & 0x000000ff);
471 }
472 pack_int8(num) {
473 this._bufferBuilder.append(num & 0xff);
474 }
475 pack_int16(num) {
476 this._bufferBuilder.append((num & 0xff00) >> 8);
477 this._bufferBuilder.append(num & 0xff);
478 }
479 pack_int32(num) {
480 this._bufferBuilder.append(num >>> 24 & 0xff);
481 this._bufferBuilder.append((num & 0x00ff0000) >>> 16);
482 this._bufferBuilder.append((num & 0x0000ff00) >>> 8);
483 this._bufferBuilder.append(num & 0x000000ff);
484 }
485 pack_int64(num) {
486 const high = Math.floor(num / 2 ** 32);
487 const low = num % 2 ** 32;
488 this._bufferBuilder.append((high & 0xff000000) >>> 24);
489 this._bufferBuilder.append((high & 0x00ff0000) >>> 16);
490 this._bufferBuilder.append((high & 0x0000ff00) >>> 8);
491 this._bufferBuilder.append(high & 0x000000ff);
492 this._bufferBuilder.append((low & 0xff000000) >>> 24);
493 this._bufferBuilder.append((low & 0x00ff0000) >>> 16);
494 this._bufferBuilder.append((low & 0x0000ff00) >>> 8);
495 this._bufferBuilder.append(low & 0x000000ff);
496 }
497 constructor(){
498 this._bufferBuilder = new $bf7fb46c6d68ead7$var$$e8379818650e2442$export$93654d4f2d6cd524();
499 this._textEncoder = new TextEncoder();
500 }
501}
502
503
504/*
505 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
506 *
507 * Use of this source code is governed by a BSD-style license
508 * that can be found in the LICENSE file in the root of the source
509 * tree.
510 */ /* eslint-env node */ /*
511 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
512 *
513 * Use of this source code is governed by a BSD-style license
514 * that can be found in the LICENSE file in the root of the source
515 * tree.
516 */ /*
517 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
518 *
519 * Use of this source code is governed by a BSD-style license
520 * that can be found in the LICENSE file in the root of the source
521 * tree.
522 */ /* eslint-env node */ "use strict";
523let $9fea4db837311579$var$logDisabled_ = true;
524let $9fea4db837311579$var$deprecationWarnings_ = true;
525function $9fea4db837311579$export$e3c02be309be1f23(uastring, expr, pos) {
526 const match = uastring.match(expr);
527 return match && match.length >= pos && parseInt(match[pos], 10);
528}
529function $9fea4db837311579$export$1f48841962b828b1(window1, eventNameToWrap, wrapper) {
530 if (!window1.RTCPeerConnection) return;
531 const proto = window1.RTCPeerConnection.prototype;
532 const nativeAddEventListener = proto.addEventListener;
533 proto.addEventListener = function(nativeEventName, cb) {
534 if (nativeEventName !== eventNameToWrap) return nativeAddEventListener.apply(this, arguments);
535 const wrappedCallback = (e)=>{
536 const modifiedEvent = wrapper(e);
537 if (modifiedEvent) {
538 if (cb.handleEvent) cb.handleEvent(modifiedEvent);
539 else cb(modifiedEvent);
540 }
541 };
542 this._eventMap = this._eventMap || {};
543 if (!this._eventMap[eventNameToWrap]) this._eventMap[eventNameToWrap] = new Map();
544 this._eventMap[eventNameToWrap].set(cb, wrappedCallback);
545 return nativeAddEventListener.apply(this, [
546 nativeEventName,
547 wrappedCallback
548 ]);
549 };
550 const nativeRemoveEventListener = proto.removeEventListener;
551 proto.removeEventListener = function(nativeEventName, cb) {
552 if (nativeEventName !== eventNameToWrap || !this._eventMap || !this._eventMap[eventNameToWrap]) return nativeRemoveEventListener.apply(this, arguments);
553 if (!this._eventMap[eventNameToWrap].has(cb)) return nativeRemoveEventListener.apply(this, arguments);
554 const unwrappedCb = this._eventMap[eventNameToWrap].get(cb);
555 this._eventMap[eventNameToWrap].delete(cb);
556 if (this._eventMap[eventNameToWrap].size === 0) delete this._eventMap[eventNameToWrap];
557 if (Object.keys(this._eventMap).length === 0) delete this._eventMap;
558 return nativeRemoveEventListener.apply(this, [
559 nativeEventName,
560 unwrappedCb
561 ]);
562 };
563 Object.defineProperty(proto, "on" + eventNameToWrap, {
564 get () {
565 return this["_on" + eventNameToWrap];
566 },
567 set (cb) {
568 if (this["_on" + eventNameToWrap]) {
569 this.removeEventListener(eventNameToWrap, this["_on" + eventNameToWrap]);
570 delete this["_on" + eventNameToWrap];
571 }
572 if (cb) this.addEventListener(eventNameToWrap, this["_on" + eventNameToWrap] = cb);
573 },
574 enumerable: true,
575 configurable: true
576 });
577}
578function $9fea4db837311579$export$afbfee8cc06fd3e4(bool) {
579 if (typeof bool !== "boolean") return new Error("Argument type: " + typeof bool + ". Please use a boolean.");
580 $9fea4db837311579$var$logDisabled_ = bool;
581 return bool ? "adapter.js logging disabled" : "adapter.js logging enabled";
582}
583function $9fea4db837311579$export$51516be4b019e41e(bool) {
584 if (typeof bool !== "boolean") return new Error("Argument type: " + typeof bool + ". Please use a boolean.");
585 $9fea4db837311579$var$deprecationWarnings_ = !bool;
586 return "adapter.js deprecation warnings " + (bool ? "disabled" : "enabled");
587}
588function $9fea4db837311579$export$bef1f36f5486a6a3() {
589 if (typeof window === "object") {
590 if ($9fea4db837311579$var$logDisabled_) return;
591 if (typeof console !== "undefined" && typeof console.log === "function") console.log.apply(console, arguments);
592 }
593}
594function $9fea4db837311579$export$cdd73fc4100a6ef4(oldMethod, newMethod) {
595 if (!$9fea4db837311579$var$deprecationWarnings_) return;
596 console.warn(oldMethod + " is deprecated, please use " + newMethod + " instead.");
597}
598function $9fea4db837311579$export$2d31490a0c05f094(window1) {
599 // Returned result object.
600 const result = {
601 browser: null,
602 version: null
603 };
604 // Fail early if it's not a browser
605 if (typeof window1 === "undefined" || !window1.navigator || !window1.navigator.userAgent) {
606 result.browser = "Not a browser.";
607 return result;
608 }
609 const { navigator: navigator } = window1;
610 if (navigator.mozGetUserMedia) {
611 result.browser = "firefox";
612 result.version = $9fea4db837311579$export$e3c02be309be1f23(navigator.userAgent, /Firefox\/(\d+)\./, 1);
613 } else if (navigator.webkitGetUserMedia || window1.isSecureContext === false && window1.webkitRTCPeerConnection) {
614 // Chrome, Chromium, Webview, Opera.
615 // Version matches Chrome/WebRTC version.
616 // Chrome 74 removed webkitGetUserMedia on http as well so we need the
617 // more complicated fallback to webkitRTCPeerConnection.
618 result.browser = "chrome";
619 result.version = $9fea4db837311579$export$e3c02be309be1f23(navigator.userAgent, /Chrom(e|ium)\/(\d+)\./, 2);
620 } else if (window1.RTCPeerConnection && navigator.userAgent.match(/AppleWebKit\/(\d+)\./)) {
621 result.browser = "safari";
622 result.version = $9fea4db837311579$export$e3c02be309be1f23(navigator.userAgent, /AppleWebKit\/(\d+)\./, 1);
623 result.supportsUnifiedPlan = window1.RTCRtpTransceiver && "currentDirection" in window1.RTCRtpTransceiver.prototype;
624 } else {
625 result.browser = "Not a supported browser.";
626 return result;
627 }
628 return result;
629}
630/**
631 * Checks if something is an object.
632 *
633 * @param {*} val The something you want to check.
634 * @return true if val is an object, false otherwise.
635 */ function $9fea4db837311579$var$isObject(val) {
636 return Object.prototype.toString.call(val) === "[object Object]";
637}
638function $9fea4db837311579$export$15384eac40dc88c8(data) {
639 if (!$9fea4db837311579$var$isObject(data)) return data;
640 return Object.keys(data).reduce(function(accumulator, key) {
641 const isObj = $9fea4db837311579$var$isObject(data[key]);
642 const value = isObj ? $9fea4db837311579$export$15384eac40dc88c8(data[key]) : data[key];
643 const isEmptyObject = isObj && !Object.keys(value).length;
644 if (value === undefined || isEmptyObject) return accumulator;
645 return Object.assign(accumulator, {
646 [key]: value
647 });
648 }, {});
649}
650function $9fea4db837311579$export$571b373e75babb58(stats, base, resultSet) {
651 if (!base || resultSet.has(base.id)) return;
652 resultSet.set(base.id, base);
653 Object.keys(base).forEach((name)=>{
654 if (name.endsWith("Id")) $9fea4db837311579$export$571b373e75babb58(stats, stats.get(base[name]), resultSet);
655 else if (name.endsWith("Ids")) base[name].forEach((id)=>{
656 $9fea4db837311579$export$571b373e75babb58(stats, stats.get(id), resultSet);
657 });
658 });
659}
660function $9fea4db837311579$export$93439ffc3f787d51(result, track, outbound) {
661 const streamStatsType = outbound ? "outbound-rtp" : "inbound-rtp";
662 const filteredResult = new Map();
663 if (track === null) return filteredResult;
664 const trackStats = [];
665 result.forEach((value)=>{
666 if (value.type === "track" && value.trackIdentifier === track.id) trackStats.push(value);
667 });
668 trackStats.forEach((trackStat)=>{
669 result.forEach((stats)=>{
670 if (stats.type === streamStatsType && stats.trackId === trackStat.id) $9fea4db837311579$export$571b373e75babb58(result, stats, filteredResult);
671 });
672 });
673 return filteredResult;
674}
675
676
677var $fb04e59b477f17ce$exports = {};
678
679$parcel$export($fb04e59b477f17ce$exports, "shimMediaStream", () => $fb04e59b477f17ce$export$33ee24e7a300bcd1);
680$parcel$export($fb04e59b477f17ce$exports, "shimOnTrack", () => $fb04e59b477f17ce$export$f358708f68ab068);
681$parcel$export($fb04e59b477f17ce$exports, "shimGetSendersWithDtmf", () => $fb04e59b477f17ce$export$a41a030a2842f5d6);
682$parcel$export($fb04e59b477f17ce$exports, "shimGetStats", () => $fb04e59b477f17ce$export$90608323826f0b17);
683$parcel$export($fb04e59b477f17ce$exports, "shimSenderReceiverGetStats", () => $fb04e59b477f17ce$export$f2f0f2338114eb4b);
684$parcel$export($fb04e59b477f17ce$exports, "shimAddTrackRemoveTrackWithNative", () => $fb04e59b477f17ce$export$30e3cdd46f8d5100);
685$parcel$export($fb04e59b477f17ce$exports, "shimAddTrackRemoveTrack", () => $fb04e59b477f17ce$export$9588259fcf4ebc91);
686$parcel$export($fb04e59b477f17ce$exports, "shimPeerConnection", () => $fb04e59b477f17ce$export$852a08dda9a55ea7);
687$parcel$export($fb04e59b477f17ce$exports, "fixNegotiationNeeded", () => $fb04e59b477f17ce$export$341293bbeaae37cb);
688$parcel$export($fb04e59b477f17ce$exports, "shimGetUserMedia", () => $de41d89a4eaa283f$export$1ed4910f4d37dc5e);
689$parcel$export($fb04e59b477f17ce$exports, "shimGetDisplayMedia", () => $9942794957ef486f$export$97270b87351d9c04);
690/*
691 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
692 *
693 * Use of this source code is governed by a BSD-style license
694 * that can be found in the LICENSE file in the root of the source
695 * tree.
696 */ /* eslint-env node */
697/*
698 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
699 *
700 * Use of this source code is governed by a BSD-style license
701 * that can be found in the LICENSE file in the root of the source
702 * tree.
703 */ /* eslint-env node */
704"use strict";
705const $de41d89a4eaa283f$var$logging = $9fea4db837311579$export$bef1f36f5486a6a3;
706function $de41d89a4eaa283f$export$1ed4910f4d37dc5e(window, browserDetails) {
707 const navigator = window && window.navigator;
708 if (!navigator.mediaDevices) return;
709 const constraintsToChrome_ = function(c) {
710 if (typeof c !== "object" || c.mandatory || c.optional) return c;
711 const cc = {};
712 Object.keys(c).forEach((key)=>{
713 if (key === "require" || key === "advanced" || key === "mediaSource") return;
714 const r = typeof c[key] === "object" ? c[key] : {
715 ideal: c[key]
716 };
717 if (r.exact !== undefined && typeof r.exact === "number") r.min = r.max = r.exact;
718 const oldname_ = function(prefix, name) {
719 if (prefix) return prefix + name.charAt(0).toUpperCase() + name.slice(1);
720 return name === "deviceId" ? "sourceId" : name;
721 };
722 if (r.ideal !== undefined) {
723 cc.optional = cc.optional || [];
724 let oc = {};
725 if (typeof r.ideal === "number") {
726 oc[oldname_("min", key)] = r.ideal;
727 cc.optional.push(oc);
728 oc = {};
729 oc[oldname_("max", key)] = r.ideal;
730 cc.optional.push(oc);
731 } else {
732 oc[oldname_("", key)] = r.ideal;
733 cc.optional.push(oc);
734 }
735 }
736 if (r.exact !== undefined && typeof r.exact !== "number") {
737 cc.mandatory = cc.mandatory || {};
738 cc.mandatory[oldname_("", key)] = r.exact;
739 } else [
740 "min",
741 "max"
742 ].forEach((mix)=>{
743 if (r[mix] !== undefined) {
744 cc.mandatory = cc.mandatory || {};
745 cc.mandatory[oldname_(mix, key)] = r[mix];
746 }
747 });
748 });
749 if (c.advanced) cc.optional = (cc.optional || []).concat(c.advanced);
750 return cc;
751 };
752 const shimConstraints_ = function(constraints, func) {
753 if (browserDetails.version >= 61) return func(constraints);
754 constraints = JSON.parse(JSON.stringify(constraints));
755 if (constraints && typeof constraints.audio === "object") {
756 const remap = function(obj, a, b) {
757 if (a in obj && !(b in obj)) {
758 obj[b] = obj[a];
759 delete obj[a];
760 }
761 };
762 constraints = JSON.parse(JSON.stringify(constraints));
763 remap(constraints.audio, "autoGainControl", "googAutoGainControl");
764 remap(constraints.audio, "noiseSuppression", "googNoiseSuppression");
765 constraints.audio = constraintsToChrome_(constraints.audio);
766 }
767 if (constraints && typeof constraints.video === "object") {
768 // Shim facingMode for mobile & surface pro.
769 let face = constraints.video.facingMode;
770 face = face && (typeof face === "object" ? face : {
771 ideal: face
772 });
773 const getSupportedFacingModeLies = browserDetails.version < 66;
774 if (face && (face.exact === "user" || face.exact === "environment" || face.ideal === "user" || face.ideal === "environment") && !(navigator.mediaDevices.getSupportedConstraints && navigator.mediaDevices.getSupportedConstraints().facingMode && !getSupportedFacingModeLies)) {
775 delete constraints.video.facingMode;
776 let matches;
777 if (face.exact === "environment" || face.ideal === "environment") matches = [
778 "back",
779 "rear"
780 ];
781 else if (face.exact === "user" || face.ideal === "user") matches = [
782 "front"
783 ];
784 if (matches) // Look for matches in label, or use last cam for back (typical).
785 return navigator.mediaDevices.enumerateDevices().then((devices)=>{
786 devices = devices.filter((d)=>d.kind === "videoinput");
787 let dev = devices.find((d)=>matches.some((match)=>d.label.toLowerCase().includes(match)));
788 if (!dev && devices.length && matches.includes("back")) dev = devices[devices.length - 1]; // more likely the back cam
789 if (dev) constraints.video.deviceId = face.exact ? {
790 exact: dev.deviceId
791 } : {
792 ideal: dev.deviceId
793 };
794 constraints.video = constraintsToChrome_(constraints.video);
795 $de41d89a4eaa283f$var$logging("chrome: " + JSON.stringify(constraints));
796 return func(constraints);
797 });
798 }
799 constraints.video = constraintsToChrome_(constraints.video);
800 }
801 $de41d89a4eaa283f$var$logging("chrome: " + JSON.stringify(constraints));
802 return func(constraints);
803 };
804 const shimError_ = function(e) {
805 if (browserDetails.version >= 64) return e;
806 return {
807 name: ({
808 PermissionDeniedError: "NotAllowedError",
809 PermissionDismissedError: "NotAllowedError",
810 InvalidStateError: "NotAllowedError",
811 DevicesNotFoundError: "NotFoundError",
812 ConstraintNotSatisfiedError: "OverconstrainedError",
813 TrackStartError: "NotReadableError",
814 MediaDeviceFailedDueToShutdown: "NotAllowedError",
815 MediaDeviceKillSwitchOn: "NotAllowedError",
816 TabCaptureError: "AbortError",
817 ScreenCaptureError: "AbortError",
818 DeviceCaptureError: "AbortError"
819 })[e.name] || e.name,
820 message: e.message,
821 constraint: e.constraint || e.constraintName,
822 toString () {
823 return this.name + (this.message && ": ") + this.message;
824 }
825 };
826 };
827 const getUserMedia_ = function(constraints, onSuccess, onError) {
828 shimConstraints_(constraints, (c)=>{
829 navigator.webkitGetUserMedia(c, onSuccess, (e)=>{
830 if (onError) onError(shimError_(e));
831 });
832 });
833 };
834 navigator.getUserMedia = getUserMedia_.bind(navigator);
835 // Even though Chrome 45 has navigator.mediaDevices and a getUserMedia
836 // function which returns a Promise, it does not accept spec-style
837 // constraints.
838 if (navigator.mediaDevices.getUserMedia) {
839 const origGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);
840 navigator.mediaDevices.getUserMedia = function(cs) {
841 return shimConstraints_(cs, (c)=>origGetUserMedia(c).then((stream)=>{
842 if (c.audio && !stream.getAudioTracks().length || c.video && !stream.getVideoTracks().length) {
843 stream.getTracks().forEach((track)=>{
844 track.stop();
845 });
846 throw new DOMException("", "NotFoundError");
847 }
848 return stream;
849 }, (e)=>Promise.reject(shimError_(e))));
850 };
851 }
852}
853
854
855/*
856 * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.
857 *
858 * Use of this source code is governed by a BSD-style license
859 * that can be found in the LICENSE file in the root of the source
860 * tree.
861 */ /* eslint-env node */ "use strict";
862function $9942794957ef486f$export$97270b87351d9c04(window, getSourceId) {
863 if (window.navigator.mediaDevices && "getDisplayMedia" in window.navigator.mediaDevices) return;
864 if (!window.navigator.mediaDevices) return;
865 // getSourceId is a function that returns a promise resolving with
866 // the sourceId of the screen/window/tab to be shared.
867 if (typeof getSourceId !== "function") {
868 console.error("shimGetDisplayMedia: getSourceId argument is not a function");
869 return;
870 }
871 window.navigator.mediaDevices.getDisplayMedia = function getDisplayMedia(constraints) {
872 return getSourceId(constraints).then((sourceId)=>{
873 const widthSpecified = constraints.video && constraints.video.width;
874 const heightSpecified = constraints.video && constraints.video.height;
875 const frameRateSpecified = constraints.video && constraints.video.frameRate;
876 constraints.video = {
877 mandatory: {
878 chromeMediaSource: "desktop",
879 chromeMediaSourceId: sourceId,
880 maxFrameRate: frameRateSpecified || 3
881 }
882 };
883 if (widthSpecified) constraints.video.mandatory.maxWidth = widthSpecified;
884 if (heightSpecified) constraints.video.mandatory.maxHeight = heightSpecified;
885 return window.navigator.mediaDevices.getUserMedia(constraints);
886 });
887 };
888}
889
890
891"use strict";
892function $fb04e59b477f17ce$export$33ee24e7a300bcd1(window) {
893 window.MediaStream = window.MediaStream || window.webkitMediaStream;
894}
895function $fb04e59b477f17ce$export$f358708f68ab068(window) {
896 if (typeof window === "object" && window.RTCPeerConnection && !("ontrack" in window.RTCPeerConnection.prototype)) {
897 Object.defineProperty(window.RTCPeerConnection.prototype, "ontrack", {
898 get () {
899 return this._ontrack;
900 },
901 set (f) {
902 if (this._ontrack) this.removeEventListener("track", this._ontrack);
903 this.addEventListener("track", this._ontrack = f);
904 },
905 enumerable: true,
906 configurable: true
907 });
908 const origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription;
909 window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() {
910 if (!this._ontrackpoly) {
911 this._ontrackpoly = (e)=>{
912 // onaddstream does not fire when a track is added to an existing
913 // stream. But stream.onaddtrack is implemented so we use that.
914 e.stream.addEventListener("addtrack", (te)=>{
915 let receiver;
916 if (window.RTCPeerConnection.prototype.getReceivers) receiver = this.getReceivers().find((r)=>r.track && r.track.id === te.track.id);
917 else receiver = {
918 track: te.track
919 };
920 const event = new Event("track");
921 event.track = te.track;
922 event.receiver = receiver;
923 event.transceiver = {
924 receiver: receiver
925 };
926 event.streams = [
927 e.stream
928 ];
929 this.dispatchEvent(event);
930 });
931 e.stream.getTracks().forEach((track)=>{
932 let receiver;
933 if (window.RTCPeerConnection.prototype.getReceivers) receiver = this.getReceivers().find((r)=>r.track && r.track.id === track.id);
934 else receiver = {
935 track: track
936 };
937 const event = new Event("track");
938 event.track = track;
939 event.receiver = receiver;
940 event.transceiver = {
941 receiver: receiver
942 };
943 event.streams = [
944 e.stream
945 ];
946 this.dispatchEvent(event);
947 });
948 };
949 this.addEventListener("addstream", this._ontrackpoly);
950 }
951 return origSetRemoteDescription.apply(this, arguments);
952 };
953 } else // even if RTCRtpTransceiver is in window, it is only used and
954 // emitted in unified-plan. Unfortunately this means we need
955 // to unconditionally wrap the event.
956 $9fea4db837311579$export$1f48841962b828b1(window, "track", (e)=>{
957 if (!e.transceiver) Object.defineProperty(e, "transceiver", {
958 value: {
959 receiver: e.receiver
960 }
961 });
962 return e;
963 });
964}
965function $fb04e59b477f17ce$export$a41a030a2842f5d6(window) {
966 // Overrides addTrack/removeTrack, depends on shimAddTrackRemoveTrack.
967 if (typeof window === "object" && window.RTCPeerConnection && !("getSenders" in window.RTCPeerConnection.prototype) && "createDTMFSender" in window.RTCPeerConnection.prototype) {
968 const shimSenderWithDtmf = function(pc, track) {
969 return {
970 track: track,
971 get dtmf () {
972 if (this._dtmf === undefined) {
973 if (track.kind === "audio") this._dtmf = pc.createDTMFSender(track);
974 else this._dtmf = null;
975 }
976 return this._dtmf;
977 },
978 _pc: pc
979 };
980 };
981 // augment addTrack when getSenders is not available.
982 if (!window.RTCPeerConnection.prototype.getSenders) {
983 window.RTCPeerConnection.prototype.getSenders = function getSenders() {
984 this._senders = this._senders || [];
985 return this._senders.slice(); // return a copy of the internal state.
986 };
987 const origAddTrack = window.RTCPeerConnection.prototype.addTrack;
988 window.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) {
989 let sender = origAddTrack.apply(this, arguments);
990 if (!sender) {
991 sender = shimSenderWithDtmf(this, track);
992 this._senders.push(sender);
993 }
994 return sender;
995 };
996 const origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;
997 window.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) {
998 origRemoveTrack.apply(this, arguments);
999 const idx = this._senders.indexOf(sender);
1000 if (idx !== -1) this._senders.splice(idx, 1);
1001 };
1002 }
1003 const origAddStream = window.RTCPeerConnection.prototype.addStream;
1004 window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
1005 this._senders = this._senders || [];
1006 origAddStream.apply(this, [
1007 stream
1008 ]);
1009 stream.getTracks().forEach((track)=>{
1010 this._senders.push(shimSenderWithDtmf(this, track));
1011 });
1012 };
1013 const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
1014 window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
1015 this._senders = this._senders || [];
1016 origRemoveStream.apply(this, [
1017 stream
1018 ]);
1019 stream.getTracks().forEach((track)=>{
1020 const sender = this._senders.find((s)=>s.track === track);
1021 if (sender) this._senders.splice(this._senders.indexOf(sender), 1);
1022 });
1023 };
1024 } else if (typeof window === "object" && window.RTCPeerConnection && "getSenders" in window.RTCPeerConnection.prototype && "createDTMFSender" in window.RTCPeerConnection.prototype && window.RTCRtpSender && !("dtmf" in window.RTCRtpSender.prototype)) {
1025 const origGetSenders = window.RTCPeerConnection.prototype.getSenders;
1026 window.RTCPeerConnection.prototype.getSenders = function getSenders() {
1027 const senders = origGetSenders.apply(this, []);
1028 senders.forEach((sender)=>sender._pc = this);
1029 return senders;
1030 };
1031 Object.defineProperty(window.RTCRtpSender.prototype, "dtmf", {
1032 get () {
1033 if (this._dtmf === undefined) {
1034 if (this.track.kind === "audio") this._dtmf = this._pc.createDTMFSender(this.track);
1035 else this._dtmf = null;
1036 }
1037 return this._dtmf;
1038 }
1039 });
1040 }
1041}
1042function $fb04e59b477f17ce$export$90608323826f0b17(window) {
1043 if (!window.RTCPeerConnection) return;
1044 const origGetStats = window.RTCPeerConnection.prototype.getStats;
1045 window.RTCPeerConnection.prototype.getStats = function getStats() {
1046 const [selector, onSucc, onErr] = arguments;
1047 // If selector is a function then we are in the old style stats so just
1048 // pass back the original getStats format to avoid breaking old users.
1049 if (arguments.length > 0 && typeof selector === "function") return origGetStats.apply(this, arguments);
1050 // When spec-style getStats is supported, return those when called with
1051 // either no arguments or the selector argument is null.
1052 if (origGetStats.length === 0 && (arguments.length === 0 || typeof selector !== "function")) return origGetStats.apply(this, []);
1053 const fixChromeStats_ = function(response) {
1054 const standardReport = {};
1055 const reports = response.result();
1056 reports.forEach((report)=>{
1057 const standardStats = {
1058 id: report.id,
1059 timestamp: report.timestamp,
1060 type: {
1061 localcandidate: "local-candidate",
1062 remotecandidate: "remote-candidate"
1063 }[report.type] || report.type
1064 };
1065 report.names().forEach((name)=>{
1066 standardStats[name] = report.stat(name);
1067 });
1068 standardReport[standardStats.id] = standardStats;
1069 });
1070 return standardReport;
1071 };
1072 // shim getStats with maplike support
1073 const makeMapStats = function(stats) {
1074 return new Map(Object.keys(stats).map((key)=>[
1075 key,
1076 stats[key]
1077 ]));
1078 };
1079 if (arguments.length >= 2) {
1080 const successCallbackWrapper_ = function(response) {
1081 onSucc(makeMapStats(fixChromeStats_(response)));
1082 };
1083 return origGetStats.apply(this, [
1084 successCallbackWrapper_,
1085 selector
1086 ]);
1087 }
1088 // promise-support
1089 return new Promise((resolve, reject)=>{
1090 origGetStats.apply(this, [
1091 function(response) {
1092 resolve(makeMapStats(fixChromeStats_(response)));
1093 },
1094 reject
1095 ]);
1096 }).then(onSucc, onErr);
1097 };
1098}
1099function $fb04e59b477f17ce$export$f2f0f2338114eb4b(window) {
1100 if (!(typeof window === "object" && window.RTCPeerConnection && window.RTCRtpSender && window.RTCRtpReceiver)) return;
1101 // shim sender stats.
1102 if (!("getStats" in window.RTCRtpSender.prototype)) {
1103 const origGetSenders = window.RTCPeerConnection.prototype.getSenders;
1104 if (origGetSenders) window.RTCPeerConnection.prototype.getSenders = function getSenders() {
1105 const senders = origGetSenders.apply(this, []);
1106 senders.forEach((sender)=>sender._pc = this);
1107 return senders;
1108 };
1109 const origAddTrack = window.RTCPeerConnection.prototype.addTrack;
1110 if (origAddTrack) window.RTCPeerConnection.prototype.addTrack = function addTrack() {
1111 const sender = origAddTrack.apply(this, arguments);
1112 sender._pc = this;
1113 return sender;
1114 };
1115 window.RTCRtpSender.prototype.getStats = function getStats() {
1116 const sender = this;
1117 return this._pc.getStats().then((result)=>/* Note: this will include stats of all senders that
1118 * send a track with the same id as sender.track as
1119 * it is not possible to identify the RTCRtpSender.
1120 */ $9fea4db837311579$export$93439ffc3f787d51(result, sender.track, true));
1121 };
1122 }
1123 // shim receiver stats.
1124 if (!("getStats" in window.RTCRtpReceiver.prototype)) {
1125 const origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;
1126 if (origGetReceivers) window.RTCPeerConnection.prototype.getReceivers = function getReceivers() {
1127 const receivers = origGetReceivers.apply(this, []);
1128 receivers.forEach((receiver)=>receiver._pc = this);
1129 return receivers;
1130 };
1131 $9fea4db837311579$export$1f48841962b828b1(window, "track", (e)=>{
1132 e.receiver._pc = e.srcElement;
1133 return e;
1134 });
1135 window.RTCRtpReceiver.prototype.getStats = function getStats() {
1136 const receiver = this;
1137 return this._pc.getStats().then((result)=>$9fea4db837311579$export$93439ffc3f787d51(result, receiver.track, false));
1138 };
1139 }
1140 if (!("getStats" in window.RTCRtpSender.prototype && "getStats" in window.RTCRtpReceiver.prototype)) return;
1141 // shim RTCPeerConnection.getStats(track).
1142 const origGetStats = window.RTCPeerConnection.prototype.getStats;
1143 window.RTCPeerConnection.prototype.getStats = function getStats() {
1144 if (arguments.length > 0 && arguments[0] instanceof window.MediaStreamTrack) {
1145 const track = arguments[0];
1146 let sender;
1147 let receiver;
1148 let err;
1149 this.getSenders().forEach((s)=>{
1150 if (s.track === track) {
1151 if (sender) err = true;
1152 else sender = s;
1153 }
1154 });
1155 this.getReceivers().forEach((r)=>{
1156 if (r.track === track) {
1157 if (receiver) err = true;
1158 else receiver = r;
1159 }
1160 return r.track === track;
1161 });
1162 if (err || sender && receiver) return Promise.reject(new DOMException("There are more than one sender or receiver for the track.", "InvalidAccessError"));
1163 else if (sender) return sender.getStats();
1164 else if (receiver) return receiver.getStats();
1165 return Promise.reject(new DOMException("There is no sender or receiver for the track.", "InvalidAccessError"));
1166 }
1167 return origGetStats.apply(this, arguments);
1168 };
1169}
1170function $fb04e59b477f17ce$export$30e3cdd46f8d5100(window) {
1171 // shim addTrack/removeTrack with native variants in order to make
1172 // the interactions with legacy getLocalStreams behave as in other browsers.
1173 // Keeps a mapping stream.id => [stream, rtpsenders...]
1174 window.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() {
1175 this._shimmedLocalStreams = this._shimmedLocalStreams || {};
1176 return Object.keys(this._shimmedLocalStreams).map((streamId)=>this._shimmedLocalStreams[streamId][0]);
1177 };
1178 const origAddTrack = window.RTCPeerConnection.prototype.addTrack;
1179 window.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) {
1180 if (!stream) return origAddTrack.apply(this, arguments);
1181 this._shimmedLocalStreams = this._shimmedLocalStreams || {};
1182 const sender = origAddTrack.apply(this, arguments);
1183 if (!this._shimmedLocalStreams[stream.id]) this._shimmedLocalStreams[stream.id] = [
1184 stream,
1185 sender
1186 ];
1187 else if (this._shimmedLocalStreams[stream.id].indexOf(sender) === -1) this._shimmedLocalStreams[stream.id].push(sender);
1188 return sender;
1189 };
1190 const origAddStream = window.RTCPeerConnection.prototype.addStream;
1191 window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
1192 this._shimmedLocalStreams = this._shimmedLocalStreams || {};
1193 stream.getTracks().forEach((track)=>{
1194 const alreadyExists = this.getSenders().find((s)=>s.track === track);
1195 if (alreadyExists) throw new DOMException("Track already exists.", "InvalidAccessError");
1196 });
1197 const existingSenders = this.getSenders();
1198 origAddStream.apply(this, arguments);
1199 const newSenders = this.getSenders().filter((newSender)=>existingSenders.indexOf(newSender) === -1);
1200 this._shimmedLocalStreams[stream.id] = [
1201 stream
1202 ].concat(newSenders);
1203 };
1204 const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
1205 window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
1206 this._shimmedLocalStreams = this._shimmedLocalStreams || {};
1207 delete this._shimmedLocalStreams[stream.id];
1208 return origRemoveStream.apply(this, arguments);
1209 };
1210 const origRemoveTrack = window.RTCPeerConnection.prototype.removeTrack;
1211 window.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) {
1212 this._shimmedLocalStreams = this._shimmedLocalStreams || {};
1213 if (sender) Object.keys(this._shimmedLocalStreams).forEach((streamId)=>{
1214 const idx = this._shimmedLocalStreams[streamId].indexOf(sender);
1215 if (idx !== -1) this._shimmedLocalStreams[streamId].splice(idx, 1);
1216 if (this._shimmedLocalStreams[streamId].length === 1) delete this._shimmedLocalStreams[streamId];
1217 });
1218 return origRemoveTrack.apply(this, arguments);
1219 };
1220}
1221function $fb04e59b477f17ce$export$9588259fcf4ebc91(window, browserDetails) {
1222 if (!window.RTCPeerConnection) return;
1223 // shim addTrack and removeTrack.
1224 if (window.RTCPeerConnection.prototype.addTrack && browserDetails.version >= 65) return $fb04e59b477f17ce$export$30e3cdd46f8d5100(window);
1225 // also shim pc.getLocalStreams when addTrack is shimmed
1226 // to return the original streams.
1227 const origGetLocalStreams = window.RTCPeerConnection.prototype.getLocalStreams;
1228 window.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() {
1229 const nativeStreams = origGetLocalStreams.apply(this);
1230 this._reverseStreams = this._reverseStreams || {};
1231 return nativeStreams.map((stream)=>this._reverseStreams[stream.id]);
1232 };
1233 const origAddStream = window.RTCPeerConnection.prototype.addStream;
1234 window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
1235 this._streams = this._streams || {};
1236 this._reverseStreams = this._reverseStreams || {};
1237 stream.getTracks().forEach((track)=>{
1238 const alreadyExists = this.getSenders().find((s)=>s.track === track);
1239 if (alreadyExists) throw new DOMException("Track already exists.", "InvalidAccessError");
1240 });
1241 // Add identity mapping for consistency with addTrack.
1242 // Unless this is being used with a stream from addTrack.
1243 if (!this._reverseStreams[stream.id]) {
1244 const newStream = new window.MediaStream(stream.getTracks());
1245 this._streams[stream.id] = newStream;
1246 this._reverseStreams[newStream.id] = stream;
1247 stream = newStream;
1248 }
1249 origAddStream.apply(this, [
1250 stream
1251 ]);
1252 };
1253 const origRemoveStream = window.RTCPeerConnection.prototype.removeStream;
1254 window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
1255 this._streams = this._streams || {};
1256 this._reverseStreams = this._reverseStreams || {};
1257 origRemoveStream.apply(this, [
1258 this._streams[stream.id] || stream
1259 ]);
1260 delete this._reverseStreams[this._streams[stream.id] ? this._streams[stream.id].id : stream.id];
1261 delete this._streams[stream.id];
1262 };
1263 window.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) {
1264 if (this.signalingState === "closed") throw new DOMException("The RTCPeerConnection's signalingState is 'closed'.", "InvalidStateError");
1265 const streams = [].slice.call(arguments, 1);
1266 if (streams.length !== 1 || !streams[0].getTracks().find((t)=>t === track)) // this is not fully correct but all we can manage without
1267 // [[associated MediaStreams]] internal slot.
1268 throw new DOMException("The adapter.js addTrack polyfill only supports a single stream which is associated with the specified track.", "NotSupportedError");
1269 const alreadyExists = this.getSenders().find((s)=>s.track === track);
1270 if (alreadyExists) throw new DOMException("Track already exists.", "InvalidAccessError");
1271 this._streams = this._streams || {};
1272 this._reverseStreams = this._reverseStreams || {};
1273 const oldStream = this._streams[stream.id];
1274 if (oldStream) {
1275 // this is using odd Chrome behaviour, use with caution:
1276 // https://bugs.chromium.org/p/webrtc/issues/detail?id=7815
1277 // Note: we rely on the high-level addTrack/dtmf shim to
1278 // create the sender with a dtmf sender.
1279 oldStream.addTrack(track);
1280 // Trigger ONN async.
1281 Promise.resolve().then(()=>{
1282 this.dispatchEvent(new Event("negotiationneeded"));
1283 });
1284 } else {
1285 const newStream = new window.MediaStream([
1286 track
1287 ]);
1288 this._streams[stream.id] = newStream;
1289 this._reverseStreams[newStream.id] = stream;
1290 this.addStream(newStream);
1291 }
1292 return this.getSenders().find((s)=>s.track === track);
1293 };
1294 // replace the internal stream id with the external one and
1295 // vice versa.
1296 function replaceInternalStreamId(pc, description) {
1297 let sdp = description.sdp;
1298 Object.keys(pc._reverseStreams || []).forEach((internalId)=>{
1299 const externalStream = pc._reverseStreams[internalId];
1300 const internalStream = pc._streams[externalStream.id];
1301 sdp = sdp.replace(new RegExp(internalStream.id, "g"), externalStream.id);
1302 });
1303 return new RTCSessionDescription({
1304 type: description.type,
1305 sdp: sdp
1306 });
1307 }
1308 function replaceExternalStreamId(pc, description) {
1309 let sdp = description.sdp;
1310 Object.keys(pc._reverseStreams || []).forEach((internalId)=>{
1311 const externalStream = pc._reverseStreams[internalId];
1312 const internalStream = pc._streams[externalStream.id];
1313 sdp = sdp.replace(new RegExp(externalStream.id, "g"), internalStream.id);
1314 });
1315 return new RTCSessionDescription({
1316 type: description.type,
1317 sdp: sdp
1318 });
1319 }
1320 [
1321 "createOffer",
1322 "createAnswer"
1323 ].forEach(function(method) {
1324 const nativeMethod = window.RTCPeerConnection.prototype[method];
1325 const methodObj = {
1326 [method] () {
1327 const args = arguments;
1328 const isLegacyCall = arguments.length && typeof arguments[0] === "function";
1329 if (isLegacyCall) return nativeMethod.apply(this, [
1330 (description)=>{
1331 const desc = replaceInternalStreamId(this, description);
1332 args[0].apply(null, [
1333 desc
1334 ]);
1335 },
1336 (err)=>{
1337 if (args[1]) args[1].apply(null, err);
1338 },
1339 arguments[2]
1340 ]);
1341 return nativeMethod.apply(this, arguments).then((description)=>replaceInternalStreamId(this, description));
1342 }
1343 };
1344 window.RTCPeerConnection.prototype[method] = methodObj[method];
1345 });
1346 const origSetLocalDescription = window.RTCPeerConnection.prototype.setLocalDescription;
1347 window.RTCPeerConnection.prototype.setLocalDescription = function setLocalDescription() {
1348 if (!arguments.length || !arguments[0].type) return origSetLocalDescription.apply(this, arguments);
1349 arguments[0] = replaceExternalStreamId(this, arguments[0]);
1350 return origSetLocalDescription.apply(this, arguments);
1351 };
1352 // TODO: mangle getStats: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats-streamidentifier
1353 const origLocalDescription = Object.getOwnPropertyDescriptor(window.RTCPeerConnection.prototype, "localDescription");
1354 Object.defineProperty(window.RTCPeerConnection.prototype, "localDescription", {
1355 get () {
1356 const description = origLocalDescription.get.apply(this);
1357 if (description.type === "") return description;
1358 return replaceInternalStreamId(this, description);
1359 }
1360 });
1361 window.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) {
1362 if (this.signalingState === "closed") throw new DOMException("The RTCPeerConnection's signalingState is 'closed'.", "InvalidStateError");
1363 // We can not yet check for sender instanceof RTCRtpSender
1364 // since we shim RTPSender. So we check if sender._pc is set.
1365 if (!sender._pc) throw new DOMException("Argument 1 of RTCPeerConnection.removeTrack does not implement interface RTCRtpSender.", "TypeError");
1366 const isLocal = sender._pc === this;
1367 if (!isLocal) throw new DOMException("Sender was not created by this connection.", "InvalidAccessError");
1368 // Search for the native stream the senders track belongs to.
1369 this._streams = this._streams || {};
1370 let stream;
1371 Object.keys(this._streams).forEach((streamid)=>{
1372 const hasTrack = this._streams[streamid].getTracks().find((track)=>sender.track === track);
1373 if (hasTrack) stream = this._streams[streamid];
1374 });
1375 if (stream) {
1376 if (stream.getTracks().length === 1) // if this is the last track of the stream, remove the stream. This
1377 // takes care of any shimmed _senders.
1378 this.removeStream(this._reverseStreams[stream.id]);
1379 else // relying on the same odd chrome behaviour as above.
1380 stream.removeTrack(sender.track);
1381 this.dispatchEvent(new Event("negotiationneeded"));
1382 }
1383 };
1384}
1385function $fb04e59b477f17ce$export$852a08dda9a55ea7(window, browserDetails) {
1386 if (!window.RTCPeerConnection && window.webkitRTCPeerConnection) // very basic support for old versions.
1387 window.RTCPeerConnection = window.webkitRTCPeerConnection;
1388 if (!window.RTCPeerConnection) return;
1389 // shim implicit creation of RTCSessionDescription/RTCIceCandidate
1390 if (browserDetails.version < 53) [
1391 "setLocalDescription",
1392 "setRemoteDescription",
1393 "addIceCandidate"
1394 ].forEach(function(method) {
1395 const nativeMethod = window.RTCPeerConnection.prototype[method];
1396 const methodObj = {
1397 [method] () {
1398 arguments[0] = new (method === "addIceCandidate" ? window.RTCIceCandidate : window.RTCSessionDescription)(arguments[0]);
1399 return nativeMethod.apply(this, arguments);
1400 }
1401 };
1402 window.RTCPeerConnection.prototype[method] = methodObj[method];
1403 });
1404}
1405function $fb04e59b477f17ce$export$341293bbeaae37cb(window, browserDetails) {
1406 $9fea4db837311579$export$1f48841962b828b1(window, "negotiationneeded", (e)=>{
1407 const pc = e.target;
1408 if (browserDetails.version < 72 || pc.getConfiguration && pc.getConfiguration().sdpSemantics === "plan-b") {
1409 if (pc.signalingState !== "stable") return;
1410 }
1411 return e;
1412 });
1413}
1414
1415
1416var $215e6581d7a09c61$exports = {};
1417
1418$parcel$export($215e6581d7a09c61$exports, "shimOnTrack", () => $215e6581d7a09c61$export$f358708f68ab068);
1419$parcel$export($215e6581d7a09c61$exports, "shimPeerConnection", () => $215e6581d7a09c61$export$852a08dda9a55ea7);
1420$parcel$export($215e6581d7a09c61$exports, "shimSenderGetStats", () => $215e6581d7a09c61$export$f0525502095c04ef);
1421$parcel$export($215e6581d7a09c61$exports, "shimReceiverGetStats", () => $215e6581d7a09c61$export$83d69126527b1171);
1422$parcel$export($215e6581d7a09c61$exports, "shimRemoveStream", () => $215e6581d7a09c61$export$825e523ef749bd8c);
1423$parcel$export($215e6581d7a09c61$exports, "shimRTCDataChannel", () => $215e6581d7a09c61$export$ff9cb3bc8990e8f7);
1424$parcel$export($215e6581d7a09c61$exports, "shimAddTransceiver", () => $215e6581d7a09c61$export$70c77533b6e9908d);
1425$parcel$export($215e6581d7a09c61$exports, "shimGetParameters", () => $215e6581d7a09c61$export$66238223c298fbaa);
1426$parcel$export($215e6581d7a09c61$exports, "shimCreateOffer", () => $215e6581d7a09c61$export$51beccf0e777b843);
1427$parcel$export($215e6581d7a09c61$exports, "shimCreateAnswer", () => $215e6581d7a09c61$export$df0b46e7cef08150);
1428$parcel$export($215e6581d7a09c61$exports, "shimGetUserMedia", () => $6c9e5f7e9edd1e60$export$1ed4910f4d37dc5e);
1429$parcel$export($215e6581d7a09c61$exports, "shimGetDisplayMedia", () => $c12684406b986df8$export$97270b87351d9c04);
1430/*
1431 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
1432 *
1433 * Use of this source code is governed by a BSD-style license
1434 * that can be found in the LICENSE file in the root of the source
1435 * tree.
1436 */ /* eslint-env node */
1437/*
1438 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
1439 *
1440 * Use of this source code is governed by a BSD-style license
1441 * that can be found in the LICENSE file in the root of the source
1442 * tree.
1443 */ /* eslint-env node */
1444"use strict";
1445function $6c9e5f7e9edd1e60$export$1ed4910f4d37dc5e(window, browserDetails) {
1446 const navigator = window && window.navigator;
1447 const MediaStreamTrack = window && window.MediaStreamTrack;
1448 navigator.getUserMedia = function(constraints, onSuccess, onError) {
1449 // Replace Firefox 44+'s deprecation warning with unprefixed version.
1450 $9fea4db837311579$export$cdd73fc4100a6ef4("navigator.getUserMedia", "navigator.mediaDevices.getUserMedia");
1451 navigator.mediaDevices.getUserMedia(constraints).then(onSuccess, onError);
1452 };
1453 if (!(browserDetails.version > 55 && "autoGainControl" in navigator.mediaDevices.getSupportedConstraints())) {
1454 const remap = function(obj, a, b) {
1455 if (a in obj && !(b in obj)) {
1456 obj[b] = obj[a];
1457 delete obj[a];
1458 }
1459 };
1460 const nativeGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);
1461 navigator.mediaDevices.getUserMedia = function(c) {
1462 if (typeof c === "object" && typeof c.audio === "object") {
1463 c = JSON.parse(JSON.stringify(c));
1464 remap(c.audio, "autoGainControl", "mozAutoGainControl");
1465 remap(c.audio, "noiseSuppression", "mozNoiseSuppression");
1466 }
1467 return nativeGetUserMedia(c);
1468 };
1469 if (MediaStreamTrack && MediaStreamTrack.prototype.getSettings) {
1470 const nativeGetSettings = MediaStreamTrack.prototype.getSettings;
1471 MediaStreamTrack.prototype.getSettings = function() {
1472 const obj = nativeGetSettings.apply(this, arguments);
1473 remap(obj, "mozAutoGainControl", "autoGainControl");
1474 remap(obj, "mozNoiseSuppression", "noiseSuppression");
1475 return obj;
1476 };
1477 }
1478 if (MediaStreamTrack && MediaStreamTrack.prototype.applyConstraints) {
1479 const nativeApplyConstraints = MediaStreamTrack.prototype.applyConstraints;
1480 MediaStreamTrack.prototype.applyConstraints = function(c) {
1481 if (this.kind === "audio" && typeof c === "object") {
1482 c = JSON.parse(JSON.stringify(c));
1483 remap(c, "autoGainControl", "mozAutoGainControl");
1484 remap(c, "noiseSuppression", "mozNoiseSuppression");
1485 }
1486 return nativeApplyConstraints.apply(this, [
1487 c
1488 ]);
1489 };
1490 }
1491 }
1492}
1493
1494
1495/*
1496 * Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.
1497 *
1498 * Use of this source code is governed by a BSD-style license
1499 * that can be found in the LICENSE file in the root of the source
1500 * tree.
1501 */ /* eslint-env node */ "use strict";
1502function $c12684406b986df8$export$97270b87351d9c04(window, preferredMediaSource) {
1503 if (window.navigator.mediaDevices && "getDisplayMedia" in window.navigator.mediaDevices) return;
1504 if (!window.navigator.mediaDevices) return;
1505 window.navigator.mediaDevices.getDisplayMedia = function getDisplayMedia(constraints) {
1506 if (!(constraints && constraints.video)) {
1507 const err = new DOMException("getDisplayMedia without video constraints is undefined");
1508 err.name = "NotFoundError";
1509 // from https://heycam.github.io/webidl/#idl-DOMException-error-names
1510 err.code = 8;
1511 return Promise.reject(err);
1512 }
1513 if (constraints.video === true) constraints.video = {
1514 mediaSource: preferredMediaSource
1515 };
1516 else constraints.video.mediaSource = preferredMediaSource;
1517 return window.navigator.mediaDevices.getUserMedia(constraints);
1518 };
1519}
1520
1521
1522"use strict";
1523function $215e6581d7a09c61$export$f358708f68ab068(window) {
1524 if (typeof window === "object" && window.RTCTrackEvent && "receiver" in window.RTCTrackEvent.prototype && !("transceiver" in window.RTCTrackEvent.prototype)) Object.defineProperty(window.RTCTrackEvent.prototype, "transceiver", {
1525 get () {
1526 return {
1527 receiver: this.receiver
1528 };
1529 }
1530 });
1531}
1532function $215e6581d7a09c61$export$852a08dda9a55ea7(window, browserDetails) {
1533 if (typeof window !== "object" || !(window.RTCPeerConnection || window.mozRTCPeerConnection)) return; // probably media.peerconnection.enabled=false in about:config
1534 if (!window.RTCPeerConnection && window.mozRTCPeerConnection) // very basic support for old versions.
1535 window.RTCPeerConnection = window.mozRTCPeerConnection;
1536 if (browserDetails.version < 53) // shim away need for obsolete RTCIceCandidate/RTCSessionDescription.
1537 [
1538 "setLocalDescription",
1539 "setRemoteDescription",
1540 "addIceCandidate"
1541 ].forEach(function(method) {
1542 const nativeMethod = window.RTCPeerConnection.prototype[method];
1543 const methodObj = {
1544 [method] () {
1545 arguments[0] = new (method === "addIceCandidate" ? window.RTCIceCandidate : window.RTCSessionDescription)(arguments[0]);
1546 return nativeMethod.apply(this, arguments);
1547 }
1548 };
1549 window.RTCPeerConnection.prototype[method] = methodObj[method];
1550 });
1551 const modernStatsTypes = {
1552 inboundrtp: "inbound-rtp",
1553 outboundrtp: "outbound-rtp",
1554 candidatepair: "candidate-pair",
1555 localcandidate: "local-candidate",
1556 remotecandidate: "remote-candidate"
1557 };
1558 const nativeGetStats = window.RTCPeerConnection.prototype.getStats;
1559 window.RTCPeerConnection.prototype.getStats = function getStats() {
1560 const [selector, onSucc, onErr] = arguments;
1561 return nativeGetStats.apply(this, [
1562 selector || null
1563 ]).then((stats)=>{
1564 if (browserDetails.version < 53 && !onSucc) // Shim only promise getStats with spec-hyphens in type names
1565 // Leave callback version alone; misc old uses of forEach before Map
1566 try {
1567 stats.forEach((stat)=>{
1568 stat.type = modernStatsTypes[stat.type] || stat.type;
1569 });
1570 } catch (e) {
1571 if (e.name !== "TypeError") throw e;
1572 // Avoid TypeError: "type" is read-only, in old versions. 34-43ish
1573 stats.forEach((stat, i)=>{
1574 stats.set(i, Object.assign({}, stat, {
1575 type: modernStatsTypes[stat.type] || stat.type
1576 }));
1577 });
1578 }
1579 return stats;
1580 }).then(onSucc, onErr);
1581 };
1582}
1583function $215e6581d7a09c61$export$f0525502095c04ef(window) {
1584 if (!(typeof window === "object" && window.RTCPeerConnection && window.RTCRtpSender)) return;
1585 if (window.RTCRtpSender && "getStats" in window.RTCRtpSender.prototype) return;
1586 const origGetSenders = window.RTCPeerConnection.prototype.getSenders;
1587 if (origGetSenders) window.RTCPeerConnection.prototype.getSenders = function getSenders() {
1588 const senders = origGetSenders.apply(this, []);
1589 senders.forEach((sender)=>sender._pc = this);
1590 return senders;
1591 };
1592 const origAddTrack = window.RTCPeerConnection.prototype.addTrack;
1593 if (origAddTrack) window.RTCPeerConnection.prototype.addTrack = function addTrack() {
1594 const sender = origAddTrack.apply(this, arguments);
1595 sender._pc = this;
1596 return sender;
1597 };
1598 window.RTCRtpSender.prototype.getStats = function getStats() {
1599 return this.track ? this._pc.getStats(this.track) : Promise.resolve(new Map());
1600 };
1601}
1602function $215e6581d7a09c61$export$83d69126527b1171(window) {
1603 if (!(typeof window === "object" && window.RTCPeerConnection && window.RTCRtpSender)) return;
1604 if (window.RTCRtpSender && "getStats" in window.RTCRtpReceiver.prototype) return;
1605 const origGetReceivers = window.RTCPeerConnection.prototype.getReceivers;
1606 if (origGetReceivers) window.RTCPeerConnection.prototype.getReceivers = function getReceivers() {
1607 const receivers = origGetReceivers.apply(this, []);
1608 receivers.forEach((receiver)=>receiver._pc = this);
1609 return receivers;
1610 };
1611 $9fea4db837311579$export$1f48841962b828b1(window, "track", (e)=>{
1612 e.receiver._pc = e.srcElement;
1613 return e;
1614 });
1615 window.RTCRtpReceiver.prototype.getStats = function getStats() {
1616 return this._pc.getStats(this.track);
1617 };
1618}
1619function $215e6581d7a09c61$export$825e523ef749bd8c(window) {
1620 if (!window.RTCPeerConnection || "removeStream" in window.RTCPeerConnection.prototype) return;
1621 window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
1622 $9fea4db837311579$export$cdd73fc4100a6ef4("removeStream", "removeTrack");
1623 this.getSenders().forEach((sender)=>{
1624 if (sender.track && stream.getTracks().includes(sender.track)) this.removeTrack(sender);
1625 });
1626 };
1627}
1628function $215e6581d7a09c61$export$ff9cb3bc8990e8f7(window) {
1629 // rename DataChannel to RTCDataChannel (native fix in FF60):
1630 // https://bugzilla.mozilla.org/show_bug.cgi?id=1173851
1631 if (window.DataChannel && !window.RTCDataChannel) window.RTCDataChannel = window.DataChannel;
1632}
1633function $215e6581d7a09c61$export$70c77533b6e9908d(window) {
1634 // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647
1635 // Firefox ignores the init sendEncodings options passed to addTransceiver
1636 // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918
1637 if (!(typeof window === "object" && window.RTCPeerConnection)) return;
1638 const origAddTransceiver = window.RTCPeerConnection.prototype.addTransceiver;
1639 if (origAddTransceiver) window.RTCPeerConnection.prototype.addTransceiver = function addTransceiver() {
1640 this.setParametersPromises = [];
1641 // WebIDL input coercion and validation
1642 let sendEncodings = arguments[1] && arguments[1].sendEncodings;
1643 if (sendEncodings === undefined) sendEncodings = [];
1644 sendEncodings = [
1645 ...sendEncodings
1646 ];
1647 const shouldPerformCheck = sendEncodings.length > 0;
1648 if (shouldPerformCheck) // If sendEncodings params are provided, validate grammar
1649 sendEncodings.forEach((encodingParam)=>{
1650 if ("rid" in encodingParam) {
1651 const ridRegex = /^[a-z0-9]{0,16}$/i;
1652 if (!ridRegex.test(encodingParam.rid)) throw new TypeError("Invalid RID value provided.");
1653 }
1654 if ("scaleResolutionDownBy" in encodingParam) {
1655 if (!(parseFloat(encodingParam.scaleResolutionDownBy) >= 1.0)) throw new RangeError("scale_resolution_down_by must be >= 1.0");
1656 }
1657 if ("maxFramerate" in encodingParam) {
1658 if (!(parseFloat(encodingParam.maxFramerate) >= 0)) throw new RangeError("max_framerate must be >= 0.0");
1659 }
1660 });
1661 const transceiver = origAddTransceiver.apply(this, arguments);
1662 if (shouldPerformCheck) {
1663 // Check if the init options were applied. If not we do this in an
1664 // asynchronous way and save the promise reference in a global object.
1665 // This is an ugly hack, but at the same time is way more robust than
1666 // checking the sender parameters before and after the createOffer
1667 // Also note that after the createoffer we are not 100% sure that
1668 // the params were asynchronously applied so we might miss the
1669 // opportunity to recreate offer.
1670 const { sender: sender } = transceiver;
1671 const params = sender.getParameters();
1672 if (!("encodings" in params) || // Avoid being fooled by patched getParameters() below.
1673 params.encodings.length === 1 && Object.keys(params.encodings[0]).length === 0) {
1674 params.encodings = sendEncodings;
1675 sender.sendEncodings = sendEncodings;
1676 this.setParametersPromises.push(sender.setParameters(params).then(()=>{
1677 delete sender.sendEncodings;
1678 }).catch(()=>{
1679 delete sender.sendEncodings;
1680 }));
1681 }
1682 }
1683 return transceiver;
1684 };
1685}
1686function $215e6581d7a09c61$export$66238223c298fbaa(window) {
1687 if (!(typeof window === "object" && window.RTCRtpSender)) return;
1688 const origGetParameters = window.RTCRtpSender.prototype.getParameters;
1689 if (origGetParameters) window.RTCRtpSender.prototype.getParameters = function getParameters() {
1690 const params = origGetParameters.apply(this, arguments);
1691 if (!("encodings" in params)) params.encodings = [].concat(this.sendEncodings || [
1692 {}
1693 ]);
1694 return params;
1695 };
1696}
1697function $215e6581d7a09c61$export$51beccf0e777b843(window) {
1698 // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647
1699 // Firefox ignores the init sendEncodings options passed to addTransceiver
1700 // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918
1701 if (!(typeof window === "object" && window.RTCPeerConnection)) return;
1702 const origCreateOffer = window.RTCPeerConnection.prototype.createOffer;
1703 window.RTCPeerConnection.prototype.createOffer = function createOffer() {
1704 if (this.setParametersPromises && this.setParametersPromises.length) return Promise.all(this.setParametersPromises).then(()=>{
1705 return origCreateOffer.apply(this, arguments);
1706 }).finally(()=>{
1707 this.setParametersPromises = [];
1708 });
1709 return origCreateOffer.apply(this, arguments);
1710 };
1711}
1712function $215e6581d7a09c61$export$df0b46e7cef08150(window) {
1713 // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647
1714 // Firefox ignores the init sendEncodings options passed to addTransceiver
1715 // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918
1716 if (!(typeof window === "object" && window.RTCPeerConnection)) return;
1717 const origCreateAnswer = window.RTCPeerConnection.prototype.createAnswer;
1718 window.RTCPeerConnection.prototype.createAnswer = function createAnswer() {
1719 if (this.setParametersPromises && this.setParametersPromises.length) return Promise.all(this.setParametersPromises).then(()=>{
1720 return origCreateAnswer.apply(this, arguments);
1721 }).finally(()=>{
1722 this.setParametersPromises = [];
1723 });
1724 return origCreateAnswer.apply(this, arguments);
1725 };
1726}
1727
1728
1729var $c1f641ee5a6f6c8f$exports = {};
1730
1731$parcel$export($c1f641ee5a6f6c8f$exports, "shimLocalStreamsAPI", () => $c1f641ee5a6f6c8f$export$8df41282f4fdcea2);
1732$parcel$export($c1f641ee5a6f6c8f$exports, "shimRemoteStreamsAPI", () => $c1f641ee5a6f6c8f$export$762aa4cbb4f2f857);
1733$parcel$export($c1f641ee5a6f6c8f$exports, "shimCallbacksAPI", () => $c1f641ee5a6f6c8f$export$da31df245debdd3);
1734$parcel$export($c1f641ee5a6f6c8f$exports, "shimGetUserMedia", () => $c1f641ee5a6f6c8f$export$1ed4910f4d37dc5e);
1735$parcel$export($c1f641ee5a6f6c8f$exports, "shimConstraints", () => $c1f641ee5a6f6c8f$export$494a01ac68ba81ac);
1736$parcel$export($c1f641ee5a6f6c8f$exports, "shimRTCIceServerUrls", () => $c1f641ee5a6f6c8f$export$671a8b47b41b6f41);
1737$parcel$export($c1f641ee5a6f6c8f$exports, "shimTrackEventTransceiver", () => $c1f641ee5a6f6c8f$export$85d53da088cb1b14);
1738$parcel$export($c1f641ee5a6f6c8f$exports, "shimCreateOfferLegacy", () => $c1f641ee5a6f6c8f$export$d444266503fdd2d4);
1739$parcel$export($c1f641ee5a6f6c8f$exports, "shimAudioContext", () => $c1f641ee5a6f6c8f$export$857cd739a7b795d2);
1740/*
1741 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
1742 *
1743 * Use of this source code is governed by a BSD-style license
1744 * that can be found in the LICENSE file in the root of the source
1745 * tree.
1746 */
1747"use strict";
1748function $c1f641ee5a6f6c8f$export$8df41282f4fdcea2(window) {
1749 if (typeof window !== "object" || !window.RTCPeerConnection) return;
1750 if (!("getLocalStreams" in window.RTCPeerConnection.prototype)) window.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() {
1751 if (!this._localStreams) this._localStreams = [];
1752 return this._localStreams;
1753 };
1754 if (!("addStream" in window.RTCPeerConnection.prototype)) {
1755 const _addTrack = window.RTCPeerConnection.prototype.addTrack;
1756 window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
1757 if (!this._localStreams) this._localStreams = [];
1758 if (!this._localStreams.includes(stream)) this._localStreams.push(stream);
1759 // Try to emulate Chrome's behaviour of adding in audio-video order.
1760 // Safari orders by track id.
1761 stream.getAudioTracks().forEach((track)=>_addTrack.call(this, track, stream));
1762 stream.getVideoTracks().forEach((track)=>_addTrack.call(this, track, stream));
1763 };
1764 window.RTCPeerConnection.prototype.addTrack = function addTrack(track, ...streams) {
1765 if (streams) streams.forEach((stream)=>{
1766 if (!this._localStreams) this._localStreams = [
1767 stream
1768 ];
1769 else if (!this._localStreams.includes(stream)) this._localStreams.push(stream);
1770 });
1771 return _addTrack.apply(this, arguments);
1772 };
1773 }
1774 if (!("removeStream" in window.RTCPeerConnection.prototype)) window.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
1775 if (!this._localStreams) this._localStreams = [];
1776 const index = this._localStreams.indexOf(stream);
1777 if (index === -1) return;
1778 this._localStreams.splice(index, 1);
1779 const tracks = stream.getTracks();
1780 this.getSenders().forEach((sender)=>{
1781 if (tracks.includes(sender.track)) this.removeTrack(sender);
1782 });
1783 };
1784}
1785function $c1f641ee5a6f6c8f$export$762aa4cbb4f2f857(window) {
1786 if (typeof window !== "object" || !window.RTCPeerConnection) return;
1787 if (!("getRemoteStreams" in window.RTCPeerConnection.prototype)) window.RTCPeerConnection.prototype.getRemoteStreams = function getRemoteStreams() {
1788 return this._remoteStreams ? this._remoteStreams : [];
1789 };
1790 if (!("onaddstream" in window.RTCPeerConnection.prototype)) {
1791 Object.defineProperty(window.RTCPeerConnection.prototype, "onaddstream", {
1792 get () {
1793 return this._onaddstream;
1794 },
1795 set (f) {
1796 if (this._onaddstream) {
1797 this.removeEventListener("addstream", this._onaddstream);
1798 this.removeEventListener("track", this._onaddstreampoly);
1799 }
1800 this.addEventListener("addstream", this._onaddstream = f);
1801 this.addEventListener("track", this._onaddstreampoly = (e)=>{
1802 e.streams.forEach((stream)=>{
1803 if (!this._remoteStreams) this._remoteStreams = [];
1804 if (this._remoteStreams.includes(stream)) return;
1805 this._remoteStreams.push(stream);
1806 const event = new Event("addstream");
1807 event.stream = stream;
1808 this.dispatchEvent(event);
1809 });
1810 });
1811 }
1812 });
1813 const origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription;
1814 window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() {
1815 const pc = this;
1816 if (!this._onaddstreampoly) this.addEventListener("track", this._onaddstreampoly = function(e) {
1817 e.streams.forEach((stream)=>{
1818 if (!pc._remoteStreams) pc._remoteStreams = [];
1819 if (pc._remoteStreams.indexOf(stream) >= 0) return;
1820 pc._remoteStreams.push(stream);
1821 const event = new Event("addstream");
1822 event.stream = stream;
1823 pc.dispatchEvent(event);
1824 });
1825 });
1826 return origSetRemoteDescription.apply(pc, arguments);
1827 };
1828 }
1829}
1830function $c1f641ee5a6f6c8f$export$da31df245debdd3(window) {
1831 if (typeof window !== "object" || !window.RTCPeerConnection) return;
1832 const prototype = window.RTCPeerConnection.prototype;
1833 const origCreateOffer = prototype.createOffer;
1834 const origCreateAnswer = prototype.createAnswer;
1835 const setLocalDescription = prototype.setLocalDescription;
1836 const setRemoteDescription = prototype.setRemoteDescription;
1837 const addIceCandidate = prototype.addIceCandidate;
1838 prototype.createOffer = function createOffer(successCallback, failureCallback) {
1839 const options = arguments.length >= 2 ? arguments[2] : arguments[0];
1840 const promise = origCreateOffer.apply(this, [
1841 options
1842 ]);
1843 if (!failureCallback) return promise;
1844 promise.then(successCallback, failureCallback);
1845 return Promise.resolve();
1846 };
1847 prototype.createAnswer = function createAnswer(successCallback, failureCallback) {
1848 const options = arguments.length >= 2 ? arguments[2] : arguments[0];
1849 const promise = origCreateAnswer.apply(this, [
1850 options
1851 ]);
1852 if (!failureCallback) return promise;
1853 promise.then(successCallback, failureCallback);
1854 return Promise.resolve();
1855 };
1856 let withCallback = function(description, successCallback, failureCallback) {
1857 const promise = setLocalDescription.apply(this, [
1858 description
1859 ]);
1860 if (!failureCallback) return promise;
1861 promise.then(successCallback, failureCallback);
1862 return Promise.resolve();
1863 };
1864 prototype.setLocalDescription = withCallback;
1865 withCallback = function(description, successCallback, failureCallback) {
1866 const promise = setRemoteDescription.apply(this, [
1867 description
1868 ]);
1869 if (!failureCallback) return promise;
1870 promise.then(successCallback, failureCallback);
1871 return Promise.resolve();
1872 };
1873 prototype.setRemoteDescription = withCallback;
1874 withCallback = function(candidate, successCallback, failureCallback) {
1875 const promise = addIceCandidate.apply(this, [
1876 candidate
1877 ]);
1878 if (!failureCallback) return promise;
1879 promise.then(successCallback, failureCallback);
1880 return Promise.resolve();
1881 };
1882 prototype.addIceCandidate = withCallback;
1883}
1884function $c1f641ee5a6f6c8f$export$1ed4910f4d37dc5e(window) {
1885 const navigator = window && window.navigator;
1886 if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
1887 // shim not needed in Safari 12.1
1888 const mediaDevices = navigator.mediaDevices;
1889 const _getUserMedia = mediaDevices.getUserMedia.bind(mediaDevices);
1890 navigator.mediaDevices.getUserMedia = (constraints)=>{
1891 return _getUserMedia($c1f641ee5a6f6c8f$export$494a01ac68ba81ac(constraints));
1892 };
1893 }
1894 if (!navigator.getUserMedia && navigator.mediaDevices && navigator.mediaDevices.getUserMedia) navigator.getUserMedia = (function getUserMedia(constraints, cb, errcb) {
1895 navigator.mediaDevices.getUserMedia(constraints).then(cb, errcb);
1896 }).bind(navigator);
1897}
1898function $c1f641ee5a6f6c8f$export$494a01ac68ba81ac(constraints) {
1899 if (constraints && constraints.video !== undefined) return Object.assign({}, constraints, {
1900 video: $9fea4db837311579$export$15384eac40dc88c8(constraints.video)
1901 });
1902 return constraints;
1903}
1904function $c1f641ee5a6f6c8f$export$671a8b47b41b6f41(window) {
1905 if (!window.RTCPeerConnection) return;
1906 // migrate from non-spec RTCIceServer.url to RTCIceServer.urls
1907 const OrigPeerConnection = window.RTCPeerConnection;
1908 window.RTCPeerConnection = function RTCPeerConnection(pcConfig, pcConstraints) {
1909 if (pcConfig && pcConfig.iceServers) {
1910 const newIceServers = [];
1911 for(let i = 0; i < pcConfig.iceServers.length; i++){
1912 let server = pcConfig.iceServers[i];
1913 if (server.urls === undefined && server.url) {
1914 $9fea4db837311579$export$cdd73fc4100a6ef4("RTCIceServer.url", "RTCIceServer.urls");
1915 server = JSON.parse(JSON.stringify(server));
1916 server.urls = server.url;
1917 delete server.url;
1918 newIceServers.push(server);
1919 } else newIceServers.push(pcConfig.iceServers[i]);
1920 }
1921 pcConfig.iceServers = newIceServers;
1922 }
1923 return new OrigPeerConnection(pcConfig, pcConstraints);
1924 };
1925 window.RTCPeerConnection.prototype = OrigPeerConnection.prototype;
1926 // wrap static methods. Currently just generateCertificate.
1927 if ("generateCertificate" in OrigPeerConnection) Object.defineProperty(window.RTCPeerConnection, "generateCertificate", {
1928 get () {
1929 return OrigPeerConnection.generateCertificate;
1930 }
1931 });
1932}
1933function $c1f641ee5a6f6c8f$export$85d53da088cb1b14(window) {
1934 // Add event.transceiver member over deprecated event.receiver
1935 if (typeof window === "object" && window.RTCTrackEvent && "receiver" in window.RTCTrackEvent.prototype && !("transceiver" in window.RTCTrackEvent.prototype)) Object.defineProperty(window.RTCTrackEvent.prototype, "transceiver", {
1936 get () {
1937 return {
1938 receiver: this.receiver
1939 };
1940 }
1941 });
1942}
1943function $c1f641ee5a6f6c8f$export$d444266503fdd2d4(window) {
1944 const origCreateOffer = window.RTCPeerConnection.prototype.createOffer;
1945 window.RTCPeerConnection.prototype.createOffer = function createOffer(offerOptions) {
1946 if (offerOptions) {
1947 if (typeof offerOptions.offerToReceiveAudio !== "undefined") // support bit values
1948 offerOptions.offerToReceiveAudio = !!offerOptions.offerToReceiveAudio;
1949 const audioTransceiver = this.getTransceivers().find((transceiver)=>transceiver.receiver.track.kind === "audio");
1950 if (offerOptions.offerToReceiveAudio === false && audioTransceiver) {
1951 if (audioTransceiver.direction === "sendrecv") {
1952 if (audioTransceiver.setDirection) audioTransceiver.setDirection("sendonly");
1953 else audioTransceiver.direction = "sendonly";
1954 } else if (audioTransceiver.direction === "recvonly") {
1955 if (audioTransceiver.setDirection) audioTransceiver.setDirection("inactive");
1956 else audioTransceiver.direction = "inactive";
1957 }
1958 } else if (offerOptions.offerToReceiveAudio === true && !audioTransceiver) this.addTransceiver("audio", {
1959 direction: "recvonly"
1960 });
1961 if (typeof offerOptions.offerToReceiveVideo !== "undefined") // support bit values
1962 offerOptions.offerToReceiveVideo = !!offerOptions.offerToReceiveVideo;
1963 const videoTransceiver = this.getTransceivers().find((transceiver)=>transceiver.receiver.track.kind === "video");
1964 if (offerOptions.offerToReceiveVideo === false && videoTransceiver) {
1965 if (videoTransceiver.direction === "sendrecv") {
1966 if (videoTransceiver.setDirection) videoTransceiver.setDirection("sendonly");
1967 else videoTransceiver.direction = "sendonly";
1968 } else if (videoTransceiver.direction === "recvonly") {
1969 if (videoTransceiver.setDirection) videoTransceiver.setDirection("inactive");
1970 else videoTransceiver.direction = "inactive";
1971 }
1972 } else if (offerOptions.offerToReceiveVideo === true && !videoTransceiver) this.addTransceiver("video", {
1973 direction: "recvonly"
1974 });
1975 }
1976 return origCreateOffer.apply(this, arguments);
1977 };
1978}
1979function $c1f641ee5a6f6c8f$export$857cd739a7b795d2(window) {
1980 if (typeof window !== "object" || window.AudioContext) return;
1981 window.AudioContext = window.webkitAudioContext;
1982}
1983
1984
1985var $5151b78094cea2ba$exports = {};
1986
1987$parcel$export($5151b78094cea2ba$exports, "shimRTCIceCandidate", () => $5151b78094cea2ba$export$cf133661e444ccfe);
1988$parcel$export($5151b78094cea2ba$exports, "shimRTCIceCandidateRelayProtocol", () => $5151b78094cea2ba$export$fdafb8d8280e29b5);
1989$parcel$export($5151b78094cea2ba$exports, "shimMaxMessageSize", () => $5151b78094cea2ba$export$a99147c78a56edc4);
1990$parcel$export($5151b78094cea2ba$exports, "shimSendThrowTypeError", () => $5151b78094cea2ba$export$d461c8d5c5db5da7);
1991$parcel$export($5151b78094cea2ba$exports, "shimConnectionState", () => $5151b78094cea2ba$export$63bb816cc75460);
1992$parcel$export($5151b78094cea2ba$exports, "removeExtmapAllowMixed", () => $5151b78094cea2ba$export$a57d114344295149);
1993$parcel$export($5151b78094cea2ba$exports, "shimAddIceCandidateNullOrEmpty", () => $5151b78094cea2ba$export$51d5e40b48c771c7);
1994$parcel$export($5151b78094cea2ba$exports, "shimParameterlessSetLocalDescription", () => $5151b78094cea2ba$export$7170d04e59f9d553);
1995/*
1996 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
1997 *
1998 * Use of this source code is governed by a BSD-style license
1999 * that can be found in the LICENSE file in the root of the source
2000 * tree.
2001 */ /* eslint-env node */ var $5d0e6002f6ec24ec$exports = {};
2002/* eslint-env node */ "use strict";
2003// SDP helpers.
2004const $5d0e6002f6ec24ec$var$SDPUtils = {};
2005// Generate an alphanumeric identifier for cname or mids.
2006// TODO: use UUIDs instead? https://gist.github.com/jed/982883
2007$5d0e6002f6ec24ec$var$SDPUtils.generateIdentifier = function() {
2008 return Math.random().toString(36).substring(2, 12);
2009};
2010// The RTCP CNAME used by all peerconnections from the same JS.
2011$5d0e6002f6ec24ec$var$SDPUtils.localCName = $5d0e6002f6ec24ec$var$SDPUtils.generateIdentifier();
2012// Splits SDP into lines, dealing with both CRLF and LF.
2013$5d0e6002f6ec24ec$var$SDPUtils.splitLines = function(blob) {
2014 return blob.trim().split("\n").map((line)=>line.trim());
2015};
2016// Splits SDP into sessionpart and mediasections. Ensures CRLF.
2017$5d0e6002f6ec24ec$var$SDPUtils.splitSections = function(blob) {
2018 const parts = blob.split("\nm=");
2019 return parts.map((part, index)=>(index > 0 ? "m=" + part : part).trim() + "\r\n");
2020};
2021// Returns the session description.
2022$5d0e6002f6ec24ec$var$SDPUtils.getDescription = function(blob) {
2023 const sections = $5d0e6002f6ec24ec$var$SDPUtils.splitSections(blob);
2024 return sections && sections[0];
2025};
2026// Returns the individual media sections.
2027$5d0e6002f6ec24ec$var$SDPUtils.getMediaSections = function(blob) {
2028 const sections = $5d0e6002f6ec24ec$var$SDPUtils.splitSections(blob);
2029 sections.shift();
2030 return sections;
2031};
2032// Returns lines that start with a certain prefix.
2033$5d0e6002f6ec24ec$var$SDPUtils.matchPrefix = function(blob, prefix) {
2034 return $5d0e6002f6ec24ec$var$SDPUtils.splitLines(blob).filter((line)=>line.indexOf(prefix) === 0);
2035};
2036// Parses an ICE candidate line. Sample input:
2037// candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8
2038// rport 55996"
2039// Input can be prefixed with a=.
2040$5d0e6002f6ec24ec$var$SDPUtils.parseCandidate = function(line) {
2041 let parts;
2042 // Parse both variants.
2043 if (line.indexOf("a=candidate:") === 0) parts = line.substring(12).split(" ");
2044 else parts = line.substring(10).split(" ");
2045 const candidate = {
2046 foundation: parts[0],
2047 component: {
2048 1: "rtp",
2049 2: "rtcp"
2050 }[parts[1]] || parts[1],
2051 protocol: parts[2].toLowerCase(),
2052 priority: parseInt(parts[3], 10),
2053 ip: parts[4],
2054 address: parts[4],
2055 port: parseInt(parts[5], 10),
2056 // skip parts[6] == 'typ'
2057 type: parts[7]
2058 };
2059 for(let i = 8; i < parts.length; i += 2)switch(parts[i]){
2060 case "raddr":
2061 candidate.relatedAddress = parts[i + 1];
2062 break;
2063 case "rport":
2064 candidate.relatedPort = parseInt(parts[i + 1], 10);
2065 break;
2066 case "tcptype":
2067 candidate.tcpType = parts[i + 1];
2068 break;
2069 case "ufrag":
2070 candidate.ufrag = parts[i + 1]; // for backward compatibility.
2071 candidate.usernameFragment = parts[i + 1];
2072 break;
2073 default:
2074 if (candidate[parts[i]] === undefined) candidate[parts[i]] = parts[i + 1];
2075 break;
2076 }
2077 return candidate;
2078};
2079// Translates a candidate object into SDP candidate attribute.
2080// This does not include the a= prefix!
2081$5d0e6002f6ec24ec$var$SDPUtils.writeCandidate = function(candidate) {
2082 const sdp = [];
2083 sdp.push(candidate.foundation);
2084 const component = candidate.component;
2085 if (component === "rtp") sdp.push(1);
2086 else if (component === "rtcp") sdp.push(2);
2087 else sdp.push(component);
2088 sdp.push(candidate.protocol.toUpperCase());
2089 sdp.push(candidate.priority);
2090 sdp.push(candidate.address || candidate.ip);
2091 sdp.push(candidate.port);
2092 const type = candidate.type;
2093 sdp.push("typ");
2094 sdp.push(type);
2095 if (type !== "host" && candidate.relatedAddress && candidate.relatedPort) {
2096 sdp.push("raddr");
2097 sdp.push(candidate.relatedAddress);
2098 sdp.push("rport");
2099 sdp.push(candidate.relatedPort);
2100 }
2101 if (candidate.tcpType && candidate.protocol.toLowerCase() === "tcp") {
2102 sdp.push("tcptype");
2103 sdp.push(candidate.tcpType);
2104 }
2105 if (candidate.usernameFragment || candidate.ufrag) {
2106 sdp.push("ufrag");
2107 sdp.push(candidate.usernameFragment || candidate.ufrag);
2108 }
2109 return "candidate:" + sdp.join(" ");
2110};
2111// Parses an ice-options line, returns an array of option tags.
2112// Sample input:
2113// a=ice-options:foo bar
2114$5d0e6002f6ec24ec$var$SDPUtils.parseIceOptions = function(line) {
2115 return line.substring(14).split(" ");
2116};
2117// Parses a rtpmap line, returns RTCRtpCoddecParameters. Sample input:
2118// a=rtpmap:111 opus/48000/2
2119$5d0e6002f6ec24ec$var$SDPUtils.parseRtpMap = function(line) {
2120 let parts = line.substring(9).split(" ");
2121 const parsed = {
2122 payloadType: parseInt(parts.shift(), 10)
2123 };
2124 parts = parts[0].split("/");
2125 parsed.name = parts[0];
2126 parsed.clockRate = parseInt(parts[1], 10); // was: clockrate
2127 parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1;
2128 // legacy alias, got renamed back to channels in ORTC.
2129 parsed.numChannels = parsed.channels;
2130 return parsed;
2131};
2132// Generates a rtpmap line from RTCRtpCodecCapability or
2133// RTCRtpCodecParameters.
2134$5d0e6002f6ec24ec$var$SDPUtils.writeRtpMap = function(codec) {
2135 let pt = codec.payloadType;
2136 if (codec.preferredPayloadType !== undefined) pt = codec.preferredPayloadType;
2137 const channels = codec.channels || codec.numChannels || 1;
2138 return "a=rtpmap:" + pt + " " + codec.name + "/" + codec.clockRate + (channels !== 1 ? "/" + channels : "") + "\r\n";
2139};
2140// Parses a extmap line (headerextension from RFC 5285). Sample input:
2141// a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
2142// a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset
2143$5d0e6002f6ec24ec$var$SDPUtils.parseExtmap = function(line) {
2144 const parts = line.substring(9).split(" ");
2145 return {
2146 id: parseInt(parts[0], 10),
2147 direction: parts[0].indexOf("/") > 0 ? parts[0].split("/")[1] : "sendrecv",
2148 uri: parts[1],
2149 attributes: parts.slice(2).join(" ")
2150 };
2151};
2152// Generates an extmap line from RTCRtpHeaderExtensionParameters or
2153// RTCRtpHeaderExtension.
2154$5d0e6002f6ec24ec$var$SDPUtils.writeExtmap = function(headerExtension) {
2155 return "a=extmap:" + (headerExtension.id || headerExtension.preferredId) + (headerExtension.direction && headerExtension.direction !== "sendrecv" ? "/" + headerExtension.direction : "") + " " + headerExtension.uri + (headerExtension.attributes ? " " + headerExtension.attributes : "") + "\r\n";
2156};
2157// Parses a fmtp line, returns dictionary. Sample input:
2158// a=fmtp:96 vbr=on;cng=on
2159// Also deals with vbr=on; cng=on
2160$5d0e6002f6ec24ec$var$SDPUtils.parseFmtp = function(line) {
2161 const parsed = {};
2162 let kv;
2163 const parts = line.substring(line.indexOf(" ") + 1).split(";");
2164 for(let j = 0; j < parts.length; j++){
2165 kv = parts[j].trim().split("=");
2166 parsed[kv[0].trim()] = kv[1];
2167 }
2168 return parsed;
2169};
2170// Generates a fmtp line from RTCRtpCodecCapability or RTCRtpCodecParameters.
2171$5d0e6002f6ec24ec$var$SDPUtils.writeFmtp = function(codec) {
2172 let line = "";
2173 let pt = codec.payloadType;
2174 if (codec.preferredPayloadType !== undefined) pt = codec.preferredPayloadType;
2175 if (codec.parameters && Object.keys(codec.parameters).length) {
2176 const params = [];
2177 Object.keys(codec.parameters).forEach((param)=>{
2178 if (codec.parameters[param] !== undefined) params.push(param + "=" + codec.parameters[param]);
2179 else params.push(param);
2180 });
2181 line += "a=fmtp:" + pt + " " + params.join(";") + "\r\n";
2182 }
2183 return line;
2184};
2185// Parses a rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:
2186// a=rtcp-fb:98 nack rpsi
2187$5d0e6002f6ec24ec$var$SDPUtils.parseRtcpFb = function(line) {
2188 const parts = line.substring(line.indexOf(" ") + 1).split(" ");
2189 return {
2190 type: parts.shift(),
2191 parameter: parts.join(" ")
2192 };
2193};
2194// Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.
2195$5d0e6002f6ec24ec$var$SDPUtils.writeRtcpFb = function(codec) {
2196 let lines = "";
2197 let pt = codec.payloadType;
2198 if (codec.preferredPayloadType !== undefined) pt = codec.preferredPayloadType;
2199 if (codec.rtcpFeedback && codec.rtcpFeedback.length) // FIXME: special handling for trr-int?
2200 codec.rtcpFeedback.forEach((fb)=>{
2201 lines += "a=rtcp-fb:" + pt + " " + fb.type + (fb.parameter && fb.parameter.length ? " " + fb.parameter : "") + "\r\n";
2202 });
2203 return lines;
2204};
2205// Parses a RFC 5576 ssrc media attribute. Sample input:
2206// a=ssrc:3735928559 cname:something
2207$5d0e6002f6ec24ec$var$SDPUtils.parseSsrcMedia = function(line) {
2208 const sp = line.indexOf(" ");
2209 const parts = {
2210 ssrc: parseInt(line.substring(7, sp), 10)
2211 };
2212 const colon = line.indexOf(":", sp);
2213 if (colon > -1) {
2214 parts.attribute = line.substring(sp + 1, colon);
2215 parts.value = line.substring(colon + 1);
2216 } else parts.attribute = line.substring(sp + 1);
2217 return parts;
2218};
2219// Parse a ssrc-group line (see RFC 5576). Sample input:
2220// a=ssrc-group:semantics 12 34
2221$5d0e6002f6ec24ec$var$SDPUtils.parseSsrcGroup = function(line) {
2222 const parts = line.substring(13).split(" ");
2223 return {
2224 semantics: parts.shift(),
2225 ssrcs: parts.map((ssrc)=>parseInt(ssrc, 10))
2226 };
2227};
2228// Extracts the MID (RFC 5888) from a media section.
2229// Returns the MID or undefined if no mid line was found.
2230$5d0e6002f6ec24ec$var$SDPUtils.getMid = function(mediaSection) {
2231 const mid = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=mid:")[0];
2232 if (mid) return mid.substring(6);
2233};
2234// Parses a fingerprint line for DTLS-SRTP.
2235$5d0e6002f6ec24ec$var$SDPUtils.parseFingerprint = function(line) {
2236 const parts = line.substring(14).split(" ");
2237 return {
2238 algorithm: parts[0].toLowerCase(),
2239 value: parts[1].toUpperCase()
2240 };
2241};
2242// Extracts DTLS parameters from SDP media section or sessionpart.
2243// FIXME: for consistency with other functions this should only
2244// get the fingerprint line as input. See also getIceParameters.
2245$5d0e6002f6ec24ec$var$SDPUtils.getDtlsParameters = function(mediaSection, sessionpart) {
2246 const lines = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection + sessionpart, "a=fingerprint:");
2247 // Note: a=setup line is ignored since we use the 'auto' role in Edge.
2248 return {
2249 role: "auto",
2250 fingerprints: lines.map($5d0e6002f6ec24ec$var$SDPUtils.parseFingerprint)
2251 };
2252};
2253// Serializes DTLS parameters to SDP.
2254$5d0e6002f6ec24ec$var$SDPUtils.writeDtlsParameters = function(params, setupType) {
2255 let sdp = "a=setup:" + setupType + "\r\n";
2256 params.fingerprints.forEach((fp)=>{
2257 sdp += "a=fingerprint:" + fp.algorithm + " " + fp.value + "\r\n";
2258 });
2259 return sdp;
2260};
2261// Parses a=crypto lines into
2262// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#dictionary-rtcsrtpsdesparameters-members
2263$5d0e6002f6ec24ec$var$SDPUtils.parseCryptoLine = function(line) {
2264 const parts = line.substring(9).split(" ");
2265 return {
2266 tag: parseInt(parts[0], 10),
2267 cryptoSuite: parts[1],
2268 keyParams: parts[2],
2269 sessionParams: parts.slice(3)
2270 };
2271};
2272$5d0e6002f6ec24ec$var$SDPUtils.writeCryptoLine = function(parameters) {
2273 return "a=crypto:" + parameters.tag + " " + parameters.cryptoSuite + " " + (typeof parameters.keyParams === "object" ? $5d0e6002f6ec24ec$var$SDPUtils.writeCryptoKeyParams(parameters.keyParams) : parameters.keyParams) + (parameters.sessionParams ? " " + parameters.sessionParams.join(" ") : "") + "\r\n";
2274};
2275// Parses the crypto key parameters into
2276// https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#rtcsrtpkeyparam*
2277$5d0e6002f6ec24ec$var$SDPUtils.parseCryptoKeyParams = function(keyParams) {
2278 if (keyParams.indexOf("inline:") !== 0) return null;
2279 const parts = keyParams.substring(7).split("|");
2280 return {
2281 keyMethod: "inline",
2282 keySalt: parts[0],
2283 lifeTime: parts[1],
2284 mkiValue: parts[2] ? parts[2].split(":")[0] : undefined,
2285 mkiLength: parts[2] ? parts[2].split(":")[1] : undefined
2286 };
2287};
2288$5d0e6002f6ec24ec$var$SDPUtils.writeCryptoKeyParams = function(keyParams) {
2289 return keyParams.keyMethod + ":" + keyParams.keySalt + (keyParams.lifeTime ? "|" + keyParams.lifeTime : "") + (keyParams.mkiValue && keyParams.mkiLength ? "|" + keyParams.mkiValue + ":" + keyParams.mkiLength : "");
2290};
2291// Extracts all SDES parameters.
2292$5d0e6002f6ec24ec$var$SDPUtils.getCryptoParameters = function(mediaSection, sessionpart) {
2293 const lines = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection + sessionpart, "a=crypto:");
2294 return lines.map($5d0e6002f6ec24ec$var$SDPUtils.parseCryptoLine);
2295};
2296// Parses ICE information from SDP media section or sessionpart.
2297// FIXME: for consistency with other functions this should only
2298// get the ice-ufrag and ice-pwd lines as input.
2299$5d0e6002f6ec24ec$var$SDPUtils.getIceParameters = function(mediaSection, sessionpart) {
2300 const ufrag = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection + sessionpart, "a=ice-ufrag:")[0];
2301 const pwd = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection + sessionpart, "a=ice-pwd:")[0];
2302 if (!(ufrag && pwd)) return null;
2303 return {
2304 usernameFragment: ufrag.substring(12),
2305 password: pwd.substring(10)
2306 };
2307};
2308// Serializes ICE parameters to SDP.
2309$5d0e6002f6ec24ec$var$SDPUtils.writeIceParameters = function(params) {
2310 let sdp = "a=ice-ufrag:" + params.usernameFragment + "\r\n" + "a=ice-pwd:" + params.password + "\r\n";
2311 if (params.iceLite) sdp += "a=ice-lite\r\n";
2312 return sdp;
2313};
2314// Parses the SDP media section and returns RTCRtpParameters.
2315$5d0e6002f6ec24ec$var$SDPUtils.parseRtpParameters = function(mediaSection) {
2316 const description = {
2317 codecs: [],
2318 headerExtensions: [],
2319 fecMechanisms: [],
2320 rtcp: []
2321 };
2322 const lines = $5d0e6002f6ec24ec$var$SDPUtils.splitLines(mediaSection);
2323 const mline = lines[0].split(" ");
2324 description.profile = mline[2];
2325 for(let i = 3; i < mline.length; i++){
2326 const pt = mline[i];
2327 const rtpmapline = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=rtpmap:" + pt + " ")[0];
2328 if (rtpmapline) {
2329 const codec = $5d0e6002f6ec24ec$var$SDPUtils.parseRtpMap(rtpmapline);
2330 const fmtps = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=fmtp:" + pt + " ");
2331 // Only the first a=fmtp:<pt> is considered.
2332 codec.parameters = fmtps.length ? $5d0e6002f6ec24ec$var$SDPUtils.parseFmtp(fmtps[0]) : {};
2333 codec.rtcpFeedback = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=rtcp-fb:" + pt + " ").map($5d0e6002f6ec24ec$var$SDPUtils.parseRtcpFb);
2334 description.codecs.push(codec);
2335 // parse FEC mechanisms from rtpmap lines.
2336 switch(codec.name.toUpperCase()){
2337 case "RED":
2338 case "ULPFEC":
2339 description.fecMechanisms.push(codec.name.toUpperCase());
2340 break;
2341 default:
2342 break;
2343 }
2344 }
2345 }
2346 $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=extmap:").forEach((line)=>{
2347 description.headerExtensions.push($5d0e6002f6ec24ec$var$SDPUtils.parseExtmap(line));
2348 });
2349 const wildcardRtcpFb = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=rtcp-fb:* ").map($5d0e6002f6ec24ec$var$SDPUtils.parseRtcpFb);
2350 description.codecs.forEach((codec)=>{
2351 wildcardRtcpFb.forEach((fb)=>{
2352 const duplicate = codec.rtcpFeedback.find((existingFeedback)=>{
2353 return existingFeedback.type === fb.type && existingFeedback.parameter === fb.parameter;
2354 });
2355 if (!duplicate) codec.rtcpFeedback.push(fb);
2356 });
2357 });
2358 // FIXME: parse rtcp.
2359 return description;
2360};
2361// Generates parts of the SDP media section describing the capabilities /
2362// parameters.
2363$5d0e6002f6ec24ec$var$SDPUtils.writeRtpDescription = function(kind, caps) {
2364 let sdp = "";
2365 // Build the mline.
2366 sdp += "m=" + kind + " ";
2367 sdp += caps.codecs.length > 0 ? "9" : "0"; // reject if no codecs.
2368 sdp += " " + (caps.profile || "UDP/TLS/RTP/SAVPF") + " ";
2369 sdp += caps.codecs.map((codec)=>{
2370 if (codec.preferredPayloadType !== undefined) return codec.preferredPayloadType;
2371 return codec.payloadType;
2372 }).join(" ") + "\r\n";
2373 sdp += "c=IN IP4 0.0.0.0\r\n";
2374 sdp += "a=rtcp:9 IN IP4 0.0.0.0\r\n";
2375 // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.
2376 caps.codecs.forEach((codec)=>{
2377 sdp += $5d0e6002f6ec24ec$var$SDPUtils.writeRtpMap(codec);
2378 sdp += $5d0e6002f6ec24ec$var$SDPUtils.writeFmtp(codec);
2379 sdp += $5d0e6002f6ec24ec$var$SDPUtils.writeRtcpFb(codec);
2380 });
2381 let maxptime = 0;
2382 caps.codecs.forEach((codec)=>{
2383 if (codec.maxptime > maxptime) maxptime = codec.maxptime;
2384 });
2385 if (maxptime > 0) sdp += "a=maxptime:" + maxptime + "\r\n";
2386 if (caps.headerExtensions) caps.headerExtensions.forEach((extension)=>{
2387 sdp += $5d0e6002f6ec24ec$var$SDPUtils.writeExtmap(extension);
2388 });
2389 // FIXME: write fecMechanisms.
2390 return sdp;
2391};
2392// Parses the SDP media section and returns an array of
2393// RTCRtpEncodingParameters.
2394$5d0e6002f6ec24ec$var$SDPUtils.parseRtpEncodingParameters = function(mediaSection) {
2395 const encodingParameters = [];
2396 const description = $5d0e6002f6ec24ec$var$SDPUtils.parseRtpParameters(mediaSection);
2397 const hasRed = description.fecMechanisms.indexOf("RED") !== -1;
2398 const hasUlpfec = description.fecMechanisms.indexOf("ULPFEC") !== -1;
2399 // filter a=ssrc:... cname:, ignore PlanB-msid
2400 const ssrcs = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=ssrc:").map((line)=>$5d0e6002f6ec24ec$var$SDPUtils.parseSsrcMedia(line)).filter((parts)=>parts.attribute === "cname");
2401 const primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;
2402 let secondarySsrc;
2403 const flows = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=ssrc-group:FID").map((line)=>{
2404 const parts = line.substring(17).split(" ");
2405 return parts.map((part)=>parseInt(part, 10));
2406 });
2407 if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) secondarySsrc = flows[0][1];
2408 description.codecs.forEach((codec)=>{
2409 if (codec.name.toUpperCase() === "RTX" && codec.parameters.apt) {
2410 let encParam = {
2411 ssrc: primarySsrc,
2412 codecPayloadType: parseInt(codec.parameters.apt, 10)
2413 };
2414 if (primarySsrc && secondarySsrc) encParam.rtx = {
2415 ssrc: secondarySsrc
2416 };
2417 encodingParameters.push(encParam);
2418 if (hasRed) {
2419 encParam = JSON.parse(JSON.stringify(encParam));
2420 encParam.fec = {
2421 ssrc: primarySsrc,
2422 mechanism: hasUlpfec ? "red+ulpfec" : "red"
2423 };
2424 encodingParameters.push(encParam);
2425 }
2426 }
2427 });
2428 if (encodingParameters.length === 0 && primarySsrc) encodingParameters.push({
2429 ssrc: primarySsrc
2430 });
2431 // we support both b=AS and b=TIAS but interpret AS as TIAS.
2432 let bandwidth = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "b=");
2433 if (bandwidth.length) {
2434 if (bandwidth[0].indexOf("b=TIAS:") === 0) bandwidth = parseInt(bandwidth[0].substring(7), 10);
2435 else if (bandwidth[0].indexOf("b=AS:") === 0) // use formula from JSEP to convert b=AS to TIAS value.
2436 bandwidth = parseInt(bandwidth[0].substring(5), 10) * 950 - 16000;
2437 else bandwidth = undefined;
2438 encodingParameters.forEach((params)=>{
2439 params.maxBitrate = bandwidth;
2440 });
2441 }
2442 return encodingParameters;
2443};
2444// parses http://draft.ortc.org/#rtcrtcpparameters*
2445$5d0e6002f6ec24ec$var$SDPUtils.parseRtcpParameters = function(mediaSection) {
2446 const rtcpParameters = {};
2447 // Gets the first SSRC. Note that with RTX there might be multiple
2448 // SSRCs.
2449 const remoteSsrc = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=ssrc:").map((line)=>$5d0e6002f6ec24ec$var$SDPUtils.parseSsrcMedia(line)).filter((obj)=>obj.attribute === "cname")[0];
2450 if (remoteSsrc) {
2451 rtcpParameters.cname = remoteSsrc.value;
2452 rtcpParameters.ssrc = remoteSsrc.ssrc;
2453 }
2454 // Edge uses the compound attribute instead of reducedSize
2455 // compound is !reducedSize
2456 const rsize = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=rtcp-rsize");
2457 rtcpParameters.reducedSize = rsize.length > 0;
2458 rtcpParameters.compound = rsize.length === 0;
2459 // parses the rtcp-mux attrіbute.
2460 // Note that Edge does not support unmuxed RTCP.
2461 const mux = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=rtcp-mux");
2462 rtcpParameters.mux = mux.length > 0;
2463 return rtcpParameters;
2464};
2465$5d0e6002f6ec24ec$var$SDPUtils.writeRtcpParameters = function(rtcpParameters) {
2466 let sdp = "";
2467 if (rtcpParameters.reducedSize) sdp += "a=rtcp-rsize\r\n";
2468 if (rtcpParameters.mux) sdp += "a=rtcp-mux\r\n";
2469 if (rtcpParameters.ssrc !== undefined && rtcpParameters.cname) sdp += "a=ssrc:" + rtcpParameters.ssrc + " cname:" + rtcpParameters.cname + "\r\n";
2470 return sdp;
2471};
2472// parses either a=msid: or a=ssrc:... msid lines and returns
2473// the id of the MediaStream and MediaStreamTrack.
2474$5d0e6002f6ec24ec$var$SDPUtils.parseMsid = function(mediaSection) {
2475 let parts;
2476 const spec = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=msid:");
2477 if (spec.length === 1) {
2478 parts = spec[0].substring(7).split(" ");
2479 return {
2480 stream: parts[0],
2481 track: parts[1]
2482 };
2483 }
2484 const planB = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=ssrc:").map((line)=>$5d0e6002f6ec24ec$var$SDPUtils.parseSsrcMedia(line)).filter((msidParts)=>msidParts.attribute === "msid");
2485 if (planB.length > 0) {
2486 parts = planB[0].value.split(" ");
2487 return {
2488 stream: parts[0],
2489 track: parts[1]
2490 };
2491 }
2492};
2493// SCTP
2494// parses draft-ietf-mmusic-sctp-sdp-26 first and falls back
2495// to draft-ietf-mmusic-sctp-sdp-05
2496$5d0e6002f6ec24ec$var$SDPUtils.parseSctpDescription = function(mediaSection) {
2497 const mline = $5d0e6002f6ec24ec$var$SDPUtils.parseMLine(mediaSection);
2498 const maxSizeLine = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=max-message-size:");
2499 let maxMessageSize;
2500 if (maxSizeLine.length > 0) maxMessageSize = parseInt(maxSizeLine[0].substring(19), 10);
2501 if (isNaN(maxMessageSize)) maxMessageSize = 65536;
2502 const sctpPort = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=sctp-port:");
2503 if (sctpPort.length > 0) return {
2504 port: parseInt(sctpPort[0].substring(12), 10),
2505 protocol: mline.fmt,
2506 maxMessageSize: maxMessageSize
2507 };
2508 const sctpMapLines = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "a=sctpmap:");
2509 if (sctpMapLines.length > 0) {
2510 const parts = sctpMapLines[0].substring(10).split(" ");
2511 return {
2512 port: parseInt(parts[0], 10),
2513 protocol: parts[1],
2514 maxMessageSize: maxMessageSize
2515 };
2516 }
2517};
2518// SCTP
2519// outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers
2520// support by now receiving in this format, unless we originally parsed
2521// as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line
2522// protocol of DTLS/SCTP -- without UDP/ or TCP/)
2523$5d0e6002f6ec24ec$var$SDPUtils.writeSctpDescription = function(media, sctp) {
2524 let output = [];
2525 if (media.protocol !== "DTLS/SCTP") output = [
2526 "m=" + media.kind + " 9 " + media.protocol + " " + sctp.protocol + "\r\n",
2527 "c=IN IP4 0.0.0.0\r\n",
2528 "a=sctp-port:" + sctp.port + "\r\n"
2529 ];
2530 else output = [
2531 "m=" + media.kind + " 9 " + media.protocol + " " + sctp.port + "\r\n",
2532 "c=IN IP4 0.0.0.0\r\n",
2533 "a=sctpmap:" + sctp.port + " " + sctp.protocol + " 65535\r\n"
2534 ];
2535 if (sctp.maxMessageSize !== undefined) output.push("a=max-message-size:" + sctp.maxMessageSize + "\r\n");
2536 return output.join("");
2537};
2538// Generate a session ID for SDP.
2539// https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1
2540// recommends using a cryptographically random +ve 64-bit value
2541// but right now this should be acceptable and within the right range
2542$5d0e6002f6ec24ec$var$SDPUtils.generateSessionId = function() {
2543 return Math.random().toString().substr(2, 22);
2544};
2545// Write boiler plate for start of SDP
2546// sessId argument is optional - if not supplied it will
2547// be generated randomly
2548// sessVersion is optional and defaults to 2
2549// sessUser is optional and defaults to 'thisisadapterortc'
2550$5d0e6002f6ec24ec$var$SDPUtils.writeSessionBoilerplate = function(sessId, sessVer, sessUser) {
2551 let sessionId;
2552 const version = sessVer !== undefined ? sessVer : 2;
2553 if (sessId) sessionId = sessId;
2554 else sessionId = $5d0e6002f6ec24ec$var$SDPUtils.generateSessionId();
2555 const user = sessUser || "thisisadapterortc";
2556 // FIXME: sess-id should be an NTP timestamp.
2557 return "v=0\r\no=" + user + " " + sessionId + " " + version + " IN IP4 127.0.0.1\r\n" + "s=-\r\n" + "t=0 0\r\n";
2558};
2559// Gets the direction from the mediaSection or the sessionpart.
2560$5d0e6002f6ec24ec$var$SDPUtils.getDirection = function(mediaSection, sessionpart) {
2561 // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.
2562 const lines = $5d0e6002f6ec24ec$var$SDPUtils.splitLines(mediaSection);
2563 for(let i = 0; i < lines.length; i++)switch(lines[i]){
2564 case "a=sendrecv":
2565 case "a=sendonly":
2566 case "a=recvonly":
2567 case "a=inactive":
2568 return lines[i].substring(2);
2569 default:
2570 }
2571 if (sessionpart) return $5d0e6002f6ec24ec$var$SDPUtils.getDirection(sessionpart);
2572 return "sendrecv";
2573};
2574$5d0e6002f6ec24ec$var$SDPUtils.getKind = function(mediaSection) {
2575 const lines = $5d0e6002f6ec24ec$var$SDPUtils.splitLines(mediaSection);
2576 const mline = lines[0].split(" ");
2577 return mline[0].substring(2);
2578};
2579$5d0e6002f6ec24ec$var$SDPUtils.isRejected = function(mediaSection) {
2580 return mediaSection.split(" ", 2)[1] === "0";
2581};
2582$5d0e6002f6ec24ec$var$SDPUtils.parseMLine = function(mediaSection) {
2583 const lines = $5d0e6002f6ec24ec$var$SDPUtils.splitLines(mediaSection);
2584 const parts = lines[0].substring(2).split(" ");
2585 return {
2586 kind: parts[0],
2587 port: parseInt(parts[1], 10),
2588 protocol: parts[2],
2589 fmt: parts.slice(3).join(" ")
2590 };
2591};
2592$5d0e6002f6ec24ec$var$SDPUtils.parseOLine = function(mediaSection) {
2593 const line = $5d0e6002f6ec24ec$var$SDPUtils.matchPrefix(mediaSection, "o=")[0];
2594 const parts = line.substring(2).split(" ");
2595 return {
2596 username: parts[0],
2597 sessionId: parts[1],
2598 sessionVersion: parseInt(parts[2], 10),
2599 netType: parts[3],
2600 addressType: parts[4],
2601 address: parts[5]
2602 };
2603};
2604// a very naive interpretation of a valid SDP.
2605$5d0e6002f6ec24ec$var$SDPUtils.isValidSDP = function(blob) {
2606 if (typeof blob !== "string" || blob.length === 0) return false;
2607 const lines = $5d0e6002f6ec24ec$var$SDPUtils.splitLines(blob);
2608 for(let i = 0; i < lines.length; i++){
2609 if (lines[i].length < 2 || lines[i].charAt(1) !== "=") return false;
2610 // TODO: check the modifier a bit more.
2611 }
2612 return true;
2613};
2614$5d0e6002f6ec24ec$exports = $5d0e6002f6ec24ec$var$SDPUtils;
2615
2616
2617
2618"use strict";
2619function $5151b78094cea2ba$export$cf133661e444ccfe(window) {
2620 // foundation is arbitrarily chosen as an indicator for full support for
2621 // https://w3c.github.io/webrtc-pc/#rtcicecandidate-interface
2622 if (!window.RTCIceCandidate || window.RTCIceCandidate && "foundation" in window.RTCIceCandidate.prototype) return;
2623 const NativeRTCIceCandidate = window.RTCIceCandidate;
2624 window.RTCIceCandidate = function RTCIceCandidate(args) {
2625 // Remove the a= which shouldn't be part of the candidate string.
2626 if (typeof args === "object" && args.candidate && args.candidate.indexOf("a=") === 0) {
2627 args = JSON.parse(JSON.stringify(args));
2628 args.candidate = args.candidate.substring(2);
2629 }
2630 if (args.candidate && args.candidate.length) {
2631 // Augment the native candidate with the parsed fields.
2632 const nativeCandidate = new NativeRTCIceCandidate(args);
2633 const parsedCandidate = (0, (/*@__PURE__*/$parcel$interopDefault($5d0e6002f6ec24ec$exports))).parseCandidate(args.candidate);
2634 for(const key in parsedCandidate)if (!(key in nativeCandidate)) Object.defineProperty(nativeCandidate, key, {
2635 value: parsedCandidate[key]
2636 });
2637 // Override serializer to not serialize the extra attributes.
2638 nativeCandidate.toJSON = function toJSON() {
2639 return {
2640 candidate: nativeCandidate.candidate,
2641 sdpMid: nativeCandidate.sdpMid,
2642 sdpMLineIndex: nativeCandidate.sdpMLineIndex,
2643 usernameFragment: nativeCandidate.usernameFragment
2644 };
2645 };
2646 return nativeCandidate;
2647 }
2648 return new NativeRTCIceCandidate(args);
2649 };
2650 window.RTCIceCandidate.prototype = NativeRTCIceCandidate.prototype;
2651 // Hook up the augmented candidate in onicecandidate and
2652 // addEventListener('icecandidate', ...)
2653 $9fea4db837311579$export$1f48841962b828b1(window, "icecandidate", (e)=>{
2654 if (e.candidate) Object.defineProperty(e, "candidate", {
2655 value: new window.RTCIceCandidate(e.candidate),
2656 writable: "false"
2657 });
2658 return e;
2659 });
2660}
2661function $5151b78094cea2ba$export$fdafb8d8280e29b5(window) {
2662 if (!window.RTCIceCandidate || window.RTCIceCandidate && "relayProtocol" in window.RTCIceCandidate.prototype) return;
2663 // Hook up the augmented candidate in onicecandidate and
2664 // addEventListener('icecandidate', ...)
2665 $9fea4db837311579$export$1f48841962b828b1(window, "icecandidate", (e)=>{
2666 if (e.candidate) {
2667 const parsedCandidate = (0, (/*@__PURE__*/$parcel$interopDefault($5d0e6002f6ec24ec$exports))).parseCandidate(e.candidate.candidate);
2668 if (parsedCandidate.type === "relay") // This is a libwebrtc-specific mapping of local type preference
2669 // to relayProtocol.
2670 e.candidate.relayProtocol = ({
2671 0: "tls",
2672 1: "tcp",
2673 2: "udp"
2674 })[parsedCandidate.priority >> 24];
2675 }
2676 return e;
2677 });
2678}
2679function $5151b78094cea2ba$export$a99147c78a56edc4(window, browserDetails) {
2680 if (!window.RTCPeerConnection) return;
2681 if (!("sctp" in window.RTCPeerConnection.prototype)) Object.defineProperty(window.RTCPeerConnection.prototype, "sctp", {
2682 get () {
2683 return typeof this._sctp === "undefined" ? null : this._sctp;
2684 }
2685 });
2686 const sctpInDescription = function(description) {
2687 if (!description || !description.sdp) return false;
2688 const sections = (0, (/*@__PURE__*/$parcel$interopDefault($5d0e6002f6ec24ec$exports))).splitSections(description.sdp);
2689 sections.shift();
2690 return sections.some((mediaSection)=>{
2691 const mLine = (0, (/*@__PURE__*/$parcel$interopDefault($5d0e6002f6ec24ec$exports))).parseMLine(mediaSection);
2692 return mLine && mLine.kind === "application" && mLine.protocol.indexOf("SCTP") !== -1;
2693 });
2694 };
2695 const getRemoteFirefoxVersion = function(description) {
2696 // TODO: Is there a better solution for detecting Firefox?
2697 const match = description.sdp.match(/mozilla...THIS_IS_SDPARTA-(\d+)/);
2698 if (match === null || match.length < 2) return -1;
2699 const version = parseInt(match[1], 10);
2700 // Test for NaN (yes, this is ugly)
2701 return version !== version ? -1 : version;
2702 };
2703 const getCanSendMaxMessageSize = function(remoteIsFirefox) {
2704 // Every implementation we know can send at least 64 KiB.
2705 // Note: Although Chrome is technically able to send up to 256 KiB, the
2706 // data does not reach the other peer reliably.
2707 // See: https://bugs.chromium.org/p/webrtc/issues/detail?id=8419
2708 let canSendMaxMessageSize = 65536;
2709 if (browserDetails.browser === "firefox") {
2710 if (browserDetails.version < 57) {
2711 if (remoteIsFirefox === -1) // FF < 57 will send in 16 KiB chunks using the deprecated PPID
2712 // fragmentation.
2713 canSendMaxMessageSize = 16384;
2714 else // However, other FF (and RAWRTC) can reassemble PPID-fragmented
2715 // messages. Thus, supporting ~2 GiB when sending.
2716 canSendMaxMessageSize = 2147483637;
2717 } else if (browserDetails.version < 60) // Currently, all FF >= 57 will reset the remote maximum message size
2718 // to the default value when a data channel is created at a later
2719 // stage. :(
2720 // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831
2721 canSendMaxMessageSize = browserDetails.version === 57 ? 65535 : 65536;
2722 else // FF >= 60 supports sending ~2 GiB
2723 canSendMaxMessageSize = 2147483637;
2724 }
2725 return canSendMaxMessageSize;
2726 };
2727 const getMaxMessageSize = function(description, remoteIsFirefox) {
2728 // Note: 65536 bytes is the default value from the SDP spec. Also,
2729 // every implementation we know supports receiving 65536 bytes.
2730 let maxMessageSize = 65536;
2731 // FF 57 has a slightly incorrect default remote max message size, so
2732 // we need to adjust it here to avoid a failure when sending.
2733 // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1425697
2734 if (browserDetails.browser === "firefox" && browserDetails.version === 57) maxMessageSize = 65535;
2735 const match = (0, (/*@__PURE__*/$parcel$interopDefault($5d0e6002f6ec24ec$exports))).matchPrefix(description.sdp, "a=max-message-size:");
2736 if (match.length > 0) maxMessageSize = parseInt(match[0].substring(19), 10);
2737 else if (browserDetails.browser === "firefox" && remoteIsFirefox !== -1) // If the maximum message size is not present in the remote SDP and
2738 // both local and remote are Firefox, the remote peer can receive
2739 // ~2 GiB.
2740 maxMessageSize = 2147483637;
2741 return maxMessageSize;
2742 };
2743 const origSetRemoteDescription = window.RTCPeerConnection.prototype.setRemoteDescription;
2744 window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() {
2745 this._sctp = null;
2746 // Chrome decided to not expose .sctp in plan-b mode.
2747 // As usual, adapter.js has to do an 'ugly worakaround'
2748 // to cover up the mess.
2749 if (browserDetails.browser === "chrome" && browserDetails.version >= 76) {
2750 const { sdpSemantics: sdpSemantics } = this.getConfiguration();
2751 if (sdpSemantics === "plan-b") Object.defineProperty(this, "sctp", {
2752 get () {
2753 return typeof this._sctp === "undefined" ? null : this._sctp;
2754 },
2755 enumerable: true,
2756 configurable: true
2757 });
2758 }
2759 if (sctpInDescription(arguments[0])) {
2760 // Check if the remote is FF.
2761 const isFirefox = getRemoteFirefoxVersion(arguments[0]);
2762 // Get the maximum message size the local peer is capable of sending
2763 const canSendMMS = getCanSendMaxMessageSize(isFirefox);
2764 // Get the maximum message size of the remote peer.
2765 const remoteMMS = getMaxMessageSize(arguments[0], isFirefox);
2766 // Determine final maximum message size
2767 let maxMessageSize;
2768 if (canSendMMS === 0 && remoteMMS === 0) maxMessageSize = Number.POSITIVE_INFINITY;
2769 else if (canSendMMS === 0 || remoteMMS === 0) maxMessageSize = Math.max(canSendMMS, remoteMMS);
2770 else maxMessageSize = Math.min(canSendMMS, remoteMMS);
2771 // Create a dummy RTCSctpTransport object and the 'maxMessageSize'
2772 // attribute.
2773 const sctp = {};
2774 Object.defineProperty(sctp, "maxMessageSize", {
2775 get () {
2776 return maxMessageSize;
2777 }
2778 });
2779 this._sctp = sctp;
2780 }
2781 return origSetRemoteDescription.apply(this, arguments);
2782 };
2783}
2784function $5151b78094cea2ba$export$d461c8d5c5db5da7(window) {
2785 if (!(window.RTCPeerConnection && "createDataChannel" in window.RTCPeerConnection.prototype)) return;
2786 // Note: Although Firefox >= 57 has a native implementation, the maximum
2787 // message size can be reset for all data channels at a later stage.
2788 // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831
2789 function wrapDcSend(dc, pc) {
2790 const origDataChannelSend = dc.send;
2791 dc.send = function send() {
2792 const data = arguments[0];
2793 const length = data.length || data.size || data.byteLength;
2794 if (dc.readyState === "open" && pc.sctp && length > pc.sctp.maxMessageSize) throw new TypeError("Message too large (can send a maximum of " + pc.sctp.maxMessageSize + " bytes)");
2795 return origDataChannelSend.apply(dc, arguments);
2796 };
2797 }
2798 const origCreateDataChannel = window.RTCPeerConnection.prototype.createDataChannel;
2799 window.RTCPeerConnection.prototype.createDataChannel = function createDataChannel() {
2800 const dataChannel = origCreateDataChannel.apply(this, arguments);
2801 wrapDcSend(dataChannel, this);
2802 return dataChannel;
2803 };
2804 $9fea4db837311579$export$1f48841962b828b1(window, "datachannel", (e)=>{
2805 wrapDcSend(e.channel, e.target);
2806 return e;
2807 });
2808}
2809function $5151b78094cea2ba$export$63bb816cc75460(window) {
2810 if (!window.RTCPeerConnection || "connectionState" in window.RTCPeerConnection.prototype) return;
2811 const proto = window.RTCPeerConnection.prototype;
2812 Object.defineProperty(proto, "connectionState", {
2813 get () {
2814 return ({
2815 completed: "connected",
2816 checking: "connecting"
2817 })[this.iceConnectionState] || this.iceConnectionState;
2818 },
2819 enumerable: true,
2820 configurable: true
2821 });
2822 Object.defineProperty(proto, "onconnectionstatechange", {
2823 get () {
2824 return this._onconnectionstatechange || null;
2825 },
2826 set (cb) {
2827 if (this._onconnectionstatechange) {
2828 this.removeEventListener("connectionstatechange", this._onconnectionstatechange);
2829 delete this._onconnectionstatechange;
2830 }
2831 if (cb) this.addEventListener("connectionstatechange", this._onconnectionstatechange = cb);
2832 },
2833 enumerable: true,
2834 configurable: true
2835 });
2836 [
2837 "setLocalDescription",
2838 "setRemoteDescription"
2839 ].forEach((method)=>{
2840 const origMethod = proto[method];
2841 proto[method] = function() {
2842 if (!this._connectionstatechangepoly) {
2843 this._connectionstatechangepoly = (e)=>{
2844 const pc = e.target;
2845 if (pc._lastConnectionState !== pc.connectionState) {
2846 pc._lastConnectionState = pc.connectionState;
2847 const newEvent = new Event("connectionstatechange", e);
2848 pc.dispatchEvent(newEvent);
2849 }
2850 return e;
2851 };
2852 this.addEventListener("iceconnectionstatechange", this._connectionstatechangepoly);
2853 }
2854 return origMethod.apply(this, arguments);
2855 };
2856 });
2857}
2858function $5151b78094cea2ba$export$a57d114344295149(window, browserDetails) {
2859 /* remove a=extmap-allow-mixed for webrtc.org < M71 */ if (!window.RTCPeerConnection) return;
2860 if (browserDetails.browser === "chrome" && browserDetails.version >= 71) return;
2861 if (browserDetails.browser === "safari" && browserDetails.version >= 605) return;
2862 const nativeSRD = window.RTCPeerConnection.prototype.setRemoteDescription;
2863 window.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription(desc) {
2864 if (desc && desc.sdp && desc.sdp.indexOf("\na=extmap-allow-mixed") !== -1) {
2865 const sdp = desc.sdp.split("\n").filter((line)=>{
2866 return line.trim() !== "a=extmap-allow-mixed";
2867 }).join("\n");
2868 // Safari enforces read-only-ness of RTCSessionDescription fields.
2869 if (window.RTCSessionDescription && desc instanceof window.RTCSessionDescription) arguments[0] = new window.RTCSessionDescription({
2870 type: desc.type,
2871 sdp: sdp
2872 });
2873 else desc.sdp = sdp;
2874 }
2875 return nativeSRD.apply(this, arguments);
2876 };
2877}
2878function $5151b78094cea2ba$export$51d5e40b48c771c7(window, browserDetails) {
2879 // Support for addIceCandidate(null or undefined)
2880 // as well as addIceCandidate({candidate: "", ...})
2881 // https://bugs.chromium.org/p/chromium/issues/detail?id=978582
2882 // Note: must be called before other polyfills which change the signature.
2883 if (!(window.RTCPeerConnection && window.RTCPeerConnection.prototype)) return;
2884 const nativeAddIceCandidate = window.RTCPeerConnection.prototype.addIceCandidate;
2885 if (!nativeAddIceCandidate || nativeAddIceCandidate.length === 0) return;
2886 window.RTCPeerConnection.prototype.addIceCandidate = function addIceCandidate() {
2887 if (!arguments[0]) {
2888 if (arguments[1]) arguments[1].apply(null);
2889 return Promise.resolve();
2890 }
2891 // Firefox 68+ emits and processes {candidate: "", ...}, ignore
2892 // in older versions.
2893 // Native support for ignoring exists for Chrome M77+.
2894 // Safari ignores as well, exact version unknown but works in the same
2895 // version that also ignores addIceCandidate(null).
2896 if ((browserDetails.browser === "chrome" && browserDetails.version < 78 || browserDetails.browser === "firefox" && browserDetails.version < 68 || browserDetails.browser === "safari") && arguments[0] && arguments[0].candidate === "") return Promise.resolve();
2897 return nativeAddIceCandidate.apply(this, arguments);
2898 };
2899}
2900function $5151b78094cea2ba$export$7170d04e59f9d553(window, browserDetails) {
2901 if (!(window.RTCPeerConnection && window.RTCPeerConnection.prototype)) return;
2902 const nativeSetLocalDescription = window.RTCPeerConnection.prototype.setLocalDescription;
2903 if (!nativeSetLocalDescription || nativeSetLocalDescription.length === 0) return;
2904 window.RTCPeerConnection.prototype.setLocalDescription = function setLocalDescription() {
2905 let desc = arguments[0] || {};
2906 if (typeof desc !== "object" || desc.type && desc.sdp) return nativeSetLocalDescription.apply(this, arguments);
2907 // The remaining steps should technically happen when SLD comes off the
2908 // RTCPeerConnection's operations chain (not ahead of going on it), but
2909 // this is too difficult to shim. Instead, this shim only covers the
2910 // common case where the operations chain is empty. This is imperfect, but
2911 // should cover many cases. Rationale: Even if we can't reduce the glare
2912 // window to zero on imperfect implementations, there's value in tapping
2913 // into the perfect negotiation pattern that several browsers support.
2914 desc = {
2915 type: desc.type,
2916 sdp: desc.sdp
2917 };
2918 if (!desc.type) switch(this.signalingState){
2919 case "stable":
2920 case "have-local-offer":
2921 case "have-remote-pranswer":
2922 desc.type = "offer";
2923 break;
2924 default:
2925 desc.type = "answer";
2926 break;
2927 }
2928 if (desc.sdp || desc.type !== "offer" && desc.type !== "answer") return nativeSetLocalDescription.apply(this, [
2929 desc
2930 ]);
2931 const func = desc.type === "offer" ? this.createOffer : this.createAnswer;
2932 return func.apply(this).then((d)=>nativeSetLocalDescription.apply(this, [
2933 d
2934 ]));
2935 };
2936}
2937
2938
2939
2940function $b657217e95eb14d8$export$e77bf46c04ac7d12({ window: window } = {}, options = {
2941 shimChrome: true,
2942 shimFirefox: true,
2943 shimSafari: true
2944}) {
2945 // Utils.
2946 const logging = $9fea4db837311579$export$bef1f36f5486a6a3;
2947 const browserDetails = $9fea4db837311579$export$2d31490a0c05f094(window);
2948 const adapter = {
2949 browserDetails: browserDetails,
2950 commonShim: $5151b78094cea2ba$exports,
2951 extractVersion: $9fea4db837311579$export$e3c02be309be1f23,
2952 disableLog: $9fea4db837311579$export$afbfee8cc06fd3e4,
2953 disableWarnings: $9fea4db837311579$export$51516be4b019e41e,
2954 sdp: // Expose sdp as a convenience. For production apps include directly.
2955 $5d0e6002f6ec24ec$exports
2956 };
2957 // Shim browser if found.
2958 switch(browserDetails.browser){
2959 case "chrome":
2960 if (!$fb04e59b477f17ce$exports || !$fb04e59b477f17ce$exports.shimPeerConnection || !options.shimChrome) {
2961 logging("Chrome shim is not included in this adapter release.");
2962 return adapter;
2963 }
2964 if (browserDetails.version === null) {
2965 logging("Chrome shim can not determine version, not shimming.");
2966 return adapter;
2967 }
2968 logging("adapter.js shimming chrome.");
2969 // Export to the adapter global object visible in the browser.
2970 adapter.browserShim = $fb04e59b477f17ce$exports;
2971 // Must be called before shimPeerConnection.
2972 $5151b78094cea2ba$export$51d5e40b48c771c7(window, browserDetails);
2973 $5151b78094cea2ba$export$7170d04e59f9d553(window, browserDetails);
2974 $fb04e59b477f17ce$exports.shimGetUserMedia(window, browserDetails);
2975 $fb04e59b477f17ce$exports.shimMediaStream(window, browserDetails);
2976 $fb04e59b477f17ce$exports.shimPeerConnection(window, browserDetails);
2977 $fb04e59b477f17ce$exports.shimOnTrack(window, browserDetails);
2978 $fb04e59b477f17ce$exports.shimAddTrackRemoveTrack(window, browserDetails);
2979 $fb04e59b477f17ce$exports.shimGetSendersWithDtmf(window, browserDetails);
2980 $fb04e59b477f17ce$exports.shimGetStats(window, browserDetails);
2981 $fb04e59b477f17ce$exports.shimSenderReceiverGetStats(window, browserDetails);
2982 $fb04e59b477f17ce$exports.fixNegotiationNeeded(window, browserDetails);
2983 $5151b78094cea2ba$export$cf133661e444ccfe(window, browserDetails);
2984 $5151b78094cea2ba$export$fdafb8d8280e29b5(window, browserDetails);
2985 $5151b78094cea2ba$export$63bb816cc75460(window, browserDetails);
2986 $5151b78094cea2ba$export$a99147c78a56edc4(window, browserDetails);
2987 $5151b78094cea2ba$export$d461c8d5c5db5da7(window, browserDetails);
2988 $5151b78094cea2ba$export$a57d114344295149(window, browserDetails);
2989 break;
2990 case "firefox":
2991 if (!$215e6581d7a09c61$exports || !$215e6581d7a09c61$exports.shimPeerConnection || !options.shimFirefox) {
2992 logging("Firefox shim is not included in this adapter release.");
2993 return adapter;
2994 }
2995 logging("adapter.js shimming firefox.");
2996 // Export to the adapter global object visible in the browser.
2997 adapter.browserShim = $215e6581d7a09c61$exports;
2998 // Must be called before shimPeerConnection.
2999 $5151b78094cea2ba$export$51d5e40b48c771c7(window, browserDetails);
3000 $5151b78094cea2ba$export$7170d04e59f9d553(window, browserDetails);
3001 $215e6581d7a09c61$exports.shimGetUserMedia(window, browserDetails);
3002 $215e6581d7a09c61$exports.shimPeerConnection(window, browserDetails);
3003 $215e6581d7a09c61$exports.shimOnTrack(window, browserDetails);
3004 $215e6581d7a09c61$exports.shimRemoveStream(window, browserDetails);
3005 $215e6581d7a09c61$exports.shimSenderGetStats(window, browserDetails);
3006 $215e6581d7a09c61$exports.shimReceiverGetStats(window, browserDetails);
3007 $215e6581d7a09c61$exports.shimRTCDataChannel(window, browserDetails);
3008 $215e6581d7a09c61$exports.shimAddTransceiver(window, browserDetails);
3009 $215e6581d7a09c61$exports.shimGetParameters(window, browserDetails);
3010 $215e6581d7a09c61$exports.shimCreateOffer(window, browserDetails);
3011 $215e6581d7a09c61$exports.shimCreateAnswer(window, browserDetails);
3012 $5151b78094cea2ba$export$cf133661e444ccfe(window, browserDetails);
3013 $5151b78094cea2ba$export$63bb816cc75460(window, browserDetails);
3014 $5151b78094cea2ba$export$a99147c78a56edc4(window, browserDetails);
3015 $5151b78094cea2ba$export$d461c8d5c5db5da7(window, browserDetails);
3016 break;
3017 case "safari":
3018 if (!$c1f641ee5a6f6c8f$exports || !options.shimSafari) {
3019 logging("Safari shim is not included in this adapter release.");
3020 return adapter;
3021 }
3022 logging("adapter.js shimming safari.");
3023 // Export to the adapter global object visible in the browser.
3024 adapter.browserShim = $c1f641ee5a6f6c8f$exports;
3025 // Must be called before shimCallbackAPI.
3026 $5151b78094cea2ba$export$51d5e40b48c771c7(window, browserDetails);
3027 $5151b78094cea2ba$export$7170d04e59f9d553(window, browserDetails);
3028 $c1f641ee5a6f6c8f$exports.shimRTCIceServerUrls(window, browserDetails);
3029 $c1f641ee5a6f6c8f$exports.shimCreateOfferLegacy(window, browserDetails);
3030 $c1f641ee5a6f6c8f$exports.shimCallbacksAPI(window, browserDetails);
3031 $c1f641ee5a6f6c8f$exports.shimLocalStreamsAPI(window, browserDetails);
3032 $c1f641ee5a6f6c8f$exports.shimRemoteStreamsAPI(window, browserDetails);
3033 $c1f641ee5a6f6c8f$exports.shimTrackEventTransceiver(window, browserDetails);
3034 $c1f641ee5a6f6c8f$exports.shimGetUserMedia(window, browserDetails);
3035 $c1f641ee5a6f6c8f$exports.shimAudioContext(window, browserDetails);
3036 $5151b78094cea2ba$export$cf133661e444ccfe(window, browserDetails);
3037 $5151b78094cea2ba$export$fdafb8d8280e29b5(window, browserDetails);
3038 $5151b78094cea2ba$export$a99147c78a56edc4(window, browserDetails);
3039 $5151b78094cea2ba$export$d461c8d5c5db5da7(window, browserDetails);
3040 $5151b78094cea2ba$export$a57d114344295149(window, browserDetails);
3041 break;
3042 default:
3043 logging("Unsupported browser!");
3044 break;
3045 }
3046 return adapter;
3047}
3048
3049
3050"use strict";
3051const $90c50c10bd6fa8b4$var$adapter = (0, $b657217e95eb14d8$export$e77bf46c04ac7d12)({
3052 window: typeof window === "undefined" ? undefined : window
3053});
3054var $90c50c10bd6fa8b4$export$2e2bcd8739ae039 = $90c50c10bd6fa8b4$var$adapter;
3055
3056
3057const $a9bc9397a7d36afa$var$webRTCAdapter = //@ts-ignore
3058(0, $90c50c10bd6fa8b4$export$2e2bcd8739ae039).default || (0, $90c50c10bd6fa8b4$export$2e2bcd8739ae039);
3059const $a9bc9397a7d36afa$export$25be9502477c137d = new class {
3060 isWebRTCSupported() {
3061 return typeof RTCPeerConnection !== "undefined";
3062 }
3063 isBrowserSupported() {
3064 const browser = this.getBrowser();
3065 const version = this.getVersion();
3066 const validBrowser = this.supportedBrowsers.includes(browser);
3067 if (!validBrowser) return false;
3068 if (browser === "chrome") return version >= this.minChromeVersion;
3069 if (browser === "firefox") return version >= this.minFirefoxVersion;
3070 if (browser === "safari") return !this.isIOS && version >= this.minSafariVersion;
3071 return false;
3072 }
3073 getBrowser() {
3074 return $a9bc9397a7d36afa$var$webRTCAdapter.browserDetails.browser;
3075 }
3076 getVersion() {
3077 return $a9bc9397a7d36afa$var$webRTCAdapter.browserDetails.version || 0;
3078 }
3079 isUnifiedPlanSupported() {
3080 const browser = this.getBrowser();
3081 const version = $a9bc9397a7d36afa$var$webRTCAdapter.browserDetails.version || 0;
3082 if (browser === "chrome" && version < this.minChromeVersion) return false;
3083 if (browser === "firefox" && version >= this.minFirefoxVersion) return true;
3084 if (!window.RTCRtpTransceiver || !("currentDirection" in RTCRtpTransceiver.prototype)) return false;
3085 let tempPc;
3086 let supported = false;
3087 try {
3088 tempPc = new RTCPeerConnection();
3089 tempPc.addTransceiver("audio");
3090 supported = true;
3091 } catch (e) {} finally{
3092 if (tempPc) tempPc.close();
3093 }
3094 return supported;
3095 }
3096 toString() {
3097 return `Supports:
3098 browser:${this.getBrowser()}
3099 version:${this.getVersion()}
3100 isIOS:${this.isIOS}
3101 isWebRTCSupported:${this.isWebRTCSupported()}
3102 isBrowserSupported:${this.isBrowserSupported()}
3103 isUnifiedPlanSupported:${this.isUnifiedPlanSupported()}`;
3104 }
3105 constructor(){
3106 this.isIOS = [
3107 "iPad",
3108 "iPhone",
3109 "iPod"
3110 ].includes(navigator.platform);
3111 this.supportedBrowsers = [
3112 "firefox",
3113 "chrome",
3114 "safari"
3115 ];
3116 this.minFirefoxVersion = 59;
3117 this.minChromeVersion = 72;
3118 this.minSafariVersion = 605;
3119 }
3120}();
3121
3122
3123const $fce54fbdd74b2319$export$f35f128fd59ea256 = (id)=>{
3124 // Allow empty ids
3125 return !id || /^[A-Za-z0-9]+(?:[ _-][A-Za-z0-9]+)*$/.test(id);
3126};
3127
3128
3129const $008766fe99f03c2f$export$4e61f672936bec77 = ()=>Math.random().toString(36).slice(2);
3130
3131
3132const $01f0d223090cb1f8$var$DEFAULT_CONFIG = {
3133 iceServers: [
3134 {
3135 urls: "stun:stun.l.google.com:19302"
3136 },
3137 {
3138 urls: [
3139 "turn:eu-0.turn.peerjs.com:3478",
3140 "turn:us-0.turn.peerjs.com:3478"
3141 ],
3142 username: "peerjs",
3143 credential: "peerjsp"
3144 }
3145 ],
3146 sdpSemantics: "unified-plan"
3147};
3148class $01f0d223090cb1f8$export$f8f26dd395d7e1bd extends (0, $616ebdf1c4998439$export$f1c5f4c9cb95390b) {
3149 noop() {}
3150 blobToArrayBuffer(blob, cb) {
3151 const fr = new FileReader();
3152 fr.onload = function(evt) {
3153 if (evt.target) cb(evt.target.result);
3154 };
3155 fr.readAsArrayBuffer(blob);
3156 return fr;
3157 }
3158 binaryStringToArrayBuffer(binary) {
3159 const byteArray = new Uint8Array(binary.length);
3160 for(let i = 0; i < binary.length; i++)byteArray[i] = binary.charCodeAt(i) & 0xff;
3161 return byteArray.buffer;
3162 }
3163 isSecure() {
3164 return location.protocol === "https:";
3165 }
3166 constructor(...args){
3167 super(...args);
3168 this.CLOUD_HOST = "0.peerjs.com";
3169 this.CLOUD_PORT = 443;
3170 // Browsers that need chunking:
3171 this.chunkedBrowsers = {
3172 Chrome: 1,
3173 chrome: 1
3174 };
3175 // Returns browser-agnostic default config
3176 this.defaultConfig = $01f0d223090cb1f8$var$DEFAULT_CONFIG;
3177 this.browser = (0, $a9bc9397a7d36afa$export$25be9502477c137d).getBrowser();
3178 this.browserVersion = (0, $a9bc9397a7d36afa$export$25be9502477c137d).getVersion();
3179 this.pack = $bf7fb46c6d68ead7$export$2a703dbb0cb35339;
3180 this.unpack = $bf7fb46c6d68ead7$export$417857010dc9287f;
3181 /**
3182 * A hash of WebRTC features mapped to booleans that correspond to whether the feature is supported by the current browser.
3183 *
3184 * :::caution
3185 * Only the properties documented here are guaranteed to be present on `util.supports`
3186 * :::
3187 */ this.supports = function() {
3188 const supported = {
3189 browser: (0, $a9bc9397a7d36afa$export$25be9502477c137d).isBrowserSupported(),
3190 webRTC: (0, $a9bc9397a7d36afa$export$25be9502477c137d).isWebRTCSupported(),
3191 audioVideo: false,
3192 data: false,
3193 binaryBlob: false,
3194 reliable: false
3195 };
3196 if (!supported.webRTC) return supported;
3197 let pc;
3198 try {
3199 pc = new RTCPeerConnection($01f0d223090cb1f8$var$DEFAULT_CONFIG);
3200 supported.audioVideo = true;
3201 let dc;
3202 try {
3203 dc = pc.createDataChannel("_PEERJSTEST", {
3204 ordered: true
3205 });
3206 supported.data = true;
3207 supported.reliable = !!dc.ordered;
3208 // Binary test
3209 try {
3210 dc.binaryType = "blob";
3211 supported.binaryBlob = !(0, $a9bc9397a7d36afa$export$25be9502477c137d).isIOS;
3212 } catch (e) {}
3213 } catch (e) {} finally{
3214 if (dc) dc.close();
3215 }
3216 } catch (e) {} finally{
3217 if (pc) pc.close();
3218 }
3219 return supported;
3220 }();
3221 // Ensure alphanumeric ids
3222 this.validateId = (0, $fce54fbdd74b2319$export$f35f128fd59ea256);
3223 this.randomToken = (0, $008766fe99f03c2f$export$4e61f672936bec77);
3224 }
3225}
3226const $01f0d223090cb1f8$export$7debb50ef11d5e0b = new $01f0d223090cb1f8$export$f8f26dd395d7e1bd();
3227
3228
3229
3230const $d3fc3aacca52312c$var$LOG_PREFIX = "PeerJS: ";
3231var $d3fc3aacca52312c$export$243e62d78d3b544d;
3232(function(LogLevel) {
3233 /**
3234 * Prints no logs.
3235 */ LogLevel[LogLevel["Disabled"] = 0] = "Disabled";
3236 /**
3237 * Prints only errors.
3238 */ LogLevel[LogLevel["Errors"] = 1] = "Errors";
3239 /**
3240 * Prints errors and warnings.
3241 */ LogLevel[LogLevel["Warnings"] = 2] = "Warnings";
3242 /**
3243 * Prints all logs.
3244 */ LogLevel[LogLevel["All"] = 3] = "All";
3245})($d3fc3aacca52312c$export$243e62d78d3b544d || ($d3fc3aacca52312c$export$243e62d78d3b544d = {}));
3246class $d3fc3aacca52312c$var$Logger {
3247 get logLevel() {
3248 return this._logLevel;
3249 }
3250 set logLevel(logLevel) {
3251 this._logLevel = logLevel;
3252 }
3253 log(...args) {
3254 if (this._logLevel >= 3) this._print(3, ...args);
3255 }
3256 warn(...args) {
3257 if (this._logLevel >= 2) this._print(2, ...args);
3258 }
3259 error(...args) {
3260 if (this._logLevel >= 1) this._print(1, ...args);
3261 }
3262 setLogFunction(fn) {
3263 this._print = fn;
3264 }
3265 _print(logLevel, ...rest) {
3266 const copy = [
3267 $d3fc3aacca52312c$var$LOG_PREFIX,
3268 ...rest
3269 ];
3270 for(const i in copy)if (copy[i] instanceof Error) copy[i] = "(" + copy[i].name + ") " + copy[i].message;
3271 if (logLevel >= 3) console.log(...copy);
3272 else if (logLevel >= 2) console.warn("WARNING", ...copy);
3273 else if (logLevel >= 1) console.error("ERROR", ...copy);
3274 }
3275 constructor(){
3276 this._logLevel = 0;
3277 }
3278}
3279var $d3fc3aacca52312c$export$2e2bcd8739ae039 = new $d3fc3aacca52312c$var$Logger();
3280
3281
3282var $f5d7fbd88de797fd$exports = {};
3283"use strict";
3284var $f5d7fbd88de797fd$var$has = Object.prototype.hasOwnProperty, $f5d7fbd88de797fd$var$prefix = "~";
3285/**
3286 * Constructor to create a storage for our `EE` objects.
3287 * An `Events` instance is a plain object whose properties are event names.
3288 *
3289 * @constructor
3290 * @private
3291 */ function $f5d7fbd88de797fd$var$Events() {}
3292//
3293// We try to not inherit from `Object.prototype`. In some engines creating an
3294// instance in this way is faster than calling `Object.create(null)` directly.
3295// If `Object.create(null)` is not supported we prefix the event names with a
3296// character to make sure that the built-in object properties are not
3297// overridden or used as an attack vector.
3298//
3299if (Object.create) {
3300 $f5d7fbd88de797fd$var$Events.prototype = Object.create(null);
3301 //
3302 // This hack is needed because the `__proto__` property is still inherited in
3303 // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
3304 //
3305 if (!new $f5d7fbd88de797fd$var$Events().__proto__) $f5d7fbd88de797fd$var$prefix = false;
3306}
3307/**
3308 * Representation of a single event listener.
3309 *
3310 * @param {Function} fn The listener function.
3311 * @param {*} context The context to invoke the listener with.
3312 * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
3313 * @constructor
3314 * @private
3315 */ function $f5d7fbd88de797fd$var$EE(fn, context, once) {
3316 this.fn = fn;
3317 this.context = context;
3318 this.once = once || false;
3319}
3320/**
3321 * Add a listener for a given event.
3322 *
3323 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
3324 * @param {(String|Symbol)} event The event name.
3325 * @param {Function} fn The listener function.
3326 * @param {*} context The context to invoke the listener with.
3327 * @param {Boolean} once Specify if the listener is a one-time listener.
3328 * @returns {EventEmitter}
3329 * @private
3330 */ function $f5d7fbd88de797fd$var$addListener(emitter, event, fn, context, once) {
3331 if (typeof fn !== "function") throw new TypeError("The listener must be a function");
3332 var listener = new $f5d7fbd88de797fd$var$EE(fn, context || emitter, once), evt = $f5d7fbd88de797fd$var$prefix ? $f5d7fbd88de797fd$var$prefix + event : event;
3333 if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
3334 else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
3335 else emitter._events[evt] = [
3336 emitter._events[evt],
3337 listener
3338 ];
3339 return emitter;
3340}
3341/**
3342 * Clear event by name.
3343 *
3344 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
3345 * @param {(String|Symbol)} evt The Event name.
3346 * @private
3347 */ function $f5d7fbd88de797fd$var$clearEvent(emitter, evt) {
3348 if (--emitter._eventsCount === 0) emitter._events = new $f5d7fbd88de797fd$var$Events();
3349 else delete emitter._events[evt];
3350}
3351/**
3352 * Minimal `EventEmitter` interface that is molded against the Node.js
3353 * `EventEmitter` interface.
3354 *
3355 * @constructor
3356 * @public
3357 */ function $f5d7fbd88de797fd$var$EventEmitter() {
3358 this._events = new $f5d7fbd88de797fd$var$Events();
3359 this._eventsCount = 0;
3360}
3361/**
3362 * Return an array listing the events for which the emitter has registered
3363 * listeners.
3364 *
3365 * @returns {Array}
3366 * @public
3367 */ $f5d7fbd88de797fd$var$EventEmitter.prototype.eventNames = function eventNames() {
3368 var names = [], events, name;
3369 if (this._eventsCount === 0) return names;
3370 for(name in events = this._events)if ($f5d7fbd88de797fd$var$has.call(events, name)) names.push($f5d7fbd88de797fd$var$prefix ? name.slice(1) : name);
3371 if (Object.getOwnPropertySymbols) return names.concat(Object.getOwnPropertySymbols(events));
3372 return names;
3373};
3374/**
3375 * Return the listeners registered for a given event.
3376 *
3377 * @param {(String|Symbol)} event The event name.
3378 * @returns {Array} The registered listeners.
3379 * @public
3380 */ $f5d7fbd88de797fd$var$EventEmitter.prototype.listeners = function listeners(event) {
3381 var evt = $f5d7fbd88de797fd$var$prefix ? $f5d7fbd88de797fd$var$prefix + event : event, handlers = this._events[evt];
3382 if (!handlers) return [];
3383 if (handlers.fn) return [
3384 handlers.fn
3385 ];
3386 for(var i = 0, l = handlers.length, ee = new Array(l); i < l; i++)ee[i] = handlers[i].fn;
3387 return ee;
3388};
3389/**
3390 * Return the number of listeners listening to a given event.
3391 *
3392 * @param {(String|Symbol)} event The event name.
3393 * @returns {Number} The number of listeners.
3394 * @public
3395 */ $f5d7fbd88de797fd$var$EventEmitter.prototype.listenerCount = function listenerCount(event) {
3396 var evt = $f5d7fbd88de797fd$var$prefix ? $f5d7fbd88de797fd$var$prefix + event : event, listeners = this._events[evt];
3397 if (!listeners) return 0;
3398 if (listeners.fn) return 1;
3399 return listeners.length;
3400};
3401/**
3402 * Calls each of the listeners registered for a given event.
3403 *
3404 * @param {(String|Symbol)} event The event name.
3405 * @returns {Boolean} `true` if the event had listeners, else `false`.
3406 * @public
3407 */ $f5d7fbd88de797fd$var$EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
3408 var evt = $f5d7fbd88de797fd$var$prefix ? $f5d7fbd88de797fd$var$prefix + event : event;
3409 if (!this._events[evt]) return false;
3410 var listeners = this._events[evt], len = arguments.length, args, i;
3411 if (listeners.fn) {
3412 if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
3413 switch(len){
3414 case 1:
3415 return listeners.fn.call(listeners.context), true;
3416 case 2:
3417 return listeners.fn.call(listeners.context, a1), true;
3418 case 3:
3419 return listeners.fn.call(listeners.context, a1, a2), true;
3420 case 4:
3421 return listeners.fn.call(listeners.context, a1, a2, a3), true;
3422 case 5:
3423 return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
3424 case 6:
3425 return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
3426 }
3427 for(i = 1, args = new Array(len - 1); i < len; i++)args[i - 1] = arguments[i];
3428 listeners.fn.apply(listeners.context, args);
3429 } else {
3430 var length = listeners.length, j;
3431 for(i = 0; i < length; i++){
3432 if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
3433 switch(len){
3434 case 1:
3435 listeners[i].fn.call(listeners[i].context);
3436 break;
3437 case 2:
3438 listeners[i].fn.call(listeners[i].context, a1);
3439 break;
3440 case 3:
3441 listeners[i].fn.call(listeners[i].context, a1, a2);
3442 break;
3443 case 4:
3444 listeners[i].fn.call(listeners[i].context, a1, a2, a3);
3445 break;
3446 default:
3447 if (!args) for(j = 1, args = new Array(len - 1); j < len; j++)args[j - 1] = arguments[j];
3448 listeners[i].fn.apply(listeners[i].context, args);
3449 }
3450 }
3451 }
3452 return true;
3453};
3454/**
3455 * Add a listener for a given event.
3456 *
3457 * @param {(String|Symbol)} event The event name.
3458 * @param {Function} fn The listener function.
3459 * @param {*} [context=this] The context to invoke the listener with.
3460 * @returns {EventEmitter} `this`.
3461 * @public
3462 */ $f5d7fbd88de797fd$var$EventEmitter.prototype.on = function on(event, fn, context) {
3463 return $f5d7fbd88de797fd$var$addListener(this, event, fn, context, false);
3464};
3465/**
3466 * Add a one-time listener for a given event.
3467 *
3468 * @param {(String|Symbol)} event The event name.
3469 * @param {Function} fn The listener function.
3470 * @param {*} [context=this] The context to invoke the listener with.
3471 * @returns {EventEmitter} `this`.
3472 * @public
3473 */ $f5d7fbd88de797fd$var$EventEmitter.prototype.once = function once(event, fn, context) {
3474 return $f5d7fbd88de797fd$var$addListener(this, event, fn, context, true);
3475};
3476/**
3477 * Remove the listeners of a given event.
3478 *
3479 * @param {(String|Symbol)} event The event name.
3480 * @param {Function} fn Only remove the listeners that match this function.
3481 * @param {*} context Only remove the listeners that have this context.
3482 * @param {Boolean} once Only remove one-time listeners.
3483 * @returns {EventEmitter} `this`.
3484 * @public
3485 */ $f5d7fbd88de797fd$var$EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
3486 var evt = $f5d7fbd88de797fd$var$prefix ? $f5d7fbd88de797fd$var$prefix + event : event;
3487 if (!this._events[evt]) return this;
3488 if (!fn) {
3489 $f5d7fbd88de797fd$var$clearEvent(this, evt);
3490 return this;
3491 }
3492 var listeners = this._events[evt];
3493 if (listeners.fn) {
3494 if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) $f5d7fbd88de797fd$var$clearEvent(this, evt);
3495 } else {
3496 for(var i = 0, events = [], length = listeners.length; i < length; i++)if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) events.push(listeners[i]);
3497 //
3498 // Reset the array, or remove it completely if we have no more listeners.
3499 //
3500 if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
3501 else $f5d7fbd88de797fd$var$clearEvent(this, evt);
3502 }
3503 return this;
3504};
3505/**
3506 * Remove all listeners, or those of the specified event.
3507 *
3508 * @param {(String|Symbol)} [event] The event name.
3509 * @returns {EventEmitter} `this`.
3510 * @public
3511 */ $f5d7fbd88de797fd$var$EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
3512 var evt;
3513 if (event) {
3514 evt = $f5d7fbd88de797fd$var$prefix ? $f5d7fbd88de797fd$var$prefix + event : event;
3515 if (this._events[evt]) $f5d7fbd88de797fd$var$clearEvent(this, evt);
3516 } else {
3517 this._events = new $f5d7fbd88de797fd$var$Events();
3518 this._eventsCount = 0;
3519 }
3520 return this;
3521};
3522//
3523// Alias methods names because people roll like that.
3524//
3525$f5d7fbd88de797fd$var$EventEmitter.prototype.off = $f5d7fbd88de797fd$var$EventEmitter.prototype.removeListener;
3526$f5d7fbd88de797fd$var$EventEmitter.prototype.addListener = $f5d7fbd88de797fd$var$EventEmitter.prototype.on;
3527//
3528// Expose the prefix.
3529//
3530$f5d7fbd88de797fd$var$EventEmitter.prefixed = $f5d7fbd88de797fd$var$prefix;
3531//
3532// Allow `EventEmitter` to be imported as module namespace.
3533//
3534$f5d7fbd88de797fd$var$EventEmitter.EventEmitter = $f5d7fbd88de797fd$var$EventEmitter;
3535$f5d7fbd88de797fd$exports = $f5d7fbd88de797fd$var$EventEmitter;
3536
3537
3538
3539var $edbcf3072a01d580$export$3157d57b4135e3bc;
3540(function(ConnectionType) {
3541 ConnectionType["Data"] = "data";
3542 ConnectionType["Media"] = "media";
3543})($edbcf3072a01d580$export$3157d57b4135e3bc || ($edbcf3072a01d580$export$3157d57b4135e3bc = {}));
3544var $edbcf3072a01d580$export$9547aaa2e39030ff;
3545(function(PeerErrorType) {
3546 /**
3547 * The client's browser does not support some or all WebRTC features that you are trying to use.
3548 */ PeerErrorType["BrowserIncompatible"] = "browser-incompatible";
3549 /**
3550 * You've already disconnected this peer from the server and can no longer make any new connections on it.
3551 */ PeerErrorType["Disconnected"] = "disconnected";
3552 /**
3553 * The ID passed into the Peer constructor contains illegal characters.
3554 */ PeerErrorType["InvalidID"] = "invalid-id";
3555 /**
3556 * The API key passed into the Peer constructor contains illegal characters or is not in the system (cloud server only).
3557 */ PeerErrorType["InvalidKey"] = "invalid-key";
3558 /**
3559 * Lost or cannot establish a connection to the signalling server.
3560 */ PeerErrorType["Network"] = "network";
3561 /**
3562 * The peer you're trying to connect to does not exist.
3563 */ PeerErrorType["PeerUnavailable"] = "peer-unavailable";
3564 /**
3565 * PeerJS is being used securely, but the cloud server does not support SSL. Use a custom PeerServer.
3566 */ PeerErrorType["SslUnavailable"] = "ssl-unavailable";
3567 /**
3568 * Unable to reach the server.
3569 */ PeerErrorType["ServerError"] = "server-error";
3570 /**
3571 * An error from the underlying socket.
3572 */ PeerErrorType["SocketError"] = "socket-error";
3573 /**
3574 * The underlying socket closed unexpectedly.
3575 */ PeerErrorType["SocketClosed"] = "socket-closed";
3576 /**
3577 * The ID passed into the Peer constructor is already taken.
3578 *
3579 * :::caution
3580 * This error is not fatal if your peer has open peer-to-peer connections.
3581 * This can happen if you attempt to {@apilink Peer.reconnect} a peer that has been disconnected from the server,
3582 * but its old ID has now been taken.
3583 * :::
3584 */ PeerErrorType["UnavailableID"] = "unavailable-id";
3585 /**
3586 * Native WebRTC errors.
3587 */ PeerErrorType["WebRTC"] = "webrtc";
3588})($edbcf3072a01d580$export$9547aaa2e39030ff || ($edbcf3072a01d580$export$9547aaa2e39030ff = {}));
3589var $edbcf3072a01d580$export$7974935686149686;
3590(function(BaseConnectionErrorType) {
3591 BaseConnectionErrorType["NegotiationFailed"] = "negotiation-failed";
3592 BaseConnectionErrorType["ConnectionClosed"] = "connection-closed";
3593})($edbcf3072a01d580$export$7974935686149686 || ($edbcf3072a01d580$export$7974935686149686 = {}));
3594var $edbcf3072a01d580$export$49ae800c114df41d;
3595(function(DataConnectionErrorType) {
3596 DataConnectionErrorType["NotOpenYet"] = "not-open-yet";
3597 DataConnectionErrorType["MessageToBig"] = "message-too-big";
3598})($edbcf3072a01d580$export$49ae800c114df41d || ($edbcf3072a01d580$export$49ae800c114df41d = {}));
3599var $edbcf3072a01d580$export$89f507cf986a947;
3600(function(SerializationType) {
3601 SerializationType["Binary"] = "binary";
3602 SerializationType["BinaryUTF8"] = "binary-utf8";
3603 SerializationType["JSON"] = "json";
3604 SerializationType["None"] = "raw";
3605})($edbcf3072a01d580$export$89f507cf986a947 || ($edbcf3072a01d580$export$89f507cf986a947 = {}));
3606var $edbcf3072a01d580$export$3b5c4a4b6354f023;
3607(function(SocketEventType) {
3608 SocketEventType["Message"] = "message";
3609 SocketEventType["Disconnected"] = "disconnected";
3610 SocketEventType["Error"] = "error";
3611 SocketEventType["Close"] = "close";
3612})($edbcf3072a01d580$export$3b5c4a4b6354f023 || ($edbcf3072a01d580$export$3b5c4a4b6354f023 = {}));
3613var $edbcf3072a01d580$export$adb4a1754da6f10d;
3614(function(ServerMessageType) {
3615 ServerMessageType["Heartbeat"] = "HEARTBEAT";
3616 ServerMessageType["Candidate"] = "CANDIDATE";
3617 ServerMessageType["Offer"] = "OFFER";
3618 ServerMessageType["Answer"] = "ANSWER";
3619 ServerMessageType["Open"] = "OPEN";
3620 ServerMessageType["Error"] = "ERROR";
3621 ServerMessageType["IdTaken"] = "ID-TAKEN";
3622 ServerMessageType["InvalidKey"] = "INVALID-KEY";
3623 ServerMessageType["Leave"] = "LEAVE";
3624 ServerMessageType["Expire"] = "EXPIRE";
3625})($edbcf3072a01d580$export$adb4a1754da6f10d || ($edbcf3072a01d580$export$adb4a1754da6f10d = {}));
3626
3627
3628var $580fed67ed3c559d$exports = {};
3629$580fed67ed3c559d$exports = JSON.parse('{"name":"peerjs","version":"1.5.2","keywords":["peerjs","webrtc","p2p","rtc"],"description":"PeerJS client","homepage":"https://peerjs.com","bugs":{"url":"https://github.com/peers/peerjs/issues"},"repository":{"type":"git","url":"https://github.com/peers/peerjs"},"license":"MIT","contributors":["Michelle Bu <michelle@michellebu.com>","afrokick <devbyru@gmail.com>","ericz <really.ez@gmail.com>","Jairo <kidandcat@gmail.com>","Jonas Gloning <34194370+jonasgloning@users.noreply.github.com>","Jairo Caro-Accino Viciana <jairo@galax.be>","Carlos Caballero <carlos.caballero.gonzalez@gmail.com>","hc <hheennrryy@gmail.com>","Muhammad Asif <capripio@gmail.com>","PrashoonB <prashoonbhattacharjee@gmail.com>","Harsh Bardhan Mishra <47351025+HarshCasper@users.noreply.github.com>","akotynski <aleksanderkotbury@gmail.com>","lmb <i@lmb.io>","Jairooo <jairocaro@msn.com>","Moritz St\xfcckler <moritz.stueckler@gmail.com>","Simon <crydotsnakegithub@gmail.com>","Denis Lukov <denismassters@gmail.com>","Philipp Hancke <fippo@andyet.net>","Hans Oksendahl <hansoksendahl@gmail.com>","Jess <jessachandler@gmail.com>","khankuan <khankuan@gmail.com>","DUODVK <kurmanov.work@gmail.com>","XiZhao <kwang1imsa@gmail.com>","Matthias Lohr <matthias@lohr.me>","=frank tree <=frnktrb@googlemail.com>","Andre Eckardt <aeckardt@outlook.com>","Chris Cowan <agentme49@gmail.com>","Alex Chuev <alex@chuev.com>","alxnull <alxnull@e.mail.de>","Yemel Jardi <angel.jardi@gmail.com>","Ben Parnell <benjaminparnell.94@gmail.com>","Benny Lichtner <bennlich@gmail.com>","fresheneesz <bitetrudpublic@gmail.com>","bob.barstead@exaptive.com <bob.barstead@exaptive.com>","chandika <chandika@gmail.com>","emersion <contact@emersion.fr>","Christopher Van <cvan@users.noreply.github.com>","eddieherm <edhermoso@gmail.com>","Eduardo Pinho <enet4mikeenet@gmail.com>","Evandro Zanatta <ezanatta@tray.net.br>","Gardner Bickford <gardner@users.noreply.github.com>","Gian Luca <gianluca.cecchi@cynny.com>","PatrickJS <github@gdi2290.com>","jonnyf <github@jonathanfoss.co.uk>","Hizkia Felix <hizkifw@gmail.com>","Hristo Oskov <hristo.oskov@gmail.com>","Isaac Madwed <i.madwed@gmail.com>","Ilya Konanykhin <ilya.konanykhin@gmail.com>","jasonbarry <jasbarry@me.com>","Jonathan Burke <jonathan.burke.1311@googlemail.com>","Josh Hamit <josh.hamit@gmail.com>","Jordan Austin <jrax86@gmail.com>","Joel Wetzell <jwetzell@yahoo.com>","xizhao <kevin.wang@cloudera.com>","Alberto Torres <kungfoobar@gmail.com>","Jonathan Mayol <mayoljonathan@gmail.com>","Jefferson Felix <me@jsfelix.dev>","Rolf Erik Lekang <me@rolflekang.com>","Kevin Mai-Husan Chia <mhchia@users.noreply.github.com>","Pepijn de Vos <pepijndevos@gmail.com>","JooYoung <qkdlql@naver.com>","Tobias Speicher <rootcommander@gmail.com>","Steve Blaurock <sblaurock@gmail.com>","Kyrylo Shegeda <shegeda@ualberta.ca>","Diwank Singh Tomer <singh@diwank.name>","So\u0308ren Balko <Soeren.Balko@gmail.com>","Arpit Solanki <solankiarpit1997@gmail.com>","Yuki Ito <yuki@gnnk.net>","Artur Zayats <zag2art@gmail.com>"],"funding":{"type":"opencollective","url":"https://opencollective.com/peer"},"collective":{"type":"opencollective","url":"https://opencollective.com/peer"},"files":["dist/*"],"sideEffects":["lib/global.ts","lib/supports.ts"],"main":"dist/bundler.cjs","module":"dist/bundler.mjs","browser-minified":"dist/peerjs.min.js","browser-unminified":"dist/peerjs.js","browser-minified-cbor":"dist/serializer.cbor.mjs","browser-minified-msgpack":"dist/serializer.msgpack.mjs","types":"dist/types.d.ts","engines":{"node":">= 14"},"targets":{"types":{"source":"lib/exports.ts"},"main":{"source":"lib/exports.ts","sourceMap":{"inlineSources":true}},"module":{"source":"lib/exports.ts","includeNodeModules":["eventemitter3"],"sourceMap":{"inlineSources":true}},"browser-minified":{"context":"browser","outputFormat":"global","optimize":true,"engines":{"browsers":"chrome >= 83, edge >= 83, firefox >= 80, safari >= 15"},"source":"lib/global.ts"},"browser-unminified":{"context":"browser","outputFormat":"global","optimize":false,"engines":{"browsers":"chrome >= 83, edge >= 83, firefox >= 80, safari >= 15"},"source":"lib/global.ts"},"browser-minified-cbor":{"context":"browser","outputFormat":"esmodule","isLibrary":true,"optimize":true,"engines":{"browsers":"chrome >= 83, edge >= 83, firefox >= 102, safari >= 15"},"source":"lib/dataconnection/StreamConnection/Cbor.ts"},"browser-minified-msgpack":{"context":"browser","outputFormat":"esmodule","isLibrary":true,"optimize":true,"engines":{"browsers":"chrome >= 83, edge >= 83, firefox >= 102, safari >= 15"},"source":"lib/dataconnection/StreamConnection/MsgPack.ts"}},"scripts":{"contributors":"git-authors-cli --print=false && prettier --write package.json && git add package.json package-lock.json && git commit -m \\"chore(contributors): update and sort contributors list\\"","check":"tsc --noEmit && tsc -p e2e/tsconfig.json --noEmit","watch":"parcel watch","build":"rm -rf dist && parcel build","prepublishOnly":"npm run build","test":"jest","test:watch":"jest --watch","coverage":"jest --coverage --collectCoverageFrom=\\"./lib/**\\"","format":"prettier --write .","format:check":"prettier --check .","semantic-release":"semantic-release","e2e":"wdio run e2e/wdio.local.conf.ts","e2e:bstack":"wdio run e2e/wdio.bstack.conf.ts"},"devDependencies":{"@parcel/config-default":"^2.9.3","@parcel/packager-ts":"^2.9.3","@parcel/transformer-typescript-tsc":"^2.9.3","@parcel/transformer-typescript-types":"^2.9.3","@semantic-release/changelog":"^6.0.1","@semantic-release/git":"^10.0.1","@swc/core":"^1.3.27","@swc/jest":"^0.2.24","@types/jasmine":"^4.3.4","@wdio/browserstack-service":"^8.11.2","@wdio/cli":"^8.11.2","@wdio/globals":"^8.11.2","@wdio/jasmine-framework":"^8.11.2","@wdio/local-runner":"^8.11.2","@wdio/spec-reporter":"^8.11.2","@wdio/types":"^8.10.4","http-server":"^14.1.1","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","mock-socket":"^9.0.0","parcel":"^2.9.3","prettier":"^3.0.0","semantic-release":"^21.0.0","ts-node":"^10.9.1","typescript":"^5.0.0","wdio-geckodriver-service":"^5.0.1"},"dependencies":{"@msgpack/msgpack":"^2.8.0","cbor-x":"1.5.4","eventemitter3":"^4.0.7","peerjs-js-binarypack":"^2.1.0","webrtc-adapter":"^8.0.0"},"alias":{"process":false,"buffer":false}}');
3630
3631
3632class $5dd3b97502a89fbb$export$4798917dbf149b79 extends (0, $f5d7fbd88de797fd$exports.EventEmitter) {
3633 start(id, token) {
3634 this._id = id;
3635 const wsUrl = `${this._baseUrl}&id=${id}&token=${token}`;
3636 if (!!this._socket || !this._disconnected) return;
3637 this._socket = new WebSocket(wsUrl + "&version=" + (0, $580fed67ed3c559d$exports.version));
3638 this._disconnected = false;
3639 this._socket.onmessage = (event)=>{
3640 let data;
3641 try {
3642 data = JSON.parse(event.data);
3643 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Server message received:", data);
3644 } catch (e) {
3645 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Invalid server message", event.data);
3646 return;
3647 }
3648 this.emit((0, $edbcf3072a01d580$export$3b5c4a4b6354f023).Message, data);
3649 };
3650 this._socket.onclose = (event)=>{
3651 if (this._disconnected) return;
3652 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Socket closed.", event);
3653 this._cleanup();
3654 this._disconnected = true;
3655 this.emit((0, $edbcf3072a01d580$export$3b5c4a4b6354f023).Disconnected);
3656 };
3657 // Take care of the queue of connections if necessary and make sure Peer knows
3658 // socket is open.
3659 this._socket.onopen = ()=>{
3660 if (this._disconnected) return;
3661 this._sendQueuedMessages();
3662 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Socket open");
3663 this._scheduleHeartbeat();
3664 };
3665 }
3666 _scheduleHeartbeat() {
3667 this._wsPingTimer = setTimeout(()=>{
3668 this._sendHeartbeat();
3669 }, this.pingInterval);
3670 }
3671 _sendHeartbeat() {
3672 if (!this._wsOpen()) {
3673 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`Cannot send heartbeat, because socket closed`);
3674 return;
3675 }
3676 const message = JSON.stringify({
3677 type: (0, $edbcf3072a01d580$export$adb4a1754da6f10d).Heartbeat
3678 });
3679 this._socket.send(message);
3680 this._scheduleHeartbeat();
3681 }
3682 /** Is the websocket currently open? */ _wsOpen() {
3683 return !!this._socket && this._socket.readyState === 1;
3684 }
3685 /** Send queued messages. */ _sendQueuedMessages() {
3686 //Create copy of queue and clear it,
3687 //because send method push the message back to queue if smth will go wrong
3688 const copiedQueue = [
3689 ...this._messagesQueue
3690 ];
3691 this._messagesQueue = [];
3692 for (const message of copiedQueue)this.send(message);
3693 }
3694 /** Exposed send for DC & Peer. */ send(data) {
3695 if (this._disconnected) return;
3696 // If we didn't get an ID yet, we can't yet send anything so we should queue
3697 // up these messages.
3698 if (!this._id) {
3699 this._messagesQueue.push(data);
3700 return;
3701 }
3702 if (!data.type) {
3703 this.emit((0, $edbcf3072a01d580$export$3b5c4a4b6354f023).Error, "Invalid message");
3704 return;
3705 }
3706 if (!this._wsOpen()) return;
3707 const message = JSON.stringify(data);
3708 this._socket.send(message);
3709 }
3710 close() {
3711 if (this._disconnected) return;
3712 this._cleanup();
3713 this._disconnected = true;
3714 }
3715 _cleanup() {
3716 if (this._socket) {
3717 this._socket.onopen = this._socket.onmessage = this._socket.onclose = null;
3718 this._socket.close();
3719 this._socket = undefined;
3720 }
3721 clearTimeout(this._wsPingTimer);
3722 }
3723 constructor(secure, host, port, path, key, pingInterval = 5000){
3724 super();
3725 this.pingInterval = pingInterval;
3726 this._disconnected = true;
3727 this._messagesQueue = [];
3728 const wsProtocol = secure ? "wss://" : "ws://";
3729 this._baseUrl = wsProtocol + host + ":" + port + path + "peerjs?key=" + key;
3730 }
3731}
3732
3733
3734
3735
3736
3737
3738class $3cabb799c2437cbe$export$89e6bb5ad64bf4a {
3739 /** Returns a PeerConnection object set up correctly (for data, media). */ startConnection(options) {
3740 const peerConnection = this._startPeerConnection();
3741 // Set the connection's PC.
3742 this.connection.peerConnection = peerConnection;
3743 if (this.connection.type === (0, $edbcf3072a01d580$export$3157d57b4135e3bc).Media && options._stream) this._addTracksToConnection(options._stream, peerConnection);
3744 // What do we need to do now?
3745 if (options.originator) {
3746 const dataConnection = this.connection;
3747 const config = {
3748 ordered: !!options.reliable
3749 };
3750 const dataChannel = peerConnection.createDataChannel(dataConnection.label, config);
3751 dataConnection._initializeDataChannel(dataChannel);
3752 this._makeOffer();
3753 } else this.handleSDP("OFFER", options.sdp);
3754 }
3755 /** Start a PC. */ _startPeerConnection() {
3756 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Creating RTCPeerConnection.");
3757 const peerConnection = new RTCPeerConnection(this.connection.provider.options.config);
3758 this._setupListeners(peerConnection);
3759 return peerConnection;
3760 }
3761 /** Set up various WebRTC listeners. */ _setupListeners(peerConnection) {
3762 const peerId = this.connection.peer;
3763 const connectionId = this.connection.connectionId;
3764 const connectionType = this.connection.type;
3765 const provider = this.connection.provider;
3766 // ICE CANDIDATES.
3767 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Listening for ICE candidates.");
3768 peerConnection.onicecandidate = (evt)=>{
3769 if (!evt.candidate || !evt.candidate.candidate) return;
3770 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`Received ICE candidates for ${peerId}:`, evt.candidate);
3771 provider.socket.send({
3772 type: (0, $edbcf3072a01d580$export$adb4a1754da6f10d).Candidate,
3773 payload: {
3774 candidate: evt.candidate,
3775 type: connectionType,
3776 connectionId: connectionId
3777 },
3778 dst: peerId
3779 });
3780 };
3781 peerConnection.oniceconnectionstatechange = ()=>{
3782 switch(peerConnection.iceConnectionState){
3783 case "failed":
3784 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("iceConnectionState is failed, closing connections to " + peerId);
3785 this.connection.emitError((0, $edbcf3072a01d580$export$7974935686149686).NegotiationFailed, "Negotiation of connection to " + peerId + " failed.");
3786 this.connection.close();
3787 break;
3788 case "closed":
3789 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("iceConnectionState is closed, closing connections to " + peerId);
3790 this.connection.emitError((0, $edbcf3072a01d580$export$7974935686149686).ConnectionClosed, "Connection to " + peerId + " closed.");
3791 this.connection.close();
3792 break;
3793 case "disconnected":
3794 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("iceConnectionState changed to disconnected on the connection with " + peerId);
3795 break;
3796 case "completed":
3797 peerConnection.onicecandidate = ()=>{};
3798 break;
3799 }
3800 this.connection.emit("iceStateChanged", peerConnection.iceConnectionState);
3801 };
3802 // DATACONNECTION.
3803 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Listening for data channel");
3804 // Fired between offer and answer, so options should already be saved
3805 // in the options hash.
3806 peerConnection.ondatachannel = (evt)=>{
3807 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Received data channel");
3808 const dataChannel = evt.channel;
3809 const connection = provider.getConnection(peerId, connectionId);
3810 connection._initializeDataChannel(dataChannel);
3811 };
3812 // MEDIACONNECTION.
3813 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Listening for remote stream");
3814 peerConnection.ontrack = (evt)=>{
3815 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Received remote stream");
3816 const stream = evt.streams[0];
3817 const connection = provider.getConnection(peerId, connectionId);
3818 if (connection.type === (0, $edbcf3072a01d580$export$3157d57b4135e3bc).Media) {
3819 const mediaConnection = connection;
3820 this._addStreamToMediaConnection(stream, mediaConnection);
3821 }
3822 };
3823 }
3824 cleanup() {
3825 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Cleaning up PeerConnection to " + this.connection.peer);
3826 const peerConnection = this.connection.peerConnection;
3827 if (!peerConnection) return;
3828 this.connection.peerConnection = null;
3829 //unsubscribe from all PeerConnection's events
3830 peerConnection.onicecandidate = peerConnection.oniceconnectionstatechange = peerConnection.ondatachannel = peerConnection.ontrack = ()=>{};
3831 const peerConnectionNotClosed = peerConnection.signalingState !== "closed";
3832 let dataChannelNotClosed = false;
3833 const dataChannel = this.connection.dataChannel;
3834 if (dataChannel) dataChannelNotClosed = !!dataChannel.readyState && dataChannel.readyState !== "closed";
3835 if (peerConnectionNotClosed || dataChannelNotClosed) peerConnection.close();
3836 }
3837 async _makeOffer() {
3838 const peerConnection = this.connection.peerConnection;
3839 const provider = this.connection.provider;
3840 try {
3841 const offer = await peerConnection.createOffer(this.connection.options.constraints);
3842 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Created offer.");
3843 if (this.connection.options.sdpTransform && typeof this.connection.options.sdpTransform === "function") offer.sdp = this.connection.options.sdpTransform(offer.sdp) || offer.sdp;
3844 try {
3845 await peerConnection.setLocalDescription(offer);
3846 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Set localDescription:", offer, `for:${this.connection.peer}`);
3847 let payload = {
3848 sdp: offer,
3849 type: this.connection.type,
3850 connectionId: this.connection.connectionId,
3851 metadata: this.connection.metadata
3852 };
3853 if (this.connection.type === (0, $edbcf3072a01d580$export$3157d57b4135e3bc).Data) {
3854 const dataConnection = this.connection;
3855 payload = {
3856 ...payload,
3857 label: dataConnection.label,
3858 reliable: dataConnection.reliable,
3859 serialization: dataConnection.serialization
3860 };
3861 }
3862 provider.socket.send({
3863 type: (0, $edbcf3072a01d580$export$adb4a1754da6f10d).Offer,
3864 payload: payload,
3865 dst: this.connection.peer
3866 });
3867 } catch (err) {
3868 // TODO: investigate why _makeOffer is being called from the answer
3869 if (err != "OperationError: Failed to set local offer sdp: Called in wrong state: kHaveRemoteOffer") {
3870 provider.emitError((0, $edbcf3072a01d580$export$9547aaa2e39030ff).WebRTC, err);
3871 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Failed to setLocalDescription, ", err);
3872 }
3873 }
3874 } catch (err_1) {
3875 provider.emitError((0, $edbcf3072a01d580$export$9547aaa2e39030ff).WebRTC, err_1);
3876 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Failed to createOffer, ", err_1);
3877 }
3878 }
3879 async _makeAnswer() {
3880 const peerConnection = this.connection.peerConnection;
3881 const provider = this.connection.provider;
3882 try {
3883 const answer = await peerConnection.createAnswer();
3884 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Created answer.");
3885 if (this.connection.options.sdpTransform && typeof this.connection.options.sdpTransform === "function") answer.sdp = this.connection.options.sdpTransform(answer.sdp) || answer.sdp;
3886 try {
3887 await peerConnection.setLocalDescription(answer);
3888 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`Set localDescription:`, answer, `for:${this.connection.peer}`);
3889 provider.socket.send({
3890 type: (0, $edbcf3072a01d580$export$adb4a1754da6f10d).Answer,
3891 payload: {
3892 sdp: answer,
3893 type: this.connection.type,
3894 connectionId: this.connection.connectionId
3895 },
3896 dst: this.connection.peer
3897 });
3898 } catch (err) {
3899 provider.emitError((0, $edbcf3072a01d580$export$9547aaa2e39030ff).WebRTC, err);
3900 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Failed to setLocalDescription, ", err);
3901 }
3902 } catch (err_1) {
3903 provider.emitError((0, $edbcf3072a01d580$export$9547aaa2e39030ff).WebRTC, err_1);
3904 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Failed to create answer, ", err_1);
3905 }
3906 }
3907 /** Handle an SDP. */ async handleSDP(type, sdp) {
3908 sdp = new RTCSessionDescription(sdp);
3909 const peerConnection = this.connection.peerConnection;
3910 const provider = this.connection.provider;
3911 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Setting remote description", sdp);
3912 const self = this;
3913 try {
3914 await peerConnection.setRemoteDescription(sdp);
3915 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`Set remoteDescription:${type} for:${this.connection.peer}`);
3916 if (type === "OFFER") await self._makeAnswer();
3917 } catch (err) {
3918 provider.emitError((0, $edbcf3072a01d580$export$9547aaa2e39030ff).WebRTC, err);
3919 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Failed to setRemoteDescription, ", err);
3920 }
3921 }
3922 /** Handle a candidate. */ async handleCandidate(ice) {
3923 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`handleCandidate:`, ice);
3924 try {
3925 await this.connection.peerConnection.addIceCandidate(ice);
3926 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`Added ICE candidate for:${this.connection.peer}`);
3927 } catch (err) {
3928 this.connection.provider.emitError((0, $edbcf3072a01d580$export$9547aaa2e39030ff).WebRTC, err);
3929 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Failed to handleCandidate, ", err);
3930 }
3931 }
3932 _addTracksToConnection(stream, peerConnection) {
3933 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`add tracks from stream ${stream.id} to peer connection`);
3934 if (!peerConnection.addTrack) return (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).error(`Your browser does't support RTCPeerConnection#addTrack. Ignored.`);
3935 stream.getTracks().forEach((track)=>{
3936 peerConnection.addTrack(track, stream);
3937 });
3938 }
3939 _addStreamToMediaConnection(stream, mediaConnection) {
3940 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`add stream ${stream.id} to media connection ${mediaConnection.connectionId}`);
3941 mediaConnection.addStream(stream);
3942 }
3943 constructor(connection){
3944 this.connection = connection;
3945 }
3946}
3947
3948
3949
3950
3951
3952class $41eb28b5735ed6cf$export$6a678e589c8a4542 extends (0, $f5d7fbd88de797fd$exports.EventEmitter) {
3953 /**
3954 * Emits a typed error message.
3955 *
3956 * @internal
3957 */ emitError(type, err) {
3958 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).error("Error:", err);
3959 // @ts-ignore
3960 this.emit("error", new $41eb28b5735ed6cf$export$98871882f492de82(`${type}`, err));
3961 }
3962}
3963class $41eb28b5735ed6cf$export$98871882f492de82 extends Error {
3964 /**
3965 * @internal
3966 */ constructor(type, err){
3967 if (typeof err === "string") super(err);
3968 else {
3969 super();
3970 Object.assign(this, err);
3971 }
3972 this.type = type;
3973 }
3974}
3975
3976
3977class $f06f075a81a8b63e$export$23a2a68283c24d80 extends (0, $41eb28b5735ed6cf$export$6a678e589c8a4542) {
3978 /**
3979 * Whether the media connection is active (e.g. your call has been answered).
3980 * You can check this if you want to set a maximum wait time for a one-sided call.
3981 */ get open() {
3982 return this._open;
3983 }
3984 constructor(/**
3985 * The ID of the peer on the other end of this connection.
3986 */ peer, provider, options){
3987 super();
3988 this.peer = peer;
3989 this.provider = provider;
3990 this.options = options;
3991 this._open = false;
3992 this.metadata = options.metadata;
3993 }
3994}
3995
3996
3997class $0bc12d7ac26e1491$export$4a84e95a2324ac29 extends (0, $f06f075a81a8b63e$export$23a2a68283c24d80) {
3998 /**
3999 * For media connections, this is always 'media'.
4000 */ get type() {
4001 return (0, $edbcf3072a01d580$export$3157d57b4135e3bc).Media;
4002 }
4003 get localStream() {
4004 return this._localStream;
4005 }
4006 get remoteStream() {
4007 return this._remoteStream;
4008 }
4009 /** Called by the Negotiator when the DataChannel is ready. */ _initializeDataChannel(dc) {
4010 this.dataChannel = dc;
4011 this.dataChannel.onopen = ()=>{
4012 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`DC#${this.connectionId} dc connection success`);
4013 this.emit("willCloseOnRemote");
4014 };
4015 this.dataChannel.onclose = ()=>{
4016 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`DC#${this.connectionId} dc closed for:`, this.peer);
4017 this.close();
4018 };
4019 }
4020 addStream(remoteStream) {
4021 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log("Receiving stream", remoteStream);
4022 this._remoteStream = remoteStream;
4023 super.emit("stream", remoteStream); // Should we call this `open`?
4024 }
4025 /**
4026 * @internal
4027 */ handleMessage(message) {
4028 const type = message.type;
4029 const payload = message.payload;
4030 switch(message.type){
4031 case (0, $edbcf3072a01d580$export$adb4a1754da6f10d).Answer:
4032 // Forward to negotiator
4033 this._negotiator.handleSDP(type, payload.sdp);
4034 this._open = true;
4035 break;
4036 case (0, $edbcf3072a01d580$export$adb4a1754da6f10d).Candidate:
4037 this._negotiator.handleCandidate(payload.candidate);
4038 break;
4039 default:
4040 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).warn(`Unrecognized message type:${type} from peer:${this.peer}`);
4041 break;
4042 }
4043 }
4044 /**
4045 * When receiving a {@apilink PeerEvents | `call`} event on a peer, you can call
4046 * `answer` on the media connection provided by the callback to accept the call
4047 * and optionally send your own media stream.
4048
4049 *
4050 * @param stream A WebRTC media stream.
4051 * @param options
4052 * @returns
4053 */ answer(stream, options = {}) {
4054 if (this._localStream) {
4055 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).warn("Local stream already exists on this MediaConnection. Are you answering a call twice?");
4056 return;
4057 }
4058 this._localStream = stream;
4059 if (options && options.sdpTransform) this.options.sdpTransform = options.sdpTransform;
4060 this._negotiator.startConnection({
4061 ...this.options._payload,
4062 _stream: stream
4063 });
4064 // Retrieve lost messages stored because PeerConnection not set up.
4065 const messages = this.provider._getMessages(this.connectionId);
4066 for (const message of messages)this.handleMessage(message);
4067 this._open = true;
4068 }
4069 /**
4070 * Exposed functionality for users.
4071 */ /**
4072 * Closes the media connection.
4073 */ close() {
4074 if (this._negotiator) {
4075 this._negotiator.cleanup();
4076 this._negotiator = null;
4077 }
4078 this._localStream = null;
4079 this._remoteStream = null;
4080 if (this.provider) {
4081 this.provider._removeConnection(this);
4082 this.provider = null;
4083 }
4084 if (this.options && this.options._stream) this.options._stream = null;
4085 if (!this.open) return;
4086 this._open = false;
4087 super.emit("close");
4088 }
4089 constructor(peerId, provider, options){
4090 super(peerId, provider, options);
4091 this._localStream = this.options._stream;
4092 this.connectionId = this.options.connectionId || $0bc12d7ac26e1491$export$4a84e95a2324ac29.ID_PREFIX + (0, $01f0d223090cb1f8$export$7debb50ef11d5e0b).randomToken();
4093 this._negotiator = new (0, $3cabb799c2437cbe$export$89e6bb5ad64bf4a)(this);
4094 if (this._localStream) this._negotiator.startConnection({
4095 _stream: this._localStream,
4096 originator: true
4097 });
4098 }
4099}
4100$0bc12d7ac26e1491$export$4a84e95a2324ac29.ID_PREFIX = "mc_";
4101
4102
4103
4104
4105
4106
4107class $4c932c6613316196$export$2c4e825dc9120f87 {
4108 _buildRequest(method) {
4109 const protocol = this._options.secure ? "https" : "http";
4110 const { host: host, port: port, path: path, key: key } = this._options;
4111 const url = new URL(`${protocol}://${host}:${port}${path}${key}/${method}`);
4112 // TODO: Why timestamp, why random?
4113 url.searchParams.set("ts", `${Date.now()}${Math.random()}`);
4114 url.searchParams.set("version", (0, $580fed67ed3c559d$exports.version));
4115 return fetch(url.href, {
4116 referrerPolicy: this._options.referrerPolicy
4117 });
4118 }
4119 /** Get a unique ID from the server via XHR and initialize with it. */ async retrieveId() {
4120 try {
4121 const response = await this._buildRequest("id");
4122 if (response.status !== 200) throw new Error(`Error. Status:${response.status}`);
4123 return response.text();
4124 } catch (error) {
4125 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).error("Error retrieving ID", error);
4126 let pathError = "";
4127 if (this._options.path === "/" && this._options.host !== (0, $01f0d223090cb1f8$export$7debb50ef11d5e0b).CLOUD_HOST) pathError = " If you passed in a `path` to your self-hosted PeerServer, you'll also need to pass in that same path when creating a new Peer.";
4128 throw new Error("Could not get an ID from the server." + pathError);
4129 }
4130 }
4131 /** @deprecated */ async listAllPeers() {
4132 try {
4133 const response = await this._buildRequest("peers");
4134 if (response.status !== 200) {
4135 if (response.status === 401) {
4136 let helpfulError = "";
4137 if (this._options.host === (0, $01f0d223090cb1f8$export$7debb50ef11d5e0b).CLOUD_HOST) helpfulError = "It looks like you're using the cloud server. You can email team@peerjs.com to enable peer listing for your API key.";
4138 else helpfulError = "You need to enable `allow_discovery` on your self-hosted PeerServer to use this feature.";
4139 throw new Error("It doesn't look like you have permission to list peers IDs. " + helpfulError);
4140 }
4141 throw new Error(`Error. Status:${response.status}`);
4142 }
4143 return response.json();
4144 } catch (error) {
4145 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).error("Error retrieving list peers", error);
4146 throw new Error("Could not get list peers from the server." + error);
4147 }
4148 }
4149 constructor(_options){
4150 this._options = _options;
4151 }
4152}
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163class $392ccce28b647101$export$d365f7ad9d7df9c9 extends (0, $f06f075a81a8b63e$export$23a2a68283c24d80) {
4164 get type() {
4165 return (0, $edbcf3072a01d580$export$3157d57b4135e3bc).Data;
4166 }
4167 /** Called by the Negotiator when the DataChannel is ready. */ _initializeDataChannel(dc) {
4168 this.dataChannel = dc;
4169 this.dataChannel.onopen = ()=>{
4170 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`DC#${this.connectionId} dc connection success`);
4171 this._open = true;
4172 this.emit("open");
4173 };
4174 this.dataChannel.onmessage = (e)=>{
4175 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`DC#${this.connectionId} dc onmessage:`, e.data);
4176 // this._handleDataMessage(e);
4177 };
4178 this.dataChannel.onclose = ()=>{
4179 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`DC#${this.connectionId} dc closed for:`, this.peer);
4180 this.close();
4181 };
4182 }
4183 /**
4184 * Exposed functionality for users.
4185 */ /** Allows user to close connection. */ close(options) {
4186 if (options?.flush) {
4187 this.send({
4188 __peerData: {
4189 type: "close"
4190 }
4191 });
4192 return;
4193 }
4194 if (this._negotiator) {
4195 this._negotiator.cleanup();
4196 this._negotiator = null;
4197 }
4198 if (this.provider) {
4199 this.provider._removeConnection(this);
4200 this.provider = null;
4201 }
4202 if (this.dataChannel) {
4203 this.dataChannel.onopen = null;
4204 this.dataChannel.onmessage = null;
4205 this.dataChannel.onclose = null;
4206 this.dataChannel = null;
4207 }
4208 if (!this.open) return;
4209 this._open = false;
4210 super.emit("close");
4211 }
4212 /** Allows user to send data. */ send(data, chunked = false) {
4213 if (!this.open) {
4214 this.emitError((0, $edbcf3072a01d580$export$49ae800c114df41d).NotOpenYet, "Connection is not open. You should listen for the `open` event before sending messages.");
4215 return;
4216 }
4217 return this._send(data, chunked);
4218 }
4219 async handleMessage(message) {
4220 const payload = message.payload;
4221 switch(message.type){
4222 case (0, $edbcf3072a01d580$export$adb4a1754da6f10d).Answer:
4223 await this._negotiator.handleSDP(message.type, payload.sdp);
4224 break;
4225 case (0, $edbcf3072a01d580$export$adb4a1754da6f10d).Candidate:
4226 await this._negotiator.handleCandidate(payload.candidate);
4227 break;
4228 default:
4229 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).warn("Unrecognized message type:", message.type, "from peer:", this.peer);
4230 break;
4231 }
4232 }
4233 constructor(peerId, provider, options){
4234 super(peerId, provider, options);
4235 this.connectionId = this.options.connectionId || $392ccce28b647101$export$d365f7ad9d7df9c9.ID_PREFIX + (0, $008766fe99f03c2f$export$4e61f672936bec77)();
4236 this.label = this.options.label || this.connectionId;
4237 this.reliable = !!this.options.reliable;
4238 this._negotiator = new (0, $3cabb799c2437cbe$export$89e6bb5ad64bf4a)(this);
4239 this._negotiator.startConnection(this.options._payload || {
4240 originator: true,
4241 reliable: this.reliable
4242 });
4243 }
4244}
4245$392ccce28b647101$export$d365f7ad9d7df9c9.ID_PREFIX = "dc_";
4246$392ccce28b647101$export$d365f7ad9d7df9c9.MAX_BUFFERED_AMOUNT = 8388608;
4247
4248
4249class $8d1d5e45d8d6520c$export$ff7c9d4c11d94e8b extends (0, $392ccce28b647101$export$d365f7ad9d7df9c9) {
4250 get bufferSize() {
4251 return this._bufferSize;
4252 }
4253 _initializeDataChannel(dc) {
4254 super._initializeDataChannel(dc);
4255 this.dataChannel.binaryType = "arraybuffer";
4256 this.dataChannel.addEventListener("message", (e)=>this._handleDataMessage(e));
4257 }
4258 _bufferedSend(msg) {
4259 if (this._buffering || !this._trySend(msg)) {
4260 this._buffer.push(msg);
4261 this._bufferSize = this._buffer.length;
4262 }
4263 }
4264 // Returns true if the send succeeds.
4265 _trySend(msg) {
4266 if (!this.open) return false;
4267 if (this.dataChannel.bufferedAmount > (0, $392ccce28b647101$export$d365f7ad9d7df9c9).MAX_BUFFERED_AMOUNT) {
4268 this._buffering = true;
4269 setTimeout(()=>{
4270 this._buffering = false;
4271 this._tryBuffer();
4272 }, 50);
4273 return false;
4274 }
4275 try {
4276 this.dataChannel.send(msg);
4277 } catch (e) {
4278 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).error(`DC#:${this.connectionId} Error when sending:`, e);
4279 this._buffering = true;
4280 this.close();
4281 return false;
4282 }
4283 return true;
4284 }
4285 // Try to send the first message in the buffer.
4286 _tryBuffer() {
4287 if (!this.open) return;
4288 if (this._buffer.length === 0) return;
4289 const msg = this._buffer[0];
4290 if (this._trySend(msg)) {
4291 this._buffer.shift();
4292 this._bufferSize = this._buffer.length;
4293 this._tryBuffer();
4294 }
4295 }
4296 close(options) {
4297 if (options?.flush) {
4298 this.send({
4299 __peerData: {
4300 type: "close"
4301 }
4302 });
4303 return;
4304 }
4305 this._buffer = [];
4306 this._bufferSize = 0;
4307 super.close();
4308 }
4309 constructor(...args){
4310 super(...args);
4311 this._buffer = [];
4312 this._bufferSize = 0;
4313 this._buffering = false;
4314 }
4315}
4316
4317
4318
4319
4320class $6b2c8b37149b9a13$export$f0a5a64d5bb37108 extends (0, $8d1d5e45d8d6520c$export$ff7c9d4c11d94e8b) {
4321 close(options) {
4322 super.close(options);
4323 this._chunkedData = {};
4324 }
4325 // Handles a DataChannel message.
4326 _handleDataMessage({ data: data }) {
4327 const deserializedData = (0, $bf7fb46c6d68ead7$export$417857010dc9287f)(data);
4328 // PeerJS specific message
4329 const peerData = deserializedData["__peerData"];
4330 if (peerData) {
4331 if (peerData.type === "close") {
4332 this.close();
4333 return;
4334 }
4335 // Chunked data -- piece things back together.
4336 // @ts-ignore
4337 this._handleChunk(deserializedData);
4338 return;
4339 }
4340 this.emit("data", deserializedData);
4341 }
4342 _handleChunk(data) {
4343 const id = data.__peerData;
4344 const chunkInfo = this._chunkedData[id] || {
4345 data: [],
4346 count: 0,
4347 total: data.total
4348 };
4349 chunkInfo.data[data.n] = new Uint8Array(data.data);
4350 chunkInfo.count++;
4351 this._chunkedData[id] = chunkInfo;
4352 if (chunkInfo.total === chunkInfo.count) {
4353 // Clean up before making the recursive call to `_handleDataMessage`.
4354 delete this._chunkedData[id];
4355 // We've received all the chunks--time to construct the complete data.
4356 // const data = new Blob(chunkInfo.data);
4357 const data = (0, $616ebdf1c4998439$export$52c89ebcdc4f53f2)(chunkInfo.data);
4358 this._handleDataMessage({
4359 data: data
4360 });
4361 }
4362 }
4363 _send(data, chunked) {
4364 const blob = (0, $bf7fb46c6d68ead7$export$2a703dbb0cb35339)(data);
4365 if (blob instanceof Promise) return this._send_blob(blob);
4366 if (!chunked && blob.byteLength > this.chunker.chunkedMTU) {
4367 this._sendChunks(blob);
4368 return;
4369 }
4370 this._bufferedSend(blob);
4371 }
4372 async _send_blob(blobPromise) {
4373 const blob = await blobPromise;
4374 if (blob.byteLength > this.chunker.chunkedMTU) {
4375 this._sendChunks(blob);
4376 return;
4377 }
4378 this._bufferedSend(blob);
4379 }
4380 _sendChunks(blob) {
4381 const blobs = this.chunker.chunk(blob);
4382 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`DC#${this.connectionId} Try to send ${blobs.length} chunks...`);
4383 for (const blob of blobs)this.send(blob, true);
4384 }
4385 constructor(peerId, provider, options){
4386 super(peerId, provider, options);
4387 this.chunker = new (0, $616ebdf1c4998439$export$f1c5f4c9cb95390b)();
4388 this.serialization = (0, $edbcf3072a01d580$export$89f507cf986a947).Binary;
4389 this._chunkedData = {};
4390 }
4391}
4392
4393
4394
4395
4396class $6faa8477ae391a66$export$6f88fe47d32c9c94 extends (0, $8d1d5e45d8d6520c$export$ff7c9d4c11d94e8b) {
4397 _handleDataMessage({ data: data }) {
4398 super.emit("data", data);
4399 }
4400 _send(data, _chunked) {
4401 this._bufferedSend(data);
4402 }
4403 constructor(...args){
4404 super(...args);
4405 this.serialization = (0, $edbcf3072a01d580$export$89f507cf986a947).None;
4406 }
4407}
4408
4409
4410
4411
4412
4413class $b524315f5ff1ee78$export$48880ac635f47186 extends (0, $8d1d5e45d8d6520c$export$ff7c9d4c11d94e8b) {
4414 // Handles a DataChannel message.
4415 _handleDataMessage({ data: data }) {
4416 const deserializedData = this.parse(this.decoder.decode(data));
4417 // PeerJS specific message
4418 const peerData = deserializedData["__peerData"];
4419 if (peerData && peerData.type === "close") {
4420 this.close();
4421 return;
4422 }
4423 this.emit("data", deserializedData);
4424 }
4425 _send(data, _chunked) {
4426 const encodedData = this.encoder.encode(this.stringify(data));
4427 if (encodedData.byteLength >= (0, $01f0d223090cb1f8$export$7debb50ef11d5e0b).chunkedMTU) {
4428 this.emitError((0, $edbcf3072a01d580$export$49ae800c114df41d).MessageToBig, "Message too big for JSON channel");
4429 return;
4430 }
4431 this._bufferedSend(encodedData);
4432 }
4433 constructor(...args){
4434 super(...args);
4435 this.serialization = (0, $edbcf3072a01d580$export$89f507cf986a947).JSON;
4436 this.encoder = new TextEncoder();
4437 this.decoder = new TextDecoder();
4438 this.stringify = JSON.stringify;
4439 this.parse = JSON.parse;
4440 }
4441}
4442
4443
4444
4445class $11967427976ce06d$var$PeerOptions {
4446}
4447class $11967427976ce06d$export$ecd1fc136c422448 extends (0, $41eb28b5735ed6cf$export$6a678e589c8a4542) {
4448 /**
4449 * The brokering ID of this peer
4450 *
4451 * If no ID was specified in {@apilink Peer | the constructor},
4452 * this will be `undefined` until the {@apilink PeerEvents | `open`} event is emitted.
4453 */ get id() {
4454 return this._id;
4455 }
4456 get options() {
4457 return this._options;
4458 }
4459 get open() {
4460 return this._open;
4461 }
4462 /**
4463 * @internal
4464 */ get socket() {
4465 return this._socket;
4466 }
4467 /**
4468 * A hash of all connections associated with this peer, keyed by the remote peer's ID.
4469 * @deprecated
4470 * Return type will change from Object to Map<string,[]>
4471 */ get connections() {
4472 const plainConnections = Object.create(null);
4473 for (const [k, v] of this._connections)plainConnections[k] = v;
4474 return plainConnections;
4475 }
4476 /**
4477 * true if this peer and all of its connections can no longer be used.
4478 */ get destroyed() {
4479 return this._destroyed;
4480 }
4481 /**
4482 * false if there is an active connection to the PeerServer.
4483 */ get disconnected() {
4484 return this._disconnected;
4485 }
4486 _createServerConnection() {
4487 const socket = new (0, $5dd3b97502a89fbb$export$4798917dbf149b79)(this._options.secure, this._options.host, this._options.port, this._options.path, this._options.key, this._options.pingInterval);
4488 socket.on((0, $edbcf3072a01d580$export$3b5c4a4b6354f023).Message, (data)=>{
4489 this._handleMessage(data);
4490 });
4491 socket.on((0, $edbcf3072a01d580$export$3b5c4a4b6354f023).Error, (error)=>{
4492 this._abort((0, $edbcf3072a01d580$export$9547aaa2e39030ff).SocketError, error);
4493 });
4494 socket.on((0, $edbcf3072a01d580$export$3b5c4a4b6354f023).Disconnected, ()=>{
4495 if (this.disconnected) return;
4496 this.emitError((0, $edbcf3072a01d580$export$9547aaa2e39030ff).Network, "Lost connection to server.");
4497 this.disconnect();
4498 });
4499 socket.on((0, $edbcf3072a01d580$export$3b5c4a4b6354f023).Close, ()=>{
4500 if (this.disconnected) return;
4501 this._abort((0, $edbcf3072a01d580$export$9547aaa2e39030ff).SocketClosed, "Underlying socket is already closed.");
4502 });
4503 return socket;
4504 }
4505 /** Initialize a connection with the server. */ _initialize(id) {
4506 this._id = id;
4507 this.socket.start(id, this._options.token);
4508 }
4509 /** Handles messages from the server. */ _handleMessage(message) {
4510 const type = message.type;
4511 const payload = message.payload;
4512 const peerId = message.src;
4513 switch(type){
4514 case (0, $edbcf3072a01d580$export$adb4a1754da6f10d).Open:
4515 this._lastServerId = this.id;
4516 this._open = true;
4517 this.emit("open", this.id);
4518 break;
4519 case (0, $edbcf3072a01d580$export$adb4a1754da6f10d).Error:
4520 this._abort((0, $edbcf3072a01d580$export$9547aaa2e39030ff).ServerError, payload.msg);
4521 break;
4522 case (0, $edbcf3072a01d580$export$adb4a1754da6f10d).IdTaken:
4523 this._abort((0, $edbcf3072a01d580$export$9547aaa2e39030ff).UnavailableID, `ID "${this.id}" is taken`);
4524 break;
4525 case (0, $edbcf3072a01d580$export$adb4a1754da6f10d).InvalidKey:
4526 this._abort((0, $edbcf3072a01d580$export$9547aaa2e39030ff).InvalidKey, `API KEY "${this._options.key}" is invalid`);
4527 break;
4528 case (0, $edbcf3072a01d580$export$adb4a1754da6f10d).Leave:
4529 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`Received leave message from ${peerId}`);
4530 this._cleanupPeer(peerId);
4531 this._connections.delete(peerId);
4532 break;
4533 case (0, $edbcf3072a01d580$export$adb4a1754da6f10d).Expire:
4534 this.emitError((0, $edbcf3072a01d580$export$9547aaa2e39030ff).PeerUnavailable, `Could not connect to peer ${peerId}`);
4535 break;
4536 case (0, $edbcf3072a01d580$export$adb4a1754da6f10d).Offer:
4537 {
4538 // we should consider switching this to CALL/CONNECT, but this is the least breaking option.
4539 const connectionId = payload.connectionId;
4540 let connection = this.getConnection(peerId, connectionId);
4541 if (connection) {
4542 connection.close();
4543 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).warn(`Offer received for existing Connection ID:${connectionId}`);
4544 }
4545 // Create a new connection.
4546 if (payload.type === (0, $edbcf3072a01d580$export$3157d57b4135e3bc).Media) {
4547 const mediaConnection = new (0, $0bc12d7ac26e1491$export$4a84e95a2324ac29)(peerId, this, {
4548 connectionId: connectionId,
4549 _payload: payload,
4550 metadata: payload.metadata
4551 });
4552 connection = mediaConnection;
4553 this._addConnection(peerId, connection);
4554 this.emit("call", mediaConnection);
4555 } else if (payload.type === (0, $edbcf3072a01d580$export$3157d57b4135e3bc).Data) {
4556 const dataConnection = new this._serializers[payload.serialization](peerId, this, {
4557 connectionId: connectionId,
4558 _payload: payload,
4559 metadata: payload.metadata,
4560 label: payload.label,
4561 serialization: payload.serialization,
4562 reliable: payload.reliable
4563 });
4564 connection = dataConnection;
4565 this._addConnection(peerId, connection);
4566 this.emit("connection", dataConnection);
4567 } else {
4568 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).warn(`Received malformed connection type:${payload.type}`);
4569 return;
4570 }
4571 // Find messages.
4572 const messages = this._getMessages(connectionId);
4573 for (const message of messages)connection.handleMessage(message);
4574 break;
4575 }
4576 default:
4577 {
4578 if (!payload) {
4579 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).warn(`You received a malformed message from ${peerId} of type ${type}`);
4580 return;
4581 }
4582 const connectionId = payload.connectionId;
4583 const connection = this.getConnection(peerId, connectionId);
4584 if (connection && connection.peerConnection) // Pass it on.
4585 connection.handleMessage(message);
4586 else if (connectionId) // Store for possible later use
4587 this._storeMessage(connectionId, message);
4588 else (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).warn("You received an unrecognized message:", message);
4589 break;
4590 }
4591 }
4592 }
4593 /** Stores messages without a set up connection, to be claimed later. */ _storeMessage(connectionId, message) {
4594 if (!this._lostMessages.has(connectionId)) this._lostMessages.set(connectionId, []);
4595 this._lostMessages.get(connectionId).push(message);
4596 }
4597 /**
4598 * Retrieve messages from lost message store
4599 * @internal
4600 */ //TODO Change it to private
4601 _getMessages(connectionId) {
4602 const messages = this._lostMessages.get(connectionId);
4603 if (messages) {
4604 this._lostMessages.delete(connectionId);
4605 return messages;
4606 }
4607 return [];
4608 }
4609 /**
4610 * Connects to the remote peer specified by id and returns a data connection.
4611 * @param peer The brokering ID of the remote peer (their {@apilink Peer.id}).
4612 * @param options for specifying details about Peer Connection
4613 */ connect(peer, options = {}) {
4614 options = {
4615 serialization: "default",
4616 ...options
4617 };
4618 if (this.disconnected) {
4619 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).warn("You cannot connect to a new Peer because you called .disconnect() on this Peer and ended your connection with the server. You can create a new Peer to reconnect, or call reconnect on this peer if you believe its ID to still be available.");
4620 this.emitError((0, $edbcf3072a01d580$export$9547aaa2e39030ff).Disconnected, "Cannot connect to new Peer after disconnecting from server.");
4621 return;
4622 }
4623 const dataConnection = new this._serializers[options.serialization](peer, this, options);
4624 this._addConnection(peer, dataConnection);
4625 return dataConnection;
4626 }
4627 /**
4628 * Calls the remote peer specified by id and returns a media connection.
4629 * @param peer The brokering ID of the remote peer (their peer.id).
4630 * @param stream The caller's media stream
4631 * @param options Metadata associated with the connection, passed in by whoever initiated the connection.
4632 */ call(peer, stream, options = {}) {
4633 if (this.disconnected) {
4634 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).warn("You cannot connect to a new Peer because you called .disconnect() on this Peer and ended your connection with the server. You can create a new Peer to reconnect.");
4635 this.emitError((0, $edbcf3072a01d580$export$9547aaa2e39030ff).Disconnected, "Cannot connect to new Peer after disconnecting from server.");
4636 return;
4637 }
4638 if (!stream) {
4639 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).error("To call a peer, you must provide a stream from your browser's `getUserMedia`.");
4640 return;
4641 }
4642 const mediaConnection = new (0, $0bc12d7ac26e1491$export$4a84e95a2324ac29)(peer, this, {
4643 ...options,
4644 _stream: stream
4645 });
4646 this._addConnection(peer, mediaConnection);
4647 return mediaConnection;
4648 }
4649 /** Add a data/media connection to this peer. */ _addConnection(peerId, connection) {
4650 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`add connection ${connection.type}:${connection.connectionId} to peerId:${peerId}`);
4651 if (!this._connections.has(peerId)) this._connections.set(peerId, []);
4652 this._connections.get(peerId).push(connection);
4653 }
4654 //TODO should be private
4655 _removeConnection(connection) {
4656 const connections = this._connections.get(connection.peer);
4657 if (connections) {
4658 const index = connections.indexOf(connection);
4659 if (index !== -1) connections.splice(index, 1);
4660 }
4661 //remove from lost messages
4662 this._lostMessages.delete(connection.connectionId);
4663 }
4664 /** Retrieve a data/media connection for this peer. */ getConnection(peerId, connectionId) {
4665 const connections = this._connections.get(peerId);
4666 if (!connections) return null;
4667 for (const connection of connections){
4668 if (connection.connectionId === connectionId) return connection;
4669 }
4670 return null;
4671 }
4672 _delayedAbort(type, message) {
4673 setTimeout(()=>{
4674 this._abort(type, message);
4675 }, 0);
4676 }
4677 /**
4678 * Emits an error message and destroys the Peer.
4679 * The Peer is not destroyed if it's in a disconnected state, in which case
4680 * it retains its disconnected state and its existing connections.
4681 */ _abort(type, message) {
4682 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).error("Aborting!");
4683 this.emitError(type, message);
4684 if (!this._lastServerId) this.destroy();
4685 else this.disconnect();
4686 }
4687 /**
4688 * Destroys the Peer: closes all active connections as well as the connection
4689 * to the server.
4690 *
4691 * :::caution
4692 * This cannot be undone; the respective peer object will no longer be able
4693 * to create or receive any connections, its ID will be forfeited on the server,
4694 * and all of its data and media connections will be closed.
4695 * :::
4696 */ destroy() {
4697 if (this.destroyed) return;
4698 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`Destroy peer with ID:${this.id}`);
4699 this.disconnect();
4700 this._cleanup();
4701 this._destroyed = true;
4702 this.emit("close");
4703 }
4704 /** Disconnects every connection on this peer. */ _cleanup() {
4705 for (const peerId of this._connections.keys()){
4706 this._cleanupPeer(peerId);
4707 this._connections.delete(peerId);
4708 }
4709 this.socket.removeAllListeners();
4710 }
4711 /** Closes all connections to this peer. */ _cleanupPeer(peerId) {
4712 const connections = this._connections.get(peerId);
4713 if (!connections) return;
4714 for (const connection of connections)connection.close();
4715 }
4716 /**
4717 * Disconnects the Peer's connection to the PeerServer. Does not close any
4718 * active connections.
4719 * Warning: The peer can no longer create or accept connections after being
4720 * disconnected. It also cannot reconnect to the server.
4721 */ disconnect() {
4722 if (this.disconnected) return;
4723 const currentId = this.id;
4724 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`Disconnect peer with ID:${currentId}`);
4725 this._disconnected = true;
4726 this._open = false;
4727 this.socket.close();
4728 this._lastServerId = currentId;
4729 this._id = null;
4730 this.emit("disconnected", currentId);
4731 }
4732 /** Attempts to reconnect with the same ID.
4733 *
4734 * Only {@apilink Peer.disconnect | disconnected peers} can be reconnected.
4735 * Destroyed peers cannot be reconnected.
4736 * If the connection fails (as an example, if the peer's old ID is now taken),
4737 * the peer's existing connections will not close, but any associated errors events will fire.
4738 */ reconnect() {
4739 if (this.disconnected && !this.destroyed) {
4740 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).log(`Attempting reconnection to server with ID ${this._lastServerId}`);
4741 this._disconnected = false;
4742 this._initialize(this._lastServerId);
4743 } else if (this.destroyed) throw new Error("This peer cannot reconnect to the server. It has already been destroyed.");
4744 else if (!this.disconnected && !this.open) // Do nothing. We're still connecting the first time.
4745 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).error("In a hurry? We're still trying to make the initial connection!");
4746 else throw new Error(`Peer ${this.id} cannot reconnect because it is not disconnected from the server!`);
4747 }
4748 /**
4749 * Get a list of available peer IDs. If you're running your own server, you'll
4750 * want to set allow_discovery: true in the PeerServer options. If you're using
4751 * the cloud server, email team@peerjs.com to get the functionality enabled for
4752 * your key.
4753 */ listAllPeers(cb = (_)=>{}) {
4754 this._api.listAllPeers().then((peers)=>cb(peers)).catch((error)=>this._abort((0, $edbcf3072a01d580$export$9547aaa2e39030ff).ServerError, error));
4755 }
4756 constructor(id, options){
4757 super();
4758 this._serializers = {
4759 raw: (0, $6faa8477ae391a66$export$6f88fe47d32c9c94),
4760 json: (0, $b524315f5ff1ee78$export$48880ac635f47186),
4761 binary: (0, $6b2c8b37149b9a13$export$f0a5a64d5bb37108),
4762 "binary-utf8": (0, $6b2c8b37149b9a13$export$f0a5a64d5bb37108),
4763 default: (0, $6b2c8b37149b9a13$export$f0a5a64d5bb37108)
4764 };
4765 this._id = null;
4766 this._lastServerId = null;
4767 // States.
4768 this._destroyed = false // Connections have been killed
4769 ;
4770 this._disconnected = false // Connection to PeerServer killed but P2P connections still active
4771 ;
4772 this._open = false // Sockets and such are not yet open.
4773 ;
4774 this._connections = new Map() // All connections for this peer.
4775 ;
4776 this._lostMessages = new Map() // src => [list of messages]
4777 ;
4778 let userId;
4779 // Deal with overloading
4780 if (id && id.constructor == Object) options = id;
4781 else if (id) userId = id.toString();
4782 // Configurize options
4783 options = {
4784 debug: 0,
4785 host: (0, $01f0d223090cb1f8$export$7debb50ef11d5e0b).CLOUD_HOST,
4786 port: (0, $01f0d223090cb1f8$export$7debb50ef11d5e0b).CLOUD_PORT,
4787 path: "/",
4788 key: $11967427976ce06d$export$ecd1fc136c422448.DEFAULT_KEY,
4789 token: (0, $01f0d223090cb1f8$export$7debb50ef11d5e0b).randomToken(),
4790 config: (0, $01f0d223090cb1f8$export$7debb50ef11d5e0b).defaultConfig,
4791 referrerPolicy: "strict-origin-when-cross-origin",
4792 serializers: {},
4793 ...options
4794 };
4795 this._options = options;
4796 this._serializers = {
4797 ...this._serializers,
4798 ...this.options.serializers
4799 };
4800 // Detect relative URL host.
4801 if (this._options.host === "/") this._options.host = window.location.hostname;
4802 // Set path correctly.
4803 if (this._options.path) {
4804 if (this._options.path[0] !== "/") this._options.path = "/" + this._options.path;
4805 if (this._options.path[this._options.path.length - 1] !== "/") this._options.path += "/";
4806 }
4807 // Set whether we use SSL to same as current host
4808 if (this._options.secure === undefined && this._options.host !== (0, $01f0d223090cb1f8$export$7debb50ef11d5e0b).CLOUD_HOST) this._options.secure = (0, $01f0d223090cb1f8$export$7debb50ef11d5e0b).isSecure();
4809 else if (this._options.host == (0, $01f0d223090cb1f8$export$7debb50ef11d5e0b).CLOUD_HOST) this._options.secure = true;
4810 // Set a custom log function if present
4811 if (this._options.logFunction) (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).setLogFunction(this._options.logFunction);
4812 (0, $d3fc3aacca52312c$export$2e2bcd8739ae039).logLevel = this._options.debug || 0;
4813 this._api = new (0, $4c932c6613316196$export$2c4e825dc9120f87)(options);
4814 this._socket = this._createServerConnection();
4815 // Sanity checks
4816 // Ensure WebRTC supported
4817 if (!(0, $01f0d223090cb1f8$export$7debb50ef11d5e0b).supports.audioVideo && !(0, $01f0d223090cb1f8$export$7debb50ef11d5e0b).supports.data) {
4818 this._delayedAbort((0, $edbcf3072a01d580$export$9547aaa2e39030ff).BrowserIncompatible, "The current browser does not support WebRTC");
4819 return;
4820 }
4821 // Ensure alphanumeric id
4822 if (!!userId && !(0, $01f0d223090cb1f8$export$7debb50ef11d5e0b).validateId(userId)) {
4823 this._delayedAbort((0, $edbcf3072a01d580$export$9547aaa2e39030ff).InvalidID, `ID "${userId}" is invalid`);
4824 return;
4825 }
4826 if (userId) this._initialize(userId);
4827 else this._api.retrieveId().then((id)=>this._initialize(id)).catch((error)=>this._abort((0, $edbcf3072a01d580$export$9547aaa2e39030ff).ServerError, error));
4828 }
4829}
4830$11967427976ce06d$export$ecd1fc136c422448.DEFAULT_KEY = "peerjs";
4831
4832
4833window.peerjs = {
4834 Peer: $11967427976ce06d$export$ecd1fc136c422448,
4835 util: $01f0d223090cb1f8$export$7debb50ef11d5e0b
4836};
4837/** @deprecated Should use peerjs namespace */ window.Peer = (0, $11967427976ce06d$export$ecd1fc136c422448);
4838
4839})();
4840//# sourceMappingURL=peerjs.js.map