UNPKG

924 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3 typeof define === 'function' && define.amd ? define('leancloud-realtime', ['exports'], factory) :
4 (global = global || self, factory(global.AV = global.AV || {}));
5}(this, (function (exports) { 'use strict';
6
7 var define = undefined;
8 var require = require || function(id) {throw new Error('Unexpected required ' + id)};
9
10
11
12 var process = (typeof window !== 'undefined' && window.process) || {};
13 process.env = process.env || {};
14
15 function _defineProperty(obj, key, value) {
16 if (key in obj) {
17 Object.defineProperty(obj, key, {
18 value: value,
19 enumerable: true,
20 configurable: true,
21 writable: true
22 });
23 } else {
24 obj[key] = value;
25 }
26
27 return obj;
28 }
29
30 var defineProperty = _defineProperty;
31
32 var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
33
34 function createCommonjsModule(fn, basedir, module) {
35 return module = {
36 path: basedir,
37 exports: {},
38 require: function (path, base) {
39 return commonjsRequire(path, (base === undefined || base === null) ? module.path : base);
40 }
41 }, fn(module, module.exports), module.exports;
42 }
43
44 function getCjsExportFromNamespace (n) {
45 return n && n['default'] || n;
46 }
47
48 function commonjsRequire () {
49 throw new Error('Dynamic requires are not currently supported by @rollup/plugin-commonjs');
50 }
51
52 var long_1 = createCommonjsModule(function (module) {
53 /*
54 Copyright 2013 Daniel Wirtz <dcode@dcode.io>
55 Copyright 2009 The Closure Library Authors. All Rights Reserved.
56
57 Licensed under the Apache License, Version 2.0 (the "License");
58 you may not use this file except in compliance with the License.
59 You may obtain a copy of the License at
60
61 http://www.apache.org/licenses/LICENSE-2.0
62
63 Unless required by applicable law or agreed to in writing, software
64 distributed under the License is distributed on an "AS-IS" BASIS,
65 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
66 See the License for the specific language governing permissions and
67 limitations under the License.
68 */
69
70 /**
71 * @license long.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
72 * Released under the Apache License, Version 2.0
73 * see: https://github.com/dcodeIO/long.js for details
74 */
75 (function(global, factory) {
76
77 /* AMD */ if (typeof commonjsRequire === 'function' && 'object' === "object" && module && module["exports"])
78 module["exports"] = factory();
79 /* Global */ else
80 (global["dcodeIO"] = global["dcodeIO"] || {})["Long"] = factory();
81
82 })(commonjsGlobal, function() {
83
84 /**
85 * Constructs a 64 bit two's-complement integer, given its low and high 32 bit values as *signed* integers.
86 * See the from* functions below for more convenient ways of constructing Longs.
87 * @exports Long
88 * @class A Long class for representing a 64 bit two's-complement integer value.
89 * @param {number} low The low (signed) 32 bits of the long
90 * @param {number} high The high (signed) 32 bits of the long
91 * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
92 * @constructor
93 */
94 function Long(low, high, unsigned) {
95
96 /**
97 * The low 32 bits as a signed value.
98 * @type {number}
99 */
100 this.low = low | 0;
101
102 /**
103 * The high 32 bits as a signed value.
104 * @type {number}
105 */
106 this.high = high | 0;
107
108 /**
109 * Whether unsigned or not.
110 * @type {boolean}
111 */
112 this.unsigned = !!unsigned;
113 }
114
115 // The internal representation of a long is the two given signed, 32-bit values.
116 // We use 32-bit pieces because these are the size of integers on which
117 // Javascript performs bit-operations. For operations like addition and
118 // multiplication, we split each number into 16 bit pieces, which can easily be
119 // multiplied within Javascript's floating-point representation without overflow
120 // or change in sign.
121 //
122 // In the algorithms below, we frequently reduce the negative case to the
123 // positive case by negating the input(s) and then post-processing the result.
124 // Note that we must ALWAYS check specially whether those values are MIN_VALUE
125 // (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
126 // a positive number, it overflows back into a negative). Not handling this
127 // case would often result in infinite recursion.
128 //
129 // Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the from*
130 // methods on which they depend.
131
132 /**
133 * An indicator used to reliably determine if an object is a Long or not.
134 * @type {boolean}
135 * @const
136 * @private
137 */
138 Long.prototype.__isLong__;
139
140 Object.defineProperty(Long.prototype, "__isLong__", {
141 value: true,
142 enumerable: false,
143 configurable: false
144 });
145
146 /**
147 * @function
148 * @param {*} obj Object
149 * @returns {boolean}
150 * @inner
151 */
152 function isLong(obj) {
153 return (obj && obj["__isLong__"]) === true;
154 }
155
156 /**
157 * Tests if the specified object is a Long.
158 * @function
159 * @param {*} obj Object
160 * @returns {boolean}
161 */
162 Long.isLong = isLong;
163
164 /**
165 * A cache of the Long representations of small integer values.
166 * @type {!Object}
167 * @inner
168 */
169 var INT_CACHE = {};
170
171 /**
172 * A cache of the Long representations of small unsigned integer values.
173 * @type {!Object}
174 * @inner
175 */
176 var UINT_CACHE = {};
177
178 /**
179 * @param {number} value
180 * @param {boolean=} unsigned
181 * @returns {!Long}
182 * @inner
183 */
184 function fromInt(value, unsigned) {
185 var obj, cachedObj, cache;
186 if (unsigned) {
187 value >>>= 0;
188 if (cache = (0 <= value && value < 256)) {
189 cachedObj = UINT_CACHE[value];
190 if (cachedObj)
191 return cachedObj;
192 }
193 obj = fromBits(value, (value | 0) < 0 ? -1 : 0, true);
194 if (cache)
195 UINT_CACHE[value] = obj;
196 return obj;
197 } else {
198 value |= 0;
199 if (cache = (-128 <= value && value < 128)) {
200 cachedObj = INT_CACHE[value];
201 if (cachedObj)
202 return cachedObj;
203 }
204 obj = fromBits(value, value < 0 ? -1 : 0, false);
205 if (cache)
206 INT_CACHE[value] = obj;
207 return obj;
208 }
209 }
210
211 /**
212 * Returns a Long representing the given 32 bit integer value.
213 * @function
214 * @param {number} value The 32 bit integer in question
215 * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
216 * @returns {!Long} The corresponding Long value
217 */
218 Long.fromInt = fromInt;
219
220 /**
221 * @param {number} value
222 * @param {boolean=} unsigned
223 * @returns {!Long}
224 * @inner
225 */
226 function fromNumber(value, unsigned) {
227 if (isNaN(value) || !isFinite(value))
228 return unsigned ? UZERO : ZERO;
229 if (unsigned) {
230 if (value < 0)
231 return UZERO;
232 if (value >= TWO_PWR_64_DBL)
233 return MAX_UNSIGNED_VALUE;
234 } else {
235 if (value <= -TWO_PWR_63_DBL)
236 return MIN_VALUE;
237 if (value + 1 >= TWO_PWR_63_DBL)
238 return MAX_VALUE;
239 }
240 if (value < 0)
241 return fromNumber(-value, unsigned).neg();
242 return fromBits((value % TWO_PWR_32_DBL) | 0, (value / TWO_PWR_32_DBL) | 0, unsigned);
243 }
244
245 /**
246 * Returns a Long representing the given value, provided that it is a finite number. Otherwise, zero is returned.
247 * @function
248 * @param {number} value The number in question
249 * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
250 * @returns {!Long} The corresponding Long value
251 */
252 Long.fromNumber = fromNumber;
253
254 /**
255 * @param {number} lowBits
256 * @param {number} highBits
257 * @param {boolean=} unsigned
258 * @returns {!Long}
259 * @inner
260 */
261 function fromBits(lowBits, highBits, unsigned) {
262 return new Long(lowBits, highBits, unsigned);
263 }
264
265 /**
266 * Returns a Long representing the 64 bit integer that comes by concatenating the given low and high bits. Each is
267 * assumed to use 32 bits.
268 * @function
269 * @param {number} lowBits The low 32 bits
270 * @param {number} highBits The high 32 bits
271 * @param {boolean=} unsigned Whether unsigned or not, defaults to `false` for signed
272 * @returns {!Long} The corresponding Long value
273 */
274 Long.fromBits = fromBits;
275
276 /**
277 * @function
278 * @param {number} base
279 * @param {number} exponent
280 * @returns {number}
281 * @inner
282 */
283 var pow_dbl = Math.pow; // Used 4 times (4*8 to 15+4)
284
285 /**
286 * @param {string} str
287 * @param {(boolean|number)=} unsigned
288 * @param {number=} radix
289 * @returns {!Long}
290 * @inner
291 */
292 function fromString(str, unsigned, radix) {
293 if (str.length === 0)
294 throw Error('empty string');
295 if (str === "NaN" || str === "Infinity" || str === "+Infinity" || str === "-Infinity")
296 return ZERO;
297 if (typeof unsigned === 'number') {
298 // For goog.math.long compatibility
299 radix = unsigned,
300 unsigned = false;
301 } else {
302 unsigned = !! unsigned;
303 }
304 radix = radix || 10;
305 if (radix < 2 || 36 < radix)
306 throw RangeError('radix');
307
308 var p;
309 if ((p = str.indexOf('-')) > 0)
310 throw Error('interior hyphen');
311 else if (p === 0) {
312 return fromString(str.substring(1), unsigned, radix).neg();
313 }
314
315 // Do several (8) digits each time through the loop, so as to
316 // minimize the calls to the very expensive emulated div.
317 var radixToPower = fromNumber(pow_dbl(radix, 8));
318
319 var result = ZERO;
320 for (var i = 0; i < str.length; i += 8) {
321 var size = Math.min(8, str.length - i),
322 value = parseInt(str.substring(i, i + size), radix);
323 if (size < 8) {
324 var power = fromNumber(pow_dbl(radix, size));
325 result = result.mul(power).add(fromNumber(value));
326 } else {
327 result = result.mul(radixToPower);
328 result = result.add(fromNumber(value));
329 }
330 }
331 result.unsigned = unsigned;
332 return result;
333 }
334
335 /**
336 * Returns a Long representation of the given string, written using the specified radix.
337 * @function
338 * @param {string} str The textual representation of the Long
339 * @param {(boolean|number)=} unsigned Whether unsigned or not, defaults to `false` for signed
340 * @param {number=} radix The radix in which the text is written (2-36), defaults to 10
341 * @returns {!Long} The corresponding Long value
342 */
343 Long.fromString = fromString;
344
345 /**
346 * @function
347 * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val
348 * @returns {!Long}
349 * @inner
350 */
351 function fromValue(val) {
352 if (val /* is compatible */ instanceof Long)
353 return val;
354 if (typeof val === 'number')
355 return fromNumber(val);
356 if (typeof val === 'string')
357 return fromString(val);
358 // Throws for non-objects, converts non-instanceof Long:
359 return fromBits(val.low, val.high, val.unsigned);
360 }
361
362 /**
363 * Converts the specified value to a Long.
364 * @function
365 * @param {!Long|number|string|!{low: number, high: number, unsigned: boolean}} val Value
366 * @returns {!Long}
367 */
368 Long.fromValue = fromValue;
369
370 // NOTE: the compiler should inline these constant values below and then remove these variables, so there should be
371 // no runtime penalty for these.
372
373 /**
374 * @type {number}
375 * @const
376 * @inner
377 */
378 var TWO_PWR_16_DBL = 1 << 16;
379
380 /**
381 * @type {number}
382 * @const
383 * @inner
384 */
385 var TWO_PWR_24_DBL = 1 << 24;
386
387 /**
388 * @type {number}
389 * @const
390 * @inner
391 */
392 var TWO_PWR_32_DBL = TWO_PWR_16_DBL * TWO_PWR_16_DBL;
393
394 /**
395 * @type {number}
396 * @const
397 * @inner
398 */
399 var TWO_PWR_64_DBL = TWO_PWR_32_DBL * TWO_PWR_32_DBL;
400
401 /**
402 * @type {number}
403 * @const
404 * @inner
405 */
406 var TWO_PWR_63_DBL = TWO_PWR_64_DBL / 2;
407
408 /**
409 * @type {!Long}
410 * @const
411 * @inner
412 */
413 var TWO_PWR_24 = fromInt(TWO_PWR_24_DBL);
414
415 /**
416 * @type {!Long}
417 * @inner
418 */
419 var ZERO = fromInt(0);
420
421 /**
422 * Signed zero.
423 * @type {!Long}
424 */
425 Long.ZERO = ZERO;
426
427 /**
428 * @type {!Long}
429 * @inner
430 */
431 var UZERO = fromInt(0, true);
432
433 /**
434 * Unsigned zero.
435 * @type {!Long}
436 */
437 Long.UZERO = UZERO;
438
439 /**
440 * @type {!Long}
441 * @inner
442 */
443 var ONE = fromInt(1);
444
445 /**
446 * Signed one.
447 * @type {!Long}
448 */
449 Long.ONE = ONE;
450
451 /**
452 * @type {!Long}
453 * @inner
454 */
455 var UONE = fromInt(1, true);
456
457 /**
458 * Unsigned one.
459 * @type {!Long}
460 */
461 Long.UONE = UONE;
462
463 /**
464 * @type {!Long}
465 * @inner
466 */
467 var NEG_ONE = fromInt(-1);
468
469 /**
470 * Signed negative one.
471 * @type {!Long}
472 */
473 Long.NEG_ONE = NEG_ONE;
474
475 /**
476 * @type {!Long}
477 * @inner
478 */
479 var MAX_VALUE = fromBits(0xFFFFFFFF|0, 0x7FFFFFFF|0, false);
480
481 /**
482 * Maximum signed value.
483 * @type {!Long}
484 */
485 Long.MAX_VALUE = MAX_VALUE;
486
487 /**
488 * @type {!Long}
489 * @inner
490 */
491 var MAX_UNSIGNED_VALUE = fromBits(0xFFFFFFFF|0, 0xFFFFFFFF|0, true);
492
493 /**
494 * Maximum unsigned value.
495 * @type {!Long}
496 */
497 Long.MAX_UNSIGNED_VALUE = MAX_UNSIGNED_VALUE;
498
499 /**
500 * @type {!Long}
501 * @inner
502 */
503 var MIN_VALUE = fromBits(0, 0x80000000|0, false);
504
505 /**
506 * Minimum signed value.
507 * @type {!Long}
508 */
509 Long.MIN_VALUE = MIN_VALUE;
510
511 /**
512 * @alias Long.prototype
513 * @inner
514 */
515 var LongPrototype = Long.prototype;
516
517 /**
518 * Converts the Long to a 32 bit integer, assuming it is a 32 bit integer.
519 * @returns {number}
520 */
521 LongPrototype.toInt = function toInt() {
522 return this.unsigned ? this.low >>> 0 : this.low;
523 };
524
525 /**
526 * Converts the Long to a the nearest floating-point representation of this value (double, 53 bit mantissa).
527 * @returns {number}
528 */
529 LongPrototype.toNumber = function toNumber() {
530 if (this.unsigned)
531 return ((this.high >>> 0) * TWO_PWR_32_DBL) + (this.low >>> 0);
532 return this.high * TWO_PWR_32_DBL + (this.low >>> 0);
533 };
534
535 /**
536 * Converts the Long to a string written in the specified radix.
537 * @param {number=} radix Radix (2-36), defaults to 10
538 * @returns {string}
539 * @override
540 * @throws {RangeError} If `radix` is out of range
541 */
542 LongPrototype.toString = function toString(radix) {
543 radix = radix || 10;
544 if (radix < 2 || 36 < radix)
545 throw RangeError('radix');
546 if (this.isZero())
547 return '0';
548 if (this.isNegative()) { // Unsigned Longs are never negative
549 if (this.eq(MIN_VALUE)) {
550 // We need to change the Long value before it can be negated, so we remove
551 // the bottom-most digit in this base and then recurse to do the rest.
552 var radixLong = fromNumber(radix),
553 div = this.div(radixLong),
554 rem1 = div.mul(radixLong).sub(this);
555 return div.toString(radix) + rem1.toInt().toString(radix);
556 } else
557 return '-' + this.neg().toString(radix);
558 }
559
560 // Do several (6) digits each time through the loop, so as to
561 // minimize the calls to the very expensive emulated div.
562 var radixToPower = fromNumber(pow_dbl(radix, 6), this.unsigned),
563 rem = this;
564 var result = '';
565 while (true) {
566 var remDiv = rem.div(radixToPower),
567 intval = rem.sub(remDiv.mul(radixToPower)).toInt() >>> 0,
568 digits = intval.toString(radix);
569 rem = remDiv;
570 if (rem.isZero())
571 return digits + result;
572 else {
573 while (digits.length < 6)
574 digits = '0' + digits;
575 result = '' + digits + result;
576 }
577 }
578 };
579
580 /**
581 * Gets the high 32 bits as a signed integer.
582 * @returns {number} Signed high bits
583 */
584 LongPrototype.getHighBits = function getHighBits() {
585 return this.high;
586 };
587
588 /**
589 * Gets the high 32 bits as an unsigned integer.
590 * @returns {number} Unsigned high bits
591 */
592 LongPrototype.getHighBitsUnsigned = function getHighBitsUnsigned() {
593 return this.high >>> 0;
594 };
595
596 /**
597 * Gets the low 32 bits as a signed integer.
598 * @returns {number} Signed low bits
599 */
600 LongPrototype.getLowBits = function getLowBits() {
601 return this.low;
602 };
603
604 /**
605 * Gets the low 32 bits as an unsigned integer.
606 * @returns {number} Unsigned low bits
607 */
608 LongPrototype.getLowBitsUnsigned = function getLowBitsUnsigned() {
609 return this.low >>> 0;
610 };
611
612 /**
613 * Gets the number of bits needed to represent the absolute value of this Long.
614 * @returns {number}
615 */
616 LongPrototype.getNumBitsAbs = function getNumBitsAbs() {
617 if (this.isNegative()) // Unsigned Longs are never negative
618 return this.eq(MIN_VALUE) ? 64 : this.neg().getNumBitsAbs();
619 var val = this.high != 0 ? this.high : this.low;
620 for (var bit = 31; bit > 0; bit--)
621 if ((val & (1 << bit)) != 0)
622 break;
623 return this.high != 0 ? bit + 33 : bit + 1;
624 };
625
626 /**
627 * Tests if this Long's value equals zero.
628 * @returns {boolean}
629 */
630 LongPrototype.isZero = function isZero() {
631 return this.high === 0 && this.low === 0;
632 };
633
634 /**
635 * Tests if this Long's value is negative.
636 * @returns {boolean}
637 */
638 LongPrototype.isNegative = function isNegative() {
639 return !this.unsigned && this.high < 0;
640 };
641
642 /**
643 * Tests if this Long's value is positive.
644 * @returns {boolean}
645 */
646 LongPrototype.isPositive = function isPositive() {
647 return this.unsigned || this.high >= 0;
648 };
649
650 /**
651 * Tests if this Long's value is odd.
652 * @returns {boolean}
653 */
654 LongPrototype.isOdd = function isOdd() {
655 return (this.low & 1) === 1;
656 };
657
658 /**
659 * Tests if this Long's value is even.
660 * @returns {boolean}
661 */
662 LongPrototype.isEven = function isEven() {
663 return (this.low & 1) === 0;
664 };
665
666 /**
667 * Tests if this Long's value equals the specified's.
668 * @param {!Long|number|string} other Other value
669 * @returns {boolean}
670 */
671 LongPrototype.equals = function equals(other) {
672 if (!isLong(other))
673 other = fromValue(other);
674 if (this.unsigned !== other.unsigned && (this.high >>> 31) === 1 && (other.high >>> 31) === 1)
675 return false;
676 return this.high === other.high && this.low === other.low;
677 };
678
679 /**
680 * Tests if this Long's value equals the specified's. This is an alias of {@link Long#equals}.
681 * @function
682 * @param {!Long|number|string} other Other value
683 * @returns {boolean}
684 */
685 LongPrototype.eq = LongPrototype.equals;
686
687 /**
688 * Tests if this Long's value differs from the specified's.
689 * @param {!Long|number|string} other Other value
690 * @returns {boolean}
691 */
692 LongPrototype.notEquals = function notEquals(other) {
693 return !this.eq(/* validates */ other);
694 };
695
696 /**
697 * Tests if this Long's value differs from the specified's. This is an alias of {@link Long#notEquals}.
698 * @function
699 * @param {!Long|number|string} other Other value
700 * @returns {boolean}
701 */
702 LongPrototype.neq = LongPrototype.notEquals;
703
704 /**
705 * Tests if this Long's value is less than the specified's.
706 * @param {!Long|number|string} other Other value
707 * @returns {boolean}
708 */
709 LongPrototype.lessThan = function lessThan(other) {
710 return this.comp(/* validates */ other) < 0;
711 };
712
713 /**
714 * Tests if this Long's value is less than the specified's. This is an alias of {@link Long#lessThan}.
715 * @function
716 * @param {!Long|number|string} other Other value
717 * @returns {boolean}
718 */
719 LongPrototype.lt = LongPrototype.lessThan;
720
721 /**
722 * Tests if this Long's value is less than or equal the specified's.
723 * @param {!Long|number|string} other Other value
724 * @returns {boolean}
725 */
726 LongPrototype.lessThanOrEqual = function lessThanOrEqual(other) {
727 return this.comp(/* validates */ other) <= 0;
728 };
729
730 /**
731 * Tests if this Long's value is less than or equal the specified's. This is an alias of {@link Long#lessThanOrEqual}.
732 * @function
733 * @param {!Long|number|string} other Other value
734 * @returns {boolean}
735 */
736 LongPrototype.lte = LongPrototype.lessThanOrEqual;
737
738 /**
739 * Tests if this Long's value is greater than the specified's.
740 * @param {!Long|number|string} other Other value
741 * @returns {boolean}
742 */
743 LongPrototype.greaterThan = function greaterThan(other) {
744 return this.comp(/* validates */ other) > 0;
745 };
746
747 /**
748 * Tests if this Long's value is greater than the specified's. This is an alias of {@link Long#greaterThan}.
749 * @function
750 * @param {!Long|number|string} other Other value
751 * @returns {boolean}
752 */
753 LongPrototype.gt = LongPrototype.greaterThan;
754
755 /**
756 * Tests if this Long's value is greater than or equal the specified's.
757 * @param {!Long|number|string} other Other value
758 * @returns {boolean}
759 */
760 LongPrototype.greaterThanOrEqual = function greaterThanOrEqual(other) {
761 return this.comp(/* validates */ other) >= 0;
762 };
763
764 /**
765 * Tests if this Long's value is greater than or equal the specified's. This is an alias of {@link Long#greaterThanOrEqual}.
766 * @function
767 * @param {!Long|number|string} other Other value
768 * @returns {boolean}
769 */
770 LongPrototype.gte = LongPrototype.greaterThanOrEqual;
771
772 /**
773 * Compares this Long's value with the specified's.
774 * @param {!Long|number|string} other Other value
775 * @returns {number} 0 if they are the same, 1 if the this is greater and -1
776 * if the given one is greater
777 */
778 LongPrototype.compare = function compare(other) {
779 if (!isLong(other))
780 other = fromValue(other);
781 if (this.eq(other))
782 return 0;
783 var thisNeg = this.isNegative(),
784 otherNeg = other.isNegative();
785 if (thisNeg && !otherNeg)
786 return -1;
787 if (!thisNeg && otherNeg)
788 return 1;
789 // At this point the sign bits are the same
790 if (!this.unsigned)
791 return this.sub(other).isNegative() ? -1 : 1;
792 // Both are positive if at least one is unsigned
793 return (other.high >>> 0) > (this.high >>> 0) || (other.high === this.high && (other.low >>> 0) > (this.low >>> 0)) ? -1 : 1;
794 };
795
796 /**
797 * Compares this Long's value with the specified's. This is an alias of {@link Long#compare}.
798 * @function
799 * @param {!Long|number|string} other Other value
800 * @returns {number} 0 if they are the same, 1 if the this is greater and -1
801 * if the given one is greater
802 */
803 LongPrototype.comp = LongPrototype.compare;
804
805 /**
806 * Negates this Long's value.
807 * @returns {!Long} Negated Long
808 */
809 LongPrototype.negate = function negate() {
810 if (!this.unsigned && this.eq(MIN_VALUE))
811 return MIN_VALUE;
812 return this.not().add(ONE);
813 };
814
815 /**
816 * Negates this Long's value. This is an alias of {@link Long#negate}.
817 * @function
818 * @returns {!Long} Negated Long
819 */
820 LongPrototype.neg = LongPrototype.negate;
821
822 /**
823 * Returns the sum of this and the specified Long.
824 * @param {!Long|number|string} addend Addend
825 * @returns {!Long} Sum
826 */
827 LongPrototype.add = function add(addend) {
828 if (!isLong(addend))
829 addend = fromValue(addend);
830
831 // Divide each number into 4 chunks of 16 bits, and then sum the chunks.
832
833 var a48 = this.high >>> 16;
834 var a32 = this.high & 0xFFFF;
835 var a16 = this.low >>> 16;
836 var a00 = this.low & 0xFFFF;
837
838 var b48 = addend.high >>> 16;
839 var b32 = addend.high & 0xFFFF;
840 var b16 = addend.low >>> 16;
841 var b00 = addend.low & 0xFFFF;
842
843 var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
844 c00 += a00 + b00;
845 c16 += c00 >>> 16;
846 c00 &= 0xFFFF;
847 c16 += a16 + b16;
848 c32 += c16 >>> 16;
849 c16 &= 0xFFFF;
850 c32 += a32 + b32;
851 c48 += c32 >>> 16;
852 c32 &= 0xFFFF;
853 c48 += a48 + b48;
854 c48 &= 0xFFFF;
855 return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
856 };
857
858 /**
859 * Returns the difference of this and the specified Long.
860 * @param {!Long|number|string} subtrahend Subtrahend
861 * @returns {!Long} Difference
862 */
863 LongPrototype.subtract = function subtract(subtrahend) {
864 if (!isLong(subtrahend))
865 subtrahend = fromValue(subtrahend);
866 return this.add(subtrahend.neg());
867 };
868
869 /**
870 * Returns the difference of this and the specified Long. This is an alias of {@link Long#subtract}.
871 * @function
872 * @param {!Long|number|string} subtrahend Subtrahend
873 * @returns {!Long} Difference
874 */
875 LongPrototype.sub = LongPrototype.subtract;
876
877 /**
878 * Returns the product of this and the specified Long.
879 * @param {!Long|number|string} multiplier Multiplier
880 * @returns {!Long} Product
881 */
882 LongPrototype.multiply = function multiply(multiplier) {
883 if (this.isZero())
884 return ZERO;
885 if (!isLong(multiplier))
886 multiplier = fromValue(multiplier);
887 if (multiplier.isZero())
888 return ZERO;
889 if (this.eq(MIN_VALUE))
890 return multiplier.isOdd() ? MIN_VALUE : ZERO;
891 if (multiplier.eq(MIN_VALUE))
892 return this.isOdd() ? MIN_VALUE : ZERO;
893
894 if (this.isNegative()) {
895 if (multiplier.isNegative())
896 return this.neg().mul(multiplier.neg());
897 else
898 return this.neg().mul(multiplier).neg();
899 } else if (multiplier.isNegative())
900 return this.mul(multiplier.neg()).neg();
901
902 // If both longs are small, use float multiplication
903 if (this.lt(TWO_PWR_24) && multiplier.lt(TWO_PWR_24))
904 return fromNumber(this.toNumber() * multiplier.toNumber(), this.unsigned);
905
906 // Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
907 // We can skip products that would overflow.
908
909 var a48 = this.high >>> 16;
910 var a32 = this.high & 0xFFFF;
911 var a16 = this.low >>> 16;
912 var a00 = this.low & 0xFFFF;
913
914 var b48 = multiplier.high >>> 16;
915 var b32 = multiplier.high & 0xFFFF;
916 var b16 = multiplier.low >>> 16;
917 var b00 = multiplier.low & 0xFFFF;
918
919 var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
920 c00 += a00 * b00;
921 c16 += c00 >>> 16;
922 c00 &= 0xFFFF;
923 c16 += a16 * b00;
924 c32 += c16 >>> 16;
925 c16 &= 0xFFFF;
926 c16 += a00 * b16;
927 c32 += c16 >>> 16;
928 c16 &= 0xFFFF;
929 c32 += a32 * b00;
930 c48 += c32 >>> 16;
931 c32 &= 0xFFFF;
932 c32 += a16 * b16;
933 c48 += c32 >>> 16;
934 c32 &= 0xFFFF;
935 c32 += a00 * b32;
936 c48 += c32 >>> 16;
937 c32 &= 0xFFFF;
938 c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
939 c48 &= 0xFFFF;
940 return fromBits((c16 << 16) | c00, (c48 << 16) | c32, this.unsigned);
941 };
942
943 /**
944 * Returns the product of this and the specified Long. This is an alias of {@link Long#multiply}.
945 * @function
946 * @param {!Long|number|string} multiplier Multiplier
947 * @returns {!Long} Product
948 */
949 LongPrototype.mul = LongPrototype.multiply;
950
951 /**
952 * Returns this Long divided by the specified. The result is signed if this Long is signed or
953 * unsigned if this Long is unsigned.
954 * @param {!Long|number|string} divisor Divisor
955 * @returns {!Long} Quotient
956 */
957 LongPrototype.divide = function divide(divisor) {
958 if (!isLong(divisor))
959 divisor = fromValue(divisor);
960 if (divisor.isZero())
961 throw Error('division by zero');
962 if (this.isZero())
963 return this.unsigned ? UZERO : ZERO;
964 var approx, rem, res;
965 if (!this.unsigned) {
966 // This section is only relevant for signed longs and is derived from the
967 // closure library as a whole.
968 if (this.eq(MIN_VALUE)) {
969 if (divisor.eq(ONE) || divisor.eq(NEG_ONE))
970 return MIN_VALUE; // recall that -MIN_VALUE == MIN_VALUE
971 else if (divisor.eq(MIN_VALUE))
972 return ONE;
973 else {
974 // At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
975 var halfThis = this.shr(1);
976 approx = halfThis.div(divisor).shl(1);
977 if (approx.eq(ZERO)) {
978 return divisor.isNegative() ? ONE : NEG_ONE;
979 } else {
980 rem = this.sub(divisor.mul(approx));
981 res = approx.add(rem.div(divisor));
982 return res;
983 }
984 }
985 } else if (divisor.eq(MIN_VALUE))
986 return this.unsigned ? UZERO : ZERO;
987 if (this.isNegative()) {
988 if (divisor.isNegative())
989 return this.neg().div(divisor.neg());
990 return this.neg().div(divisor).neg();
991 } else if (divisor.isNegative())
992 return this.div(divisor.neg()).neg();
993 res = ZERO;
994 } else {
995 // The algorithm below has not been made for unsigned longs. It's therefore
996 // required to take special care of the MSB prior to running it.
997 if (!divisor.unsigned)
998 divisor = divisor.toUnsigned();
999 if (divisor.gt(this))
1000 return UZERO;
1001 if (divisor.gt(this.shru(1))) // 15 >>> 1 = 7 ; with divisor = 8 ; true
1002 return UONE;
1003 res = UZERO;
1004 }
1005
1006 // Repeat the following until the remainder is less than other: find a
1007 // floating-point that approximates remainder / other *from below*, add this
1008 // into the result, and subtract it from the remainder. It is critical that
1009 // the approximate value is less than or equal to the real value so that the
1010 // remainder never becomes negative.
1011 rem = this;
1012 while (rem.gte(divisor)) {
1013 // Approximate the result of division. This may be a little greater or
1014 // smaller than the actual value.
1015 approx = Math.max(1, Math.floor(rem.toNumber() / divisor.toNumber()));
1016
1017 // We will tweak the approximate result by changing it in the 48-th digit or
1018 // the smallest non-fractional digit, whichever is larger.
1019 var log2 = Math.ceil(Math.log(approx) / Math.LN2),
1020 delta = (log2 <= 48) ? 1 : pow_dbl(2, log2 - 48),
1021
1022 // Decrease the approximation until it is smaller than the remainder. Note
1023 // that if it is too large, the product overflows and is negative.
1024 approxRes = fromNumber(approx),
1025 approxRem = approxRes.mul(divisor);
1026 while (approxRem.isNegative() || approxRem.gt(rem)) {
1027 approx -= delta;
1028 approxRes = fromNumber(approx, this.unsigned);
1029 approxRem = approxRes.mul(divisor);
1030 }
1031
1032 // We know the answer can't be zero... and actually, zero would cause
1033 // infinite recursion since we would make no progress.
1034 if (approxRes.isZero())
1035 approxRes = ONE;
1036
1037 res = res.add(approxRes);
1038 rem = rem.sub(approxRem);
1039 }
1040 return res;
1041 };
1042
1043 /**
1044 * Returns this Long divided by the specified. This is an alias of {@link Long#divide}.
1045 * @function
1046 * @param {!Long|number|string} divisor Divisor
1047 * @returns {!Long} Quotient
1048 */
1049 LongPrototype.div = LongPrototype.divide;
1050
1051 /**
1052 * Returns this Long modulo the specified.
1053 * @param {!Long|number|string} divisor Divisor
1054 * @returns {!Long} Remainder
1055 */
1056 LongPrototype.modulo = function modulo(divisor) {
1057 if (!isLong(divisor))
1058 divisor = fromValue(divisor);
1059 return this.sub(this.div(divisor).mul(divisor));
1060 };
1061
1062 /**
1063 * Returns this Long modulo the specified. This is an alias of {@link Long#modulo}.
1064 * @function
1065 * @param {!Long|number|string} divisor Divisor
1066 * @returns {!Long} Remainder
1067 */
1068 LongPrototype.mod = LongPrototype.modulo;
1069
1070 /**
1071 * Returns the bitwise NOT of this Long.
1072 * @returns {!Long}
1073 */
1074 LongPrototype.not = function not() {
1075 return fromBits(~this.low, ~this.high, this.unsigned);
1076 };
1077
1078 /**
1079 * Returns the bitwise AND of this Long and the specified.
1080 * @param {!Long|number|string} other Other Long
1081 * @returns {!Long}
1082 */
1083 LongPrototype.and = function and(other) {
1084 if (!isLong(other))
1085 other = fromValue(other);
1086 return fromBits(this.low & other.low, this.high & other.high, this.unsigned);
1087 };
1088
1089 /**
1090 * Returns the bitwise OR of this Long and the specified.
1091 * @param {!Long|number|string} other Other Long
1092 * @returns {!Long}
1093 */
1094 LongPrototype.or = function or(other) {
1095 if (!isLong(other))
1096 other = fromValue(other);
1097 return fromBits(this.low | other.low, this.high | other.high, this.unsigned);
1098 };
1099
1100 /**
1101 * Returns the bitwise XOR of this Long and the given one.
1102 * @param {!Long|number|string} other Other Long
1103 * @returns {!Long}
1104 */
1105 LongPrototype.xor = function xor(other) {
1106 if (!isLong(other))
1107 other = fromValue(other);
1108 return fromBits(this.low ^ other.low, this.high ^ other.high, this.unsigned);
1109 };
1110
1111 /**
1112 * Returns this Long with bits shifted to the left by the given amount.
1113 * @param {number|!Long} numBits Number of bits
1114 * @returns {!Long} Shifted Long
1115 */
1116 LongPrototype.shiftLeft = function shiftLeft(numBits) {
1117 if (isLong(numBits))
1118 numBits = numBits.toInt();
1119 if ((numBits &= 63) === 0)
1120 return this;
1121 else if (numBits < 32)
1122 return fromBits(this.low << numBits, (this.high << numBits) | (this.low >>> (32 - numBits)), this.unsigned);
1123 else
1124 return fromBits(0, this.low << (numBits - 32), this.unsigned);
1125 };
1126
1127 /**
1128 * Returns this Long with bits shifted to the left by the given amount. This is an alias of {@link Long#shiftLeft}.
1129 * @function
1130 * @param {number|!Long} numBits Number of bits
1131 * @returns {!Long} Shifted Long
1132 */
1133 LongPrototype.shl = LongPrototype.shiftLeft;
1134
1135 /**
1136 * Returns this Long with bits arithmetically shifted to the right by the given amount.
1137 * @param {number|!Long} numBits Number of bits
1138 * @returns {!Long} Shifted Long
1139 */
1140 LongPrototype.shiftRight = function shiftRight(numBits) {
1141 if (isLong(numBits))
1142 numBits = numBits.toInt();
1143 if ((numBits &= 63) === 0)
1144 return this;
1145 else if (numBits < 32)
1146 return fromBits((this.low >>> numBits) | (this.high << (32 - numBits)), this.high >> numBits, this.unsigned);
1147 else
1148 return fromBits(this.high >> (numBits - 32), this.high >= 0 ? 0 : -1, this.unsigned);
1149 };
1150
1151 /**
1152 * Returns this Long with bits arithmetically shifted to the right by the given amount. This is an alias of {@link Long#shiftRight}.
1153 * @function
1154 * @param {number|!Long} numBits Number of bits
1155 * @returns {!Long} Shifted Long
1156 */
1157 LongPrototype.shr = LongPrototype.shiftRight;
1158
1159 /**
1160 * Returns this Long with bits logically shifted to the right by the given amount.
1161 * @param {number|!Long} numBits Number of bits
1162 * @returns {!Long} Shifted Long
1163 */
1164 LongPrototype.shiftRightUnsigned = function shiftRightUnsigned(numBits) {
1165 if (isLong(numBits))
1166 numBits = numBits.toInt();
1167 numBits &= 63;
1168 if (numBits === 0)
1169 return this;
1170 else {
1171 var high = this.high;
1172 if (numBits < 32) {
1173 var low = this.low;
1174 return fromBits((low >>> numBits) | (high << (32 - numBits)), high >>> numBits, this.unsigned);
1175 } else if (numBits === 32)
1176 return fromBits(high, 0, this.unsigned);
1177 else
1178 return fromBits(high >>> (numBits - 32), 0, this.unsigned);
1179 }
1180 };
1181
1182 /**
1183 * Returns this Long with bits logically shifted to the right by the given amount. This is an alias of {@link Long#shiftRightUnsigned}.
1184 * @function
1185 * @param {number|!Long} numBits Number of bits
1186 * @returns {!Long} Shifted Long
1187 */
1188 LongPrototype.shru = LongPrototype.shiftRightUnsigned;
1189
1190 /**
1191 * Converts this Long to signed.
1192 * @returns {!Long} Signed long
1193 */
1194 LongPrototype.toSigned = function toSigned() {
1195 if (!this.unsigned)
1196 return this;
1197 return fromBits(this.low, this.high, false);
1198 };
1199
1200 /**
1201 * Converts this Long to unsigned.
1202 * @returns {!Long} Unsigned long
1203 */
1204 LongPrototype.toUnsigned = function toUnsigned() {
1205 if (this.unsigned)
1206 return this;
1207 return fromBits(this.low, this.high, true);
1208 };
1209
1210 /**
1211 * Converts this Long to its byte representation.
1212 * @param {boolean=} le Whether little or big endian, defaults to big endian
1213 * @returns {!Array.<number>} Byte representation
1214 */
1215 LongPrototype.toBytes = function(le) {
1216 return le ? this.toBytesLE() : this.toBytesBE();
1217 };
1218
1219 /**
1220 * Converts this Long to its little endian byte representation.
1221 * @returns {!Array.<number>} Little endian byte representation
1222 */
1223 LongPrototype.toBytesLE = function() {
1224 var hi = this.high,
1225 lo = this.low;
1226 return [
1227 lo & 0xff,
1228 (lo >>> 8) & 0xff,
1229 (lo >>> 16) & 0xff,
1230 (lo >>> 24) & 0xff,
1231 hi & 0xff,
1232 (hi >>> 8) & 0xff,
1233 (hi >>> 16) & 0xff,
1234 (hi >>> 24) & 0xff
1235 ];
1236 };
1237
1238 /**
1239 * Converts this Long to its big endian byte representation.
1240 * @returns {!Array.<number>} Big endian byte representation
1241 */
1242 LongPrototype.toBytesBE = function() {
1243 var hi = this.high,
1244 lo = this.low;
1245 return [
1246 (hi >>> 24) & 0xff,
1247 (hi >>> 16) & 0xff,
1248 (hi >>> 8) & 0xff,
1249 hi & 0xff,
1250 (lo >>> 24) & 0xff,
1251 (lo >>> 16) & 0xff,
1252 (lo >>> 8) & 0xff,
1253 lo & 0xff
1254 ];
1255 };
1256
1257 return Long;
1258 });
1259 });
1260
1261 var bytebuffer = createCommonjsModule(function (module) {
1262 /*
1263 Copyright 2013-2014 Daniel Wirtz <dcode@dcode.io>
1264
1265 Licensed under the Apache License, Version 2.0 (the "License");
1266 you may not use this file except in compliance with the License.
1267 You may obtain a copy of the License at
1268
1269 http://www.apache.org/licenses/LICENSE-2.0
1270
1271 Unless required by applicable law or agreed to in writing, software
1272 distributed under the License is distributed on an "AS IS" BASIS,
1273 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1274 See the License for the specific language governing permissions and
1275 limitations under the License.
1276 */
1277
1278 /**
1279 * @license bytebuffer.js (c) 2015 Daniel Wirtz <dcode@dcode.io>
1280 * Backing buffer: ArrayBuffer, Accessor: Uint8Array
1281 * Released under the Apache License, Version 2.0
1282 * see: https://github.com/dcodeIO/bytebuffer.js for details
1283 */
1284 (function(global, factory) {
1285
1286 /* AMD */ if (typeof commonjsRequire === 'function' && 'object' === "object" && module && module["exports"])
1287 module['exports'] = (function() {
1288 var Long; try { Long = long_1; } catch (e) {}
1289 return factory(Long);
1290 })();
1291 /* Global */ else
1292 (global["dcodeIO"] = global["dcodeIO"] || {})["ByteBuffer"] = factory(global["dcodeIO"]["Long"]);
1293
1294 })(commonjsGlobal, function(Long) {
1295
1296 /**
1297 * Constructs a new ByteBuffer.
1298 * @class The swiss army knife for binary data in JavaScript.
1299 * @exports ByteBuffer
1300 * @constructor
1301 * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
1302 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
1303 * {@link ByteBuffer.DEFAULT_ENDIAN}.
1304 * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
1305 * {@link ByteBuffer.DEFAULT_NOASSERT}.
1306 * @expose
1307 */
1308 var ByteBuffer = function(capacity, littleEndian, noAssert) {
1309 if (typeof capacity === 'undefined')
1310 capacity = ByteBuffer.DEFAULT_CAPACITY;
1311 if (typeof littleEndian === 'undefined')
1312 littleEndian = ByteBuffer.DEFAULT_ENDIAN;
1313 if (typeof noAssert === 'undefined')
1314 noAssert = ByteBuffer.DEFAULT_NOASSERT;
1315 if (!noAssert) {
1316 capacity = capacity | 0;
1317 if (capacity < 0)
1318 throw RangeError("Illegal capacity");
1319 littleEndian = !!littleEndian;
1320 noAssert = !!noAssert;
1321 }
1322
1323 /**
1324 * Backing ArrayBuffer.
1325 * @type {!ArrayBuffer}
1326 * @expose
1327 */
1328 this.buffer = capacity === 0 ? EMPTY_BUFFER : new ArrayBuffer(capacity);
1329
1330 /**
1331 * Uint8Array utilized to manipulate the backing buffer. Becomes `null` if the backing buffer has a capacity of `0`.
1332 * @type {?Uint8Array}
1333 * @expose
1334 */
1335 this.view = capacity === 0 ? null : new Uint8Array(this.buffer);
1336
1337 /**
1338 * Absolute read/write offset.
1339 * @type {number}
1340 * @expose
1341 * @see ByteBuffer#flip
1342 * @see ByteBuffer#clear
1343 */
1344 this.offset = 0;
1345
1346 /**
1347 * Marked offset.
1348 * @type {number}
1349 * @expose
1350 * @see ByteBuffer#mark
1351 * @see ByteBuffer#reset
1352 */
1353 this.markedOffset = -1;
1354
1355 /**
1356 * Absolute limit of the contained data. Set to the backing buffer's capacity upon allocation.
1357 * @type {number}
1358 * @expose
1359 * @see ByteBuffer#flip
1360 * @see ByteBuffer#clear
1361 */
1362 this.limit = capacity;
1363
1364 /**
1365 * Whether to use little endian byte order, defaults to `false` for big endian.
1366 * @type {boolean}
1367 * @expose
1368 */
1369 this.littleEndian = littleEndian;
1370
1371 /**
1372 * Whether to skip assertions of offsets and values, defaults to `false`.
1373 * @type {boolean}
1374 * @expose
1375 */
1376 this.noAssert = noAssert;
1377 };
1378
1379 /**
1380 * ByteBuffer version.
1381 * @type {string}
1382 * @const
1383 * @expose
1384 */
1385 ByteBuffer.VERSION = "5.0.1";
1386
1387 /**
1388 * Little endian constant that can be used instead of its boolean value. Evaluates to `true`.
1389 * @type {boolean}
1390 * @const
1391 * @expose
1392 */
1393 ByteBuffer.LITTLE_ENDIAN = true;
1394
1395 /**
1396 * Big endian constant that can be used instead of its boolean value. Evaluates to `false`.
1397 * @type {boolean}
1398 * @const
1399 * @expose
1400 */
1401 ByteBuffer.BIG_ENDIAN = false;
1402
1403 /**
1404 * Default initial capacity of `16`.
1405 * @type {number}
1406 * @expose
1407 */
1408 ByteBuffer.DEFAULT_CAPACITY = 16;
1409
1410 /**
1411 * Default endianess of `false` for big endian.
1412 * @type {boolean}
1413 * @expose
1414 */
1415 ByteBuffer.DEFAULT_ENDIAN = ByteBuffer.BIG_ENDIAN;
1416
1417 /**
1418 * Default no assertions flag of `false`.
1419 * @type {boolean}
1420 * @expose
1421 */
1422 ByteBuffer.DEFAULT_NOASSERT = false;
1423
1424 /**
1425 * A `Long` class for representing a 64-bit two's-complement integer value. May be `null` if Long.js has not been loaded
1426 * and int64 support is not available.
1427 * @type {?Long}
1428 * @const
1429 * @see https://github.com/dcodeIO/long.js
1430 * @expose
1431 */
1432 ByteBuffer.Long = Long || null;
1433
1434 /**
1435 * @alias ByteBuffer.prototype
1436 * @inner
1437 */
1438 var ByteBufferPrototype = ByteBuffer.prototype;
1439
1440 /**
1441 * An indicator used to reliably determine if an object is a ByteBuffer or not.
1442 * @type {boolean}
1443 * @const
1444 * @expose
1445 * @private
1446 */
1447 ByteBufferPrototype.__isByteBuffer__;
1448
1449 Object.defineProperty(ByteBufferPrototype, "__isByteBuffer__", {
1450 value: true,
1451 enumerable: false,
1452 configurable: false
1453 });
1454
1455 // helpers
1456
1457 /**
1458 * @type {!ArrayBuffer}
1459 * @inner
1460 */
1461 var EMPTY_BUFFER = new ArrayBuffer(0);
1462
1463 /**
1464 * String.fromCharCode reference for compile-time renaming.
1465 * @type {function(...number):string}
1466 * @inner
1467 */
1468 var stringFromCharCode = String.fromCharCode;
1469
1470 /**
1471 * Creates a source function for a string.
1472 * @param {string} s String to read from
1473 * @returns {function():number|null} Source function returning the next char code respectively `null` if there are
1474 * no more characters left.
1475 * @throws {TypeError} If the argument is invalid
1476 * @inner
1477 */
1478 function stringSource(s) {
1479 var i=0; return function() {
1480 return i < s.length ? s.charCodeAt(i++) : null;
1481 };
1482 }
1483
1484 /**
1485 * Creates a destination function for a string.
1486 * @returns {function(number=):undefined|string} Destination function successively called with the next char code.
1487 * Returns the final string when called without arguments.
1488 * @inner
1489 */
1490 function stringDestination() {
1491 var cs = [], ps = []; return function() {
1492 if (arguments.length === 0)
1493 return ps.join('')+stringFromCharCode.apply(String, cs);
1494 if (cs.length + arguments.length > 1024)
1495 ps.push(stringFromCharCode.apply(String, cs)),
1496 cs.length = 0;
1497 Array.prototype.push.apply(cs, arguments);
1498 };
1499 }
1500
1501 /**
1502 * Gets the accessor type.
1503 * @returns {Function} `Buffer` under node.js, `Uint8Array` respectively `DataView` in the browser (classes)
1504 * @expose
1505 */
1506 ByteBuffer.accessor = function() {
1507 return Uint8Array;
1508 };
1509 /**
1510 * Allocates a new ByteBuffer backed by a buffer of the specified capacity.
1511 * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
1512 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
1513 * {@link ByteBuffer.DEFAULT_ENDIAN}.
1514 * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
1515 * {@link ByteBuffer.DEFAULT_NOASSERT}.
1516 * @returns {!ByteBuffer}
1517 * @expose
1518 */
1519 ByteBuffer.allocate = function(capacity, littleEndian, noAssert) {
1520 return new ByteBuffer(capacity, littleEndian, noAssert);
1521 };
1522
1523 /**
1524 * Concatenates multiple ByteBuffers into one.
1525 * @param {!Array.<!ByteBuffer|!ArrayBuffer|!Uint8Array|string>} buffers Buffers to concatenate
1526 * @param {(string|boolean)=} encoding String encoding if `buffers` contains a string ("base64", "hex", "binary",
1527 * defaults to "utf8")
1528 * @param {boolean=} littleEndian Whether to use little or big endian byte order for the resulting ByteBuffer. Defaults
1529 * to {@link ByteBuffer.DEFAULT_ENDIAN}.
1530 * @param {boolean=} noAssert Whether to skip assertions of offsets and values for the resulting ByteBuffer. Defaults to
1531 * {@link ByteBuffer.DEFAULT_NOASSERT}.
1532 * @returns {!ByteBuffer} Concatenated ByteBuffer
1533 * @expose
1534 */
1535 ByteBuffer.concat = function(buffers, encoding, littleEndian, noAssert) {
1536 if (typeof encoding === 'boolean' || typeof encoding !== 'string') {
1537 noAssert = littleEndian;
1538 littleEndian = encoding;
1539 encoding = undefined;
1540 }
1541 var capacity = 0;
1542 for (var i=0, k=buffers.length, length; i<k; ++i) {
1543 if (!ByteBuffer.isByteBuffer(buffers[i]))
1544 buffers[i] = ByteBuffer.wrap(buffers[i], encoding);
1545 length = buffers[i].limit - buffers[i].offset;
1546 if (length > 0) capacity += length;
1547 }
1548 if (capacity === 0)
1549 return new ByteBuffer(0, littleEndian, noAssert);
1550 var bb = new ByteBuffer(capacity, littleEndian, noAssert),
1551 bi;
1552 i=0; while (i<k) {
1553 bi = buffers[i++];
1554 length = bi.limit - bi.offset;
1555 if (length <= 0) continue;
1556 bb.view.set(bi.view.subarray(bi.offset, bi.limit), bb.offset);
1557 bb.offset += length;
1558 }
1559 bb.limit = bb.offset;
1560 bb.offset = 0;
1561 return bb;
1562 };
1563
1564 /**
1565 * Tests if the specified type is a ByteBuffer.
1566 * @param {*} bb ByteBuffer to test
1567 * @returns {boolean} `true` if it is a ByteBuffer, otherwise `false`
1568 * @expose
1569 */
1570 ByteBuffer.isByteBuffer = function(bb) {
1571 return (bb && bb["__isByteBuffer__"]) === true;
1572 };
1573 /**
1574 * Gets the backing buffer type.
1575 * @returns {Function} `Buffer` under node.js, `ArrayBuffer` in the browser (classes)
1576 * @expose
1577 */
1578 ByteBuffer.type = function() {
1579 return ArrayBuffer;
1580 };
1581 /**
1582 * Wraps a buffer or a string. Sets the allocated ByteBuffer's {@link ByteBuffer#offset} to `0` and its
1583 * {@link ByteBuffer#limit} to the length of the wrapped data.
1584 * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string|!Array.<number>} buffer Anything that can be wrapped
1585 * @param {(string|boolean)=} encoding String encoding if `buffer` is a string ("base64", "hex", "binary", defaults to
1586 * "utf8")
1587 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
1588 * {@link ByteBuffer.DEFAULT_ENDIAN}.
1589 * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
1590 * {@link ByteBuffer.DEFAULT_NOASSERT}.
1591 * @returns {!ByteBuffer} A ByteBuffer wrapping `buffer`
1592 * @expose
1593 */
1594 ByteBuffer.wrap = function(buffer, encoding, littleEndian, noAssert) {
1595 if (typeof encoding !== 'string') {
1596 noAssert = littleEndian;
1597 littleEndian = encoding;
1598 encoding = undefined;
1599 }
1600 if (typeof buffer === 'string') {
1601 if (typeof encoding === 'undefined')
1602 encoding = "utf8";
1603 switch (encoding) {
1604 case "base64":
1605 return ByteBuffer.fromBase64(buffer, littleEndian);
1606 case "hex":
1607 return ByteBuffer.fromHex(buffer, littleEndian);
1608 case "binary":
1609 return ByteBuffer.fromBinary(buffer, littleEndian);
1610 case "utf8":
1611 return ByteBuffer.fromUTF8(buffer, littleEndian);
1612 case "debug":
1613 return ByteBuffer.fromDebug(buffer, littleEndian);
1614 default:
1615 throw Error("Unsupported encoding: "+encoding);
1616 }
1617 }
1618 if (buffer === null || typeof buffer !== 'object')
1619 throw TypeError("Illegal buffer");
1620 var bb;
1621 if (ByteBuffer.isByteBuffer(buffer)) {
1622 bb = ByteBufferPrototype.clone.call(buffer);
1623 bb.markedOffset = -1;
1624 return bb;
1625 }
1626 if (buffer instanceof Uint8Array) { // Extract ArrayBuffer from Uint8Array
1627 bb = new ByteBuffer(0, littleEndian, noAssert);
1628 if (buffer.length > 0) { // Avoid references to more than one EMPTY_BUFFER
1629 bb.buffer = buffer.buffer;
1630 bb.offset = buffer.byteOffset;
1631 bb.limit = buffer.byteOffset + buffer.byteLength;
1632 bb.view = new Uint8Array(buffer.buffer);
1633 }
1634 } else if (buffer instanceof ArrayBuffer) { // Reuse ArrayBuffer
1635 bb = new ByteBuffer(0, littleEndian, noAssert);
1636 if (buffer.byteLength > 0) {
1637 bb.buffer = buffer;
1638 bb.offset = 0;
1639 bb.limit = buffer.byteLength;
1640 bb.view = buffer.byteLength > 0 ? new Uint8Array(buffer) : null;
1641 }
1642 } else if (Object.prototype.toString.call(buffer) === "[object Array]") { // Create from octets
1643 bb = new ByteBuffer(buffer.length, littleEndian, noAssert);
1644 bb.limit = buffer.length;
1645 for (var i=0; i<buffer.length; ++i)
1646 bb.view[i] = buffer[i];
1647 } else
1648 throw TypeError("Illegal buffer"); // Otherwise fail
1649 return bb;
1650 };
1651
1652 /**
1653 * Writes the array as a bitset.
1654 * @param {Array<boolean>} value Array of booleans to write
1655 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
1656 * @returns {!ByteBuffer}
1657 * @expose
1658 */
1659 ByteBufferPrototype.writeBitSet = function(value, offset) {
1660 var relative = typeof offset === 'undefined';
1661 if (relative) offset = this.offset;
1662 if (!this.noAssert) {
1663 if (!(value instanceof Array))
1664 throw TypeError("Illegal BitSet: Not an array");
1665 if (typeof offset !== 'number' || offset % 1 !== 0)
1666 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1667 offset >>>= 0;
1668 if (offset < 0 || offset + 0 > this.buffer.byteLength)
1669 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
1670 }
1671
1672 var start = offset,
1673 bits = value.length,
1674 bytes = (bits >> 3),
1675 bit = 0,
1676 k;
1677
1678 offset += this.writeVarint32(bits,offset);
1679
1680 while(bytes--) {
1681 k = (!!value[bit++] & 1) |
1682 ((!!value[bit++] & 1) << 1) |
1683 ((!!value[bit++] & 1) << 2) |
1684 ((!!value[bit++] & 1) << 3) |
1685 ((!!value[bit++] & 1) << 4) |
1686 ((!!value[bit++] & 1) << 5) |
1687 ((!!value[bit++] & 1) << 6) |
1688 ((!!value[bit++] & 1) << 7);
1689 this.writeByte(k,offset++);
1690 }
1691
1692 if(bit < bits) {
1693 var m = 0; k = 0;
1694 while(bit < bits) k = k | ((!!value[bit++] & 1) << (m++));
1695 this.writeByte(k,offset++);
1696 }
1697
1698 if (relative) {
1699 this.offset = offset;
1700 return this;
1701 }
1702 return offset - start;
1703 };
1704
1705 /**
1706 * Reads a BitSet as an array of booleans.
1707 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
1708 * @returns {Array<boolean>
1709 * @expose
1710 */
1711 ByteBufferPrototype.readBitSet = function(offset) {
1712 var relative = typeof offset === 'undefined';
1713 if (relative) offset = this.offset;
1714
1715 var ret = this.readVarint32(offset),
1716 bits = ret.value,
1717 bytes = (bits >> 3),
1718 bit = 0,
1719 value = [],
1720 k;
1721
1722 offset += ret.length;
1723
1724 while(bytes--) {
1725 k = this.readByte(offset++);
1726 value[bit++] = !!(k & 0x01);
1727 value[bit++] = !!(k & 0x02);
1728 value[bit++] = !!(k & 0x04);
1729 value[bit++] = !!(k & 0x08);
1730 value[bit++] = !!(k & 0x10);
1731 value[bit++] = !!(k & 0x20);
1732 value[bit++] = !!(k & 0x40);
1733 value[bit++] = !!(k & 0x80);
1734 }
1735
1736 if(bit < bits) {
1737 var m = 0;
1738 k = this.readByte(offset++);
1739 while(bit < bits) value[bit++] = !!((k >> (m++)) & 1);
1740 }
1741
1742 if (relative) {
1743 this.offset = offset;
1744 }
1745 return value;
1746 };
1747 /**
1748 * Reads the specified number of bytes.
1749 * @param {number} length Number of bytes to read
1750 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
1751 * @returns {!ByteBuffer}
1752 * @expose
1753 */
1754 ByteBufferPrototype.readBytes = function(length, offset) {
1755 var relative = typeof offset === 'undefined';
1756 if (relative) offset = this.offset;
1757 if (!this.noAssert) {
1758 if (typeof offset !== 'number' || offset % 1 !== 0)
1759 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1760 offset >>>= 0;
1761 if (offset < 0 || offset + length > this.buffer.byteLength)
1762 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
1763 }
1764 var slice = this.slice(offset, offset + length);
1765 if (relative) this.offset += length;
1766 return slice;
1767 };
1768
1769 /**
1770 * Writes a payload of bytes. This is an alias of {@link ByteBuffer#append}.
1771 * @function
1772 * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to write. If `source` is a ByteBuffer, its offsets
1773 * will be modified according to the performed read operation.
1774 * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
1775 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
1776 * written if omitted.
1777 * @returns {!ByteBuffer} this
1778 * @expose
1779 */
1780 ByteBufferPrototype.writeBytes = ByteBufferPrototype.append;
1781
1782 // types/ints/int8
1783
1784 /**
1785 * Writes an 8bit signed integer.
1786 * @param {number} value Value to write
1787 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
1788 * @returns {!ByteBuffer} this
1789 * @expose
1790 */
1791 ByteBufferPrototype.writeInt8 = function(value, offset) {
1792 var relative = typeof offset === 'undefined';
1793 if (relative) offset = this.offset;
1794 if (!this.noAssert) {
1795 if (typeof value !== 'number' || value % 1 !== 0)
1796 throw TypeError("Illegal value: "+value+" (not an integer)");
1797 value |= 0;
1798 if (typeof offset !== 'number' || offset % 1 !== 0)
1799 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1800 offset >>>= 0;
1801 if (offset < 0 || offset + 0 > this.buffer.byteLength)
1802 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
1803 }
1804 offset += 1;
1805 var capacity0 = this.buffer.byteLength;
1806 if (offset > capacity0)
1807 this.resize((capacity0 *= 2) > offset ? capacity0 : offset);
1808 offset -= 1;
1809 this.view[offset] = value;
1810 if (relative) this.offset += 1;
1811 return this;
1812 };
1813
1814 /**
1815 * Writes an 8bit signed integer. This is an alias of {@link ByteBuffer#writeInt8}.
1816 * @function
1817 * @param {number} value Value to write
1818 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
1819 * @returns {!ByteBuffer} this
1820 * @expose
1821 */
1822 ByteBufferPrototype.writeByte = ByteBufferPrototype.writeInt8;
1823
1824 /**
1825 * Reads an 8bit signed integer.
1826 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
1827 * @returns {number} Value read
1828 * @expose
1829 */
1830 ByteBufferPrototype.readInt8 = function(offset) {
1831 var relative = typeof offset === 'undefined';
1832 if (relative) offset = this.offset;
1833 if (!this.noAssert) {
1834 if (typeof offset !== 'number' || offset % 1 !== 0)
1835 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1836 offset >>>= 0;
1837 if (offset < 0 || offset + 1 > this.buffer.byteLength)
1838 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
1839 }
1840 var value = this.view[offset];
1841 if ((value & 0x80) === 0x80) value = -(0xFF - value + 1); // Cast to signed
1842 if (relative) this.offset += 1;
1843 return value;
1844 };
1845
1846 /**
1847 * Reads an 8bit signed integer. This is an alias of {@link ByteBuffer#readInt8}.
1848 * @function
1849 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
1850 * @returns {number} Value read
1851 * @expose
1852 */
1853 ByteBufferPrototype.readByte = ByteBufferPrototype.readInt8;
1854
1855 /**
1856 * Writes an 8bit unsigned integer.
1857 * @param {number} value Value to write
1858 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
1859 * @returns {!ByteBuffer} this
1860 * @expose
1861 */
1862 ByteBufferPrototype.writeUint8 = function(value, offset) {
1863 var relative = typeof offset === 'undefined';
1864 if (relative) offset = this.offset;
1865 if (!this.noAssert) {
1866 if (typeof value !== 'number' || value % 1 !== 0)
1867 throw TypeError("Illegal value: "+value+" (not an integer)");
1868 value >>>= 0;
1869 if (typeof offset !== 'number' || offset % 1 !== 0)
1870 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1871 offset >>>= 0;
1872 if (offset < 0 || offset + 0 > this.buffer.byteLength)
1873 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
1874 }
1875 offset += 1;
1876 var capacity1 = this.buffer.byteLength;
1877 if (offset > capacity1)
1878 this.resize((capacity1 *= 2) > offset ? capacity1 : offset);
1879 offset -= 1;
1880 this.view[offset] = value;
1881 if (relative) this.offset += 1;
1882 return this;
1883 };
1884
1885 /**
1886 * Writes an 8bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint8}.
1887 * @function
1888 * @param {number} value Value to write
1889 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
1890 * @returns {!ByteBuffer} this
1891 * @expose
1892 */
1893 ByteBufferPrototype.writeUInt8 = ByteBufferPrototype.writeUint8;
1894
1895 /**
1896 * Reads an 8bit unsigned integer.
1897 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
1898 * @returns {number} Value read
1899 * @expose
1900 */
1901 ByteBufferPrototype.readUint8 = function(offset) {
1902 var relative = typeof offset === 'undefined';
1903 if (relative) offset = this.offset;
1904 if (!this.noAssert) {
1905 if (typeof offset !== 'number' || offset % 1 !== 0)
1906 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1907 offset >>>= 0;
1908 if (offset < 0 || offset + 1 > this.buffer.byteLength)
1909 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
1910 }
1911 var value = this.view[offset];
1912 if (relative) this.offset += 1;
1913 return value;
1914 };
1915
1916 /**
1917 * Reads an 8bit unsigned integer. This is an alias of {@link ByteBuffer#readUint8}.
1918 * @function
1919 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
1920 * @returns {number} Value read
1921 * @expose
1922 */
1923 ByteBufferPrototype.readUInt8 = ByteBufferPrototype.readUint8;
1924
1925 // types/ints/int16
1926
1927 /**
1928 * Writes a 16bit signed integer.
1929 * @param {number} value Value to write
1930 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
1931 * @throws {TypeError} If `offset` or `value` is not a valid number
1932 * @throws {RangeError} If `offset` is out of bounds
1933 * @expose
1934 */
1935 ByteBufferPrototype.writeInt16 = function(value, offset) {
1936 var relative = typeof offset === 'undefined';
1937 if (relative) offset = this.offset;
1938 if (!this.noAssert) {
1939 if (typeof value !== 'number' || value % 1 !== 0)
1940 throw TypeError("Illegal value: "+value+" (not an integer)");
1941 value |= 0;
1942 if (typeof offset !== 'number' || offset % 1 !== 0)
1943 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1944 offset >>>= 0;
1945 if (offset < 0 || offset + 0 > this.buffer.byteLength)
1946 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
1947 }
1948 offset += 2;
1949 var capacity2 = this.buffer.byteLength;
1950 if (offset > capacity2)
1951 this.resize((capacity2 *= 2) > offset ? capacity2 : offset);
1952 offset -= 2;
1953 if (this.littleEndian) {
1954 this.view[offset+1] = (value & 0xFF00) >>> 8;
1955 this.view[offset ] = value & 0x00FF;
1956 } else {
1957 this.view[offset] = (value & 0xFF00) >>> 8;
1958 this.view[offset+1] = value & 0x00FF;
1959 }
1960 if (relative) this.offset += 2;
1961 return this;
1962 };
1963
1964 /**
1965 * Writes a 16bit signed integer. This is an alias of {@link ByteBuffer#writeInt16}.
1966 * @function
1967 * @param {number} value Value to write
1968 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
1969 * @throws {TypeError} If `offset` or `value` is not a valid number
1970 * @throws {RangeError} If `offset` is out of bounds
1971 * @expose
1972 */
1973 ByteBufferPrototype.writeShort = ByteBufferPrototype.writeInt16;
1974
1975 /**
1976 * Reads a 16bit signed integer.
1977 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
1978 * @returns {number} Value read
1979 * @throws {TypeError} If `offset` is not a valid number
1980 * @throws {RangeError} If `offset` is out of bounds
1981 * @expose
1982 */
1983 ByteBufferPrototype.readInt16 = function(offset) {
1984 var relative = typeof offset === 'undefined';
1985 if (relative) offset = this.offset;
1986 if (!this.noAssert) {
1987 if (typeof offset !== 'number' || offset % 1 !== 0)
1988 throw TypeError("Illegal offset: "+offset+" (not an integer)");
1989 offset >>>= 0;
1990 if (offset < 0 || offset + 2 > this.buffer.byteLength)
1991 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
1992 }
1993 var value = 0;
1994 if (this.littleEndian) {
1995 value = this.view[offset ];
1996 value |= this.view[offset+1] << 8;
1997 } else {
1998 value = this.view[offset ] << 8;
1999 value |= this.view[offset+1];
2000 }
2001 if ((value & 0x8000) === 0x8000) value = -(0xFFFF - value + 1); // Cast to signed
2002 if (relative) this.offset += 2;
2003 return value;
2004 };
2005
2006 /**
2007 * Reads a 16bit signed integer. This is an alias of {@link ByteBuffer#readInt16}.
2008 * @function
2009 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
2010 * @returns {number} Value read
2011 * @throws {TypeError} If `offset` is not a valid number
2012 * @throws {RangeError} If `offset` is out of bounds
2013 * @expose
2014 */
2015 ByteBufferPrototype.readShort = ByteBufferPrototype.readInt16;
2016
2017 /**
2018 * Writes a 16bit unsigned integer.
2019 * @param {number} value Value to write
2020 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
2021 * @throws {TypeError} If `offset` or `value` is not a valid number
2022 * @throws {RangeError} If `offset` is out of bounds
2023 * @expose
2024 */
2025 ByteBufferPrototype.writeUint16 = function(value, offset) {
2026 var relative = typeof offset === 'undefined';
2027 if (relative) offset = this.offset;
2028 if (!this.noAssert) {
2029 if (typeof value !== 'number' || value % 1 !== 0)
2030 throw TypeError("Illegal value: "+value+" (not an integer)");
2031 value >>>= 0;
2032 if (typeof offset !== 'number' || offset % 1 !== 0)
2033 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2034 offset >>>= 0;
2035 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2036 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2037 }
2038 offset += 2;
2039 var capacity3 = this.buffer.byteLength;
2040 if (offset > capacity3)
2041 this.resize((capacity3 *= 2) > offset ? capacity3 : offset);
2042 offset -= 2;
2043 if (this.littleEndian) {
2044 this.view[offset+1] = (value & 0xFF00) >>> 8;
2045 this.view[offset ] = value & 0x00FF;
2046 } else {
2047 this.view[offset] = (value & 0xFF00) >>> 8;
2048 this.view[offset+1] = value & 0x00FF;
2049 }
2050 if (relative) this.offset += 2;
2051 return this;
2052 };
2053
2054 /**
2055 * Writes a 16bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint16}.
2056 * @function
2057 * @param {number} value Value to write
2058 * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
2059 * @throws {TypeError} If `offset` or `value` is not a valid number
2060 * @throws {RangeError} If `offset` is out of bounds
2061 * @expose
2062 */
2063 ByteBufferPrototype.writeUInt16 = ByteBufferPrototype.writeUint16;
2064
2065 /**
2066 * Reads a 16bit unsigned integer.
2067 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
2068 * @returns {number} Value read
2069 * @throws {TypeError} If `offset` is not a valid number
2070 * @throws {RangeError} If `offset` is out of bounds
2071 * @expose
2072 */
2073 ByteBufferPrototype.readUint16 = function(offset) {
2074 var relative = typeof offset === 'undefined';
2075 if (relative) offset = this.offset;
2076 if (!this.noAssert) {
2077 if (typeof offset !== 'number' || offset % 1 !== 0)
2078 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2079 offset >>>= 0;
2080 if (offset < 0 || offset + 2 > this.buffer.byteLength)
2081 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+2+") <= "+this.buffer.byteLength);
2082 }
2083 var value = 0;
2084 if (this.littleEndian) {
2085 value = this.view[offset ];
2086 value |= this.view[offset+1] << 8;
2087 } else {
2088 value = this.view[offset ] << 8;
2089 value |= this.view[offset+1];
2090 }
2091 if (relative) this.offset += 2;
2092 return value;
2093 };
2094
2095 /**
2096 * Reads a 16bit unsigned integer. This is an alias of {@link ByteBuffer#readUint16}.
2097 * @function
2098 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
2099 * @returns {number} Value read
2100 * @throws {TypeError} If `offset` is not a valid number
2101 * @throws {RangeError} If `offset` is out of bounds
2102 * @expose
2103 */
2104 ByteBufferPrototype.readUInt16 = ByteBufferPrototype.readUint16;
2105
2106 // types/ints/int32
2107
2108 /**
2109 * Writes a 32bit signed integer.
2110 * @param {number} value Value to write
2111 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2112 * @expose
2113 */
2114 ByteBufferPrototype.writeInt32 = function(value, offset) {
2115 var relative = typeof offset === 'undefined';
2116 if (relative) offset = this.offset;
2117 if (!this.noAssert) {
2118 if (typeof value !== 'number' || value % 1 !== 0)
2119 throw TypeError("Illegal value: "+value+" (not an integer)");
2120 value |= 0;
2121 if (typeof offset !== 'number' || offset % 1 !== 0)
2122 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2123 offset >>>= 0;
2124 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2125 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2126 }
2127 offset += 4;
2128 var capacity4 = this.buffer.byteLength;
2129 if (offset > capacity4)
2130 this.resize((capacity4 *= 2) > offset ? capacity4 : offset);
2131 offset -= 4;
2132 if (this.littleEndian) {
2133 this.view[offset+3] = (value >>> 24) & 0xFF;
2134 this.view[offset+2] = (value >>> 16) & 0xFF;
2135 this.view[offset+1] = (value >>> 8) & 0xFF;
2136 this.view[offset ] = value & 0xFF;
2137 } else {
2138 this.view[offset ] = (value >>> 24) & 0xFF;
2139 this.view[offset+1] = (value >>> 16) & 0xFF;
2140 this.view[offset+2] = (value >>> 8) & 0xFF;
2141 this.view[offset+3] = value & 0xFF;
2142 }
2143 if (relative) this.offset += 4;
2144 return this;
2145 };
2146
2147 /**
2148 * Writes a 32bit signed integer. This is an alias of {@link ByteBuffer#writeInt32}.
2149 * @param {number} value Value to write
2150 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2151 * @expose
2152 */
2153 ByteBufferPrototype.writeInt = ByteBufferPrototype.writeInt32;
2154
2155 /**
2156 * Reads a 32bit signed integer.
2157 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2158 * @returns {number} Value read
2159 * @expose
2160 */
2161 ByteBufferPrototype.readInt32 = function(offset) {
2162 var relative = typeof offset === 'undefined';
2163 if (relative) offset = this.offset;
2164 if (!this.noAssert) {
2165 if (typeof offset !== 'number' || offset % 1 !== 0)
2166 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2167 offset >>>= 0;
2168 if (offset < 0 || offset + 4 > this.buffer.byteLength)
2169 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
2170 }
2171 var value = 0;
2172 if (this.littleEndian) {
2173 value = this.view[offset+2] << 16;
2174 value |= this.view[offset+1] << 8;
2175 value |= this.view[offset ];
2176 value += this.view[offset+3] << 24 >>> 0;
2177 } else {
2178 value = this.view[offset+1] << 16;
2179 value |= this.view[offset+2] << 8;
2180 value |= this.view[offset+3];
2181 value += this.view[offset ] << 24 >>> 0;
2182 }
2183 value |= 0; // Cast to signed
2184 if (relative) this.offset += 4;
2185 return value;
2186 };
2187
2188 /**
2189 * Reads a 32bit signed integer. This is an alias of {@link ByteBuffer#readInt32}.
2190 * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `4` if omitted.
2191 * @returns {number} Value read
2192 * @expose
2193 */
2194 ByteBufferPrototype.readInt = ByteBufferPrototype.readInt32;
2195
2196 /**
2197 * Writes a 32bit unsigned integer.
2198 * @param {number} value Value to write
2199 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2200 * @expose
2201 */
2202 ByteBufferPrototype.writeUint32 = function(value, offset) {
2203 var relative = typeof offset === 'undefined';
2204 if (relative) offset = this.offset;
2205 if (!this.noAssert) {
2206 if (typeof value !== 'number' || value % 1 !== 0)
2207 throw TypeError("Illegal value: "+value+" (not an integer)");
2208 value >>>= 0;
2209 if (typeof offset !== 'number' || offset % 1 !== 0)
2210 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2211 offset >>>= 0;
2212 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2213 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2214 }
2215 offset += 4;
2216 var capacity5 = this.buffer.byteLength;
2217 if (offset > capacity5)
2218 this.resize((capacity5 *= 2) > offset ? capacity5 : offset);
2219 offset -= 4;
2220 if (this.littleEndian) {
2221 this.view[offset+3] = (value >>> 24) & 0xFF;
2222 this.view[offset+2] = (value >>> 16) & 0xFF;
2223 this.view[offset+1] = (value >>> 8) & 0xFF;
2224 this.view[offset ] = value & 0xFF;
2225 } else {
2226 this.view[offset ] = (value >>> 24) & 0xFF;
2227 this.view[offset+1] = (value >>> 16) & 0xFF;
2228 this.view[offset+2] = (value >>> 8) & 0xFF;
2229 this.view[offset+3] = value & 0xFF;
2230 }
2231 if (relative) this.offset += 4;
2232 return this;
2233 };
2234
2235 /**
2236 * Writes a 32bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint32}.
2237 * @function
2238 * @param {number} value Value to write
2239 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2240 * @expose
2241 */
2242 ByteBufferPrototype.writeUInt32 = ByteBufferPrototype.writeUint32;
2243
2244 /**
2245 * Reads a 32bit unsigned integer.
2246 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2247 * @returns {number} Value read
2248 * @expose
2249 */
2250 ByteBufferPrototype.readUint32 = function(offset) {
2251 var relative = typeof offset === 'undefined';
2252 if (relative) offset = this.offset;
2253 if (!this.noAssert) {
2254 if (typeof offset !== 'number' || offset % 1 !== 0)
2255 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2256 offset >>>= 0;
2257 if (offset < 0 || offset + 4 > this.buffer.byteLength)
2258 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
2259 }
2260 var value = 0;
2261 if (this.littleEndian) {
2262 value = this.view[offset+2] << 16;
2263 value |= this.view[offset+1] << 8;
2264 value |= this.view[offset ];
2265 value += this.view[offset+3] << 24 >>> 0;
2266 } else {
2267 value = this.view[offset+1] << 16;
2268 value |= this.view[offset+2] << 8;
2269 value |= this.view[offset+3];
2270 value += this.view[offset ] << 24 >>> 0;
2271 }
2272 if (relative) this.offset += 4;
2273 return value;
2274 };
2275
2276 /**
2277 * Reads a 32bit unsigned integer. This is an alias of {@link ByteBuffer#readUint32}.
2278 * @function
2279 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2280 * @returns {number} Value read
2281 * @expose
2282 */
2283 ByteBufferPrototype.readUInt32 = ByteBufferPrototype.readUint32;
2284
2285 // types/ints/int64
2286
2287 if (Long) {
2288
2289 /**
2290 * Writes a 64bit signed integer.
2291 * @param {number|!Long} value Value to write
2292 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2293 * @returns {!ByteBuffer} this
2294 * @expose
2295 */
2296 ByteBufferPrototype.writeInt64 = function(value, offset) {
2297 var relative = typeof offset === 'undefined';
2298 if (relative) offset = this.offset;
2299 if (!this.noAssert) {
2300 if (typeof value === 'number')
2301 value = Long.fromNumber(value);
2302 else if (typeof value === 'string')
2303 value = Long.fromString(value);
2304 else if (!(value && value instanceof Long))
2305 throw TypeError("Illegal value: "+value+" (not an integer or Long)");
2306 if (typeof offset !== 'number' || offset % 1 !== 0)
2307 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2308 offset >>>= 0;
2309 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2310 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2311 }
2312 if (typeof value === 'number')
2313 value = Long.fromNumber(value);
2314 else if (typeof value === 'string')
2315 value = Long.fromString(value);
2316 offset += 8;
2317 var capacity6 = this.buffer.byteLength;
2318 if (offset > capacity6)
2319 this.resize((capacity6 *= 2) > offset ? capacity6 : offset);
2320 offset -= 8;
2321 var lo = value.low,
2322 hi = value.high;
2323 if (this.littleEndian) {
2324 this.view[offset+3] = (lo >>> 24) & 0xFF;
2325 this.view[offset+2] = (lo >>> 16) & 0xFF;
2326 this.view[offset+1] = (lo >>> 8) & 0xFF;
2327 this.view[offset ] = lo & 0xFF;
2328 offset += 4;
2329 this.view[offset+3] = (hi >>> 24) & 0xFF;
2330 this.view[offset+2] = (hi >>> 16) & 0xFF;
2331 this.view[offset+1] = (hi >>> 8) & 0xFF;
2332 this.view[offset ] = hi & 0xFF;
2333 } else {
2334 this.view[offset ] = (hi >>> 24) & 0xFF;
2335 this.view[offset+1] = (hi >>> 16) & 0xFF;
2336 this.view[offset+2] = (hi >>> 8) & 0xFF;
2337 this.view[offset+3] = hi & 0xFF;
2338 offset += 4;
2339 this.view[offset ] = (lo >>> 24) & 0xFF;
2340 this.view[offset+1] = (lo >>> 16) & 0xFF;
2341 this.view[offset+2] = (lo >>> 8) & 0xFF;
2342 this.view[offset+3] = lo & 0xFF;
2343 }
2344 if (relative) this.offset += 8;
2345 return this;
2346 };
2347
2348 /**
2349 * Writes a 64bit signed integer. This is an alias of {@link ByteBuffer#writeInt64}.
2350 * @param {number|!Long} value Value to write
2351 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2352 * @returns {!ByteBuffer} this
2353 * @expose
2354 */
2355 ByteBufferPrototype.writeLong = ByteBufferPrototype.writeInt64;
2356
2357 /**
2358 * Reads a 64bit signed integer.
2359 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2360 * @returns {!Long}
2361 * @expose
2362 */
2363 ByteBufferPrototype.readInt64 = function(offset) {
2364 var relative = typeof offset === 'undefined';
2365 if (relative) offset = this.offset;
2366 if (!this.noAssert) {
2367 if (typeof offset !== 'number' || offset % 1 !== 0)
2368 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2369 offset >>>= 0;
2370 if (offset < 0 || offset + 8 > this.buffer.byteLength)
2371 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
2372 }
2373 var lo = 0,
2374 hi = 0;
2375 if (this.littleEndian) {
2376 lo = this.view[offset+2] << 16;
2377 lo |= this.view[offset+1] << 8;
2378 lo |= this.view[offset ];
2379 lo += this.view[offset+3] << 24 >>> 0;
2380 offset += 4;
2381 hi = this.view[offset+2] << 16;
2382 hi |= this.view[offset+1] << 8;
2383 hi |= this.view[offset ];
2384 hi += this.view[offset+3] << 24 >>> 0;
2385 } else {
2386 hi = this.view[offset+1] << 16;
2387 hi |= this.view[offset+2] << 8;
2388 hi |= this.view[offset+3];
2389 hi += this.view[offset ] << 24 >>> 0;
2390 offset += 4;
2391 lo = this.view[offset+1] << 16;
2392 lo |= this.view[offset+2] << 8;
2393 lo |= this.view[offset+3];
2394 lo += this.view[offset ] << 24 >>> 0;
2395 }
2396 var value = new Long(lo, hi, false);
2397 if (relative) this.offset += 8;
2398 return value;
2399 };
2400
2401 /**
2402 * Reads a 64bit signed integer. This is an alias of {@link ByteBuffer#readInt64}.
2403 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2404 * @returns {!Long}
2405 * @expose
2406 */
2407 ByteBufferPrototype.readLong = ByteBufferPrototype.readInt64;
2408
2409 /**
2410 * Writes a 64bit unsigned integer.
2411 * @param {number|!Long} value Value to write
2412 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2413 * @returns {!ByteBuffer} this
2414 * @expose
2415 */
2416 ByteBufferPrototype.writeUint64 = function(value, offset) {
2417 var relative = typeof offset === 'undefined';
2418 if (relative) offset = this.offset;
2419 if (!this.noAssert) {
2420 if (typeof value === 'number')
2421 value = Long.fromNumber(value);
2422 else if (typeof value === 'string')
2423 value = Long.fromString(value);
2424 else if (!(value && value instanceof Long))
2425 throw TypeError("Illegal value: "+value+" (not an integer or Long)");
2426 if (typeof offset !== 'number' || offset % 1 !== 0)
2427 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2428 offset >>>= 0;
2429 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2430 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2431 }
2432 if (typeof value === 'number')
2433 value = Long.fromNumber(value);
2434 else if (typeof value === 'string')
2435 value = Long.fromString(value);
2436 offset += 8;
2437 var capacity7 = this.buffer.byteLength;
2438 if (offset > capacity7)
2439 this.resize((capacity7 *= 2) > offset ? capacity7 : offset);
2440 offset -= 8;
2441 var lo = value.low,
2442 hi = value.high;
2443 if (this.littleEndian) {
2444 this.view[offset+3] = (lo >>> 24) & 0xFF;
2445 this.view[offset+2] = (lo >>> 16) & 0xFF;
2446 this.view[offset+1] = (lo >>> 8) & 0xFF;
2447 this.view[offset ] = lo & 0xFF;
2448 offset += 4;
2449 this.view[offset+3] = (hi >>> 24) & 0xFF;
2450 this.view[offset+2] = (hi >>> 16) & 0xFF;
2451 this.view[offset+1] = (hi >>> 8) & 0xFF;
2452 this.view[offset ] = hi & 0xFF;
2453 } else {
2454 this.view[offset ] = (hi >>> 24) & 0xFF;
2455 this.view[offset+1] = (hi >>> 16) & 0xFF;
2456 this.view[offset+2] = (hi >>> 8) & 0xFF;
2457 this.view[offset+3] = hi & 0xFF;
2458 offset += 4;
2459 this.view[offset ] = (lo >>> 24) & 0xFF;
2460 this.view[offset+1] = (lo >>> 16) & 0xFF;
2461 this.view[offset+2] = (lo >>> 8) & 0xFF;
2462 this.view[offset+3] = lo & 0xFF;
2463 }
2464 if (relative) this.offset += 8;
2465 return this;
2466 };
2467
2468 /**
2469 * Writes a 64bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint64}.
2470 * @function
2471 * @param {number|!Long} value Value to write
2472 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2473 * @returns {!ByteBuffer} this
2474 * @expose
2475 */
2476 ByteBufferPrototype.writeUInt64 = ByteBufferPrototype.writeUint64;
2477
2478 /**
2479 * Reads a 64bit unsigned integer.
2480 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2481 * @returns {!Long}
2482 * @expose
2483 */
2484 ByteBufferPrototype.readUint64 = function(offset) {
2485 var relative = typeof offset === 'undefined';
2486 if (relative) offset = this.offset;
2487 if (!this.noAssert) {
2488 if (typeof offset !== 'number' || offset % 1 !== 0)
2489 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2490 offset >>>= 0;
2491 if (offset < 0 || offset + 8 > this.buffer.byteLength)
2492 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
2493 }
2494 var lo = 0,
2495 hi = 0;
2496 if (this.littleEndian) {
2497 lo = this.view[offset+2] << 16;
2498 lo |= this.view[offset+1] << 8;
2499 lo |= this.view[offset ];
2500 lo += this.view[offset+3] << 24 >>> 0;
2501 offset += 4;
2502 hi = this.view[offset+2] << 16;
2503 hi |= this.view[offset+1] << 8;
2504 hi |= this.view[offset ];
2505 hi += this.view[offset+3] << 24 >>> 0;
2506 } else {
2507 hi = this.view[offset+1] << 16;
2508 hi |= this.view[offset+2] << 8;
2509 hi |= this.view[offset+3];
2510 hi += this.view[offset ] << 24 >>> 0;
2511 offset += 4;
2512 lo = this.view[offset+1] << 16;
2513 lo |= this.view[offset+2] << 8;
2514 lo |= this.view[offset+3];
2515 lo += this.view[offset ] << 24 >>> 0;
2516 }
2517 var value = new Long(lo, hi, true);
2518 if (relative) this.offset += 8;
2519 return value;
2520 };
2521
2522 /**
2523 * Reads a 64bit unsigned integer. This is an alias of {@link ByteBuffer#readUint64}.
2524 * @function
2525 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2526 * @returns {!Long}
2527 * @expose
2528 */
2529 ByteBufferPrototype.readUInt64 = ByteBufferPrototype.readUint64;
2530
2531 } // Long
2532
2533
2534 // types/floats/float32
2535
2536 /*
2537 ieee754 - https://github.com/feross/ieee754
2538
2539 The MIT License (MIT)
2540
2541 Copyright (c) Feross Aboukhadijeh
2542
2543 Permission is hereby granted, free of charge, to any person obtaining a copy
2544 of this software and associated documentation files (the "Software"), to deal
2545 in the Software without restriction, including without limitation the rights
2546 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2547 copies of the Software, and to permit persons to whom the Software is
2548 furnished to do so, subject to the following conditions:
2549
2550 The above copyright notice and this permission notice shall be included in
2551 all copies or substantial portions of the Software.
2552
2553 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2554 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2555 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2556 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2557 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2558 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2559 THE SOFTWARE.
2560 */
2561
2562 /**
2563 * Reads an IEEE754 float from a byte array.
2564 * @param {!Array} buffer
2565 * @param {number} offset
2566 * @param {boolean} isLE
2567 * @param {number} mLen
2568 * @param {number} nBytes
2569 * @returns {number}
2570 * @inner
2571 */
2572 function ieee754_read(buffer, offset, isLE, mLen, nBytes) {
2573 var e, m,
2574 eLen = nBytes * 8 - mLen - 1,
2575 eMax = (1 << eLen) - 1,
2576 eBias = eMax >> 1,
2577 nBits = -7,
2578 i = isLE ? (nBytes - 1) : 0,
2579 d = isLE ? -1 : 1,
2580 s = buffer[offset + i];
2581
2582 i += d;
2583
2584 e = s & ((1 << (-nBits)) - 1);
2585 s >>= (-nBits);
2586 nBits += eLen;
2587 for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8) {}
2588
2589 m = e & ((1 << (-nBits)) - 1);
2590 e >>= (-nBits);
2591 nBits += mLen;
2592 for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8) {}
2593
2594 if (e === 0) {
2595 e = 1 - eBias;
2596 } else if (e === eMax) {
2597 return m ? NaN : ((s ? -1 : 1) * Infinity);
2598 } else {
2599 m = m + Math.pow(2, mLen);
2600 e = e - eBias;
2601 }
2602 return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
2603 }
2604
2605 /**
2606 * Writes an IEEE754 float to a byte array.
2607 * @param {!Array} buffer
2608 * @param {number} value
2609 * @param {number} offset
2610 * @param {boolean} isLE
2611 * @param {number} mLen
2612 * @param {number} nBytes
2613 * @inner
2614 */
2615 function ieee754_write(buffer, value, offset, isLE, mLen, nBytes) {
2616 var e, m, c,
2617 eLen = nBytes * 8 - mLen - 1,
2618 eMax = (1 << eLen) - 1,
2619 eBias = eMax >> 1,
2620 rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0),
2621 i = isLE ? 0 : (nBytes - 1),
2622 d = isLE ? 1 : -1,
2623 s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0;
2624
2625 value = Math.abs(value);
2626
2627 if (isNaN(value) || value === Infinity) {
2628 m = isNaN(value) ? 1 : 0;
2629 e = eMax;
2630 } else {
2631 e = Math.floor(Math.log(value) / Math.LN2);
2632 if (value * (c = Math.pow(2, -e)) < 1) {
2633 e--;
2634 c *= 2;
2635 }
2636 if (e + eBias >= 1) {
2637 value += rt / c;
2638 } else {
2639 value += rt * Math.pow(2, 1 - eBias);
2640 }
2641 if (value * c >= 2) {
2642 e++;
2643 c /= 2;
2644 }
2645
2646 if (e + eBias >= eMax) {
2647 m = 0;
2648 e = eMax;
2649 } else if (e + eBias >= 1) {
2650 m = (value * c - 1) * Math.pow(2, mLen);
2651 e = e + eBias;
2652 } else {
2653 m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
2654 e = 0;
2655 }
2656 }
2657
2658 for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}
2659
2660 e = (e << mLen) | m;
2661 eLen += mLen;
2662 for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}
2663
2664 buffer[offset + i - d] |= s * 128;
2665 }
2666
2667 /**
2668 * Writes a 32bit float.
2669 * @param {number} value Value to write
2670 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2671 * @returns {!ByteBuffer} this
2672 * @expose
2673 */
2674 ByteBufferPrototype.writeFloat32 = function(value, offset) {
2675 var relative = typeof offset === 'undefined';
2676 if (relative) offset = this.offset;
2677 if (!this.noAssert) {
2678 if (typeof value !== 'number')
2679 throw TypeError("Illegal value: "+value+" (not a number)");
2680 if (typeof offset !== 'number' || offset % 1 !== 0)
2681 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2682 offset >>>= 0;
2683 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2684 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2685 }
2686 offset += 4;
2687 var capacity8 = this.buffer.byteLength;
2688 if (offset > capacity8)
2689 this.resize((capacity8 *= 2) > offset ? capacity8 : offset);
2690 offset -= 4;
2691 ieee754_write(this.view, value, offset, this.littleEndian, 23, 4);
2692 if (relative) this.offset += 4;
2693 return this;
2694 };
2695
2696 /**
2697 * Writes a 32bit float. This is an alias of {@link ByteBuffer#writeFloat32}.
2698 * @function
2699 * @param {number} value Value to write
2700 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2701 * @returns {!ByteBuffer} this
2702 * @expose
2703 */
2704 ByteBufferPrototype.writeFloat = ByteBufferPrototype.writeFloat32;
2705
2706 /**
2707 * Reads a 32bit float.
2708 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2709 * @returns {number}
2710 * @expose
2711 */
2712 ByteBufferPrototype.readFloat32 = function(offset) {
2713 var relative = typeof offset === 'undefined';
2714 if (relative) offset = this.offset;
2715 if (!this.noAssert) {
2716 if (typeof offset !== 'number' || offset % 1 !== 0)
2717 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2718 offset >>>= 0;
2719 if (offset < 0 || offset + 4 > this.buffer.byteLength)
2720 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
2721 }
2722 var value = ieee754_read(this.view, offset, this.littleEndian, 23, 4);
2723 if (relative) this.offset += 4;
2724 return value;
2725 };
2726
2727 /**
2728 * Reads a 32bit float. This is an alias of {@link ByteBuffer#readFloat32}.
2729 * @function
2730 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
2731 * @returns {number}
2732 * @expose
2733 */
2734 ByteBufferPrototype.readFloat = ByteBufferPrototype.readFloat32;
2735
2736 // types/floats/float64
2737
2738 /**
2739 * Writes a 64bit float.
2740 * @param {number} value Value to write
2741 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2742 * @returns {!ByteBuffer} this
2743 * @expose
2744 */
2745 ByteBufferPrototype.writeFloat64 = function(value, offset) {
2746 var relative = typeof offset === 'undefined';
2747 if (relative) offset = this.offset;
2748 if (!this.noAssert) {
2749 if (typeof value !== 'number')
2750 throw TypeError("Illegal value: "+value+" (not a number)");
2751 if (typeof offset !== 'number' || offset % 1 !== 0)
2752 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2753 offset >>>= 0;
2754 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2755 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2756 }
2757 offset += 8;
2758 var capacity9 = this.buffer.byteLength;
2759 if (offset > capacity9)
2760 this.resize((capacity9 *= 2) > offset ? capacity9 : offset);
2761 offset -= 8;
2762 ieee754_write(this.view, value, offset, this.littleEndian, 52, 8);
2763 if (relative) this.offset += 8;
2764 return this;
2765 };
2766
2767 /**
2768 * Writes a 64bit float. This is an alias of {@link ByteBuffer#writeFloat64}.
2769 * @function
2770 * @param {number} value Value to write
2771 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2772 * @returns {!ByteBuffer} this
2773 * @expose
2774 */
2775 ByteBufferPrototype.writeDouble = ByteBufferPrototype.writeFloat64;
2776
2777 /**
2778 * Reads a 64bit float.
2779 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2780 * @returns {number}
2781 * @expose
2782 */
2783 ByteBufferPrototype.readFloat64 = function(offset) {
2784 var relative = typeof offset === 'undefined';
2785 if (relative) offset = this.offset;
2786 if (!this.noAssert) {
2787 if (typeof offset !== 'number' || offset % 1 !== 0)
2788 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2789 offset >>>= 0;
2790 if (offset < 0 || offset + 8 > this.buffer.byteLength)
2791 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+8+") <= "+this.buffer.byteLength);
2792 }
2793 var value = ieee754_read(this.view, offset, this.littleEndian, 52, 8);
2794 if (relative) this.offset += 8;
2795 return value;
2796 };
2797
2798 /**
2799 * Reads a 64bit float. This is an alias of {@link ByteBuffer#readFloat64}.
2800 * @function
2801 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2802 * @returns {number}
2803 * @expose
2804 */
2805 ByteBufferPrototype.readDouble = ByteBufferPrototype.readFloat64;
2806
2807
2808 // types/varints/varint32
2809
2810 /**
2811 * Maximum number of bytes required to store a 32bit base 128 variable-length integer.
2812 * @type {number}
2813 * @const
2814 * @expose
2815 */
2816 ByteBuffer.MAX_VARINT32_BYTES = 5;
2817
2818 /**
2819 * Calculates the actual number of bytes required to store a 32bit base 128 variable-length integer.
2820 * @param {number} value Value to encode
2821 * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT32_BYTES}
2822 * @expose
2823 */
2824 ByteBuffer.calculateVarint32 = function(value) {
2825 // ref: src/google/protobuf/io/coded_stream.cc
2826 value = value >>> 0;
2827 if (value < 1 << 7 ) return 1;
2828 else if (value < 1 << 14) return 2;
2829 else if (value < 1 << 21) return 3;
2830 else if (value < 1 << 28) return 4;
2831 else return 5;
2832 };
2833
2834 /**
2835 * Zigzag encodes a signed 32bit integer so that it can be effectively used with varint encoding.
2836 * @param {number} n Signed 32bit integer
2837 * @returns {number} Unsigned zigzag encoded 32bit integer
2838 * @expose
2839 */
2840 ByteBuffer.zigZagEncode32 = function(n) {
2841 return (((n |= 0) << 1) ^ (n >> 31)) >>> 0; // ref: src/google/protobuf/wire_format_lite.h
2842 };
2843
2844 /**
2845 * Decodes a zigzag encoded signed 32bit integer.
2846 * @param {number} n Unsigned zigzag encoded 32bit integer
2847 * @returns {number} Signed 32bit integer
2848 * @expose
2849 */
2850 ByteBuffer.zigZagDecode32 = function(n) {
2851 return ((n >>> 1) ^ -(n & 1)) | 0; // // ref: src/google/protobuf/wire_format_lite.h
2852 };
2853
2854 /**
2855 * Writes a 32bit base 128 variable-length integer.
2856 * @param {number} value Value to write
2857 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
2858 * written if omitted.
2859 * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
2860 * @expose
2861 */
2862 ByteBufferPrototype.writeVarint32 = function(value, offset) {
2863 var relative = typeof offset === 'undefined';
2864 if (relative) offset = this.offset;
2865 if (!this.noAssert) {
2866 if (typeof value !== 'number' || value % 1 !== 0)
2867 throw TypeError("Illegal value: "+value+" (not an integer)");
2868 value |= 0;
2869 if (typeof offset !== 'number' || offset % 1 !== 0)
2870 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2871 offset >>>= 0;
2872 if (offset < 0 || offset + 0 > this.buffer.byteLength)
2873 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
2874 }
2875 var size = ByteBuffer.calculateVarint32(value),
2876 b;
2877 offset += size;
2878 var capacity10 = this.buffer.byteLength;
2879 if (offset > capacity10)
2880 this.resize((capacity10 *= 2) > offset ? capacity10 : offset);
2881 offset -= size;
2882 value >>>= 0;
2883 while (value >= 0x80) {
2884 b = (value & 0x7f) | 0x80;
2885 this.view[offset++] = b;
2886 value >>>= 7;
2887 }
2888 this.view[offset++] = value;
2889 if (relative) {
2890 this.offset = offset;
2891 return this;
2892 }
2893 return size;
2894 };
2895
2896 /**
2897 * Writes a zig-zag encoded (signed) 32bit base 128 variable-length integer.
2898 * @param {number} value Value to write
2899 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
2900 * written if omitted.
2901 * @returns {!ByteBuffer|number} this if `offset` is omitted, else the actual number of bytes written
2902 * @expose
2903 */
2904 ByteBufferPrototype.writeVarint32ZigZag = function(value, offset) {
2905 return this.writeVarint32(ByteBuffer.zigZagEncode32(value), offset);
2906 };
2907
2908 /**
2909 * Reads a 32bit base 128 variable-length integer.
2910 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
2911 * written if omitted.
2912 * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
2913 * and the actual number of bytes read.
2914 * @throws {Error} If it's not a valid varint. Has a property `truncated = true` if there is not enough data available
2915 * to fully decode the varint.
2916 * @expose
2917 */
2918 ByteBufferPrototype.readVarint32 = function(offset) {
2919 var relative = typeof offset === 'undefined';
2920 if (relative) offset = this.offset;
2921 if (!this.noAssert) {
2922 if (typeof offset !== 'number' || offset % 1 !== 0)
2923 throw TypeError("Illegal offset: "+offset+" (not an integer)");
2924 offset >>>= 0;
2925 if (offset < 0 || offset + 1 > this.buffer.byteLength)
2926 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
2927 }
2928 var c = 0,
2929 value = 0 >>> 0,
2930 b;
2931 do {
2932 if (!this.noAssert && offset > this.limit) {
2933 var err = Error("Truncated");
2934 err['truncated'] = true;
2935 throw err;
2936 }
2937 b = this.view[offset++];
2938 if (c < 5)
2939 value |= (b & 0x7f) << (7*c);
2940 ++c;
2941 } while ((b & 0x80) !== 0);
2942 value |= 0;
2943 if (relative) {
2944 this.offset = offset;
2945 return value;
2946 }
2947 return {
2948 "value": value,
2949 "length": c
2950 };
2951 };
2952
2953 /**
2954 * Reads a zig-zag encoded (signed) 32bit base 128 variable-length integer.
2955 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
2956 * written if omitted.
2957 * @returns {number|!{value: number, length: number}} The value read if offset is omitted, else the value read
2958 * and the actual number of bytes read.
2959 * @throws {Error} If it's not a valid varint
2960 * @expose
2961 */
2962 ByteBufferPrototype.readVarint32ZigZag = function(offset) {
2963 var val = this.readVarint32(offset);
2964 if (typeof val === 'object')
2965 val["value"] = ByteBuffer.zigZagDecode32(val["value"]);
2966 else
2967 val = ByteBuffer.zigZagDecode32(val);
2968 return val;
2969 };
2970
2971 // types/varints/varint64
2972
2973 if (Long) {
2974
2975 /**
2976 * Maximum number of bytes required to store a 64bit base 128 variable-length integer.
2977 * @type {number}
2978 * @const
2979 * @expose
2980 */
2981 ByteBuffer.MAX_VARINT64_BYTES = 10;
2982
2983 /**
2984 * Calculates the actual number of bytes required to store a 64bit base 128 variable-length integer.
2985 * @param {number|!Long} value Value to encode
2986 * @returns {number} Number of bytes required. Capped to {@link ByteBuffer.MAX_VARINT64_BYTES}
2987 * @expose
2988 */
2989 ByteBuffer.calculateVarint64 = function(value) {
2990 if (typeof value === 'number')
2991 value = Long.fromNumber(value);
2992 else if (typeof value === 'string')
2993 value = Long.fromString(value);
2994 // ref: src/google/protobuf/io/coded_stream.cc
2995 var part0 = value.toInt() >>> 0,
2996 part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
2997 part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
2998 if (part2 == 0) {
2999 if (part1 == 0) {
3000 if (part0 < 1 << 14)
3001 return part0 < 1 << 7 ? 1 : 2;
3002 else
3003 return part0 < 1 << 21 ? 3 : 4;
3004 } else {
3005 if (part1 < 1 << 14)
3006 return part1 < 1 << 7 ? 5 : 6;
3007 else
3008 return part1 < 1 << 21 ? 7 : 8;
3009 }
3010 } else
3011 return part2 < 1 << 7 ? 9 : 10;
3012 };
3013
3014 /**
3015 * Zigzag encodes a signed 64bit integer so that it can be effectively used with varint encoding.
3016 * @param {number|!Long} value Signed long
3017 * @returns {!Long} Unsigned zigzag encoded long
3018 * @expose
3019 */
3020 ByteBuffer.zigZagEncode64 = function(value) {
3021 if (typeof value === 'number')
3022 value = Long.fromNumber(value, false);
3023 else if (typeof value === 'string')
3024 value = Long.fromString(value, false);
3025 else if (value.unsigned !== false) value = value.toSigned();
3026 // ref: src/google/protobuf/wire_format_lite.h
3027 return value.shiftLeft(1).xor(value.shiftRight(63)).toUnsigned();
3028 };
3029
3030 /**
3031 * Decodes a zigzag encoded signed 64bit integer.
3032 * @param {!Long|number} value Unsigned zigzag encoded long or JavaScript number
3033 * @returns {!Long} Signed long
3034 * @expose
3035 */
3036 ByteBuffer.zigZagDecode64 = function(value) {
3037 if (typeof value === 'number')
3038 value = Long.fromNumber(value, false);
3039 else if (typeof value === 'string')
3040 value = Long.fromString(value, false);
3041 else if (value.unsigned !== false) value = value.toSigned();
3042 // ref: src/google/protobuf/wire_format_lite.h
3043 return value.shiftRightUnsigned(1).xor(value.and(Long.ONE).toSigned().negate()).toSigned();
3044 };
3045
3046 /**
3047 * Writes a 64bit base 128 variable-length integer.
3048 * @param {number|Long} value Value to write
3049 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3050 * written if omitted.
3051 * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
3052 * @expose
3053 */
3054 ByteBufferPrototype.writeVarint64 = function(value, offset) {
3055 var relative = typeof offset === 'undefined';
3056 if (relative) offset = this.offset;
3057 if (!this.noAssert) {
3058 if (typeof value === 'number')
3059 value = Long.fromNumber(value);
3060 else if (typeof value === 'string')
3061 value = Long.fromString(value);
3062 else if (!(value && value instanceof Long))
3063 throw TypeError("Illegal value: "+value+" (not an integer or Long)");
3064 if (typeof offset !== 'number' || offset % 1 !== 0)
3065 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3066 offset >>>= 0;
3067 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3068 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3069 }
3070 if (typeof value === 'number')
3071 value = Long.fromNumber(value, false);
3072 else if (typeof value === 'string')
3073 value = Long.fromString(value, false);
3074 else if (value.unsigned !== false) value = value.toSigned();
3075 var size = ByteBuffer.calculateVarint64(value),
3076 part0 = value.toInt() >>> 0,
3077 part1 = value.shiftRightUnsigned(28).toInt() >>> 0,
3078 part2 = value.shiftRightUnsigned(56).toInt() >>> 0;
3079 offset += size;
3080 var capacity11 = this.buffer.byteLength;
3081 if (offset > capacity11)
3082 this.resize((capacity11 *= 2) > offset ? capacity11 : offset);
3083 offset -= size;
3084 switch (size) {
3085 case 10: this.view[offset+9] = (part2 >>> 7) & 0x01;
3086 case 9 : this.view[offset+8] = size !== 9 ? (part2 ) | 0x80 : (part2 ) & 0x7F;
3087 case 8 : this.view[offset+7] = size !== 8 ? (part1 >>> 21) | 0x80 : (part1 >>> 21) & 0x7F;
3088 case 7 : this.view[offset+6] = size !== 7 ? (part1 >>> 14) | 0x80 : (part1 >>> 14) & 0x7F;
3089 case 6 : this.view[offset+5] = size !== 6 ? (part1 >>> 7) | 0x80 : (part1 >>> 7) & 0x7F;
3090 case 5 : this.view[offset+4] = size !== 5 ? (part1 ) | 0x80 : (part1 ) & 0x7F;
3091 case 4 : this.view[offset+3] = size !== 4 ? (part0 >>> 21) | 0x80 : (part0 >>> 21) & 0x7F;
3092 case 3 : this.view[offset+2] = size !== 3 ? (part0 >>> 14) | 0x80 : (part0 >>> 14) & 0x7F;
3093 case 2 : this.view[offset+1] = size !== 2 ? (part0 >>> 7) | 0x80 : (part0 >>> 7) & 0x7F;
3094 case 1 : this.view[offset ] = size !== 1 ? (part0 ) | 0x80 : (part0 ) & 0x7F;
3095 }
3096 if (relative) {
3097 this.offset += size;
3098 return this;
3099 } else {
3100 return size;
3101 }
3102 };
3103
3104 /**
3105 * Writes a zig-zag encoded 64bit base 128 variable-length integer.
3106 * @param {number|Long} value Value to write
3107 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3108 * written if omitted.
3109 * @returns {!ByteBuffer|number} `this` if offset is omitted, else the actual number of bytes written.
3110 * @expose
3111 */
3112 ByteBufferPrototype.writeVarint64ZigZag = function(value, offset) {
3113 return this.writeVarint64(ByteBuffer.zigZagEncode64(value), offset);
3114 };
3115
3116 /**
3117 * Reads a 64bit base 128 variable-length integer. Requires Long.js.
3118 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3119 * read if omitted.
3120 * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
3121 * the actual number of bytes read.
3122 * @throws {Error} If it's not a valid varint
3123 * @expose
3124 */
3125 ByteBufferPrototype.readVarint64 = function(offset) {
3126 var relative = typeof offset === 'undefined';
3127 if (relative) offset = this.offset;
3128 if (!this.noAssert) {
3129 if (typeof offset !== 'number' || offset % 1 !== 0)
3130 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3131 offset >>>= 0;
3132 if (offset < 0 || offset + 1 > this.buffer.byteLength)
3133 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
3134 }
3135 // ref: src/google/protobuf/io/coded_stream.cc
3136 var start = offset,
3137 part0 = 0,
3138 part1 = 0,
3139 part2 = 0,
3140 b = 0;
3141 b = this.view[offset++]; part0 = (b & 0x7F) ; if ( b & 0x80 ) {
3142 b = this.view[offset++]; part0 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3143 b = this.view[offset++]; part0 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3144 b = this.view[offset++]; part0 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3145 b = this.view[offset++]; part1 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3146 b = this.view[offset++]; part1 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3147 b = this.view[offset++]; part1 |= (b & 0x7F) << 14; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3148 b = this.view[offset++]; part1 |= (b & 0x7F) << 21; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3149 b = this.view[offset++]; part2 = (b & 0x7F) ; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3150 b = this.view[offset++]; part2 |= (b & 0x7F) << 7; if ((b & 0x80) || (this.noAssert && typeof b === 'undefined')) {
3151 throw Error("Buffer overrun"); }}}}}}}}}}
3152 var value = Long.fromBits(part0 | (part1 << 28), (part1 >>> 4) | (part2) << 24, false);
3153 if (relative) {
3154 this.offset = offset;
3155 return value;
3156 } else {
3157 return {
3158 'value': value,
3159 'length': offset-start
3160 };
3161 }
3162 };
3163
3164 /**
3165 * Reads a zig-zag encoded 64bit base 128 variable-length integer. Requires Long.js.
3166 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3167 * read if omitted.
3168 * @returns {!Long|!{value: Long, length: number}} The value read if offset is omitted, else the value read and
3169 * the actual number of bytes read.
3170 * @throws {Error} If it's not a valid varint
3171 * @expose
3172 */
3173 ByteBufferPrototype.readVarint64ZigZag = function(offset) {
3174 var val = this.readVarint64(offset);
3175 if (val && val['value'] instanceof Long)
3176 val["value"] = ByteBuffer.zigZagDecode64(val["value"]);
3177 else
3178 val = ByteBuffer.zigZagDecode64(val);
3179 return val;
3180 };
3181
3182 } // Long
3183
3184
3185 // types/strings/cstring
3186
3187 /**
3188 * Writes a NULL-terminated UTF8 encoded string. For this to work the specified string must not contain any NULL
3189 * characters itself.
3190 * @param {string} str String to write
3191 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3192 * contained in `str` + 1 if omitted.
3193 * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written
3194 * @expose
3195 */
3196 ByteBufferPrototype.writeCString = function(str, offset) {
3197 var relative = typeof offset === 'undefined';
3198 if (relative) offset = this.offset;
3199 var i,
3200 k = str.length;
3201 if (!this.noAssert) {
3202 if (typeof str !== 'string')
3203 throw TypeError("Illegal str: Not a string");
3204 for (i=0; i<k; ++i) {
3205 if (str.charCodeAt(i) === 0)
3206 throw RangeError("Illegal str: Contains NULL-characters");
3207 }
3208 if (typeof offset !== 'number' || offset % 1 !== 0)
3209 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3210 offset >>>= 0;
3211 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3212 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3213 }
3214 // UTF8 strings do not contain zero bytes in between except for the zero character, so:
3215 k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
3216 offset += k+1;
3217 var capacity12 = this.buffer.byteLength;
3218 if (offset > capacity12)
3219 this.resize((capacity12 *= 2) > offset ? capacity12 : offset);
3220 offset -= k+1;
3221 utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
3222 this.view[offset++] = b;
3223 }.bind(this));
3224 this.view[offset++] = 0;
3225 if (relative) {
3226 this.offset = offset;
3227 return this;
3228 }
3229 return k;
3230 };
3231
3232 /**
3233 * Reads a NULL-terminated UTF8 encoded string. For this to work the string read must not contain any NULL characters
3234 * itself.
3235 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3236 * read if omitted.
3237 * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
3238 * read and the actual number of bytes read.
3239 * @expose
3240 */
3241 ByteBufferPrototype.readCString = function(offset) {
3242 var relative = typeof offset === 'undefined';
3243 if (relative) offset = this.offset;
3244 if (!this.noAssert) {
3245 if (typeof offset !== 'number' || offset % 1 !== 0)
3246 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3247 offset >>>= 0;
3248 if (offset < 0 || offset + 1 > this.buffer.byteLength)
3249 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
3250 }
3251 var start = offset;
3252 // UTF8 strings do not contain zero bytes in between except for the zero character itself, so:
3253 var sd, b = -1;
3254 utfx.decodeUTF8toUTF16(function() {
3255 if (b === 0) return null;
3256 if (offset >= this.limit)
3257 throw RangeError("Illegal range: Truncated data, "+offset+" < "+this.limit);
3258 b = this.view[offset++];
3259 return b === 0 ? null : b;
3260 }.bind(this), sd = stringDestination(), true);
3261 if (relative) {
3262 this.offset = offset;
3263 return sd();
3264 } else {
3265 return {
3266 "string": sd(),
3267 "length": offset - start
3268 };
3269 }
3270 };
3271
3272 // types/strings/istring
3273
3274 /**
3275 * Writes a length as uint32 prefixed UTF8 encoded string.
3276 * @param {string} str String to write
3277 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3278 * written if omitted.
3279 * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
3280 * @expose
3281 * @see ByteBuffer#writeVarint32
3282 */
3283 ByteBufferPrototype.writeIString = function(str, offset) {
3284 var relative = typeof offset === 'undefined';
3285 if (relative) offset = this.offset;
3286 if (!this.noAssert) {
3287 if (typeof str !== 'string')
3288 throw TypeError("Illegal str: Not a string");
3289 if (typeof offset !== 'number' || offset % 1 !== 0)
3290 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3291 offset >>>= 0;
3292 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3293 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3294 }
3295 var start = offset,
3296 k;
3297 k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
3298 offset += 4+k;
3299 var capacity13 = this.buffer.byteLength;
3300 if (offset > capacity13)
3301 this.resize((capacity13 *= 2) > offset ? capacity13 : offset);
3302 offset -= 4+k;
3303 if (this.littleEndian) {
3304 this.view[offset+3] = (k >>> 24) & 0xFF;
3305 this.view[offset+2] = (k >>> 16) & 0xFF;
3306 this.view[offset+1] = (k >>> 8) & 0xFF;
3307 this.view[offset ] = k & 0xFF;
3308 } else {
3309 this.view[offset ] = (k >>> 24) & 0xFF;
3310 this.view[offset+1] = (k >>> 16) & 0xFF;
3311 this.view[offset+2] = (k >>> 8) & 0xFF;
3312 this.view[offset+3] = k & 0xFF;
3313 }
3314 offset += 4;
3315 utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
3316 this.view[offset++] = b;
3317 }.bind(this));
3318 if (offset !== start + 4 + k)
3319 throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+4+k));
3320 if (relative) {
3321 this.offset = offset;
3322 return this;
3323 }
3324 return offset - start;
3325 };
3326
3327 /**
3328 * Reads a length as uint32 prefixed UTF8 encoded string.
3329 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3330 * read if omitted.
3331 * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
3332 * read and the actual number of bytes read.
3333 * @expose
3334 * @see ByteBuffer#readVarint32
3335 */
3336 ByteBufferPrototype.readIString = function(offset) {
3337 var relative = typeof offset === 'undefined';
3338 if (relative) offset = this.offset;
3339 if (!this.noAssert) {
3340 if (typeof offset !== 'number' || offset % 1 !== 0)
3341 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3342 offset >>>= 0;
3343 if (offset < 0 || offset + 4 > this.buffer.byteLength)
3344 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+4+") <= "+this.buffer.byteLength);
3345 }
3346 var start = offset;
3347 var len = this.readUint32(offset);
3348 var str = this.readUTF8String(len, ByteBuffer.METRICS_BYTES, offset += 4);
3349 offset += str['length'];
3350 if (relative) {
3351 this.offset = offset;
3352 return str['string'];
3353 } else {
3354 return {
3355 'string': str['string'],
3356 'length': offset - start
3357 };
3358 }
3359 };
3360
3361 // types/strings/utf8string
3362
3363 /**
3364 * Metrics representing number of UTF8 characters. Evaluates to `c`.
3365 * @type {string}
3366 * @const
3367 * @expose
3368 */
3369 ByteBuffer.METRICS_CHARS = 'c';
3370
3371 /**
3372 * Metrics representing number of bytes. Evaluates to `b`.
3373 * @type {string}
3374 * @const
3375 * @expose
3376 */
3377 ByteBuffer.METRICS_BYTES = 'b';
3378
3379 /**
3380 * Writes an UTF8 encoded string.
3381 * @param {string} str String to write
3382 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
3383 * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
3384 * @expose
3385 */
3386 ByteBufferPrototype.writeUTF8String = function(str, offset) {
3387 var relative = typeof offset === 'undefined';
3388 if (relative) offset = this.offset;
3389 if (!this.noAssert) {
3390 if (typeof offset !== 'number' || offset % 1 !== 0)
3391 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3392 offset >>>= 0;
3393 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3394 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3395 }
3396 var k;
3397 var start = offset;
3398 k = utfx.calculateUTF16asUTF8(stringSource(str))[1];
3399 offset += k;
3400 var capacity14 = this.buffer.byteLength;
3401 if (offset > capacity14)
3402 this.resize((capacity14 *= 2) > offset ? capacity14 : offset);
3403 offset -= k;
3404 utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
3405 this.view[offset++] = b;
3406 }.bind(this));
3407 if (relative) {
3408 this.offset = offset;
3409 return this;
3410 }
3411 return offset - start;
3412 };
3413
3414 /**
3415 * Writes an UTF8 encoded string. This is an alias of {@link ByteBuffer#writeUTF8String}.
3416 * @function
3417 * @param {string} str String to write
3418 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} if omitted.
3419 * @returns {!ByteBuffer|number} this if offset is omitted, else the actual number of bytes written.
3420 * @expose
3421 */
3422 ByteBufferPrototype.writeString = ByteBufferPrototype.writeUTF8String;
3423
3424 /**
3425 * Calculates the number of UTF8 characters of a string. JavaScript itself uses UTF-16, so that a string's
3426 * `length` property does not reflect its actual UTF8 size if it contains code points larger than 0xFFFF.
3427 * @param {string} str String to calculate
3428 * @returns {number} Number of UTF8 characters
3429 * @expose
3430 */
3431 ByteBuffer.calculateUTF8Chars = function(str) {
3432 return utfx.calculateUTF16asUTF8(stringSource(str))[0];
3433 };
3434
3435 /**
3436 * Calculates the number of UTF8 bytes of a string.
3437 * @param {string} str String to calculate
3438 * @returns {number} Number of UTF8 bytes
3439 * @expose
3440 */
3441 ByteBuffer.calculateUTF8Bytes = function(str) {
3442 return utfx.calculateUTF16asUTF8(stringSource(str))[1];
3443 };
3444
3445 /**
3446 * Calculates the number of UTF8 bytes of a string. This is an alias of {@link ByteBuffer.calculateUTF8Bytes}.
3447 * @function
3448 * @param {string} str String to calculate
3449 * @returns {number} Number of UTF8 bytes
3450 * @expose
3451 */
3452 ByteBuffer.calculateString = ByteBuffer.calculateUTF8Bytes;
3453
3454 /**
3455 * Reads an UTF8 encoded string.
3456 * @param {number} length Number of characters or bytes to read.
3457 * @param {string=} metrics Metrics specifying what `length` is meant to count. Defaults to
3458 * {@link ByteBuffer.METRICS_CHARS}.
3459 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3460 * read if omitted.
3461 * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
3462 * read and the actual number of bytes read.
3463 * @expose
3464 */
3465 ByteBufferPrototype.readUTF8String = function(length, metrics, offset) {
3466 if (typeof metrics === 'number') {
3467 offset = metrics;
3468 metrics = undefined;
3469 }
3470 var relative = typeof offset === 'undefined';
3471 if (relative) offset = this.offset;
3472 if (typeof metrics === 'undefined') metrics = ByteBuffer.METRICS_CHARS;
3473 if (!this.noAssert) {
3474 if (typeof length !== 'number' || length % 1 !== 0)
3475 throw TypeError("Illegal length: "+length+" (not an integer)");
3476 length |= 0;
3477 if (typeof offset !== 'number' || offset % 1 !== 0)
3478 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3479 offset >>>= 0;
3480 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3481 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3482 }
3483 var i = 0,
3484 start = offset,
3485 sd;
3486 if (metrics === ByteBuffer.METRICS_CHARS) { // The same for node and the browser
3487 sd = stringDestination();
3488 utfx.decodeUTF8(function() {
3489 return i < length && offset < this.limit ? this.view[offset++] : null;
3490 }.bind(this), function(cp) {
3491 ++i; utfx.UTF8toUTF16(cp, sd);
3492 });
3493 if (i !== length)
3494 throw RangeError("Illegal range: Truncated data, "+i+" == "+length);
3495 if (relative) {
3496 this.offset = offset;
3497 return sd();
3498 } else {
3499 return {
3500 "string": sd(),
3501 "length": offset - start
3502 };
3503 }
3504 } else if (metrics === ByteBuffer.METRICS_BYTES) {
3505 if (!this.noAssert) {
3506 if (typeof offset !== 'number' || offset % 1 !== 0)
3507 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3508 offset >>>= 0;
3509 if (offset < 0 || offset + length > this.buffer.byteLength)
3510 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+length+") <= "+this.buffer.byteLength);
3511 }
3512 var k = offset + length;
3513 utfx.decodeUTF8toUTF16(function() {
3514 return offset < k ? this.view[offset++] : null;
3515 }.bind(this), sd = stringDestination(), this.noAssert);
3516 if (offset !== k)
3517 throw RangeError("Illegal range: Truncated data, "+offset+" == "+k);
3518 if (relative) {
3519 this.offset = offset;
3520 return sd();
3521 } else {
3522 return {
3523 'string': sd(),
3524 'length': offset - start
3525 };
3526 }
3527 } else
3528 throw TypeError("Unsupported metrics: "+metrics);
3529 };
3530
3531 /**
3532 * Reads an UTF8 encoded string. This is an alias of {@link ByteBuffer#readUTF8String}.
3533 * @function
3534 * @param {number} length Number of characters or bytes to read
3535 * @param {number=} metrics Metrics specifying what `n` is meant to count. Defaults to
3536 * {@link ByteBuffer.METRICS_CHARS}.
3537 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3538 * read if omitted.
3539 * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
3540 * read and the actual number of bytes read.
3541 * @expose
3542 */
3543 ByteBufferPrototype.readString = ByteBufferPrototype.readUTF8String;
3544
3545 // types/strings/vstring
3546
3547 /**
3548 * Writes a length as varint32 prefixed UTF8 encoded string.
3549 * @param {string} str String to write
3550 * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3551 * written if omitted.
3552 * @returns {!ByteBuffer|number} `this` if `offset` is omitted, else the actual number of bytes written
3553 * @expose
3554 * @see ByteBuffer#writeVarint32
3555 */
3556 ByteBufferPrototype.writeVString = function(str, offset) {
3557 var relative = typeof offset === 'undefined';
3558 if (relative) offset = this.offset;
3559 if (!this.noAssert) {
3560 if (typeof str !== 'string')
3561 throw TypeError("Illegal str: Not a string");
3562 if (typeof offset !== 'number' || offset % 1 !== 0)
3563 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3564 offset >>>= 0;
3565 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3566 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3567 }
3568 var start = offset,
3569 k, l;
3570 k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1];
3571 l = ByteBuffer.calculateVarint32(k);
3572 offset += l+k;
3573 var capacity15 = this.buffer.byteLength;
3574 if (offset > capacity15)
3575 this.resize((capacity15 *= 2) > offset ? capacity15 : offset);
3576 offset -= l+k;
3577 offset += this.writeVarint32(k, offset);
3578 utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
3579 this.view[offset++] = b;
3580 }.bind(this));
3581 if (offset !== start+k+l)
3582 throw RangeError("Illegal range: Truncated data, "+offset+" == "+(offset+k+l));
3583 if (relative) {
3584 this.offset = offset;
3585 return this;
3586 }
3587 return offset - start;
3588 };
3589
3590 /**
3591 * Reads a length as varint32 prefixed UTF8 encoded string.
3592 * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3593 * read if omitted.
3594 * @returns {string|!{string: string, length: number}} The string read if offset is omitted, else the string
3595 * read and the actual number of bytes read.
3596 * @expose
3597 * @see ByteBuffer#readVarint32
3598 */
3599 ByteBufferPrototype.readVString = function(offset) {
3600 var relative = typeof offset === 'undefined';
3601 if (relative) offset = this.offset;
3602 if (!this.noAssert) {
3603 if (typeof offset !== 'number' || offset % 1 !== 0)
3604 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3605 offset >>>= 0;
3606 if (offset < 0 || offset + 1 > this.buffer.byteLength)
3607 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+1+") <= "+this.buffer.byteLength);
3608 }
3609 var start = offset;
3610 var len = this.readVarint32(offset);
3611 var str = this.readUTF8String(len['value'], ByteBuffer.METRICS_BYTES, offset += len['length']);
3612 offset += str['length'];
3613 if (relative) {
3614 this.offset = offset;
3615 return str['string'];
3616 } else {
3617 return {
3618 'string': str['string'],
3619 'length': offset - start
3620 };
3621 }
3622 };
3623
3624
3625 /**
3626 * Appends some data to this ByteBuffer. This will overwrite any contents behind the specified offset up to the appended
3627 * data's length.
3628 * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to append. If `source` is a ByteBuffer, its offsets
3629 * will be modified according to the performed read operation.
3630 * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
3631 * @param {number=} offset Offset to append at. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3632 * written if omitted.
3633 * @returns {!ByteBuffer} this
3634 * @expose
3635 * @example A relative `<01 02>03.append(<04 05>)` will result in `<01 02 04 05>, 04 05|`
3636 * @example An absolute `<01 02>03.append(04 05>, 1)` will result in `<01 04>05, 04 05|`
3637 */
3638 ByteBufferPrototype.append = function(source, encoding, offset) {
3639 if (typeof encoding === 'number' || typeof encoding !== 'string') {
3640 offset = encoding;
3641 encoding = undefined;
3642 }
3643 var relative = typeof offset === 'undefined';
3644 if (relative) offset = this.offset;
3645 if (!this.noAssert) {
3646 if (typeof offset !== 'number' || offset % 1 !== 0)
3647 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3648 offset >>>= 0;
3649 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3650 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3651 }
3652 if (!(source instanceof ByteBuffer))
3653 source = ByteBuffer.wrap(source, encoding);
3654 var length = source.limit - source.offset;
3655 if (length <= 0) return this; // Nothing to append
3656 offset += length;
3657 var capacity16 = this.buffer.byteLength;
3658 if (offset > capacity16)
3659 this.resize((capacity16 *= 2) > offset ? capacity16 : offset);
3660 offset -= length;
3661 this.view.set(source.view.subarray(source.offset, source.limit), offset);
3662 source.offset += length;
3663 if (relative) this.offset += length;
3664 return this;
3665 };
3666
3667 /**
3668 * Appends this ByteBuffer's contents to another ByteBuffer. This will overwrite any contents at and after the
3669 specified offset up to the length of this ByteBuffer's data.
3670 * @param {!ByteBuffer} target Target ByteBuffer
3671 * @param {number=} offset Offset to append to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3672 * read if omitted.
3673 * @returns {!ByteBuffer} this
3674 * @expose
3675 * @see ByteBuffer#append
3676 */
3677 ByteBufferPrototype.appendTo = function(target, offset) {
3678 target.append(this, offset);
3679 return this;
3680 };
3681
3682 /**
3683 * Enables or disables assertions of argument types and offsets. Assertions are enabled by default but you can opt to
3684 * disable them if your code already makes sure that everything is valid.
3685 * @param {boolean} assert `true` to enable assertions, otherwise `false`
3686 * @returns {!ByteBuffer} this
3687 * @expose
3688 */
3689 ByteBufferPrototype.assert = function(assert) {
3690 this.noAssert = !assert;
3691 return this;
3692 };
3693
3694 /**
3695 * Gets the capacity of this ByteBuffer's backing buffer.
3696 * @returns {number} Capacity of the backing buffer
3697 * @expose
3698 */
3699 ByteBufferPrototype.capacity = function() {
3700 return this.buffer.byteLength;
3701 };
3702 /**
3703 * Clears this ByteBuffer's offsets by setting {@link ByteBuffer#offset} to `0` and {@link ByteBuffer#limit} to the
3704 * backing buffer's capacity. Discards {@link ByteBuffer#markedOffset}.
3705 * @returns {!ByteBuffer} this
3706 * @expose
3707 */
3708 ByteBufferPrototype.clear = function() {
3709 this.offset = 0;
3710 this.limit = this.buffer.byteLength;
3711 this.markedOffset = -1;
3712 return this;
3713 };
3714
3715 /**
3716 * Creates a cloned instance of this ByteBuffer, preset with this ByteBuffer's values for {@link ByteBuffer#offset},
3717 * {@link ByteBuffer#markedOffset} and {@link ByteBuffer#limit}.
3718 * @param {boolean=} copy Whether to copy the backing buffer or to return another view on the same, defaults to `false`
3719 * @returns {!ByteBuffer} Cloned instance
3720 * @expose
3721 */
3722 ByteBufferPrototype.clone = function(copy) {
3723 var bb = new ByteBuffer(0, this.littleEndian, this.noAssert);
3724 if (copy) {
3725 bb.buffer = new ArrayBuffer(this.buffer.byteLength);
3726 bb.view = new Uint8Array(bb.buffer);
3727 } else {
3728 bb.buffer = this.buffer;
3729 bb.view = this.view;
3730 }
3731 bb.offset = this.offset;
3732 bb.markedOffset = this.markedOffset;
3733 bb.limit = this.limit;
3734 return bb;
3735 };
3736
3737 /**
3738 * Compacts this ByteBuffer to be backed by a {@link ByteBuffer#buffer} of its contents' length. Contents are the bytes
3739 * between {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will set `offset = 0` and `limit = capacity` and
3740 * adapt {@link ByteBuffer#markedOffset} to the same relative position if set.
3741 * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
3742 * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
3743 * @returns {!ByteBuffer} this
3744 * @expose
3745 */
3746 ByteBufferPrototype.compact = function(begin, end) {
3747 if (typeof begin === 'undefined') begin = this.offset;
3748 if (typeof end === 'undefined') end = this.limit;
3749 if (!this.noAssert) {
3750 if (typeof begin !== 'number' || begin % 1 !== 0)
3751 throw TypeError("Illegal begin: Not an integer");
3752 begin >>>= 0;
3753 if (typeof end !== 'number' || end % 1 !== 0)
3754 throw TypeError("Illegal end: Not an integer");
3755 end >>>= 0;
3756 if (begin < 0 || begin > end || end > this.buffer.byteLength)
3757 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
3758 }
3759 if (begin === 0 && end === this.buffer.byteLength)
3760 return this; // Already compacted
3761 var len = end - begin;
3762 if (len === 0) {
3763 this.buffer = EMPTY_BUFFER;
3764 this.view = null;
3765 if (this.markedOffset >= 0) this.markedOffset -= begin;
3766 this.offset = 0;
3767 this.limit = 0;
3768 return this;
3769 }
3770 var buffer = new ArrayBuffer(len);
3771 var view = new Uint8Array(buffer);
3772 view.set(this.view.subarray(begin, end));
3773 this.buffer = buffer;
3774 this.view = view;
3775 if (this.markedOffset >= 0) this.markedOffset -= begin;
3776 this.offset = 0;
3777 this.limit = len;
3778 return this;
3779 };
3780
3781 /**
3782 * Creates a copy of this ByteBuffer's contents. Contents are the bytes between {@link ByteBuffer#offset} and
3783 * {@link ByteBuffer#limit}.
3784 * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
3785 * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
3786 * @returns {!ByteBuffer} Copy
3787 * @expose
3788 */
3789 ByteBufferPrototype.copy = function(begin, end) {
3790 if (typeof begin === 'undefined') begin = this.offset;
3791 if (typeof end === 'undefined') end = this.limit;
3792 if (!this.noAssert) {
3793 if (typeof begin !== 'number' || begin % 1 !== 0)
3794 throw TypeError("Illegal begin: Not an integer");
3795 begin >>>= 0;
3796 if (typeof end !== 'number' || end % 1 !== 0)
3797 throw TypeError("Illegal end: Not an integer");
3798 end >>>= 0;
3799 if (begin < 0 || begin > end || end > this.buffer.byteLength)
3800 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
3801 }
3802 if (begin === end)
3803 return new ByteBuffer(0, this.littleEndian, this.noAssert);
3804 var capacity = end - begin,
3805 bb = new ByteBuffer(capacity, this.littleEndian, this.noAssert);
3806 bb.offset = 0;
3807 bb.limit = capacity;
3808 if (bb.markedOffset >= 0) bb.markedOffset -= begin;
3809 this.copyTo(bb, 0, begin, end);
3810 return bb;
3811 };
3812
3813 /**
3814 * Copies this ByteBuffer's contents to another ByteBuffer. Contents are the bytes between {@link ByteBuffer#offset} and
3815 * {@link ByteBuffer#limit}.
3816 * @param {!ByteBuffer} target Target ByteBuffer
3817 * @param {number=} targetOffset Offset to copy to. Will use and increase the target's {@link ByteBuffer#offset}
3818 * by the number of bytes copied if omitted.
3819 * @param {number=} sourceOffset Offset to start copying from. Will use and increase {@link ByteBuffer#offset} by the
3820 * number of bytes copied if omitted.
3821 * @param {number=} sourceLimit Offset to end copying from, defaults to {@link ByteBuffer#limit}
3822 * @returns {!ByteBuffer} this
3823 * @expose
3824 */
3825 ByteBufferPrototype.copyTo = function(target, targetOffset, sourceOffset, sourceLimit) {
3826 var relative,
3827 targetRelative;
3828 if (!this.noAssert) {
3829 if (!ByteBuffer.isByteBuffer(target))
3830 throw TypeError("Illegal target: Not a ByteBuffer");
3831 }
3832 targetOffset = (targetRelative = typeof targetOffset === 'undefined') ? target.offset : targetOffset | 0;
3833 sourceOffset = (relative = typeof sourceOffset === 'undefined') ? this.offset : sourceOffset | 0;
3834 sourceLimit = typeof sourceLimit === 'undefined' ? this.limit : sourceLimit | 0;
3835
3836 if (targetOffset < 0 || targetOffset > target.buffer.byteLength)
3837 throw RangeError("Illegal target range: 0 <= "+targetOffset+" <= "+target.buffer.byteLength);
3838 if (sourceOffset < 0 || sourceLimit > this.buffer.byteLength)
3839 throw RangeError("Illegal source range: 0 <= "+sourceOffset+" <= "+this.buffer.byteLength);
3840
3841 var len = sourceLimit - sourceOffset;
3842 if (len === 0)
3843 return target; // Nothing to copy
3844
3845 target.ensureCapacity(targetOffset + len);
3846
3847 target.view.set(this.view.subarray(sourceOffset, sourceLimit), targetOffset);
3848
3849 if (relative) this.offset += len;
3850 if (targetRelative) target.offset += len;
3851
3852 return this;
3853 };
3854
3855 /**
3856 * Makes sure that this ByteBuffer is backed by a {@link ByteBuffer#buffer} of at least the specified capacity. If the
3857 * current capacity is exceeded, it will be doubled. If double the current capacity is less than the required capacity,
3858 * the required capacity will be used instead.
3859 * @param {number} capacity Required capacity
3860 * @returns {!ByteBuffer} this
3861 * @expose
3862 */
3863 ByteBufferPrototype.ensureCapacity = function(capacity) {
3864 var current = this.buffer.byteLength;
3865 if (current < capacity)
3866 return this.resize((current *= 2) > capacity ? current : capacity);
3867 return this;
3868 };
3869
3870 /**
3871 * Overwrites this ByteBuffer's contents with the specified value. Contents are the bytes between
3872 * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
3873 * @param {number|string} value Byte value to fill with. If given as a string, the first character is used.
3874 * @param {number=} begin Begin offset. Will use and increase {@link ByteBuffer#offset} by the number of bytes
3875 * written if omitted. defaults to {@link ByteBuffer#offset}.
3876 * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
3877 * @returns {!ByteBuffer} this
3878 * @expose
3879 * @example `someByteBuffer.clear().fill(0)` fills the entire backing buffer with zeroes
3880 */
3881 ByteBufferPrototype.fill = function(value, begin, end) {
3882 var relative = typeof begin === 'undefined';
3883 if (relative) begin = this.offset;
3884 if (typeof value === 'string' && value.length > 0)
3885 value = value.charCodeAt(0);
3886 if (typeof begin === 'undefined') begin = this.offset;
3887 if (typeof end === 'undefined') end = this.limit;
3888 if (!this.noAssert) {
3889 if (typeof value !== 'number' || value % 1 !== 0)
3890 throw TypeError("Illegal value: "+value+" (not an integer)");
3891 value |= 0;
3892 if (typeof begin !== 'number' || begin % 1 !== 0)
3893 throw TypeError("Illegal begin: Not an integer");
3894 begin >>>= 0;
3895 if (typeof end !== 'number' || end % 1 !== 0)
3896 throw TypeError("Illegal end: Not an integer");
3897 end >>>= 0;
3898 if (begin < 0 || begin > end || end > this.buffer.byteLength)
3899 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
3900 }
3901 if (begin >= end)
3902 return this; // Nothing to fill
3903 while (begin < end) this.view[begin++] = value;
3904 if (relative) this.offset = begin;
3905 return this;
3906 };
3907
3908 /**
3909 * Makes this ByteBuffer ready for a new sequence of write or relative read operations. Sets `limit = offset` and
3910 * `offset = 0`. Make sure always to flip a ByteBuffer when all relative read or write operations are complete.
3911 * @returns {!ByteBuffer} this
3912 * @expose
3913 */
3914 ByteBufferPrototype.flip = function() {
3915 this.limit = this.offset;
3916 this.offset = 0;
3917 return this;
3918 };
3919 /**
3920 * Marks an offset on this ByteBuffer to be used later.
3921 * @param {number=} offset Offset to mark. Defaults to {@link ByteBuffer#offset}.
3922 * @returns {!ByteBuffer} this
3923 * @throws {TypeError} If `offset` is not a valid number
3924 * @throws {RangeError} If `offset` is out of bounds
3925 * @see ByteBuffer#reset
3926 * @expose
3927 */
3928 ByteBufferPrototype.mark = function(offset) {
3929 offset = typeof offset === 'undefined' ? this.offset : offset;
3930 if (!this.noAssert) {
3931 if (typeof offset !== 'number' || offset % 1 !== 0)
3932 throw TypeError("Illegal offset: "+offset+" (not an integer)");
3933 offset >>>= 0;
3934 if (offset < 0 || offset + 0 > this.buffer.byteLength)
3935 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
3936 }
3937 this.markedOffset = offset;
3938 return this;
3939 };
3940 /**
3941 * Sets the byte order.
3942 * @param {boolean} littleEndian `true` for little endian byte order, `false` for big endian
3943 * @returns {!ByteBuffer} this
3944 * @expose
3945 */
3946 ByteBufferPrototype.order = function(littleEndian) {
3947 if (!this.noAssert) {
3948 if (typeof littleEndian !== 'boolean')
3949 throw TypeError("Illegal littleEndian: Not a boolean");
3950 }
3951 this.littleEndian = !!littleEndian;
3952 return this;
3953 };
3954
3955 /**
3956 * Switches (to) little endian byte order.
3957 * @param {boolean=} littleEndian Defaults to `true`, otherwise uses big endian
3958 * @returns {!ByteBuffer} this
3959 * @expose
3960 */
3961 ByteBufferPrototype.LE = function(littleEndian) {
3962 this.littleEndian = typeof littleEndian !== 'undefined' ? !!littleEndian : true;
3963 return this;
3964 };
3965
3966 /**
3967 * Switches (to) big endian byte order.
3968 * @param {boolean=} bigEndian Defaults to `true`, otherwise uses little endian
3969 * @returns {!ByteBuffer} this
3970 * @expose
3971 */
3972 ByteBufferPrototype.BE = function(bigEndian) {
3973 this.littleEndian = typeof bigEndian !== 'undefined' ? !bigEndian : false;
3974 return this;
3975 };
3976 /**
3977 * Prepends some data to this ByteBuffer. This will overwrite any contents before the specified offset up to the
3978 * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
3979 * will be resized and its contents moved accordingly.
3980 * @param {!ByteBuffer|string|!ArrayBuffer} source Data to prepend. If `source` is a ByteBuffer, its offset will be
3981 * modified according to the performed read operation.
3982 * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
3983 * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
3984 * prepended if omitted.
3985 * @returns {!ByteBuffer} this
3986 * @expose
3987 * @example A relative `00<01 02 03>.prepend(<04 05>)` results in `<04 05 01 02 03>, 04 05|`
3988 * @example An absolute `00<01 02 03>.prepend(<04 05>, 2)` results in `04<05 02 03>, 04 05|`
3989 */
3990 ByteBufferPrototype.prepend = function(source, encoding, offset) {
3991 if (typeof encoding === 'number' || typeof encoding !== 'string') {
3992 offset = encoding;
3993 encoding = undefined;
3994 }
3995 var relative = typeof offset === 'undefined';
3996 if (relative) offset = this.offset;
3997 if (!this.noAssert) {
3998 if (typeof offset !== 'number' || offset % 1 !== 0)
3999 throw TypeError("Illegal offset: "+offset+" (not an integer)");
4000 offset >>>= 0;
4001 if (offset < 0 || offset + 0 > this.buffer.byteLength)
4002 throw RangeError("Illegal offset: 0 <= "+offset+" (+"+0+") <= "+this.buffer.byteLength);
4003 }
4004 if (!(source instanceof ByteBuffer))
4005 source = ByteBuffer.wrap(source, encoding);
4006 var len = source.limit - source.offset;
4007 if (len <= 0) return this; // Nothing to prepend
4008 var diff = len - offset;
4009 if (diff > 0) { // Not enough space before offset, so resize + move
4010 var buffer = new ArrayBuffer(this.buffer.byteLength + diff);
4011 var view = new Uint8Array(buffer);
4012 view.set(this.view.subarray(offset, this.buffer.byteLength), len);
4013 this.buffer = buffer;
4014 this.view = view;
4015 this.offset += diff;
4016 if (this.markedOffset >= 0) this.markedOffset += diff;
4017 this.limit += diff;
4018 offset += diff;
4019 } else {
4020 var arrayView = new Uint8Array(this.buffer);
4021 }
4022 this.view.set(source.view.subarray(source.offset, source.limit), offset - len);
4023
4024 source.offset = source.limit;
4025 if (relative)
4026 this.offset -= len;
4027 return this;
4028 };
4029
4030 /**
4031 * Prepends this ByteBuffer to another ByteBuffer. This will overwrite any contents before the specified offset up to the
4032 * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
4033 * will be resized and its contents moved accordingly.
4034 * @param {!ByteBuffer} target Target ByteBuffer
4035 * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
4036 * prepended if omitted.
4037 * @returns {!ByteBuffer} this
4038 * @expose
4039 * @see ByteBuffer#prepend
4040 */
4041 ByteBufferPrototype.prependTo = function(target, offset) {
4042 target.prepend(this, offset);
4043 return this;
4044 };
4045 /**
4046 * Prints debug information about this ByteBuffer's contents.
4047 * @param {function(string)=} out Output function to call, defaults to console.log
4048 * @expose
4049 */
4050 ByteBufferPrototype.printDebug = function(out) {
4051 if (typeof out !== 'function') out = console.log.bind(console);
4052 out(
4053 this.toString()+"\n"+
4054 "-------------------------------------------------------------------\n"+
4055 this.toDebug(/* columns */ true)
4056 );
4057 };
4058
4059 /**
4060 * Gets the number of remaining readable bytes. Contents are the bytes between {@link ByteBuffer#offset} and
4061 * {@link ByteBuffer#limit}, so this returns `limit - offset`.
4062 * @returns {number} Remaining readable bytes. May be negative if `offset > limit`.
4063 * @expose
4064 */
4065 ByteBufferPrototype.remaining = function() {
4066 return this.limit - this.offset;
4067 };
4068 /**
4069 * Resets this ByteBuffer's {@link ByteBuffer#offset}. If an offset has been marked through {@link ByteBuffer#mark}
4070 * before, `offset` will be set to {@link ByteBuffer#markedOffset}, which will then be discarded. If no offset has been
4071 * marked, sets `offset = 0`.
4072 * @returns {!ByteBuffer} this
4073 * @see ByteBuffer#mark
4074 * @expose
4075 */
4076 ByteBufferPrototype.reset = function() {
4077 if (this.markedOffset >= 0) {
4078 this.offset = this.markedOffset;
4079 this.markedOffset = -1;
4080 } else {
4081 this.offset = 0;
4082 }
4083 return this;
4084 };
4085 /**
4086 * Resizes this ByteBuffer to be backed by a buffer of at least the given capacity. Will do nothing if already that
4087 * large or larger.
4088 * @param {number} capacity Capacity required
4089 * @returns {!ByteBuffer} this
4090 * @throws {TypeError} If `capacity` is not a number
4091 * @throws {RangeError} If `capacity < 0`
4092 * @expose
4093 */
4094 ByteBufferPrototype.resize = function(capacity) {
4095 if (!this.noAssert) {
4096 if (typeof capacity !== 'number' || capacity % 1 !== 0)
4097 throw TypeError("Illegal capacity: "+capacity+" (not an integer)");
4098 capacity |= 0;
4099 if (capacity < 0)
4100 throw RangeError("Illegal capacity: 0 <= "+capacity);
4101 }
4102 if (this.buffer.byteLength < capacity) {
4103 var buffer = new ArrayBuffer(capacity);
4104 var view = new Uint8Array(buffer);
4105 view.set(this.view);
4106 this.buffer = buffer;
4107 this.view = view;
4108 }
4109 return this;
4110 };
4111 /**
4112 * Reverses this ByteBuffer's contents.
4113 * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
4114 * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
4115 * @returns {!ByteBuffer} this
4116 * @expose
4117 */
4118 ByteBufferPrototype.reverse = function(begin, end) {
4119 if (typeof begin === 'undefined') begin = this.offset;
4120 if (typeof end === 'undefined') end = this.limit;
4121 if (!this.noAssert) {
4122 if (typeof begin !== 'number' || begin % 1 !== 0)
4123 throw TypeError("Illegal begin: Not an integer");
4124 begin >>>= 0;
4125 if (typeof end !== 'number' || end % 1 !== 0)
4126 throw TypeError("Illegal end: Not an integer");
4127 end >>>= 0;
4128 if (begin < 0 || begin > end || end > this.buffer.byteLength)
4129 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
4130 }
4131 if (begin === end)
4132 return this; // Nothing to reverse
4133 Array.prototype.reverse.call(this.view.subarray(begin, end));
4134 return this;
4135 };
4136 /**
4137 * Skips the next `length` bytes. This will just advance
4138 * @param {number} length Number of bytes to skip. May also be negative to move the offset back.
4139 * @returns {!ByteBuffer} this
4140 * @expose
4141 */
4142 ByteBufferPrototype.skip = function(length) {
4143 if (!this.noAssert) {
4144 if (typeof length !== 'number' || length % 1 !== 0)
4145 throw TypeError("Illegal length: "+length+" (not an integer)");
4146 length |= 0;
4147 }
4148 var offset = this.offset + length;
4149 if (!this.noAssert) {
4150 if (offset < 0 || offset > this.buffer.byteLength)
4151 throw RangeError("Illegal length: 0 <= "+this.offset+" + "+length+" <= "+this.buffer.byteLength);
4152 }
4153 this.offset = offset;
4154 return this;
4155 };
4156
4157 /**
4158 * Slices this ByteBuffer by creating a cloned instance with `offset = begin` and `limit = end`.
4159 * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
4160 * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
4161 * @returns {!ByteBuffer} Clone of this ByteBuffer with slicing applied, backed by the same {@link ByteBuffer#buffer}
4162 * @expose
4163 */
4164 ByteBufferPrototype.slice = function(begin, end) {
4165 if (typeof begin === 'undefined') begin = this.offset;
4166 if (typeof end === 'undefined') end = this.limit;
4167 if (!this.noAssert) {
4168 if (typeof begin !== 'number' || begin % 1 !== 0)
4169 throw TypeError("Illegal begin: Not an integer");
4170 begin >>>= 0;
4171 if (typeof end !== 'number' || end % 1 !== 0)
4172 throw TypeError("Illegal end: Not an integer");
4173 end >>>= 0;
4174 if (begin < 0 || begin > end || end > this.buffer.byteLength)
4175 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
4176 }
4177 var bb = this.clone();
4178 bb.offset = begin;
4179 bb.limit = end;
4180 return bb;
4181 };
4182 /**
4183 * Returns a copy of the backing buffer that contains this ByteBuffer's contents. Contents are the bytes between
4184 * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
4185 * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory if
4186 * possible. Defaults to `false`
4187 * @returns {!ArrayBuffer} Contents as an ArrayBuffer
4188 * @expose
4189 */
4190 ByteBufferPrototype.toBuffer = function(forceCopy) {
4191 var offset = this.offset,
4192 limit = this.limit;
4193 if (!this.noAssert) {
4194 if (typeof offset !== 'number' || offset % 1 !== 0)
4195 throw TypeError("Illegal offset: Not an integer");
4196 offset >>>= 0;
4197 if (typeof limit !== 'number' || limit % 1 !== 0)
4198 throw TypeError("Illegal limit: Not an integer");
4199 limit >>>= 0;
4200 if (offset < 0 || offset > limit || limit > this.buffer.byteLength)
4201 throw RangeError("Illegal range: 0 <= "+offset+" <= "+limit+" <= "+this.buffer.byteLength);
4202 }
4203 // NOTE: It's not possible to have another ArrayBuffer reference the same memory as the backing buffer. This is
4204 // possible with Uint8Array#subarray only, but we have to return an ArrayBuffer by contract. So:
4205 if (!forceCopy && offset === 0 && limit === this.buffer.byteLength)
4206 return this.buffer;
4207 if (offset === limit)
4208 return EMPTY_BUFFER;
4209 var buffer = new ArrayBuffer(limit - offset);
4210 new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(offset, limit), 0);
4211 return buffer;
4212 };
4213
4214 /**
4215 * Returns a raw buffer compacted to contain this ByteBuffer's contents. Contents are the bytes between
4216 * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. This is an alias of {@link ByteBuffer#toBuffer}.
4217 * @function
4218 * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory.
4219 * Defaults to `false`
4220 * @returns {!ArrayBuffer} Contents as an ArrayBuffer
4221 * @expose
4222 */
4223 ByteBufferPrototype.toArrayBuffer = ByteBufferPrototype.toBuffer;
4224
4225 /**
4226 * Converts the ByteBuffer's contents to a string.
4227 * @param {string=} encoding Output encoding. Returns an informative string representation if omitted but also allows
4228 * direct conversion to "utf8", "hex", "base64" and "binary" encoding. "debug" returns a hex representation with
4229 * highlighted offsets.
4230 * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}
4231 * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
4232 * @returns {string} String representation
4233 * @throws {Error} If `encoding` is invalid
4234 * @expose
4235 */
4236 ByteBufferPrototype.toString = function(encoding, begin, end) {
4237 if (typeof encoding === 'undefined')
4238 return "ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+")";
4239 if (typeof encoding === 'number')
4240 encoding = "utf8",
4241 begin = encoding,
4242 end = begin;
4243 switch (encoding) {
4244 case "utf8":
4245 return this.toUTF8(begin, end);
4246 case "base64":
4247 return this.toBase64(begin, end);
4248 case "hex":
4249 return this.toHex(begin, end);
4250 case "binary":
4251 return this.toBinary(begin, end);
4252 case "debug":
4253 return this.toDebug();
4254 case "columns":
4255 return this.toColumns();
4256 default:
4257 throw Error("Unsupported encoding: "+encoding);
4258 }
4259 };
4260
4261 // lxiv-embeddable
4262
4263 /**
4264 * lxiv-embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io>
4265 * Released under the Apache License, Version 2.0
4266 * see: https://github.com/dcodeIO/lxiv for details
4267 */
4268 var lxiv = function() {
4269
4270 /**
4271 * lxiv namespace.
4272 * @type {!Object.<string,*>}
4273 * @exports lxiv
4274 */
4275 var lxiv = {};
4276
4277 /**
4278 * Character codes for output.
4279 * @type {!Array.<number>}
4280 * @inner
4281 */
4282 var aout = [
4283 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
4284 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102,
4285 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118,
4286 119, 120, 121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47
4287 ];
4288
4289 /**
4290 * Character codes for input.
4291 * @type {!Array.<number>}
4292 * @inner
4293 */
4294 var ain = [];
4295 for (var i=0, k=aout.length; i<k; ++i)
4296 ain[aout[i]] = i;
4297
4298 /**
4299 * Encodes bytes to base64 char codes.
4300 * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if
4301 * there are no more bytes left.
4302 * @param {!function(number)} dst Characters destination as a function successively called with each encoded char
4303 * code.
4304 */
4305 lxiv.encode = function(src, dst) {
4306 var b, t;
4307 while ((b = src()) !== null) {
4308 dst(aout[(b>>2)&0x3f]);
4309 t = (b&0x3)<<4;
4310 if ((b = src()) !== null) {
4311 t |= (b>>4)&0xf;
4312 dst(aout[(t|((b>>4)&0xf))&0x3f]);
4313 t = (b&0xf)<<2;
4314 if ((b = src()) !== null)
4315 dst(aout[(t|((b>>6)&0x3))&0x3f]),
4316 dst(aout[b&0x3f]);
4317 else
4318 dst(aout[t&0x3f]),
4319 dst(61);
4320 } else
4321 dst(aout[t&0x3f]),
4322 dst(61),
4323 dst(61);
4324 }
4325 };
4326
4327 /**
4328 * Decodes base64 char codes to bytes.
4329 * @param {!function():number|null} src Characters source as a function returning the next char code respectively
4330 * `null` if there are no more characters left.
4331 * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
4332 * @throws {Error} If a character code is invalid
4333 */
4334 lxiv.decode = function(src, dst) {
4335 var c, t1, t2;
4336 function fail(c) {
4337 throw Error("Illegal character code: "+c);
4338 }
4339 while ((c = src()) !== null) {
4340 t1 = ain[c];
4341 if (typeof t1 === 'undefined') fail(c);
4342 if ((c = src()) !== null) {
4343 t2 = ain[c];
4344 if (typeof t2 === 'undefined') fail(c);
4345 dst((t1<<2)>>>0|(t2&0x30)>>4);
4346 if ((c = src()) !== null) {
4347 t1 = ain[c];
4348 if (typeof t1 === 'undefined')
4349 if (c === 61) break; else fail(c);
4350 dst(((t2&0xf)<<4)>>>0|(t1&0x3c)>>2);
4351 if ((c = src()) !== null) {
4352 t2 = ain[c];
4353 if (typeof t2 === 'undefined')
4354 if (c === 61) break; else fail(c);
4355 dst(((t1&0x3)<<6)>>>0|t2);
4356 }
4357 }
4358 }
4359 }
4360 };
4361
4362 /**
4363 * Tests if a string is valid base64.
4364 * @param {string} str String to test
4365 * @returns {boolean} `true` if valid, otherwise `false`
4366 */
4367 lxiv.test = function(str) {
4368 return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(str);
4369 };
4370
4371 return lxiv;
4372 }();
4373
4374 // encodings/base64
4375
4376 /**
4377 * Encodes this ByteBuffer's contents to a base64 encoded string.
4378 * @param {number=} begin Offset to begin at, defaults to {@link ByteBuffer#offset}.
4379 * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}.
4380 * @returns {string} Base64 encoded string
4381 * @throws {RangeError} If `begin` or `end` is out of bounds
4382 * @expose
4383 */
4384 ByteBufferPrototype.toBase64 = function(begin, end) {
4385 if (typeof begin === 'undefined')
4386 begin = this.offset;
4387 if (typeof end === 'undefined')
4388 end = this.limit;
4389 begin = begin | 0; end = end | 0;
4390 if (begin < 0 || end > this.capacity || begin > end)
4391 throw RangeError("begin, end");
4392 var sd; lxiv.encode(function() {
4393 return begin < end ? this.view[begin++] : null;
4394 }.bind(this), sd = stringDestination());
4395 return sd();
4396 };
4397
4398 /**
4399 * Decodes a base64 encoded string to a ByteBuffer.
4400 * @param {string} str String to decode
4401 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
4402 * {@link ByteBuffer.DEFAULT_ENDIAN}.
4403 * @returns {!ByteBuffer} ByteBuffer
4404 * @expose
4405 */
4406 ByteBuffer.fromBase64 = function(str, littleEndian) {
4407 if (typeof str !== 'string')
4408 throw TypeError("str");
4409 var bb = new ByteBuffer(str.length/4*3, littleEndian),
4410 i = 0;
4411 lxiv.decode(stringSource(str), function(b) {
4412 bb.view[i++] = b;
4413 });
4414 bb.limit = i;
4415 return bb;
4416 };
4417
4418 /**
4419 * Encodes a binary string to base64 like `window.btoa` does.
4420 * @param {string} str Binary string
4421 * @returns {string} Base64 encoded string
4422 * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.btoa
4423 * @expose
4424 */
4425 ByteBuffer.btoa = function(str) {
4426 return ByteBuffer.fromBinary(str).toBase64();
4427 };
4428
4429 /**
4430 * Decodes a base64 encoded string to binary like `window.atob` does.
4431 * @param {string} b64 Base64 encoded string
4432 * @returns {string} Binary string
4433 * @see https://developer.mozilla.org/en-US/docs/Web/API/Window.atob
4434 * @expose
4435 */
4436 ByteBuffer.atob = function(b64) {
4437 return ByteBuffer.fromBase64(b64).toBinary();
4438 };
4439
4440 // encodings/binary
4441
4442 /**
4443 * Encodes this ByteBuffer to a binary encoded string, that is using only characters 0x00-0xFF as bytes.
4444 * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}.
4445 * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}.
4446 * @returns {string} Binary encoded string
4447 * @throws {RangeError} If `offset > limit`
4448 * @expose
4449 */
4450 ByteBufferPrototype.toBinary = function(begin, end) {
4451 if (typeof begin === 'undefined')
4452 begin = this.offset;
4453 if (typeof end === 'undefined')
4454 end = this.limit;
4455 begin |= 0; end |= 0;
4456 if (begin < 0 || end > this.capacity() || begin > end)
4457 throw RangeError("begin, end");
4458 if (begin === end)
4459 return "";
4460 var chars = [],
4461 parts = [];
4462 while (begin < end) {
4463 chars.push(this.view[begin++]);
4464 if (chars.length >= 1024)
4465 parts.push(String.fromCharCode.apply(String, chars)),
4466 chars = [];
4467 }
4468 return parts.join('') + String.fromCharCode.apply(String, chars);
4469 };
4470
4471 /**
4472 * Decodes a binary encoded string, that is using only characters 0x00-0xFF as bytes, to a ByteBuffer.
4473 * @param {string} str String to decode
4474 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
4475 * {@link ByteBuffer.DEFAULT_ENDIAN}.
4476 * @returns {!ByteBuffer} ByteBuffer
4477 * @expose
4478 */
4479 ByteBuffer.fromBinary = function(str, littleEndian) {
4480 if (typeof str !== 'string')
4481 throw TypeError("str");
4482 var i = 0,
4483 k = str.length,
4484 charCode,
4485 bb = new ByteBuffer(k, littleEndian);
4486 while (i<k) {
4487 charCode = str.charCodeAt(i);
4488 if (charCode > 0xff)
4489 throw RangeError("illegal char code: "+charCode);
4490 bb.view[i++] = charCode;
4491 }
4492 bb.limit = k;
4493 return bb;
4494 };
4495
4496 // encodings/debug
4497
4498 /**
4499 * Encodes this ByteBuffer to a hex encoded string with marked offsets. Offset symbols are:
4500 * * `<` : offset,
4501 * * `'` : markedOffset,
4502 * * `>` : limit,
4503 * * `|` : offset and limit,
4504 * * `[` : offset and markedOffset,
4505 * * `]` : markedOffset and limit,
4506 * * `!` : offset, markedOffset and limit
4507 * @param {boolean=} columns If `true` returns two columns hex + ascii, defaults to `false`
4508 * @returns {string|!Array.<string>} Debug string or array of lines if `asArray = true`
4509 * @expose
4510 * @example `>00'01 02<03` contains four bytes with `limit=0, markedOffset=1, offset=3`
4511 * @example `00[01 02 03>` contains four bytes with `offset=markedOffset=1, limit=4`
4512 * @example `00|01 02 03` contains four bytes with `offset=limit=1, markedOffset=-1`
4513 * @example `|` contains zero bytes with `offset=limit=0, markedOffset=-1`
4514 */
4515 ByteBufferPrototype.toDebug = function(columns) {
4516 var i = -1,
4517 k = this.buffer.byteLength,
4518 b,
4519 hex = "",
4520 asc = "",
4521 out = "";
4522 while (i<k) {
4523 if (i !== -1) {
4524 b = this.view[i];
4525 if (b < 0x10) hex += "0"+b.toString(16).toUpperCase();
4526 else hex += b.toString(16).toUpperCase();
4527 if (columns)
4528 asc += b > 32 && b < 127 ? String.fromCharCode(b) : '.';
4529 }
4530 ++i;
4531 if (columns) {
4532 if (i > 0 && i % 16 === 0 && i !== k) {
4533 while (hex.length < 3*16+3) hex += " ";
4534 out += hex+asc+"\n";
4535 hex = asc = "";
4536 }
4537 }
4538 if (i === this.offset && i === this.limit)
4539 hex += i === this.markedOffset ? "!" : "|";
4540 else if (i === this.offset)
4541 hex += i === this.markedOffset ? "[" : "<";
4542 else if (i === this.limit)
4543 hex += i === this.markedOffset ? "]" : ">";
4544 else
4545 hex += i === this.markedOffset ? "'" : (columns || (i !== 0 && i !== k) ? " " : "");
4546 }
4547 if (columns && hex !== " ") {
4548 while (hex.length < 3*16+3)
4549 hex += " ";
4550 out += hex + asc + "\n";
4551 }
4552 return columns ? out : hex;
4553 };
4554
4555 /**
4556 * Decodes a hex encoded string with marked offsets to a ByteBuffer.
4557 * @param {string} str Debug string to decode (not be generated with `columns = true`)
4558 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
4559 * {@link ByteBuffer.DEFAULT_ENDIAN}.
4560 * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
4561 * {@link ByteBuffer.DEFAULT_NOASSERT}.
4562 * @returns {!ByteBuffer} ByteBuffer
4563 * @expose
4564 * @see ByteBuffer#toDebug
4565 */
4566 ByteBuffer.fromDebug = function(str, littleEndian, noAssert) {
4567 var k = str.length,
4568 bb = new ByteBuffer(((k+1)/3)|0, littleEndian, noAssert);
4569 var i = 0, j = 0, ch, b,
4570 rs = false, // Require symbol next
4571 ho = false, hm = false, hl = false, // Already has offset (ho), markedOffset (hm), limit (hl)?
4572 fail = false;
4573 while (i<k) {
4574 switch (ch = str.charAt(i++)) {
4575 case '!':
4576 if (!noAssert) {
4577 if (ho || hm || hl) {
4578 fail = true;
4579 break;
4580 }
4581 ho = hm = hl = true;
4582 }
4583 bb.offset = bb.markedOffset = bb.limit = j;
4584 rs = false;
4585 break;
4586 case '|':
4587 if (!noAssert) {
4588 if (ho || hl) {
4589 fail = true;
4590 break;
4591 }
4592 ho = hl = true;
4593 }
4594 bb.offset = bb.limit = j;
4595 rs = false;
4596 break;
4597 case '[':
4598 if (!noAssert) {
4599 if (ho || hm) {
4600 fail = true;
4601 break;
4602 }
4603 ho = hm = true;
4604 }
4605 bb.offset = bb.markedOffset = j;
4606 rs = false;
4607 break;
4608 case '<':
4609 if (!noAssert) {
4610 if (ho) {
4611 fail = true;
4612 break;
4613 }
4614 ho = true;
4615 }
4616 bb.offset = j;
4617 rs = false;
4618 break;
4619 case ']':
4620 if (!noAssert) {
4621 if (hl || hm) {
4622 fail = true;
4623 break;
4624 }
4625 hl = hm = true;
4626 }
4627 bb.limit = bb.markedOffset = j;
4628 rs = false;
4629 break;
4630 case '>':
4631 if (!noAssert) {
4632 if (hl) {
4633 fail = true;
4634 break;
4635 }
4636 hl = true;
4637 }
4638 bb.limit = j;
4639 rs = false;
4640 break;
4641 case "'":
4642 if (!noAssert) {
4643 if (hm) {
4644 fail = true;
4645 break;
4646 }
4647 hm = true;
4648 }
4649 bb.markedOffset = j;
4650 rs = false;
4651 break;
4652 case ' ':
4653 rs = false;
4654 break;
4655 default:
4656 if (!noAssert) {
4657 if (rs) {
4658 fail = true;
4659 break;
4660 }
4661 }
4662 b = parseInt(ch+str.charAt(i++), 16);
4663 if (!noAssert) {
4664 if (isNaN(b) || b < 0 || b > 255)
4665 throw TypeError("Illegal str: Not a debug encoded string");
4666 }
4667 bb.view[j++] = b;
4668 rs = true;
4669 }
4670 if (fail)
4671 throw TypeError("Illegal str: Invalid symbol at "+i);
4672 }
4673 if (!noAssert) {
4674 if (!ho || !hl)
4675 throw TypeError("Illegal str: Missing offset or limit");
4676 if (j<bb.buffer.byteLength)
4677 throw TypeError("Illegal str: Not a debug encoded string (is it hex?) "+j+" < "+k);
4678 }
4679 return bb;
4680 };
4681
4682 // encodings/hex
4683
4684 /**
4685 * Encodes this ByteBuffer's contents to a hex encoded string.
4686 * @param {number=} begin Offset to begin at. Defaults to {@link ByteBuffer#offset}.
4687 * @param {number=} end Offset to end at. Defaults to {@link ByteBuffer#limit}.
4688 * @returns {string} Hex encoded string
4689 * @expose
4690 */
4691 ByteBufferPrototype.toHex = function(begin, end) {
4692 begin = typeof begin === 'undefined' ? this.offset : begin;
4693 end = typeof end === 'undefined' ? this.limit : end;
4694 if (!this.noAssert) {
4695 if (typeof begin !== 'number' || begin % 1 !== 0)
4696 throw TypeError("Illegal begin: Not an integer");
4697 begin >>>= 0;
4698 if (typeof end !== 'number' || end % 1 !== 0)
4699 throw TypeError("Illegal end: Not an integer");
4700 end >>>= 0;
4701 if (begin < 0 || begin > end || end > this.buffer.byteLength)
4702 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
4703 }
4704 var out = new Array(end - begin),
4705 b;
4706 while (begin < end) {
4707 b = this.view[begin++];
4708 if (b < 0x10)
4709 out.push("0", b.toString(16));
4710 else out.push(b.toString(16));
4711 }
4712 return out.join('');
4713 };
4714
4715 /**
4716 * Decodes a hex encoded string to a ByteBuffer.
4717 * @param {string} str String to decode
4718 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
4719 * {@link ByteBuffer.DEFAULT_ENDIAN}.
4720 * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
4721 * {@link ByteBuffer.DEFAULT_NOASSERT}.
4722 * @returns {!ByteBuffer} ByteBuffer
4723 * @expose
4724 */
4725 ByteBuffer.fromHex = function(str, littleEndian, noAssert) {
4726 if (!noAssert) {
4727 if (typeof str !== 'string')
4728 throw TypeError("Illegal str: Not a string");
4729 if (str.length % 2 !== 0)
4730 throw TypeError("Illegal str: Length not a multiple of 2");
4731 }
4732 var k = str.length,
4733 bb = new ByteBuffer((k / 2) | 0, littleEndian),
4734 b;
4735 for (var i=0, j=0; i<k; i+=2) {
4736 b = parseInt(str.substring(i, i+2), 16);
4737 if (!noAssert)
4738 if (!isFinite(b) || b < 0 || b > 255)
4739 throw TypeError("Illegal str: Contains non-hex characters");
4740 bb.view[j++] = b;
4741 }
4742 bb.limit = j;
4743 return bb;
4744 };
4745
4746 // utfx-embeddable
4747
4748 /**
4749 * utfx-embeddable (c) 2014 Daniel Wirtz <dcode@dcode.io>
4750 * Released under the Apache License, Version 2.0
4751 * see: https://github.com/dcodeIO/utfx for details
4752 */
4753 var utfx = function() {
4754
4755 /**
4756 * utfx namespace.
4757 * @inner
4758 * @type {!Object.<string,*>}
4759 */
4760 var utfx = {};
4761
4762 /**
4763 * Maximum valid code point.
4764 * @type {number}
4765 * @const
4766 */
4767 utfx.MAX_CODEPOINT = 0x10FFFF;
4768
4769 /**
4770 * Encodes UTF8 code points to UTF8 bytes.
4771 * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
4772 * respectively `null` if there are no more code points left or a single numeric code point.
4773 * @param {!function(number)} dst Bytes destination as a function successively called with the next byte
4774 */
4775 utfx.encodeUTF8 = function(src, dst) {
4776 var cp = null;
4777 if (typeof src === 'number')
4778 cp = src,
4779 src = function() { return null; };
4780 while (cp !== null || (cp = src()) !== null) {
4781 if (cp < 0x80)
4782 dst(cp&0x7F);
4783 else if (cp < 0x800)
4784 dst(((cp>>6)&0x1F)|0xC0),
4785 dst((cp&0x3F)|0x80);
4786 else if (cp < 0x10000)
4787 dst(((cp>>12)&0x0F)|0xE0),
4788 dst(((cp>>6)&0x3F)|0x80),
4789 dst((cp&0x3F)|0x80);
4790 else
4791 dst(((cp>>18)&0x07)|0xF0),
4792 dst(((cp>>12)&0x3F)|0x80),
4793 dst(((cp>>6)&0x3F)|0x80),
4794 dst((cp&0x3F)|0x80);
4795 cp = null;
4796 }
4797 };
4798
4799 /**
4800 * Decodes UTF8 bytes to UTF8 code points.
4801 * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
4802 * are no more bytes left.
4803 * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point.
4804 * @throws {RangeError} If a starting byte is invalid in UTF8
4805 * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the
4806 * remaining bytes.
4807 */
4808 utfx.decodeUTF8 = function(src, dst) {
4809 var a, b, c, d, fail = function(b) {
4810 b = b.slice(0, b.indexOf(null));
4811 var err = Error(b.toString());
4812 err.name = "TruncatedError";
4813 err['bytes'] = b;
4814 throw err;
4815 };
4816 while ((a = src()) !== null) {
4817 if ((a&0x80) === 0)
4818 dst(a);
4819 else if ((a&0xE0) === 0xC0)
4820 ((b = src()) === null) && fail([a, b]),
4821 dst(((a&0x1F)<<6) | (b&0x3F));
4822 else if ((a&0xF0) === 0xE0)
4823 ((b=src()) === null || (c=src()) === null) && fail([a, b, c]),
4824 dst(((a&0x0F)<<12) | ((b&0x3F)<<6) | (c&0x3F));
4825 else if ((a&0xF8) === 0xF0)
4826 ((b=src()) === null || (c=src()) === null || (d=src()) === null) && fail([a, b, c ,d]),
4827 dst(((a&0x07)<<18) | ((b&0x3F)<<12) | ((c&0x3F)<<6) | (d&0x3F));
4828 else throw RangeError("Illegal starting byte: "+a);
4829 }
4830 };
4831
4832 /**
4833 * Converts UTF16 characters to UTF8 code points.
4834 * @param {!function():number|null} src Characters source as a function returning the next char code respectively
4835 * `null` if there are no more characters left.
4836 * @param {!function(number)} dst Code points destination as a function successively called with each converted code
4837 * point.
4838 */
4839 utfx.UTF16toUTF8 = function(src, dst) {
4840 var c1, c2 = null;
4841 while (true) {
4842 if ((c1 = c2 !== null ? c2 : src()) === null)
4843 break;
4844 if (c1 >= 0xD800 && c1 <= 0xDFFF) {
4845 if ((c2 = src()) !== null) {
4846 if (c2 >= 0xDC00 && c2 <= 0xDFFF) {
4847 dst((c1-0xD800)*0x400+c2-0xDC00+0x10000);
4848 c2 = null; continue;
4849 }
4850 }
4851 }
4852 dst(c1);
4853 }
4854 if (c2 !== null) dst(c2);
4855 };
4856
4857 /**
4858 * Converts UTF8 code points to UTF16 characters.
4859 * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
4860 * respectively `null` if there are no more code points left or a single numeric code point.
4861 * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
4862 * @throws {RangeError} If a code point is out of range
4863 */
4864 utfx.UTF8toUTF16 = function(src, dst) {
4865 var cp = null;
4866 if (typeof src === 'number')
4867 cp = src, src = function() { return null; };
4868 while (cp !== null || (cp = src()) !== null) {
4869 if (cp <= 0xFFFF)
4870 dst(cp);
4871 else
4872 cp -= 0x10000,
4873 dst((cp>>10)+0xD800),
4874 dst((cp%0x400)+0xDC00);
4875 cp = null;
4876 }
4877 };
4878
4879 /**
4880 * Converts and encodes UTF16 characters to UTF8 bytes.
4881 * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null`
4882 * if there are no more characters left.
4883 * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
4884 */
4885 utfx.encodeUTF16toUTF8 = function(src, dst) {
4886 utfx.UTF16toUTF8(src, function(cp) {
4887 utfx.encodeUTF8(cp, dst);
4888 });
4889 };
4890
4891 /**
4892 * Decodes and converts UTF8 bytes to UTF16 characters.
4893 * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
4894 * are no more bytes left.
4895 * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
4896 * @throws {RangeError} If a starting byte is invalid in UTF8
4897 * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes.
4898 */
4899 utfx.decodeUTF8toUTF16 = function(src, dst) {
4900 utfx.decodeUTF8(src, function(cp) {
4901 utfx.UTF8toUTF16(cp, dst);
4902 });
4903 };
4904
4905 /**
4906 * Calculates the byte length of an UTF8 code point.
4907 * @param {number} cp UTF8 code point
4908 * @returns {number} Byte length
4909 */
4910 utfx.calculateCodePoint = function(cp) {
4911 return (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
4912 };
4913
4914 /**
4915 * Calculates the number of UTF8 bytes required to store UTF8 code points.
4916 * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively
4917 * `null` if there are no more code points left.
4918 * @returns {number} The number of UTF8 bytes required
4919 */
4920 utfx.calculateUTF8 = function(src) {
4921 var cp, l=0;
4922 while ((cp = src()) !== null)
4923 l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
4924 return l;
4925 };
4926
4927 /**
4928 * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes.
4929 * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively
4930 * `null` if there are no more characters left.
4931 * @returns {!Array.<number>} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1.
4932 */
4933 utfx.calculateUTF16asUTF8 = function(src) {
4934 var n=0, l=0;
4935 utfx.UTF16toUTF8(src, function(cp) {
4936 ++n; l += (cp < 0x80) ? 1 : (cp < 0x800) ? 2 : (cp < 0x10000) ? 3 : 4;
4937 });
4938 return [n,l];
4939 };
4940
4941 return utfx;
4942 }();
4943
4944 // encodings/utf8
4945
4946 /**
4947 * Encodes this ByteBuffer's contents between {@link ByteBuffer#offset} and {@link ByteBuffer#limit} to an UTF8 encoded
4948 * string.
4949 * @returns {string} Hex encoded string
4950 * @throws {RangeError} If `offset > limit`
4951 * @expose
4952 */
4953 ByteBufferPrototype.toUTF8 = function(begin, end) {
4954 if (typeof begin === 'undefined') begin = this.offset;
4955 if (typeof end === 'undefined') end = this.limit;
4956 if (!this.noAssert) {
4957 if (typeof begin !== 'number' || begin % 1 !== 0)
4958 throw TypeError("Illegal begin: Not an integer");
4959 begin >>>= 0;
4960 if (typeof end !== 'number' || end % 1 !== 0)
4961 throw TypeError("Illegal end: Not an integer");
4962 end >>>= 0;
4963 if (begin < 0 || begin > end || end > this.buffer.byteLength)
4964 throw RangeError("Illegal range: 0 <= "+begin+" <= "+end+" <= "+this.buffer.byteLength);
4965 }
4966 var sd; try {
4967 utfx.decodeUTF8toUTF16(function() {
4968 return begin < end ? this.view[begin++] : null;
4969 }.bind(this), sd = stringDestination());
4970 } catch (e) {
4971 if (begin !== end)
4972 throw RangeError("Illegal range: Truncated data, "+begin+" != "+end);
4973 }
4974 return sd();
4975 };
4976
4977 /**
4978 * Decodes an UTF8 encoded string to a ByteBuffer.
4979 * @param {string} str String to decode
4980 * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
4981 * {@link ByteBuffer.DEFAULT_ENDIAN}.
4982 * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
4983 * {@link ByteBuffer.DEFAULT_NOASSERT}.
4984 * @returns {!ByteBuffer} ByteBuffer
4985 * @expose
4986 */
4987 ByteBuffer.fromUTF8 = function(str, littleEndian, noAssert) {
4988 if (!noAssert)
4989 if (typeof str !== 'string')
4990 throw TypeError("Illegal str: Not a string");
4991 var bb = new ByteBuffer(utfx.calculateUTF16asUTF8(stringSource(str), true)[1], littleEndian, noAssert),
4992 i = 0;
4993 utfx.encodeUTF16toUTF8(stringSource(str), function(b) {
4994 bb.view[i++] = b;
4995 });
4996 bb.limit = i;
4997 return bb;
4998 };
4999
5000 return ByteBuffer;
5001 });
5002 });
5003
5004 var _nodeResolve_empty = {};
5005
5006 var _nodeResolve_empty$1 = /*#__PURE__*/Object.freeze({
5007 __proto__: null,
5008 'default': _nodeResolve_empty
5009 });
5010
5011 var require$$2 = getCjsExportFromNamespace(_nodeResolve_empty$1);
5012
5013 var protobufLight = createCommonjsModule(function (module) {
5014 /*
5015 Copyright 2013 Daniel Wirtz <dcode@dcode.io>
5016
5017 Licensed under the Apache License, Version 2.0 (the "License");
5018 you may not use this file except in compliance with the License.
5019 You may obtain a copy of the License at
5020
5021 http://www.apache.org/licenses/LICENSE-2.0
5022
5023 Unless required by applicable law or agreed to in writing, software
5024 distributed under the License is distributed on an "AS IS" BASIS,
5025 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5026 See the License for the specific language governing permissions and
5027 limitations under the License.
5028 */
5029
5030 /**
5031 * @license protobuf.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
5032 * Released under the Apache License, Version 2.0
5033 * see: https://github.com/dcodeIO/protobuf.js for details
5034 */
5035 (function(global, factory) {
5036
5037 /* AMD */ if (typeof commonjsRequire === "function" && 'object' === "object" && module && module["exports"])
5038 module["exports"] = factory(bytebuffer, true);
5039 /* Global */ else
5040 (global["dcodeIO"] = global["dcodeIO"] || {})["ProtoBuf"] = factory(global["dcodeIO"]["ByteBuffer"]);
5041
5042 })(commonjsGlobal, function(ByteBuffer, isCommonJS) {
5043
5044 /**
5045 * The ProtoBuf namespace.
5046 * @exports ProtoBuf
5047 * @namespace
5048 * @expose
5049 */
5050 var ProtoBuf = {};
5051
5052 /**
5053 * @type {!function(new: ByteBuffer, ...[*])}
5054 * @expose
5055 */
5056 ProtoBuf.ByteBuffer = ByteBuffer;
5057
5058 /**
5059 * @type {?function(new: Long, ...[*])}
5060 * @expose
5061 */
5062 ProtoBuf.Long = ByteBuffer.Long || null;
5063
5064 /**
5065 * ProtoBuf.js version.
5066 * @type {string}
5067 * @const
5068 * @expose
5069 */
5070 ProtoBuf.VERSION = "5.0.3";
5071
5072 /**
5073 * Wire types.
5074 * @type {Object.<string,number>}
5075 * @const
5076 * @expose
5077 */
5078 ProtoBuf.WIRE_TYPES = {};
5079
5080 /**
5081 * Varint wire type.
5082 * @type {number}
5083 * @expose
5084 */
5085 ProtoBuf.WIRE_TYPES.VARINT = 0;
5086
5087 /**
5088 * Fixed 64 bits wire type.
5089 * @type {number}
5090 * @const
5091 * @expose
5092 */
5093 ProtoBuf.WIRE_TYPES.BITS64 = 1;
5094
5095 /**
5096 * Length delimited wire type.
5097 * @type {number}
5098 * @const
5099 * @expose
5100 */
5101 ProtoBuf.WIRE_TYPES.LDELIM = 2;
5102
5103 /**
5104 * Start group wire type.
5105 * @type {number}
5106 * @const
5107 * @expose
5108 */
5109 ProtoBuf.WIRE_TYPES.STARTGROUP = 3;
5110
5111 /**
5112 * End group wire type.
5113 * @type {number}
5114 * @const
5115 * @expose
5116 */
5117 ProtoBuf.WIRE_TYPES.ENDGROUP = 4;
5118
5119 /**
5120 * Fixed 32 bits wire type.
5121 * @type {number}
5122 * @const
5123 * @expose
5124 */
5125 ProtoBuf.WIRE_TYPES.BITS32 = 5;
5126
5127 /**
5128 * Packable wire types.
5129 * @type {!Array.<number>}
5130 * @const
5131 * @expose
5132 */
5133 ProtoBuf.PACKABLE_WIRE_TYPES = [
5134 ProtoBuf.WIRE_TYPES.VARINT,
5135 ProtoBuf.WIRE_TYPES.BITS64,
5136 ProtoBuf.WIRE_TYPES.BITS32
5137 ];
5138
5139 /**
5140 * Types.
5141 * @dict
5142 * @type {!Object.<string,{name: string, wireType: number, defaultValue: *}>}
5143 * @const
5144 * @expose
5145 */
5146 ProtoBuf.TYPES = {
5147 // According to the protobuf spec.
5148 "int32": {
5149 name: "int32",
5150 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5151 defaultValue: 0
5152 },
5153 "uint32": {
5154 name: "uint32",
5155 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5156 defaultValue: 0
5157 },
5158 "sint32": {
5159 name: "sint32",
5160 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5161 defaultValue: 0
5162 },
5163 "int64": {
5164 name: "int64",
5165 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5166 defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined
5167 },
5168 "uint64": {
5169 name: "uint64",
5170 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5171 defaultValue: ProtoBuf.Long ? ProtoBuf.Long.UZERO : undefined
5172 },
5173 "sint64": {
5174 name: "sint64",
5175 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5176 defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined
5177 },
5178 "bool": {
5179 name: "bool",
5180 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5181 defaultValue: false
5182 },
5183 "double": {
5184 name: "double",
5185 wireType: ProtoBuf.WIRE_TYPES.BITS64,
5186 defaultValue: 0
5187 },
5188 "string": {
5189 name: "string",
5190 wireType: ProtoBuf.WIRE_TYPES.LDELIM,
5191 defaultValue: ""
5192 },
5193 "bytes": {
5194 name: "bytes",
5195 wireType: ProtoBuf.WIRE_TYPES.LDELIM,
5196 defaultValue: null // overridden in the code, must be a unique instance
5197 },
5198 "fixed32": {
5199 name: "fixed32",
5200 wireType: ProtoBuf.WIRE_TYPES.BITS32,
5201 defaultValue: 0
5202 },
5203 "sfixed32": {
5204 name: "sfixed32",
5205 wireType: ProtoBuf.WIRE_TYPES.BITS32,
5206 defaultValue: 0
5207 },
5208 "fixed64": {
5209 name: "fixed64",
5210 wireType: ProtoBuf.WIRE_TYPES.BITS64,
5211 defaultValue: ProtoBuf.Long ? ProtoBuf.Long.UZERO : undefined
5212 },
5213 "sfixed64": {
5214 name: "sfixed64",
5215 wireType: ProtoBuf.WIRE_TYPES.BITS64,
5216 defaultValue: ProtoBuf.Long ? ProtoBuf.Long.ZERO : undefined
5217 },
5218 "float": {
5219 name: "float",
5220 wireType: ProtoBuf.WIRE_TYPES.BITS32,
5221 defaultValue: 0
5222 },
5223 "enum": {
5224 name: "enum",
5225 wireType: ProtoBuf.WIRE_TYPES.VARINT,
5226 defaultValue: 0
5227 },
5228 "message": {
5229 name: "message",
5230 wireType: ProtoBuf.WIRE_TYPES.LDELIM,
5231 defaultValue: null
5232 },
5233 "group": {
5234 name: "group",
5235 wireType: ProtoBuf.WIRE_TYPES.STARTGROUP,
5236 defaultValue: null
5237 }
5238 };
5239
5240 /**
5241 * Valid map key types.
5242 * @type {!Array.<!Object.<string,{name: string, wireType: number, defaultValue: *}>>}
5243 * @const
5244 * @expose
5245 */
5246 ProtoBuf.MAP_KEY_TYPES = [
5247 ProtoBuf.TYPES["int32"],
5248 ProtoBuf.TYPES["sint32"],
5249 ProtoBuf.TYPES["sfixed32"],
5250 ProtoBuf.TYPES["uint32"],
5251 ProtoBuf.TYPES["fixed32"],
5252 ProtoBuf.TYPES["int64"],
5253 ProtoBuf.TYPES["sint64"],
5254 ProtoBuf.TYPES["sfixed64"],
5255 ProtoBuf.TYPES["uint64"],
5256 ProtoBuf.TYPES["fixed64"],
5257 ProtoBuf.TYPES["bool"],
5258 ProtoBuf.TYPES["string"],
5259 ProtoBuf.TYPES["bytes"]
5260 ];
5261
5262 /**
5263 * Minimum field id.
5264 * @type {number}
5265 * @const
5266 * @expose
5267 */
5268 ProtoBuf.ID_MIN = 1;
5269
5270 /**
5271 * Maximum field id.
5272 * @type {number}
5273 * @const
5274 * @expose
5275 */
5276 ProtoBuf.ID_MAX = 0x1FFFFFFF;
5277
5278 /**
5279 * If set to `true`, field names will be converted from underscore notation to camel case. Defaults to `false`.
5280 * Must be set prior to parsing.
5281 * @type {boolean}
5282 * @expose
5283 */
5284 ProtoBuf.convertFieldsToCamelCase = false;
5285
5286 /**
5287 * By default, messages are populated with (setX, set_x) accessors for each field. This can be disabled by
5288 * setting this to `false` prior to building messages.
5289 * @type {boolean}
5290 * @expose
5291 */
5292 ProtoBuf.populateAccessors = true;
5293
5294 /**
5295 * By default, messages are populated with default values if a field is not present on the wire. To disable
5296 * this behavior, set this setting to `false`.
5297 * @type {boolean}
5298 * @expose
5299 */
5300 ProtoBuf.populateDefaults = true;
5301
5302 /**
5303 * @alias ProtoBuf.Util
5304 * @expose
5305 */
5306 ProtoBuf.Util = (function() {
5307
5308 /**
5309 * ProtoBuf utilities.
5310 * @exports ProtoBuf.Util
5311 * @namespace
5312 */
5313 var Util = {};
5314
5315 /**
5316 * Flag if running in node or not.
5317 * @type {boolean}
5318 * @const
5319 * @expose
5320 */
5321 Util.IS_NODE = !!(
5322 typeof process === 'object' && process+'' === '[object process]' && !process['browser']
5323 );
5324
5325 /**
5326 * Constructs a XMLHttpRequest object.
5327 * @return {XMLHttpRequest}
5328 * @throws {Error} If XMLHttpRequest is not supported
5329 * @expose
5330 */
5331 Util.XHR = function() {
5332 // No dependencies please, ref: http://www.quirksmode.org/js/xmlhttp.html
5333 var XMLHttpFactories = [
5334 function () {return new XMLHttpRequest()},
5335 function () {return new ActiveXObject("Msxml2.XMLHTTP")},
5336 function () {return new ActiveXObject("Msxml3.XMLHTTP")},
5337 function () {return new ActiveXObject("Microsoft.XMLHTTP")}
5338 ];
5339 /** @type {?XMLHttpRequest} */
5340 var xhr = null;
5341 for (var i=0;i<XMLHttpFactories.length;i++) {
5342 try { xhr = XMLHttpFactories[i](); }
5343 catch (e) { continue; }
5344 break;
5345 }
5346 if (!xhr)
5347 throw Error("XMLHttpRequest is not supported");
5348 return xhr;
5349 };
5350
5351 /**
5352 * Fetches a resource.
5353 * @param {string} path Resource path
5354 * @param {function(?string)=} callback Callback receiving the resource's contents. If omitted the resource will
5355 * be fetched synchronously. If the request failed, contents will be null.
5356 * @return {?string|undefined} Resource contents if callback is omitted (null if the request failed), else undefined.
5357 * @expose
5358 */
5359 Util.fetch = function(path, callback) {
5360 if (callback && typeof callback != 'function')
5361 callback = null;
5362 if (Util.IS_NODE) {
5363 var fs = require$$2;
5364 if (callback) {
5365 fs.readFile(path, function(err, data) {
5366 if (err)
5367 callback(null);
5368 else
5369 callback(""+data);
5370 });
5371 } else
5372 try {
5373 return fs.readFileSync(path);
5374 } catch (e) {
5375 return null;
5376 }
5377 } else {
5378 var xhr = Util.XHR();
5379 xhr.open('GET', path, callback ? true : false);
5380 // xhr.setRequestHeader('User-Agent', 'XMLHTTP/1.0');
5381 xhr.setRequestHeader('Accept', 'text/plain');
5382 if (typeof xhr.overrideMimeType === 'function') xhr.overrideMimeType('text/plain');
5383 if (callback) {
5384 xhr.onreadystatechange = function() {
5385 if (xhr.readyState != 4) return;
5386 if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
5387 callback(xhr.responseText);
5388 else
5389 callback(null);
5390 };
5391 if (xhr.readyState == 4)
5392 return;
5393 xhr.send(null);
5394 } else {
5395 xhr.send(null);
5396 if (/* remote */ xhr.status == 200 || /* local */ (xhr.status == 0 && typeof xhr.responseText === 'string'))
5397 return xhr.responseText;
5398 return null;
5399 }
5400 }
5401 };
5402
5403 /**
5404 * Converts a string to camel case.
5405 * @param {string} str
5406 * @returns {string}
5407 * @expose
5408 */
5409 Util.toCamelCase = function(str) {
5410 return str.replace(/_([a-zA-Z])/g, function ($0, $1) {
5411 return $1.toUpperCase();
5412 });
5413 };
5414
5415 return Util;
5416 })();
5417
5418 /**
5419 * Language expressions.
5420 * @type {!Object.<string,!RegExp>}
5421 * @expose
5422 */
5423 ProtoBuf.Lang = {
5424
5425 // Characters always ending a statement
5426 DELIM: /[\s\{\}=;:\[\],'"\(\)<>]/g,
5427
5428 // Field rules
5429 RULE: /^(?:required|optional|repeated|map)$/,
5430
5431 // Field types
5432 TYPE: /^(?:double|float|int32|uint32|sint32|int64|uint64|sint64|fixed32|sfixed32|fixed64|sfixed64|bool|string|bytes)$/,
5433
5434 // Names
5435 NAME: /^[a-zA-Z_][a-zA-Z_0-9]*$/,
5436
5437 // Type definitions
5438 TYPEDEF: /^[a-zA-Z][a-zA-Z_0-9]*$/,
5439
5440 // Type references
5441 TYPEREF: /^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)(?:\.[a-zA-Z_][a-zA-Z_0-9]*)*$/,
5442
5443 // Fully qualified type references
5444 FQTYPEREF: /^(?:\.[a-zA-Z_][a-zA-Z_0-9]*)+$/,
5445
5446 // All numbers
5447 NUMBER: /^-?(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+|([0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)?)|inf|nan)$/,
5448
5449 // Decimal numbers
5450 NUMBER_DEC: /^(?:[1-9][0-9]*|0)$/,
5451
5452 // Hexadecimal numbers
5453 NUMBER_HEX: /^0[xX][0-9a-fA-F]+$/,
5454
5455 // Octal numbers
5456 NUMBER_OCT: /^0[0-7]+$/,
5457
5458 // Floating point numbers
5459 NUMBER_FLT: /^([0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)?|inf|nan)$/,
5460
5461 // Booleans
5462 BOOL: /^(?:true|false)$/i,
5463
5464 // Id numbers
5465 ID: /^(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+)$/,
5466
5467 // Negative id numbers (enum values)
5468 NEGID: /^\-?(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+)$/,
5469
5470 // Whitespaces
5471 WHITESPACE: /\s/,
5472
5473 // All strings
5474 STRING: /(?:"([^"\\]*(?:\\.[^"\\]*)*)")|(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g,
5475
5476 // Double quoted strings
5477 STRING_DQ: /(?:"([^"\\]*(?:\\.[^"\\]*)*)")/g,
5478
5479 // Single quoted strings
5480 STRING_SQ: /(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g
5481 };
5482
5483
5484 /**
5485 * @alias ProtoBuf.Reflect
5486 * @expose
5487 */
5488 ProtoBuf.Reflect = (function(ProtoBuf) {
5489
5490 /**
5491 * Reflection types.
5492 * @exports ProtoBuf.Reflect
5493 * @namespace
5494 */
5495 var Reflect = {};
5496
5497 /**
5498 * Constructs a Reflect base class.
5499 * @exports ProtoBuf.Reflect.T
5500 * @constructor
5501 * @abstract
5502 * @param {!ProtoBuf.Builder} builder Builder reference
5503 * @param {?ProtoBuf.Reflect.T} parent Parent object
5504 * @param {string} name Object name
5505 */
5506 var T = function(builder, parent, name) {
5507
5508 /**
5509 * Builder reference.
5510 * @type {!ProtoBuf.Builder}
5511 * @expose
5512 */
5513 this.builder = builder;
5514
5515 /**
5516 * Parent object.
5517 * @type {?ProtoBuf.Reflect.T}
5518 * @expose
5519 */
5520 this.parent = parent;
5521
5522 /**
5523 * Object name in namespace.
5524 * @type {string}
5525 * @expose
5526 */
5527 this.name = name;
5528
5529 /**
5530 * Fully qualified class name
5531 * @type {string}
5532 * @expose
5533 */
5534 this.className;
5535 };
5536
5537 /**
5538 * @alias ProtoBuf.Reflect.T.prototype
5539 * @inner
5540 */
5541 var TPrototype = T.prototype;
5542
5543 /**
5544 * Returns the fully qualified name of this object.
5545 * @returns {string} Fully qualified name as of ".PATH.TO.THIS"
5546 * @expose
5547 */
5548 TPrototype.fqn = function() {
5549 var name = this.name,
5550 ptr = this;
5551 do {
5552 ptr = ptr.parent;
5553 if (ptr == null)
5554 break;
5555 name = ptr.name+"."+name;
5556 } while (true);
5557 return name;
5558 };
5559
5560 /**
5561 * Returns a string representation of this Reflect object (its fully qualified name).
5562 * @param {boolean=} includeClass Set to true to include the class name. Defaults to false.
5563 * @return String representation
5564 * @expose
5565 */
5566 TPrototype.toString = function(includeClass) {
5567 return (includeClass ? this.className + " " : "") + this.fqn();
5568 };
5569
5570 /**
5571 * Builds this type.
5572 * @throws {Error} If this type cannot be built directly
5573 * @expose
5574 */
5575 TPrototype.build = function() {
5576 throw Error(this.toString(true)+" cannot be built directly");
5577 };
5578
5579 /**
5580 * @alias ProtoBuf.Reflect.T
5581 * @expose
5582 */
5583 Reflect.T = T;
5584
5585 /**
5586 * Constructs a new Namespace.
5587 * @exports ProtoBuf.Reflect.Namespace
5588 * @param {!ProtoBuf.Builder} builder Builder reference
5589 * @param {?ProtoBuf.Reflect.Namespace} parent Namespace parent
5590 * @param {string} name Namespace name
5591 * @param {Object.<string,*>=} options Namespace options
5592 * @param {string?} syntax The syntax level of this definition (e.g., proto3)
5593 * @constructor
5594 * @extends ProtoBuf.Reflect.T
5595 */
5596 var Namespace = function(builder, parent, name, options, syntax) {
5597 T.call(this, builder, parent, name);
5598
5599 /**
5600 * @override
5601 */
5602 this.className = "Namespace";
5603
5604 /**
5605 * Children inside the namespace.
5606 * @type {!Array.<ProtoBuf.Reflect.T>}
5607 */
5608 this.children = [];
5609
5610 /**
5611 * Options.
5612 * @type {!Object.<string, *>}
5613 */
5614 this.options = options || {};
5615
5616 /**
5617 * Syntax level (e.g., proto2 or proto3).
5618 * @type {!string}
5619 */
5620 this.syntax = syntax || "proto2";
5621 };
5622
5623 /**
5624 * @alias ProtoBuf.Reflect.Namespace.prototype
5625 * @inner
5626 */
5627 var NamespacePrototype = Namespace.prototype = Object.create(T.prototype);
5628
5629 /**
5630 * Returns an array of the namespace's children.
5631 * @param {ProtoBuf.Reflect.T=} type Filter type (returns instances of this type only). Defaults to null (all children).
5632 * @return {Array.<ProtoBuf.Reflect.T>}
5633 * @expose
5634 */
5635 NamespacePrototype.getChildren = function(type) {
5636 type = type || null;
5637 if (type == null)
5638 return this.children.slice();
5639 var children = [];
5640 for (var i=0, k=this.children.length; i<k; ++i)
5641 if (this.children[i] instanceof type)
5642 children.push(this.children[i]);
5643 return children;
5644 };
5645
5646 /**
5647 * Adds a child to the namespace.
5648 * @param {ProtoBuf.Reflect.T} child Child
5649 * @throws {Error} If the child cannot be added (duplicate)
5650 * @expose
5651 */
5652 NamespacePrototype.addChild = function(child) {
5653 var other;
5654 if (other = this.getChild(child.name)) {
5655 // Try to revert camelcase transformation on collision
5656 if (other instanceof Message.Field && other.name !== other.originalName && this.getChild(other.originalName) === null)
5657 other.name = other.originalName; // Revert previous first (effectively keeps both originals)
5658 else if (child instanceof Message.Field && child.name !== child.originalName && this.getChild(child.originalName) === null)
5659 child.name = child.originalName;
5660 else
5661 throw Error("Duplicate name in namespace "+this.toString(true)+": "+child.name);
5662 }
5663 this.children.push(child);
5664 };
5665
5666 /**
5667 * Gets a child by its name or id.
5668 * @param {string|number} nameOrId Child name or id
5669 * @return {?ProtoBuf.Reflect.T} The child or null if not found
5670 * @expose
5671 */
5672 NamespacePrototype.getChild = function(nameOrId) {
5673 var key = typeof nameOrId === 'number' ? 'id' : 'name';
5674 for (var i=0, k=this.children.length; i<k; ++i)
5675 if (this.children[i][key] === nameOrId)
5676 return this.children[i];
5677 return null;
5678 };
5679
5680 /**
5681 * Resolves a reflect object inside of this namespace.
5682 * @param {string|!Array.<string>} qn Qualified name to resolve
5683 * @param {boolean=} excludeNonNamespace Excludes non-namespace types, defaults to `false`
5684 * @return {?ProtoBuf.Reflect.Namespace} The resolved type or null if not found
5685 * @expose
5686 */
5687 NamespacePrototype.resolve = function(qn, excludeNonNamespace) {
5688 var part = typeof qn === 'string' ? qn.split(".") : qn,
5689 ptr = this,
5690 i = 0;
5691 if (part[i] === "") { // Fully qualified name, e.g. ".My.Message'
5692 while (ptr.parent !== null)
5693 ptr = ptr.parent;
5694 i++;
5695 }
5696 var child;
5697 do {
5698 do {
5699 if (!(ptr instanceof Reflect.Namespace)) {
5700 ptr = null;
5701 break;
5702 }
5703 child = ptr.getChild(part[i]);
5704 if (!child || !(child instanceof Reflect.T) || (excludeNonNamespace && !(child instanceof Reflect.Namespace))) {
5705 ptr = null;
5706 break;
5707 }
5708 ptr = child; i++;
5709 } while (i < part.length);
5710 if (ptr != null)
5711 break; // Found
5712 // Else search the parent
5713 if (this.parent !== null)
5714 return this.parent.resolve(qn, excludeNonNamespace);
5715 } while (ptr != null);
5716 return ptr;
5717 };
5718
5719 /**
5720 * Determines the shortest qualified name of the specified type, if any, relative to this namespace.
5721 * @param {!ProtoBuf.Reflect.T} t Reflection type
5722 * @returns {string} The shortest qualified name or, if there is none, the fqn
5723 * @expose
5724 */
5725 NamespacePrototype.qn = function(t) {
5726 var part = [], ptr = t;
5727 do {
5728 part.unshift(ptr.name);
5729 ptr = ptr.parent;
5730 } while (ptr !== null);
5731 for (var len=1; len <= part.length; len++) {
5732 var qn = part.slice(part.length-len);
5733 if (t === this.resolve(qn, t instanceof Reflect.Namespace))
5734 return qn.join(".");
5735 }
5736 return t.fqn();
5737 };
5738
5739 /**
5740 * Builds the namespace and returns the runtime counterpart.
5741 * @return {Object.<string,Function|Object>} Runtime namespace
5742 * @expose
5743 */
5744 NamespacePrototype.build = function() {
5745 /** @dict */
5746 var ns = {};
5747 var children = this.children;
5748 for (var i=0, k=children.length, child; i<k; ++i) {
5749 child = children[i];
5750 if (child instanceof Namespace)
5751 ns[child.name] = child.build();
5752 }
5753 if (Object.defineProperty)
5754 Object.defineProperty(ns, "$options", { "value": this.buildOpt() });
5755 return ns;
5756 };
5757
5758 /**
5759 * Builds the namespace's '$options' property.
5760 * @return {Object.<string,*>}
5761 */
5762 NamespacePrototype.buildOpt = function() {
5763 var opt = {},
5764 keys = Object.keys(this.options);
5765 for (var i=0, k=keys.length; i<k; ++i) {
5766 var key = keys[i],
5767 val = this.options[keys[i]];
5768 // TODO: Options are not resolved, yet.
5769 // if (val instanceof Namespace) {
5770 // opt[key] = val.build();
5771 // } else {
5772 opt[key] = val;
5773 // }
5774 }
5775 return opt;
5776 };
5777
5778 /**
5779 * Gets the value assigned to the option with the specified name.
5780 * @param {string=} name Returns the option value if specified, otherwise all options are returned.
5781 * @return {*|Object.<string,*>}null} Option value or NULL if there is no such option
5782 */
5783 NamespacePrototype.getOption = function(name) {
5784 if (typeof name === 'undefined')
5785 return this.options;
5786 return typeof this.options[name] !== 'undefined' ? this.options[name] : null;
5787 };
5788
5789 /**
5790 * @alias ProtoBuf.Reflect.Namespace
5791 * @expose
5792 */
5793 Reflect.Namespace = Namespace;
5794
5795 /**
5796 * Constructs a new Element implementation that checks and converts values for a
5797 * particular field type, as appropriate.
5798 *
5799 * An Element represents a single value: either the value of a singular field,
5800 * or a value contained in one entry of a repeated field or map field. This
5801 * class does not implement these higher-level concepts; it only encapsulates
5802 * the low-level typechecking and conversion.
5803 *
5804 * @exports ProtoBuf.Reflect.Element
5805 * @param {{name: string, wireType: number}} type Resolved data type
5806 * @param {ProtoBuf.Reflect.T|null} resolvedType Resolved type, if relevant
5807 * (e.g. submessage field).
5808 * @param {boolean} isMapKey Is this element a Map key? The value will be
5809 * converted to string form if so.
5810 * @param {string} syntax Syntax level of defining message type, e.g.,
5811 * proto2 or proto3.
5812 * @param {string} name Name of the field containing this element (for error
5813 * messages)
5814 * @constructor
5815 */
5816 var Element = function(type, resolvedType, isMapKey, syntax, name) {
5817
5818 /**
5819 * Element type, as a string (e.g., int32).
5820 * @type {{name: string, wireType: number}}
5821 */
5822 this.type = type;
5823
5824 /**
5825 * Element type reference to submessage or enum definition, if needed.
5826 * @type {ProtoBuf.Reflect.T|null}
5827 */
5828 this.resolvedType = resolvedType;
5829
5830 /**
5831 * Element is a map key.
5832 * @type {boolean}
5833 */
5834 this.isMapKey = isMapKey;
5835
5836 /**
5837 * Syntax level of defining message type, e.g., proto2 or proto3.
5838 * @type {string}
5839 */
5840 this.syntax = syntax;
5841
5842 /**
5843 * Name of the field containing this element (for error messages)
5844 * @type {string}
5845 */
5846 this.name = name;
5847
5848 if (isMapKey && ProtoBuf.MAP_KEY_TYPES.indexOf(type) < 0)
5849 throw Error("Invalid map key type: " + type.name);
5850 };
5851
5852 var ElementPrototype = Element.prototype;
5853
5854 /**
5855 * Obtains a (new) default value for the specified type.
5856 * @param type {string|{name: string, wireType: number}} Field type
5857 * @returns {*} Default value
5858 * @inner
5859 */
5860 function mkDefault(type) {
5861 if (typeof type === 'string')
5862 type = ProtoBuf.TYPES[type];
5863 if (typeof type.defaultValue === 'undefined')
5864 throw Error("default value for type "+type.name+" is not supported");
5865 if (type == ProtoBuf.TYPES["bytes"])
5866 return new ByteBuffer(0);
5867 return type.defaultValue;
5868 }
5869
5870 /**
5871 * Returns the default value for this field in proto3.
5872 * @function
5873 * @param type {string|{name: string, wireType: number}} the field type
5874 * @returns {*} Default value
5875 */
5876 Element.defaultFieldValue = mkDefault;
5877
5878 /**
5879 * Makes a Long from a value.
5880 * @param {{low: number, high: number, unsigned: boolean}|string|number} value Value
5881 * @param {boolean=} unsigned Whether unsigned or not, defaults to reuse it from Long-like objects or to signed for
5882 * strings and numbers
5883 * @returns {!Long}
5884 * @throws {Error} If the value cannot be converted to a Long
5885 * @inner
5886 */
5887 function mkLong(value, unsigned) {
5888 if (value && typeof value.low === 'number' && typeof value.high === 'number' && typeof value.unsigned === 'boolean'
5889 && value.low === value.low && value.high === value.high)
5890 return new ProtoBuf.Long(value.low, value.high, typeof unsigned === 'undefined' ? value.unsigned : unsigned);
5891 if (typeof value === 'string')
5892 return ProtoBuf.Long.fromString(value, unsigned || false, 10);
5893 if (typeof value === 'number')
5894 return ProtoBuf.Long.fromNumber(value, unsigned || false);
5895 throw Error("not convertible to Long");
5896 }
5897
5898 ElementPrototype.toString = function() {
5899 return (this.name || '') + (this.isMapKey ? 'map' : 'value') + ' element';
5900 };
5901
5902 /**
5903 * Checks if the given value can be set for an element of this type (singular
5904 * field or one element of a repeated field or map).
5905 * @param {*} value Value to check
5906 * @return {*} Verified, maybe adjusted, value
5907 * @throws {Error} If the value cannot be verified for this element slot
5908 * @expose
5909 */
5910 ElementPrototype.verifyValue = function(value) {
5911 var self = this;
5912 function fail(val, msg) {
5913 throw Error("Illegal value for "+self.toString(true)+" of type "+self.type.name+": "+val+" ("+msg+")");
5914 }
5915 switch (this.type) {
5916 // Signed 32bit
5917 case ProtoBuf.TYPES["int32"]:
5918 case ProtoBuf.TYPES["sint32"]:
5919 case ProtoBuf.TYPES["sfixed32"]:
5920 // Account for !NaN: value === value
5921 if (typeof value !== 'number' || (value === value && value % 1 !== 0))
5922 fail(typeof value, "not an integer");
5923 return value > 4294967295 ? value | 0 : value;
5924
5925 // Unsigned 32bit
5926 case ProtoBuf.TYPES["uint32"]:
5927 case ProtoBuf.TYPES["fixed32"]:
5928 if (typeof value !== 'number' || (value === value && value % 1 !== 0))
5929 fail(typeof value, "not an integer");
5930 return value < 0 ? value >>> 0 : value;
5931
5932 // Signed 64bit
5933 case ProtoBuf.TYPES["int64"]:
5934 case ProtoBuf.TYPES["sint64"]:
5935 case ProtoBuf.TYPES["sfixed64"]: {
5936 if (ProtoBuf.Long)
5937 try {
5938 return mkLong(value, false);
5939 } catch (e) {
5940 fail(typeof value, e.message);
5941 }
5942 else
5943 fail(typeof value, "requires Long.js");
5944 }
5945
5946 // Unsigned 64bit
5947 case ProtoBuf.TYPES["uint64"]:
5948 case ProtoBuf.TYPES["fixed64"]: {
5949 if (ProtoBuf.Long)
5950 try {
5951 return mkLong(value, true);
5952 } catch (e) {
5953 fail(typeof value, e.message);
5954 }
5955 else
5956 fail(typeof value, "requires Long.js");
5957 }
5958
5959 // Bool
5960 case ProtoBuf.TYPES["bool"]:
5961 if (typeof value !== 'boolean')
5962 fail(typeof value, "not a boolean");
5963 return value;
5964
5965 // Float
5966 case ProtoBuf.TYPES["float"]:
5967 case ProtoBuf.TYPES["double"]:
5968 if (typeof value !== 'number')
5969 fail(typeof value, "not a number");
5970 return value;
5971
5972 // Length-delimited string
5973 case ProtoBuf.TYPES["string"]:
5974 if (typeof value !== 'string' && !(value && value instanceof String))
5975 fail(typeof value, "not a string");
5976 return ""+value; // Convert String object to string
5977
5978 // Length-delimited bytes
5979 case ProtoBuf.TYPES["bytes"]:
5980 if (ByteBuffer.isByteBuffer(value))
5981 return value;
5982 return ByteBuffer.wrap(value, "base64");
5983
5984 // Constant enum value
5985 case ProtoBuf.TYPES["enum"]: {
5986 var values = this.resolvedType.getChildren(ProtoBuf.Reflect.Enum.Value);
5987 for (i=0; i<values.length; i++)
5988 if (values[i].name == value)
5989 return values[i].id;
5990 else if (values[i].id == value)
5991 return values[i].id;
5992
5993 if (this.syntax === 'proto3') {
5994 // proto3: just make sure it's an integer.
5995 if (typeof value !== 'number' || (value === value && value % 1 !== 0))
5996 fail(typeof value, "not an integer");
5997 if (value > 4294967295 || value < 0)
5998 fail(typeof value, "not in range for uint32");
5999 return value;
6000 } else {
6001 // proto2 requires enum values to be valid.
6002 fail(value, "not a valid enum value");
6003 }
6004 }
6005 // Embedded message
6006 case ProtoBuf.TYPES["group"]:
6007 case ProtoBuf.TYPES["message"]: {
6008 if (!value || typeof value !== 'object')
6009 fail(typeof value, "object expected");
6010 if (value instanceof this.resolvedType.clazz)
6011 return value;
6012 if (value instanceof ProtoBuf.Builder.Message) {
6013 // Mismatched type: Convert to object (see: https://github.com/dcodeIO/ProtoBuf.js/issues/180)
6014 var obj = {};
6015 for (var i in value)
6016 if (value.hasOwnProperty(i))
6017 obj[i] = value[i];
6018 value = obj;
6019 }
6020 // Else let's try to construct one from a key-value object
6021 return new (this.resolvedType.clazz)(value); // May throw for a hundred of reasons
6022 }
6023 }
6024
6025 // We should never end here
6026 throw Error("[INTERNAL] Illegal value for "+this.toString(true)+": "+value+" (undefined type "+this.type+")");
6027 };
6028
6029 /**
6030 * Calculates the byte length of an element on the wire.
6031 * @param {number} id Field number
6032 * @param {*} value Field value
6033 * @returns {number} Byte length
6034 * @throws {Error} If the value cannot be calculated
6035 * @expose
6036 */
6037 ElementPrototype.calculateLength = function(id, value) {
6038 if (value === null) return 0; // Nothing to encode
6039 // Tag has already been written
6040 var n;
6041 switch (this.type) {
6042 case ProtoBuf.TYPES["int32"]:
6043 return value < 0 ? ByteBuffer.calculateVarint64(value) : ByteBuffer.calculateVarint32(value);
6044 case ProtoBuf.TYPES["uint32"]:
6045 return ByteBuffer.calculateVarint32(value);
6046 case ProtoBuf.TYPES["sint32"]:
6047 return ByteBuffer.calculateVarint32(ByteBuffer.zigZagEncode32(value));
6048 case ProtoBuf.TYPES["fixed32"]:
6049 case ProtoBuf.TYPES["sfixed32"]:
6050 case ProtoBuf.TYPES["float"]:
6051 return 4;
6052 case ProtoBuf.TYPES["int64"]:
6053 case ProtoBuf.TYPES["uint64"]:
6054 return ByteBuffer.calculateVarint64(value);
6055 case ProtoBuf.TYPES["sint64"]:
6056 return ByteBuffer.calculateVarint64(ByteBuffer.zigZagEncode64(value));
6057 case ProtoBuf.TYPES["fixed64"]:
6058 case ProtoBuf.TYPES["sfixed64"]:
6059 return 8;
6060 case ProtoBuf.TYPES["bool"]:
6061 return 1;
6062 case ProtoBuf.TYPES["enum"]:
6063 return ByteBuffer.calculateVarint32(value);
6064 case ProtoBuf.TYPES["double"]:
6065 return 8;
6066 case ProtoBuf.TYPES["string"]:
6067 n = ByteBuffer.calculateUTF8Bytes(value);
6068 return ByteBuffer.calculateVarint32(n) + n;
6069 case ProtoBuf.TYPES["bytes"]:
6070 if (value.remaining() < 0)
6071 throw Error("Illegal value for "+this.toString(true)+": "+value.remaining()+" bytes remaining");
6072 return ByteBuffer.calculateVarint32(value.remaining()) + value.remaining();
6073 case ProtoBuf.TYPES["message"]:
6074 n = this.resolvedType.calculate(value);
6075 return ByteBuffer.calculateVarint32(n) + n;
6076 case ProtoBuf.TYPES["group"]:
6077 n = this.resolvedType.calculate(value);
6078 return n + ByteBuffer.calculateVarint32((id << 3) | ProtoBuf.WIRE_TYPES.ENDGROUP);
6079 }
6080 // We should never end here
6081 throw Error("[INTERNAL] Illegal value to encode in "+this.toString(true)+": "+value+" (unknown type)");
6082 };
6083
6084 /**
6085 * Encodes a value to the specified buffer. Does not encode the key.
6086 * @param {number} id Field number
6087 * @param {*} value Field value
6088 * @param {ByteBuffer} buffer ByteBuffer to encode to
6089 * @return {ByteBuffer} The ByteBuffer for chaining
6090 * @throws {Error} If the value cannot be encoded
6091 * @expose
6092 */
6093 ElementPrototype.encodeValue = function(id, value, buffer) {
6094 if (value === null) return buffer; // Nothing to encode
6095 // Tag has already been written
6096
6097 switch (this.type) {
6098 // 32bit signed varint
6099 case ProtoBuf.TYPES["int32"]:
6100 // "If you use int32 or int64 as the type for a negative number, the resulting varint is always ten bytes
6101 // long – it is, effectively, treated like a very large unsigned integer." (see #122)
6102 if (value < 0)
6103 buffer.writeVarint64(value);
6104 else
6105 buffer.writeVarint32(value);
6106 break;
6107
6108 // 32bit unsigned varint
6109 case ProtoBuf.TYPES["uint32"]:
6110 buffer.writeVarint32(value);
6111 break;
6112
6113 // 32bit varint zig-zag
6114 case ProtoBuf.TYPES["sint32"]:
6115 buffer.writeVarint32ZigZag(value);
6116 break;
6117
6118 // Fixed unsigned 32bit
6119 case ProtoBuf.TYPES["fixed32"]:
6120 buffer.writeUint32(value);
6121 break;
6122
6123 // Fixed signed 32bit
6124 case ProtoBuf.TYPES["sfixed32"]:
6125 buffer.writeInt32(value);
6126 break;
6127
6128 // 64bit varint as-is
6129 case ProtoBuf.TYPES["int64"]:
6130 case ProtoBuf.TYPES["uint64"]:
6131 buffer.writeVarint64(value); // throws
6132 break;
6133
6134 // 64bit varint zig-zag
6135 case ProtoBuf.TYPES["sint64"]:
6136 buffer.writeVarint64ZigZag(value); // throws
6137 break;
6138
6139 // Fixed unsigned 64bit
6140 case ProtoBuf.TYPES["fixed64"]:
6141 buffer.writeUint64(value); // throws
6142 break;
6143
6144 // Fixed signed 64bit
6145 case ProtoBuf.TYPES["sfixed64"]:
6146 buffer.writeInt64(value); // throws
6147 break;
6148
6149 // Bool
6150 case ProtoBuf.TYPES["bool"]:
6151 if (typeof value === 'string')
6152 buffer.writeVarint32(value.toLowerCase() === 'false' ? 0 : !!value);
6153 else
6154 buffer.writeVarint32(value ? 1 : 0);
6155 break;
6156
6157 // Constant enum value
6158 case ProtoBuf.TYPES["enum"]:
6159 buffer.writeVarint32(value);
6160 break;
6161
6162 // 32bit float
6163 case ProtoBuf.TYPES["float"]:
6164 buffer.writeFloat32(value);
6165 break;
6166
6167 // 64bit float
6168 case ProtoBuf.TYPES["double"]:
6169 buffer.writeFloat64(value);
6170 break;
6171
6172 // Length-delimited string
6173 case ProtoBuf.TYPES["string"]:
6174 buffer.writeVString(value);
6175 break;
6176
6177 // Length-delimited bytes
6178 case ProtoBuf.TYPES["bytes"]:
6179 if (value.remaining() < 0)
6180 throw Error("Illegal value for "+this.toString(true)+": "+value.remaining()+" bytes remaining");
6181 var prevOffset = value.offset;
6182 buffer.writeVarint32(value.remaining());
6183 buffer.append(value);
6184 value.offset = prevOffset;
6185 break;
6186
6187 // Embedded message
6188 case ProtoBuf.TYPES["message"]:
6189 var bb = new ByteBuffer().LE();
6190 this.resolvedType.encode(value, bb);
6191 buffer.writeVarint32(bb.offset);
6192 buffer.append(bb.flip());
6193 break;
6194
6195 // Legacy group
6196 case ProtoBuf.TYPES["group"]:
6197 this.resolvedType.encode(value, buffer);
6198 buffer.writeVarint32((id << 3) | ProtoBuf.WIRE_TYPES.ENDGROUP);
6199 break;
6200
6201 default:
6202 // We should never end here
6203 throw Error("[INTERNAL] Illegal value to encode in "+this.toString(true)+": "+value+" (unknown type)");
6204 }
6205 return buffer;
6206 };
6207
6208 /**
6209 * Decode one element value from the specified buffer.
6210 * @param {ByteBuffer} buffer ByteBuffer to decode from
6211 * @param {number} wireType The field wire type
6212 * @param {number} id The field number
6213 * @return {*} Decoded value
6214 * @throws {Error} If the field cannot be decoded
6215 * @expose
6216 */
6217 ElementPrototype.decode = function(buffer, wireType, id) {
6218 if (wireType != this.type.wireType)
6219 throw Error("Unexpected wire type for element");
6220
6221 var value, nBytes;
6222 switch (this.type) {
6223 // 32bit signed varint
6224 case ProtoBuf.TYPES["int32"]:
6225 return buffer.readVarint32() | 0;
6226
6227 // 32bit unsigned varint
6228 case ProtoBuf.TYPES["uint32"]:
6229 return buffer.readVarint32() >>> 0;
6230
6231 // 32bit signed varint zig-zag
6232 case ProtoBuf.TYPES["sint32"]:
6233 return buffer.readVarint32ZigZag() | 0;
6234
6235 // Fixed 32bit unsigned
6236 case ProtoBuf.TYPES["fixed32"]:
6237 return buffer.readUint32() >>> 0;
6238
6239 case ProtoBuf.TYPES["sfixed32"]:
6240 return buffer.readInt32() | 0;
6241
6242 // 64bit signed varint
6243 case ProtoBuf.TYPES["int64"]:
6244 return buffer.readVarint64();
6245
6246 // 64bit unsigned varint
6247 case ProtoBuf.TYPES["uint64"]:
6248 return buffer.readVarint64().toUnsigned();
6249
6250 // 64bit signed varint zig-zag
6251 case ProtoBuf.TYPES["sint64"]:
6252 return buffer.readVarint64ZigZag();
6253
6254 // Fixed 64bit unsigned
6255 case ProtoBuf.TYPES["fixed64"]:
6256 return buffer.readUint64();
6257
6258 // Fixed 64bit signed
6259 case ProtoBuf.TYPES["sfixed64"]:
6260 return buffer.readInt64();
6261
6262 // Bool varint
6263 case ProtoBuf.TYPES["bool"]:
6264 return !!buffer.readVarint32();
6265
6266 // Constant enum value (varint)
6267 case ProtoBuf.TYPES["enum"]:
6268 // The following Builder.Message#set will already throw
6269 return buffer.readVarint32();
6270
6271 // 32bit float
6272 case ProtoBuf.TYPES["float"]:
6273 return buffer.readFloat();
6274
6275 // 64bit float
6276 case ProtoBuf.TYPES["double"]:
6277 return buffer.readDouble();
6278
6279 // Length-delimited string
6280 case ProtoBuf.TYPES["string"]:
6281 return buffer.readVString();
6282
6283 // Length-delimited bytes
6284 case ProtoBuf.TYPES["bytes"]: {
6285 nBytes = buffer.readVarint32();
6286 if (buffer.remaining() < nBytes)
6287 throw Error("Illegal number of bytes for "+this.toString(true)+": "+nBytes+" required but got only "+buffer.remaining());
6288 value = buffer.clone(); // Offset already set
6289 value.limit = value.offset+nBytes;
6290 buffer.offset += nBytes;
6291 return value;
6292 }
6293
6294 // Length-delimited embedded message
6295 case ProtoBuf.TYPES["message"]: {
6296 nBytes = buffer.readVarint32();
6297 return this.resolvedType.decode(buffer, nBytes);
6298 }
6299
6300 // Legacy group
6301 case ProtoBuf.TYPES["group"]:
6302 return this.resolvedType.decode(buffer, -1, id);
6303 }
6304
6305 // We should never end here
6306 throw Error("[INTERNAL] Illegal decode type");
6307 };
6308
6309 /**
6310 * Converts a value from a string to the canonical element type.
6311 *
6312 * Legal only when isMapKey is true.
6313 *
6314 * @param {string} str The string value
6315 * @returns {*} The value
6316 */
6317 ElementPrototype.valueFromString = function(str) {
6318 if (!this.isMapKey) {
6319 throw Error("valueFromString() called on non-map-key element");
6320 }
6321
6322 switch (this.type) {
6323 case ProtoBuf.TYPES["int32"]:
6324 case ProtoBuf.TYPES["sint32"]:
6325 case ProtoBuf.TYPES["sfixed32"]:
6326 case ProtoBuf.TYPES["uint32"]:
6327 case ProtoBuf.TYPES["fixed32"]:
6328 return this.verifyValue(parseInt(str));
6329
6330 case ProtoBuf.TYPES["int64"]:
6331 case ProtoBuf.TYPES["sint64"]:
6332 case ProtoBuf.TYPES["sfixed64"]:
6333 case ProtoBuf.TYPES["uint64"]:
6334 case ProtoBuf.TYPES["fixed64"]:
6335 // Long-based fields support conversions from string already.
6336 return this.verifyValue(str);
6337
6338 case ProtoBuf.TYPES["bool"]:
6339 return str === "true";
6340
6341 case ProtoBuf.TYPES["string"]:
6342 return this.verifyValue(str);
6343
6344 case ProtoBuf.TYPES["bytes"]:
6345 return ByteBuffer.fromBinary(str);
6346 }
6347 };
6348
6349 /**
6350 * Converts a value from the canonical element type to a string.
6351 *
6352 * It should be the case that `valueFromString(valueToString(val))` returns
6353 * a value equivalent to `verifyValue(val)` for every legal value of `val`
6354 * according to this element type.
6355 *
6356 * This may be used when the element must be stored or used as a string,
6357 * e.g., as a map key on an Object.
6358 *
6359 * Legal only when isMapKey is true.
6360 *
6361 * @param {*} val The value
6362 * @returns {string} The string form of the value.
6363 */
6364 ElementPrototype.valueToString = function(value) {
6365 if (!this.isMapKey) {
6366 throw Error("valueToString() called on non-map-key element");
6367 }
6368
6369 if (this.type === ProtoBuf.TYPES["bytes"]) {
6370 return value.toString("binary");
6371 } else {
6372 return value.toString();
6373 }
6374 };
6375
6376 /**
6377 * @alias ProtoBuf.Reflect.Element
6378 * @expose
6379 */
6380 Reflect.Element = Element;
6381
6382 /**
6383 * Constructs a new Message.
6384 * @exports ProtoBuf.Reflect.Message
6385 * @param {!ProtoBuf.Builder} builder Builder reference
6386 * @param {!ProtoBuf.Reflect.Namespace} parent Parent message or namespace
6387 * @param {string} name Message name
6388 * @param {Object.<string,*>=} options Message options
6389 * @param {boolean=} isGroup `true` if this is a legacy group
6390 * @param {string?} syntax The syntax level of this definition (e.g., proto3)
6391 * @constructor
6392 * @extends ProtoBuf.Reflect.Namespace
6393 */
6394 var Message = function(builder, parent, name, options, isGroup, syntax) {
6395 Namespace.call(this, builder, parent, name, options, syntax);
6396
6397 /**
6398 * @override
6399 */
6400 this.className = "Message";
6401
6402 /**
6403 * Extensions range.
6404 * @type {!Array.<number>|undefined}
6405 * @expose
6406 */
6407 this.extensions = undefined;
6408
6409 /**
6410 * Runtime message class.
6411 * @type {?function(new:ProtoBuf.Builder.Message)}
6412 * @expose
6413 */
6414 this.clazz = null;
6415
6416 /**
6417 * Whether this is a legacy group or not.
6418 * @type {boolean}
6419 * @expose
6420 */
6421 this.isGroup = !!isGroup;
6422
6423 // The following cached collections are used to efficiently iterate over or look up fields when decoding.
6424
6425 /**
6426 * Cached fields.
6427 * @type {?Array.<!ProtoBuf.Reflect.Message.Field>}
6428 * @private
6429 */
6430 this._fields = null;
6431
6432 /**
6433 * Cached fields by id.
6434 * @type {?Object.<number,!ProtoBuf.Reflect.Message.Field>}
6435 * @private
6436 */
6437 this._fieldsById = null;
6438
6439 /**
6440 * Cached fields by name.
6441 * @type {?Object.<string,!ProtoBuf.Reflect.Message.Field>}
6442 * @private
6443 */
6444 this._fieldsByName = null;
6445 };
6446
6447 /**
6448 * @alias ProtoBuf.Reflect.Message.prototype
6449 * @inner
6450 */
6451 var MessagePrototype = Message.prototype = Object.create(Namespace.prototype);
6452
6453 /**
6454 * Builds the message and returns the runtime counterpart, which is a fully functional class.
6455 * @see ProtoBuf.Builder.Message
6456 * @param {boolean=} rebuild Whether to rebuild or not, defaults to false
6457 * @return {ProtoBuf.Reflect.Message} Message class
6458 * @throws {Error} If the message cannot be built
6459 * @expose
6460 */
6461 MessagePrototype.build = function(rebuild) {
6462 if (this.clazz && !rebuild)
6463 return this.clazz;
6464
6465 // Create the runtime Message class in its own scope
6466 var clazz = (function(ProtoBuf, T) {
6467
6468 var fields = T.getChildren(ProtoBuf.Reflect.Message.Field),
6469 oneofs = T.getChildren(ProtoBuf.Reflect.Message.OneOf);
6470
6471 /**
6472 * Constructs a new runtime Message.
6473 * @name ProtoBuf.Builder.Message
6474 * @class Barebone of all runtime messages.
6475 * @param {!Object.<string,*>|string} values Preset values
6476 * @param {...string} var_args
6477 * @constructor
6478 * @throws {Error} If the message cannot be created
6479 */
6480 var Message = function(values, var_args) {
6481 ProtoBuf.Builder.Message.call(this);
6482
6483 // Create virtual oneof properties
6484 for (var i=0, k=oneofs.length; i<k; ++i)
6485 this[oneofs[i].name] = null;
6486 // Create fields and set default values
6487 for (i=0, k=fields.length; i<k; ++i) {
6488 var field = fields[i];
6489 this[field.name] =
6490 field.repeated ? [] :
6491 (field.map ? new ProtoBuf.Map(field) : null);
6492 if ((field.required || T.syntax === 'proto3') &&
6493 field.defaultValue !== null)
6494 this[field.name] = field.defaultValue;
6495 }
6496
6497 if (arguments.length > 0) {
6498 var value;
6499 // Set field values from a values object
6500 if (arguments.length === 1 && values !== null && typeof values === 'object' &&
6501 /* not _another_ Message */ (typeof values.encode !== 'function' || values instanceof Message) &&
6502 /* not a repeated field */ !Array.isArray(values) &&
6503 /* not a Map */ !(values instanceof ProtoBuf.Map) &&
6504 /* not a ByteBuffer */ !ByteBuffer.isByteBuffer(values) &&
6505 /* not an ArrayBuffer */ !(values instanceof ArrayBuffer) &&
6506 /* not a Long */ !(ProtoBuf.Long && values instanceof ProtoBuf.Long)) {
6507 this.$set(values);
6508 } else // Set field values from arguments, in declaration order
6509 for (i=0, k=arguments.length; i<k; ++i)
6510 if (typeof (value = arguments[i]) !== 'undefined')
6511 this.$set(fields[i].name, value); // May throw
6512 }
6513 };
6514
6515 /**
6516 * @alias ProtoBuf.Builder.Message.prototype
6517 * @inner
6518 */
6519 var MessagePrototype = Message.prototype = Object.create(ProtoBuf.Builder.Message.prototype);
6520
6521 /**
6522 * Adds a value to a repeated field.
6523 * @name ProtoBuf.Builder.Message#add
6524 * @function
6525 * @param {string} key Field name
6526 * @param {*} value Value to add
6527 * @param {boolean=} noAssert Whether to assert the value or not (asserts by default)
6528 * @returns {!ProtoBuf.Builder.Message} this
6529 * @throws {Error} If the value cannot be added
6530 * @expose
6531 */
6532 MessagePrototype.add = function(key, value, noAssert) {
6533 var field = T._fieldsByName[key];
6534 if (!noAssert) {
6535 if (!field)
6536 throw Error(this+"#"+key+" is undefined");
6537 if (!(field instanceof ProtoBuf.Reflect.Message.Field))
6538 throw Error(this+"#"+key+" is not a field: "+field.toString(true)); // May throw if it's an enum or embedded message
6539 if (!field.repeated)
6540 throw Error(this+"#"+key+" is not a repeated field");
6541 value = field.verifyValue(value, true);
6542 }
6543 if (this[key] === null)
6544 this[key] = [];
6545 this[key].push(value);
6546 return this;
6547 };
6548
6549 /**
6550 * Adds a value to a repeated field. This is an alias for {@link ProtoBuf.Builder.Message#add}.
6551 * @name ProtoBuf.Builder.Message#$add
6552 * @function
6553 * @param {string} key Field name
6554 * @param {*} value Value to add
6555 * @param {boolean=} noAssert Whether to assert the value or not (asserts by default)
6556 * @returns {!ProtoBuf.Builder.Message} this
6557 * @throws {Error} If the value cannot be added
6558 * @expose
6559 */
6560 MessagePrototype.$add = MessagePrototype.add;
6561
6562 /**
6563 * Sets a field's value.
6564 * @name ProtoBuf.Builder.Message#set
6565 * @function
6566 * @param {string|!Object.<string,*>} keyOrObj String key or plain object holding multiple values
6567 * @param {(*|boolean)=} value Value to set if key is a string, otherwise omitted
6568 * @param {boolean=} noAssert Whether to not assert for an actual field / proper value type, defaults to `false`
6569 * @returns {!ProtoBuf.Builder.Message} this
6570 * @throws {Error} If the value cannot be set
6571 * @expose
6572 */
6573 MessagePrototype.set = function(keyOrObj, value, noAssert) {
6574 if (keyOrObj && typeof keyOrObj === 'object') {
6575 noAssert = value;
6576 for (var ikey in keyOrObj) {
6577 // Check if virtual oneof field - don't set these
6578 if (keyOrObj.hasOwnProperty(ikey) && typeof (value = keyOrObj[ikey]) !== 'undefined' && T._oneofsByName[ikey] === undefined)
6579 this.$set(ikey, value, noAssert);
6580 }
6581 return this;
6582 }
6583 var field = T._fieldsByName[keyOrObj];
6584 if (!noAssert) {
6585 if (!field)
6586 throw Error(this+"#"+keyOrObj+" is not a field: undefined");
6587 if (!(field instanceof ProtoBuf.Reflect.Message.Field))
6588 throw Error(this+"#"+keyOrObj+" is not a field: "+field.toString(true));
6589 this[field.name] = (value = field.verifyValue(value)); // May throw
6590 } else
6591 this[keyOrObj] = value;
6592 if (field && field.oneof) { // Field is part of an OneOf (not a virtual OneOf field)
6593 var currentField = this[field.oneof.name]; // Virtual field references currently set field
6594 if (value !== null) {
6595 if (currentField !== null && currentField !== field.name)
6596 this[currentField] = null; // Clear currently set field
6597 this[field.oneof.name] = field.name; // Point virtual field at this field
6598 } else if (/* value === null && */currentField === keyOrObj)
6599 this[field.oneof.name] = null; // Clear virtual field (current field explicitly cleared)
6600 }
6601 return this;
6602 };
6603
6604 /**
6605 * Sets a field's value. This is an alias for [@link ProtoBuf.Builder.Message#set}.
6606 * @name ProtoBuf.Builder.Message#$set
6607 * @function
6608 * @param {string|!Object.<string,*>} keyOrObj String key or plain object holding multiple values
6609 * @param {(*|boolean)=} value Value to set if key is a string, otherwise omitted
6610 * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
6611 * @throws {Error} If the value cannot be set
6612 * @expose
6613 */
6614 MessagePrototype.$set = MessagePrototype.set;
6615
6616 /**
6617 * Gets a field's value.
6618 * @name ProtoBuf.Builder.Message#get
6619 * @function
6620 * @param {string} key Key
6621 * @param {boolean=} noAssert Whether to not assert for an actual field, defaults to `false`
6622 * @return {*} Value
6623 * @throws {Error} If there is no such field
6624 * @expose
6625 */
6626 MessagePrototype.get = function(key, noAssert) {
6627 if (noAssert)
6628 return this[key];
6629 var field = T._fieldsByName[key];
6630 if (!field || !(field instanceof ProtoBuf.Reflect.Message.Field))
6631 throw Error(this+"#"+key+" is not a field: undefined");
6632 if (!(field instanceof ProtoBuf.Reflect.Message.Field))
6633 throw Error(this+"#"+key+" is not a field: "+field.toString(true));
6634 return this[field.name];
6635 };
6636
6637 /**
6638 * Gets a field's value. This is an alias for {@link ProtoBuf.Builder.Message#$get}.
6639 * @name ProtoBuf.Builder.Message#$get
6640 * @function
6641 * @param {string} key Key
6642 * @return {*} Value
6643 * @throws {Error} If there is no such field
6644 * @expose
6645 */
6646 MessagePrototype.$get = MessagePrototype.get;
6647
6648 // Getters and setters
6649
6650 for (var i=0; i<fields.length; i++) {
6651 var field = fields[i];
6652 // no setters for extension fields as these are named by their fqn
6653 if (field instanceof ProtoBuf.Reflect.Message.ExtensionField)
6654 continue;
6655
6656 if (T.builder.options['populateAccessors'])
6657 (function(field) {
6658 // set/get[SomeValue]
6659 var Name = field.originalName.replace(/(_[a-zA-Z])/g, function(match) {
6660 return match.toUpperCase().replace('_','');
6661 });
6662 Name = Name.substring(0,1).toUpperCase() + Name.substring(1);
6663
6664 // set/get_[some_value] FIXME: Do we really need these?
6665 var name = field.originalName.replace(/([A-Z])/g, function(match) {
6666 return "_"+match;
6667 });
6668
6669 /**
6670 * The current field's unbound setter function.
6671 * @function
6672 * @param {*} value
6673 * @param {boolean=} noAssert
6674 * @returns {!ProtoBuf.Builder.Message}
6675 * @inner
6676 */
6677 var setter = function(value, noAssert) {
6678 this[field.name] = noAssert ? value : field.verifyValue(value);
6679 return this;
6680 };
6681
6682 /**
6683 * The current field's unbound getter function.
6684 * @function
6685 * @returns {*}
6686 * @inner
6687 */
6688 var getter = function() {
6689 return this[field.name];
6690 };
6691
6692 if (T.getChild("set"+Name) === null)
6693 /**
6694 * Sets a value. This method is present for each field, but only if there is no name conflict with
6695 * another field.
6696 * @name ProtoBuf.Builder.Message#set[SomeField]
6697 * @function
6698 * @param {*} value Value to set
6699 * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
6700 * @returns {!ProtoBuf.Builder.Message} this
6701 * @abstract
6702 * @throws {Error} If the value cannot be set
6703 */
6704 MessagePrototype["set"+Name] = setter;
6705
6706 if (T.getChild("set_"+name) === null)
6707 /**
6708 * Sets a value. This method is present for each field, but only if there is no name conflict with
6709 * another field.
6710 * @name ProtoBuf.Builder.Message#set_[some_field]
6711 * @function
6712 * @param {*} value Value to set
6713 * @param {boolean=} noAssert Whether to not assert the value, defaults to `false`
6714 * @returns {!ProtoBuf.Builder.Message} this
6715 * @abstract
6716 * @throws {Error} If the value cannot be set
6717 */
6718 MessagePrototype["set_"+name] = setter;
6719
6720 if (T.getChild("get"+Name) === null)
6721 /**
6722 * Gets a value. This method is present for each field, but only if there is no name conflict with
6723 * another field.
6724 * @name ProtoBuf.Builder.Message#get[SomeField]
6725 * @function
6726 * @abstract
6727 * @return {*} The value
6728 */
6729 MessagePrototype["get"+Name] = getter;
6730
6731 if (T.getChild("get_"+name) === null)
6732 /**
6733 * Gets a value. This method is present for each field, but only if there is no name conflict with
6734 * another field.
6735 * @name ProtoBuf.Builder.Message#get_[some_field]
6736 * @function
6737 * @return {*} The value
6738 * @abstract
6739 */
6740 MessagePrototype["get_"+name] = getter;
6741
6742 })(field);
6743 }
6744
6745 // En-/decoding
6746
6747 /**
6748 * Encodes the message.
6749 * @name ProtoBuf.Builder.Message#$encode
6750 * @function
6751 * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.
6752 * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
6753 * @return {!ByteBuffer} Encoded message as a ByteBuffer
6754 * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
6755 * returns the encoded ByteBuffer in the `encoded` property on the error.
6756 * @expose
6757 * @see ProtoBuf.Builder.Message#encode64
6758 * @see ProtoBuf.Builder.Message#encodeHex
6759 * @see ProtoBuf.Builder.Message#encodeAB
6760 */
6761 MessagePrototype.encode = function(buffer, noVerify) {
6762 if (typeof buffer === 'boolean')
6763 noVerify = buffer,
6764 buffer = undefined;
6765 var isNew = false;
6766 if (!buffer)
6767 buffer = new ByteBuffer(),
6768 isNew = true;
6769 var le = buffer.littleEndian;
6770 try {
6771 T.encode(this, buffer.LE(), noVerify);
6772 return (isNew ? buffer.flip() : buffer).LE(le);
6773 } catch (e) {
6774 buffer.LE(le);
6775 throw(e);
6776 }
6777 };
6778
6779 /**
6780 * Encodes a message using the specified data payload.
6781 * @param {!Object.<string,*>} data Data payload
6782 * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.
6783 * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
6784 * @return {!ByteBuffer} Encoded message as a ByteBuffer
6785 * @expose
6786 */
6787 Message.encode = function(data, buffer, noVerify) {
6788 return new Message(data).encode(buffer, noVerify);
6789 };
6790
6791 /**
6792 * Calculates the byte length of the message.
6793 * @name ProtoBuf.Builder.Message#calculate
6794 * @function
6795 * @returns {number} Byte length
6796 * @throws {Error} If the message cannot be calculated or if required fields are missing.
6797 * @expose
6798 */
6799 MessagePrototype.calculate = function() {
6800 return T.calculate(this);
6801 };
6802
6803 /**
6804 * Encodes the varint32 length-delimited message.
6805 * @name ProtoBuf.Builder.Message#encodeDelimited
6806 * @function
6807 * @param {(!ByteBuffer|boolean)=} buffer ByteBuffer to encode to. Will create a new one and flip it if omitted.
6808 * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
6809 * @return {!ByteBuffer} Encoded message as a ByteBuffer
6810 * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
6811 * returns the encoded ByteBuffer in the `encoded` property on the error.
6812 * @expose
6813 */
6814 MessagePrototype.encodeDelimited = function(buffer, noVerify) {
6815 var isNew = false;
6816 if (!buffer)
6817 buffer = new ByteBuffer(),
6818 isNew = true;
6819 var enc = new ByteBuffer().LE();
6820 T.encode(this, enc, noVerify).flip();
6821 buffer.writeVarint32(enc.remaining());
6822 buffer.append(enc);
6823 return isNew ? buffer.flip() : buffer;
6824 };
6825
6826 /**
6827 * Directly encodes the message to an ArrayBuffer.
6828 * @name ProtoBuf.Builder.Message#encodeAB
6829 * @function
6830 * @return {ArrayBuffer} Encoded message as ArrayBuffer
6831 * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
6832 * returns the encoded ArrayBuffer in the `encoded` property on the error.
6833 * @expose
6834 */
6835 MessagePrototype.encodeAB = function() {
6836 try {
6837 return this.encode().toArrayBuffer();
6838 } catch (e) {
6839 if (e["encoded"]) e["encoded"] = e["encoded"].toArrayBuffer();
6840 throw(e);
6841 }
6842 };
6843
6844 /**
6845 * Returns the message as an ArrayBuffer. This is an alias for {@link ProtoBuf.Builder.Message#encodeAB}.
6846 * @name ProtoBuf.Builder.Message#toArrayBuffer
6847 * @function
6848 * @return {ArrayBuffer} Encoded message as ArrayBuffer
6849 * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
6850 * returns the encoded ArrayBuffer in the `encoded` property on the error.
6851 * @expose
6852 */
6853 MessagePrototype.toArrayBuffer = MessagePrototype.encodeAB;
6854
6855 /**
6856 * Directly encodes the message to a node Buffer.
6857 * @name ProtoBuf.Builder.Message#encodeNB
6858 * @function
6859 * @return {!Buffer}
6860 * @throws {Error} If the message cannot be encoded, not running under node.js or if required fields are
6861 * missing. The later still returns the encoded node Buffer in the `encoded` property on the error.
6862 * @expose
6863 */
6864 MessagePrototype.encodeNB = function() {
6865 try {
6866 return this.encode().toBuffer();
6867 } catch (e) {
6868 if (e["encoded"]) e["encoded"] = e["encoded"].toBuffer();
6869 throw(e);
6870 }
6871 };
6872
6873 /**
6874 * Returns the message as a node Buffer. This is an alias for {@link ProtoBuf.Builder.Message#encodeNB}.
6875 * @name ProtoBuf.Builder.Message#toBuffer
6876 * @function
6877 * @return {!Buffer}
6878 * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
6879 * returns the encoded node Buffer in the `encoded` property on the error.
6880 * @expose
6881 */
6882 MessagePrototype.toBuffer = MessagePrototype.encodeNB;
6883
6884 /**
6885 * Directly encodes the message to a base64 encoded string.
6886 * @name ProtoBuf.Builder.Message#encode64
6887 * @function
6888 * @return {string} Base64 encoded string
6889 * @throws {Error} If the underlying buffer cannot be encoded or if required fields are missing. The later
6890 * still returns the encoded base64 string in the `encoded` property on the error.
6891 * @expose
6892 */
6893 MessagePrototype.encode64 = function() {
6894 try {
6895 return this.encode().toBase64();
6896 } catch (e) {
6897 if (e["encoded"]) e["encoded"] = e["encoded"].toBase64();
6898 throw(e);
6899 }
6900 };
6901
6902 /**
6903 * Returns the message as a base64 encoded string. This is an alias for {@link ProtoBuf.Builder.Message#encode64}.
6904 * @name ProtoBuf.Builder.Message#toBase64
6905 * @function
6906 * @return {string} Base64 encoded string
6907 * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
6908 * returns the encoded base64 string in the `encoded` property on the error.
6909 * @expose
6910 */
6911 MessagePrototype.toBase64 = MessagePrototype.encode64;
6912
6913 /**
6914 * Directly encodes the message to a hex encoded string.
6915 * @name ProtoBuf.Builder.Message#encodeHex
6916 * @function
6917 * @return {string} Hex encoded string
6918 * @throws {Error} If the underlying buffer cannot be encoded or if required fields are missing. The later
6919 * still returns the encoded hex string in the `encoded` property on the error.
6920 * @expose
6921 */
6922 MessagePrototype.encodeHex = function() {
6923 try {
6924 return this.encode().toHex();
6925 } catch (e) {
6926 if (e["encoded"]) e["encoded"] = e["encoded"].toHex();
6927 throw(e);
6928 }
6929 };
6930
6931 /**
6932 * Returns the message as a hex encoded string. This is an alias for {@link ProtoBuf.Builder.Message#encodeHex}.
6933 * @name ProtoBuf.Builder.Message#toHex
6934 * @function
6935 * @return {string} Hex encoded string
6936 * @throws {Error} If the message cannot be encoded or if required fields are missing. The later still
6937 * returns the encoded hex string in the `encoded` property on the error.
6938 * @expose
6939 */
6940 MessagePrototype.toHex = MessagePrototype.encodeHex;
6941
6942 /**
6943 * Clones a message object or field value to a raw object.
6944 * @param {*} obj Object to clone
6945 * @param {boolean} binaryAsBase64 Whether to include binary data as base64 strings or as a buffer otherwise
6946 * @param {boolean} longsAsStrings Whether to encode longs as strings
6947 * @param {!ProtoBuf.Reflect.T=} resolvedType The resolved field type if a field
6948 * @returns {*} Cloned object
6949 * @inner
6950 */
6951 function cloneRaw(obj, binaryAsBase64, longsAsStrings, resolvedType) {
6952 if (obj === null || typeof obj !== 'object') {
6953 // Convert enum values to their respective names
6954 if (resolvedType && resolvedType instanceof ProtoBuf.Reflect.Enum) {
6955 var name = ProtoBuf.Reflect.Enum.getName(resolvedType.object, obj);
6956 if (name !== null)
6957 return name;
6958 }
6959 // Pass-through string, number, boolean, null...
6960 return obj;
6961 }
6962 // Convert ByteBuffers to raw buffer or strings
6963 if (ByteBuffer.isByteBuffer(obj))
6964 return binaryAsBase64 ? obj.toBase64() : obj.toBuffer();
6965 // Convert Longs to proper objects or strings
6966 if (ProtoBuf.Long.isLong(obj))
6967 return longsAsStrings ? obj.toString() : ProtoBuf.Long.fromValue(obj);
6968 var clone;
6969 // Clone arrays
6970 if (Array.isArray(obj)) {
6971 clone = [];
6972 obj.forEach(function(v, k) {
6973 clone[k] = cloneRaw(v, binaryAsBase64, longsAsStrings, resolvedType);
6974 });
6975 return clone;
6976 }
6977 clone = {};
6978 // Convert maps to objects
6979 if (obj instanceof ProtoBuf.Map) {
6980 var it = obj.entries();
6981 for (var e = it.next(); !e.done; e = it.next())
6982 clone[obj.keyElem.valueToString(e.value[0])] = cloneRaw(e.value[1], binaryAsBase64, longsAsStrings, obj.valueElem.resolvedType);
6983 return clone;
6984 }
6985 // Everything else is a non-null object
6986 var type = obj.$type,
6987 field = undefined;
6988 for (var i in obj)
6989 if (obj.hasOwnProperty(i)) {
6990 if (type && (field = type.getChild(i)))
6991 clone[i] = cloneRaw(obj[i], binaryAsBase64, longsAsStrings, field.resolvedType);
6992 else
6993 clone[i] = cloneRaw(obj[i], binaryAsBase64, longsAsStrings);
6994 }
6995 return clone;
6996 }
6997
6998 /**
6999 * Returns the message's raw payload.
7000 * @param {boolean=} binaryAsBase64 Whether to include binary data as base64 strings instead of Buffers, defaults to `false`
7001 * @param {boolean} longsAsStrings Whether to encode longs as strings
7002 * @returns {Object.<string,*>} Raw payload
7003 * @expose
7004 */
7005 MessagePrototype.toRaw = function(binaryAsBase64, longsAsStrings) {
7006 return cloneRaw(this, !!binaryAsBase64, !!longsAsStrings, this.$type);
7007 };
7008
7009 /**
7010 * Encodes a message to JSON.
7011 * @returns {string} JSON string
7012 * @expose
7013 */
7014 MessagePrototype.encodeJSON = function() {
7015 return JSON.stringify(
7016 cloneRaw(this,
7017 /* binary-as-base64 */ true,
7018 /* longs-as-strings */ true,
7019 this.$type
7020 )
7021 );
7022 };
7023
7024 /**
7025 * Decodes a message from the specified buffer or string.
7026 * @name ProtoBuf.Builder.Message.decode
7027 * @function
7028 * @param {!ByteBuffer|!ArrayBuffer|!Buffer|string} buffer Buffer to decode from
7029 * @param {(number|string)=} length Message length. Defaults to decode all the remainig data.
7030 * @param {string=} enc Encoding if buffer is a string: hex, utf8 (not recommended), defaults to base64
7031 * @return {!ProtoBuf.Builder.Message} Decoded message
7032 * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
7033 * returns the decoded message with missing fields in the `decoded` property on the error.
7034 * @expose
7035 * @see ProtoBuf.Builder.Message.decode64
7036 * @see ProtoBuf.Builder.Message.decodeHex
7037 */
7038 Message.decode = function(buffer, length, enc) {
7039 if (typeof length === 'string')
7040 enc = length,
7041 length = -1;
7042 if (typeof buffer === 'string')
7043 buffer = ByteBuffer.wrap(buffer, enc ? enc : "base64");
7044 else if (!ByteBuffer.isByteBuffer(buffer))
7045 buffer = ByteBuffer.wrap(buffer); // May throw
7046 var le = buffer.littleEndian;
7047 try {
7048 var msg = T.decode(buffer.LE(), length);
7049 buffer.LE(le);
7050 return msg;
7051 } catch (e) {
7052 buffer.LE(le);
7053 throw(e);
7054 }
7055 };
7056
7057 /**
7058 * Decodes a varint32 length-delimited message from the specified buffer or string.
7059 * @name ProtoBuf.Builder.Message.decodeDelimited
7060 * @function
7061 * @param {!ByteBuffer|!ArrayBuffer|!Buffer|string} buffer Buffer to decode from
7062 * @param {string=} enc Encoding if buffer is a string: hex, utf8 (not recommended), defaults to base64
7063 * @return {ProtoBuf.Builder.Message} Decoded message or `null` if not enough bytes are available yet
7064 * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
7065 * returns the decoded message with missing fields in the `decoded` property on the error.
7066 * @expose
7067 */
7068 Message.decodeDelimited = function(buffer, enc) {
7069 if (typeof buffer === 'string')
7070 buffer = ByteBuffer.wrap(buffer, enc ? enc : "base64");
7071 else if (!ByteBuffer.isByteBuffer(buffer))
7072 buffer = ByteBuffer.wrap(buffer); // May throw
7073 if (buffer.remaining() < 1)
7074 return null;
7075 var off = buffer.offset,
7076 len = buffer.readVarint32();
7077 if (buffer.remaining() < len) {
7078 buffer.offset = off;
7079 return null;
7080 }
7081 try {
7082 var msg = T.decode(buffer.slice(buffer.offset, buffer.offset + len).LE());
7083 buffer.offset += len;
7084 return msg;
7085 } catch (err) {
7086 buffer.offset += len;
7087 throw err;
7088 }
7089 };
7090
7091 /**
7092 * Decodes the message from the specified base64 encoded string.
7093 * @name ProtoBuf.Builder.Message.decode64
7094 * @function
7095 * @param {string} str String to decode from
7096 * @return {!ProtoBuf.Builder.Message} Decoded message
7097 * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
7098 * returns the decoded message with missing fields in the `decoded` property on the error.
7099 * @expose
7100 */
7101 Message.decode64 = function(str) {
7102 return Message.decode(str, "base64");
7103 };
7104
7105 /**
7106 * Decodes the message from the specified hex encoded string.
7107 * @name ProtoBuf.Builder.Message.decodeHex
7108 * @function
7109 * @param {string} str String to decode from
7110 * @return {!ProtoBuf.Builder.Message} Decoded message
7111 * @throws {Error} If the message cannot be decoded or if required fields are missing. The later still
7112 * returns the decoded message with missing fields in the `decoded` property on the error.
7113 * @expose
7114 */
7115 Message.decodeHex = function(str) {
7116 return Message.decode(str, "hex");
7117 };
7118
7119 /**
7120 * Decodes the message from a JSON string.
7121 * @name ProtoBuf.Builder.Message.decodeJSON
7122 * @function
7123 * @param {string} str String to decode from
7124 * @return {!ProtoBuf.Builder.Message} Decoded message
7125 * @throws {Error} If the message cannot be decoded or if required fields are
7126 * missing.
7127 * @expose
7128 */
7129 Message.decodeJSON = function(str) {
7130 return new Message(JSON.parse(str));
7131 };
7132
7133 // Utility
7134
7135 /**
7136 * Returns a string representation of this Message.
7137 * @name ProtoBuf.Builder.Message#toString
7138 * @function
7139 * @return {string} String representation as of ".Fully.Qualified.MessageName"
7140 * @expose
7141 */
7142 MessagePrototype.toString = function() {
7143 return T.toString();
7144 };
7145
7146 if (Object.defineProperty)
7147 Object.defineProperty(Message, '$options', { "value": T.buildOpt() }),
7148 Object.defineProperty(MessagePrototype, "$options", { "value": Message["$options"] }),
7149 Object.defineProperty(Message, "$type", { "value": T }),
7150 Object.defineProperty(MessagePrototype, "$type", { "value": T });
7151
7152 return Message;
7153
7154 })(ProtoBuf, this);
7155
7156 // Static enums and prototyped sub-messages / cached collections
7157 this._fields = [];
7158 this._fieldsById = {};
7159 this._fieldsByName = {};
7160 this._oneofsByName = {};
7161 for (var i=0, k=this.children.length, child; i<k; i++) {
7162 child = this.children[i];
7163 if (child instanceof Enum || child instanceof Message || child instanceof Service) {
7164 if (clazz.hasOwnProperty(child.name))
7165 throw Error("Illegal reflect child of "+this.toString(true)+": "+child.toString(true)+" cannot override static property '"+child.name+"'");
7166 clazz[child.name] = child.build();
7167 } else if (child instanceof Message.Field)
7168 child.build(),
7169 this._fields.push(child),
7170 this._fieldsById[child.id] = child,
7171 this._fieldsByName[child.name] = child;
7172 else if (child instanceof Message.OneOf) {
7173 this._oneofsByName[child.name] = child;
7174 }
7175 else if (!(child instanceof Message.OneOf) && !(child instanceof Extension)) // Not built
7176 throw Error("Illegal reflect child of "+this.toString(true)+": "+this.children[i].toString(true));
7177 }
7178
7179 return this.clazz = clazz;
7180 };
7181
7182 /**
7183 * Encodes a runtime message's contents to the specified buffer.
7184 * @param {!ProtoBuf.Builder.Message} message Runtime message to encode
7185 * @param {ByteBuffer} buffer ByteBuffer to write to
7186 * @param {boolean=} noVerify Whether to not verify field values, defaults to `false`
7187 * @return {ByteBuffer} The ByteBuffer for chaining
7188 * @throws {Error} If required fields are missing or the message cannot be encoded for another reason
7189 * @expose
7190 */
7191 MessagePrototype.encode = function(message, buffer, noVerify) {
7192 var fieldMissing = null,
7193 field;
7194 for (var i=0, k=this._fields.length, val; i<k; ++i) {
7195 field = this._fields[i];
7196 val = message[field.name];
7197 if (field.required && val === null) {
7198 if (fieldMissing === null)
7199 fieldMissing = field;
7200 } else
7201 field.encode(noVerify ? val : field.verifyValue(val), buffer, message);
7202 }
7203 if (fieldMissing !== null) {
7204 var err = Error("Missing at least one required field for "+this.toString(true)+": "+fieldMissing);
7205 err["encoded"] = buffer; // Still expose what we got
7206 throw(err);
7207 }
7208 return buffer;
7209 };
7210
7211 /**
7212 * Calculates a runtime message's byte length.
7213 * @param {!ProtoBuf.Builder.Message} message Runtime message to encode
7214 * @returns {number} Byte length
7215 * @throws {Error} If required fields are missing or the message cannot be calculated for another reason
7216 * @expose
7217 */
7218 MessagePrototype.calculate = function(message) {
7219 for (var n=0, i=0, k=this._fields.length, field, val; i<k; ++i) {
7220 field = this._fields[i];
7221 val = message[field.name];
7222 if (field.required && val === null)
7223 throw Error("Missing at least one required field for "+this.toString(true)+": "+field);
7224 else
7225 n += field.calculate(val, message);
7226 }
7227 return n;
7228 };
7229
7230 /**
7231 * Skips all data until the end of the specified group has been reached.
7232 * @param {number} expectedId Expected GROUPEND id
7233 * @param {!ByteBuffer} buf ByteBuffer
7234 * @returns {boolean} `true` if a value as been skipped, `false` if the end has been reached
7235 * @throws {Error} If it wasn't possible to find the end of the group (buffer overrun or end tag mismatch)
7236 * @inner
7237 */
7238 function skipTillGroupEnd(expectedId, buf) {
7239 var tag = buf.readVarint32(), // Throws on OOB
7240 wireType = tag & 0x07,
7241 id = tag >>> 3;
7242 switch (wireType) {
7243 case ProtoBuf.WIRE_TYPES.VARINT:
7244 do tag = buf.readUint8();
7245 while ((tag & 0x80) === 0x80);
7246 break;
7247 case ProtoBuf.WIRE_TYPES.BITS64:
7248 buf.offset += 8;
7249 break;
7250 case ProtoBuf.WIRE_TYPES.LDELIM:
7251 tag = buf.readVarint32(); // reads the varint
7252 buf.offset += tag; // skips n bytes
7253 break;
7254 case ProtoBuf.WIRE_TYPES.STARTGROUP:
7255 skipTillGroupEnd(id, buf);
7256 break;
7257 case ProtoBuf.WIRE_TYPES.ENDGROUP:
7258 if (id === expectedId)
7259 return false;
7260 else
7261 throw Error("Illegal GROUPEND after unknown group: "+id+" ("+expectedId+" expected)");
7262 case ProtoBuf.WIRE_TYPES.BITS32:
7263 buf.offset += 4;
7264 break;
7265 default:
7266 throw Error("Illegal wire type in unknown group "+expectedId+": "+wireType);
7267 }
7268 return true;
7269 }
7270
7271 /**
7272 * Decodes an encoded message and returns the decoded message.
7273 * @param {ByteBuffer} buffer ByteBuffer to decode from
7274 * @param {number=} length Message length. Defaults to decode all remaining data.
7275 * @param {number=} expectedGroupEndId Expected GROUPEND id if this is a legacy group
7276 * @return {ProtoBuf.Builder.Message} Decoded message
7277 * @throws {Error} If the message cannot be decoded
7278 * @expose
7279 */
7280 MessagePrototype.decode = function(buffer, length, expectedGroupEndId) {
7281 if (typeof length !== 'number')
7282 length = -1;
7283 var start = buffer.offset,
7284 msg = new (this.clazz)(),
7285 tag, wireType, id, field;
7286 while (buffer.offset < start+length || (length === -1 && buffer.remaining() > 0)) {
7287 tag = buffer.readVarint32();
7288 wireType = tag & 0x07;
7289 id = tag >>> 3;
7290 if (wireType === ProtoBuf.WIRE_TYPES.ENDGROUP) {
7291 if (id !== expectedGroupEndId)
7292 throw Error("Illegal group end indicator for "+this.toString(true)+": "+id+" ("+(expectedGroupEndId ? expectedGroupEndId+" expected" : "not a group")+")");
7293 break;
7294 }
7295 if (!(field = this._fieldsById[id])) {
7296 // "messages created by your new code can be parsed by your old code: old binaries simply ignore the new field when parsing."
7297 switch (wireType) {
7298 case ProtoBuf.WIRE_TYPES.VARINT:
7299 buffer.readVarint32();
7300 break;
7301 case ProtoBuf.WIRE_TYPES.BITS32:
7302 buffer.offset += 4;
7303 break;
7304 case ProtoBuf.WIRE_TYPES.BITS64:
7305 buffer.offset += 8;
7306 break;
7307 case ProtoBuf.WIRE_TYPES.LDELIM:
7308 var len = buffer.readVarint32();
7309 buffer.offset += len;
7310 break;
7311 case ProtoBuf.WIRE_TYPES.STARTGROUP:
7312 while (skipTillGroupEnd(id, buffer)) {}
7313 break;
7314 default:
7315 throw Error("Illegal wire type for unknown field "+id+" in "+this.toString(true)+"#decode: "+wireType);
7316 }
7317 continue;
7318 }
7319 if (field.repeated && !field.options["packed"]) {
7320 msg[field.name].push(field.decode(wireType, buffer));
7321 } else if (field.map) {
7322 var keyval = field.decode(wireType, buffer);
7323 msg[field.name].set(keyval[0], keyval[1]);
7324 } else {
7325 msg[field.name] = field.decode(wireType, buffer);
7326 if (field.oneof) { // Field is part of an OneOf (not a virtual OneOf field)
7327 var currentField = msg[field.oneof.name]; // Virtual field references currently set field
7328 if (currentField !== null && currentField !== field.name)
7329 msg[currentField] = null; // Clear currently set field
7330 msg[field.oneof.name] = field.name; // Point virtual field at this field
7331 }
7332 }
7333 }
7334
7335 // Check if all required fields are present and set default values for optional fields that are not
7336 for (var i=0, k=this._fields.length; i<k; ++i) {
7337 field = this._fields[i];
7338 if (msg[field.name] === null) {
7339 if (this.syntax === "proto3") { // Proto3 sets default values by specification
7340 msg[field.name] = field.defaultValue;
7341 } else if (field.required) {
7342 var err = Error("Missing at least one required field for " + this.toString(true) + ": " + field.name);
7343 err["decoded"] = msg; // Still expose what we got
7344 throw(err);
7345 } else if (ProtoBuf.populateDefaults && field.defaultValue !== null)
7346 msg[field.name] = field.defaultValue;
7347 }
7348 }
7349 return msg;
7350 };
7351
7352 /**
7353 * @alias ProtoBuf.Reflect.Message
7354 * @expose
7355 */
7356 Reflect.Message = Message;
7357
7358 /**
7359 * Constructs a new Message Field.
7360 * @exports ProtoBuf.Reflect.Message.Field
7361 * @param {!ProtoBuf.Builder} builder Builder reference
7362 * @param {!ProtoBuf.Reflect.Message} message Message reference
7363 * @param {string} rule Rule, one of requried, optional, repeated
7364 * @param {string?} keytype Key data type, if any.
7365 * @param {string} type Data type, e.g. int32
7366 * @param {string} name Field name
7367 * @param {number} id Unique field id
7368 * @param {Object.<string,*>=} options Options
7369 * @param {!ProtoBuf.Reflect.Message.OneOf=} oneof Enclosing OneOf
7370 * @param {string?} syntax The syntax level of this definition (e.g., proto3)
7371 * @constructor
7372 * @extends ProtoBuf.Reflect.T
7373 */
7374 var Field = function(builder, message, rule, keytype, type, name, id, options, oneof, syntax) {
7375 T.call(this, builder, message, name);
7376
7377 /**
7378 * @override
7379 */
7380 this.className = "Message.Field";
7381
7382 /**
7383 * Message field required flag.
7384 * @type {boolean}
7385 * @expose
7386 */
7387 this.required = rule === "required";
7388
7389 /**
7390 * Message field repeated flag.
7391 * @type {boolean}
7392 * @expose
7393 */
7394 this.repeated = rule === "repeated";
7395
7396 /**
7397 * Message field map flag.
7398 * @type {boolean}
7399 * @expose
7400 */
7401 this.map = rule === "map";
7402
7403 /**
7404 * Message field key type. Type reference string if unresolved, protobuf
7405 * type if resolved. Valid only if this.map === true, null otherwise.
7406 * @type {string|{name: string, wireType: number}|null}
7407 * @expose
7408 */
7409 this.keyType = keytype || null;
7410
7411 /**
7412 * Message field type. Type reference string if unresolved, protobuf type if
7413 * resolved. In a map field, this is the value type.
7414 * @type {string|{name: string, wireType: number}}
7415 * @expose
7416 */
7417 this.type = type;
7418
7419 /**
7420 * Resolved type reference inside the global namespace.
7421 * @type {ProtoBuf.Reflect.T|null}
7422 * @expose
7423 */
7424 this.resolvedType = null;
7425
7426 /**
7427 * Unique message field id.
7428 * @type {number}
7429 * @expose
7430 */
7431 this.id = id;
7432
7433 /**
7434 * Message field options.
7435 * @type {!Object.<string,*>}
7436 * @dict
7437 * @expose
7438 */
7439 this.options = options || {};
7440
7441 /**
7442 * Default value.
7443 * @type {*}
7444 * @expose
7445 */
7446 this.defaultValue = null;
7447
7448 /**
7449 * Enclosing OneOf.
7450 * @type {?ProtoBuf.Reflect.Message.OneOf}
7451 * @expose
7452 */
7453 this.oneof = oneof || null;
7454
7455 /**
7456 * Syntax level of this definition (e.g., proto3).
7457 * @type {string}
7458 * @expose
7459 */
7460 this.syntax = syntax || 'proto2';
7461
7462 /**
7463 * Original field name.
7464 * @type {string}
7465 * @expose
7466 */
7467 this.originalName = this.name; // Used to revert camelcase transformation on naming collisions
7468
7469 /**
7470 * Element implementation. Created in build() after types are resolved.
7471 * @type {ProtoBuf.Element}
7472 * @expose
7473 */
7474 this.element = null;
7475
7476 /**
7477 * Key element implementation, for map fields. Created in build() after
7478 * types are resolved.
7479 * @type {ProtoBuf.Element}
7480 * @expose
7481 */
7482 this.keyElement = null;
7483
7484 // Convert field names to camel case notation if the override is set
7485 if (this.builder.options['convertFieldsToCamelCase'] && !(this instanceof Message.ExtensionField))
7486 this.name = ProtoBuf.Util.toCamelCase(this.name);
7487 };
7488
7489 /**
7490 * @alias ProtoBuf.Reflect.Message.Field.prototype
7491 * @inner
7492 */
7493 var FieldPrototype = Field.prototype = Object.create(T.prototype);
7494
7495 /**
7496 * Builds the field.
7497 * @override
7498 * @expose
7499 */
7500 FieldPrototype.build = function() {
7501 this.element = new Element(this.type, this.resolvedType, false, this.syntax, this.name);
7502 if (this.map)
7503 this.keyElement = new Element(this.keyType, undefined, true, this.syntax, this.name);
7504
7505 // In proto3, fields do not have field presence, and every field is set to
7506 // its type's default value ("", 0, 0.0, or false).
7507 if (this.syntax === 'proto3' && !this.repeated && !this.map)
7508 this.defaultValue = Element.defaultFieldValue(this.type);
7509
7510 // Otherwise, default values are present when explicitly specified
7511 else if (typeof this.options['default'] !== 'undefined')
7512 this.defaultValue = this.verifyValue(this.options['default']);
7513 };
7514
7515 /**
7516 * Checks if the given value can be set for this field.
7517 * @param {*} value Value to check
7518 * @param {boolean=} skipRepeated Whether to skip the repeated value check or not. Defaults to false.
7519 * @return {*} Verified, maybe adjusted, value
7520 * @throws {Error} If the value cannot be set for this field
7521 * @expose
7522 */
7523 FieldPrototype.verifyValue = function(value, skipRepeated) {
7524 skipRepeated = skipRepeated || false;
7525 var self = this;
7526 function fail(val, msg) {
7527 throw Error("Illegal value for "+self.toString(true)+" of type "+self.type.name+": "+val+" ("+msg+")");
7528 }
7529 if (value === null) { // NULL values for optional fields
7530 if (this.required)
7531 fail(typeof value, "required");
7532 if (this.syntax === 'proto3' && this.type !== ProtoBuf.TYPES["message"])
7533 fail(typeof value, "proto3 field without field presence cannot be null");
7534 return null;
7535 }
7536 var i;
7537 if (this.repeated && !skipRepeated) { // Repeated values as arrays
7538 if (!Array.isArray(value))
7539 value = [value];
7540 var res = [];
7541 for (i=0; i<value.length; i++)
7542 res.push(this.element.verifyValue(value[i]));
7543 return res;
7544 }
7545 if (this.map && !skipRepeated) { // Map values as objects
7546 if (!(value instanceof ProtoBuf.Map)) {
7547 // If not already a Map, attempt to convert.
7548 if (!(value instanceof Object)) {
7549 fail(typeof value,
7550 "expected ProtoBuf.Map or raw object for map field");
7551 }
7552 return new ProtoBuf.Map(this, value);
7553 } else {
7554 return value;
7555 }
7556 }
7557 // All non-repeated fields expect no array
7558 if (!this.repeated && Array.isArray(value))
7559 fail(typeof value, "no array expected");
7560
7561 return this.element.verifyValue(value);
7562 };
7563
7564 /**
7565 * Determines whether the field will have a presence on the wire given its
7566 * value.
7567 * @param {*} value Verified field value
7568 * @param {!ProtoBuf.Builder.Message} message Runtime message
7569 * @return {boolean} Whether the field will be present on the wire
7570 */
7571 FieldPrototype.hasWirePresence = function(value, message) {
7572 if (this.syntax !== 'proto3')
7573 return (value !== null);
7574 if (this.oneof && message[this.oneof.name] === this.name)
7575 return true;
7576 switch (this.type) {
7577 case ProtoBuf.TYPES["int32"]:
7578 case ProtoBuf.TYPES["sint32"]:
7579 case ProtoBuf.TYPES["sfixed32"]:
7580 case ProtoBuf.TYPES["uint32"]:
7581 case ProtoBuf.TYPES["fixed32"]:
7582 return value !== 0;
7583
7584 case ProtoBuf.TYPES["int64"]:
7585 case ProtoBuf.TYPES["sint64"]:
7586 case ProtoBuf.TYPES["sfixed64"]:
7587 case ProtoBuf.TYPES["uint64"]:
7588 case ProtoBuf.TYPES["fixed64"]:
7589 return value.low !== 0 || value.high !== 0;
7590
7591 case ProtoBuf.TYPES["bool"]:
7592 return value;
7593
7594 case ProtoBuf.TYPES["float"]:
7595 case ProtoBuf.TYPES["double"]:
7596 return value !== 0.0;
7597
7598 case ProtoBuf.TYPES["string"]:
7599 return value.length > 0;
7600
7601 case ProtoBuf.TYPES["bytes"]:
7602 return value.remaining() > 0;
7603
7604 case ProtoBuf.TYPES["enum"]:
7605 return value !== 0;
7606
7607 case ProtoBuf.TYPES["message"]:
7608 return value !== null;
7609 default:
7610 return true;
7611 }
7612 };
7613
7614 /**
7615 * Encodes the specified field value to the specified buffer.
7616 * @param {*} value Verified field value
7617 * @param {ByteBuffer} buffer ByteBuffer to encode to
7618 * @param {!ProtoBuf.Builder.Message} message Runtime message
7619 * @return {ByteBuffer} The ByteBuffer for chaining
7620 * @throws {Error} If the field cannot be encoded
7621 * @expose
7622 */
7623 FieldPrototype.encode = function(value, buffer, message) {
7624 if (this.type === null || typeof this.type !== 'object')
7625 throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
7626 if (value === null || (this.repeated && value.length == 0))
7627 return buffer; // Optional omitted
7628 try {
7629 if (this.repeated) {
7630 var i;
7631 // "Only repeated fields of primitive numeric types (types which use the varint, 32-bit, or 64-bit wire
7632 // types) can be declared 'packed'."
7633 if (this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {
7634 // "All of the elements of the field are packed into a single key-value pair with wire type 2
7635 // (length-delimited). Each element is encoded the same way it would be normally, except without a
7636 // tag preceding it."
7637 buffer.writeVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
7638 buffer.ensureCapacity(buffer.offset += 1); // We do not know the length yet, so let's assume a varint of length 1
7639 var start = buffer.offset; // Remember where the contents begin
7640 for (i=0; i<value.length; i++)
7641 this.element.encodeValue(this.id, value[i], buffer);
7642 var len = buffer.offset-start,
7643 varintLen = ByteBuffer.calculateVarint32(len);
7644 if (varintLen > 1) { // We need to move the contents
7645 var contents = buffer.slice(start, buffer.offset);
7646 start += varintLen-1;
7647 buffer.offset = start;
7648 buffer.append(contents);
7649 }
7650 buffer.writeVarint32(len, start-varintLen);
7651 } else {
7652 // "If your message definition has repeated elements (without the [packed=true] option), the encoded
7653 // message has zero or more key-value pairs with the same tag number"
7654 for (i=0; i<value.length; i++)
7655 buffer.writeVarint32((this.id << 3) | this.type.wireType),
7656 this.element.encodeValue(this.id, value[i], buffer);
7657 }
7658 } else if (this.map) {
7659 // Write out each map entry as a submessage.
7660 value.forEach(function(val, key, m) {
7661 // Compute the length of the submessage (key, val) pair.
7662 var length =
7663 ByteBuffer.calculateVarint32((1 << 3) | this.keyType.wireType) +
7664 this.keyElement.calculateLength(1, key) +
7665 ByteBuffer.calculateVarint32((2 << 3) | this.type.wireType) +
7666 this.element.calculateLength(2, val);
7667
7668 // Submessage with wire type of length-delimited.
7669 buffer.writeVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
7670 buffer.writeVarint32(length);
7671
7672 // Write out the key and val.
7673 buffer.writeVarint32((1 << 3) | this.keyType.wireType);
7674 this.keyElement.encodeValue(1, key, buffer);
7675 buffer.writeVarint32((2 << 3) | this.type.wireType);
7676 this.element.encodeValue(2, val, buffer);
7677 }, this);
7678 } else {
7679 if (this.hasWirePresence(value, message)) {
7680 buffer.writeVarint32((this.id << 3) | this.type.wireType);
7681 this.element.encodeValue(this.id, value, buffer);
7682 }
7683 }
7684 } catch (e) {
7685 throw Error("Illegal value for "+this.toString(true)+": "+value+" ("+e+")");
7686 }
7687 return buffer;
7688 };
7689
7690 /**
7691 * Calculates the length of this field's value on the network level.
7692 * @param {*} value Field value
7693 * @param {!ProtoBuf.Builder.Message} message Runtime message
7694 * @returns {number} Byte length
7695 * @expose
7696 */
7697 FieldPrototype.calculate = function(value, message) {
7698 value = this.verifyValue(value); // May throw
7699 if (this.type === null || typeof this.type !== 'object')
7700 throw Error("[INTERNAL] Unresolved type in "+this.toString(true)+": "+this.type);
7701 if (value === null || (this.repeated && value.length == 0))
7702 return 0; // Optional omitted
7703 var n = 0;
7704 try {
7705 if (this.repeated) {
7706 var i, ni;
7707 if (this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {
7708 n += ByteBuffer.calculateVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
7709 ni = 0;
7710 for (i=0; i<value.length; i++)
7711 ni += this.element.calculateLength(this.id, value[i]);
7712 n += ByteBuffer.calculateVarint32(ni);
7713 n += ni;
7714 } else {
7715 for (i=0; i<value.length; i++)
7716 n += ByteBuffer.calculateVarint32((this.id << 3) | this.type.wireType),
7717 n += this.element.calculateLength(this.id, value[i]);
7718 }
7719 } else if (this.map) {
7720 // Each map entry becomes a submessage.
7721 value.forEach(function(val, key, m) {
7722 // Compute the length of the submessage (key, val) pair.
7723 var length =
7724 ByteBuffer.calculateVarint32((1 << 3) | this.keyType.wireType) +
7725 this.keyElement.calculateLength(1, key) +
7726 ByteBuffer.calculateVarint32((2 << 3) | this.type.wireType) +
7727 this.element.calculateLength(2, val);
7728
7729 n += ByteBuffer.calculateVarint32((this.id << 3) | ProtoBuf.WIRE_TYPES.LDELIM);
7730 n += ByteBuffer.calculateVarint32(length);
7731 n += length;
7732 }, this);
7733 } else {
7734 if (this.hasWirePresence(value, message)) {
7735 n += ByteBuffer.calculateVarint32((this.id << 3) | this.type.wireType);
7736 n += this.element.calculateLength(this.id, value);
7737 }
7738 }
7739 } catch (e) {
7740 throw Error("Illegal value for "+this.toString(true)+": "+value+" ("+e+")");
7741 }
7742 return n;
7743 };
7744
7745 /**
7746 * Decode the field value from the specified buffer.
7747 * @param {number} wireType Leading wire type
7748 * @param {ByteBuffer} buffer ByteBuffer to decode from
7749 * @param {boolean=} skipRepeated Whether to skip the repeated check or not. Defaults to false.
7750 * @return {*} Decoded value: array for packed repeated fields, [key, value] for
7751 * map fields, or an individual value otherwise.
7752 * @throws {Error} If the field cannot be decoded
7753 * @expose
7754 */
7755 FieldPrototype.decode = function(wireType, buffer, skipRepeated) {
7756 var value, nBytes;
7757
7758 // We expect wireType to match the underlying type's wireType unless we see
7759 // a packed repeated field, or unless this is a map field.
7760 var wireTypeOK =
7761 (!this.map && wireType == this.type.wireType) ||
7762 (!skipRepeated && this.repeated && this.options["packed"] &&
7763 wireType == ProtoBuf.WIRE_TYPES.LDELIM) ||
7764 (this.map && wireType == ProtoBuf.WIRE_TYPES.LDELIM);
7765 if (!wireTypeOK)
7766 throw Error("Illegal wire type for field "+this.toString(true)+": "+wireType+" ("+this.type.wireType+" expected)");
7767
7768 // Handle packed repeated fields.
7769 if (wireType == ProtoBuf.WIRE_TYPES.LDELIM && this.repeated && this.options["packed"] && ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType) >= 0) {
7770 if (!skipRepeated) {
7771 nBytes = buffer.readVarint32();
7772 nBytes = buffer.offset + nBytes; // Limit
7773 var values = [];
7774 while (buffer.offset < nBytes)
7775 values.push(this.decode(this.type.wireType, buffer, true));
7776 return values;
7777 }
7778 // Read the next value otherwise...
7779 }
7780
7781 // Handle maps.
7782 if (this.map) {
7783 // Read one (key, value) submessage, and return [key, value]
7784 var key = Element.defaultFieldValue(this.keyType);
7785 value = Element.defaultFieldValue(this.type);
7786
7787 // Read the length
7788 nBytes = buffer.readVarint32();
7789 if (buffer.remaining() < nBytes)
7790 throw Error("Illegal number of bytes for "+this.toString(true)+": "+nBytes+" required but got only "+buffer.remaining());
7791
7792 // Get a sub-buffer of this key/value submessage
7793 var msgbuf = buffer.clone();
7794 msgbuf.limit = msgbuf.offset + nBytes;
7795 buffer.offset += nBytes;
7796
7797 while (msgbuf.remaining() > 0) {
7798 var tag = msgbuf.readVarint32();
7799 wireType = tag & 0x07;
7800 var id = tag >>> 3;
7801 if (id === 1) {
7802 key = this.keyElement.decode(msgbuf, wireType, id);
7803 } else if (id === 2) {
7804 value = this.element.decode(msgbuf, wireType, id);
7805 } else {
7806 throw Error("Unexpected tag in map field key/value submessage");
7807 }
7808 }
7809
7810 return [key, value];
7811 }
7812
7813 // Handle singular and non-packed repeated field values.
7814 return this.element.decode(buffer, wireType, this.id);
7815 };
7816
7817 /**
7818 * @alias ProtoBuf.Reflect.Message.Field
7819 * @expose
7820 */
7821 Reflect.Message.Field = Field;
7822
7823 /**
7824 * Constructs a new Message ExtensionField.
7825 * @exports ProtoBuf.Reflect.Message.ExtensionField
7826 * @param {!ProtoBuf.Builder} builder Builder reference
7827 * @param {!ProtoBuf.Reflect.Message} message Message reference
7828 * @param {string} rule Rule, one of requried, optional, repeated
7829 * @param {string} type Data type, e.g. int32
7830 * @param {string} name Field name
7831 * @param {number} id Unique field id
7832 * @param {!Object.<string,*>=} options Options
7833 * @constructor
7834 * @extends ProtoBuf.Reflect.Message.Field
7835 */
7836 var ExtensionField = function(builder, message, rule, type, name, id, options) {
7837 Field.call(this, builder, message, rule, /* keytype = */ null, type, name, id, options);
7838
7839 /**
7840 * Extension reference.
7841 * @type {!ProtoBuf.Reflect.Extension}
7842 * @expose
7843 */
7844 this.extension;
7845 };
7846
7847 // Extends Field
7848 ExtensionField.prototype = Object.create(Field.prototype);
7849
7850 /**
7851 * @alias ProtoBuf.Reflect.Message.ExtensionField
7852 * @expose
7853 */
7854 Reflect.Message.ExtensionField = ExtensionField;
7855
7856 /**
7857 * Constructs a new Message OneOf.
7858 * @exports ProtoBuf.Reflect.Message.OneOf
7859 * @param {!ProtoBuf.Builder} builder Builder reference
7860 * @param {!ProtoBuf.Reflect.Message} message Message reference
7861 * @param {string} name OneOf name
7862 * @constructor
7863 * @extends ProtoBuf.Reflect.T
7864 */
7865 var OneOf = function(builder, message, name) {
7866 T.call(this, builder, message, name);
7867
7868 /**
7869 * Enclosed fields.
7870 * @type {!Array.<!ProtoBuf.Reflect.Message.Field>}
7871 * @expose
7872 */
7873 this.fields = [];
7874 };
7875
7876 /**
7877 * @alias ProtoBuf.Reflect.Message.OneOf
7878 * @expose
7879 */
7880 Reflect.Message.OneOf = OneOf;
7881
7882 /**
7883 * Constructs a new Enum.
7884 * @exports ProtoBuf.Reflect.Enum
7885 * @param {!ProtoBuf.Builder} builder Builder reference
7886 * @param {!ProtoBuf.Reflect.T} parent Parent Reflect object
7887 * @param {string} name Enum name
7888 * @param {Object.<string,*>=} options Enum options
7889 * @param {string?} syntax The syntax level (e.g., proto3)
7890 * @constructor
7891 * @extends ProtoBuf.Reflect.Namespace
7892 */
7893 var Enum = function(builder, parent, name, options, syntax) {
7894 Namespace.call(this, builder, parent, name, options, syntax);
7895
7896 /**
7897 * @override
7898 */
7899 this.className = "Enum";
7900
7901 /**
7902 * Runtime enum object.
7903 * @type {Object.<string,number>|null}
7904 * @expose
7905 */
7906 this.object = null;
7907 };
7908
7909 /**
7910 * Gets the string name of an enum value.
7911 * @param {!ProtoBuf.Builder.Enum} enm Runtime enum
7912 * @param {number} value Enum value
7913 * @returns {?string} Name or `null` if not present
7914 * @expose
7915 */
7916 Enum.getName = function(enm, value) {
7917 var keys = Object.keys(enm);
7918 for (var i=0, key; i<keys.length; ++i)
7919 if (enm[key = keys[i]] === value)
7920 return key;
7921 return null;
7922 };
7923
7924 /**
7925 * @alias ProtoBuf.Reflect.Enum.prototype
7926 * @inner
7927 */
7928 var EnumPrototype = Enum.prototype = Object.create(Namespace.prototype);
7929
7930 /**
7931 * Builds this enum and returns the runtime counterpart.
7932 * @param {boolean} rebuild Whether to rebuild or not, defaults to false
7933 * @returns {!Object.<string,number>}
7934 * @expose
7935 */
7936 EnumPrototype.build = function(rebuild) {
7937 if (this.object && !rebuild)
7938 return this.object;
7939 var enm = new ProtoBuf.Builder.Enum(),
7940 values = this.getChildren(Enum.Value);
7941 for (var i=0, k=values.length; i<k; ++i)
7942 enm[values[i]['name']] = values[i]['id'];
7943 if (Object.defineProperty)
7944 Object.defineProperty(enm, '$options', {
7945 "value": this.buildOpt(),
7946 "enumerable": false
7947 });
7948 return this.object = enm;
7949 };
7950
7951 /**
7952 * @alias ProtoBuf.Reflect.Enum
7953 * @expose
7954 */
7955 Reflect.Enum = Enum;
7956
7957 /**
7958 * Constructs a new Enum Value.
7959 * @exports ProtoBuf.Reflect.Enum.Value
7960 * @param {!ProtoBuf.Builder} builder Builder reference
7961 * @param {!ProtoBuf.Reflect.Enum} enm Enum reference
7962 * @param {string} name Field name
7963 * @param {number} id Unique field id
7964 * @constructor
7965 * @extends ProtoBuf.Reflect.T
7966 */
7967 var Value = function(builder, enm, name, id) {
7968 T.call(this, builder, enm, name);
7969
7970 /**
7971 * @override
7972 */
7973 this.className = "Enum.Value";
7974
7975 /**
7976 * Unique enum value id.
7977 * @type {number}
7978 * @expose
7979 */
7980 this.id = id;
7981 };
7982
7983 // Extends T
7984 Value.prototype = Object.create(T.prototype);
7985
7986 /**
7987 * @alias ProtoBuf.Reflect.Enum.Value
7988 * @expose
7989 */
7990 Reflect.Enum.Value = Value;
7991
7992 /**
7993 * An extension (field).
7994 * @exports ProtoBuf.Reflect.Extension
7995 * @constructor
7996 * @param {!ProtoBuf.Builder} builder Builder reference
7997 * @param {!ProtoBuf.Reflect.T} parent Parent object
7998 * @param {string} name Object name
7999 * @param {!ProtoBuf.Reflect.Message.Field} field Extension field
8000 */
8001 var Extension = function(builder, parent, name, field) {
8002 T.call(this, builder, parent, name);
8003
8004 /**
8005 * Extended message field.
8006 * @type {!ProtoBuf.Reflect.Message.Field}
8007 * @expose
8008 */
8009 this.field = field;
8010 };
8011
8012 // Extends T
8013 Extension.prototype = Object.create(T.prototype);
8014
8015 /**
8016 * @alias ProtoBuf.Reflect.Extension
8017 * @expose
8018 */
8019 Reflect.Extension = Extension;
8020
8021 /**
8022 * Constructs a new Service.
8023 * @exports ProtoBuf.Reflect.Service
8024 * @param {!ProtoBuf.Builder} builder Builder reference
8025 * @param {!ProtoBuf.Reflect.Namespace} root Root
8026 * @param {string} name Service name
8027 * @param {Object.<string,*>=} options Options
8028 * @constructor
8029 * @extends ProtoBuf.Reflect.Namespace
8030 */
8031 var Service = function(builder, root, name, options) {
8032 Namespace.call(this, builder, root, name, options);
8033
8034 /**
8035 * @override
8036 */
8037 this.className = "Service";
8038
8039 /**
8040 * Built runtime service class.
8041 * @type {?function(new:ProtoBuf.Builder.Service)}
8042 */
8043 this.clazz = null;
8044 };
8045
8046 /**
8047 * @alias ProtoBuf.Reflect.Service.prototype
8048 * @inner
8049 */
8050 var ServicePrototype = Service.prototype = Object.create(Namespace.prototype);
8051
8052 /**
8053 * Builds the service and returns the runtime counterpart, which is a fully functional class.
8054 * @see ProtoBuf.Builder.Service
8055 * @param {boolean=} rebuild Whether to rebuild or not
8056 * @return {Function} Service class
8057 * @throws {Error} If the message cannot be built
8058 * @expose
8059 */
8060 ServicePrototype.build = function(rebuild) {
8061 if (this.clazz && !rebuild)
8062 return this.clazz;
8063
8064 // Create the runtime Service class in its own scope
8065 return this.clazz = (function(ProtoBuf, T) {
8066
8067 /**
8068 * Constructs a new runtime Service.
8069 * @name ProtoBuf.Builder.Service
8070 * @param {function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))=} rpcImpl RPC implementation receiving the method name and the message
8071 * @class Barebone of all runtime services.
8072 * @constructor
8073 * @throws {Error} If the service cannot be created
8074 */
8075 var Service = function(rpcImpl) {
8076 ProtoBuf.Builder.Service.call(this);
8077
8078 /**
8079 * Service implementation.
8080 * @name ProtoBuf.Builder.Service#rpcImpl
8081 * @type {!function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))}
8082 * @expose
8083 */
8084 this.rpcImpl = rpcImpl || function(name, msg, callback) {
8085 // This is what a user has to implement: A function receiving the method name, the actual message to
8086 // send (type checked) and the callback that's either provided with the error as its first
8087 // argument or null and the actual response message.
8088 setTimeout(callback.bind(this, Error("Not implemented, see: https://github.com/dcodeIO/ProtoBuf.js/wiki/Services")), 0); // Must be async!
8089 };
8090 };
8091
8092 /**
8093 * @alias ProtoBuf.Builder.Service.prototype
8094 * @inner
8095 */
8096 var ServicePrototype = Service.prototype = Object.create(ProtoBuf.Builder.Service.prototype);
8097
8098 /**
8099 * Asynchronously performs an RPC call using the given RPC implementation.
8100 * @name ProtoBuf.Builder.Service.[Method]
8101 * @function
8102 * @param {!function(string, ProtoBuf.Builder.Message, function(Error, ProtoBuf.Builder.Message=))} rpcImpl RPC implementation
8103 * @param {ProtoBuf.Builder.Message} req Request
8104 * @param {function(Error, (ProtoBuf.Builder.Message|ByteBuffer|Buffer|string)=)} callback Callback receiving
8105 * the error if any and the response either as a pre-parsed message or as its raw bytes
8106 * @abstract
8107 */
8108
8109 /**
8110 * Asynchronously performs an RPC call using the instance's RPC implementation.
8111 * @name ProtoBuf.Builder.Service#[Method]
8112 * @function
8113 * @param {ProtoBuf.Builder.Message} req Request
8114 * @param {function(Error, (ProtoBuf.Builder.Message|ByteBuffer|Buffer|string)=)} callback Callback receiving
8115 * the error if any and the response either as a pre-parsed message or as its raw bytes
8116 * @abstract
8117 */
8118
8119 var rpc = T.getChildren(ProtoBuf.Reflect.Service.RPCMethod);
8120 for (var i=0; i<rpc.length; i++) {
8121 (function(method) {
8122
8123 // service#Method(message, callback)
8124 ServicePrototype[method.name] = function(req, callback) {
8125 try {
8126 try {
8127 // If given as a buffer, decode the request. Will throw a TypeError if not a valid buffer.
8128 req = method.resolvedRequestType.clazz.decode(ByteBuffer.wrap(req));
8129 } catch (err) {
8130 if (!(err instanceof TypeError))
8131 throw err;
8132 }
8133 if (req === null || typeof req !== 'object')
8134 throw Error("Illegal arguments");
8135 if (!(req instanceof method.resolvedRequestType.clazz))
8136 req = new method.resolvedRequestType.clazz(req);
8137 this.rpcImpl(method.fqn(), req, function(err, res) { // Assumes that this is properly async
8138 if (err) {
8139 callback(err);
8140 return;
8141 }
8142 // Coalesce to empty string when service response has empty content
8143 if (res === null)
8144 res = '';
8145 try { res = method.resolvedResponseType.clazz.decode(res); } catch (notABuffer) {}
8146 if (!res || !(res instanceof method.resolvedResponseType.clazz)) {
8147 callback(Error("Illegal response type received in service method "+ T.name+"#"+method.name));
8148 return;
8149 }
8150 callback(null, res);
8151 });
8152 } catch (err) {
8153 setTimeout(callback.bind(this, err), 0);
8154 }
8155 };
8156
8157 // Service.Method(rpcImpl, message, callback)
8158 Service[method.name] = function(rpcImpl, req, callback) {
8159 new Service(rpcImpl)[method.name](req, callback);
8160 };
8161
8162 if (Object.defineProperty)
8163 Object.defineProperty(Service[method.name], "$options", { "value": method.buildOpt() }),
8164 Object.defineProperty(ServicePrototype[method.name], "$options", { "value": Service[method.name]["$options"] });
8165 })(rpc[i]);
8166 }
8167
8168 if (Object.defineProperty)
8169 Object.defineProperty(Service, "$options", { "value": T.buildOpt() }),
8170 Object.defineProperty(ServicePrototype, "$options", { "value": Service["$options"] }),
8171 Object.defineProperty(Service, "$type", { "value": T }),
8172 Object.defineProperty(ServicePrototype, "$type", { "value": T });
8173
8174 return Service;
8175
8176 })(ProtoBuf, this);
8177 };
8178
8179 /**
8180 * @alias ProtoBuf.Reflect.Service
8181 * @expose
8182 */
8183 Reflect.Service = Service;
8184
8185 /**
8186 * Abstract service method.
8187 * @exports ProtoBuf.Reflect.Service.Method
8188 * @param {!ProtoBuf.Builder} builder Builder reference
8189 * @param {!ProtoBuf.Reflect.Service} svc Service
8190 * @param {string} name Method name
8191 * @param {Object.<string,*>=} options Options
8192 * @constructor
8193 * @extends ProtoBuf.Reflect.T
8194 */
8195 var Method = function(builder, svc, name, options) {
8196 T.call(this, builder, svc, name);
8197
8198 /**
8199 * @override
8200 */
8201 this.className = "Service.Method";
8202
8203 /**
8204 * Options.
8205 * @type {Object.<string, *>}
8206 * @expose
8207 */
8208 this.options = options || {};
8209 };
8210
8211 /**
8212 * @alias ProtoBuf.Reflect.Service.Method.prototype
8213 * @inner
8214 */
8215 var MethodPrototype = Method.prototype = Object.create(T.prototype);
8216
8217 /**
8218 * Builds the method's '$options' property.
8219 * @name ProtoBuf.Reflect.Service.Method#buildOpt
8220 * @function
8221 * @return {Object.<string,*>}
8222 */
8223 MethodPrototype.buildOpt = NamespacePrototype.buildOpt;
8224
8225 /**
8226 * @alias ProtoBuf.Reflect.Service.Method
8227 * @expose
8228 */
8229 Reflect.Service.Method = Method;
8230
8231 /**
8232 * RPC service method.
8233 * @exports ProtoBuf.Reflect.Service.RPCMethod
8234 * @param {!ProtoBuf.Builder} builder Builder reference
8235 * @param {!ProtoBuf.Reflect.Service} svc Service
8236 * @param {string} name Method name
8237 * @param {string} request Request message name
8238 * @param {string} response Response message name
8239 * @param {boolean} request_stream Whether requests are streamed
8240 * @param {boolean} response_stream Whether responses are streamed
8241 * @param {Object.<string,*>=} options Options
8242 * @constructor
8243 * @extends ProtoBuf.Reflect.Service.Method
8244 */
8245 var RPCMethod = function(builder, svc, name, request, response, request_stream, response_stream, options) {
8246 Method.call(this, builder, svc, name, options);
8247
8248 /**
8249 * @override
8250 */
8251 this.className = "Service.RPCMethod";
8252
8253 /**
8254 * Request message name.
8255 * @type {string}
8256 * @expose
8257 */
8258 this.requestName = request;
8259
8260 /**
8261 * Response message name.
8262 * @type {string}
8263 * @expose
8264 */
8265 this.responseName = response;
8266
8267 /**
8268 * Whether requests are streamed
8269 * @type {bool}
8270 * @expose
8271 */
8272 this.requestStream = request_stream;
8273
8274 /**
8275 * Whether responses are streamed
8276 * @type {bool}
8277 * @expose
8278 */
8279 this.responseStream = response_stream;
8280
8281 /**
8282 * Resolved request message type.
8283 * @type {ProtoBuf.Reflect.Message}
8284 * @expose
8285 */
8286 this.resolvedRequestType = null;
8287
8288 /**
8289 * Resolved response message type.
8290 * @type {ProtoBuf.Reflect.Message}
8291 * @expose
8292 */
8293 this.resolvedResponseType = null;
8294 };
8295
8296 // Extends Method
8297 RPCMethod.prototype = Object.create(Method.prototype);
8298
8299 /**
8300 * @alias ProtoBuf.Reflect.Service.RPCMethod
8301 * @expose
8302 */
8303 Reflect.Service.RPCMethod = RPCMethod;
8304
8305 return Reflect;
8306
8307 })(ProtoBuf);
8308
8309 /**
8310 * @alias ProtoBuf.Builder
8311 * @expose
8312 */
8313 ProtoBuf.Builder = (function(ProtoBuf, Lang, Reflect) {
8314
8315 /**
8316 * Constructs a new Builder.
8317 * @exports ProtoBuf.Builder
8318 * @class Provides the functionality to build protocol messages.
8319 * @param {Object.<string,*>=} options Options
8320 * @constructor
8321 */
8322 var Builder = function(options) {
8323
8324 /**
8325 * Namespace.
8326 * @type {ProtoBuf.Reflect.Namespace}
8327 * @expose
8328 */
8329 this.ns = new Reflect.Namespace(this, null, ""); // Global namespace
8330
8331 /**
8332 * Namespace pointer.
8333 * @type {ProtoBuf.Reflect.T}
8334 * @expose
8335 */
8336 this.ptr = this.ns;
8337
8338 /**
8339 * Resolved flag.
8340 * @type {boolean}
8341 * @expose
8342 */
8343 this.resolved = false;
8344
8345 /**
8346 * The current building result.
8347 * @type {Object.<string,ProtoBuf.Builder.Message|Object>|null}
8348 * @expose
8349 */
8350 this.result = null;
8351
8352 /**
8353 * Imported files.
8354 * @type {Array.<string>}
8355 * @expose
8356 */
8357 this.files = {};
8358
8359 /**
8360 * Import root override.
8361 * @type {?string}
8362 * @expose
8363 */
8364 this.importRoot = null;
8365
8366 /**
8367 * Options.
8368 * @type {!Object.<string, *>}
8369 * @expose
8370 */
8371 this.options = options || {};
8372 };
8373
8374 /**
8375 * @alias ProtoBuf.Builder.prototype
8376 * @inner
8377 */
8378 var BuilderPrototype = Builder.prototype;
8379
8380 // ----- Definition tests -----
8381
8382 /**
8383 * Tests if a definition most likely describes a message.
8384 * @param {!Object} def
8385 * @returns {boolean}
8386 * @expose
8387 */
8388 Builder.isMessage = function(def) {
8389 // Messages require a string name
8390 if (typeof def["name"] !== 'string')
8391 return false;
8392 // Messages do not contain values (enum) or rpc methods (service)
8393 if (typeof def["values"] !== 'undefined' || typeof def["rpc"] !== 'undefined')
8394 return false;
8395 return true;
8396 };
8397
8398 /**
8399 * Tests if a definition most likely describes a message field.
8400 * @param {!Object} def
8401 * @returns {boolean}
8402 * @expose
8403 */
8404 Builder.isMessageField = function(def) {
8405 // Message fields require a string rule, name and type and an id
8406 if (typeof def["rule"] !== 'string' || typeof def["name"] !== 'string' || typeof def["type"] !== 'string' || typeof def["id"] === 'undefined')
8407 return false;
8408 return true;
8409 };
8410
8411 /**
8412 * Tests if a definition most likely describes an enum.
8413 * @param {!Object} def
8414 * @returns {boolean}
8415 * @expose
8416 */
8417 Builder.isEnum = function(def) {
8418 // Enums require a string name
8419 if (typeof def["name"] !== 'string')
8420 return false;
8421 // Enums require at least one value
8422 if (typeof def["values"] === 'undefined' || !Array.isArray(def["values"]) || def["values"].length === 0)
8423 return false;
8424 return true;
8425 };
8426
8427 /**
8428 * Tests if a definition most likely describes a service.
8429 * @param {!Object} def
8430 * @returns {boolean}
8431 * @expose
8432 */
8433 Builder.isService = function(def) {
8434 // Services require a string name and an rpc object
8435 if (typeof def["name"] !== 'string' || typeof def["rpc"] !== 'object' || !def["rpc"])
8436 return false;
8437 return true;
8438 };
8439
8440 /**
8441 * Tests if a definition most likely describes an extended message
8442 * @param {!Object} def
8443 * @returns {boolean}
8444 * @expose
8445 */
8446 Builder.isExtend = function(def) {
8447 // Extends rquire a string ref
8448 if (typeof def["ref"] !== 'string')
8449 return false;
8450 return true;
8451 };
8452
8453 // ----- Building -----
8454
8455 /**
8456 * Resets the pointer to the root namespace.
8457 * @returns {!ProtoBuf.Builder} this
8458 * @expose
8459 */
8460 BuilderPrototype.reset = function() {
8461 this.ptr = this.ns;
8462 return this;
8463 };
8464
8465 /**
8466 * Defines a namespace on top of the current pointer position and places the pointer on it.
8467 * @param {string} namespace
8468 * @return {!ProtoBuf.Builder} this
8469 * @expose
8470 */
8471 BuilderPrototype.define = function(namespace) {
8472 if (typeof namespace !== 'string' || !Lang.TYPEREF.test(namespace))
8473 throw Error("illegal namespace: "+namespace);
8474 namespace.split(".").forEach(function(part) {
8475 var ns = this.ptr.getChild(part);
8476 if (ns === null) // Keep existing
8477 this.ptr.addChild(ns = new Reflect.Namespace(this, this.ptr, part));
8478 this.ptr = ns;
8479 }, this);
8480 return this;
8481 };
8482
8483 /**
8484 * Creates the specified definitions at the current pointer position.
8485 * @param {!Array.<!Object>} defs Messages, enums or services to create
8486 * @returns {!ProtoBuf.Builder} this
8487 * @throws {Error} If a message definition is invalid
8488 * @expose
8489 */
8490 BuilderPrototype.create = function(defs) {
8491 if (!defs)
8492 return this; // Nothing to create
8493 if (!Array.isArray(defs))
8494 defs = [defs];
8495 else {
8496 if (defs.length === 0)
8497 return this;
8498 defs = defs.slice();
8499 }
8500
8501 // It's quite hard to keep track of scopes and memory here, so let's do this iteratively.
8502 var stack = [defs];
8503 while (stack.length > 0) {
8504 defs = stack.pop();
8505
8506 if (!Array.isArray(defs)) // Stack always contains entire namespaces
8507 throw Error("not a valid namespace: "+JSON.stringify(defs));
8508
8509 while (defs.length > 0) {
8510 var def = defs.shift(); // Namespaces always contain an array of messages, enums and services
8511
8512 if (Builder.isMessage(def)) {
8513 var obj = new Reflect.Message(this, this.ptr, def["name"], def["options"], def["isGroup"], def["syntax"]);
8514
8515 // Create OneOfs
8516 var oneofs = {};
8517 if (def["oneofs"])
8518 Object.keys(def["oneofs"]).forEach(function(name) {
8519 obj.addChild(oneofs[name] = new Reflect.Message.OneOf(this, obj, name));
8520 }, this);
8521
8522 // Create fields
8523 if (def["fields"])
8524 def["fields"].forEach(function(fld) {
8525 if (obj.getChild(fld["id"]|0) !== null)
8526 throw Error("duplicate or invalid field id in "+obj.name+": "+fld['id']);
8527 if (fld["options"] && typeof fld["options"] !== 'object')
8528 throw Error("illegal field options in "+obj.name+"#"+fld["name"]);
8529 var oneof = null;
8530 if (typeof fld["oneof"] === 'string' && !(oneof = oneofs[fld["oneof"]]))
8531 throw Error("illegal oneof in "+obj.name+"#"+fld["name"]+": "+fld["oneof"]);
8532 fld = new Reflect.Message.Field(this, obj, fld["rule"], fld["keytype"], fld["type"], fld["name"], fld["id"], fld["options"], oneof, def["syntax"]);
8533 if (oneof)
8534 oneof.fields.push(fld);
8535 obj.addChild(fld);
8536 }, this);
8537
8538 // Push children to stack
8539 var subObj = [];
8540 if (def["enums"])
8541 def["enums"].forEach(function(enm) {
8542 subObj.push(enm);
8543 });
8544 if (def["messages"])
8545 def["messages"].forEach(function(msg) {
8546 subObj.push(msg);
8547 });
8548 if (def["services"])
8549 def["services"].forEach(function(svc) {
8550 subObj.push(svc);
8551 });
8552
8553 // Set extension ranges
8554 if (def["extensions"]) {
8555 if (typeof def["extensions"][0] === 'number') // pre 5.0.1
8556 obj.extensions = [ def["extensions"] ];
8557 else
8558 obj.extensions = def["extensions"];
8559 }
8560
8561 // Create on top of current namespace
8562 this.ptr.addChild(obj);
8563 if (subObj.length > 0) {
8564 stack.push(defs); // Push the current level back
8565 defs = subObj; // Continue processing sub level
8566 subObj = null;
8567 this.ptr = obj; // And move the pointer to this namespace
8568 obj = null;
8569 continue;
8570 }
8571 subObj = null;
8572
8573 } else if (Builder.isEnum(def)) {
8574
8575 obj = new Reflect.Enum(this, this.ptr, def["name"], def["options"], def["syntax"]);
8576 def["values"].forEach(function(val) {
8577 obj.addChild(new Reflect.Enum.Value(this, obj, val["name"], val["id"]));
8578 }, this);
8579 this.ptr.addChild(obj);
8580
8581 } else if (Builder.isService(def)) {
8582
8583 obj = new Reflect.Service(this, this.ptr, def["name"], def["options"]);
8584 Object.keys(def["rpc"]).forEach(function(name) {
8585 var mtd = def["rpc"][name];
8586 obj.addChild(new Reflect.Service.RPCMethod(this, obj, name, mtd["request"], mtd["response"], !!mtd["request_stream"], !!mtd["response_stream"], mtd["options"]));
8587 }, this);
8588 this.ptr.addChild(obj);
8589
8590 } else if (Builder.isExtend(def)) {
8591
8592 obj = this.ptr.resolve(def["ref"], true);
8593 if (obj) {
8594 def["fields"].forEach(function(fld) {
8595 if (obj.getChild(fld['id']|0) !== null)
8596 throw Error("duplicate extended field id in "+obj.name+": "+fld['id']);
8597 // Check if field id is allowed to be extended
8598 if (obj.extensions) {
8599 var valid = false;
8600 obj.extensions.forEach(function(range) {
8601 if (fld["id"] >= range[0] && fld["id"] <= range[1])
8602 valid = true;
8603 });
8604 if (!valid)
8605 throw Error("illegal extended field id in "+obj.name+": "+fld['id']+" (not within valid ranges)");
8606 }
8607 // Convert extension field names to camel case notation if the override is set
8608 var name = fld["name"];
8609 if (this.options['convertFieldsToCamelCase'])
8610 name = ProtoBuf.Util.toCamelCase(name);
8611 // see #161: Extensions use their fully qualified name as their runtime key and...
8612 var field = new Reflect.Message.ExtensionField(this, obj, fld["rule"], fld["type"], this.ptr.fqn()+'.'+name, fld["id"], fld["options"]);
8613 // ...are added on top of the current namespace as an extension which is used for
8614 // resolving their type later on (the extension always keeps the original name to
8615 // prevent naming collisions)
8616 var ext = new Reflect.Extension(this, this.ptr, fld["name"], field);
8617 field.extension = ext;
8618 this.ptr.addChild(ext);
8619 obj.addChild(field);
8620 }, this);
8621
8622 } else if (!/\.?google\.protobuf\./.test(def["ref"])) // Silently skip internal extensions
8623 throw Error("extended message "+def["ref"]+" is not defined");
8624
8625 } else
8626 throw Error("not a valid definition: "+JSON.stringify(def));
8627
8628 def = null;
8629 obj = null;
8630 }
8631 // Break goes here
8632 defs = null;
8633 this.ptr = this.ptr.parent; // Namespace done, continue at parent
8634 }
8635 this.resolved = false; // Require re-resolve
8636 this.result = null; // Require re-build
8637 return this;
8638 };
8639
8640 /**
8641 * Propagates syntax to all children.
8642 * @param {!Object} parent
8643 * @inner
8644 */
8645 function propagateSyntax(parent) {
8646 if (parent['messages']) {
8647 parent['messages'].forEach(function(child) {
8648 child["syntax"] = parent["syntax"];
8649 propagateSyntax(child);
8650 });
8651 }
8652 if (parent['enums']) {
8653 parent['enums'].forEach(function(child) {
8654 child["syntax"] = parent["syntax"];
8655 });
8656 }
8657 }
8658
8659 /**
8660 * Imports another definition into this builder.
8661 * @param {Object.<string,*>} json Parsed import
8662 * @param {(string|{root: string, file: string})=} filename Imported file name
8663 * @returns {!ProtoBuf.Builder} this
8664 * @throws {Error} If the definition or file cannot be imported
8665 * @expose
8666 */
8667 BuilderPrototype["import"] = function(json, filename) {
8668 var delim = '/';
8669
8670 // Make sure to skip duplicate imports
8671
8672 if (typeof filename === 'string') {
8673
8674 if (ProtoBuf.Util.IS_NODE)
8675 filename = require$$2['resolve'](filename);
8676 if (this.files[filename] === true)
8677 return this.reset();
8678 this.files[filename] = true;
8679
8680 } else if (typeof filename === 'object') { // Object with root, file.
8681
8682 var root = filename.root;
8683 if (ProtoBuf.Util.IS_NODE)
8684 root = require$$2['resolve'](root);
8685 if (root.indexOf("\\") >= 0 || filename.file.indexOf("\\") >= 0)
8686 delim = '\\';
8687 var fname;
8688 if (ProtoBuf.Util.IS_NODE)
8689 fname = require$$2['join'](root, filename.file);
8690 else
8691 fname = root + delim + filename.file;
8692 if (this.files[fname] === true)
8693 return this.reset();
8694 this.files[fname] = true;
8695 }
8696
8697 // Import imports
8698
8699 if (json['imports'] && json['imports'].length > 0) {
8700 var importRoot,
8701 resetRoot = false;
8702
8703 if (typeof filename === 'object') { // If an import root is specified, override
8704
8705 this.importRoot = filename["root"]; resetRoot = true; // ... and reset afterwards
8706 importRoot = this.importRoot;
8707 filename = filename["file"];
8708 if (importRoot.indexOf("\\") >= 0 || filename.indexOf("\\") >= 0)
8709 delim = '\\';
8710
8711 } else if (typeof filename === 'string') {
8712
8713 if (this.importRoot) // If import root is overridden, use it
8714 importRoot = this.importRoot;
8715 else { // Otherwise compute from filename
8716 if (filename.indexOf("/") >= 0) { // Unix
8717 importRoot = filename.replace(/\/[^\/]*$/, "");
8718 if (/* /file.proto */ importRoot === "")
8719 importRoot = "/";
8720 } else if (filename.indexOf("\\") >= 0) { // Windows
8721 importRoot = filename.replace(/\\[^\\]*$/, "");
8722 delim = '\\';
8723 } else
8724 importRoot = ".";
8725 }
8726
8727 } else
8728 importRoot = null;
8729
8730 for (var i=0; i<json['imports'].length; i++) {
8731 if (typeof json['imports'][i] === 'string') { // Import file
8732 if (!importRoot)
8733 throw Error("cannot determine import root");
8734 var importFilename = json['imports'][i];
8735 if (importFilename === "google/protobuf/descriptor.proto")
8736 continue; // Not needed and therefore not used
8737 if (ProtoBuf.Util.IS_NODE)
8738 importFilename = require$$2['join'](importRoot, importFilename);
8739 else
8740 importFilename = importRoot + delim + importFilename;
8741 if (this.files[importFilename] === true)
8742 continue; // Already imported
8743 if (/\.proto$/i.test(importFilename) && !ProtoBuf.DotProto) // If this is a light build
8744 importFilename = importFilename.replace(/\.proto$/, ".json"); // always load the JSON file
8745 var contents = ProtoBuf.Util.fetch(importFilename);
8746 if (contents === null)
8747 throw Error("failed to import '"+importFilename+"' in '"+filename+"': file not found");
8748 if (/\.json$/i.test(importFilename)) // Always possible
8749 this["import"](JSON.parse(contents+""), importFilename); // May throw
8750 else
8751 this["import"](ProtoBuf.DotProto.Parser.parse(contents), importFilename); // May throw
8752 } else // Import structure
8753 if (!filename)
8754 this["import"](json['imports'][i]);
8755 else if (/\.(\w+)$/.test(filename)) // With extension: Append _importN to the name portion to make it unique
8756 this["import"](json['imports'][i], filename.replace(/^(.+)\.(\w+)$/, function($0, $1, $2) { return $1+"_import"+i+"."+$2; }));
8757 else // Without extension: Append _importN to make it unique
8758 this["import"](json['imports'][i], filename+"_import"+i);
8759 }
8760 if (resetRoot) // Reset import root override when all imports are done
8761 this.importRoot = null;
8762 }
8763
8764 // Import structures
8765
8766 if (json['package'])
8767 this.define(json['package']);
8768 if (json['syntax'])
8769 propagateSyntax(json);
8770 var base = this.ptr;
8771 if (json['options'])
8772 Object.keys(json['options']).forEach(function(key) {
8773 base.options[key] = json['options'][key];
8774 });
8775 if (json['messages'])
8776 this.create(json['messages']),
8777 this.ptr = base;
8778 if (json['enums'])
8779 this.create(json['enums']),
8780 this.ptr = base;
8781 if (json['services'])
8782 this.create(json['services']),
8783 this.ptr = base;
8784 if (json['extends'])
8785 this.create(json['extends']);
8786
8787 return this.reset();
8788 };
8789
8790 /**
8791 * Resolves all namespace objects.
8792 * @throws {Error} If a type cannot be resolved
8793 * @returns {!ProtoBuf.Builder} this
8794 * @expose
8795 */
8796 BuilderPrototype.resolveAll = function() {
8797 // Resolve all reflected objects
8798 var res;
8799 if (this.ptr == null || typeof this.ptr.type === 'object')
8800 return this; // Done (already resolved)
8801
8802 if (this.ptr instanceof Reflect.Namespace) { // Resolve children
8803
8804 this.ptr.children.forEach(function(child) {
8805 this.ptr = child;
8806 this.resolveAll();
8807 }, this);
8808
8809 } else if (this.ptr instanceof Reflect.Message.Field) { // Resolve type
8810
8811 if (!Lang.TYPE.test(this.ptr.type)) {
8812 if (!Lang.TYPEREF.test(this.ptr.type))
8813 throw Error("illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.type);
8814 res = (this.ptr instanceof Reflect.Message.ExtensionField ? this.ptr.extension.parent : this.ptr.parent).resolve(this.ptr.type, true);
8815 if (!res)
8816 throw Error("unresolvable type reference in "+this.ptr.toString(true)+": "+this.ptr.type);
8817 this.ptr.resolvedType = res;
8818 if (res instanceof Reflect.Enum) {
8819 this.ptr.type = ProtoBuf.TYPES["enum"];
8820 if (this.ptr.syntax === 'proto3' && res.syntax !== 'proto3')
8821 throw Error("proto3 message cannot reference proto2 enum");
8822 }
8823 else if (res instanceof Reflect.Message)
8824 this.ptr.type = res.isGroup ? ProtoBuf.TYPES["group"] : ProtoBuf.TYPES["message"];
8825 else
8826 throw Error("illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.type);
8827 } else
8828 this.ptr.type = ProtoBuf.TYPES[this.ptr.type];
8829
8830 // If it's a map field, also resolve the key type. The key type can be only a numeric, string, or bool type
8831 // (i.e., no enums or messages), so we don't need to resolve against the current namespace.
8832 if (this.ptr.map) {
8833 if (!Lang.TYPE.test(this.ptr.keyType))
8834 throw Error("illegal key type for map field in "+this.ptr.toString(true)+": "+this.ptr.keyType);
8835 this.ptr.keyType = ProtoBuf.TYPES[this.ptr.keyType];
8836 }
8837
8838 // If it's a repeated and packable field then proto3 mandates it should be packed by
8839 // default
8840 if (
8841 this.ptr.syntax === 'proto3' &&
8842 this.ptr.repeated && this.ptr.options.packed === undefined &&
8843 ProtoBuf.PACKABLE_WIRE_TYPES.indexOf(this.ptr.type.wireType) !== -1
8844 ) {
8845 this.ptr.options.packed = true;
8846 }
8847
8848 } else if (this.ptr instanceof ProtoBuf.Reflect.Service.Method) {
8849
8850 if (this.ptr instanceof ProtoBuf.Reflect.Service.RPCMethod) {
8851 res = this.ptr.parent.resolve(this.ptr.requestName, true);
8852 if (!res || !(res instanceof ProtoBuf.Reflect.Message))
8853 throw Error("Illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.requestName);
8854 this.ptr.resolvedRequestType = res;
8855 res = this.ptr.parent.resolve(this.ptr.responseName, true);
8856 if (!res || !(res instanceof ProtoBuf.Reflect.Message))
8857 throw Error("Illegal type reference in "+this.ptr.toString(true)+": "+this.ptr.responseName);
8858 this.ptr.resolvedResponseType = res;
8859 } else // Should not happen as nothing else is implemented
8860 throw Error("illegal service type in "+this.ptr.toString(true));
8861
8862 } else if (
8863 !(this.ptr instanceof ProtoBuf.Reflect.Message.OneOf) && // Not built
8864 !(this.ptr instanceof ProtoBuf.Reflect.Extension) && // Not built
8865 !(this.ptr instanceof ProtoBuf.Reflect.Enum.Value) // Built in enum
8866 )
8867 throw Error("illegal object in namespace: "+typeof(this.ptr)+": "+this.ptr);
8868
8869 return this.reset();
8870 };
8871
8872 /**
8873 * Builds the protocol. This will first try to resolve all definitions and, if this has been successful,
8874 * return the built package.
8875 * @param {(string|Array.<string>)=} path Specifies what to return. If omitted, the entire namespace will be returned.
8876 * @returns {!ProtoBuf.Builder.Message|!Object.<string,*>}
8877 * @throws {Error} If a type could not be resolved
8878 * @expose
8879 */
8880 BuilderPrototype.build = function(path) {
8881 this.reset();
8882 if (!this.resolved)
8883 this.resolveAll(),
8884 this.resolved = true,
8885 this.result = null; // Require re-build
8886 if (this.result === null) // (Re-)Build
8887 this.result = this.ns.build();
8888 if (!path)
8889 return this.result;
8890 var part = typeof path === 'string' ? path.split(".") : path,
8891 ptr = this.result; // Build namespace pointer (no hasChild etc.)
8892 for (var i=0; i<part.length; i++)
8893 if (ptr[part[i]])
8894 ptr = ptr[part[i]];
8895 else {
8896 ptr = null;
8897 break;
8898 }
8899 return ptr;
8900 };
8901
8902 /**
8903 * Similar to {@link ProtoBuf.Builder#build}, but looks up the internal reflection descriptor.
8904 * @param {string=} path Specifies what to return. If omitted, the entire namespace wiil be returned.
8905 * @param {boolean=} excludeNonNamespace Excludes non-namespace types like fields, defaults to `false`
8906 * @returns {?ProtoBuf.Reflect.T} Reflection descriptor or `null` if not found
8907 */
8908 BuilderPrototype.lookup = function(path, excludeNonNamespace) {
8909 return path ? this.ns.resolve(path, excludeNonNamespace) : this.ns;
8910 };
8911
8912 /**
8913 * Returns a string representation of this object.
8914 * @return {string} String representation as of "Builder"
8915 * @expose
8916 */
8917 BuilderPrototype.toString = function() {
8918 return "Builder";
8919 };
8920
8921 // ----- Base classes -----
8922 // Exist for the sole purpose of being able to "... instanceof ProtoBuf.Builder.Message" etc.
8923
8924 /**
8925 * @alias ProtoBuf.Builder.Message
8926 */
8927 Builder.Message = function() {};
8928
8929 /**
8930 * @alias ProtoBuf.Builder.Enum
8931 */
8932 Builder.Enum = function() {};
8933
8934 /**
8935 * @alias ProtoBuf.Builder.Message
8936 */
8937 Builder.Service = function() {};
8938
8939 return Builder;
8940
8941 })(ProtoBuf, ProtoBuf.Lang, ProtoBuf.Reflect);
8942
8943 /**
8944 * @alias ProtoBuf.Map
8945 * @expose
8946 */
8947 ProtoBuf.Map = (function(ProtoBuf, Reflect) {
8948
8949 /**
8950 * Constructs a new Map. A Map is a container that is used to implement map
8951 * fields on message objects. It closely follows the ES6 Map API; however,
8952 * it is distinct because we do not want to depend on external polyfills or
8953 * on ES6 itself.
8954 *
8955 * @exports ProtoBuf.Map
8956 * @param {!ProtoBuf.Reflect.Field} field Map field
8957 * @param {Object.<string,*>=} contents Initial contents
8958 * @constructor
8959 */
8960 var Map = function(field, contents) {
8961 if (!field.map)
8962 throw Error("field is not a map");
8963
8964 /**
8965 * The field corresponding to this map.
8966 * @type {!ProtoBuf.Reflect.Field}
8967 */
8968 this.field = field;
8969
8970 /**
8971 * Element instance corresponding to key type.
8972 * @type {!ProtoBuf.Reflect.Element}
8973 */
8974 this.keyElem = new Reflect.Element(field.keyType, null, true, field.syntax);
8975
8976 /**
8977 * Element instance corresponding to value type.
8978 * @type {!ProtoBuf.Reflect.Element}
8979 */
8980 this.valueElem = new Reflect.Element(field.type, field.resolvedType, false, field.syntax);
8981
8982 /**
8983 * Internal map: stores mapping of (string form of key) -> (key, value)
8984 * pair.
8985 *
8986 * We provide map semantics for arbitrary key types, but we build on top
8987 * of an Object, which has only string keys. In order to avoid the need
8988 * to convert a string key back to its native type in many situations,
8989 * we store the native key value alongside the value. Thus, we only need
8990 * a one-way mapping from a key type to its string form that guarantees
8991 * uniqueness and equality (i.e., str(K1) === str(K2) if and only if K1
8992 * === K2).
8993 *
8994 * @type {!Object<string, {key: *, value: *}>}
8995 */
8996 this.map = {};
8997
8998 /**
8999 * Returns the number of elements in the map.
9000 */
9001 Object.defineProperty(this, "size", {
9002 get: function() { return Object.keys(this.map).length; }
9003 });
9004
9005 // Fill initial contents from a raw object.
9006 if (contents) {
9007 var keys = Object.keys(contents);
9008 for (var i = 0; i < keys.length; i++) {
9009 var key = this.keyElem.valueFromString(keys[i]);
9010 var val = this.valueElem.verifyValue(contents[keys[i]]);
9011 this.map[this.keyElem.valueToString(key)] =
9012 { key: key, value: val };
9013 }
9014 }
9015 };
9016
9017 var MapPrototype = Map.prototype;
9018
9019 /**
9020 * Helper: return an iterator over an array.
9021 * @param {!Array<*>} arr the array
9022 * @returns {!Object} an iterator
9023 * @inner
9024 */
9025 function arrayIterator(arr) {
9026 var idx = 0;
9027 return {
9028 next: function() {
9029 if (idx < arr.length)
9030 return { done: false, value: arr[idx++] };
9031 return { done: true };
9032 }
9033 }
9034 }
9035
9036 /**
9037 * Clears the map.
9038 */
9039 MapPrototype.clear = function() {
9040 this.map = {};
9041 };
9042
9043 /**
9044 * Deletes a particular key from the map.
9045 * @returns {boolean} Whether any entry with this key was deleted.
9046 */
9047 MapPrototype["delete"] = function(key) {
9048 var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));
9049 var hadKey = keyValue in this.map;
9050 delete this.map[keyValue];
9051 return hadKey;
9052 };
9053
9054 /**
9055 * Returns an iterator over [key, value] pairs in the map.
9056 * @returns {Object} The iterator
9057 */
9058 MapPrototype.entries = function() {
9059 var entries = [];
9060 var strKeys = Object.keys(this.map);
9061 for (var i = 0, entry; i < strKeys.length; i++)
9062 entries.push([(entry=this.map[strKeys[i]]).key, entry.value]);
9063 return arrayIterator(entries);
9064 };
9065
9066 /**
9067 * Returns an iterator over keys in the map.
9068 * @returns {Object} The iterator
9069 */
9070 MapPrototype.keys = function() {
9071 var keys = [];
9072 var strKeys = Object.keys(this.map);
9073 for (var i = 0; i < strKeys.length; i++)
9074 keys.push(this.map[strKeys[i]].key);
9075 return arrayIterator(keys);
9076 };
9077
9078 /**
9079 * Returns an iterator over values in the map.
9080 * @returns {!Object} The iterator
9081 */
9082 MapPrototype.values = function() {
9083 var values = [];
9084 var strKeys = Object.keys(this.map);
9085 for (var i = 0; i < strKeys.length; i++)
9086 values.push(this.map[strKeys[i]].value);
9087 return arrayIterator(values);
9088 };
9089
9090 /**
9091 * Iterates over entries in the map, calling a function on each.
9092 * @param {function(this:*, *, *, *)} cb The callback to invoke with value, key, and map arguments.
9093 * @param {Object=} thisArg The `this` value for the callback
9094 */
9095 MapPrototype.forEach = function(cb, thisArg) {
9096 var strKeys = Object.keys(this.map);
9097 for (var i = 0, entry; i < strKeys.length; i++)
9098 cb.call(thisArg, (entry=this.map[strKeys[i]]).value, entry.key, this);
9099 };
9100
9101 /**
9102 * Sets a key in the map to the given value.
9103 * @param {*} key The key
9104 * @param {*} value The value
9105 * @returns {!ProtoBuf.Map} The map instance
9106 */
9107 MapPrototype.set = function(key, value) {
9108 var keyValue = this.keyElem.verifyValue(key);
9109 var valValue = this.valueElem.verifyValue(value);
9110 this.map[this.keyElem.valueToString(keyValue)] =
9111 { key: keyValue, value: valValue };
9112 return this;
9113 };
9114
9115 /**
9116 * Gets the value corresponding to a key in the map.
9117 * @param {*} key The key
9118 * @returns {*|undefined} The value, or `undefined` if key not present
9119 */
9120 MapPrototype.get = function(key) {
9121 var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));
9122 if (!(keyValue in this.map))
9123 return undefined;
9124 return this.map[keyValue].value;
9125 };
9126
9127 /**
9128 * Determines whether the given key is present in the map.
9129 * @param {*} key The key
9130 * @returns {boolean} `true` if the key is present
9131 */
9132 MapPrototype.has = function(key) {
9133 var keyValue = this.keyElem.valueToString(this.keyElem.verifyValue(key));
9134 return (keyValue in this.map);
9135 };
9136
9137 return Map;
9138 })(ProtoBuf, ProtoBuf.Reflect);
9139
9140
9141 /**
9142 * Constructs a new empty Builder.
9143 * @param {Object.<string,*>=} options Builder options, defaults to global options set on ProtoBuf
9144 * @return {!ProtoBuf.Builder} Builder
9145 * @expose
9146 */
9147 ProtoBuf.newBuilder = function(options) {
9148 options = options || {};
9149 if (typeof options['convertFieldsToCamelCase'] === 'undefined')
9150 options['convertFieldsToCamelCase'] = ProtoBuf.convertFieldsToCamelCase;
9151 if (typeof options['populateAccessors'] === 'undefined')
9152 options['populateAccessors'] = ProtoBuf.populateAccessors;
9153 return new ProtoBuf.Builder(options);
9154 };
9155
9156 /**
9157 * Loads a .json definition and returns the Builder.
9158 * @param {!*|string} json JSON definition
9159 * @param {(ProtoBuf.Builder|string|{root: string, file: string})=} builder Builder to append to. Will create a new one if omitted.
9160 * @param {(string|{root: string, file: string})=} filename The corresponding file name if known. Must be specified for imports.
9161 * @return {ProtoBuf.Builder} Builder to create new messages
9162 * @throws {Error} If the definition cannot be parsed or built
9163 * @expose
9164 */
9165 ProtoBuf.loadJson = function(json, builder, filename) {
9166 if (typeof builder === 'string' || (builder && typeof builder["file"] === 'string' && typeof builder["root"] === 'string'))
9167 filename = builder,
9168 builder = null;
9169 if (!builder || typeof builder !== 'object')
9170 builder = ProtoBuf.newBuilder();
9171 if (typeof json === 'string')
9172 json = JSON.parse(json);
9173 builder["import"](json, filename);
9174 builder.resolveAll();
9175 return builder;
9176 };
9177
9178 /**
9179 * Loads a .json file and returns the Builder.
9180 * @param {string|!{root: string, file: string}} filename Path to json file or an object specifying 'file' with
9181 * an overridden 'root' path for all imported files.
9182 * @param {function(?Error, !ProtoBuf.Builder=)=} callback Callback that will receive `null` as the first and
9183 * the Builder as its second argument on success, otherwise the error as its first argument. If omitted, the
9184 * file will be read synchronously and this function will return the Builder.
9185 * @param {ProtoBuf.Builder=} builder Builder to append to. Will create a new one if omitted.
9186 * @return {?ProtoBuf.Builder|undefined} The Builder if synchronous (no callback specified, will be NULL if the
9187 * request has failed), else undefined
9188 * @expose
9189 */
9190 ProtoBuf.loadJsonFile = function(filename, callback, builder) {
9191 if (callback && typeof callback === 'object')
9192 builder = callback,
9193 callback = null;
9194 else if (!callback || typeof callback !== 'function')
9195 callback = null;
9196 if (callback)
9197 return ProtoBuf.Util.fetch(typeof filename === 'string' ? filename : filename["root"]+"/"+filename["file"], function(contents) {
9198 if (contents === null) {
9199 callback(Error("Failed to fetch file"));
9200 return;
9201 }
9202 try {
9203 callback(null, ProtoBuf.loadJson(JSON.parse(contents), builder, filename));
9204 } catch (e) {
9205 callback(e);
9206 }
9207 });
9208 var contents = ProtoBuf.Util.fetch(typeof filename === 'object' ? filename["root"]+"/"+filename["file"] : filename);
9209 return contents === null ? null : ProtoBuf.loadJson(JSON.parse(contents), builder, filename);
9210 };
9211
9212 return ProtoBuf;
9213 });
9214 });
9215
9216 var messageCompiled = protobufLight.newBuilder({})['import']({
9217 "package": 'push_server.messages2',
9218 syntax: 'proto2',
9219 options: {
9220 objc_class_prefix: 'AVIM'
9221 },
9222 messages: [{
9223 name: 'JsonObjectMessage',
9224 syntax: 'proto2',
9225 fields: [{
9226 rule: 'required',
9227 type: 'string',
9228 name: 'data',
9229 id: 1
9230 }]
9231 }, {
9232 name: 'UnreadTuple',
9233 syntax: 'proto2',
9234 fields: [{
9235 rule: 'required',
9236 type: 'string',
9237 name: 'cid',
9238 id: 1
9239 }, {
9240 rule: 'required',
9241 type: 'int32',
9242 name: 'unread',
9243 id: 2
9244 }, {
9245 rule: 'optional',
9246 type: 'string',
9247 name: 'mid',
9248 id: 3
9249 }, {
9250 rule: 'optional',
9251 type: 'int64',
9252 name: 'timestamp',
9253 id: 4
9254 }, {
9255 rule: 'optional',
9256 type: 'string',
9257 name: 'from',
9258 id: 5
9259 }, {
9260 rule: 'optional',
9261 type: 'string',
9262 name: 'data',
9263 id: 6
9264 }, {
9265 rule: 'optional',
9266 type: 'int64',
9267 name: 'patchTimestamp',
9268 id: 7
9269 }, {
9270 rule: 'optional',
9271 type: 'bool',
9272 name: 'mentioned',
9273 id: 8
9274 }, {
9275 rule: 'optional',
9276 type: 'bytes',
9277 name: 'binaryMsg',
9278 id: 9
9279 }, {
9280 rule: 'optional',
9281 type: 'int32',
9282 name: 'convType',
9283 id: 10
9284 }]
9285 }, {
9286 name: 'LogItem',
9287 syntax: 'proto2',
9288 fields: [{
9289 rule: 'optional',
9290 type: 'string',
9291 name: 'from',
9292 id: 1
9293 }, {
9294 rule: 'optional',
9295 type: 'string',
9296 name: 'data',
9297 id: 2
9298 }, {
9299 rule: 'optional',
9300 type: 'int64',
9301 name: 'timestamp',
9302 id: 3
9303 }, {
9304 rule: 'optional',
9305 type: 'string',
9306 name: 'msgId',
9307 id: 4
9308 }, {
9309 rule: 'optional',
9310 type: 'int64',
9311 name: 'ackAt',
9312 id: 5
9313 }, {
9314 rule: 'optional',
9315 type: 'int64',
9316 name: 'readAt',
9317 id: 6
9318 }, {
9319 rule: 'optional',
9320 type: 'int64',
9321 name: 'patchTimestamp',
9322 id: 7
9323 }, {
9324 rule: 'optional',
9325 type: 'bool',
9326 name: 'mentionAll',
9327 id: 8
9328 }, {
9329 rule: 'repeated',
9330 type: 'string',
9331 name: 'mentionPids',
9332 id: 9
9333 }, {
9334 rule: 'optional',
9335 type: 'bool',
9336 name: 'bin',
9337 id: 10
9338 }, {
9339 rule: 'optional',
9340 type: 'int32',
9341 name: 'convType',
9342 id: 11
9343 }]
9344 }, {
9345 name: 'ConvMemberInfo',
9346 syntax: 'proto2',
9347 fields: [{
9348 rule: 'optional',
9349 type: 'string',
9350 name: 'pid',
9351 id: 1
9352 }, {
9353 rule: 'optional',
9354 type: 'string',
9355 name: 'role',
9356 id: 2
9357 }, {
9358 rule: 'optional',
9359 type: 'string',
9360 name: 'infoId',
9361 id: 3
9362 }]
9363 }, {
9364 name: 'DataCommand',
9365 syntax: 'proto2',
9366 fields: [{
9367 rule: 'repeated',
9368 type: 'string',
9369 name: 'ids',
9370 id: 1
9371 }, {
9372 rule: 'repeated',
9373 type: 'JsonObjectMessage',
9374 name: 'msg',
9375 id: 2
9376 }, {
9377 rule: 'optional',
9378 type: 'bool',
9379 name: 'offline',
9380 id: 3
9381 }]
9382 }, {
9383 name: 'SessionCommand',
9384 syntax: 'proto2',
9385 fields: [{
9386 rule: 'optional',
9387 type: 'int64',
9388 name: 't',
9389 id: 1
9390 }, {
9391 rule: 'optional',
9392 type: 'string',
9393 name: 'n',
9394 id: 2
9395 }, {
9396 rule: 'optional',
9397 type: 'string',
9398 name: 's',
9399 id: 3
9400 }, {
9401 rule: 'optional',
9402 type: 'string',
9403 name: 'ua',
9404 id: 4
9405 }, {
9406 rule: 'optional',
9407 type: 'bool',
9408 name: 'r',
9409 id: 5
9410 }, {
9411 rule: 'optional',
9412 type: 'string',
9413 name: 'tag',
9414 id: 6
9415 }, {
9416 rule: 'optional',
9417 type: 'string',
9418 name: 'deviceId',
9419 id: 7
9420 }, {
9421 rule: 'repeated',
9422 type: 'string',
9423 name: 'sessionPeerIds',
9424 id: 8
9425 }, {
9426 rule: 'repeated',
9427 type: 'string',
9428 name: 'onlineSessionPeerIds',
9429 id: 9
9430 }, {
9431 rule: 'optional',
9432 type: 'string',
9433 name: 'st',
9434 id: 10
9435 }, {
9436 rule: 'optional',
9437 type: 'int32',
9438 name: 'stTtl',
9439 id: 11
9440 }, {
9441 rule: 'optional',
9442 type: 'int32',
9443 name: 'code',
9444 id: 12
9445 }, {
9446 rule: 'optional',
9447 type: 'string',
9448 name: 'reason',
9449 id: 13
9450 }, {
9451 rule: 'optional',
9452 type: 'string',
9453 name: 'deviceToken',
9454 id: 14
9455 }, {
9456 rule: 'optional',
9457 type: 'bool',
9458 name: 'sp',
9459 id: 15
9460 }, {
9461 rule: 'optional',
9462 type: 'string',
9463 name: 'detail',
9464 id: 16
9465 }, {
9466 rule: 'optional',
9467 type: 'int64',
9468 name: 'lastUnreadNotifTime',
9469 id: 17
9470 }, {
9471 rule: 'optional',
9472 type: 'int64',
9473 name: 'lastPatchTime',
9474 id: 18
9475 }, {
9476 rule: 'optional',
9477 type: 'int64',
9478 name: 'configBitmap',
9479 id: 19
9480 }]
9481 }, {
9482 name: 'ErrorCommand',
9483 syntax: 'proto2',
9484 fields: [{
9485 rule: 'required',
9486 type: 'int32',
9487 name: 'code',
9488 id: 1
9489 }, {
9490 rule: 'required',
9491 type: 'string',
9492 name: 'reason',
9493 id: 2
9494 }, {
9495 rule: 'optional',
9496 type: 'int32',
9497 name: 'appCode',
9498 id: 3
9499 }, {
9500 rule: 'optional',
9501 type: 'string',
9502 name: 'detail',
9503 id: 4
9504 }, {
9505 rule: 'repeated',
9506 type: 'string',
9507 name: 'pids',
9508 id: 5
9509 }, {
9510 rule: 'optional',
9511 type: 'string',
9512 name: 'appMsg',
9513 id: 6
9514 }]
9515 }, {
9516 name: 'DirectCommand',
9517 syntax: 'proto2',
9518 fields: [{
9519 rule: 'optional',
9520 type: 'string',
9521 name: 'msg',
9522 id: 1
9523 }, {
9524 rule: 'optional',
9525 type: 'string',
9526 name: 'uid',
9527 id: 2
9528 }, {
9529 rule: 'optional',
9530 type: 'string',
9531 name: 'fromPeerId',
9532 id: 3
9533 }, {
9534 rule: 'optional',
9535 type: 'int64',
9536 name: 'timestamp',
9537 id: 4
9538 }, {
9539 rule: 'optional',
9540 type: 'bool',
9541 name: 'offline',
9542 id: 5
9543 }, {
9544 rule: 'optional',
9545 type: 'bool',
9546 name: 'hasMore',
9547 id: 6
9548 }, {
9549 rule: 'repeated',
9550 type: 'string',
9551 name: 'toPeerIds',
9552 id: 7
9553 }, {
9554 rule: 'optional',
9555 type: 'bool',
9556 name: 'r',
9557 id: 10
9558 }, {
9559 rule: 'optional',
9560 type: 'string',
9561 name: 'cid',
9562 id: 11
9563 }, {
9564 rule: 'optional',
9565 type: 'string',
9566 name: 'id',
9567 id: 12
9568 }, {
9569 rule: 'optional',
9570 type: 'bool',
9571 name: 'transient',
9572 id: 13
9573 }, {
9574 rule: 'optional',
9575 type: 'string',
9576 name: 'dt',
9577 id: 14
9578 }, {
9579 rule: 'optional',
9580 type: 'string',
9581 name: 'roomId',
9582 id: 15
9583 }, {
9584 rule: 'optional',
9585 type: 'string',
9586 name: 'pushData',
9587 id: 16
9588 }, {
9589 rule: 'optional',
9590 type: 'bool',
9591 name: 'will',
9592 id: 17
9593 }, {
9594 rule: 'optional',
9595 type: 'int64',
9596 name: 'patchTimestamp',
9597 id: 18
9598 }, {
9599 rule: 'optional',
9600 type: 'bytes',
9601 name: 'binaryMsg',
9602 id: 19
9603 }, {
9604 rule: 'repeated',
9605 type: 'string',
9606 name: 'mentionPids',
9607 id: 20
9608 }, {
9609 rule: 'optional',
9610 type: 'bool',
9611 name: 'mentionAll',
9612 id: 21
9613 }, {
9614 rule: 'optional',
9615 type: 'int32',
9616 name: 'convType',
9617 id: 22
9618 }]
9619 }, {
9620 name: 'AckCommand',
9621 syntax: 'proto2',
9622 fields: [{
9623 rule: 'optional',
9624 type: 'int32',
9625 name: 'code',
9626 id: 1
9627 }, {
9628 rule: 'optional',
9629 type: 'string',
9630 name: 'reason',
9631 id: 2
9632 }, {
9633 rule: 'optional',
9634 type: 'string',
9635 name: 'mid',
9636 id: 3
9637 }, {
9638 rule: 'optional',
9639 type: 'string',
9640 name: 'cid',
9641 id: 4
9642 }, {
9643 rule: 'optional',
9644 type: 'int64',
9645 name: 't',
9646 id: 5
9647 }, {
9648 rule: 'optional',
9649 type: 'string',
9650 name: 'uid',
9651 id: 6
9652 }, {
9653 rule: 'optional',
9654 type: 'int64',
9655 name: 'fromts',
9656 id: 7
9657 }, {
9658 rule: 'optional',
9659 type: 'int64',
9660 name: 'tots',
9661 id: 8
9662 }, {
9663 rule: 'optional',
9664 type: 'string',
9665 name: 'type',
9666 id: 9
9667 }, {
9668 rule: 'repeated',
9669 type: 'string',
9670 name: 'ids',
9671 id: 10
9672 }, {
9673 rule: 'optional',
9674 type: 'int32',
9675 name: 'appCode',
9676 id: 11
9677 }, {
9678 rule: 'optional',
9679 type: 'string',
9680 name: 'appMsg',
9681 id: 12
9682 }]
9683 }, {
9684 name: 'UnreadCommand',
9685 syntax: 'proto2',
9686 fields: [{
9687 rule: 'repeated',
9688 type: 'UnreadTuple',
9689 name: 'convs',
9690 id: 1
9691 }, {
9692 rule: 'optional',
9693 type: 'int64',
9694 name: 'notifTime',
9695 id: 2
9696 }]
9697 }, {
9698 name: 'ConvCommand',
9699 syntax: 'proto2',
9700 fields: [{
9701 rule: 'repeated',
9702 type: 'string',
9703 name: 'm',
9704 id: 1
9705 }, {
9706 rule: 'optional',
9707 type: 'bool',
9708 name: 'transient',
9709 id: 2
9710 }, {
9711 rule: 'optional',
9712 type: 'bool',
9713 name: 'unique',
9714 id: 3
9715 }, {
9716 rule: 'optional',
9717 type: 'string',
9718 name: 'cid',
9719 id: 4
9720 }, {
9721 rule: 'optional',
9722 type: 'string',
9723 name: 'cdate',
9724 id: 5
9725 }, {
9726 rule: 'optional',
9727 type: 'string',
9728 name: 'initBy',
9729 id: 6
9730 }, {
9731 rule: 'optional',
9732 type: 'string',
9733 name: 'sort',
9734 id: 7
9735 }, {
9736 rule: 'optional',
9737 type: 'int32',
9738 name: 'limit',
9739 id: 8
9740 }, {
9741 rule: 'optional',
9742 type: 'int32',
9743 name: 'skip',
9744 id: 9
9745 }, {
9746 rule: 'optional',
9747 type: 'int32',
9748 name: 'flag',
9749 id: 10
9750 }, {
9751 rule: 'optional',
9752 type: 'int32',
9753 name: 'count',
9754 id: 11
9755 }, {
9756 rule: 'optional',
9757 type: 'string',
9758 name: 'udate',
9759 id: 12
9760 }, {
9761 rule: 'optional',
9762 type: 'int64',
9763 name: 't',
9764 id: 13
9765 }, {
9766 rule: 'optional',
9767 type: 'string',
9768 name: 'n',
9769 id: 14
9770 }, {
9771 rule: 'optional',
9772 type: 'string',
9773 name: 's',
9774 id: 15
9775 }, {
9776 rule: 'optional',
9777 type: 'bool',
9778 name: 'statusSub',
9779 id: 16
9780 }, {
9781 rule: 'optional',
9782 type: 'bool',
9783 name: 'statusPub',
9784 id: 17
9785 }, {
9786 rule: 'optional',
9787 type: 'int32',
9788 name: 'statusTTL',
9789 id: 18
9790 }, {
9791 rule: 'optional',
9792 type: 'string',
9793 name: 'uniqueId',
9794 id: 19
9795 }, {
9796 rule: 'optional',
9797 type: 'string',
9798 name: 'targetClientId',
9799 id: 20
9800 }, {
9801 rule: 'optional',
9802 type: 'int64',
9803 name: 'maxReadTimestamp',
9804 id: 21
9805 }, {
9806 rule: 'optional',
9807 type: 'int64',
9808 name: 'maxAckTimestamp',
9809 id: 22
9810 }, {
9811 rule: 'optional',
9812 type: 'bool',
9813 name: 'queryAllMembers',
9814 id: 23
9815 }, {
9816 rule: 'repeated',
9817 type: 'MaxReadTuple',
9818 name: 'maxReadTuples',
9819 id: 24
9820 }, {
9821 rule: 'repeated',
9822 type: 'string',
9823 name: 'cids',
9824 id: 25
9825 }, {
9826 rule: 'optional',
9827 type: 'ConvMemberInfo',
9828 name: 'info',
9829 id: 26
9830 }, {
9831 rule: 'optional',
9832 type: 'bool',
9833 name: 'tempConv',
9834 id: 27
9835 }, {
9836 rule: 'optional',
9837 type: 'int32',
9838 name: 'tempConvTTL',
9839 id: 28
9840 }, {
9841 rule: 'repeated',
9842 type: 'string',
9843 name: 'tempConvIds',
9844 id: 29
9845 }, {
9846 rule: 'repeated',
9847 type: 'string',
9848 name: 'allowedPids',
9849 id: 30
9850 }, {
9851 rule: 'repeated',
9852 type: 'ErrorCommand',
9853 name: 'failedPids',
9854 id: 31
9855 }, {
9856 rule: 'optional',
9857 type: 'string',
9858 name: 'next',
9859 id: 40
9860 }, {
9861 rule: 'optional',
9862 type: 'JsonObjectMessage',
9863 name: 'results',
9864 id: 100
9865 }, {
9866 rule: 'optional',
9867 type: 'JsonObjectMessage',
9868 name: 'where',
9869 id: 101
9870 }, {
9871 rule: 'optional',
9872 type: 'JsonObjectMessage',
9873 name: 'attr',
9874 id: 103
9875 }, {
9876 rule: 'optional',
9877 type: 'JsonObjectMessage',
9878 name: 'attrModified',
9879 id: 104
9880 }]
9881 }, {
9882 name: 'RoomCommand',
9883 syntax: 'proto2',
9884 fields: [{
9885 rule: 'optional',
9886 type: 'string',
9887 name: 'roomId',
9888 id: 1
9889 }, {
9890 rule: 'optional',
9891 type: 'string',
9892 name: 's',
9893 id: 2
9894 }, {
9895 rule: 'optional',
9896 type: 'int64',
9897 name: 't',
9898 id: 3
9899 }, {
9900 rule: 'optional',
9901 type: 'string',
9902 name: 'n',
9903 id: 4
9904 }, {
9905 rule: 'optional',
9906 type: 'bool',
9907 name: 'transient',
9908 id: 5
9909 }, {
9910 rule: 'repeated',
9911 type: 'string',
9912 name: 'roomPeerIds',
9913 id: 6
9914 }, {
9915 rule: 'optional',
9916 type: 'string',
9917 name: 'byPeerId',
9918 id: 7
9919 }]
9920 }, {
9921 name: 'LogsCommand',
9922 syntax: 'proto2',
9923 fields: [{
9924 rule: 'optional',
9925 type: 'string',
9926 name: 'cid',
9927 id: 1
9928 }, {
9929 rule: 'optional',
9930 type: 'int32',
9931 name: 'l',
9932 id: 2
9933 }, {
9934 rule: 'optional',
9935 type: 'int32',
9936 name: 'limit',
9937 id: 3
9938 }, {
9939 rule: 'optional',
9940 type: 'int64',
9941 name: 't',
9942 id: 4
9943 }, {
9944 rule: 'optional',
9945 type: 'int64',
9946 name: 'tt',
9947 id: 5
9948 }, {
9949 rule: 'optional',
9950 type: 'string',
9951 name: 'tmid',
9952 id: 6
9953 }, {
9954 rule: 'optional',
9955 type: 'string',
9956 name: 'mid',
9957 id: 7
9958 }, {
9959 rule: 'optional',
9960 type: 'string',
9961 name: 'checksum',
9962 id: 8
9963 }, {
9964 rule: 'optional',
9965 type: 'bool',
9966 name: 'stored',
9967 id: 9
9968 }, {
9969 rule: 'optional',
9970 type: 'QueryDirection',
9971 name: 'direction',
9972 id: 10,
9973 options: {
9974 "default": 'OLD'
9975 }
9976 }, {
9977 rule: 'optional',
9978 type: 'bool',
9979 name: 'tIncluded',
9980 id: 11
9981 }, {
9982 rule: 'optional',
9983 type: 'bool',
9984 name: 'ttIncluded',
9985 id: 12
9986 }, {
9987 rule: 'optional',
9988 type: 'int32',
9989 name: 'lctype',
9990 id: 13
9991 }, {
9992 rule: 'repeated',
9993 type: 'LogItem',
9994 name: 'logs',
9995 id: 105
9996 }],
9997 enums: [{
9998 name: 'QueryDirection',
9999 syntax: 'proto2',
10000 values: [{
10001 name: 'OLD',
10002 id: 1
10003 }, {
10004 name: 'NEW',
10005 id: 2
10006 }]
10007 }]
10008 }, {
10009 name: 'RcpCommand',
10010 syntax: 'proto2',
10011 fields: [{
10012 rule: 'optional',
10013 type: 'string',
10014 name: 'id',
10015 id: 1
10016 }, {
10017 rule: 'optional',
10018 type: 'string',
10019 name: 'cid',
10020 id: 2
10021 }, {
10022 rule: 'optional',
10023 type: 'int64',
10024 name: 't',
10025 id: 3
10026 }, {
10027 rule: 'optional',
10028 type: 'bool',
10029 name: 'read',
10030 id: 4
10031 }, {
10032 rule: 'optional',
10033 type: 'string',
10034 name: 'from',
10035 id: 5
10036 }]
10037 }, {
10038 name: 'ReadTuple',
10039 syntax: 'proto2',
10040 fields: [{
10041 rule: 'required',
10042 type: 'string',
10043 name: 'cid',
10044 id: 1
10045 }, {
10046 rule: 'optional',
10047 type: 'int64',
10048 name: 'timestamp',
10049 id: 2
10050 }, {
10051 rule: 'optional',
10052 type: 'string',
10053 name: 'mid',
10054 id: 3
10055 }]
10056 }, {
10057 name: 'MaxReadTuple',
10058 syntax: 'proto2',
10059 fields: [{
10060 rule: 'optional',
10061 type: 'string',
10062 name: 'pid',
10063 id: 1
10064 }, {
10065 rule: 'optional',
10066 type: 'int64',
10067 name: 'maxAckTimestamp',
10068 id: 2
10069 }, {
10070 rule: 'optional',
10071 type: 'int64',
10072 name: 'maxReadTimestamp',
10073 id: 3
10074 }]
10075 }, {
10076 name: 'ReadCommand',
10077 syntax: 'proto2',
10078 fields: [{
10079 rule: 'optional',
10080 type: 'string',
10081 name: 'cid',
10082 id: 1
10083 }, {
10084 rule: 'repeated',
10085 type: 'string',
10086 name: 'cids',
10087 id: 2
10088 }, {
10089 rule: 'repeated',
10090 type: 'ReadTuple',
10091 name: 'convs',
10092 id: 3
10093 }]
10094 }, {
10095 name: 'PresenceCommand',
10096 syntax: 'proto2',
10097 fields: [{
10098 rule: 'optional',
10099 type: 'StatusType',
10100 name: 'status',
10101 id: 1
10102 }, {
10103 rule: 'repeated',
10104 type: 'string',
10105 name: 'sessionPeerIds',
10106 id: 2
10107 }, {
10108 rule: 'optional',
10109 type: 'string',
10110 name: 'cid',
10111 id: 3
10112 }]
10113 }, {
10114 name: 'ReportCommand',
10115 syntax: 'proto2',
10116 fields: [{
10117 rule: 'optional',
10118 type: 'bool',
10119 name: 'initiative',
10120 id: 1
10121 }, {
10122 rule: 'optional',
10123 type: 'string',
10124 name: 'type',
10125 id: 2
10126 }, {
10127 rule: 'optional',
10128 type: 'string',
10129 name: 'data',
10130 id: 3
10131 }]
10132 }, {
10133 name: 'PatchItem',
10134 syntax: 'proto2',
10135 fields: [{
10136 rule: 'optional',
10137 type: 'string',
10138 name: 'cid',
10139 id: 1
10140 }, {
10141 rule: 'optional',
10142 type: 'string',
10143 name: 'mid',
10144 id: 2
10145 }, {
10146 rule: 'optional',
10147 type: 'int64',
10148 name: 'timestamp',
10149 id: 3
10150 }, {
10151 rule: 'optional',
10152 type: 'bool',
10153 name: 'recall',
10154 id: 4
10155 }, {
10156 rule: 'optional',
10157 type: 'string',
10158 name: 'data',
10159 id: 5
10160 }, {
10161 rule: 'optional',
10162 type: 'int64',
10163 name: 'patchTimestamp',
10164 id: 6
10165 }, {
10166 rule: 'optional',
10167 type: 'string',
10168 name: 'from',
10169 id: 7
10170 }, {
10171 rule: 'optional',
10172 type: 'bytes',
10173 name: 'binaryMsg',
10174 id: 8
10175 }, {
10176 rule: 'optional',
10177 type: 'bool',
10178 name: 'mentionAll',
10179 id: 9
10180 }, {
10181 rule: 'repeated',
10182 type: 'string',
10183 name: 'mentionPids',
10184 id: 10
10185 }, {
10186 rule: 'optional',
10187 type: 'int64',
10188 name: 'patchCode',
10189 id: 11
10190 }, {
10191 rule: 'optional',
10192 type: 'string',
10193 name: 'patchReason',
10194 id: 12
10195 }]
10196 }, {
10197 name: 'PatchCommand',
10198 syntax: 'proto2',
10199 fields: [{
10200 rule: 'repeated',
10201 type: 'PatchItem',
10202 name: 'patches',
10203 id: 1
10204 }, {
10205 rule: 'optional',
10206 type: 'int64',
10207 name: 'lastPatchTime',
10208 id: 2
10209 }]
10210 }, {
10211 name: 'PubsubCommand',
10212 syntax: 'proto2',
10213 fields: [{
10214 rule: 'optional',
10215 type: 'string',
10216 name: 'cid',
10217 id: 1
10218 }, {
10219 rule: 'repeated',
10220 type: 'string',
10221 name: 'cids',
10222 id: 2
10223 }, {
10224 rule: 'optional',
10225 type: 'string',
10226 name: 'topic',
10227 id: 3
10228 }, {
10229 rule: 'optional',
10230 type: 'string',
10231 name: 'subtopic',
10232 id: 4
10233 }, {
10234 rule: 'repeated',
10235 type: 'string',
10236 name: 'topics',
10237 id: 5
10238 }, {
10239 rule: 'repeated',
10240 type: 'string',
10241 name: 'subtopics',
10242 id: 6
10243 }, {
10244 rule: 'optional',
10245 type: 'JsonObjectMessage',
10246 name: 'results',
10247 id: 7
10248 }]
10249 }, {
10250 name: 'BlacklistCommand',
10251 syntax: 'proto2',
10252 fields: [{
10253 rule: 'optional',
10254 type: 'string',
10255 name: 'srcCid',
10256 id: 1
10257 }, {
10258 rule: 'repeated',
10259 type: 'string',
10260 name: 'toPids',
10261 id: 2
10262 }, {
10263 rule: 'optional',
10264 type: 'string',
10265 name: 'srcPid',
10266 id: 3
10267 }, {
10268 rule: 'repeated',
10269 type: 'string',
10270 name: 'toCids',
10271 id: 4
10272 }, {
10273 rule: 'optional',
10274 type: 'int32',
10275 name: 'limit',
10276 id: 5
10277 }, {
10278 rule: 'optional',
10279 type: 'string',
10280 name: 'next',
10281 id: 6
10282 }, {
10283 rule: 'repeated',
10284 type: 'string',
10285 name: 'blockedPids',
10286 id: 8
10287 }, {
10288 rule: 'repeated',
10289 type: 'string',
10290 name: 'blockedCids',
10291 id: 9
10292 }, {
10293 rule: 'repeated',
10294 type: 'string',
10295 name: 'allowedPids',
10296 id: 10
10297 }, {
10298 rule: 'repeated',
10299 type: 'ErrorCommand',
10300 name: 'failedPids',
10301 id: 11
10302 }, {
10303 rule: 'optional',
10304 type: 'int64',
10305 name: 't',
10306 id: 12
10307 }, {
10308 rule: 'optional',
10309 type: 'string',
10310 name: 'n',
10311 id: 13
10312 }, {
10313 rule: 'optional',
10314 type: 'string',
10315 name: 's',
10316 id: 14
10317 }]
10318 }, {
10319 name: 'GenericCommand',
10320 syntax: 'proto2',
10321 fields: [{
10322 rule: 'optional',
10323 type: 'CommandType',
10324 name: 'cmd',
10325 id: 1
10326 }, {
10327 rule: 'optional',
10328 type: 'OpType',
10329 name: 'op',
10330 id: 2
10331 }, {
10332 rule: 'optional',
10333 type: 'string',
10334 name: 'appId',
10335 id: 3
10336 }, {
10337 rule: 'optional',
10338 type: 'string',
10339 name: 'peerId',
10340 id: 4
10341 }, {
10342 rule: 'optional',
10343 type: 'int32',
10344 name: 'i',
10345 id: 5
10346 }, {
10347 rule: 'optional',
10348 type: 'string',
10349 name: 'installationId',
10350 id: 6
10351 }, {
10352 rule: 'optional',
10353 type: 'int32',
10354 name: 'priority',
10355 id: 7
10356 }, {
10357 rule: 'optional',
10358 type: 'int32',
10359 name: 'service',
10360 id: 8
10361 }, {
10362 rule: 'optional',
10363 type: 'int64',
10364 name: 'serverTs',
10365 id: 9
10366 }, {
10367 rule: 'optional',
10368 type: 'int64',
10369 name: 'clientTs',
10370 id: 10
10371 }, {
10372 rule: 'optional',
10373 type: 'int32',
10374 name: 'notificationType',
10375 id: 11
10376 }, {
10377 rule: 'optional',
10378 type: 'DataCommand',
10379 name: 'dataMessage',
10380 id: 101
10381 }, {
10382 rule: 'optional',
10383 type: 'SessionCommand',
10384 name: 'sessionMessage',
10385 id: 102
10386 }, {
10387 rule: 'optional',
10388 type: 'ErrorCommand',
10389 name: 'errorMessage',
10390 id: 103
10391 }, {
10392 rule: 'optional',
10393 type: 'DirectCommand',
10394 name: 'directMessage',
10395 id: 104
10396 }, {
10397 rule: 'optional',
10398 type: 'AckCommand',
10399 name: 'ackMessage',
10400 id: 105
10401 }, {
10402 rule: 'optional',
10403 type: 'UnreadCommand',
10404 name: 'unreadMessage',
10405 id: 106
10406 }, {
10407 rule: 'optional',
10408 type: 'ReadCommand',
10409 name: 'readMessage',
10410 id: 107
10411 }, {
10412 rule: 'optional',
10413 type: 'RcpCommand',
10414 name: 'rcpMessage',
10415 id: 108
10416 }, {
10417 rule: 'optional',
10418 type: 'LogsCommand',
10419 name: 'logsMessage',
10420 id: 109
10421 }, {
10422 rule: 'optional',
10423 type: 'ConvCommand',
10424 name: 'convMessage',
10425 id: 110
10426 }, {
10427 rule: 'optional',
10428 type: 'RoomCommand',
10429 name: 'roomMessage',
10430 id: 111
10431 }, {
10432 rule: 'optional',
10433 type: 'PresenceCommand',
10434 name: 'presenceMessage',
10435 id: 112
10436 }, {
10437 rule: 'optional',
10438 type: 'ReportCommand',
10439 name: 'reportMessage',
10440 id: 113
10441 }, {
10442 rule: 'optional',
10443 type: 'PatchCommand',
10444 name: 'patchMessage',
10445 id: 114
10446 }, {
10447 rule: 'optional',
10448 type: 'PubsubCommand',
10449 name: 'pubsubMessage',
10450 id: 115
10451 }, {
10452 rule: 'optional',
10453 type: 'BlacklistCommand',
10454 name: 'blacklistMessage',
10455 id: 116
10456 }]
10457 }],
10458 enums: [{
10459 name: 'CommandType',
10460 syntax: 'proto2',
10461 values: [{
10462 name: 'session',
10463 id: 0
10464 }, {
10465 name: 'conv',
10466 id: 1
10467 }, {
10468 name: 'direct',
10469 id: 2
10470 }, {
10471 name: 'ack',
10472 id: 3
10473 }, {
10474 name: 'rcp',
10475 id: 4
10476 }, {
10477 name: 'unread',
10478 id: 5
10479 }, {
10480 name: 'logs',
10481 id: 6
10482 }, {
10483 name: 'error',
10484 id: 7
10485 }, {
10486 name: 'login',
10487 id: 8
10488 }, {
10489 name: 'data',
10490 id: 9
10491 }, {
10492 name: 'room',
10493 id: 10
10494 }, {
10495 name: 'read',
10496 id: 11
10497 }, {
10498 name: 'presence',
10499 id: 12
10500 }, {
10501 name: 'report',
10502 id: 13
10503 }, {
10504 name: 'echo',
10505 id: 14
10506 }, {
10507 name: 'loggedin',
10508 id: 15
10509 }, {
10510 name: 'logout',
10511 id: 16
10512 }, {
10513 name: 'loggedout',
10514 id: 17
10515 }, {
10516 name: 'patch',
10517 id: 18
10518 }, {
10519 name: 'pubsub',
10520 id: 19
10521 }, {
10522 name: 'blacklist',
10523 id: 20
10524 }, {
10525 name: 'goaway',
10526 id: 21
10527 }]
10528 }, {
10529 name: 'OpType',
10530 syntax: 'proto2',
10531 values: [{
10532 name: 'open',
10533 id: 1
10534 }, {
10535 name: 'add',
10536 id: 2
10537 }, {
10538 name: 'remove',
10539 id: 3
10540 }, {
10541 name: 'close',
10542 id: 4
10543 }, {
10544 name: 'opened',
10545 id: 5
10546 }, {
10547 name: 'closed',
10548 id: 6
10549 }, {
10550 name: 'query',
10551 id: 7
10552 }, {
10553 name: 'query_result',
10554 id: 8
10555 }, {
10556 name: 'conflict',
10557 id: 9
10558 }, {
10559 name: 'added',
10560 id: 10
10561 }, {
10562 name: 'removed',
10563 id: 11
10564 }, {
10565 name: 'refresh',
10566 id: 12
10567 }, {
10568 name: 'refreshed',
10569 id: 13
10570 }, {
10571 name: 'start',
10572 id: 30
10573 }, {
10574 name: 'started',
10575 id: 31
10576 }, {
10577 name: 'joined',
10578 id: 32
10579 }, {
10580 name: 'members_joined',
10581 id: 33
10582 }, {
10583 name: 'left',
10584 id: 39
10585 }, {
10586 name: 'members_left',
10587 id: 40
10588 }, {
10589 name: 'results',
10590 id: 42
10591 }, {
10592 name: 'count',
10593 id: 43
10594 }, {
10595 name: 'result',
10596 id: 44
10597 }, {
10598 name: 'update',
10599 id: 45
10600 }, {
10601 name: 'updated',
10602 id: 46
10603 }, {
10604 name: 'mute',
10605 id: 47
10606 }, {
10607 name: 'unmute',
10608 id: 48
10609 }, {
10610 name: 'status',
10611 id: 49
10612 }, {
10613 name: 'members',
10614 id: 50
10615 }, {
10616 name: 'max_read',
10617 id: 51
10618 }, {
10619 name: 'is_member',
10620 id: 52
10621 }, {
10622 name: 'member_info_update',
10623 id: 53
10624 }, {
10625 name: 'member_info_updated',
10626 id: 54
10627 }, {
10628 name: 'member_info_changed',
10629 id: 55
10630 }, {
10631 name: 'join',
10632 id: 80
10633 }, {
10634 name: 'invite',
10635 id: 81
10636 }, {
10637 name: 'leave',
10638 id: 82
10639 }, {
10640 name: 'kick',
10641 id: 83
10642 }, {
10643 name: 'reject',
10644 id: 84
10645 }, {
10646 name: 'invited',
10647 id: 85
10648 }, {
10649 name: 'kicked',
10650 id: 86
10651 }, {
10652 name: 'upload',
10653 id: 100
10654 }, {
10655 name: 'uploaded',
10656 id: 101
10657 }, {
10658 name: 'subscribe',
10659 id: 120
10660 }, {
10661 name: 'subscribed',
10662 id: 121
10663 }, {
10664 name: 'unsubscribe',
10665 id: 122
10666 }, {
10667 name: 'unsubscribed',
10668 id: 123
10669 }, {
10670 name: 'is_subscribed',
10671 id: 124
10672 }, {
10673 name: 'modify',
10674 id: 150
10675 }, {
10676 name: 'modified',
10677 id: 151
10678 }, {
10679 name: 'block',
10680 id: 170
10681 }, {
10682 name: 'unblock',
10683 id: 171
10684 }, {
10685 name: 'blocked',
10686 id: 172
10687 }, {
10688 name: 'unblocked',
10689 id: 173
10690 }, {
10691 name: 'members_blocked',
10692 id: 174
10693 }, {
10694 name: 'members_unblocked',
10695 id: 175
10696 }, {
10697 name: 'check_block',
10698 id: 176
10699 }, {
10700 name: 'check_result',
10701 id: 177
10702 }, {
10703 name: 'add_shutup',
10704 id: 180
10705 }, {
10706 name: 'remove_shutup',
10707 id: 181
10708 }, {
10709 name: 'query_shutup',
10710 id: 182
10711 }, {
10712 name: 'shutup_added',
10713 id: 183
10714 }, {
10715 name: 'shutup_removed',
10716 id: 184
10717 }, {
10718 name: 'shutup_result',
10719 id: 185
10720 }, {
10721 name: 'shutuped',
10722 id: 186
10723 }, {
10724 name: 'unshutuped',
10725 id: 187
10726 }, {
10727 name: 'members_shutuped',
10728 id: 188
10729 }, {
10730 name: 'members_unshutuped',
10731 id: 189
10732 }, {
10733 name: 'check_shutup',
10734 id: 190
10735 }]
10736 }, {
10737 name: 'StatusType',
10738 syntax: 'proto2',
10739 values: [{
10740 name: 'on',
10741 id: 1
10742 }, {
10743 name: 'off',
10744 id: 2
10745 }]
10746 }],
10747 isNamespace: true
10748 }).build();
10749
10750 var _messages$push_server = messageCompiled.push_server.messages2,
10751 JsonObjectMessage = _messages$push_server.JsonObjectMessage,
10752 UnreadTuple = _messages$push_server.UnreadTuple,
10753 LogItem = _messages$push_server.LogItem,
10754 DataCommand = _messages$push_server.DataCommand,
10755 SessionCommand = _messages$push_server.SessionCommand,
10756 ErrorCommand = _messages$push_server.ErrorCommand,
10757 DirectCommand = _messages$push_server.DirectCommand,
10758 AckCommand = _messages$push_server.AckCommand,
10759 UnreadCommand = _messages$push_server.UnreadCommand,
10760 ConvCommand = _messages$push_server.ConvCommand,
10761 RoomCommand = _messages$push_server.RoomCommand,
10762 LogsCommand = _messages$push_server.LogsCommand,
10763 RcpCommand = _messages$push_server.RcpCommand,
10764 ReadTuple = _messages$push_server.ReadTuple,
10765 MaxReadTuple = _messages$push_server.MaxReadTuple,
10766 ReadCommand = _messages$push_server.ReadCommand,
10767 PresenceCommand = _messages$push_server.PresenceCommand,
10768 ReportCommand = _messages$push_server.ReportCommand,
10769 GenericCommand = _messages$push_server.GenericCommand,
10770 BlacklistCommand = _messages$push_server.BlacklistCommand,
10771 PatchCommand = _messages$push_server.PatchCommand,
10772 PatchItem = _messages$push_server.PatchItem,
10773 ConvMemberInfo = _messages$push_server.ConvMemberInfo,
10774 CommandType = _messages$push_server.CommandType,
10775 OpType = _messages$push_server.OpType,
10776 StatusType = _messages$push_server.StatusType;
10777
10778 var message = /*#__PURE__*/Object.freeze({
10779 __proto__: null,
10780 JsonObjectMessage: JsonObjectMessage,
10781 UnreadTuple: UnreadTuple,
10782 LogItem: LogItem,
10783 DataCommand: DataCommand,
10784 SessionCommand: SessionCommand,
10785 ErrorCommand: ErrorCommand,
10786 DirectCommand: DirectCommand,
10787 AckCommand: AckCommand,
10788 UnreadCommand: UnreadCommand,
10789 ConvCommand: ConvCommand,
10790 RoomCommand: RoomCommand,
10791 LogsCommand: LogsCommand,
10792 RcpCommand: RcpCommand,
10793 ReadTuple: ReadTuple,
10794 MaxReadTuple: MaxReadTuple,
10795 ReadCommand: ReadCommand,
10796 PresenceCommand: PresenceCommand,
10797 ReportCommand: ReportCommand,
10798 GenericCommand: GenericCommand,
10799 BlacklistCommand: BlacklistCommand,
10800 PatchCommand: PatchCommand,
10801 PatchItem: PatchItem,
10802 ConvMemberInfo: ConvMemberInfo,
10803 CommandType: CommandType,
10804 OpType: OpType,
10805 StatusType: StatusType
10806 });
10807
10808 var eventemitter3 = createCommonjsModule(function (module) {
10809
10810 var has = Object.prototype.hasOwnProperty
10811 , prefix = '~';
10812
10813 /**
10814 * Constructor to create a storage for our `EE` objects.
10815 * An `Events` instance is a plain object whose properties are event names.
10816 *
10817 * @constructor
10818 * @private
10819 */
10820 function Events() {}
10821
10822 //
10823 // We try to not inherit from `Object.prototype`. In some engines creating an
10824 // instance in this way is faster than calling `Object.create(null)` directly.
10825 // If `Object.create(null)` is not supported we prefix the event names with a
10826 // character to make sure that the built-in object properties are not
10827 // overridden or used as an attack vector.
10828 //
10829 if (Object.create) {
10830 Events.prototype = Object.create(null);
10831
10832 //
10833 // This hack is needed because the `__proto__` property is still inherited in
10834 // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
10835 //
10836 if (!new Events().__proto__) prefix = false;
10837 }
10838
10839 /**
10840 * Representation of a single event listener.
10841 *
10842 * @param {Function} fn The listener function.
10843 * @param {*} context The context to invoke the listener with.
10844 * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
10845 * @constructor
10846 * @private
10847 */
10848 function EE(fn, context, once) {
10849 this.fn = fn;
10850 this.context = context;
10851 this.once = once || false;
10852 }
10853
10854 /**
10855 * Add a listener for a given event.
10856 *
10857 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
10858 * @param {(String|Symbol)} event The event name.
10859 * @param {Function} fn The listener function.
10860 * @param {*} context The context to invoke the listener with.
10861 * @param {Boolean} once Specify if the listener is a one-time listener.
10862 * @returns {EventEmitter}
10863 * @private
10864 */
10865 function addListener(emitter, event, fn, context, once) {
10866 if (typeof fn !== 'function') {
10867 throw new TypeError('The listener must be a function');
10868 }
10869
10870 var listener = new EE(fn, context || emitter, once)
10871 , evt = prefix ? prefix + event : event;
10872
10873 if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
10874 else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
10875 else emitter._events[evt] = [emitter._events[evt], listener];
10876
10877 return emitter;
10878 }
10879
10880 /**
10881 * Clear event by name.
10882 *
10883 * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
10884 * @param {(String|Symbol)} evt The Event name.
10885 * @private
10886 */
10887 function clearEvent(emitter, evt) {
10888 if (--emitter._eventsCount === 0) emitter._events = new Events();
10889 else delete emitter._events[evt];
10890 }
10891
10892 /**
10893 * Minimal `EventEmitter` interface that is molded against the Node.js
10894 * `EventEmitter` interface.
10895 *
10896 * @constructor
10897 * @public
10898 */
10899 function EventEmitter() {
10900 this._events = new Events();
10901 this._eventsCount = 0;
10902 }
10903
10904 /**
10905 * Return an array listing the events for which the emitter has registered
10906 * listeners.
10907 *
10908 * @returns {Array}
10909 * @public
10910 */
10911 EventEmitter.prototype.eventNames = function eventNames() {
10912 var names = []
10913 , events
10914 , name;
10915
10916 if (this._eventsCount === 0) return names;
10917
10918 for (name in (events = this._events)) {
10919 if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
10920 }
10921
10922 if (Object.getOwnPropertySymbols) {
10923 return names.concat(Object.getOwnPropertySymbols(events));
10924 }
10925
10926 return names;
10927 };
10928
10929 /**
10930 * Return the listeners registered for a given event.
10931 *
10932 * @param {(String|Symbol)} event The event name.
10933 * @returns {Array} The registered listeners.
10934 * @public
10935 */
10936 EventEmitter.prototype.listeners = function listeners(event) {
10937 var evt = prefix ? prefix + event : event
10938 , handlers = this._events[evt];
10939
10940 if (!handlers) return [];
10941 if (handlers.fn) return [handlers.fn];
10942
10943 for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
10944 ee[i] = handlers[i].fn;
10945 }
10946
10947 return ee;
10948 };
10949
10950 /**
10951 * Return the number of listeners listening to a given event.
10952 *
10953 * @param {(String|Symbol)} event The event name.
10954 * @returns {Number} The number of listeners.
10955 * @public
10956 */
10957 EventEmitter.prototype.listenerCount = function listenerCount(event) {
10958 var evt = prefix ? prefix + event : event
10959 , listeners = this._events[evt];
10960
10961 if (!listeners) return 0;
10962 if (listeners.fn) return 1;
10963 return listeners.length;
10964 };
10965
10966 /**
10967 * Calls each of the listeners registered for a given event.
10968 *
10969 * @param {(String|Symbol)} event The event name.
10970 * @returns {Boolean} `true` if the event had listeners, else `false`.
10971 * @public
10972 */
10973 EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
10974 var evt = prefix ? prefix + event : event;
10975
10976 if (!this._events[evt]) return false;
10977
10978 var listeners = this._events[evt]
10979 , len = arguments.length
10980 , args
10981 , i;
10982
10983 if (listeners.fn) {
10984 if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
10985
10986 switch (len) {
10987 case 1: return listeners.fn.call(listeners.context), true;
10988 case 2: return listeners.fn.call(listeners.context, a1), true;
10989 case 3: return listeners.fn.call(listeners.context, a1, a2), true;
10990 case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
10991 case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
10992 case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
10993 }
10994
10995 for (i = 1, args = new Array(len -1); i < len; i++) {
10996 args[i - 1] = arguments[i];
10997 }
10998
10999 listeners.fn.apply(listeners.context, args);
11000 } else {
11001 var length = listeners.length
11002 , j;
11003
11004 for (i = 0; i < length; i++) {
11005 if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
11006
11007 switch (len) {
11008 case 1: listeners[i].fn.call(listeners[i].context); break;
11009 case 2: listeners[i].fn.call(listeners[i].context, a1); break;
11010 case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
11011 case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
11012 default:
11013 if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
11014 args[j - 1] = arguments[j];
11015 }
11016
11017 listeners[i].fn.apply(listeners[i].context, args);
11018 }
11019 }
11020 }
11021
11022 return true;
11023 };
11024
11025 /**
11026 * Add a listener for a given event.
11027 *
11028 * @param {(String|Symbol)} event The event name.
11029 * @param {Function} fn The listener function.
11030 * @param {*} [context=this] The context to invoke the listener with.
11031 * @returns {EventEmitter} `this`.
11032 * @public
11033 */
11034 EventEmitter.prototype.on = function on(event, fn, context) {
11035 return addListener(this, event, fn, context, false);
11036 };
11037
11038 /**
11039 * Add a one-time listener for a given event.
11040 *
11041 * @param {(String|Symbol)} event The event name.
11042 * @param {Function} fn The listener function.
11043 * @param {*} [context=this] The context to invoke the listener with.
11044 * @returns {EventEmitter} `this`.
11045 * @public
11046 */
11047 EventEmitter.prototype.once = function once(event, fn, context) {
11048 return addListener(this, event, fn, context, true);
11049 };
11050
11051 /**
11052 * Remove the listeners of a given event.
11053 *
11054 * @param {(String|Symbol)} event The event name.
11055 * @param {Function} fn Only remove the listeners that match this function.
11056 * @param {*} context Only remove the listeners that have this context.
11057 * @param {Boolean} once Only remove one-time listeners.
11058 * @returns {EventEmitter} `this`.
11059 * @public
11060 */
11061 EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
11062 var evt = prefix ? prefix + event : event;
11063
11064 if (!this._events[evt]) return this;
11065 if (!fn) {
11066 clearEvent(this, evt);
11067 return this;
11068 }
11069
11070 var listeners = this._events[evt];
11071
11072 if (listeners.fn) {
11073 if (
11074 listeners.fn === fn &&
11075 (!once || listeners.once) &&
11076 (!context || listeners.context === context)
11077 ) {
11078 clearEvent(this, evt);
11079 }
11080 } else {
11081 for (var i = 0, events = [], length = listeners.length; i < length; i++) {
11082 if (
11083 listeners[i].fn !== fn ||
11084 (once && !listeners[i].once) ||
11085 (context && listeners[i].context !== context)
11086 ) {
11087 events.push(listeners[i]);
11088 }
11089 }
11090
11091 //
11092 // Reset the array, or remove it completely if we have no more listeners.
11093 //
11094 if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
11095 else clearEvent(this, evt);
11096 }
11097
11098 return this;
11099 };
11100
11101 /**
11102 * Remove all listeners, or those of the specified event.
11103 *
11104 * @param {(String|Symbol)} [event] The event name.
11105 * @returns {EventEmitter} `this`.
11106 * @public
11107 */
11108 EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
11109 var evt;
11110
11111 if (event) {
11112 evt = prefix ? prefix + event : event;
11113 if (this._events[evt]) clearEvent(this, evt);
11114 } else {
11115 this._events = new Events();
11116 this._eventsCount = 0;
11117 }
11118
11119 return this;
11120 };
11121
11122 //
11123 // Alias methods names because people roll like that.
11124 //
11125 EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
11126 EventEmitter.prototype.addListener = EventEmitter.prototype.on;
11127
11128 //
11129 // Expose the prefix.
11130 //
11131 EventEmitter.prefixed = prefix;
11132
11133 //
11134 // Allow `EventEmitter` to be imported as module namespace.
11135 //
11136 EventEmitter.EventEmitter = EventEmitter;
11137
11138 //
11139 // Expose the module.
11140 //
11141 {
11142 module.exports = EventEmitter;
11143 }
11144 });
11145
11146 var runtime_1 = createCommonjsModule(function (module) {
11147 /**
11148 * Copyright (c) 2014-present, Facebook, Inc.
11149 *
11150 * This source code is licensed under the MIT license found in the
11151 * LICENSE file in the root directory of this source tree.
11152 */
11153
11154 var runtime = (function (exports) {
11155
11156 var Op = Object.prototype;
11157 var hasOwn = Op.hasOwnProperty;
11158 var undefined$1; // More compressible than void 0.
11159 var $Symbol = typeof Symbol === "function" ? Symbol : {};
11160 var iteratorSymbol = $Symbol.iterator || "@@iterator";
11161 var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
11162 var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
11163
11164 function wrap(innerFn, outerFn, self, tryLocsList) {
11165 // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
11166 var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
11167 var generator = Object.create(protoGenerator.prototype);
11168 var context = new Context(tryLocsList || []);
11169
11170 // The ._invoke method unifies the implementations of the .next,
11171 // .throw, and .return methods.
11172 generator._invoke = makeInvokeMethod(innerFn, self, context);
11173
11174 return generator;
11175 }
11176 exports.wrap = wrap;
11177
11178 // Try/catch helper to minimize deoptimizations. Returns a completion
11179 // record like context.tryEntries[i].completion. This interface could
11180 // have been (and was previously) designed to take a closure to be
11181 // invoked without arguments, but in all the cases we care about we
11182 // already have an existing method we want to call, so there's no need
11183 // to create a new function object. We can even get away with assuming
11184 // the method takes exactly one argument, since that happens to be true
11185 // in every case, so we don't have to touch the arguments object. The
11186 // only additional allocation required is the completion record, which
11187 // has a stable shape and so hopefully should be cheap to allocate.
11188 function tryCatch(fn, obj, arg) {
11189 try {
11190 return { type: "normal", arg: fn.call(obj, arg) };
11191 } catch (err) {
11192 return { type: "throw", arg: err };
11193 }
11194 }
11195
11196 var GenStateSuspendedStart = "suspendedStart";
11197 var GenStateSuspendedYield = "suspendedYield";
11198 var GenStateExecuting = "executing";
11199 var GenStateCompleted = "completed";
11200
11201 // Returning this object from the innerFn has the same effect as
11202 // breaking out of the dispatch switch statement.
11203 var ContinueSentinel = {};
11204
11205 // Dummy constructor functions that we use as the .constructor and
11206 // .constructor.prototype properties for functions that return Generator
11207 // objects. For full spec compliance, you may wish to configure your
11208 // minifier not to mangle the names of these two functions.
11209 function Generator() {}
11210 function GeneratorFunction() {}
11211 function GeneratorFunctionPrototype() {}
11212
11213 // This is a polyfill for %IteratorPrototype% for environments that
11214 // don't natively support it.
11215 var IteratorPrototype = {};
11216 IteratorPrototype[iteratorSymbol] = function () {
11217 return this;
11218 };
11219
11220 var getProto = Object.getPrototypeOf;
11221 var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
11222 if (NativeIteratorPrototype &&
11223 NativeIteratorPrototype !== Op &&
11224 hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
11225 // This environment has a native %IteratorPrototype%; use it instead
11226 // of the polyfill.
11227 IteratorPrototype = NativeIteratorPrototype;
11228 }
11229
11230 var Gp = GeneratorFunctionPrototype.prototype =
11231 Generator.prototype = Object.create(IteratorPrototype);
11232 GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
11233 GeneratorFunctionPrototype.constructor = GeneratorFunction;
11234 GeneratorFunctionPrototype[toStringTagSymbol] =
11235 GeneratorFunction.displayName = "GeneratorFunction";
11236
11237 // Helper for defining the .next, .throw, and .return methods of the
11238 // Iterator interface in terms of a single ._invoke method.
11239 function defineIteratorMethods(prototype) {
11240 ["next", "throw", "return"].forEach(function(method) {
11241 prototype[method] = function(arg) {
11242 return this._invoke(method, arg);
11243 };
11244 });
11245 }
11246
11247 exports.isGeneratorFunction = function(genFun) {
11248 var ctor = typeof genFun === "function" && genFun.constructor;
11249 return ctor
11250 ? ctor === GeneratorFunction ||
11251 // For the native GeneratorFunction constructor, the best we can
11252 // do is to check its .name property.
11253 (ctor.displayName || ctor.name) === "GeneratorFunction"
11254 : false;
11255 };
11256
11257 exports.mark = function(genFun) {
11258 if (Object.setPrototypeOf) {
11259 Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
11260 } else {
11261 genFun.__proto__ = GeneratorFunctionPrototype;
11262 if (!(toStringTagSymbol in genFun)) {
11263 genFun[toStringTagSymbol] = "GeneratorFunction";
11264 }
11265 }
11266 genFun.prototype = Object.create(Gp);
11267 return genFun;
11268 };
11269
11270 // Within the body of any async function, `await x` is transformed to
11271 // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
11272 // `hasOwn.call(value, "__await")` to determine if the yielded value is
11273 // meant to be awaited.
11274 exports.awrap = function(arg) {
11275 return { __await: arg };
11276 };
11277
11278 function AsyncIterator(generator, PromiseImpl) {
11279 function invoke(method, arg, resolve, reject) {
11280 var record = tryCatch(generator[method], generator, arg);
11281 if (record.type === "throw") {
11282 reject(record.arg);
11283 } else {
11284 var result = record.arg;
11285 var value = result.value;
11286 if (value &&
11287 typeof value === "object" &&
11288 hasOwn.call(value, "__await")) {
11289 return PromiseImpl.resolve(value.__await).then(function(value) {
11290 invoke("next", value, resolve, reject);
11291 }, function(err) {
11292 invoke("throw", err, resolve, reject);
11293 });
11294 }
11295
11296 return PromiseImpl.resolve(value).then(function(unwrapped) {
11297 // When a yielded Promise is resolved, its final value becomes
11298 // the .value of the Promise<{value,done}> result for the
11299 // current iteration.
11300 result.value = unwrapped;
11301 resolve(result);
11302 }, function(error) {
11303 // If a rejected Promise was yielded, throw the rejection back
11304 // into the async generator function so it can be handled there.
11305 return invoke("throw", error, resolve, reject);
11306 });
11307 }
11308 }
11309
11310 var previousPromise;
11311
11312 function enqueue(method, arg) {
11313 function callInvokeWithMethodAndArg() {
11314 return new PromiseImpl(function(resolve, reject) {
11315 invoke(method, arg, resolve, reject);
11316 });
11317 }
11318
11319 return previousPromise =
11320 // If enqueue has been called before, then we want to wait until
11321 // all previous Promises have been resolved before calling invoke,
11322 // so that results are always delivered in the correct order. If
11323 // enqueue has not been called before, then it is important to
11324 // call invoke immediately, without waiting on a callback to fire,
11325 // so that the async generator function has the opportunity to do
11326 // any necessary setup in a predictable way. This predictability
11327 // is why the Promise constructor synchronously invokes its
11328 // executor callback, and why async functions synchronously
11329 // execute code before the first await. Since we implement simple
11330 // async functions in terms of async generators, it is especially
11331 // important to get this right, even though it requires care.
11332 previousPromise ? previousPromise.then(
11333 callInvokeWithMethodAndArg,
11334 // Avoid propagating failures to Promises returned by later
11335 // invocations of the iterator.
11336 callInvokeWithMethodAndArg
11337 ) : callInvokeWithMethodAndArg();
11338 }
11339
11340 // Define the unified helper method that is used to implement .next,
11341 // .throw, and .return (see defineIteratorMethods).
11342 this._invoke = enqueue;
11343 }
11344
11345 defineIteratorMethods(AsyncIterator.prototype);
11346 AsyncIterator.prototype[asyncIteratorSymbol] = function () {
11347 return this;
11348 };
11349 exports.AsyncIterator = AsyncIterator;
11350
11351 // Note that simple async functions are implemented on top of
11352 // AsyncIterator objects; they just return a Promise for the value of
11353 // the final result produced by the iterator.
11354 exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) {
11355 if (PromiseImpl === void 0) PromiseImpl = Promise;
11356
11357 var iter = new AsyncIterator(
11358 wrap(innerFn, outerFn, self, tryLocsList),
11359 PromiseImpl
11360 );
11361
11362 return exports.isGeneratorFunction(outerFn)
11363 ? iter // If outerFn is a generator, return the full iterator.
11364 : iter.next().then(function(result) {
11365 return result.done ? result.value : iter.next();
11366 });
11367 };
11368
11369 function makeInvokeMethod(innerFn, self, context) {
11370 var state = GenStateSuspendedStart;
11371
11372 return function invoke(method, arg) {
11373 if (state === GenStateExecuting) {
11374 throw new Error("Generator is already running");
11375 }
11376
11377 if (state === GenStateCompleted) {
11378 if (method === "throw") {
11379 throw arg;
11380 }
11381
11382 // Be forgiving, per 25.3.3.3.3 of the spec:
11383 // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
11384 return doneResult();
11385 }
11386
11387 context.method = method;
11388 context.arg = arg;
11389
11390 while (true) {
11391 var delegate = context.delegate;
11392 if (delegate) {
11393 var delegateResult = maybeInvokeDelegate(delegate, context);
11394 if (delegateResult) {
11395 if (delegateResult === ContinueSentinel) continue;
11396 return delegateResult;
11397 }
11398 }
11399
11400 if (context.method === "next") {
11401 // Setting context._sent for legacy support of Babel's
11402 // function.sent implementation.
11403 context.sent = context._sent = context.arg;
11404
11405 } else if (context.method === "throw") {
11406 if (state === GenStateSuspendedStart) {
11407 state = GenStateCompleted;
11408 throw context.arg;
11409 }
11410
11411 context.dispatchException(context.arg);
11412
11413 } else if (context.method === "return") {
11414 context.abrupt("return", context.arg);
11415 }
11416
11417 state = GenStateExecuting;
11418
11419 var record = tryCatch(innerFn, self, context);
11420 if (record.type === "normal") {
11421 // If an exception is thrown from innerFn, we leave state ===
11422 // GenStateExecuting and loop back for another invocation.
11423 state = context.done
11424 ? GenStateCompleted
11425 : GenStateSuspendedYield;
11426
11427 if (record.arg === ContinueSentinel) {
11428 continue;
11429 }
11430
11431 return {
11432 value: record.arg,
11433 done: context.done
11434 };
11435
11436 } else if (record.type === "throw") {
11437 state = GenStateCompleted;
11438 // Dispatch the exception by looping back around to the
11439 // context.dispatchException(context.arg) call above.
11440 context.method = "throw";
11441 context.arg = record.arg;
11442 }
11443 }
11444 };
11445 }
11446
11447 // Call delegate.iterator[context.method](context.arg) and handle the
11448 // result, either by returning a { value, done } result from the
11449 // delegate iterator, or by modifying context.method and context.arg,
11450 // setting context.delegate to null, and returning the ContinueSentinel.
11451 function maybeInvokeDelegate(delegate, context) {
11452 var method = delegate.iterator[context.method];
11453 if (method === undefined$1) {
11454 // A .throw or .return when the delegate iterator has no .throw
11455 // method always terminates the yield* loop.
11456 context.delegate = null;
11457
11458 if (context.method === "throw") {
11459 // Note: ["return"] must be used for ES3 parsing compatibility.
11460 if (delegate.iterator["return"]) {
11461 // If the delegate iterator has a return method, give it a
11462 // chance to clean up.
11463 context.method = "return";
11464 context.arg = undefined$1;
11465 maybeInvokeDelegate(delegate, context);
11466
11467 if (context.method === "throw") {
11468 // If maybeInvokeDelegate(context) changed context.method from
11469 // "return" to "throw", let that override the TypeError below.
11470 return ContinueSentinel;
11471 }
11472 }
11473
11474 context.method = "throw";
11475 context.arg = new TypeError(
11476 "The iterator does not provide a 'throw' method");
11477 }
11478
11479 return ContinueSentinel;
11480 }
11481
11482 var record = tryCatch(method, delegate.iterator, context.arg);
11483
11484 if (record.type === "throw") {
11485 context.method = "throw";
11486 context.arg = record.arg;
11487 context.delegate = null;
11488 return ContinueSentinel;
11489 }
11490
11491 var info = record.arg;
11492
11493 if (! info) {
11494 context.method = "throw";
11495 context.arg = new TypeError("iterator result is not an object");
11496 context.delegate = null;
11497 return ContinueSentinel;
11498 }
11499
11500 if (info.done) {
11501 // Assign the result of the finished delegate to the temporary
11502 // variable specified by delegate.resultName (see delegateYield).
11503 context[delegate.resultName] = info.value;
11504
11505 // Resume execution at the desired location (see delegateYield).
11506 context.next = delegate.nextLoc;
11507
11508 // If context.method was "throw" but the delegate handled the
11509 // exception, let the outer generator proceed normally. If
11510 // context.method was "next", forget context.arg since it has been
11511 // "consumed" by the delegate iterator. If context.method was
11512 // "return", allow the original .return call to continue in the
11513 // outer generator.
11514 if (context.method !== "return") {
11515 context.method = "next";
11516 context.arg = undefined$1;
11517 }
11518
11519 } else {
11520 // Re-yield the result returned by the delegate method.
11521 return info;
11522 }
11523
11524 // The delegate iterator is finished, so forget it and continue with
11525 // the outer generator.
11526 context.delegate = null;
11527 return ContinueSentinel;
11528 }
11529
11530 // Define Generator.prototype.{next,throw,return} in terms of the
11531 // unified ._invoke helper method.
11532 defineIteratorMethods(Gp);
11533
11534 Gp[toStringTagSymbol] = "Generator";
11535
11536 // A Generator should always return itself as the iterator object when the
11537 // @@iterator function is called on it. Some browsers' implementations of the
11538 // iterator prototype chain incorrectly implement this, causing the Generator
11539 // object to not be returned from this call. This ensures that doesn't happen.
11540 // See https://github.com/facebook/regenerator/issues/274 for more details.
11541 Gp[iteratorSymbol] = function() {
11542 return this;
11543 };
11544
11545 Gp.toString = function() {
11546 return "[object Generator]";
11547 };
11548
11549 function pushTryEntry(locs) {
11550 var entry = { tryLoc: locs[0] };
11551
11552 if (1 in locs) {
11553 entry.catchLoc = locs[1];
11554 }
11555
11556 if (2 in locs) {
11557 entry.finallyLoc = locs[2];
11558 entry.afterLoc = locs[3];
11559 }
11560
11561 this.tryEntries.push(entry);
11562 }
11563
11564 function resetTryEntry(entry) {
11565 var record = entry.completion || {};
11566 record.type = "normal";
11567 delete record.arg;
11568 entry.completion = record;
11569 }
11570
11571 function Context(tryLocsList) {
11572 // The root entry object (effectively a try statement without a catch
11573 // or a finally block) gives us a place to store values thrown from
11574 // locations where there is no enclosing try statement.
11575 this.tryEntries = [{ tryLoc: "root" }];
11576 tryLocsList.forEach(pushTryEntry, this);
11577 this.reset(true);
11578 }
11579
11580 exports.keys = function(object) {
11581 var keys = [];
11582 for (var key in object) {
11583 keys.push(key);
11584 }
11585 keys.reverse();
11586
11587 // Rather than returning an object with a next method, we keep
11588 // things simple and return the next function itself.
11589 return function next() {
11590 while (keys.length) {
11591 var key = keys.pop();
11592 if (key in object) {
11593 next.value = key;
11594 next.done = false;
11595 return next;
11596 }
11597 }
11598
11599 // To avoid creating an additional object, we just hang the .value
11600 // and .done properties off the next function object itself. This
11601 // also ensures that the minifier will not anonymize the function.
11602 next.done = true;
11603 return next;
11604 };
11605 };
11606
11607 function values(iterable) {
11608 if (iterable) {
11609 var iteratorMethod = iterable[iteratorSymbol];
11610 if (iteratorMethod) {
11611 return iteratorMethod.call(iterable);
11612 }
11613
11614 if (typeof iterable.next === "function") {
11615 return iterable;
11616 }
11617
11618 if (!isNaN(iterable.length)) {
11619 var i = -1, next = function next() {
11620 while (++i < iterable.length) {
11621 if (hasOwn.call(iterable, i)) {
11622 next.value = iterable[i];
11623 next.done = false;
11624 return next;
11625 }
11626 }
11627
11628 next.value = undefined$1;
11629 next.done = true;
11630
11631 return next;
11632 };
11633
11634 return next.next = next;
11635 }
11636 }
11637
11638 // Return an iterator with no values.
11639 return { next: doneResult };
11640 }
11641 exports.values = values;
11642
11643 function doneResult() {
11644 return { value: undefined$1, done: true };
11645 }
11646
11647 Context.prototype = {
11648 constructor: Context,
11649
11650 reset: function(skipTempReset) {
11651 this.prev = 0;
11652 this.next = 0;
11653 // Resetting context._sent for legacy support of Babel's
11654 // function.sent implementation.
11655 this.sent = this._sent = undefined$1;
11656 this.done = false;
11657 this.delegate = null;
11658
11659 this.method = "next";
11660 this.arg = undefined$1;
11661
11662 this.tryEntries.forEach(resetTryEntry);
11663
11664 if (!skipTempReset) {
11665 for (var name in this) {
11666 // Not sure about the optimal order of these conditions:
11667 if (name.charAt(0) === "t" &&
11668 hasOwn.call(this, name) &&
11669 !isNaN(+name.slice(1))) {
11670 this[name] = undefined$1;
11671 }
11672 }
11673 }
11674 },
11675
11676 stop: function() {
11677 this.done = true;
11678
11679 var rootEntry = this.tryEntries[0];
11680 var rootRecord = rootEntry.completion;
11681 if (rootRecord.type === "throw") {
11682 throw rootRecord.arg;
11683 }
11684
11685 return this.rval;
11686 },
11687
11688 dispatchException: function(exception) {
11689 if (this.done) {
11690 throw exception;
11691 }
11692
11693 var context = this;
11694 function handle(loc, caught) {
11695 record.type = "throw";
11696 record.arg = exception;
11697 context.next = loc;
11698
11699 if (caught) {
11700 // If the dispatched exception was caught by a catch block,
11701 // then let that catch block handle the exception normally.
11702 context.method = "next";
11703 context.arg = undefined$1;
11704 }
11705
11706 return !! caught;
11707 }
11708
11709 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
11710 var entry = this.tryEntries[i];
11711 var record = entry.completion;
11712
11713 if (entry.tryLoc === "root") {
11714 // Exception thrown outside of any try block that could handle
11715 // it, so set the completion value of the entire function to
11716 // throw the exception.
11717 return handle("end");
11718 }
11719
11720 if (entry.tryLoc <= this.prev) {
11721 var hasCatch = hasOwn.call(entry, "catchLoc");
11722 var hasFinally = hasOwn.call(entry, "finallyLoc");
11723
11724 if (hasCatch && hasFinally) {
11725 if (this.prev < entry.catchLoc) {
11726 return handle(entry.catchLoc, true);
11727 } else if (this.prev < entry.finallyLoc) {
11728 return handle(entry.finallyLoc);
11729 }
11730
11731 } else if (hasCatch) {
11732 if (this.prev < entry.catchLoc) {
11733 return handle(entry.catchLoc, true);
11734 }
11735
11736 } else if (hasFinally) {
11737 if (this.prev < entry.finallyLoc) {
11738 return handle(entry.finallyLoc);
11739 }
11740
11741 } else {
11742 throw new Error("try statement without catch or finally");
11743 }
11744 }
11745 }
11746 },
11747
11748 abrupt: function(type, arg) {
11749 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
11750 var entry = this.tryEntries[i];
11751 if (entry.tryLoc <= this.prev &&
11752 hasOwn.call(entry, "finallyLoc") &&
11753 this.prev < entry.finallyLoc) {
11754 var finallyEntry = entry;
11755 break;
11756 }
11757 }
11758
11759 if (finallyEntry &&
11760 (type === "break" ||
11761 type === "continue") &&
11762 finallyEntry.tryLoc <= arg &&
11763 arg <= finallyEntry.finallyLoc) {
11764 // Ignore the finally entry if control is not jumping to a
11765 // location outside the try/catch block.
11766 finallyEntry = null;
11767 }
11768
11769 var record = finallyEntry ? finallyEntry.completion : {};
11770 record.type = type;
11771 record.arg = arg;
11772
11773 if (finallyEntry) {
11774 this.method = "next";
11775 this.next = finallyEntry.finallyLoc;
11776 return ContinueSentinel;
11777 }
11778
11779 return this.complete(record);
11780 },
11781
11782 complete: function(record, afterLoc) {
11783 if (record.type === "throw") {
11784 throw record.arg;
11785 }
11786
11787 if (record.type === "break" ||
11788 record.type === "continue") {
11789 this.next = record.arg;
11790 } else if (record.type === "return") {
11791 this.rval = this.arg = record.arg;
11792 this.method = "return";
11793 this.next = "end";
11794 } else if (record.type === "normal" && afterLoc) {
11795 this.next = afterLoc;
11796 }
11797
11798 return ContinueSentinel;
11799 },
11800
11801 finish: function(finallyLoc) {
11802 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
11803 var entry = this.tryEntries[i];
11804 if (entry.finallyLoc === finallyLoc) {
11805 this.complete(entry.completion, entry.afterLoc);
11806 resetTryEntry(entry);
11807 return ContinueSentinel;
11808 }
11809 }
11810 },
11811
11812 "catch": function(tryLoc) {
11813 for (var i = this.tryEntries.length - 1; i >= 0; --i) {
11814 var entry = this.tryEntries[i];
11815 if (entry.tryLoc === tryLoc) {
11816 var record = entry.completion;
11817 if (record.type === "throw") {
11818 var thrown = record.arg;
11819 resetTryEntry(entry);
11820 }
11821 return thrown;
11822 }
11823 }
11824
11825 // The context.catch method must only be called with a location
11826 // argument that corresponds to a known catch block.
11827 throw new Error("illegal catch attempt");
11828 },
11829
11830 delegateYield: function(iterable, resultName, nextLoc) {
11831 this.delegate = {
11832 iterator: values(iterable),
11833 resultName: resultName,
11834 nextLoc: nextLoc
11835 };
11836
11837 if (this.method === "next") {
11838 // Deliberately forget the last sent value so that we don't
11839 // accidentally pass it on to the delegate.
11840 this.arg = undefined$1;
11841 }
11842
11843 return ContinueSentinel;
11844 }
11845 };
11846
11847 // Regardless of whether this script is executing as a CommonJS module
11848 // or not, return the runtime object so that we can declare the variable
11849 // regeneratorRuntime in the outer scope, which allows this module to be
11850 // injected easily by `bin/regenerator --include-runtime script.js`.
11851 return exports;
11852
11853 }(
11854 // If this script is executing as a CommonJS module, use module.exports
11855 // as the regeneratorRuntime namespace. Otherwise create a new empty
11856 // object. Either way, the resulting object will be used to initialize
11857 // the regeneratorRuntime variable at the top of this file.
11858 module.exports
11859 ));
11860
11861 try {
11862 regeneratorRuntime = runtime;
11863 } catch (accidentalStrictMode) {
11864 // This module should not be running in strict mode, so the above
11865 // assignment should always work unless something is misconfigured. Just
11866 // in case runtime.js accidentally runs in strict mode, we can escape
11867 // strict mode using a global Function call. This could conceivably fail
11868 // if a Content Security Policy forbids using Function, but in that case
11869 // the proper solution is to fix the accidental strict mode problem. If
11870 // you've misconfigured your bundler to force strict mode and applied a
11871 // CSP to forbid Function, and you're not willing to fix either of those
11872 // problems, please detail your unique predicament in a GitHub issue.
11873 Function("r", "regeneratorRuntime = r")(runtime);
11874 }
11875 });
11876
11877 var regenerator = runtime_1;
11878
11879 function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
11880 try {
11881 var info = gen[key](arg);
11882 var value = info.value;
11883 } catch (error) {
11884 reject(error);
11885 return;
11886 }
11887
11888 if (info.done) {
11889 resolve(value);
11890 } else {
11891 Promise.resolve(value).then(_next, _throw);
11892 }
11893 }
11894
11895 function _asyncToGenerator(fn) {
11896 return function () {
11897 var self = this,
11898 args = arguments;
11899 return new Promise(function (resolve, reject) {
11900 var gen = fn.apply(self, args);
11901
11902 function _next(value) {
11903 asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
11904 }
11905
11906 function _throw(err) {
11907 asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
11908 }
11909
11910 _next(undefined);
11911 });
11912 };
11913 }
11914
11915 var asyncToGenerator = _asyncToGenerator;
11916
11917 function _arrayLikeToArray(arr, len) {
11918 if (len == null || len > arr.length) len = arr.length;
11919
11920 for (var i = 0, arr2 = new Array(len); i < len; i++) {
11921 arr2[i] = arr[i];
11922 }
11923
11924 return arr2;
11925 }
11926
11927 var arrayLikeToArray = _arrayLikeToArray;
11928
11929 function _arrayWithoutHoles(arr) {
11930 if (Array.isArray(arr)) return arrayLikeToArray(arr);
11931 }
11932
11933 var arrayWithoutHoles = _arrayWithoutHoles;
11934
11935 function _iterableToArray(iter) {
11936 if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter);
11937 }
11938
11939 var iterableToArray = _iterableToArray;
11940
11941 function _unsupportedIterableToArray(o, minLen) {
11942 if (!o) return;
11943 if (typeof o === "string") return arrayLikeToArray(o, minLen);
11944 var n = Object.prototype.toString.call(o).slice(8, -1);
11945 if (n === "Object" && o.constructor) n = o.constructor.name;
11946 if (n === "Map" || n === "Set") return Array.from(o);
11947 if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);
11948 }
11949
11950 var unsupportedIterableToArray = _unsupportedIterableToArray;
11951
11952 function _nonIterableSpread() {
11953 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
11954 }
11955
11956 var nonIterableSpread = _nonIterableSpread;
11957
11958 function _toConsumableArray(arr) {
11959 return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();
11960 }
11961
11962 var toConsumableArray = _toConsumableArray;
11963
11964 function _objectWithoutPropertiesLoose(source, excluded) {
11965 if (source == null) return {};
11966 var target = {};
11967 var sourceKeys = Object.keys(source);
11968 var key, i;
11969
11970 for (i = 0; i < sourceKeys.length; i++) {
11971 key = sourceKeys[i];
11972 if (excluded.indexOf(key) >= 0) continue;
11973 target[key] = source[key];
11974 }
11975
11976 return target;
11977 }
11978
11979 var objectWithoutPropertiesLoose = _objectWithoutPropertiesLoose;
11980
11981 function _objectWithoutProperties(source, excluded) {
11982 if (source == null) return {};
11983 var target = objectWithoutPropertiesLoose(source, excluded);
11984 var key, i;
11985
11986 if (Object.getOwnPropertySymbols) {
11987 var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
11988
11989 for (i = 0; i < sourceSymbolKeys.length; i++) {
11990 key = sourceSymbolKeys[i];
11991 if (excluded.indexOf(key) >= 0) continue;
11992 if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
11993 target[key] = source[key];
11994 }
11995 }
11996
11997 return target;
11998 }
11999
12000 var objectWithoutProperties = _objectWithoutProperties;
12001
12002 function _assertThisInitialized(self) {
12003 if (self === void 0) {
12004 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
12005 }
12006
12007 return self;
12008 }
12009
12010 var assertThisInitialized = _assertThisInitialized;
12011
12012 function _inheritsLoose(subClass, superClass) {
12013 subClass.prototype = Object.create(superClass.prototype);
12014 subClass.prototype.constructor = subClass;
12015 subClass.__proto__ = superClass;
12016 }
12017
12018 var inheritsLoose = _inheritsLoose;
12019
12020 /**
12021 * Helpers.
12022 */
12023
12024 var s = 1000;
12025 var m = s * 60;
12026 var h = m * 60;
12027 var d = h * 24;
12028 var w = d * 7;
12029 var y = d * 365.25;
12030
12031 /**
12032 * Parse or format the given `val`.
12033 *
12034 * Options:
12035 *
12036 * - `long` verbose formatting [false]
12037 *
12038 * @param {String|Number} val
12039 * @param {Object} [options]
12040 * @throws {Error} throw an error if val is not a non-empty string or a number
12041 * @return {String|Number}
12042 * @api public
12043 */
12044
12045 var ms = function(val, options) {
12046 options = options || {};
12047 var type = typeof val;
12048 if (type === 'string' && val.length > 0) {
12049 return parse(val);
12050 } else if (type === 'number' && isNaN(val) === false) {
12051 return options.long ? fmtLong(val) : fmtShort(val);
12052 }
12053 throw new Error(
12054 'val is not a non-empty string or a valid number. val=' +
12055 JSON.stringify(val)
12056 );
12057 };
12058
12059 /**
12060 * Parse the given `str` and return milliseconds.
12061 *
12062 * @param {String} str
12063 * @return {Number}
12064 * @api private
12065 */
12066
12067 function parse(str) {
12068 str = String(str);
12069 if (str.length > 100) {
12070 return;
12071 }
12072 var match = /^((?:\d+)?\-?\d?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
12073 str
12074 );
12075 if (!match) {
12076 return;
12077 }
12078 var n = parseFloat(match[1]);
12079 var type = (match[2] || 'ms').toLowerCase();
12080 switch (type) {
12081 case 'years':
12082 case 'year':
12083 case 'yrs':
12084 case 'yr':
12085 case 'y':
12086 return n * y;
12087 case 'weeks':
12088 case 'week':
12089 case 'w':
12090 return n * w;
12091 case 'days':
12092 case 'day':
12093 case 'd':
12094 return n * d;
12095 case 'hours':
12096 case 'hour':
12097 case 'hrs':
12098 case 'hr':
12099 case 'h':
12100 return n * h;
12101 case 'minutes':
12102 case 'minute':
12103 case 'mins':
12104 case 'min':
12105 case 'm':
12106 return n * m;
12107 case 'seconds':
12108 case 'second':
12109 case 'secs':
12110 case 'sec':
12111 case 's':
12112 return n * s;
12113 case 'milliseconds':
12114 case 'millisecond':
12115 case 'msecs':
12116 case 'msec':
12117 case 'ms':
12118 return n;
12119 default:
12120 return undefined;
12121 }
12122 }
12123
12124 /**
12125 * Short format for `ms`.
12126 *
12127 * @param {Number} ms
12128 * @return {String}
12129 * @api private
12130 */
12131
12132 function fmtShort(ms) {
12133 var msAbs = Math.abs(ms);
12134 if (msAbs >= d) {
12135 return Math.round(ms / d) + 'd';
12136 }
12137 if (msAbs >= h) {
12138 return Math.round(ms / h) + 'h';
12139 }
12140 if (msAbs >= m) {
12141 return Math.round(ms / m) + 'm';
12142 }
12143 if (msAbs >= s) {
12144 return Math.round(ms / s) + 's';
12145 }
12146 return ms + 'ms';
12147 }
12148
12149 /**
12150 * Long format for `ms`.
12151 *
12152 * @param {Number} ms
12153 * @return {String}
12154 * @api private
12155 */
12156
12157 function fmtLong(ms) {
12158 var msAbs = Math.abs(ms);
12159 if (msAbs >= d) {
12160 return plural(ms, msAbs, d, 'day');
12161 }
12162 if (msAbs >= h) {
12163 return plural(ms, msAbs, h, 'hour');
12164 }
12165 if (msAbs >= m) {
12166 return plural(ms, msAbs, m, 'minute');
12167 }
12168 if (msAbs >= s) {
12169 return plural(ms, msAbs, s, 'second');
12170 }
12171 return ms + ' ms';
12172 }
12173
12174 /**
12175 * Pluralization helper.
12176 */
12177
12178 function plural(ms, msAbs, n, name) {
12179 var isPlural = msAbs >= n * 1.5;
12180 return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
12181 }
12182
12183 /**
12184 * This is the common logic for both the Node.js and web browser
12185 * implementations of `debug()`.
12186 */
12187 function setup(env) {
12188 createDebug.debug = createDebug;
12189 createDebug.default = createDebug;
12190 createDebug.coerce = coerce;
12191 createDebug.disable = disable;
12192 createDebug.enable = enable;
12193 createDebug.enabled = enabled;
12194 createDebug.humanize = ms;
12195 Object.keys(env).forEach(function (key) {
12196 createDebug[key] = env[key];
12197 });
12198 /**
12199 * Active `debug` instances.
12200 */
12201
12202 createDebug.instances = [];
12203 /**
12204 * The currently active debug mode names, and names to skip.
12205 */
12206
12207 createDebug.names = [];
12208 createDebug.skips = [];
12209 /**
12210 * Map of special "%n" handling functions, for the debug "format" argument.
12211 *
12212 * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
12213 */
12214
12215 createDebug.formatters = {};
12216 /**
12217 * Selects a color for a debug namespace
12218 * @param {String} namespace The namespace string for the for the debug instance to be colored
12219 * @return {Number|String} An ANSI color code for the given namespace
12220 * @api private
12221 */
12222
12223 function selectColor(namespace) {
12224 var hash = 0;
12225
12226 for (var i = 0; i < namespace.length; i++) {
12227 hash = (hash << 5) - hash + namespace.charCodeAt(i);
12228 hash |= 0; // Convert to 32bit integer
12229 }
12230
12231 return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
12232 }
12233
12234 createDebug.selectColor = selectColor;
12235 /**
12236 * Create a debugger with the given `namespace`.
12237 *
12238 * @param {String} namespace
12239 * @return {Function}
12240 * @api public
12241 */
12242
12243 function createDebug(namespace) {
12244 var prevTime;
12245
12246 function debug() {
12247 // Disabled?
12248 if (!debug.enabled) {
12249 return;
12250 }
12251
12252 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
12253 args[_key] = arguments[_key];
12254 }
12255
12256 var self = debug; // Set `diff` timestamp
12257
12258 var curr = Number(new Date());
12259 var ms = curr - (prevTime || curr);
12260 self.diff = ms;
12261 self.prev = prevTime;
12262 self.curr = curr;
12263 prevTime = curr;
12264 args[0] = createDebug.coerce(args[0]);
12265
12266 if (typeof args[0] !== 'string') {
12267 // Anything else let's inspect with %O
12268 args.unshift('%O');
12269 } // Apply any `formatters` transformations
12270
12271
12272 var index = 0;
12273 args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) {
12274 // If we encounter an escaped % then don't increase the array index
12275 if (match === '%%') {
12276 return match;
12277 }
12278
12279 index++;
12280 var formatter = createDebug.formatters[format];
12281
12282 if (typeof formatter === 'function') {
12283 var val = args[index];
12284 match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format`
12285
12286 args.splice(index, 1);
12287 index--;
12288 }
12289
12290 return match;
12291 }); // Apply env-specific formatting (colors, etc.)
12292
12293 createDebug.formatArgs.call(self, args);
12294 var logFn = self.log || createDebug.log;
12295 logFn.apply(self, args);
12296 }
12297
12298 debug.namespace = namespace;
12299 debug.enabled = createDebug.enabled(namespace);
12300 debug.useColors = createDebug.useColors();
12301 debug.color = selectColor(namespace);
12302 debug.destroy = destroy;
12303 debug.extend = extend; // Debug.formatArgs = formatArgs;
12304 // debug.rawLog = rawLog;
12305 // env-specific initialization logic for debug instances
12306
12307 if (typeof createDebug.init === 'function') {
12308 createDebug.init(debug);
12309 }
12310
12311 createDebug.instances.push(debug);
12312 return debug;
12313 }
12314
12315 function destroy() {
12316 var index = createDebug.instances.indexOf(this);
12317
12318 if (index !== -1) {
12319 createDebug.instances.splice(index, 1);
12320 return true;
12321 }
12322
12323 return false;
12324 }
12325
12326 function extend(namespace, delimiter) {
12327 return createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
12328 }
12329 /**
12330 * Enables a debug mode by namespaces. This can include modes
12331 * separated by a colon and wildcards.
12332 *
12333 * @param {String} namespaces
12334 * @api public
12335 */
12336
12337
12338 function enable(namespaces) {
12339 createDebug.save(namespaces);
12340 createDebug.names = [];
12341 createDebug.skips = [];
12342 var i;
12343 var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
12344 var len = split.length;
12345
12346 for (i = 0; i < len; i++) {
12347 if (!split[i]) {
12348 // ignore empty strings
12349 continue;
12350 }
12351
12352 namespaces = split[i].replace(/\*/g, '.*?');
12353
12354 if (namespaces[0] === '-') {
12355 createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));
12356 } else {
12357 createDebug.names.push(new RegExp('^' + namespaces + '$'));
12358 }
12359 }
12360
12361 for (i = 0; i < createDebug.instances.length; i++) {
12362 var instance = createDebug.instances[i];
12363 instance.enabled = createDebug.enabled(instance.namespace);
12364 }
12365 }
12366 /**
12367 * Disable debug output.
12368 *
12369 * @api public
12370 */
12371
12372
12373 function disable() {
12374 createDebug.enable('');
12375 }
12376 /**
12377 * Returns true if the given mode name is enabled, false otherwise.
12378 *
12379 * @param {String} name
12380 * @return {Boolean}
12381 * @api public
12382 */
12383
12384
12385 function enabled(name) {
12386 if (name[name.length - 1] === '*') {
12387 return true;
12388 }
12389
12390 var i;
12391 var len;
12392
12393 for (i = 0, len = createDebug.skips.length; i < len; i++) {
12394 if (createDebug.skips[i].test(name)) {
12395 return false;
12396 }
12397 }
12398
12399 for (i = 0, len = createDebug.names.length; i < len; i++) {
12400 if (createDebug.names[i].test(name)) {
12401 return true;
12402 }
12403 }
12404
12405 return false;
12406 }
12407 /**
12408 * Coerce `val`.
12409 *
12410 * @param {Mixed} val
12411 * @return {Mixed}
12412 * @api private
12413 */
12414
12415
12416 function coerce(val) {
12417 if (val instanceof Error) {
12418 return val.stack || val.message;
12419 }
12420
12421 return val;
12422 }
12423
12424 createDebug.enable(createDebug.load());
12425 return createDebug;
12426 }
12427
12428 var common = setup;
12429
12430 var browser = createCommonjsModule(function (module, exports) {
12431
12432 function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
12433
12434 /* eslint-env browser */
12435
12436 /**
12437 * This is the web browser implementation of `debug()`.
12438 */
12439 exports.log = log;
12440 exports.formatArgs = formatArgs;
12441 exports.save = save;
12442 exports.load = load;
12443 exports.useColors = useColors;
12444 exports.storage = localstorage();
12445 /**
12446 * Colors.
12447 */
12448
12449 exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33'];
12450 /**
12451 * Currently only WebKit-based Web Inspectors, Firefox >= v31,
12452 * and the Firebug extension (any Firefox version) are known
12453 * to support "%c" CSS customizations.
12454 *
12455 * TODO: add a `localStorage` variable to explicitly enable/disable colors
12456 */
12457 // eslint-disable-next-line complexity
12458
12459 function useColors() {
12460 // NB: In an Electron preload script, document will be defined but not fully
12461 // initialized. Since we know we're in Chrome, we'll just detect this case
12462 // explicitly
12463 if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
12464 return true;
12465 } // Internet Explorer and Edge do not support colors.
12466
12467
12468 if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
12469 return false;
12470 } // Is webkit? http://stackoverflow.com/a/16459606/376773
12471 // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
12472
12473
12474 return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773
12475 typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31?
12476 // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
12477 typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker
12478 typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/);
12479 }
12480 /**
12481 * Colorize log arguments if enabled.
12482 *
12483 * @api public
12484 */
12485
12486
12487 function formatArgs(args) {
12488 args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff);
12489
12490 if (!this.useColors) {
12491 return;
12492 }
12493
12494 var c = 'color: ' + this.color;
12495 args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other
12496 // arguments passed either before or after the %c, so we need to
12497 // figure out the correct index to insert the CSS into
12498
12499 var index = 0;
12500 var lastC = 0;
12501 args[0].replace(/%[a-zA-Z%]/g, function (match) {
12502 if (match === '%%') {
12503 return;
12504 }
12505
12506 index++;
12507
12508 if (match === '%c') {
12509 // We only are interested in the *last* %c
12510 // (the user may have provided their own)
12511 lastC = index;
12512 }
12513 });
12514 args.splice(lastC, 0, c);
12515 }
12516 /**
12517 * Invokes `console.log()` when available.
12518 * No-op when `console.log` is not a "function".
12519 *
12520 * @api public
12521 */
12522
12523
12524 function log() {
12525 var _console;
12526
12527 // This hackery is required for IE8/9, where
12528 // the `console.log` function doesn't have 'apply'
12529 return (typeof console === "undefined" ? "undefined" : _typeof(console)) === 'object' && console.log && (_console = console).log.apply(_console, arguments);
12530 }
12531 /**
12532 * Save `namespaces`.
12533 *
12534 * @param {String} namespaces
12535 * @api private
12536 */
12537
12538
12539 function save(namespaces) {
12540 try {
12541 if (namespaces) {
12542 exports.storage.setItem('debug', namespaces);
12543 } else {
12544 exports.storage.removeItem('debug');
12545 }
12546 } catch (error) {// Swallow
12547 // XXX (@Qix-) should we be logging these?
12548 }
12549 }
12550 /**
12551 * Load `namespaces`.
12552 *
12553 * @return {String} returns the previously persisted debug modes
12554 * @api private
12555 */
12556
12557
12558 function load() {
12559 var r;
12560
12561 try {
12562 r = exports.storage.getItem('debug');
12563 } catch (error) {} // Swallow
12564 // XXX (@Qix-) should we be logging these?
12565 // If debug isn't set in LS, and we're in Electron, try to load $DEBUG
12566
12567
12568 if (!r && typeof process !== 'undefined' && 'env' in process) {
12569 r = process.env.DEBUG;
12570 }
12571
12572 return r;
12573 }
12574 /**
12575 * Localstorage attempts to return the localstorage.
12576 *
12577 * This is necessary because safari throws
12578 * when a user disables cookies/localstorage
12579 * and you attempt to access it.
12580 *
12581 * @return {LocalStorage}
12582 * @api private
12583 */
12584
12585
12586 function localstorage() {
12587 try {
12588 // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
12589 // The Browser also has localStorage in the global context.
12590 return localStorage;
12591 } catch (error) {// Swallow
12592 // XXX (@Qix-) should we be logging these?
12593 }
12594 }
12595
12596 module.exports = common(exports);
12597 var formatters = module.exports.formatters;
12598 /**
12599 * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
12600 */
12601
12602 formatters.j = function (v) {
12603 try {
12604 return JSON.stringify(v);
12605 } catch (error) {
12606 return '[UnexpectedJSONParseError]: ' + error.message;
12607 }
12608 };
12609 });
12610 var browser_1 = browser.log;
12611 var browser_2 = browser.formatArgs;
12612 var browser_3 = browser.save;
12613 var browser_4 = browser.load;
12614 var browser_5 = browser.useColors;
12615 var browser_6 = browser.storage;
12616 var browser_7 = browser.colors;
12617
12618 /**
12619 * Copies the values of `source` to `array`.
12620 *
12621 * @private
12622 * @param {Array} source The array to copy values from.
12623 * @param {Array} [array=[]] The array to copy values to.
12624 * @returns {Array} Returns `array`.
12625 */
12626 function copyArray(source, array) {
12627 var index = -1,
12628 length = source.length;
12629
12630 array || (array = Array(length));
12631 while (++index < length) {
12632 array[index] = source[index];
12633 }
12634 return array;
12635 }
12636
12637 var _copyArray = copyArray;
12638
12639 /* Built-in method references for those with the same name as other `lodash` methods. */
12640 var nativeFloor = Math.floor,
12641 nativeRandom = Math.random;
12642
12643 /**
12644 * The base implementation of `_.random` without support for returning
12645 * floating-point numbers.
12646 *
12647 * @private
12648 * @param {number} lower The lower bound.
12649 * @param {number} upper The upper bound.
12650 * @returns {number} Returns the random number.
12651 */
12652 function baseRandom(lower, upper) {
12653 return lower + nativeFloor(nativeRandom() * (upper - lower + 1));
12654 }
12655
12656 var _baseRandom = baseRandom;
12657
12658 /**
12659 * A specialized version of `_.shuffle` which mutates and sets the size of `array`.
12660 *
12661 * @private
12662 * @param {Array} array The array to shuffle.
12663 * @param {number} [size=array.length] The size of `array`.
12664 * @returns {Array} Returns `array`.
12665 */
12666 function shuffleSelf(array, size) {
12667 var index = -1,
12668 length = array.length,
12669 lastIndex = length - 1;
12670
12671 size = size === undefined ? length : size;
12672 while (++index < size) {
12673 var rand = _baseRandom(index, lastIndex),
12674 value = array[rand];
12675
12676 array[rand] = array[index];
12677 array[index] = value;
12678 }
12679 array.length = size;
12680 return array;
12681 }
12682
12683 var _shuffleSelf = shuffleSelf;
12684
12685 /**
12686 * A specialized version of `_.shuffle` for arrays.
12687 *
12688 * @private
12689 * @param {Array} array The array to shuffle.
12690 * @returns {Array} Returns the new shuffled array.
12691 */
12692 function arrayShuffle(array) {
12693 return _shuffleSelf(_copyArray(array));
12694 }
12695
12696 var _arrayShuffle = arrayShuffle;
12697
12698 /**
12699 * A specialized version of `_.map` for arrays without support for iteratee
12700 * shorthands.
12701 *
12702 * @private
12703 * @param {Array} [array] The array to iterate over.
12704 * @param {Function} iteratee The function invoked per iteration.
12705 * @returns {Array} Returns the new mapped array.
12706 */
12707 function arrayMap(array, iteratee) {
12708 var index = -1,
12709 length = array == null ? 0 : array.length,
12710 result = Array(length);
12711
12712 while (++index < length) {
12713 result[index] = iteratee(array[index], index, array);
12714 }
12715 return result;
12716 }
12717
12718 var _arrayMap = arrayMap;
12719
12720 /**
12721 * The base implementation of `_.values` and `_.valuesIn` which creates an
12722 * array of `object` property values corresponding to the property names
12723 * of `props`.
12724 *
12725 * @private
12726 * @param {Object} object The object to query.
12727 * @param {Array} props The property names to get values for.
12728 * @returns {Object} Returns the array of property values.
12729 */
12730 function baseValues(object, props) {
12731 return _arrayMap(props, function(key) {
12732 return object[key];
12733 });
12734 }
12735
12736 var _baseValues = baseValues;
12737
12738 /**
12739 * The base implementation of `_.times` without support for iteratee shorthands
12740 * or max array length checks.
12741 *
12742 * @private
12743 * @param {number} n The number of times to invoke `iteratee`.
12744 * @param {Function} iteratee The function invoked per iteration.
12745 * @returns {Array} Returns the array of results.
12746 */
12747 function baseTimes(n, iteratee) {
12748 var index = -1,
12749 result = Array(n);
12750
12751 while (++index < n) {
12752 result[index] = iteratee(index);
12753 }
12754 return result;
12755 }
12756
12757 var _baseTimes = baseTimes;
12758
12759 /** Detect free variable `global` from Node.js. */
12760 var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
12761
12762 var _freeGlobal = freeGlobal;
12763
12764 /** Detect free variable `self`. */
12765 var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
12766
12767 /** Used as a reference to the global object. */
12768 var root = _freeGlobal || freeSelf || Function('return this')();
12769
12770 var _root = root;
12771
12772 /** Built-in value references. */
12773 var Symbol$1 = _root.Symbol;
12774
12775 var _Symbol = Symbol$1;
12776
12777 /** Used for built-in method references. */
12778 var objectProto = Object.prototype;
12779
12780 /** Used to check objects for own properties. */
12781 var hasOwnProperty = objectProto.hasOwnProperty;
12782
12783 /**
12784 * Used to resolve the
12785 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
12786 * of values.
12787 */
12788 var nativeObjectToString = objectProto.toString;
12789
12790 /** Built-in value references. */
12791 var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined;
12792
12793 /**
12794 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
12795 *
12796 * @private
12797 * @param {*} value The value to query.
12798 * @returns {string} Returns the raw `toStringTag`.
12799 */
12800 function getRawTag(value) {
12801 var isOwn = hasOwnProperty.call(value, symToStringTag),
12802 tag = value[symToStringTag];
12803
12804 try {
12805 value[symToStringTag] = undefined;
12806 var unmasked = true;
12807 } catch (e) {}
12808
12809 var result = nativeObjectToString.call(value);
12810 if (unmasked) {
12811 if (isOwn) {
12812 value[symToStringTag] = tag;
12813 } else {
12814 delete value[symToStringTag];
12815 }
12816 }
12817 return result;
12818 }
12819
12820 var _getRawTag = getRawTag;
12821
12822 /** Used for built-in method references. */
12823 var objectProto$1 = Object.prototype;
12824
12825 /**
12826 * Used to resolve the
12827 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
12828 * of values.
12829 */
12830 var nativeObjectToString$1 = objectProto$1.toString;
12831
12832 /**
12833 * Converts `value` to a string using `Object.prototype.toString`.
12834 *
12835 * @private
12836 * @param {*} value The value to convert.
12837 * @returns {string} Returns the converted string.
12838 */
12839 function objectToString(value) {
12840 return nativeObjectToString$1.call(value);
12841 }
12842
12843 var _objectToString = objectToString;
12844
12845 /** `Object#toString` result references. */
12846 var nullTag = '[object Null]',
12847 undefinedTag = '[object Undefined]';
12848
12849 /** Built-in value references. */
12850 var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined;
12851
12852 /**
12853 * The base implementation of `getTag` without fallbacks for buggy environments.
12854 *
12855 * @private
12856 * @param {*} value The value to query.
12857 * @returns {string} Returns the `toStringTag`.
12858 */
12859 function baseGetTag(value) {
12860 if (value == null) {
12861 return value === undefined ? undefinedTag : nullTag;
12862 }
12863 return (symToStringTag$1 && symToStringTag$1 in Object(value))
12864 ? _getRawTag(value)
12865 : _objectToString(value);
12866 }
12867
12868 var _baseGetTag = baseGetTag;
12869
12870 /**
12871 * Checks if `value` is object-like. A value is object-like if it's not `null`
12872 * and has a `typeof` result of "object".
12873 *
12874 * @static
12875 * @memberOf _
12876 * @since 4.0.0
12877 * @category Lang
12878 * @param {*} value The value to check.
12879 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
12880 * @example
12881 *
12882 * _.isObjectLike({});
12883 * // => true
12884 *
12885 * _.isObjectLike([1, 2, 3]);
12886 * // => true
12887 *
12888 * _.isObjectLike(_.noop);
12889 * // => false
12890 *
12891 * _.isObjectLike(null);
12892 * // => false
12893 */
12894 function isObjectLike(value) {
12895 return value != null && typeof value == 'object';
12896 }
12897
12898 var isObjectLike_1 = isObjectLike;
12899
12900 /** `Object#toString` result references. */
12901 var argsTag = '[object Arguments]';
12902
12903 /**
12904 * The base implementation of `_.isArguments`.
12905 *
12906 * @private
12907 * @param {*} value The value to check.
12908 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
12909 */
12910 function baseIsArguments(value) {
12911 return isObjectLike_1(value) && _baseGetTag(value) == argsTag;
12912 }
12913
12914 var _baseIsArguments = baseIsArguments;
12915
12916 /** Used for built-in method references. */
12917 var objectProto$2 = Object.prototype;
12918
12919 /** Used to check objects for own properties. */
12920 var hasOwnProperty$1 = objectProto$2.hasOwnProperty;
12921
12922 /** Built-in value references. */
12923 var propertyIsEnumerable = objectProto$2.propertyIsEnumerable;
12924
12925 /**
12926 * Checks if `value` is likely an `arguments` object.
12927 *
12928 * @static
12929 * @memberOf _
12930 * @since 0.1.0
12931 * @category Lang
12932 * @param {*} value The value to check.
12933 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
12934 * else `false`.
12935 * @example
12936 *
12937 * _.isArguments(function() { return arguments; }());
12938 * // => true
12939 *
12940 * _.isArguments([1, 2, 3]);
12941 * // => false
12942 */
12943 var isArguments = _baseIsArguments(function() { return arguments; }()) ? _baseIsArguments : function(value) {
12944 return isObjectLike_1(value) && hasOwnProperty$1.call(value, 'callee') &&
12945 !propertyIsEnumerable.call(value, 'callee');
12946 };
12947
12948 var isArguments_1 = isArguments;
12949
12950 /**
12951 * Checks if `value` is classified as an `Array` object.
12952 *
12953 * @static
12954 * @memberOf _
12955 * @since 0.1.0
12956 * @category Lang
12957 * @param {*} value The value to check.
12958 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
12959 * @example
12960 *
12961 * _.isArray([1, 2, 3]);
12962 * // => true
12963 *
12964 * _.isArray(document.body.children);
12965 * // => false
12966 *
12967 * _.isArray('abc');
12968 * // => false
12969 *
12970 * _.isArray(_.noop);
12971 * // => false
12972 */
12973 var isArray = Array.isArray;
12974
12975 var isArray_1 = isArray;
12976
12977 /**
12978 * This method returns `false`.
12979 *
12980 * @static
12981 * @memberOf _
12982 * @since 4.13.0
12983 * @category Util
12984 * @returns {boolean} Returns `false`.
12985 * @example
12986 *
12987 * _.times(2, _.stubFalse);
12988 * // => [false, false]
12989 */
12990 function stubFalse() {
12991 return false;
12992 }
12993
12994 var stubFalse_1 = stubFalse;
12995
12996 var isBuffer_1 = createCommonjsModule(function (module, exports) {
12997 /** Detect free variable `exports`. */
12998 var freeExports = exports && !exports.nodeType && exports;
12999
13000 /** Detect free variable `module`. */
13001 var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
13002
13003 /** Detect the popular CommonJS extension `module.exports`. */
13004 var moduleExports = freeModule && freeModule.exports === freeExports;
13005
13006 /** Built-in value references. */
13007 var Buffer = moduleExports ? _root.Buffer : undefined;
13008
13009 /* Built-in method references for those with the same name as other `lodash` methods. */
13010 var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
13011
13012 /**
13013 * Checks if `value` is a buffer.
13014 *
13015 * @static
13016 * @memberOf _
13017 * @since 4.3.0
13018 * @category Lang
13019 * @param {*} value The value to check.
13020 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
13021 * @example
13022 *
13023 * _.isBuffer(new Buffer(2));
13024 * // => true
13025 *
13026 * _.isBuffer(new Uint8Array(2));
13027 * // => false
13028 */
13029 var isBuffer = nativeIsBuffer || stubFalse_1;
13030
13031 module.exports = isBuffer;
13032 });
13033
13034 /** Used as references for various `Number` constants. */
13035 var MAX_SAFE_INTEGER = 9007199254740991;
13036
13037 /** Used to detect unsigned integer values. */
13038 var reIsUint = /^(?:0|[1-9]\d*)$/;
13039
13040 /**
13041 * Checks if `value` is a valid array-like index.
13042 *
13043 * @private
13044 * @param {*} value The value to check.
13045 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
13046 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
13047 */
13048 function isIndex(value, length) {
13049 var type = typeof value;
13050 length = length == null ? MAX_SAFE_INTEGER : length;
13051
13052 return !!length &&
13053 (type == 'number' ||
13054 (type != 'symbol' && reIsUint.test(value))) &&
13055 (value > -1 && value % 1 == 0 && value < length);
13056 }
13057
13058 var _isIndex = isIndex;
13059
13060 /** Used as references for various `Number` constants. */
13061 var MAX_SAFE_INTEGER$1 = 9007199254740991;
13062
13063 /**
13064 * Checks if `value` is a valid array-like length.
13065 *
13066 * **Note:** This method is loosely based on
13067 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
13068 *
13069 * @static
13070 * @memberOf _
13071 * @since 4.0.0
13072 * @category Lang
13073 * @param {*} value The value to check.
13074 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
13075 * @example
13076 *
13077 * _.isLength(3);
13078 * // => true
13079 *
13080 * _.isLength(Number.MIN_VALUE);
13081 * // => false
13082 *
13083 * _.isLength(Infinity);
13084 * // => false
13085 *
13086 * _.isLength('3');
13087 * // => false
13088 */
13089 function isLength(value) {
13090 return typeof value == 'number' &&
13091 value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER$1;
13092 }
13093
13094 var isLength_1 = isLength;
13095
13096 /** `Object#toString` result references. */
13097 var argsTag$1 = '[object Arguments]',
13098 arrayTag = '[object Array]',
13099 boolTag = '[object Boolean]',
13100 dateTag = '[object Date]',
13101 errorTag = '[object Error]',
13102 funcTag = '[object Function]',
13103 mapTag = '[object Map]',
13104 numberTag = '[object Number]',
13105 objectTag = '[object Object]',
13106 regexpTag = '[object RegExp]',
13107 setTag = '[object Set]',
13108 stringTag = '[object String]',
13109 weakMapTag = '[object WeakMap]';
13110
13111 var arrayBufferTag = '[object ArrayBuffer]',
13112 dataViewTag = '[object DataView]',
13113 float32Tag = '[object Float32Array]',
13114 float64Tag = '[object Float64Array]',
13115 int8Tag = '[object Int8Array]',
13116 int16Tag = '[object Int16Array]',
13117 int32Tag = '[object Int32Array]',
13118 uint8Tag = '[object Uint8Array]',
13119 uint8ClampedTag = '[object Uint8ClampedArray]',
13120 uint16Tag = '[object Uint16Array]',
13121 uint32Tag = '[object Uint32Array]';
13122
13123 /** Used to identify `toStringTag` values of typed arrays. */
13124 var typedArrayTags = {};
13125 typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
13126 typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
13127 typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
13128 typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
13129 typedArrayTags[uint32Tag] = true;
13130 typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] =
13131 typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
13132 typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
13133 typedArrayTags[errorTag] = typedArrayTags[funcTag] =
13134 typedArrayTags[mapTag] = typedArrayTags[numberTag] =
13135 typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
13136 typedArrayTags[setTag] = typedArrayTags[stringTag] =
13137 typedArrayTags[weakMapTag] = false;
13138
13139 /**
13140 * The base implementation of `_.isTypedArray` without Node.js optimizations.
13141 *
13142 * @private
13143 * @param {*} value The value to check.
13144 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
13145 */
13146 function baseIsTypedArray(value) {
13147 return isObjectLike_1(value) &&
13148 isLength_1(value.length) && !!typedArrayTags[_baseGetTag(value)];
13149 }
13150
13151 var _baseIsTypedArray = baseIsTypedArray;
13152
13153 /**
13154 * The base implementation of `_.unary` without support for storing metadata.
13155 *
13156 * @private
13157 * @param {Function} func The function to cap arguments for.
13158 * @returns {Function} Returns the new capped function.
13159 */
13160 function baseUnary(func) {
13161 return function(value) {
13162 return func(value);
13163 };
13164 }
13165
13166 var _baseUnary = baseUnary;
13167
13168 var _nodeUtil = createCommonjsModule(function (module, exports) {
13169 /** Detect free variable `exports`. */
13170 var freeExports = exports && !exports.nodeType && exports;
13171
13172 /** Detect free variable `module`. */
13173 var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
13174
13175 /** Detect the popular CommonJS extension `module.exports`. */
13176 var moduleExports = freeModule && freeModule.exports === freeExports;
13177
13178 /** Detect free variable `process` from Node.js. */
13179 var freeProcess = moduleExports && _freeGlobal.process;
13180
13181 /** Used to access faster Node.js helpers. */
13182 var nodeUtil = (function() {
13183 try {
13184 // Use `util.types` for Node.js 10+.
13185 var types = freeModule && freeModule.require && freeModule.require('util').types;
13186
13187 if (types) {
13188 return types;
13189 }
13190
13191 // Legacy `process.binding('util')` for Node.js < 10.
13192 return freeProcess && freeProcess.binding && freeProcess.binding('util');
13193 } catch (e) {}
13194 }());
13195
13196 module.exports = nodeUtil;
13197 });
13198
13199 /* Node.js helper references. */
13200 var nodeIsTypedArray = _nodeUtil && _nodeUtil.isTypedArray;
13201
13202 /**
13203 * Checks if `value` is classified as a typed array.
13204 *
13205 * @static
13206 * @memberOf _
13207 * @since 3.0.0
13208 * @category Lang
13209 * @param {*} value The value to check.
13210 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
13211 * @example
13212 *
13213 * _.isTypedArray(new Uint8Array);
13214 * // => true
13215 *
13216 * _.isTypedArray([]);
13217 * // => false
13218 */
13219 var isTypedArray = nodeIsTypedArray ? _baseUnary(nodeIsTypedArray) : _baseIsTypedArray;
13220
13221 var isTypedArray_1 = isTypedArray;
13222
13223 /** Used for built-in method references. */
13224 var objectProto$3 = Object.prototype;
13225
13226 /** Used to check objects for own properties. */
13227 var hasOwnProperty$2 = objectProto$3.hasOwnProperty;
13228
13229 /**
13230 * Creates an array of the enumerable property names of the array-like `value`.
13231 *
13232 * @private
13233 * @param {*} value The value to query.
13234 * @param {boolean} inherited Specify returning inherited property names.
13235 * @returns {Array} Returns the array of property names.
13236 */
13237 function arrayLikeKeys(value, inherited) {
13238 var isArr = isArray_1(value),
13239 isArg = !isArr && isArguments_1(value),
13240 isBuff = !isArr && !isArg && isBuffer_1(value),
13241 isType = !isArr && !isArg && !isBuff && isTypedArray_1(value),
13242 skipIndexes = isArr || isArg || isBuff || isType,
13243 result = skipIndexes ? _baseTimes(value.length, String) : [],
13244 length = result.length;
13245
13246 for (var key in value) {
13247 if ((inherited || hasOwnProperty$2.call(value, key)) &&
13248 !(skipIndexes && (
13249 // Safari 9 has enumerable `arguments.length` in strict mode.
13250 key == 'length' ||
13251 // Node.js 0.10 has enumerable non-index properties on buffers.
13252 (isBuff && (key == 'offset' || key == 'parent')) ||
13253 // PhantomJS 2 has enumerable non-index properties on typed arrays.
13254 (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
13255 // Skip index properties.
13256 _isIndex(key, length)
13257 ))) {
13258 result.push(key);
13259 }
13260 }
13261 return result;
13262 }
13263
13264 var _arrayLikeKeys = arrayLikeKeys;
13265
13266 /** Used for built-in method references. */
13267 var objectProto$4 = Object.prototype;
13268
13269 /**
13270 * Checks if `value` is likely a prototype object.
13271 *
13272 * @private
13273 * @param {*} value The value to check.
13274 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
13275 */
13276 function isPrototype(value) {
13277 var Ctor = value && value.constructor,
13278 proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$4;
13279
13280 return value === proto;
13281 }
13282
13283 var _isPrototype = isPrototype;
13284
13285 /**
13286 * Creates a unary function that invokes `func` with its argument transformed.
13287 *
13288 * @private
13289 * @param {Function} func The function to wrap.
13290 * @param {Function} transform The argument transform.
13291 * @returns {Function} Returns the new function.
13292 */
13293 function overArg(func, transform) {
13294 return function(arg) {
13295 return func(transform(arg));
13296 };
13297 }
13298
13299 var _overArg = overArg;
13300
13301 /* Built-in method references for those with the same name as other `lodash` methods. */
13302 var nativeKeys = _overArg(Object.keys, Object);
13303
13304 var _nativeKeys = nativeKeys;
13305
13306 /** Used for built-in method references. */
13307 var objectProto$5 = Object.prototype;
13308
13309 /** Used to check objects for own properties. */
13310 var hasOwnProperty$3 = objectProto$5.hasOwnProperty;
13311
13312 /**
13313 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
13314 *
13315 * @private
13316 * @param {Object} object The object to query.
13317 * @returns {Array} Returns the array of property names.
13318 */
13319 function baseKeys(object) {
13320 if (!_isPrototype(object)) {
13321 return _nativeKeys(object);
13322 }
13323 var result = [];
13324 for (var key in Object(object)) {
13325 if (hasOwnProperty$3.call(object, key) && key != 'constructor') {
13326 result.push(key);
13327 }
13328 }
13329 return result;
13330 }
13331
13332 var _baseKeys = baseKeys;
13333
13334 /**
13335 * Checks if `value` is the
13336 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
13337 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
13338 *
13339 * @static
13340 * @memberOf _
13341 * @since 0.1.0
13342 * @category Lang
13343 * @param {*} value The value to check.
13344 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
13345 * @example
13346 *
13347 * _.isObject({});
13348 * // => true
13349 *
13350 * _.isObject([1, 2, 3]);
13351 * // => true
13352 *
13353 * _.isObject(_.noop);
13354 * // => true
13355 *
13356 * _.isObject(null);
13357 * // => false
13358 */
13359 function isObject(value) {
13360 var type = typeof value;
13361 return value != null && (type == 'object' || type == 'function');
13362 }
13363
13364 var isObject_1 = isObject;
13365
13366 /** `Object#toString` result references. */
13367 var asyncTag = '[object AsyncFunction]',
13368 funcTag$1 = '[object Function]',
13369 genTag = '[object GeneratorFunction]',
13370 proxyTag = '[object Proxy]';
13371
13372 /**
13373 * Checks if `value` is classified as a `Function` object.
13374 *
13375 * @static
13376 * @memberOf _
13377 * @since 0.1.0
13378 * @category Lang
13379 * @param {*} value The value to check.
13380 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
13381 * @example
13382 *
13383 * _.isFunction(_);
13384 * // => true
13385 *
13386 * _.isFunction(/abc/);
13387 * // => false
13388 */
13389 function isFunction(value) {
13390 if (!isObject_1(value)) {
13391 return false;
13392 }
13393 // The use of `Object#toString` avoids issues with the `typeof` operator
13394 // in Safari 9 which returns 'object' for typed arrays and other constructors.
13395 var tag = _baseGetTag(value);
13396 return tag == funcTag$1 || tag == genTag || tag == asyncTag || tag == proxyTag;
13397 }
13398
13399 var isFunction_1 = isFunction;
13400
13401 /**
13402 * Checks if `value` is array-like. A value is considered array-like if it's
13403 * not a function and has a `value.length` that's an integer greater than or
13404 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
13405 *
13406 * @static
13407 * @memberOf _
13408 * @since 4.0.0
13409 * @category Lang
13410 * @param {*} value The value to check.
13411 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
13412 * @example
13413 *
13414 * _.isArrayLike([1, 2, 3]);
13415 * // => true
13416 *
13417 * _.isArrayLike(document.body.children);
13418 * // => true
13419 *
13420 * _.isArrayLike('abc');
13421 * // => true
13422 *
13423 * _.isArrayLike(_.noop);
13424 * // => false
13425 */
13426 function isArrayLike(value) {
13427 return value != null && isLength_1(value.length) && !isFunction_1(value);
13428 }
13429
13430 var isArrayLike_1 = isArrayLike;
13431
13432 /**
13433 * Creates an array of the own enumerable property names of `object`.
13434 *
13435 * **Note:** Non-object values are coerced to objects. See the
13436 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
13437 * for more details.
13438 *
13439 * @static
13440 * @since 0.1.0
13441 * @memberOf _
13442 * @category Object
13443 * @param {Object} object The object to query.
13444 * @returns {Array} Returns the array of property names.
13445 * @example
13446 *
13447 * function Foo() {
13448 * this.a = 1;
13449 * this.b = 2;
13450 * }
13451 *
13452 * Foo.prototype.c = 3;
13453 *
13454 * _.keys(new Foo);
13455 * // => ['a', 'b'] (iteration order is not guaranteed)
13456 *
13457 * _.keys('hi');
13458 * // => ['0', '1']
13459 */
13460 function keys(object) {
13461 return isArrayLike_1(object) ? _arrayLikeKeys(object) : _baseKeys(object);
13462 }
13463
13464 var keys_1 = keys;
13465
13466 /**
13467 * Creates an array of the own enumerable string keyed property values of `object`.
13468 *
13469 * **Note:** Non-object values are coerced to objects.
13470 *
13471 * @static
13472 * @since 0.1.0
13473 * @memberOf _
13474 * @category Object
13475 * @param {Object} object The object to query.
13476 * @returns {Array} Returns the array of property values.
13477 * @example
13478 *
13479 * function Foo() {
13480 * this.a = 1;
13481 * this.b = 2;
13482 * }
13483 *
13484 * Foo.prototype.c = 3;
13485 *
13486 * _.values(new Foo);
13487 * // => [1, 2] (iteration order is not guaranteed)
13488 *
13489 * _.values('hi');
13490 * // => ['h', 'i']
13491 */
13492 function values(object) {
13493 return object == null ? [] : _baseValues(object, keys_1(object));
13494 }
13495
13496 var values_1 = values;
13497
13498 /**
13499 * The base implementation of `_.shuffle`.
13500 *
13501 * @private
13502 * @param {Array|Object} collection The collection to shuffle.
13503 * @returns {Array} Returns the new shuffled array.
13504 */
13505 function baseShuffle(collection) {
13506 return _shuffleSelf(values_1(collection));
13507 }
13508
13509 var _baseShuffle = baseShuffle;
13510
13511 /**
13512 * Creates an array of shuffled values, using a version of the
13513 * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
13514 *
13515 * @static
13516 * @memberOf _
13517 * @since 0.1.0
13518 * @category Collection
13519 * @param {Array|Object} collection The collection to shuffle.
13520 * @returns {Array} Returns the new shuffled array.
13521 * @example
13522 *
13523 * _.shuffle([1, 2, 3, 4]);
13524 * // => [4, 1, 3, 2]
13525 */
13526 function shuffle(collection) {
13527 var func = isArray_1(collection) ? _arrayShuffle : _baseShuffle;
13528 return func(collection);
13529 }
13530
13531 var shuffle_1 = shuffle;
13532
13533 function _arrayWithHoles(arr) {
13534 if (Array.isArray(arr)) return arr;
13535 }
13536
13537 var arrayWithHoles = _arrayWithHoles;
13538
13539 function _nonIterableRest() {
13540 throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
13541 }
13542
13543 var nonIterableRest = _nonIterableRest;
13544
13545 function _toArray(arr) {
13546 return arrayWithHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableRest();
13547 }
13548
13549 var toArray = _toArray;
13550
13551 function _defineProperties(target, props) {
13552 for (var i = 0; i < props.length; i++) {
13553 var descriptor = props[i];
13554 descriptor.enumerable = descriptor.enumerable || false;
13555 descriptor.configurable = true;
13556 if ("value" in descriptor) descriptor.writable = true;
13557 Object.defineProperty(target, descriptor.key, descriptor);
13558 }
13559 }
13560
13561 function _createClass(Constructor, protoProps, staticProps) {
13562 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
13563 if (staticProps) _defineProperties(Constructor, staticProps);
13564 return Constructor;
13565 }
13566
13567 var createClass = _createClass;
13568
13569 function _applyDecoratedDescriptor(target, property, decorators, descriptor, context) {
13570 var desc = {};
13571 Object.keys(descriptor).forEach(function (key) {
13572 desc[key] = descriptor[key];
13573 });
13574 desc.enumerable = !!desc.enumerable;
13575 desc.configurable = !!desc.configurable;
13576
13577 if ('value' in desc || desc.initializer) {
13578 desc.writable = true;
13579 }
13580
13581 desc = decorators.slice().reverse().reduce(function (desc, decorator) {
13582 return decorator(target, property, desc) || desc;
13583 }, desc);
13584
13585 if (context && desc.initializer !== void 0) {
13586 desc.value = desc.initializer ? desc.initializer.call(context) : void 0;
13587 desc.initializer = undefined;
13588 }
13589
13590 if (desc.initializer === void 0) {
13591 Object.defineProperty(target, property, desc);
13592 desc = null;
13593 }
13594
13595 return desc;
13596 }
13597
13598 var applyDecoratedDescriptor = _applyDecoratedDescriptor;
13599
13600 var stateMachine = createCommonjsModule(function (module, exports) {
13601 /*
13602
13603 Javascript State Machine Library - https://github.com/jakesgordon/javascript-state-machine
13604
13605 Copyright (c) 2012, 2013, 2014, 2015, Jake Gordon and contributors
13606 Released under the MIT license - https://github.com/jakesgordon/javascript-state-machine/blob/master/LICENSE
13607
13608 */
13609
13610 (function () {
13611
13612 var StateMachine = {
13613
13614 //---------------------------------------------------------------------------
13615
13616 VERSION: "2.4.0",
13617
13618 //---------------------------------------------------------------------------
13619
13620 Result: {
13621 SUCCEEDED: 1, // the event transitioned successfully from one state to another
13622 NOTRANSITION: 2, // the event was successfull but no state transition was necessary
13623 CANCELLED: 3, // the event was cancelled by the caller in a beforeEvent callback
13624 PENDING: 4 // the event is asynchronous and the caller is in control of when the transition occurs
13625 },
13626
13627 Error: {
13628 INVALID_TRANSITION: 100, // caller tried to fire an event that was innapropriate in the current state
13629 PENDING_TRANSITION: 200, // caller tried to fire an event while an async transition was still pending
13630 INVALID_CALLBACK: 300 // caller provided callback function threw an exception
13631 },
13632
13633 WILDCARD: '*',
13634 ASYNC: 'async',
13635
13636 //---------------------------------------------------------------------------
13637
13638 create: function(cfg, target) {
13639
13640 var initial = (typeof cfg.initial == 'string') ? { state: cfg.initial } : cfg.initial; // allow for a simple string, or an object with { state: 'foo', event: 'setup', defer: true|false }
13641 var terminal = cfg.terminal || cfg['final'];
13642 var fsm = target || cfg.target || {};
13643 var events = cfg.events || [];
13644 var callbacks = cfg.callbacks || {};
13645 var map = {}; // track state transitions allowed for an event { event: { from: [ to ] } }
13646 var transitions = {}; // track events allowed from a state { state: [ event ] }
13647
13648 var add = function(e) {
13649 var from = Array.isArray(e.from) ? e.from : (e.from ? [e.from] : [StateMachine.WILDCARD]); // allow 'wildcard' transition if 'from' is not specified
13650 map[e.name] = map[e.name] || {};
13651 for (var n = 0 ; n < from.length ; n++) {
13652 transitions[from[n]] = transitions[from[n]] || [];
13653 transitions[from[n]].push(e.name);
13654
13655 map[e.name][from[n]] = e.to || from[n]; // allow no-op transition if 'to' is not specified
13656 }
13657 if (e.to)
13658 transitions[e.to] = transitions[e.to] || [];
13659 };
13660
13661 if (initial) {
13662 initial.event = initial.event || 'startup';
13663 add({ name: initial.event, from: 'none', to: initial.state });
13664 }
13665
13666 for(var n = 0 ; n < events.length ; n++)
13667 add(events[n]);
13668
13669 for(var name in map) {
13670 if (map.hasOwnProperty(name))
13671 fsm[name] = StateMachine.buildEvent(name, map[name]);
13672 }
13673
13674 for(var name in callbacks) {
13675 if (callbacks.hasOwnProperty(name))
13676 fsm[name] = callbacks[name];
13677 }
13678
13679 fsm.current = 'none';
13680 fsm.is = function(state) { return Array.isArray(state) ? (state.indexOf(this.current) >= 0) : (this.current === state); };
13681 fsm.can = function(event) { return !this.transition && (map[event] !== undefined) && (map[event].hasOwnProperty(this.current) || map[event].hasOwnProperty(StateMachine.WILDCARD)); };
13682 fsm.cannot = function(event) { return !this.can(event); };
13683 fsm.transitions = function() { return (transitions[this.current] || []).concat(transitions[StateMachine.WILDCARD] || []); };
13684 fsm.isFinished = function() { return this.is(terminal); };
13685 fsm.error = cfg.error || function(name, from, to, args, error, msg, e) { throw e || msg; }; // default behavior when something unexpected happens is to throw an exception, but caller can override this behavior if desired (see github issue #3 and #17)
13686 fsm.states = function() { return Object.keys(transitions).sort() };
13687
13688 if (initial && !initial.defer)
13689 fsm[initial.event]();
13690
13691 return fsm;
13692
13693 },
13694
13695 //===========================================================================
13696
13697 doCallback: function(fsm, func, name, from, to, args) {
13698 if (func) {
13699 try {
13700 return func.apply(fsm, [name, from, to].concat(args));
13701 }
13702 catch(e) {
13703 return fsm.error(name, from, to, args, StateMachine.Error.INVALID_CALLBACK, "an exception occurred in a caller-provided callback function", e);
13704 }
13705 }
13706 },
13707
13708 beforeAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbeforeevent'], name, from, to, args); },
13709 afterAnyEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafterevent'] || fsm['onevent'], name, from, to, args); },
13710 leaveAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleavestate'], name, from, to, args); },
13711 enterAnyState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenterstate'] || fsm['onstate'], name, from, to, args); },
13712 changeState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onchangestate'], name, from, to, args); },
13713
13714 beforeThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onbefore' + name], name, from, to, args); },
13715 afterThisEvent: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onafter' + name] || fsm['on' + name], name, from, to, args); },
13716 leaveThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onleave' + from], name, from, to, args); },
13717 enterThisState: function(fsm, name, from, to, args) { return StateMachine.doCallback(fsm, fsm['onenter' + to] || fsm['on' + to], name, from, to, args); },
13718
13719 beforeEvent: function(fsm, name, from, to, args) {
13720 if ((false === StateMachine.beforeThisEvent(fsm, name, from, to, args)) ||
13721 (false === StateMachine.beforeAnyEvent( fsm, name, from, to, args)))
13722 return false;
13723 },
13724
13725 afterEvent: function(fsm, name, from, to, args) {
13726 StateMachine.afterThisEvent(fsm, name, from, to, args);
13727 StateMachine.afterAnyEvent( fsm, name, from, to, args);
13728 },
13729
13730 leaveState: function(fsm, name, from, to, args) {
13731 var specific = StateMachine.leaveThisState(fsm, name, from, to, args),
13732 general = StateMachine.leaveAnyState( fsm, name, from, to, args);
13733 if ((false === specific) || (false === general))
13734 return false;
13735 else if ((StateMachine.ASYNC === specific) || (StateMachine.ASYNC === general))
13736 return StateMachine.ASYNC;
13737 },
13738
13739 enterState: function(fsm, name, from, to, args) {
13740 StateMachine.enterThisState(fsm, name, from, to, args);
13741 StateMachine.enterAnyState( fsm, name, from, to, args);
13742 },
13743
13744 //===========================================================================
13745
13746 buildEvent: function(name, map) {
13747 return function() {
13748
13749 var from = this.current;
13750 var to = map[from] || (map[StateMachine.WILDCARD] != StateMachine.WILDCARD ? map[StateMachine.WILDCARD] : from) || from;
13751 var args = Array.prototype.slice.call(arguments); // turn arguments into pure array
13752
13753 if (this.transition)
13754 return this.error(name, from, to, args, StateMachine.Error.PENDING_TRANSITION, "event " + name + " inappropriate because previous transition did not complete");
13755
13756 if (this.cannot(name))
13757 return this.error(name, from, to, args, StateMachine.Error.INVALID_TRANSITION, "event " + name + " inappropriate in current state " + this.current);
13758
13759 if (false === StateMachine.beforeEvent(this, name, from, to, args))
13760 return StateMachine.Result.CANCELLED;
13761
13762 if (from === to) {
13763 StateMachine.afterEvent(this, name, from, to, args);
13764 return StateMachine.Result.NOTRANSITION;
13765 }
13766
13767 // prepare a transition method for use EITHER lower down, or by caller if they want an async transition (indicated by an ASYNC return value from leaveState)
13768 var fsm = this;
13769 this.transition = function() {
13770 fsm.transition = null; // this method should only ever be called once
13771 fsm.current = to;
13772 StateMachine.enterState( fsm, name, from, to, args);
13773 StateMachine.changeState(fsm, name, from, to, args);
13774 StateMachine.afterEvent( fsm, name, from, to, args);
13775 return StateMachine.Result.SUCCEEDED;
13776 };
13777 this.transition.cancel = function() { // provide a way for caller to cancel async transition if desired (issue #22)
13778 fsm.transition = null;
13779 StateMachine.afterEvent(fsm, name, from, to, args);
13780 };
13781
13782 var leave = StateMachine.leaveState(this, name, from, to, args);
13783 if (false === leave) {
13784 this.transition = null;
13785 return StateMachine.Result.CANCELLED;
13786 }
13787 else if (StateMachine.ASYNC === leave) {
13788 return StateMachine.Result.PENDING;
13789 }
13790 else {
13791 if (this.transition) // need to check in case user manually called transition() but forgot to return StateMachine.ASYNC
13792 return this.transition();
13793 }
13794
13795 };
13796 }
13797
13798 }; // StateMachine
13799
13800 //===========================================================================
13801
13802 //======
13803 // NODE
13804 //======
13805 {
13806 if ( module.exports) {
13807 exports = module.exports = StateMachine;
13808 }
13809 exports.StateMachine = StateMachine;
13810 }
13811
13812 }());
13813 });
13814 var stateMachine_1 = stateMachine.StateMachine;
13815
13816 var adapters = {};
13817
13818 var getAdapter = function getAdapter(name) {
13819 var adapter = adapters[name];
13820
13821 if (adapter === undefined) {
13822 throw new Error("".concat(name, " adapter is not configured"));
13823 }
13824
13825 return adapter;
13826 };
13827 /**
13828 * 指定 Adapters
13829 * @function
13830 * @memberof module:leancloud-realtime
13831 * @param {Adapters} newAdapters Adapters 的类型请参考 {@link https://url.leanapp.cn/adapter-type-definitions @leancloud/adapter-types} 中的定义
13832 */
13833
13834
13835 var setAdapters = function setAdapters(newAdapters) {
13836 Object.assign(adapters, newAdapters);
13837 };
13838
13839 var _typeof_1 = createCommonjsModule(function (module) {
13840 function _typeof(obj) {
13841 "@babel/helpers - typeof";
13842
13843 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
13844 module.exports = _typeof = function _typeof(obj) {
13845 return typeof obj;
13846 };
13847 } else {
13848 module.exports = _typeof = function _typeof(obj) {
13849 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
13850 };
13851 }
13852
13853 return _typeof(obj);
13854 }
13855
13856 module.exports = _typeof;
13857 });
13858
13859 /** Built-in value references. */
13860 var getPrototype = _overArg(Object.getPrototypeOf, Object);
13861
13862 var _getPrototype = getPrototype;
13863
13864 /** `Object#toString` result references. */
13865 var objectTag$1 = '[object Object]';
13866
13867 /** Used for built-in method references. */
13868 var funcProto = Function.prototype,
13869 objectProto$6 = Object.prototype;
13870
13871 /** Used to resolve the decompiled source of functions. */
13872 var funcToString = funcProto.toString;
13873
13874 /** Used to check objects for own properties. */
13875 var hasOwnProperty$4 = objectProto$6.hasOwnProperty;
13876
13877 /** Used to infer the `Object` constructor. */
13878 var objectCtorString = funcToString.call(Object);
13879
13880 /**
13881 * Checks if `value` is a plain object, that is, an object created by the
13882 * `Object` constructor or one with a `[[Prototype]]` of `null`.
13883 *
13884 * @static
13885 * @memberOf _
13886 * @since 0.8.0
13887 * @category Lang
13888 * @param {*} value The value to check.
13889 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
13890 * @example
13891 *
13892 * function Foo() {
13893 * this.a = 1;
13894 * }
13895 *
13896 * _.isPlainObject(new Foo);
13897 * // => false
13898 *
13899 * _.isPlainObject([1, 2, 3]);
13900 * // => false
13901 *
13902 * _.isPlainObject({ 'x': 0, 'y': 0 });
13903 * // => true
13904 *
13905 * _.isPlainObject(Object.create(null));
13906 * // => true
13907 */
13908 function isPlainObject(value) {
13909 if (!isObjectLike_1(value) || _baseGetTag(value) != objectTag$1) {
13910 return false;
13911 }
13912 var proto = _getPrototype(value);
13913 if (proto === null) {
13914 return true;
13915 }
13916 var Ctor = hasOwnProperty$4.call(proto, 'constructor') && proto.constructor;
13917 return typeof Ctor == 'function' && Ctor instanceof Ctor &&
13918 funcToString.call(Ctor) == objectCtorString;
13919 }
13920
13921 var isPlainObject_1 = isPlainObject;
13922
13923 /* eslint-disable */
13924 var global$1 = typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : {};
13925
13926 var EXPIRED = Symbol('expired');
13927 var debug = browser('LC:Expirable');
13928
13929 var Expirable = /*#__PURE__*/function () {
13930 function Expirable(value, ttl) {
13931 this.originalValue = value;
13932
13933 if (typeof ttl === 'number') {
13934 this.expiredAt = Date.now() + ttl;
13935 }
13936 }
13937
13938 createClass(Expirable, [{
13939 key: "value",
13940 get: function get() {
13941 var expired = this.expiredAt && this.expiredAt <= Date.now();
13942 if (expired) debug("expired: ".concat(this.originalValue));
13943 return expired ? EXPIRED : this.originalValue;
13944 }
13945 }]);
13946
13947 return Expirable;
13948 }();
13949 Expirable.EXPIRED = EXPIRED;
13950
13951 var debug$1 = browser('LC:Cache');
13952
13953 var Cache = /*#__PURE__*/function () {
13954 function Cache() {
13955 var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'anonymous';
13956 this.name = name;
13957 this._map = {};
13958 }
13959
13960 var _proto = Cache.prototype;
13961
13962 _proto.get = function get(key) {
13963 var cache = this._map[key];
13964
13965 if (cache) {
13966 var value = cache.value;
13967
13968 if (value !== Expirable.EXPIRED) {
13969 debug$1('[%s] hit: %s', this.name, key);
13970 return value;
13971 }
13972
13973 delete this._map[key];
13974 }
13975
13976 debug$1("[".concat(this.name, "] missed: ").concat(key));
13977 return null;
13978 };
13979
13980 _proto.set = function set(key, value, ttl) {
13981 debug$1('[%s] set: %s %d', this.name, key, ttl);
13982 this._map[key] = new Expirable(value, ttl);
13983 };
13984
13985 return Cache;
13986 }();
13987
13988 function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
13989
13990 function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
13991 /**
13992 * 调试日志控制器
13993 * @const
13994 * @memberof module:leancloud-realtime
13995 * @example
13996 * debug.enable(); // 启用调试日志
13997 * debug.disable(); // 关闭调试日志
13998 */
13999
14000 var debug$2 = {
14001 enable: function enable() {
14002 var namespaces = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'LC*';
14003 return browser.enable(namespaces);
14004 },
14005 disable: browser.disable
14006 };
14007 var tryAll = function tryAll(promiseConstructors) {
14008 var promise = new Promise(promiseConstructors[0]);
14009
14010 if (promiseConstructors.length === 1) {
14011 return promise;
14012 }
14013
14014 return promise["catch"](function () {
14015 return tryAll(promiseConstructors.slice(1));
14016 });
14017 }; // eslint-disable-next-line no-sequences
14018
14019 var tap = function tap(interceptor) {
14020 return function (value) {
14021 return interceptor(value), value;
14022 };
14023 };
14024 var finalize = function finalize(callback) {
14025 return [// eslint-disable-next-line no-sequences
14026 function (value) {
14027 return callback(), value;
14028 }, function (error) {
14029 callback();
14030 throw error;
14031 }];
14032 };
14033 /**
14034 * 将对象转换为 Date,支持 string、number、ProtoBuf Long 以及 LeanCloud 的 Date 类型,
14035 * 其他情况下(包括对象为 falsy)返回原值。
14036 * @private
14037 */
14038
14039 var decodeDate = function decodeDate(date) {
14040 if (!date) return date;
14041
14042 if (typeof date === 'string' || typeof date === 'number') {
14043 return new Date(date);
14044 }
14045
14046 if (date.__type === 'Date' && date.iso) {
14047 return new Date(date.iso);
14048 } // Long
14049
14050
14051 if (typeof date.toNumber === 'function') {
14052 return new Date(date.toNumber());
14053 }
14054
14055 return date;
14056 };
14057 /**
14058 * 获取 Date 的毫秒数,如果不是一个 Date 返回 undefined。
14059 * @private
14060 */
14061
14062 var getTime = function getTime(date) {
14063 return date && date.getTime ? date.getTime() : undefined;
14064 };
14065 /**
14066 * 解码对象中的 LeanCloud 数据结构。
14067 * 目前仅会处理 Date 类型。
14068 * @private
14069 */
14070
14071 var decode = function decode(value) {
14072 if (!value) return value;
14073
14074 if (value.__type === 'Date' && value.iso) {
14075 return new Date(value.iso);
14076 }
14077
14078 if (Array.isArray(value)) {
14079 return value.map(decode);
14080 }
14081
14082 if (isPlainObject_1(value)) {
14083 return Object.keys(value).reduce(function (result, key) {
14084 return _objectSpread(_objectSpread({}, result), {}, defineProperty({}, key, decode(value[key])));
14085 }, {});
14086 }
14087
14088 return value;
14089 };
14090 /**
14091 * 将对象中的特殊类型编码为 LeanCloud 数据结构。
14092 * 目前仅会处理 Date 类型。
14093 * @private
14094 */
14095
14096 var encode = function encode(value) {
14097 if (value instanceof Date) return {
14098 __type: 'Date',
14099 iso: value.toJSON()
14100 };
14101
14102 if (Array.isArray(value)) {
14103 return value.map(encode);
14104 }
14105
14106 if (isPlainObject_1(value)) {
14107 return Object.keys(value).reduce(function (result, key) {
14108 return _objectSpread(_objectSpread({}, result), {}, defineProperty({}, key, encode(value[key])));
14109 }, {});
14110 }
14111
14112 return value;
14113 };
14114 var keyRemap = function keyRemap(keymap, obj) {
14115 return Object.keys(obj).reduce(function (newObj, key) {
14116 var newKey = keymap[key] || key;
14117 return Object.assign(newObj, defineProperty({}, newKey, obj[key]));
14118 }, {});
14119 };
14120 var isIE10 = global$1.navigator && global$1.navigator.userAgent && global$1.navigator.userAgent.indexOf('MSIE 10.') !== -1;
14121 /* eslint-disable no-proto */
14122
14123 var getStaticProperty = function getStaticProperty(klass, property) {
14124 return klass[property] || (klass.__proto__ ? getStaticProperty(klass.__proto__, property) : undefined);
14125 };
14126 /* eslint-enable no-proto */
14127
14128 var union = function union(a, b) {
14129 return Array.from(new Set([].concat(toConsumableArray(a), toConsumableArray(b))));
14130 };
14131 var difference = function difference(a, b) {
14132 return Array.from(function (bSet) {
14133 return new Set(a.filter(function (x) {
14134 return !bSet.has(x);
14135 }));
14136 }(new Set(b)));
14137 };
14138 var map = new WeakMap(); // protected property helper
14139
14140 var internal = function internal(object) {
14141 if (!map.has(object)) {
14142 map.set(object, {});
14143 }
14144
14145 return map.get(object);
14146 };
14147 var compact = function compact(obj, filter) {
14148 if (!isPlainObject_1(obj)) return obj;
14149
14150 var object = _objectSpread({}, obj);
14151
14152 Object.keys(object).forEach(function (prop) {
14153 var value = object[prop];
14154
14155 if (value === filter) {
14156 delete object[prop];
14157 } else {
14158 object[prop] = compact(value, filter);
14159 }
14160 });
14161 return object;
14162 }; // debug utility
14163
14164 var removeNull = function removeNull(obj) {
14165 return compact(obj, null);
14166 };
14167
14168 var trim = function trim(message) {
14169 return removeNull(JSON.parse(JSON.stringify(message)));
14170 };
14171 var ensureArray = function ensureArray(target) {
14172 if (Array.isArray(target)) {
14173 return target;
14174 }
14175
14176 if (target === undefined || target === null) {
14177 return [];
14178 }
14179
14180 return [target];
14181 };
14182 var setValue = function setValue(target, key, value) {
14183 // '.' is not allowed in Class keys, escaping is not in concern now.
14184 var segs = key.split('.');
14185 var lastSeg = segs.pop();
14186 var currentTarget = target;
14187 segs.forEach(function (seg) {
14188 if (currentTarget[seg] === undefined) currentTarget[seg] = {};
14189 currentTarget = currentTarget[seg];
14190 });
14191 currentTarget[lastSeg] = value;
14192 return target;
14193 };
14194 var isWeapp = // eslint-disable-next-line no-undef
14195 (typeof wx === "undefined" ? "undefined" : _typeof_1(wx)) === 'object' && typeof wx.connectSocket === 'function'; // throttle decorator
14196
14197 var throttle = function throttle(wait) {
14198 return function (target, property, descriptor) {
14199 var callback = descriptor.value; // very naive, internal use only
14200
14201 if (callback.length) {
14202 throw new Error('throttled function should not accept any arguments');
14203 }
14204
14205 return _objectSpread(_objectSpread({}, descriptor), {}, {
14206 value: function value() {
14207 var _this = this;
14208
14209 var _internal = internal(this),
14210 throttleMeta = _internal.throttleMeta;
14211
14212 if (!throttleMeta) {
14213 throttleMeta = {};
14214 internal(this).throttleMeta = throttleMeta;
14215 }
14216
14217 var _throttleMeta = throttleMeta,
14218 propertyMeta = _throttleMeta[property];
14219
14220 if (!propertyMeta) {
14221 propertyMeta = {};
14222 throttleMeta[property] = propertyMeta;
14223 }
14224
14225 var _propertyMeta = propertyMeta,
14226 _propertyMeta$previou = _propertyMeta.previouseTimestamp,
14227 previouseTimestamp = _propertyMeta$previou === void 0 ? 0 : _propertyMeta$previou,
14228 timeout = _propertyMeta.timeout;
14229 var now = Date.now();
14230 var remainingTime = wait - (now - previouseTimestamp);
14231
14232 if (remainingTime <= 0) {
14233 throttleMeta[property].previouseTimestamp = now;
14234 callback.apply(this);
14235 } else if (!timeout) {
14236 propertyMeta.timeout = setTimeout(function () {
14237 propertyMeta.previouseTimestamp = Date.now();
14238 delete propertyMeta.timeout;
14239 callback.apply(_this);
14240 }, remainingTime);
14241 }
14242 }
14243 });
14244 };
14245 };
14246 var isCNApp = function isCNApp(appId) {
14247 return appId.slice(-9) !== '-MdYXbMMI';
14248 };
14249 var equalBuffer = function equalBuffer(buffer1, buffer2) {
14250 if (!buffer1 || !buffer2) return false;
14251 if (buffer1.byteLength !== buffer2.byteLength) return false;
14252 var a = new Uint8Array(buffer1);
14253 var b = new Uint8Array(buffer2);
14254 return !a.some(function (value, index) {
14255 return value !== b[index];
14256 });
14257 };
14258
14259 var _class;
14260
14261 function ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
14262
14263 function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$1(Object(source), true).forEach(function (key) { defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
14264 var debug$3 = browser('LC:WebSocketPlus');
14265 var OPEN = 'open';
14266 var DISCONNECT = 'disconnect';
14267 var RECONNECT = 'reconnect';
14268 var RETRY = 'retry';
14269 var SCHEDULE = 'schedule';
14270 var OFFLINE = 'offline';
14271 var ONLINE = 'online';
14272 var ERROR = 'error';
14273 var MESSAGE = 'message';
14274 var HEARTBEAT_TIME = 180000;
14275 var TIMEOUT_TIME = 380000;
14276
14277 var DEFAULT_RETRY_STRATEGY = function DEFAULT_RETRY_STRATEGY(attempt) {
14278 return Math.min(1000 * Math.pow(2, attempt), 300000);
14279 };
14280
14281 var requireConnected = function requireConnected(target, name, descriptor) {
14282 return _objectSpread$1(_objectSpread$1({}, descriptor), {}, {
14283 value: function requireConnectedWrapper() {
14284 var _descriptor$value;
14285
14286 this.checkConnectionAvailability(name);
14287
14288 for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
14289 args[_key] = arguments[_key];
14290 }
14291
14292 return (_descriptor$value = descriptor.value).call.apply(_descriptor$value, [this].concat(args));
14293 }
14294 });
14295 };
14296
14297 var WebSocketPlus = (_class = /*#__PURE__*/function (_EventEmitter) {
14298 inheritsLoose(WebSocketPlus, _EventEmitter);
14299
14300 createClass(WebSocketPlus, [{
14301 key: "urls",
14302 get: function get() {
14303 return this._urls;
14304 },
14305 set: function set(urls) {
14306 this._urls = ensureArray(urls);
14307 }
14308 }]);
14309
14310 function WebSocketPlus(getUrls, protocol) {
14311 var _this;
14312
14313 _this = _EventEmitter.call(this) || this;
14314
14315 _this.init();
14316
14317 _this._protocol = protocol;
14318 Promise.resolve(typeof getUrls === 'function' ? getUrls() : getUrls).then(ensureArray).then(function (urls) {
14319 _this._urls = urls;
14320 return _this._open();
14321 }).then(function () {
14322 _this.__postponeTimeoutTimer = _this._postponeTimeoutTimer.bind(assertThisInitialized(_this));
14323
14324 if (global$1.addEventListener) {
14325 _this.__pause = function () {
14326 if (_this.can('pause')) _this.pause();
14327 };
14328
14329 _this.__resume = function () {
14330 if (_this.can('resume')) _this.resume();
14331 };
14332
14333 global$1.addEventListener('offline', _this.__pause);
14334 global$1.addEventListener('online', _this.__resume);
14335 }
14336
14337 _this.open();
14338 })["catch"](_this["throw"].bind(assertThisInitialized(_this)));
14339 return _this;
14340 }
14341
14342 var _proto = WebSocketPlus.prototype;
14343
14344 _proto._open = function _open() {
14345 var _this2 = this;
14346
14347 return this._createWs(this._urls, this._protocol).then(function (ws) {
14348 var _this2$_urls = toArray(_this2._urls),
14349 first = _this2$_urls[0],
14350 reset = _this2$_urls.slice(1);
14351
14352 _this2._urls = [].concat(toConsumableArray(reset), [first]);
14353 return ws;
14354 });
14355 };
14356
14357 _proto._createWs = function _createWs(urls, protocol) {
14358 var _this3 = this;
14359
14360 return tryAll(urls.map(function (url) {
14361 return function (resolve, reject) {
14362 debug$3("connect [".concat(url, "] ").concat(protocol));
14363 var WebSocket = getAdapter('WebSocket');
14364 var ws = protocol ? new WebSocket(url, protocol) : new WebSocket(url);
14365 ws.binaryType = _this3.binaryType || 'arraybuffer';
14366
14367 ws.onopen = function () {
14368 return resolve(ws);
14369 };
14370
14371 ws.onclose = function (error) {
14372 if (error instanceof Error) {
14373 return reject(error);
14374 } // in browser, error event is useless
14375
14376
14377 return reject(new Error("Failed to connect [".concat(url, "]")));
14378 };
14379
14380 ws.onerror = ws.onclose;
14381 };
14382 })).then(function (ws) {
14383 _this3._ws = ws;
14384 _this3._ws.onclose = _this3._handleClose.bind(_this3);
14385 _this3._ws.onmessage = _this3._handleMessage.bind(_this3);
14386 return ws;
14387 });
14388 };
14389
14390 _proto._destroyWs = function _destroyWs() {
14391 var ws = this._ws;
14392 if (!ws) return;
14393 ws.onopen = null;
14394 ws.onclose = null;
14395 ws.onerror = null;
14396 ws.onmessage = null;
14397 this._ws = null;
14398 ws.close();
14399 } // eslint-disable-next-line class-methods-use-this
14400 ;
14401
14402 _proto.onbeforeevent = function onbeforeevent(event, from, to) {
14403 for (var _len2 = arguments.length, payload = new Array(_len2 > 3 ? _len2 - 3 : 0), _key2 = 3; _key2 < _len2; _key2++) {
14404 payload[_key2 - 3] = arguments[_key2];
14405 }
14406
14407 debug$3("".concat(event, ": ").concat(from, " -> ").concat(to, " %o"), payload);
14408 };
14409
14410 _proto.onopen = function onopen() {
14411 this.emit(OPEN);
14412 };
14413
14414 _proto.onconnected = function onconnected() {
14415 this._startConnectionKeeper();
14416 };
14417
14418 _proto.onleaveconnected = function onleaveconnected(event, from, to) {
14419 this._stopConnectionKeeper();
14420
14421 this._destroyWs();
14422
14423 if (to === 'offline' || to === 'disconnected') {
14424 this.emit(DISCONNECT);
14425 }
14426 };
14427
14428 _proto.onpause = function onpause() {
14429 this.emit(OFFLINE);
14430 };
14431
14432 _proto.onbeforeresume = function onbeforeresume() {
14433 this.emit(ONLINE);
14434 };
14435
14436 _proto.onreconnect = function onreconnect() {
14437 this.emit(RECONNECT);
14438 };
14439
14440 _proto.ondisconnected = function ondisconnected(event, from, to) {
14441 var _this4 = this;
14442
14443 var attempt = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
14444 var delay = from === OFFLINE ? 0 : DEFAULT_RETRY_STRATEGY.call(null, attempt);
14445 debug$3("schedule attempt=".concat(attempt, " delay=").concat(delay));
14446 this.emit(SCHEDULE, attempt, delay);
14447
14448 if (this.__scheduledRetry) {
14449 clearTimeout(this.__scheduledRetry);
14450 }
14451
14452 this.__scheduledRetry = setTimeout(function () {
14453 if (_this4.is('disconnected')) {
14454 _this4.retry(attempt);
14455 }
14456 }, delay);
14457 };
14458
14459 _proto.onretry = function onretry(event, from, to) {
14460 var _this5 = this;
14461
14462 var attempt = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
14463 this.emit(RETRY, attempt);
14464
14465 this._open().then(function () {
14466 return _this5.can('reconnect') && _this5.reconnect();
14467 }, function () {
14468 return _this5.can('fail') && _this5.fail(attempt + 1);
14469 });
14470 };
14471
14472 _proto.onerror = function onerror(event, from, to, error) {
14473 this.emit(ERROR, error);
14474 };
14475
14476 _proto.onclose = function onclose() {
14477 if (global$1.removeEventListener) {
14478 if (this.__pause) global$1.removeEventListener('offline', this.__pause);
14479 if (this.__resume) global$1.removeEventListener('online', this.__resume);
14480 }
14481 };
14482
14483 _proto.checkConnectionAvailability = function checkConnectionAvailability() {
14484 var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'API';
14485
14486 if (!this.is('connected')) {
14487 var currentState = this.current;
14488 console.warn("".concat(name, " should not be called when the connection is ").concat(currentState));
14489
14490 if (this.is('disconnected') || this.is('reconnecting')) {
14491 console.warn('disconnect and reconnect event should be handled to avoid such calls.');
14492 }
14493
14494 throw new Error('Connection unavailable');
14495 }
14496 } // jsdoc-ignore-start
14497 ;
14498
14499 _proto. // jsdoc-ignore-end
14500 _ping = function _ping() {
14501 debug$3('ping');
14502
14503 try {
14504 this.ping();
14505 } catch (error) {
14506 console.warn("websocket ping error: ".concat(error.message));
14507 }
14508 };
14509
14510 _proto.ping = function ping() {
14511 if (this._ws.ping) {
14512 this._ws.ping();
14513 } else {
14514 console.warn("The WebSocket implement does not support sending ping frame.\n Override ping method to use application defined ping/pong mechanism.");
14515 }
14516 };
14517
14518 _proto._postponeTimeoutTimer = function _postponeTimeoutTimer() {
14519 var _this6 = this;
14520
14521 debug$3('_postponeTimeoutTimer');
14522
14523 this._clearTimeoutTimers();
14524
14525 this._timeoutTimer = setTimeout(function () {
14526 debug$3('timeout');
14527
14528 _this6.disconnect();
14529 }, TIMEOUT_TIME);
14530 };
14531
14532 _proto._clearTimeoutTimers = function _clearTimeoutTimers() {
14533 if (this._timeoutTimer) {
14534 clearTimeout(this._timeoutTimer);
14535 }
14536 };
14537
14538 _proto._startConnectionKeeper = function _startConnectionKeeper() {
14539 debug$3('start connection keeper');
14540 this._heartbeatTimer = setInterval(this._ping.bind(this), HEARTBEAT_TIME);
14541 var addListener = this._ws.addListener || this._ws.addEventListener;
14542
14543 if (!addListener) {
14544 debug$3('connection keeper disabled due to the lack of #addEventListener.');
14545 return;
14546 }
14547
14548 addListener.call(this._ws, 'message', this.__postponeTimeoutTimer);
14549 addListener.call(this._ws, 'pong', this.__postponeTimeoutTimer);
14550
14551 this._postponeTimeoutTimer();
14552 };
14553
14554 _proto._stopConnectionKeeper = function _stopConnectionKeeper() {
14555 debug$3('stop connection keeper'); // websockets/ws#489
14556
14557 var removeListener = this._ws.removeListener || this._ws.removeEventListener;
14558
14559 if (removeListener) {
14560 removeListener.call(this._ws, 'message', this.__postponeTimeoutTimer);
14561 removeListener.call(this._ws, 'pong', this.__postponeTimeoutTimer);
14562
14563 this._clearTimeoutTimers();
14564 }
14565
14566 if (this._heartbeatTimer) {
14567 clearInterval(this._heartbeatTimer);
14568 }
14569 };
14570
14571 _proto._handleClose = function _handleClose(event) {
14572 debug$3("ws closed [".concat(event.code, "] ").concat(event.reason)); // socket closed manually, ignore close event.
14573
14574 if (this.isFinished()) return;
14575 this.handleClose(event);
14576 };
14577
14578 _proto.handleClose = function handleClose() {
14579 // reconnect
14580 this.disconnect();
14581 } // jsdoc-ignore-start
14582 ;
14583
14584 _proto. // jsdoc-ignore-end
14585 send = function send(data) {
14586 debug$3('send', data);
14587
14588 this._ws.send(data);
14589 };
14590
14591 _proto._handleMessage = function _handleMessage(event) {
14592 debug$3('message', event.data);
14593 this.handleMessage(event.data);
14594 };
14595
14596 _proto.handleMessage = function handleMessage(message) {
14597 this.emit(MESSAGE, message);
14598 };
14599
14600 return WebSocketPlus;
14601 }(eventemitter3), (applyDecoratedDescriptor(_class.prototype, "_ping", [requireConnected], Object.getOwnPropertyDescriptor(_class.prototype, "_ping"), _class.prototype), applyDecoratedDescriptor(_class.prototype, "send", [requireConnected], Object.getOwnPropertyDescriptor(_class.prototype, "send"), _class.prototype)), _class);
14602 stateMachine.create({
14603 target: WebSocketPlus.prototype,
14604 initial: {
14605 state: 'initialized',
14606 event: 'init',
14607 defer: true
14608 },
14609 terminal: 'closed',
14610 events: [{
14611 name: 'open',
14612 from: 'initialized',
14613 to: 'connected'
14614 }, {
14615 name: 'disconnect',
14616 from: 'connected',
14617 to: 'disconnected'
14618 }, {
14619 name: 'retry',
14620 from: 'disconnected',
14621 to: 'reconnecting'
14622 }, {
14623 name: 'fail',
14624 from: 'reconnecting',
14625 to: 'disconnected'
14626 }, {
14627 name: 'reconnect',
14628 from: 'reconnecting',
14629 to: 'connected'
14630 }, {
14631 name: 'pause',
14632 from: ['connected', 'disconnected', 'reconnecting'],
14633 to: 'offline'
14634 }, {}, {
14635 name: 'resume',
14636 from: 'offline',
14637 to: 'disconnected'
14638 }, {
14639 name: 'close',
14640 from: ['connected', 'disconnected', 'reconnecting', 'offline'],
14641 to: 'closed'
14642 }, {
14643 name: 'throw',
14644 from: '*',
14645 to: 'error'
14646 }]
14647 });
14648
14649 var error = Object.freeze({
14650 1000: {
14651 name: 'CLOSE_NORMAL'
14652 },
14653 1006: {
14654 name: 'CLOSE_ABNORMAL'
14655 },
14656 4100: {
14657 name: 'APP_NOT_AVAILABLE',
14658 message: 'App not exists or realtime message service is disabled.'
14659 },
14660 4102: {
14661 name: 'SIGNATURE_FAILED',
14662 message: 'Login signature mismatch.'
14663 },
14664 4103: {
14665 name: 'INVALID_LOGIN',
14666 message: 'Malformed clientId.'
14667 },
14668 4105: {
14669 name: 'SESSION_REQUIRED',
14670 message: 'Message sent before session opened.'
14671 },
14672 4107: {
14673 name: 'READ_TIMEOUT'
14674 },
14675 4108: {
14676 name: 'LOGIN_TIMEOUT'
14677 },
14678 4109: {
14679 name: 'FRAME_TOO_LONG'
14680 },
14681 4110: {
14682 name: 'INVALID_ORIGIN',
14683 message: 'Access denied by domain whitelist.'
14684 },
14685 4111: {
14686 name: 'SESSION_CONFLICT'
14687 },
14688 4112: {
14689 name: 'SESSION_TOKEN_EXPIRED'
14690 },
14691 4113: {
14692 name: 'APP_QUOTA_EXCEEDED',
14693 message: 'The daily active users limit exceeded.'
14694 },
14695 4116: {
14696 name: 'MESSAGE_SENT_QUOTA_EXCEEDED',
14697 message: 'Command sent too fast.'
14698 },
14699 4200: {
14700 name: 'INTERNAL_ERROR',
14701 message: 'Internal error, please contact LeanCloud for support.'
14702 },
14703 4301: {
14704 name: 'CONVERSATION_API_FAILED',
14705 message: 'Upstream Conversatoin API failed, see error.detail for details.'
14706 },
14707 4302: {
14708 name: 'CONVERSATION_SIGNATURE_FAILED',
14709 message: 'Conversation action signature mismatch.'
14710 },
14711 4303: {
14712 name: 'CONVERSATION_NOT_FOUND'
14713 },
14714 4304: {
14715 name: 'CONVERSATION_FULL'
14716 },
14717 4305: {
14718 name: 'CONVERSATION_REJECTED_BY_APP',
14719 message: 'Conversation action rejected by hook.'
14720 },
14721 4306: {
14722 name: 'CONVERSATION_UPDATE_FAILED'
14723 },
14724 4307: {
14725 name: 'CONVERSATION_READ_ONLY'
14726 },
14727 4308: {
14728 name: 'CONVERSATION_NOT_ALLOWED'
14729 },
14730 4309: {
14731 name: 'CONVERSATION_UPDATE_REJECTED',
14732 message: 'Conversation update rejected because the client is not a member.'
14733 },
14734 4310: {
14735 name: 'CONVERSATION_QUERY_FAILED',
14736 message: 'Conversation query failed because it is too expansive.'
14737 },
14738 4311: {
14739 name: 'CONVERSATION_LOG_FAILED'
14740 },
14741 4312: {
14742 name: 'CONVERSATION_LOG_REJECTED',
14743 message: 'Message query rejected because the client is not a member of the conversation.'
14744 },
14745 4313: {
14746 name: 'SYSTEM_CONVERSATION_REQUIRED'
14747 },
14748 4314: {
14749 name: 'NORMAL_CONVERSATION_REQUIRED'
14750 },
14751 4315: {
14752 name: 'CONVERSATION_BLACKLISTED',
14753 message: 'Blacklisted in the conversation.'
14754 },
14755 4316: {
14756 name: 'TRANSIENT_CONVERSATION_REQUIRED'
14757 },
14758 4317: {
14759 name: 'CONVERSATION_MEMBERSHIP_REQUIRED'
14760 },
14761 4318: {
14762 name: 'CONVERSATION_API_QUOTA_EXCEEDED',
14763 message: 'LeanCloud API quota exceeded. You may upgrade your plan.'
14764 },
14765 4323: {
14766 name: 'TEMPORARY_CONVERSATION_EXPIRED',
14767 message: 'Temporary conversation expired or does not exist.'
14768 },
14769 4401: {
14770 name: 'INVALID_MESSAGING_TARGET',
14771 message: 'Conversation does not exist or client is not a member.'
14772 },
14773 4402: {
14774 name: 'MESSAGE_REJECTED_BY_APP',
14775 message: 'Message rejected by hook.'
14776 },
14777 4403: {
14778 name: 'MESSAGE_OWNERSHIP_REQUIRED'
14779 },
14780 4404: {
14781 name: 'MESSAGE_NOT_FOUND'
14782 },
14783 4405: {
14784 name: 'MESSAGE_UPDATE_REJECTED_BY_APP',
14785 message: 'Message update rejected by hook.'
14786 },
14787 4406: {
14788 name: 'MESSAGE_EDIT_DISABLED'
14789 },
14790 4407: {
14791 name: 'MESSAGE_RECALL_DISABLED'
14792 },
14793 5130: {
14794 name: 'OWNER_PROMOTION_NOT_ALLOWED',
14795 message: "Updating a member's role to owner is not allowed."
14796 }
14797 });
14798 var ErrorCode = Object.freeze(Object.keys(error).reduce(function (result, code) {
14799 return Object.assign(result, defineProperty({}, error[code].name, Number(code)));
14800 }, {}));
14801 var createError = function createError(_ref) {
14802 var code = _ref.code,
14803 reason = _ref.reason,
14804 appCode = _ref.appCode,
14805 detail = _ref.detail,
14806 errorMessage = _ref.error;
14807 var message = reason || detail || errorMessage;
14808 var name = reason;
14809
14810 if (!message && error[code]) {
14811 name = error[code].name;
14812 message = error[code].message || name;
14813 }
14814
14815 if (!message) {
14816 message = "Unknow Error: ".concat(code);
14817 }
14818
14819 var err = new Error(message);
14820 return Object.assign(err, {
14821 code: code,
14822 appCode: appCode,
14823 detail: detail,
14824 name: name
14825 });
14826 };
14827
14828 var debug$4 = browser('LC:Connection');
14829 var COMMAND_TIMEOUT = 20000;
14830 var EXPIRE = Symbol('expire');
14831
14832 var isIdempotentCommand = function isIdempotentCommand(command) {
14833 return !(command.cmd === CommandType.direct || command.cmd === CommandType.session && command.op === OpType.open || command.cmd === CommandType.conv && (command.op === OpType.start || command.op === OpType.update || command.op === OpType.members));
14834 };
14835
14836 var Connection = /*#__PURE__*/function (_WebSocketPlus) {
14837 inheritsLoose(Connection, _WebSocketPlus);
14838
14839 function Connection(getUrl, _ref) {
14840 var _this;
14841
14842 var format = _ref.format,
14843 version = _ref.version;
14844 debug$4('initializing Connection');
14845 var protocolString = "lc.".concat(format, ".").concat(version);
14846 _this = _WebSocketPlus.call(this, getUrl, protocolString) || this;
14847 _this._protocolFormat = format;
14848 _this._commands = {};
14849 _this._serialId = 0;
14850 return _this;
14851 }
14852
14853 var _proto = Connection.prototype;
14854
14855 _proto.send = /*#__PURE__*/function () {
14856 var _send = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee(command) {
14857 var _this2 = this;
14858
14859 var waitingForRespond,
14860 buffer,
14861 serialId,
14862 duplicatedCommand,
14863 message,
14864 promise,
14865 _args = arguments;
14866 return regenerator.wrap(function _callee$(_context) {
14867 while (1) {
14868 switch (_context.prev = _context.next) {
14869 case 0:
14870 waitingForRespond = _args.length > 1 && _args[1] !== undefined ? _args[1] : true;
14871
14872 if (!waitingForRespond) {
14873 _context.next = 11;
14874 break;
14875 }
14876
14877 if (!isIdempotentCommand(command)) {
14878 _context.next = 8;
14879 break;
14880 }
14881
14882 buffer = command.toArrayBuffer();
14883 duplicatedCommand = values_1(this._commands).find(function (_ref2) {
14884 var targetBuffer = _ref2.buffer,
14885 targetCommand = _ref2.command;
14886 return targetCommand.cmd === command.cmd && targetCommand.op === command.op && equalBuffer(targetBuffer, buffer);
14887 });
14888
14889 if (!duplicatedCommand) {
14890 _context.next = 8;
14891 break;
14892 }
14893
14894 console.warn("Duplicated command [cmd:".concat(command.cmd, " op:").concat(command.op, "] is throttled."));
14895 return _context.abrupt("return", duplicatedCommand.promise);
14896
14897 case 8:
14898 this._serialId += 1;
14899 serialId = this._serialId;
14900 command.i = serialId; // eslint-disable-line no-param-reassign
14901
14902 case 11:
14903 if (debug$4.enabled) debug$4('↑ %O sent', trim(command));
14904
14905 if (this._protocolFormat === 'proto2base64') {
14906 message = command.toBase64();
14907 } else if (command.toArrayBuffer) {
14908 message = command.toArrayBuffer();
14909 }
14910
14911 if (message) {
14912 _context.next = 15;
14913 break;
14914 }
14915
14916 throw new TypeError("".concat(command, " is not a GenericCommand"));
14917
14918 case 15:
14919 _WebSocketPlus.prototype.send.call(this, message);
14920
14921 if (waitingForRespond) {
14922 _context.next = 18;
14923 break;
14924 }
14925
14926 return _context.abrupt("return", undefined);
14927
14928 case 18:
14929 promise = new Promise(function (resolve, reject) {
14930 _this2._commands[serialId] = {
14931 command: command,
14932 buffer: buffer,
14933 resolve: resolve,
14934 reject: reject,
14935 timeout: setTimeout(function () {
14936 if (_this2._commands[serialId]) {
14937 if (debug$4.enabled) debug$4('✗ %O timeout', trim(command));
14938 reject(createError({
14939 error: "Command Timeout [cmd:".concat(command.cmd, " op:").concat(command.op, "]"),
14940 name: 'COMMAND_TIMEOUT'
14941 }));
14942 delete _this2._commands[serialId];
14943 }
14944 }, COMMAND_TIMEOUT)
14945 };
14946 });
14947 this._commands[serialId].promise = promise;
14948 return _context.abrupt("return", promise);
14949
14950 case 21:
14951 case "end":
14952 return _context.stop();
14953 }
14954 }
14955 }, _callee, this);
14956 }));
14957
14958 function send(_x) {
14959 return _send.apply(this, arguments);
14960 }
14961
14962 return send;
14963 }();
14964
14965 _proto.handleMessage = function handleMessage(msg) {
14966 var message;
14967
14968 try {
14969 message = GenericCommand.decode(msg);
14970 if (debug$4.enabled) debug$4('↓ %O received', trim(message));
14971 } catch (e) {
14972 console.warn('Decode message failed:', e.message, msg);
14973 return;
14974 }
14975
14976 var serialId = message.i;
14977
14978 if (serialId) {
14979 if (this._commands[serialId]) {
14980 clearTimeout(this._commands[serialId].timeout);
14981
14982 if (message.cmd === CommandType.error) {
14983 this._commands[serialId].reject(createError(message.errorMessage));
14984 } else {
14985 this._commands[serialId].resolve(message);
14986 }
14987
14988 delete this._commands[serialId];
14989 } else {
14990 console.warn("Unexpected command received with serialId [".concat(serialId, "],\n which have timed out or never been requested."));
14991 }
14992 } else {
14993 switch (message.cmd) {
14994 case CommandType.error:
14995 {
14996 this.emit(ERROR, createError(message.errorMessage));
14997 return;
14998 }
14999
15000 case CommandType.goaway:
15001 {
15002 this.emit(EXPIRE);
15003 return;
15004 }
15005
15006 default:
15007 {
15008 this.emit(MESSAGE, message);
15009 }
15010 }
15011 }
15012 };
15013
15014 _proto.ping = function ping() {
15015 return this.send(new GenericCommand({
15016 cmd: CommandType.echo
15017 }))["catch"](function (error) {
15018 return debug$4('ping failed:', error);
15019 });
15020 };
15021
15022 return Connection;
15023 }(WebSocketPlus);
15024
15025 var promiseTimeout = createCommonjsModule(function (module) {
15026 /**
15027 * Local reference to TimeoutError
15028 * @private
15029 */
15030
15031 var TimeoutError;
15032 /**
15033 * Rejects a promise with a {@link TimeoutError} if it does not settle within
15034 * the specified timeout.
15035 *
15036 * @param {Promise} promise The promise.
15037 * @param {number} timeoutMillis Number of milliseconds to wait on settling.
15038 * @returns {Promise} Either resolves/rejects with `promise`, or rejects with
15039 * `TimeoutError`, whichever settles first.
15040 */
15041
15042 var timeout = module.exports.timeout = function (promise, timeoutMillis) {
15043 var error = new TimeoutError(),
15044 timeout;
15045 return Promise.race([promise, new Promise(function (resolve, reject) {
15046 timeout = setTimeout(function () {
15047 reject(error);
15048 }, timeoutMillis);
15049 })]).then(function (v) {
15050 clearTimeout(timeout);
15051 return v;
15052 }, function (err) {
15053 clearTimeout(timeout);
15054 throw err;
15055 });
15056 };
15057 /**
15058 * Exception indicating that the timeout expired.
15059 */
15060
15061
15062 TimeoutError = module.exports.TimeoutError = function () {
15063 Error.call(this);
15064 this.stack = Error().stack;
15065 this.message = 'Timeout';
15066 };
15067
15068 TimeoutError.prototype = Object.create(Error.prototype);
15069 TimeoutError.prototype.name = "TimeoutError";
15070 });
15071 var promiseTimeout_1 = promiseTimeout.timeout;
15072 var promiseTimeout_2 = promiseTimeout.TimeoutError;
15073
15074 var debug$5 = browser('LC:request');
15075 var request = (function (_ref) {
15076 var _ref$method = _ref.method,
15077 method = _ref$method === void 0 ? 'GET' : _ref$method,
15078 _url = _ref.url,
15079 query = _ref.query,
15080 headers = _ref.headers,
15081 data = _ref.data,
15082 time = _ref.timeout;
15083 var url = _url;
15084
15085 if (query) {
15086 var queryString = Object.keys(query).map(function (key) {
15087 var value = query[key];
15088 if (value === undefined) return undefined;
15089 var v = isPlainObject_1(value) ? JSON.stringify(value) : value;
15090 return "".concat(encodeURIComponent(key), "=").concat(encodeURIComponent(v));
15091 }).filter(function (qs) {
15092 return qs;
15093 }).join('&');
15094 url = "".concat(url, "?").concat(queryString);
15095 }
15096
15097 debug$5('Req: %O %O %O', method, url, {
15098 headers: headers,
15099 data: data
15100 });
15101 var request = getAdapter('request');
15102 var promise = request(url, {
15103 method: method,
15104 headers: headers,
15105 data: data
15106 }).then(function (response) {
15107 if (response.ok === false) {
15108 var error = createError(response.data);
15109 error.response = response;
15110 throw error;
15111 }
15112
15113 debug$5('Res: %O %O %O', url, response.status, response.data);
15114 return response.data;
15115 })["catch"](function (error) {
15116 if (error.response) {
15117 debug$5('Error: %O %O %O', url, error.response.status, error.response.data);
15118 }
15119
15120 throw error;
15121 });
15122 return time ? promiseTimeout_1(promise, time) : promise;
15123 });
15124
15125 var checkType = function checkType(middleware) {
15126 return function (param) {
15127 var constructor = param.constructor;
15128 return Promise.resolve(param).then(middleware).then(tap(function (result) {
15129 if (result === undefined || result === null) {
15130 // eslint-disable-next-line max-len
15131 return console.warn("Middleware[".concat(middleware._pluginName || 'anonymous plugin', ":").concat(middleware.name || 'anonymous middleware', "] param/return types not match. It returns ").concat(result, " while a ").concat(param.constructor.name, " expected."));
15132 }
15133
15134 if (!(result instanceof constructor)) {
15135 // eslint-disable-next-line max-len
15136 return console.warn("Middleware[".concat(middleware._pluginName || 'anonymous plugin', ":").concat(middleware.name || 'anonymous middleware', "] param/return types not match. It returns a ").concat(result.constructor.name, " while a ").concat(param.constructor.name, " expected."));
15137 }
15138
15139 return 0;
15140 }));
15141 };
15142 };
15143
15144 var applyDecorators = function applyDecorators(decorators, target) {
15145 if (decorators) {
15146 decorators.forEach(function (decorator) {
15147 try {
15148 decorator(target);
15149 } catch (error) {
15150 if (decorator._pluginName) {
15151 error.message += "[".concat(decorator._pluginName, "]");
15152 }
15153
15154 throw error;
15155 }
15156 });
15157 }
15158 };
15159 var applyMiddlewares = function applyMiddlewares(middlewares) {
15160 return function (target) {
15161 return ensureArray(middlewares).reduce(function (previousPromise, middleware) {
15162 return previousPromise.then(checkType(middleware))["catch"](function (error) {
15163 if (middleware._pluginName) {
15164 // eslint-disable-next-line no-param-reassign
15165 error.message += "[".concat(middleware._pluginName, "]");
15166 }
15167
15168 throw error;
15169 });
15170 }, Promise.resolve(target));
15171 };
15172 };
15173 var applyDispatcher = function applyDispatcher(dispatchers, payload) {
15174 return ensureArray(dispatchers).reduce(function (resultPromise, dispatcher) {
15175 return resultPromise.then(function (shouldDispatch) {
15176 return shouldDispatch === false ? false : dispatcher.apply(void 0, toConsumableArray(payload));
15177 })["catch"](function (error) {
15178 if (dispatcher._pluginName) {
15179 // eslint-disable-next-line no-param-reassign
15180 error.message += "[".concat(dispatcher._pluginName, "]");
15181 }
15182
15183 throw error;
15184 });
15185 }, Promise.resolve(true));
15186 };
15187
15188 var version = "5.0.0-rc.7";
15189
15190 function ownKeys$2(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
15191
15192 function _objectSpread$2(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$2(Object(source), true).forEach(function (key) { defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$2(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
15193 var debug$6 = browser('LC:Realtime');
15194 var routerCache = new Cache('push-router');
15195 var initializedApp = {};
15196
15197 var Realtime = /*#__PURE__*/function (_EventEmitter) {
15198 inheritsLoose(Realtime, _EventEmitter);
15199
15200 /**
15201 * @extends EventEmitter
15202 * @param {Object} options
15203 * @param {String} options.appId
15204 * @param {String} options.appKey (since 4.0.0)
15205 * @param {String|Object} [options.server] 指定服务器域名,中国节点应用此参数必填(since 4.0.0)
15206 * @param {Boolean} [options.noBinary=false] 设置 WebSocket 使用字符串格式收发消息(默认为二进制格式)。
15207 * 适用于 WebSocket 实现不支持二进制数据格式的情况
15208 * @param {Boolean} [options.ssl=true] 使用 wss 进行连接
15209 * @param {String|String[]} [options.RTMServers] 指定私有部署的 RTM 服务器地址(since 4.0.0)
15210 * @param {Plugin[]} [options.plugins] 加载插件(since 3.1.0)
15211 */
15212 function Realtime(_ref) {
15213 var _this2;
15214
15215 var plugins = _ref.plugins,
15216 options = objectWithoutProperties(_ref, ["plugins"]);
15217
15218 debug$6('initializing Realtime %s %O', version, options);
15219 _this2 = _EventEmitter.call(this) || this;
15220 var appId = options.appId;
15221
15222 if (typeof appId !== 'string') {
15223 throw new TypeError("appId [".concat(appId, "] is not a string"));
15224 }
15225
15226 if (initializedApp[appId]) {
15227 throw new Error("App [".concat(appId, "] is already initialized."));
15228 }
15229
15230 initializedApp[appId] = true;
15231
15232 if (typeof options.appKey !== 'string') {
15233 throw new TypeError("appKey [".concat(options.appKey, "] is not a string"));
15234 }
15235
15236 if (isCNApp(appId)) {
15237 if (!options.server) {
15238 throw new TypeError("server option is required for apps from CN region");
15239 }
15240 }
15241
15242 _this2._options = _objectSpread$2({
15243 appId: undefined,
15244 appKey: undefined,
15245 noBinary: false,
15246 ssl: true,
15247 RTMServerName: typeof process !== 'undefined' ? process.env.RTM_SERVER_NAME : undefined
15248 }, options);
15249 _this2._cache = new Cache('endpoints');
15250
15251 var _this = internal(assertThisInitialized(_this2));
15252
15253 _this.clients = new Set();
15254 _this.pendingClients = new Set();
15255 var mergedPlugins = [].concat(toConsumableArray(ensureArray(Realtime.__preRegisteredPlugins)), toConsumableArray(ensureArray(plugins)));
15256 debug$6('Using plugins %o', mergedPlugins.map(function (plugin) {
15257 return plugin.name;
15258 }));
15259 _this2._plugins = mergedPlugins.reduce(function (result, plugin) {
15260 Object.keys(plugin).forEach(function (hook) {
15261 if ({}.hasOwnProperty.call(plugin, hook) && hook !== 'name') {
15262 if (plugin.name) {
15263 ensureArray(plugin[hook]).forEach(function (value) {
15264 // eslint-disable-next-line no-param-reassign
15265 value._pluginName = plugin.name;
15266 });
15267 } // eslint-disable-next-line no-param-reassign
15268
15269
15270 result[hook] = ensureArray(result[hook]).concat(plugin[hook]);
15271 }
15272 });
15273 return result;
15274 }, {}); // onRealtimeCreate hook
15275
15276 applyDecorators(_this2._plugins.onRealtimeCreate, assertThisInitialized(_this2));
15277 return _this2;
15278 }
15279
15280 var _proto = Realtime.prototype;
15281
15282 _proto._request = /*#__PURE__*/function () {
15283 var _request2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee(_ref2) {
15284 var method, _url, _ref2$version, version, path, query, headers, data, url, _this$_options, appId, server, _yield$this$construct, api;
15285
15286 return regenerator.wrap(function _callee$(_context) {
15287 while (1) {
15288 switch (_context.prev = _context.next) {
15289 case 0:
15290 method = _ref2.method, _url = _ref2.url, _ref2$version = _ref2.version, version = _ref2$version === void 0 ? '1.1' : _ref2$version, path = _ref2.path, query = _ref2.query, headers = _ref2.headers, data = _ref2.data;
15291 url = _url;
15292
15293 if (url) {
15294 _context.next = 9;
15295 break;
15296 }
15297
15298 _this$_options = this._options, appId = _this$_options.appId, server = _this$_options.server;
15299 _context.next = 6;
15300 return this.constructor._getServerUrls({
15301 appId: appId,
15302 server: server
15303 });
15304
15305 case 6:
15306 _yield$this$construct = _context.sent;
15307 api = _yield$this$construct.api;
15308 url = "".concat(api, "/").concat(version).concat(path);
15309
15310 case 9:
15311 return _context.abrupt("return", request({
15312 url: url,
15313 method: method,
15314 query: query,
15315 headers: _objectSpread$2({
15316 'X-LC-Id': this._options.appId,
15317 'X-LC-Key': this._options.appKey
15318 }, headers),
15319 data: data
15320 }));
15321
15322 case 10:
15323 case "end":
15324 return _context.stop();
15325 }
15326 }
15327 }, _callee, this);
15328 }));
15329
15330 function _request(_x) {
15331 return _request2.apply(this, arguments);
15332 }
15333
15334 return _request;
15335 }();
15336
15337 _proto._open = function _open() {
15338 var _this3 = this;
15339
15340 if (this._openPromise) return this._openPromise;
15341 var format = 'protobuf2';
15342
15343 if (this._options.noBinary) {
15344 // 不发送 binary data,fallback to base64 string
15345 format = 'proto2base64';
15346 }
15347
15348 var version = 3;
15349 var protocol = {
15350 format: format,
15351 version: version
15352 };
15353 this._openPromise = new Promise(function (resolve, reject) {
15354 debug$6('No connection established, create a new one.');
15355 var connection = new Connection(function () {
15356 return _this3._getRTMServers(_this3._options);
15357 }, protocol);
15358 connection.on(OPEN, function () {
15359 return resolve(connection);
15360 }).on(ERROR, function (error) {
15361 delete _this3._openPromise;
15362 reject(error);
15363 }).on(EXPIRE, /*#__PURE__*/asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee2() {
15364 return regenerator.wrap(function _callee2$(_context2) {
15365 while (1) {
15366 switch (_context2.prev = _context2.next) {
15367 case 0:
15368 debug$6('Connection expired. Refresh endpoints.');
15369
15370 _this3._cache.set('endpoints', null, 0);
15371
15372 _context2.next = 4;
15373 return _this3._getRTMServers(_this3._options);
15374
15375 case 4:
15376 connection.urls = _context2.sent;
15377 connection.disconnect();
15378
15379 case 6:
15380 case "end":
15381 return _context2.stop();
15382 }
15383 }
15384 }, _callee2);
15385 }))).on(MESSAGE, _this3._dispatchCommand.bind(_this3));
15386 /**
15387 * 连接断开。
15388 * 连接断开可能是因为 SDK 进入了离线状态(see {@link Realtime#event:OFFLINE}),或长时间没有收到服务器心跳。
15389 * 连接断开后所有的网络操作都会失败,请在连接断开后禁用相关的 UI 元素。
15390 * @event Realtime#DISCONNECT
15391 */
15392
15393 /**
15394 * 计划在一段时间后尝试重新连接
15395 * @event Realtime#SCHEDULE
15396 * @param {Number} attempt 尝试重连的次数
15397 * @param {Number} delay 延迟的毫秒数
15398 */
15399
15400 /**
15401 * 正在尝试重新连接
15402 * @event Realtime#RETRY
15403 * @param {Number} attempt 尝试重连的次数
15404 */
15405
15406 /**
15407 * 连接恢复正常。
15408 * 请重新启用在 {@link Realtime#event:DISCONNECT} 事件中禁用的相关 UI 元素
15409 * @event Realtime#RECONNECT
15410 */
15411
15412 /**
15413 * 客户端连接断开
15414 * @event IMClient#DISCONNECT
15415 * @see Realtime#event:DISCONNECT
15416 * @since 3.2.0
15417 */
15418
15419 /**
15420 * 计划在一段时间后尝试重新连接
15421 * @event IMClient#SCHEDULE
15422 * @param {Number} attempt 尝试重连的次数
15423 * @param {Number} delay 延迟的毫秒数
15424 * @since 3.2.0
15425 */
15426
15427 /**
15428 * 正在尝试重新连接
15429 * @event IMClient#RETRY
15430 * @param {Number} attempt 尝试重连的次数
15431 * @since 3.2.0
15432 */
15433
15434 /**
15435 * 客户端进入离线状态。
15436 * 这通常意味着网络已断开,或者 {@link Realtime#pause} 被调用
15437 * @event Realtime#OFFLINE
15438 * @since 3.4.0
15439 */
15440
15441 /**
15442 * 客户端恢复在线状态
15443 * 这通常意味着网络已恢复,或者 {@link Realtime#resume} 被调用
15444 * @event Realtime#ONLINE
15445 * @since 3.4.0
15446 */
15447
15448 /**
15449 * 进入离线状态。
15450 * 这通常意味着网络已断开,或者 {@link Realtime#pause} 被调用
15451 * @event IMClient#OFFLINE
15452 * @since 3.4.0
15453 */
15454
15455 /**
15456 * 恢复在线状态
15457 * 这通常意味着网络已恢复,或者 {@link Realtime#resume} 被调用
15458 * @event IMClient#ONLINE
15459 * @since 3.4.0
15460 */
15461 // event proxy
15462
15463 [DISCONNECT, RECONNECT, RETRY, SCHEDULE, OFFLINE, ONLINE].forEach(function (event) {
15464 return connection.on(event, function () {
15465 for (var _len = arguments.length, payload = new Array(_len), _key = 0; _key < _len; _key++) {
15466 payload[_key] = arguments[_key];
15467 }
15468
15469 debug$6("".concat(event, " event emitted. %o"), payload);
15470
15471 _this3.emit.apply(_this3, [event].concat(payload));
15472
15473 if (event !== RECONNECT) {
15474 internal(_this3).clients.forEach(function (client) {
15475 client.emit.apply(client, [event].concat(payload));
15476 });
15477 }
15478 });
15479 }); // override handleClose
15480
15481 connection.handleClose = function handleClose(event) {
15482 var isFatal = [ErrorCode.APP_NOT_AVAILABLE, ErrorCode.INVALID_LOGIN, ErrorCode.INVALID_ORIGIN].some(function (errorCode) {
15483 return errorCode === event.code;
15484 });
15485
15486 if (isFatal) {
15487 // in these cases, SDK should throw.
15488 this["throw"](createError(event));
15489 } else {
15490 // reconnect
15491 this.disconnect();
15492 }
15493 };
15494
15495 internal(_this3).connection = connection;
15496 });
15497 return this._openPromise;
15498 };
15499
15500 _proto._getRTMServers = /*#__PURE__*/function () {
15501 var _getRTMServers2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee3(options) {
15502 var info, cachedEndPoints, _info, server, secondary, ttl;
15503
15504 return regenerator.wrap(function _callee3$(_context3) {
15505 while (1) {
15506 switch (_context3.prev = _context3.next) {
15507 case 0:
15508 if (!options.RTMServers) {
15509 _context3.next = 2;
15510 break;
15511 }
15512
15513 return _context3.abrupt("return", shuffle_1(ensureArray(options.RTMServers)));
15514
15515 case 2:
15516 cachedEndPoints = this._cache.get('endpoints');
15517
15518 if (!cachedEndPoints) {
15519 _context3.next = 7;
15520 break;
15521 }
15522
15523 info = cachedEndPoints;
15524 _context3.next = 14;
15525 break;
15526
15527 case 7:
15528 _context3.next = 9;
15529 return this.constructor._fetchRTMServers(options);
15530
15531 case 9:
15532 info = _context3.sent;
15533 _info = info, server = _info.server, secondary = _info.secondary, ttl = _info.ttl;
15534
15535 if (!(typeof server !== 'string' && typeof secondary !== 'string' && typeof ttl !== 'number')) {
15536 _context3.next = 13;
15537 break;
15538 }
15539
15540 throw new Error("malformed RTM route response: ".concat(JSON.stringify(info)));
15541
15542 case 13:
15543 this._cache.set('endpoints', info, info.ttl * 1000);
15544
15545 case 14:
15546 debug$6('endpoint info: %O', info);
15547 return _context3.abrupt("return", [info.server, info.secondary]);
15548
15549 case 16:
15550 case "end":
15551 return _context3.stop();
15552 }
15553 }
15554 }, _callee3, this);
15555 }));
15556
15557 function _getRTMServers(_x2) {
15558 return _getRTMServers2.apply(this, arguments);
15559 }
15560
15561 return _getRTMServers;
15562 }();
15563
15564 Realtime._getServerUrls = /*#__PURE__*/function () {
15565 var _getServerUrls2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee4(_ref4) {
15566 var appId, server, cachedRouter, defaultProtocol;
15567 return regenerator.wrap(function _callee4$(_context4) {
15568 while (1) {
15569 switch (_context4.prev = _context4.next) {
15570 case 0:
15571 appId = _ref4.appId, server = _ref4.server;
15572 debug$6('fetch server urls');
15573
15574 if (!server) {
15575 _context4.next = 6;
15576 break;
15577 }
15578
15579 if (!(typeof server !== 'string')) {
15580 _context4.next = 5;
15581 break;
15582 }
15583
15584 return _context4.abrupt("return", server);
15585
15586 case 5:
15587 return _context4.abrupt("return", {
15588 RTMRouter: server,
15589 api: server
15590 });
15591
15592 case 6:
15593 cachedRouter = routerCache.get(appId);
15594
15595 if (!cachedRouter) {
15596 _context4.next = 9;
15597 break;
15598 }
15599
15600 return _context4.abrupt("return", cachedRouter);
15601
15602 case 9:
15603 defaultProtocol = 'https://';
15604 return _context4.abrupt("return", request({
15605 url: 'https://app-router.com/2/route',
15606 query: {
15607 appId: appId
15608 },
15609 timeout: 20000
15610 }).then(tap(debug$6)).then(function (_ref5) {
15611 var RTMRouterServer = _ref5.rtm_router_server,
15612 APIServer = _ref5.api_server,
15613 _ref5$ttl = _ref5.ttl,
15614 ttl = _ref5$ttl === void 0 ? 3600 : _ref5$ttl;
15615
15616 if (!RTMRouterServer) {
15617 throw new Error('rtm router not exists');
15618 }
15619
15620 var serverUrls = {
15621 RTMRouter: "".concat(defaultProtocol).concat(RTMRouterServer),
15622 api: "".concat(defaultProtocol).concat(APIServer)
15623 };
15624 routerCache.set(appId, serverUrls, ttl * 1000);
15625 return serverUrls;
15626 })["catch"](function () {
15627 var id = appId.slice(0, 8).toLowerCase();
15628 var domain = 'lncldglobal.com';
15629 return {
15630 RTMRouter: "".concat(defaultProtocol).concat(id, ".rtm.").concat(domain),
15631 api: "".concat(defaultProtocol).concat(id, ".api.").concat(domain)
15632 };
15633 }));
15634
15635 case 11:
15636 case "end":
15637 return _context4.stop();
15638 }
15639 }
15640 }, _callee4);
15641 }));
15642
15643 function _getServerUrls(_x3) {
15644 return _getServerUrls2.apply(this, arguments);
15645 }
15646
15647 return _getServerUrls;
15648 }();
15649
15650 Realtime._fetchRTMServers = function _fetchRTMServers(_ref6) {
15651 var appId = _ref6.appId,
15652 ssl = _ref6.ssl,
15653 server = _ref6.server,
15654 RTMServerName = _ref6.RTMServerName;
15655 debug$6('fetch endpoint info');
15656 return this._getServerUrls({
15657 appId: appId,
15658 server: server
15659 }).then(tap(debug$6)).then(function (_ref7) {
15660 var RTMRouter = _ref7.RTMRouter;
15661 return request({
15662 url: "".concat(RTMRouter, "/v1/route"),
15663 query: {
15664 appId: appId,
15665 secure: ssl,
15666 features: isWeapp ? 'wechat' : undefined,
15667 server: RTMServerName,
15668 _t: Date.now()
15669 },
15670 timeout: 20000
15671 }).then(tap(debug$6));
15672 });
15673 };
15674
15675 _proto._close = function _close() {
15676 if (this._openPromise) {
15677 this._openPromise.then(function (connection) {
15678 return connection.close();
15679 });
15680 }
15681
15682 delete this._openPromise;
15683 }
15684 /**
15685 * 手动进行重连。
15686 * SDK 在网络出现异常时会自动按照一定的时间间隔尝试重连,调用该方法会立即尝试重连并重置重连尝试计数器。
15687 * 只能在 `SCHEDULE` 事件之后,`RETRY` 事件之前调用,如果当前网络正常或者正在进行重连,调用该方法会抛异常。
15688 */
15689 ;
15690
15691 _proto.retry = function retry() {
15692 var _internal = internal(this),
15693 connection = _internal.connection;
15694
15695 if (!connection) {
15696 throw new Error('no connection established');
15697 }
15698
15699 if (connection.cannot('retry')) {
15700 throw new Error("retrying not allowed when not disconnected. the connection is now ".concat(connection.current));
15701 }
15702
15703 return connection.retry();
15704 }
15705 /**
15706 * 暂停,使 SDK 进入离线状态。
15707 * 你可以在网络断开、应用进入后台等时刻调用该方法让 SDK 进入离线状态,离线状态下不会尝试重连。
15708 * 在浏览器中 SDK 会自动监听网络变化,因此无需手动调用该方法。
15709 *
15710 * @since 3.4.0
15711 * @see Realtime#event:OFFLINE
15712 */
15713 ;
15714
15715 _proto.pause = function pause() {
15716 // 这个方法常常在网络断开、进入后台时被调用,此时 connection 可能没有建立或者已经 close。
15717 // 因此不像 retry,这个方法应该尽可能 loose
15718 var _internal2 = internal(this),
15719 connection = _internal2.connection;
15720
15721 if (!connection) return;
15722 if (connection.can('pause')) connection.pause();
15723 }
15724 /**
15725 * 恢复在线状态。
15726 * 你可以在网络恢复、应用回到前台等时刻调用该方法让 SDK 恢复在线状态,恢复在线状态后 SDK 会开始尝试重连。
15727 *
15728 * @since 3.4.0
15729 * @see Realtime#event:ONLINE
15730 */
15731 ;
15732
15733 _proto.resume = function resume() {
15734 // 与 pause 一样,这个方法应该尽可能 loose
15735 var _internal3 = internal(this),
15736 connection = _internal3.connection;
15737
15738 if (!connection) return;
15739 if (connection.can('resume')) connection.resume();
15740 };
15741
15742 _proto._registerPending = function _registerPending(value) {
15743 internal(this).pendingClients.add(value);
15744 };
15745
15746 _proto._deregisterPending = function _deregisterPending(client) {
15747 internal(this).pendingClients["delete"](client);
15748 };
15749
15750 _proto._register = function _register(client) {
15751 internal(this).clients.add(client);
15752 };
15753
15754 _proto._deregister = function _deregister(client) {
15755 var _this = internal(this);
15756
15757 _this.clients["delete"](client);
15758
15759 if (_this.clients.size + _this.pendingClients.size === 0) {
15760 this._close();
15761 }
15762 };
15763
15764 _proto._dispatchCommand = function _dispatchCommand(command) {
15765 return applyDispatcher(this._plugins.beforeCommandDispatch, [command, this]).then(function (shouldDispatch) {
15766 // no plugin handled this command
15767 if (shouldDispatch) return debug$6('[WARN] Unexpected message received: %O', trim(command));
15768 return false;
15769 });
15770 };
15771
15772 return Realtime;
15773 }(eventemitter3); // For test purpose only
15774
15775 var polyfilledPromise = Promise;
15776
15777 var rngBrowser = createCommonjsModule(function (module) {
15778 // Unique ID creation requires a high quality random # generator. In the
15779 // browser this is a little complicated due to unknown quality of Math.random()
15780 // and inconsistent support for the `crypto` API. We do the best we can via
15781 // feature-detection
15782
15783 // getRandomValues needs to be invoked in a context where "this" is a Crypto
15784 // implementation. Also, find the complete implementation of crypto on IE11.
15785 var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) ||
15786 (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto));
15787
15788 if (getRandomValues) {
15789 // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto
15790 var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef
15791
15792 module.exports = function whatwgRNG() {
15793 getRandomValues(rnds8);
15794 return rnds8;
15795 };
15796 } else {
15797 // Math.random()-based (RNG)
15798 //
15799 // If all else fails, use Math.random(). It's fast, but is of unspecified
15800 // quality.
15801 var rnds = new Array(16);
15802
15803 module.exports = function mathRNG() {
15804 for (var i = 0, r; i < 16; i++) {
15805 if ((i & 0x03) === 0) r = Math.random() * 0x100000000;
15806 rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
15807 }
15808
15809 return rnds;
15810 };
15811 }
15812 });
15813
15814 /**
15815 * Convert array of 16 byte values to UUID string format of the form:
15816 * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
15817 */
15818 var byteToHex = [];
15819 for (var i = 0; i < 256; ++i) {
15820 byteToHex[i] = (i + 0x100).toString(16).substr(1);
15821 }
15822
15823 function bytesToUuid(buf, offset) {
15824 var i = offset || 0;
15825 var bth = byteToHex;
15826 // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4
15827 return ([bth[buf[i++]], bth[buf[i++]],
15828 bth[buf[i++]], bth[buf[i++]], '-',
15829 bth[buf[i++]], bth[buf[i++]], '-',
15830 bth[buf[i++]], bth[buf[i++]], '-',
15831 bth[buf[i++]], bth[buf[i++]], '-',
15832 bth[buf[i++]], bth[buf[i++]],
15833 bth[buf[i++]], bth[buf[i++]],
15834 bth[buf[i++]], bth[buf[i++]]]).join('');
15835 }
15836
15837 var bytesToUuid_1 = bytesToUuid;
15838
15839 function v4(options, buf, offset) {
15840 var i = buf && offset || 0;
15841
15842 if (typeof(options) == 'string') {
15843 buf = options === 'binary' ? new Array(16) : null;
15844 options = null;
15845 }
15846 options = options || {};
15847
15848 var rnds = options.random || (options.rng || rngBrowser)();
15849
15850 // Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
15851 rnds[6] = (rnds[6] & 0x0f) | 0x40;
15852 rnds[8] = (rnds[8] & 0x3f) | 0x80;
15853
15854 // Copy bytes to buffer, if provided
15855 if (buf) {
15856 for (var ii = 0; ii < 16; ++ii) {
15857 buf[i + ii] = rnds[ii];
15858 }
15859 }
15860
15861 return buf || bytesToUuid_1(rnds);
15862 }
15863
15864 var v4_1 = v4;
15865
15866 function _iterableToArrayLimit(arr, i) {
15867 if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return;
15868 var _arr = [];
15869 var _n = true;
15870 var _d = false;
15871 var _e = undefined;
15872
15873 try {
15874 for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
15875 _arr.push(_s.value);
15876
15877 if (i && _arr.length === i) break;
15878 }
15879 } catch (err) {
15880 _d = true;
15881 _e = err;
15882 } finally {
15883 try {
15884 if (!_n && _i["return"] != null) _i["return"]();
15885 } finally {
15886 if (_d) throw _e;
15887 }
15888 }
15889
15890 return _arr;
15891 }
15892
15893 var iterableToArrayLimit = _iterableToArrayLimit;
15894
15895 function _slicedToArray(arr, i) {
15896 return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();
15897 }
15898
15899 var slicedToArray = _slicedToArray;
15900
15901 var base64Arraybuffer = createCommonjsModule(function (module, exports) {
15902 /*
15903 * base64-arraybuffer
15904 * https://github.com/niklasvh/base64-arraybuffer
15905 *
15906 * Copyright (c) 2012 Niklas von Hertzen
15907 * Licensed under the MIT license.
15908 */
15909 (function(){
15910
15911 var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
15912
15913 // Use a lookup table to find the index.
15914 var lookup = new Uint8Array(256);
15915 for (var i = 0; i < chars.length; i++) {
15916 lookup[chars.charCodeAt(i)] = i;
15917 }
15918
15919 exports.encode = function(arraybuffer) {
15920 var bytes = new Uint8Array(arraybuffer),
15921 i, len = bytes.length, base64 = "";
15922
15923 for (i = 0; i < len; i+=3) {
15924 base64 += chars[bytes[i] >> 2];
15925 base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
15926 base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
15927 base64 += chars[bytes[i + 2] & 63];
15928 }
15929
15930 if ((len % 3) === 2) {
15931 base64 = base64.substring(0, base64.length - 1) + "=";
15932 } else if (len % 3 === 1) {
15933 base64 = base64.substring(0, base64.length - 2) + "==";
15934 }
15935
15936 return base64;
15937 };
15938
15939 exports.decode = function(base64) {
15940 var bufferLength = base64.length * 0.75,
15941 len = base64.length, i, p = 0,
15942 encoded1, encoded2, encoded3, encoded4;
15943
15944 if (base64[base64.length - 1] === "=") {
15945 bufferLength--;
15946 if (base64[base64.length - 2] === "=") {
15947 bufferLength--;
15948 }
15949 }
15950
15951 var arraybuffer = new ArrayBuffer(bufferLength),
15952 bytes = new Uint8Array(arraybuffer);
15953
15954 for (i = 0; i < len; i+=4) {
15955 encoded1 = lookup[base64.charCodeAt(i)];
15956 encoded2 = lookup[base64.charCodeAt(i+1)];
15957 encoded3 = lookup[base64.charCodeAt(i+2)];
15958 encoded4 = lookup[base64.charCodeAt(i+3)];
15959
15960 bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
15961 bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
15962 bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
15963 }
15964
15965 return arraybuffer;
15966 };
15967 })();
15968 });
15969 var base64Arraybuffer_1 = base64Arraybuffer.encode;
15970 var base64Arraybuffer_2 = base64Arraybuffer.decode;
15971
15972 /**
15973 * Removes all key-value entries from the list cache.
15974 *
15975 * @private
15976 * @name clear
15977 * @memberOf ListCache
15978 */
15979 function listCacheClear() {
15980 this.__data__ = [];
15981 this.size = 0;
15982 }
15983
15984 var _listCacheClear = listCacheClear;
15985
15986 /**
15987 * Performs a
15988 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
15989 * comparison between two values to determine if they are equivalent.
15990 *
15991 * @static
15992 * @memberOf _
15993 * @since 4.0.0
15994 * @category Lang
15995 * @param {*} value The value to compare.
15996 * @param {*} other The other value to compare.
15997 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
15998 * @example
15999 *
16000 * var object = { 'a': 1 };
16001 * var other = { 'a': 1 };
16002 *
16003 * _.eq(object, object);
16004 * // => true
16005 *
16006 * _.eq(object, other);
16007 * // => false
16008 *
16009 * _.eq('a', 'a');
16010 * // => true
16011 *
16012 * _.eq('a', Object('a'));
16013 * // => false
16014 *
16015 * _.eq(NaN, NaN);
16016 * // => true
16017 */
16018 function eq(value, other) {
16019 return value === other || (value !== value && other !== other);
16020 }
16021
16022 var eq_1 = eq;
16023
16024 /**
16025 * Gets the index at which the `key` is found in `array` of key-value pairs.
16026 *
16027 * @private
16028 * @param {Array} array The array to inspect.
16029 * @param {*} key The key to search for.
16030 * @returns {number} Returns the index of the matched value, else `-1`.
16031 */
16032 function assocIndexOf(array, key) {
16033 var length = array.length;
16034 while (length--) {
16035 if (eq_1(array[length][0], key)) {
16036 return length;
16037 }
16038 }
16039 return -1;
16040 }
16041
16042 var _assocIndexOf = assocIndexOf;
16043
16044 /** Used for built-in method references. */
16045 var arrayProto = Array.prototype;
16046
16047 /** Built-in value references. */
16048 var splice = arrayProto.splice;
16049
16050 /**
16051 * Removes `key` and its value from the list cache.
16052 *
16053 * @private
16054 * @name delete
16055 * @memberOf ListCache
16056 * @param {string} key The key of the value to remove.
16057 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
16058 */
16059 function listCacheDelete(key) {
16060 var data = this.__data__,
16061 index = _assocIndexOf(data, key);
16062
16063 if (index < 0) {
16064 return false;
16065 }
16066 var lastIndex = data.length - 1;
16067 if (index == lastIndex) {
16068 data.pop();
16069 } else {
16070 splice.call(data, index, 1);
16071 }
16072 --this.size;
16073 return true;
16074 }
16075
16076 var _listCacheDelete = listCacheDelete;
16077
16078 /**
16079 * Gets the list cache value for `key`.
16080 *
16081 * @private
16082 * @name get
16083 * @memberOf ListCache
16084 * @param {string} key The key of the value to get.
16085 * @returns {*} Returns the entry value.
16086 */
16087 function listCacheGet(key) {
16088 var data = this.__data__,
16089 index = _assocIndexOf(data, key);
16090
16091 return index < 0 ? undefined : data[index][1];
16092 }
16093
16094 var _listCacheGet = listCacheGet;
16095
16096 /**
16097 * Checks if a list cache value for `key` exists.
16098 *
16099 * @private
16100 * @name has
16101 * @memberOf ListCache
16102 * @param {string} key The key of the entry to check.
16103 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
16104 */
16105 function listCacheHas(key) {
16106 return _assocIndexOf(this.__data__, key) > -1;
16107 }
16108
16109 var _listCacheHas = listCacheHas;
16110
16111 /**
16112 * Sets the list cache `key` to `value`.
16113 *
16114 * @private
16115 * @name set
16116 * @memberOf ListCache
16117 * @param {string} key The key of the value to set.
16118 * @param {*} value The value to set.
16119 * @returns {Object} Returns the list cache instance.
16120 */
16121 function listCacheSet(key, value) {
16122 var data = this.__data__,
16123 index = _assocIndexOf(data, key);
16124
16125 if (index < 0) {
16126 ++this.size;
16127 data.push([key, value]);
16128 } else {
16129 data[index][1] = value;
16130 }
16131 return this;
16132 }
16133
16134 var _listCacheSet = listCacheSet;
16135
16136 /**
16137 * Creates an list cache object.
16138 *
16139 * @private
16140 * @constructor
16141 * @param {Array} [entries] The key-value pairs to cache.
16142 */
16143 function ListCache(entries) {
16144 var index = -1,
16145 length = entries == null ? 0 : entries.length;
16146
16147 this.clear();
16148 while (++index < length) {
16149 var entry = entries[index];
16150 this.set(entry[0], entry[1]);
16151 }
16152 }
16153
16154 // Add methods to `ListCache`.
16155 ListCache.prototype.clear = _listCacheClear;
16156 ListCache.prototype['delete'] = _listCacheDelete;
16157 ListCache.prototype.get = _listCacheGet;
16158 ListCache.prototype.has = _listCacheHas;
16159 ListCache.prototype.set = _listCacheSet;
16160
16161 var _ListCache = ListCache;
16162
16163 /**
16164 * Removes all key-value entries from the stack.
16165 *
16166 * @private
16167 * @name clear
16168 * @memberOf Stack
16169 */
16170 function stackClear() {
16171 this.__data__ = new _ListCache;
16172 this.size = 0;
16173 }
16174
16175 var _stackClear = stackClear;
16176
16177 /**
16178 * Removes `key` and its value from the stack.
16179 *
16180 * @private
16181 * @name delete
16182 * @memberOf Stack
16183 * @param {string} key The key of the value to remove.
16184 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
16185 */
16186 function stackDelete(key) {
16187 var data = this.__data__,
16188 result = data['delete'](key);
16189
16190 this.size = data.size;
16191 return result;
16192 }
16193
16194 var _stackDelete = stackDelete;
16195
16196 /**
16197 * Gets the stack value for `key`.
16198 *
16199 * @private
16200 * @name get
16201 * @memberOf Stack
16202 * @param {string} key The key of the value to get.
16203 * @returns {*} Returns the entry value.
16204 */
16205 function stackGet(key) {
16206 return this.__data__.get(key);
16207 }
16208
16209 var _stackGet = stackGet;
16210
16211 /**
16212 * Checks if a stack value for `key` exists.
16213 *
16214 * @private
16215 * @name has
16216 * @memberOf Stack
16217 * @param {string} key The key of the entry to check.
16218 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
16219 */
16220 function stackHas(key) {
16221 return this.__data__.has(key);
16222 }
16223
16224 var _stackHas = stackHas;
16225
16226 /** Used to detect overreaching core-js shims. */
16227 var coreJsData = _root['__core-js_shared__'];
16228
16229 var _coreJsData = coreJsData;
16230
16231 /** Used to detect methods masquerading as native. */
16232 var maskSrcKey = (function() {
16233 var uid = /[^.]+$/.exec(_coreJsData && _coreJsData.keys && _coreJsData.keys.IE_PROTO || '');
16234 return uid ? ('Symbol(src)_1.' + uid) : '';
16235 }());
16236
16237 /**
16238 * Checks if `func` has its source masked.
16239 *
16240 * @private
16241 * @param {Function} func The function to check.
16242 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
16243 */
16244 function isMasked(func) {
16245 return !!maskSrcKey && (maskSrcKey in func);
16246 }
16247
16248 var _isMasked = isMasked;
16249
16250 /** Used for built-in method references. */
16251 var funcProto$1 = Function.prototype;
16252
16253 /** Used to resolve the decompiled source of functions. */
16254 var funcToString$1 = funcProto$1.toString;
16255
16256 /**
16257 * Converts `func` to its source code.
16258 *
16259 * @private
16260 * @param {Function} func The function to convert.
16261 * @returns {string} Returns the source code.
16262 */
16263 function toSource(func) {
16264 if (func != null) {
16265 try {
16266 return funcToString$1.call(func);
16267 } catch (e) {}
16268 try {
16269 return (func + '');
16270 } catch (e) {}
16271 }
16272 return '';
16273 }
16274
16275 var _toSource = toSource;
16276
16277 /**
16278 * Used to match `RegExp`
16279 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
16280 */
16281 var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
16282
16283 /** Used to detect host constructors (Safari). */
16284 var reIsHostCtor = /^\[object .+?Constructor\]$/;
16285
16286 /** Used for built-in method references. */
16287 var funcProto$2 = Function.prototype,
16288 objectProto$7 = Object.prototype;
16289
16290 /** Used to resolve the decompiled source of functions. */
16291 var funcToString$2 = funcProto$2.toString;
16292
16293 /** Used to check objects for own properties. */
16294 var hasOwnProperty$5 = objectProto$7.hasOwnProperty;
16295
16296 /** Used to detect if a method is native. */
16297 var reIsNative = RegExp('^' +
16298 funcToString$2.call(hasOwnProperty$5).replace(reRegExpChar, '\\$&')
16299 .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
16300 );
16301
16302 /**
16303 * The base implementation of `_.isNative` without bad shim checks.
16304 *
16305 * @private
16306 * @param {*} value The value to check.
16307 * @returns {boolean} Returns `true` if `value` is a native function,
16308 * else `false`.
16309 */
16310 function baseIsNative(value) {
16311 if (!isObject_1(value) || _isMasked(value)) {
16312 return false;
16313 }
16314 var pattern = isFunction_1(value) ? reIsNative : reIsHostCtor;
16315 return pattern.test(_toSource(value));
16316 }
16317
16318 var _baseIsNative = baseIsNative;
16319
16320 /**
16321 * Gets the value at `key` of `object`.
16322 *
16323 * @private
16324 * @param {Object} [object] The object to query.
16325 * @param {string} key The key of the property to get.
16326 * @returns {*} Returns the property value.
16327 */
16328 function getValue(object, key) {
16329 return object == null ? undefined : object[key];
16330 }
16331
16332 var _getValue = getValue;
16333
16334 /**
16335 * Gets the native function at `key` of `object`.
16336 *
16337 * @private
16338 * @param {Object} object The object to query.
16339 * @param {string} key The key of the method to get.
16340 * @returns {*} Returns the function if it's native, else `undefined`.
16341 */
16342 function getNative(object, key) {
16343 var value = _getValue(object, key);
16344 return _baseIsNative(value) ? value : undefined;
16345 }
16346
16347 var _getNative = getNative;
16348
16349 /* Built-in method references that are verified to be native. */
16350 var Map = _getNative(_root, 'Map');
16351
16352 var _Map = Map;
16353
16354 /* Built-in method references that are verified to be native. */
16355 var nativeCreate = _getNative(Object, 'create');
16356
16357 var _nativeCreate = nativeCreate;
16358
16359 /**
16360 * Removes all key-value entries from the hash.
16361 *
16362 * @private
16363 * @name clear
16364 * @memberOf Hash
16365 */
16366 function hashClear() {
16367 this.__data__ = _nativeCreate ? _nativeCreate(null) : {};
16368 this.size = 0;
16369 }
16370
16371 var _hashClear = hashClear;
16372
16373 /**
16374 * Removes `key` and its value from the hash.
16375 *
16376 * @private
16377 * @name delete
16378 * @memberOf Hash
16379 * @param {Object} hash The hash to modify.
16380 * @param {string} key The key of the value to remove.
16381 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
16382 */
16383 function hashDelete(key) {
16384 var result = this.has(key) && delete this.__data__[key];
16385 this.size -= result ? 1 : 0;
16386 return result;
16387 }
16388
16389 var _hashDelete = hashDelete;
16390
16391 /** Used to stand-in for `undefined` hash values. */
16392 var HASH_UNDEFINED = '__lodash_hash_undefined__';
16393
16394 /** Used for built-in method references. */
16395 var objectProto$8 = Object.prototype;
16396
16397 /** Used to check objects for own properties. */
16398 var hasOwnProperty$6 = objectProto$8.hasOwnProperty;
16399
16400 /**
16401 * Gets the hash value for `key`.
16402 *
16403 * @private
16404 * @name get
16405 * @memberOf Hash
16406 * @param {string} key The key of the value to get.
16407 * @returns {*} Returns the entry value.
16408 */
16409 function hashGet(key) {
16410 var data = this.__data__;
16411 if (_nativeCreate) {
16412 var result = data[key];
16413 return result === HASH_UNDEFINED ? undefined : result;
16414 }
16415 return hasOwnProperty$6.call(data, key) ? data[key] : undefined;
16416 }
16417
16418 var _hashGet = hashGet;
16419
16420 /** Used for built-in method references. */
16421 var objectProto$9 = Object.prototype;
16422
16423 /** Used to check objects for own properties. */
16424 var hasOwnProperty$7 = objectProto$9.hasOwnProperty;
16425
16426 /**
16427 * Checks if a hash value for `key` exists.
16428 *
16429 * @private
16430 * @name has
16431 * @memberOf Hash
16432 * @param {string} key The key of the entry to check.
16433 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
16434 */
16435 function hashHas(key) {
16436 var data = this.__data__;
16437 return _nativeCreate ? (data[key] !== undefined) : hasOwnProperty$7.call(data, key);
16438 }
16439
16440 var _hashHas = hashHas;
16441
16442 /** Used to stand-in for `undefined` hash values. */
16443 var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';
16444
16445 /**
16446 * Sets the hash `key` to `value`.
16447 *
16448 * @private
16449 * @name set
16450 * @memberOf Hash
16451 * @param {string} key The key of the value to set.
16452 * @param {*} value The value to set.
16453 * @returns {Object} Returns the hash instance.
16454 */
16455 function hashSet(key, value) {
16456 var data = this.__data__;
16457 this.size += this.has(key) ? 0 : 1;
16458 data[key] = (_nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value;
16459 return this;
16460 }
16461
16462 var _hashSet = hashSet;
16463
16464 /**
16465 * Creates a hash object.
16466 *
16467 * @private
16468 * @constructor
16469 * @param {Array} [entries] The key-value pairs to cache.
16470 */
16471 function Hash(entries) {
16472 var index = -1,
16473 length = entries == null ? 0 : entries.length;
16474
16475 this.clear();
16476 while (++index < length) {
16477 var entry = entries[index];
16478 this.set(entry[0], entry[1]);
16479 }
16480 }
16481
16482 // Add methods to `Hash`.
16483 Hash.prototype.clear = _hashClear;
16484 Hash.prototype['delete'] = _hashDelete;
16485 Hash.prototype.get = _hashGet;
16486 Hash.prototype.has = _hashHas;
16487 Hash.prototype.set = _hashSet;
16488
16489 var _Hash = Hash;
16490
16491 /**
16492 * Removes all key-value entries from the map.
16493 *
16494 * @private
16495 * @name clear
16496 * @memberOf MapCache
16497 */
16498 function mapCacheClear() {
16499 this.size = 0;
16500 this.__data__ = {
16501 'hash': new _Hash,
16502 'map': new (_Map || _ListCache),
16503 'string': new _Hash
16504 };
16505 }
16506
16507 var _mapCacheClear = mapCacheClear;
16508
16509 /**
16510 * Checks if `value` is suitable for use as unique object key.
16511 *
16512 * @private
16513 * @param {*} value The value to check.
16514 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
16515 */
16516 function isKeyable(value) {
16517 var type = typeof value;
16518 return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
16519 ? (value !== '__proto__')
16520 : (value === null);
16521 }
16522
16523 var _isKeyable = isKeyable;
16524
16525 /**
16526 * Gets the data for `map`.
16527 *
16528 * @private
16529 * @param {Object} map The map to query.
16530 * @param {string} key The reference key.
16531 * @returns {*} Returns the map data.
16532 */
16533 function getMapData(map, key) {
16534 var data = map.__data__;
16535 return _isKeyable(key)
16536 ? data[typeof key == 'string' ? 'string' : 'hash']
16537 : data.map;
16538 }
16539
16540 var _getMapData = getMapData;
16541
16542 /**
16543 * Removes `key` and its value from the map.
16544 *
16545 * @private
16546 * @name delete
16547 * @memberOf MapCache
16548 * @param {string} key The key of the value to remove.
16549 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
16550 */
16551 function mapCacheDelete(key) {
16552 var result = _getMapData(this, key)['delete'](key);
16553 this.size -= result ? 1 : 0;
16554 return result;
16555 }
16556
16557 var _mapCacheDelete = mapCacheDelete;
16558
16559 /**
16560 * Gets the map value for `key`.
16561 *
16562 * @private
16563 * @name get
16564 * @memberOf MapCache
16565 * @param {string} key The key of the value to get.
16566 * @returns {*} Returns the entry value.
16567 */
16568 function mapCacheGet(key) {
16569 return _getMapData(this, key).get(key);
16570 }
16571
16572 var _mapCacheGet = mapCacheGet;
16573
16574 /**
16575 * Checks if a map value for `key` exists.
16576 *
16577 * @private
16578 * @name has
16579 * @memberOf MapCache
16580 * @param {string} key The key of the entry to check.
16581 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
16582 */
16583 function mapCacheHas(key) {
16584 return _getMapData(this, key).has(key);
16585 }
16586
16587 var _mapCacheHas = mapCacheHas;
16588
16589 /**
16590 * Sets the map `key` to `value`.
16591 *
16592 * @private
16593 * @name set
16594 * @memberOf MapCache
16595 * @param {string} key The key of the value to set.
16596 * @param {*} value The value to set.
16597 * @returns {Object} Returns the map cache instance.
16598 */
16599 function mapCacheSet(key, value) {
16600 var data = _getMapData(this, key),
16601 size = data.size;
16602
16603 data.set(key, value);
16604 this.size += data.size == size ? 0 : 1;
16605 return this;
16606 }
16607
16608 var _mapCacheSet = mapCacheSet;
16609
16610 /**
16611 * Creates a map cache object to store key-value pairs.
16612 *
16613 * @private
16614 * @constructor
16615 * @param {Array} [entries] The key-value pairs to cache.
16616 */
16617 function MapCache(entries) {
16618 var index = -1,
16619 length = entries == null ? 0 : entries.length;
16620
16621 this.clear();
16622 while (++index < length) {
16623 var entry = entries[index];
16624 this.set(entry[0], entry[1]);
16625 }
16626 }
16627
16628 // Add methods to `MapCache`.
16629 MapCache.prototype.clear = _mapCacheClear;
16630 MapCache.prototype['delete'] = _mapCacheDelete;
16631 MapCache.prototype.get = _mapCacheGet;
16632 MapCache.prototype.has = _mapCacheHas;
16633 MapCache.prototype.set = _mapCacheSet;
16634
16635 var _MapCache = MapCache;
16636
16637 /** Used as the size to enable large array optimizations. */
16638 var LARGE_ARRAY_SIZE = 200;
16639
16640 /**
16641 * Sets the stack `key` to `value`.
16642 *
16643 * @private
16644 * @name set
16645 * @memberOf Stack
16646 * @param {string} key The key of the value to set.
16647 * @param {*} value The value to set.
16648 * @returns {Object} Returns the stack cache instance.
16649 */
16650 function stackSet(key, value) {
16651 var data = this.__data__;
16652 if (data instanceof _ListCache) {
16653 var pairs = data.__data__;
16654 if (!_Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
16655 pairs.push([key, value]);
16656 this.size = ++data.size;
16657 return this;
16658 }
16659 data = this.__data__ = new _MapCache(pairs);
16660 }
16661 data.set(key, value);
16662 this.size = data.size;
16663 return this;
16664 }
16665
16666 var _stackSet = stackSet;
16667
16668 /**
16669 * Creates a stack cache object to store key-value pairs.
16670 *
16671 * @private
16672 * @constructor
16673 * @param {Array} [entries] The key-value pairs to cache.
16674 */
16675 function Stack(entries) {
16676 var data = this.__data__ = new _ListCache(entries);
16677 this.size = data.size;
16678 }
16679
16680 // Add methods to `Stack`.
16681 Stack.prototype.clear = _stackClear;
16682 Stack.prototype['delete'] = _stackDelete;
16683 Stack.prototype.get = _stackGet;
16684 Stack.prototype.has = _stackHas;
16685 Stack.prototype.set = _stackSet;
16686
16687 var _Stack = Stack;
16688
16689 /** Used to stand-in for `undefined` hash values. */
16690 var HASH_UNDEFINED$2 = '__lodash_hash_undefined__';
16691
16692 /**
16693 * Adds `value` to the array cache.
16694 *
16695 * @private
16696 * @name add
16697 * @memberOf SetCache
16698 * @alias push
16699 * @param {*} value The value to cache.
16700 * @returns {Object} Returns the cache instance.
16701 */
16702 function setCacheAdd(value) {
16703 this.__data__.set(value, HASH_UNDEFINED$2);
16704 return this;
16705 }
16706
16707 var _setCacheAdd = setCacheAdd;
16708
16709 /**
16710 * Checks if `value` is in the array cache.
16711 *
16712 * @private
16713 * @name has
16714 * @memberOf SetCache
16715 * @param {*} value The value to search for.
16716 * @returns {number} Returns `true` if `value` is found, else `false`.
16717 */
16718 function setCacheHas(value) {
16719 return this.__data__.has(value);
16720 }
16721
16722 var _setCacheHas = setCacheHas;
16723
16724 /**
16725 *
16726 * Creates an array cache object to store unique values.
16727 *
16728 * @private
16729 * @constructor
16730 * @param {Array} [values] The values to cache.
16731 */
16732 function SetCache(values) {
16733 var index = -1,
16734 length = values == null ? 0 : values.length;
16735
16736 this.__data__ = new _MapCache;
16737 while (++index < length) {
16738 this.add(values[index]);
16739 }
16740 }
16741
16742 // Add methods to `SetCache`.
16743 SetCache.prototype.add = SetCache.prototype.push = _setCacheAdd;
16744 SetCache.prototype.has = _setCacheHas;
16745
16746 var _SetCache = SetCache;
16747
16748 /**
16749 * A specialized version of `_.some` for arrays without support for iteratee
16750 * shorthands.
16751 *
16752 * @private
16753 * @param {Array} [array] The array to iterate over.
16754 * @param {Function} predicate The function invoked per iteration.
16755 * @returns {boolean} Returns `true` if any element passes the predicate check,
16756 * else `false`.
16757 */
16758 function arraySome(array, predicate) {
16759 var index = -1,
16760 length = array == null ? 0 : array.length;
16761
16762 while (++index < length) {
16763 if (predicate(array[index], index, array)) {
16764 return true;
16765 }
16766 }
16767 return false;
16768 }
16769
16770 var _arraySome = arraySome;
16771
16772 /**
16773 * Checks if a `cache` value for `key` exists.
16774 *
16775 * @private
16776 * @param {Object} cache The cache to query.
16777 * @param {string} key The key of the entry to check.
16778 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
16779 */
16780 function cacheHas(cache, key) {
16781 return cache.has(key);
16782 }
16783
16784 var _cacheHas = cacheHas;
16785
16786 /** Used to compose bitmasks for value comparisons. */
16787 var COMPARE_PARTIAL_FLAG = 1,
16788 COMPARE_UNORDERED_FLAG = 2;
16789
16790 /**
16791 * A specialized version of `baseIsEqualDeep` for arrays with support for
16792 * partial deep comparisons.
16793 *
16794 * @private
16795 * @param {Array} array The array to compare.
16796 * @param {Array} other The other array to compare.
16797 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
16798 * @param {Function} customizer The function to customize comparisons.
16799 * @param {Function} equalFunc The function to determine equivalents of values.
16800 * @param {Object} stack Tracks traversed `array` and `other` objects.
16801 * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
16802 */
16803 function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
16804 var isPartial = bitmask & COMPARE_PARTIAL_FLAG,
16805 arrLength = array.length,
16806 othLength = other.length;
16807
16808 if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
16809 return false;
16810 }
16811 // Check that cyclic values are equal.
16812 var arrStacked = stack.get(array);
16813 var othStacked = stack.get(other);
16814 if (arrStacked && othStacked) {
16815 return arrStacked == other && othStacked == array;
16816 }
16817 var index = -1,
16818 result = true,
16819 seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new _SetCache : undefined;
16820
16821 stack.set(array, other);
16822 stack.set(other, array);
16823
16824 // Ignore non-index properties.
16825 while (++index < arrLength) {
16826 var arrValue = array[index],
16827 othValue = other[index];
16828
16829 if (customizer) {
16830 var compared = isPartial
16831 ? customizer(othValue, arrValue, index, other, array, stack)
16832 : customizer(arrValue, othValue, index, array, other, stack);
16833 }
16834 if (compared !== undefined) {
16835 if (compared) {
16836 continue;
16837 }
16838 result = false;
16839 break;
16840 }
16841 // Recursively compare arrays (susceptible to call stack limits).
16842 if (seen) {
16843 if (!_arraySome(other, function(othValue, othIndex) {
16844 if (!_cacheHas(seen, othIndex) &&
16845 (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
16846 return seen.push(othIndex);
16847 }
16848 })) {
16849 result = false;
16850 break;
16851 }
16852 } else if (!(
16853 arrValue === othValue ||
16854 equalFunc(arrValue, othValue, bitmask, customizer, stack)
16855 )) {
16856 result = false;
16857 break;
16858 }
16859 }
16860 stack['delete'](array);
16861 stack['delete'](other);
16862 return result;
16863 }
16864
16865 var _equalArrays = equalArrays;
16866
16867 /** Built-in value references. */
16868 var Uint8Array$1 = _root.Uint8Array;
16869
16870 var _Uint8Array = Uint8Array$1;
16871
16872 /**
16873 * Converts `map` to its key-value pairs.
16874 *
16875 * @private
16876 * @param {Object} map The map to convert.
16877 * @returns {Array} Returns the key-value pairs.
16878 */
16879 function mapToArray(map) {
16880 var index = -1,
16881 result = Array(map.size);
16882
16883 map.forEach(function(value, key) {
16884 result[++index] = [key, value];
16885 });
16886 return result;
16887 }
16888
16889 var _mapToArray = mapToArray;
16890
16891 /**
16892 * Converts `set` to an array of its values.
16893 *
16894 * @private
16895 * @param {Object} set The set to convert.
16896 * @returns {Array} Returns the values.
16897 */
16898 function setToArray(set) {
16899 var index = -1,
16900 result = Array(set.size);
16901
16902 set.forEach(function(value) {
16903 result[++index] = value;
16904 });
16905 return result;
16906 }
16907
16908 var _setToArray = setToArray;
16909
16910 /** Used to compose bitmasks for value comparisons. */
16911 var COMPARE_PARTIAL_FLAG$1 = 1,
16912 COMPARE_UNORDERED_FLAG$1 = 2;
16913
16914 /** `Object#toString` result references. */
16915 var boolTag$1 = '[object Boolean]',
16916 dateTag$1 = '[object Date]',
16917 errorTag$1 = '[object Error]',
16918 mapTag$1 = '[object Map]',
16919 numberTag$1 = '[object Number]',
16920 regexpTag$1 = '[object RegExp]',
16921 setTag$1 = '[object Set]',
16922 stringTag$1 = '[object String]',
16923 symbolTag = '[object Symbol]';
16924
16925 var arrayBufferTag$1 = '[object ArrayBuffer]',
16926 dataViewTag$1 = '[object DataView]';
16927
16928 /** Used to convert symbols to primitives and strings. */
16929 var symbolProto = _Symbol ? _Symbol.prototype : undefined,
16930 symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
16931
16932 /**
16933 * A specialized version of `baseIsEqualDeep` for comparing objects of
16934 * the same `toStringTag`.
16935 *
16936 * **Note:** This function only supports comparing values with tags of
16937 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
16938 *
16939 * @private
16940 * @param {Object} object The object to compare.
16941 * @param {Object} other The other object to compare.
16942 * @param {string} tag The `toStringTag` of the objects to compare.
16943 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
16944 * @param {Function} customizer The function to customize comparisons.
16945 * @param {Function} equalFunc The function to determine equivalents of values.
16946 * @param {Object} stack Tracks traversed `object` and `other` objects.
16947 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
16948 */
16949 function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
16950 switch (tag) {
16951 case dataViewTag$1:
16952 if ((object.byteLength != other.byteLength) ||
16953 (object.byteOffset != other.byteOffset)) {
16954 return false;
16955 }
16956 object = object.buffer;
16957 other = other.buffer;
16958
16959 case arrayBufferTag$1:
16960 if ((object.byteLength != other.byteLength) ||
16961 !equalFunc(new _Uint8Array(object), new _Uint8Array(other))) {
16962 return false;
16963 }
16964 return true;
16965
16966 case boolTag$1:
16967 case dateTag$1:
16968 case numberTag$1:
16969 // Coerce booleans to `1` or `0` and dates to milliseconds.
16970 // Invalid dates are coerced to `NaN`.
16971 return eq_1(+object, +other);
16972
16973 case errorTag$1:
16974 return object.name == other.name && object.message == other.message;
16975
16976 case regexpTag$1:
16977 case stringTag$1:
16978 // Coerce regexes to strings and treat strings, primitives and objects,
16979 // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
16980 // for more details.
16981 return object == (other + '');
16982
16983 case mapTag$1:
16984 var convert = _mapToArray;
16985
16986 case setTag$1:
16987 var isPartial = bitmask & COMPARE_PARTIAL_FLAG$1;
16988 convert || (convert = _setToArray);
16989
16990 if (object.size != other.size && !isPartial) {
16991 return false;
16992 }
16993 // Assume cyclic values are equal.
16994 var stacked = stack.get(object);
16995 if (stacked) {
16996 return stacked == other;
16997 }
16998 bitmask |= COMPARE_UNORDERED_FLAG$1;
16999
17000 // Recursively compare objects (susceptible to call stack limits).
17001 stack.set(object, other);
17002 var result = _equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
17003 stack['delete'](object);
17004 return result;
17005
17006 case symbolTag:
17007 if (symbolValueOf) {
17008 return symbolValueOf.call(object) == symbolValueOf.call(other);
17009 }
17010 }
17011 return false;
17012 }
17013
17014 var _equalByTag = equalByTag;
17015
17016 /**
17017 * Appends the elements of `values` to `array`.
17018 *
17019 * @private
17020 * @param {Array} array The array to modify.
17021 * @param {Array} values The values to append.
17022 * @returns {Array} Returns `array`.
17023 */
17024 function arrayPush(array, values) {
17025 var index = -1,
17026 length = values.length,
17027 offset = array.length;
17028
17029 while (++index < length) {
17030 array[offset + index] = values[index];
17031 }
17032 return array;
17033 }
17034
17035 var _arrayPush = arrayPush;
17036
17037 /**
17038 * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
17039 * `keysFunc` and `symbolsFunc` to get the enumerable property names and
17040 * symbols of `object`.
17041 *
17042 * @private
17043 * @param {Object} object The object to query.
17044 * @param {Function} keysFunc The function to get the keys of `object`.
17045 * @param {Function} symbolsFunc The function to get the symbols of `object`.
17046 * @returns {Array} Returns the array of property names and symbols.
17047 */
17048 function baseGetAllKeys(object, keysFunc, symbolsFunc) {
17049 var result = keysFunc(object);
17050 return isArray_1(object) ? result : _arrayPush(result, symbolsFunc(object));
17051 }
17052
17053 var _baseGetAllKeys = baseGetAllKeys;
17054
17055 /**
17056 * A specialized version of `_.filter` for arrays without support for
17057 * iteratee shorthands.
17058 *
17059 * @private
17060 * @param {Array} [array] The array to iterate over.
17061 * @param {Function} predicate The function invoked per iteration.
17062 * @returns {Array} Returns the new filtered array.
17063 */
17064 function arrayFilter(array, predicate) {
17065 var index = -1,
17066 length = array == null ? 0 : array.length,
17067 resIndex = 0,
17068 result = [];
17069
17070 while (++index < length) {
17071 var value = array[index];
17072 if (predicate(value, index, array)) {
17073 result[resIndex++] = value;
17074 }
17075 }
17076 return result;
17077 }
17078
17079 var _arrayFilter = arrayFilter;
17080
17081 /**
17082 * This method returns a new empty array.
17083 *
17084 * @static
17085 * @memberOf _
17086 * @since 4.13.0
17087 * @category Util
17088 * @returns {Array} Returns the new empty array.
17089 * @example
17090 *
17091 * var arrays = _.times(2, _.stubArray);
17092 *
17093 * console.log(arrays);
17094 * // => [[], []]
17095 *
17096 * console.log(arrays[0] === arrays[1]);
17097 * // => false
17098 */
17099 function stubArray() {
17100 return [];
17101 }
17102
17103 var stubArray_1 = stubArray;
17104
17105 /** Used for built-in method references. */
17106 var objectProto$a = Object.prototype;
17107
17108 /** Built-in value references. */
17109 var propertyIsEnumerable$1 = objectProto$a.propertyIsEnumerable;
17110
17111 /* Built-in method references for those with the same name as other `lodash` methods. */
17112 var nativeGetSymbols = Object.getOwnPropertySymbols;
17113
17114 /**
17115 * Creates an array of the own enumerable symbols of `object`.
17116 *
17117 * @private
17118 * @param {Object} object The object to query.
17119 * @returns {Array} Returns the array of symbols.
17120 */
17121 var getSymbols = !nativeGetSymbols ? stubArray_1 : function(object) {
17122 if (object == null) {
17123 return [];
17124 }
17125 object = Object(object);
17126 return _arrayFilter(nativeGetSymbols(object), function(symbol) {
17127 return propertyIsEnumerable$1.call(object, symbol);
17128 });
17129 };
17130
17131 var _getSymbols = getSymbols;
17132
17133 /**
17134 * Creates an array of own enumerable property names and symbols of `object`.
17135 *
17136 * @private
17137 * @param {Object} object The object to query.
17138 * @returns {Array} Returns the array of property names and symbols.
17139 */
17140 function getAllKeys(object) {
17141 return _baseGetAllKeys(object, keys_1, _getSymbols);
17142 }
17143
17144 var _getAllKeys = getAllKeys;
17145
17146 /** Used to compose bitmasks for value comparisons. */
17147 var COMPARE_PARTIAL_FLAG$2 = 1;
17148
17149 /** Used for built-in method references. */
17150 var objectProto$b = Object.prototype;
17151
17152 /** Used to check objects for own properties. */
17153 var hasOwnProperty$8 = objectProto$b.hasOwnProperty;
17154
17155 /**
17156 * A specialized version of `baseIsEqualDeep` for objects with support for
17157 * partial deep comparisons.
17158 *
17159 * @private
17160 * @param {Object} object The object to compare.
17161 * @param {Object} other The other object to compare.
17162 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
17163 * @param {Function} customizer The function to customize comparisons.
17164 * @param {Function} equalFunc The function to determine equivalents of values.
17165 * @param {Object} stack Tracks traversed `object` and `other` objects.
17166 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
17167 */
17168 function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
17169 var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2,
17170 objProps = _getAllKeys(object),
17171 objLength = objProps.length,
17172 othProps = _getAllKeys(other),
17173 othLength = othProps.length;
17174
17175 if (objLength != othLength && !isPartial) {
17176 return false;
17177 }
17178 var index = objLength;
17179 while (index--) {
17180 var key = objProps[index];
17181 if (!(isPartial ? key in other : hasOwnProperty$8.call(other, key))) {
17182 return false;
17183 }
17184 }
17185 // Check that cyclic values are equal.
17186 var objStacked = stack.get(object);
17187 var othStacked = stack.get(other);
17188 if (objStacked && othStacked) {
17189 return objStacked == other && othStacked == object;
17190 }
17191 var result = true;
17192 stack.set(object, other);
17193 stack.set(other, object);
17194
17195 var skipCtor = isPartial;
17196 while (++index < objLength) {
17197 key = objProps[index];
17198 var objValue = object[key],
17199 othValue = other[key];
17200
17201 if (customizer) {
17202 var compared = isPartial
17203 ? customizer(othValue, objValue, key, other, object, stack)
17204 : customizer(objValue, othValue, key, object, other, stack);
17205 }
17206 // Recursively compare objects (susceptible to call stack limits).
17207 if (!(compared === undefined
17208 ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
17209 : compared
17210 )) {
17211 result = false;
17212 break;
17213 }
17214 skipCtor || (skipCtor = key == 'constructor');
17215 }
17216 if (result && !skipCtor) {
17217 var objCtor = object.constructor,
17218 othCtor = other.constructor;
17219
17220 // Non `Object` object instances with different constructors are not equal.
17221 if (objCtor != othCtor &&
17222 ('constructor' in object && 'constructor' in other) &&
17223 !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
17224 typeof othCtor == 'function' && othCtor instanceof othCtor)) {
17225 result = false;
17226 }
17227 }
17228 stack['delete'](object);
17229 stack['delete'](other);
17230 return result;
17231 }
17232
17233 var _equalObjects = equalObjects;
17234
17235 /* Built-in method references that are verified to be native. */
17236 var DataView = _getNative(_root, 'DataView');
17237
17238 var _DataView = DataView;
17239
17240 /* Built-in method references that are verified to be native. */
17241 var Promise$1 = _getNative(_root, 'Promise');
17242
17243 var _Promise = Promise$1;
17244
17245 /* Built-in method references that are verified to be native. */
17246 var Set$1 = _getNative(_root, 'Set');
17247
17248 var _Set = Set$1;
17249
17250 /* Built-in method references that are verified to be native. */
17251 var WeakMap$1 = _getNative(_root, 'WeakMap');
17252
17253 var _WeakMap = WeakMap$1;
17254
17255 /** `Object#toString` result references. */
17256 var mapTag$2 = '[object Map]',
17257 objectTag$2 = '[object Object]',
17258 promiseTag = '[object Promise]',
17259 setTag$2 = '[object Set]',
17260 weakMapTag$1 = '[object WeakMap]';
17261
17262 var dataViewTag$2 = '[object DataView]';
17263
17264 /** Used to detect maps, sets, and weakmaps. */
17265 var dataViewCtorString = _toSource(_DataView),
17266 mapCtorString = _toSource(_Map),
17267 promiseCtorString = _toSource(_Promise),
17268 setCtorString = _toSource(_Set),
17269 weakMapCtorString = _toSource(_WeakMap);
17270
17271 /**
17272 * Gets the `toStringTag` of `value`.
17273 *
17274 * @private
17275 * @param {*} value The value to query.
17276 * @returns {string} Returns the `toStringTag`.
17277 */
17278 var getTag = _baseGetTag;
17279
17280 // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
17281 if ((_DataView && getTag(new _DataView(new ArrayBuffer(1))) != dataViewTag$2) ||
17282 (_Map && getTag(new _Map) != mapTag$2) ||
17283 (_Promise && getTag(_Promise.resolve()) != promiseTag) ||
17284 (_Set && getTag(new _Set) != setTag$2) ||
17285 (_WeakMap && getTag(new _WeakMap) != weakMapTag$1)) {
17286 getTag = function(value) {
17287 var result = _baseGetTag(value),
17288 Ctor = result == objectTag$2 ? value.constructor : undefined,
17289 ctorString = Ctor ? _toSource(Ctor) : '';
17290
17291 if (ctorString) {
17292 switch (ctorString) {
17293 case dataViewCtorString: return dataViewTag$2;
17294 case mapCtorString: return mapTag$2;
17295 case promiseCtorString: return promiseTag;
17296 case setCtorString: return setTag$2;
17297 case weakMapCtorString: return weakMapTag$1;
17298 }
17299 }
17300 return result;
17301 };
17302 }
17303
17304 var _getTag = getTag;
17305
17306 /** Used to compose bitmasks for value comparisons. */
17307 var COMPARE_PARTIAL_FLAG$3 = 1;
17308
17309 /** `Object#toString` result references. */
17310 var argsTag$2 = '[object Arguments]',
17311 arrayTag$1 = '[object Array]',
17312 objectTag$3 = '[object Object]';
17313
17314 /** Used for built-in method references. */
17315 var objectProto$c = Object.prototype;
17316
17317 /** Used to check objects for own properties. */
17318 var hasOwnProperty$9 = objectProto$c.hasOwnProperty;
17319
17320 /**
17321 * A specialized version of `baseIsEqual` for arrays and objects which performs
17322 * deep comparisons and tracks traversed objects enabling objects with circular
17323 * references to be compared.
17324 *
17325 * @private
17326 * @param {Object} object The object to compare.
17327 * @param {Object} other The other object to compare.
17328 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
17329 * @param {Function} customizer The function to customize comparisons.
17330 * @param {Function} equalFunc The function to determine equivalents of values.
17331 * @param {Object} [stack] Tracks traversed `object` and `other` objects.
17332 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
17333 */
17334 function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
17335 var objIsArr = isArray_1(object),
17336 othIsArr = isArray_1(other),
17337 objTag = objIsArr ? arrayTag$1 : _getTag(object),
17338 othTag = othIsArr ? arrayTag$1 : _getTag(other);
17339
17340 objTag = objTag == argsTag$2 ? objectTag$3 : objTag;
17341 othTag = othTag == argsTag$2 ? objectTag$3 : othTag;
17342
17343 var objIsObj = objTag == objectTag$3,
17344 othIsObj = othTag == objectTag$3,
17345 isSameTag = objTag == othTag;
17346
17347 if (isSameTag && isBuffer_1(object)) {
17348 if (!isBuffer_1(other)) {
17349 return false;
17350 }
17351 objIsArr = true;
17352 objIsObj = false;
17353 }
17354 if (isSameTag && !objIsObj) {
17355 stack || (stack = new _Stack);
17356 return (objIsArr || isTypedArray_1(object))
17357 ? _equalArrays(object, other, bitmask, customizer, equalFunc, stack)
17358 : _equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
17359 }
17360 if (!(bitmask & COMPARE_PARTIAL_FLAG$3)) {
17361 var objIsWrapped = objIsObj && hasOwnProperty$9.call(object, '__wrapped__'),
17362 othIsWrapped = othIsObj && hasOwnProperty$9.call(other, '__wrapped__');
17363
17364 if (objIsWrapped || othIsWrapped) {
17365 var objUnwrapped = objIsWrapped ? object.value() : object,
17366 othUnwrapped = othIsWrapped ? other.value() : other;
17367
17368 stack || (stack = new _Stack);
17369 return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
17370 }
17371 }
17372 if (!isSameTag) {
17373 return false;
17374 }
17375 stack || (stack = new _Stack);
17376 return _equalObjects(object, other, bitmask, customizer, equalFunc, stack);
17377 }
17378
17379 var _baseIsEqualDeep = baseIsEqualDeep;
17380
17381 /**
17382 * The base implementation of `_.isEqual` which supports partial comparisons
17383 * and tracks traversed objects.
17384 *
17385 * @private
17386 * @param {*} value The value to compare.
17387 * @param {*} other The other value to compare.
17388 * @param {boolean} bitmask The bitmask flags.
17389 * 1 - Unordered comparison
17390 * 2 - Partial comparison
17391 * @param {Function} [customizer] The function to customize comparisons.
17392 * @param {Object} [stack] Tracks traversed `value` and `other` objects.
17393 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
17394 */
17395 function baseIsEqual(value, other, bitmask, customizer, stack) {
17396 if (value === other) {
17397 return true;
17398 }
17399 if (value == null || other == null || (!isObjectLike_1(value) && !isObjectLike_1(other))) {
17400 return value !== value && other !== other;
17401 }
17402 return _baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
17403 }
17404
17405 var _baseIsEqual = baseIsEqual;
17406
17407 /** Used to compose bitmasks for value comparisons. */
17408 var COMPARE_PARTIAL_FLAG$4 = 1,
17409 COMPARE_UNORDERED_FLAG$2 = 2;
17410
17411 /**
17412 * The base implementation of `_.isMatch` without support for iteratee shorthands.
17413 *
17414 * @private
17415 * @param {Object} object The object to inspect.
17416 * @param {Object} source The object of property values to match.
17417 * @param {Array} matchData The property names, values, and compare flags to match.
17418 * @param {Function} [customizer] The function to customize comparisons.
17419 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
17420 */
17421 function baseIsMatch(object, source, matchData, customizer) {
17422 var index = matchData.length,
17423 length = index,
17424 noCustomizer = !customizer;
17425
17426 if (object == null) {
17427 return !length;
17428 }
17429 object = Object(object);
17430 while (index--) {
17431 var data = matchData[index];
17432 if ((noCustomizer && data[2])
17433 ? data[1] !== object[data[0]]
17434 : !(data[0] in object)
17435 ) {
17436 return false;
17437 }
17438 }
17439 while (++index < length) {
17440 data = matchData[index];
17441 var key = data[0],
17442 objValue = object[key],
17443 srcValue = data[1];
17444
17445 if (noCustomizer && data[2]) {
17446 if (objValue === undefined && !(key in object)) {
17447 return false;
17448 }
17449 } else {
17450 var stack = new _Stack;
17451 if (customizer) {
17452 var result = customizer(objValue, srcValue, key, object, source, stack);
17453 }
17454 if (!(result === undefined
17455 ? _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$4 | COMPARE_UNORDERED_FLAG$2, customizer, stack)
17456 : result
17457 )) {
17458 return false;
17459 }
17460 }
17461 }
17462 return true;
17463 }
17464
17465 var _baseIsMatch = baseIsMatch;
17466
17467 /**
17468 * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
17469 *
17470 * @private
17471 * @param {*} value The value to check.
17472 * @returns {boolean} Returns `true` if `value` if suitable for strict
17473 * equality comparisons, else `false`.
17474 */
17475 function isStrictComparable(value) {
17476 return value === value && !isObject_1(value);
17477 }
17478
17479 var _isStrictComparable = isStrictComparable;
17480
17481 /**
17482 * Gets the property names, values, and compare flags of `object`.
17483 *
17484 * @private
17485 * @param {Object} object The object to query.
17486 * @returns {Array} Returns the match data of `object`.
17487 */
17488 function getMatchData(object) {
17489 var result = keys_1(object),
17490 length = result.length;
17491
17492 while (length--) {
17493 var key = result[length],
17494 value = object[key];
17495
17496 result[length] = [key, value, _isStrictComparable(value)];
17497 }
17498 return result;
17499 }
17500
17501 var _getMatchData = getMatchData;
17502
17503 /**
17504 * A specialized version of `matchesProperty` for source values suitable
17505 * for strict equality comparisons, i.e. `===`.
17506 *
17507 * @private
17508 * @param {string} key The key of the property to get.
17509 * @param {*} srcValue The value to match.
17510 * @returns {Function} Returns the new spec function.
17511 */
17512 function matchesStrictComparable(key, srcValue) {
17513 return function(object) {
17514 if (object == null) {
17515 return false;
17516 }
17517 return object[key] === srcValue &&
17518 (srcValue !== undefined || (key in Object(object)));
17519 };
17520 }
17521
17522 var _matchesStrictComparable = matchesStrictComparable;
17523
17524 /**
17525 * The base implementation of `_.matches` which doesn't clone `source`.
17526 *
17527 * @private
17528 * @param {Object} source The object of property values to match.
17529 * @returns {Function} Returns the new spec function.
17530 */
17531 function baseMatches(source) {
17532 var matchData = _getMatchData(source);
17533 if (matchData.length == 1 && matchData[0][2]) {
17534 return _matchesStrictComparable(matchData[0][0], matchData[0][1]);
17535 }
17536 return function(object) {
17537 return object === source || _baseIsMatch(object, source, matchData);
17538 };
17539 }
17540
17541 var _baseMatches = baseMatches;
17542
17543 /** `Object#toString` result references. */
17544 var symbolTag$1 = '[object Symbol]';
17545
17546 /**
17547 * Checks if `value` is classified as a `Symbol` primitive or object.
17548 *
17549 * @static
17550 * @memberOf _
17551 * @since 4.0.0
17552 * @category Lang
17553 * @param {*} value The value to check.
17554 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
17555 * @example
17556 *
17557 * _.isSymbol(Symbol.iterator);
17558 * // => true
17559 *
17560 * _.isSymbol('abc');
17561 * // => false
17562 */
17563 function isSymbol(value) {
17564 return typeof value == 'symbol' ||
17565 (isObjectLike_1(value) && _baseGetTag(value) == symbolTag$1);
17566 }
17567
17568 var isSymbol_1 = isSymbol;
17569
17570 /** Used to match property names within property paths. */
17571 var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
17572 reIsPlainProp = /^\w*$/;
17573
17574 /**
17575 * Checks if `value` is a property name and not a property path.
17576 *
17577 * @private
17578 * @param {*} value The value to check.
17579 * @param {Object} [object] The object to query keys on.
17580 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
17581 */
17582 function isKey(value, object) {
17583 if (isArray_1(value)) {
17584 return false;
17585 }
17586 var type = typeof value;
17587 if (type == 'number' || type == 'symbol' || type == 'boolean' ||
17588 value == null || isSymbol_1(value)) {
17589 return true;
17590 }
17591 return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
17592 (object != null && value in Object(object));
17593 }
17594
17595 var _isKey = isKey;
17596
17597 /** Error message constants. */
17598 var FUNC_ERROR_TEXT = 'Expected a function';
17599
17600 /**
17601 * Creates a function that memoizes the result of `func`. If `resolver` is
17602 * provided, it determines the cache key for storing the result based on the
17603 * arguments provided to the memoized function. By default, the first argument
17604 * provided to the memoized function is used as the map cache key. The `func`
17605 * is invoked with the `this` binding of the memoized function.
17606 *
17607 * **Note:** The cache is exposed as the `cache` property on the memoized
17608 * function. Its creation may be customized by replacing the `_.memoize.Cache`
17609 * constructor with one whose instances implement the
17610 * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
17611 * method interface of `clear`, `delete`, `get`, `has`, and `set`.
17612 *
17613 * @static
17614 * @memberOf _
17615 * @since 0.1.0
17616 * @category Function
17617 * @param {Function} func The function to have its output memoized.
17618 * @param {Function} [resolver] The function to resolve the cache key.
17619 * @returns {Function} Returns the new memoized function.
17620 * @example
17621 *
17622 * var object = { 'a': 1, 'b': 2 };
17623 * var other = { 'c': 3, 'd': 4 };
17624 *
17625 * var values = _.memoize(_.values);
17626 * values(object);
17627 * // => [1, 2]
17628 *
17629 * values(other);
17630 * // => [3, 4]
17631 *
17632 * object.a = 2;
17633 * values(object);
17634 * // => [1, 2]
17635 *
17636 * // Modify the result cache.
17637 * values.cache.set(object, ['a', 'b']);
17638 * values(object);
17639 * // => ['a', 'b']
17640 *
17641 * // Replace `_.memoize.Cache`.
17642 * _.memoize.Cache = WeakMap;
17643 */
17644 function memoize(func, resolver) {
17645 if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
17646 throw new TypeError(FUNC_ERROR_TEXT);
17647 }
17648 var memoized = function() {
17649 var args = arguments,
17650 key = resolver ? resolver.apply(this, args) : args[0],
17651 cache = memoized.cache;
17652
17653 if (cache.has(key)) {
17654 return cache.get(key);
17655 }
17656 var result = func.apply(this, args);
17657 memoized.cache = cache.set(key, result) || cache;
17658 return result;
17659 };
17660 memoized.cache = new (memoize.Cache || _MapCache);
17661 return memoized;
17662 }
17663
17664 // Expose `MapCache`.
17665 memoize.Cache = _MapCache;
17666
17667 var memoize_1 = memoize;
17668
17669 /** Used as the maximum memoize cache size. */
17670 var MAX_MEMOIZE_SIZE = 500;
17671
17672 /**
17673 * A specialized version of `_.memoize` which clears the memoized function's
17674 * cache when it exceeds `MAX_MEMOIZE_SIZE`.
17675 *
17676 * @private
17677 * @param {Function} func The function to have its output memoized.
17678 * @returns {Function} Returns the new memoized function.
17679 */
17680 function memoizeCapped(func) {
17681 var result = memoize_1(func, function(key) {
17682 if (cache.size === MAX_MEMOIZE_SIZE) {
17683 cache.clear();
17684 }
17685 return key;
17686 });
17687
17688 var cache = result.cache;
17689 return result;
17690 }
17691
17692 var _memoizeCapped = memoizeCapped;
17693
17694 /** Used to match property names within property paths. */
17695 var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
17696
17697 /** Used to match backslashes in property paths. */
17698 var reEscapeChar = /\\(\\)?/g;
17699
17700 /**
17701 * Converts `string` to a property path array.
17702 *
17703 * @private
17704 * @param {string} string The string to convert.
17705 * @returns {Array} Returns the property path array.
17706 */
17707 var stringToPath = _memoizeCapped(function(string) {
17708 var result = [];
17709 if (string.charCodeAt(0) === 46 /* . */) {
17710 result.push('');
17711 }
17712 string.replace(rePropName, function(match, number, quote, subString) {
17713 result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
17714 });
17715 return result;
17716 });
17717
17718 var _stringToPath = stringToPath;
17719
17720 /** Used as references for various `Number` constants. */
17721 var INFINITY = 1 / 0;
17722
17723 /** Used to convert symbols to primitives and strings. */
17724 var symbolProto$1 = _Symbol ? _Symbol.prototype : undefined,
17725 symbolToString = symbolProto$1 ? symbolProto$1.toString : undefined;
17726
17727 /**
17728 * The base implementation of `_.toString` which doesn't convert nullish
17729 * values to empty strings.
17730 *
17731 * @private
17732 * @param {*} value The value to process.
17733 * @returns {string} Returns the string.
17734 */
17735 function baseToString(value) {
17736 // Exit early for strings to avoid a performance hit in some environments.
17737 if (typeof value == 'string') {
17738 return value;
17739 }
17740 if (isArray_1(value)) {
17741 // Recursively convert values (susceptible to call stack limits).
17742 return _arrayMap(value, baseToString) + '';
17743 }
17744 if (isSymbol_1(value)) {
17745 return symbolToString ? symbolToString.call(value) : '';
17746 }
17747 var result = (value + '');
17748 return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
17749 }
17750
17751 var _baseToString = baseToString;
17752
17753 /**
17754 * Converts `value` to a string. An empty string is returned for `null`
17755 * and `undefined` values. The sign of `-0` is preserved.
17756 *
17757 * @static
17758 * @memberOf _
17759 * @since 4.0.0
17760 * @category Lang
17761 * @param {*} value The value to convert.
17762 * @returns {string} Returns the converted string.
17763 * @example
17764 *
17765 * _.toString(null);
17766 * // => ''
17767 *
17768 * _.toString(-0);
17769 * // => '-0'
17770 *
17771 * _.toString([1, 2, 3]);
17772 * // => '1,2,3'
17773 */
17774 function toString(value) {
17775 return value == null ? '' : _baseToString(value);
17776 }
17777
17778 var toString_1 = toString;
17779
17780 /**
17781 * Casts `value` to a path array if it's not one.
17782 *
17783 * @private
17784 * @param {*} value The value to inspect.
17785 * @param {Object} [object] The object to query keys on.
17786 * @returns {Array} Returns the cast property path array.
17787 */
17788 function castPath(value, object) {
17789 if (isArray_1(value)) {
17790 return value;
17791 }
17792 return _isKey(value, object) ? [value] : _stringToPath(toString_1(value));
17793 }
17794
17795 var _castPath = castPath;
17796
17797 /** Used as references for various `Number` constants. */
17798 var INFINITY$1 = 1 / 0;
17799
17800 /**
17801 * Converts `value` to a string key if it's not a string or symbol.
17802 *
17803 * @private
17804 * @param {*} value The value to inspect.
17805 * @returns {string|symbol} Returns the key.
17806 */
17807 function toKey(value) {
17808 if (typeof value == 'string' || isSymbol_1(value)) {
17809 return value;
17810 }
17811 var result = (value + '');
17812 return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result;
17813 }
17814
17815 var _toKey = toKey;
17816
17817 /**
17818 * The base implementation of `_.get` without support for default values.
17819 *
17820 * @private
17821 * @param {Object} object The object to query.
17822 * @param {Array|string} path The path of the property to get.
17823 * @returns {*} Returns the resolved value.
17824 */
17825 function baseGet(object, path) {
17826 path = _castPath(path, object);
17827
17828 var index = 0,
17829 length = path.length;
17830
17831 while (object != null && index < length) {
17832 object = object[_toKey(path[index++])];
17833 }
17834 return (index && index == length) ? object : undefined;
17835 }
17836
17837 var _baseGet = baseGet;
17838
17839 /**
17840 * Gets the value at `path` of `object`. If the resolved value is
17841 * `undefined`, the `defaultValue` is returned in its place.
17842 *
17843 * @static
17844 * @memberOf _
17845 * @since 3.7.0
17846 * @category Object
17847 * @param {Object} object The object to query.
17848 * @param {Array|string} path The path of the property to get.
17849 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
17850 * @returns {*} Returns the resolved value.
17851 * @example
17852 *
17853 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
17854 *
17855 * _.get(object, 'a[0].b.c');
17856 * // => 3
17857 *
17858 * _.get(object, ['a', '0', 'b', 'c']);
17859 * // => 3
17860 *
17861 * _.get(object, 'a.b.c', 'default');
17862 * // => 'default'
17863 */
17864 function get(object, path, defaultValue) {
17865 var result = object == null ? undefined : _baseGet(object, path);
17866 return result === undefined ? defaultValue : result;
17867 }
17868
17869 var get_1 = get;
17870
17871 /**
17872 * The base implementation of `_.hasIn` without support for deep paths.
17873 *
17874 * @private
17875 * @param {Object} [object] The object to query.
17876 * @param {Array|string} key The key to check.
17877 * @returns {boolean} Returns `true` if `key` exists, else `false`.
17878 */
17879 function baseHasIn(object, key) {
17880 return object != null && key in Object(object);
17881 }
17882
17883 var _baseHasIn = baseHasIn;
17884
17885 /**
17886 * Checks if `path` exists on `object`.
17887 *
17888 * @private
17889 * @param {Object} object The object to query.
17890 * @param {Array|string} path The path to check.
17891 * @param {Function} hasFunc The function to check properties.
17892 * @returns {boolean} Returns `true` if `path` exists, else `false`.
17893 */
17894 function hasPath(object, path, hasFunc) {
17895 path = _castPath(path, object);
17896
17897 var index = -1,
17898 length = path.length,
17899 result = false;
17900
17901 while (++index < length) {
17902 var key = _toKey(path[index]);
17903 if (!(result = object != null && hasFunc(object, key))) {
17904 break;
17905 }
17906 object = object[key];
17907 }
17908 if (result || ++index != length) {
17909 return result;
17910 }
17911 length = object == null ? 0 : object.length;
17912 return !!length && isLength_1(length) && _isIndex(key, length) &&
17913 (isArray_1(object) || isArguments_1(object));
17914 }
17915
17916 var _hasPath = hasPath;
17917
17918 /**
17919 * Checks if `path` is a direct or inherited property of `object`.
17920 *
17921 * @static
17922 * @memberOf _
17923 * @since 4.0.0
17924 * @category Object
17925 * @param {Object} object The object to query.
17926 * @param {Array|string} path The path to check.
17927 * @returns {boolean} Returns `true` if `path` exists, else `false`.
17928 * @example
17929 *
17930 * var object = _.create({ 'a': _.create({ 'b': 2 }) });
17931 *
17932 * _.hasIn(object, 'a');
17933 * // => true
17934 *
17935 * _.hasIn(object, 'a.b');
17936 * // => true
17937 *
17938 * _.hasIn(object, ['a', 'b']);
17939 * // => true
17940 *
17941 * _.hasIn(object, 'b');
17942 * // => false
17943 */
17944 function hasIn(object, path) {
17945 return object != null && _hasPath(object, path, _baseHasIn);
17946 }
17947
17948 var hasIn_1 = hasIn;
17949
17950 /** Used to compose bitmasks for value comparisons. */
17951 var COMPARE_PARTIAL_FLAG$5 = 1,
17952 COMPARE_UNORDERED_FLAG$3 = 2;
17953
17954 /**
17955 * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
17956 *
17957 * @private
17958 * @param {string} path The path of the property to get.
17959 * @param {*} srcValue The value to match.
17960 * @returns {Function} Returns the new spec function.
17961 */
17962 function baseMatchesProperty(path, srcValue) {
17963 if (_isKey(path) && _isStrictComparable(srcValue)) {
17964 return _matchesStrictComparable(_toKey(path), srcValue);
17965 }
17966 return function(object) {
17967 var objValue = get_1(object, path);
17968 return (objValue === undefined && objValue === srcValue)
17969 ? hasIn_1(object, path)
17970 : _baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3);
17971 };
17972 }
17973
17974 var _baseMatchesProperty = baseMatchesProperty;
17975
17976 /**
17977 * This method returns the first argument it receives.
17978 *
17979 * @static
17980 * @since 0.1.0
17981 * @memberOf _
17982 * @category Util
17983 * @param {*} value Any value.
17984 * @returns {*} Returns `value`.
17985 * @example
17986 *
17987 * var object = { 'a': 1 };
17988 *
17989 * console.log(_.identity(object) === object);
17990 * // => true
17991 */
17992 function identity(value) {
17993 return value;
17994 }
17995
17996 var identity_1 = identity;
17997
17998 /**
17999 * The base implementation of `_.property` without support for deep paths.
18000 *
18001 * @private
18002 * @param {string} key The key of the property to get.
18003 * @returns {Function} Returns the new accessor function.
18004 */
18005 function baseProperty(key) {
18006 return function(object) {
18007 return object == null ? undefined : object[key];
18008 };
18009 }
18010
18011 var _baseProperty = baseProperty;
18012
18013 /**
18014 * A specialized version of `baseProperty` which supports deep paths.
18015 *
18016 * @private
18017 * @param {Array|string} path The path of the property to get.
18018 * @returns {Function} Returns the new accessor function.
18019 */
18020 function basePropertyDeep(path) {
18021 return function(object) {
18022 return _baseGet(object, path);
18023 };
18024 }
18025
18026 var _basePropertyDeep = basePropertyDeep;
18027
18028 /**
18029 * Creates a function that returns the value at `path` of a given object.
18030 *
18031 * @static
18032 * @memberOf _
18033 * @since 2.4.0
18034 * @category Util
18035 * @param {Array|string} path The path of the property to get.
18036 * @returns {Function} Returns the new accessor function.
18037 * @example
18038 *
18039 * var objects = [
18040 * { 'a': { 'b': 2 } },
18041 * { 'a': { 'b': 1 } }
18042 * ];
18043 *
18044 * _.map(objects, _.property('a.b'));
18045 * // => [2, 1]
18046 *
18047 * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
18048 * // => [1, 2]
18049 */
18050 function property(path) {
18051 return _isKey(path) ? _baseProperty(_toKey(path)) : _basePropertyDeep(path);
18052 }
18053
18054 var property_1 = property;
18055
18056 /**
18057 * The base implementation of `_.iteratee`.
18058 *
18059 * @private
18060 * @param {*} [value=_.identity] The value to convert to an iteratee.
18061 * @returns {Function} Returns the iteratee.
18062 */
18063 function baseIteratee(value) {
18064 // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
18065 // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
18066 if (typeof value == 'function') {
18067 return value;
18068 }
18069 if (value == null) {
18070 return identity_1;
18071 }
18072 if (typeof value == 'object') {
18073 return isArray_1(value)
18074 ? _baseMatchesProperty(value[0], value[1])
18075 : _baseMatches(value);
18076 }
18077 return property_1(value);
18078 }
18079
18080 var _baseIteratee = baseIteratee;
18081
18082 /**
18083 * Gets the last element of `array`.
18084 *
18085 * @static
18086 * @memberOf _
18087 * @since 0.1.0
18088 * @category Array
18089 * @param {Array} array The array to query.
18090 * @returns {*} Returns the last element of `array`.
18091 * @example
18092 *
18093 * _.last([1, 2, 3]);
18094 * // => 3
18095 */
18096 function last(array) {
18097 var length = array == null ? 0 : array.length;
18098 return length ? array[length - 1] : undefined;
18099 }
18100
18101 var last_1 = last;
18102
18103 /**
18104 * The base implementation of `_.slice` without an iteratee call guard.
18105 *
18106 * @private
18107 * @param {Array} array The array to slice.
18108 * @param {number} [start=0] The start position.
18109 * @param {number} [end=array.length] The end position.
18110 * @returns {Array} Returns the slice of `array`.
18111 */
18112 function baseSlice(array, start, end) {
18113 var index = -1,
18114 length = array.length;
18115
18116 if (start < 0) {
18117 start = -start > length ? 0 : (length + start);
18118 }
18119 end = end > length ? length : end;
18120 if (end < 0) {
18121 end += length;
18122 }
18123 length = start > end ? 0 : ((end - start) >>> 0);
18124 start >>>= 0;
18125
18126 var result = Array(length);
18127 while (++index < length) {
18128 result[index] = array[index + start];
18129 }
18130 return result;
18131 }
18132
18133 var _baseSlice = baseSlice;
18134
18135 /**
18136 * Gets the parent value at `path` of `object`.
18137 *
18138 * @private
18139 * @param {Object} object The object to query.
18140 * @param {Array} path The path to get the parent value of.
18141 * @returns {*} Returns the parent value.
18142 */
18143 function parent(object, path) {
18144 return path.length < 2 ? object : _baseGet(object, _baseSlice(path, 0, -1));
18145 }
18146
18147 var _parent = parent;
18148
18149 /**
18150 * The base implementation of `_.unset`.
18151 *
18152 * @private
18153 * @param {Object} object The object to modify.
18154 * @param {Array|string} path The property path to unset.
18155 * @returns {boolean} Returns `true` if the property is deleted, else `false`.
18156 */
18157 function baseUnset(object, path) {
18158 path = _castPath(path, object);
18159 object = _parent(object, path);
18160 return object == null || delete object[_toKey(last_1(path))];
18161 }
18162
18163 var _baseUnset = baseUnset;
18164
18165 /** Used for built-in method references. */
18166 var arrayProto$1 = Array.prototype;
18167
18168 /** Built-in value references. */
18169 var splice$1 = arrayProto$1.splice;
18170
18171 /**
18172 * The base implementation of `_.pullAt` without support for individual
18173 * indexes or capturing the removed elements.
18174 *
18175 * @private
18176 * @param {Array} array The array to modify.
18177 * @param {number[]} indexes The indexes of elements to remove.
18178 * @returns {Array} Returns `array`.
18179 */
18180 function basePullAt(array, indexes) {
18181 var length = array ? indexes.length : 0,
18182 lastIndex = length - 1;
18183
18184 while (length--) {
18185 var index = indexes[length];
18186 if (length == lastIndex || index !== previous) {
18187 var previous = index;
18188 if (_isIndex(index)) {
18189 splice$1.call(array, index, 1);
18190 } else {
18191 _baseUnset(array, index);
18192 }
18193 }
18194 }
18195 return array;
18196 }
18197
18198 var _basePullAt = basePullAt;
18199
18200 /**
18201 * Removes all elements from `array` that `predicate` returns truthy for
18202 * and returns an array of the removed elements. The predicate is invoked
18203 * with three arguments: (value, index, array).
18204 *
18205 * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
18206 * to pull elements from an array by value.
18207 *
18208 * @static
18209 * @memberOf _
18210 * @since 2.0.0
18211 * @category Array
18212 * @param {Array} array The array to modify.
18213 * @param {Function} [predicate=_.identity] The function invoked per iteration.
18214 * @returns {Array} Returns the new array of removed elements.
18215 * @example
18216 *
18217 * var array = [1, 2, 3, 4];
18218 * var evens = _.remove(array, function(n) {
18219 * return n % 2 == 0;
18220 * });
18221 *
18222 * console.log(array);
18223 * // => [1, 3]
18224 *
18225 * console.log(evens);
18226 * // => [2, 4]
18227 */
18228 function remove(array, predicate) {
18229 var result = [];
18230 if (!(array && array.length)) {
18231 return result;
18232 }
18233 var index = -1,
18234 indexes = [],
18235 length = array.length;
18236
18237 predicate = _baseIteratee(predicate);
18238 while (++index < length) {
18239 var value = array[index];
18240 if (predicate(value, index, array)) {
18241 result.push(value);
18242 indexes.push(index);
18243 }
18244 }
18245 _basePullAt(array, indexes);
18246 return result;
18247 }
18248
18249 var remove_1 = remove;
18250
18251 /** `Object#toString` result references. */
18252 var mapTag$3 = '[object Map]',
18253 setTag$3 = '[object Set]';
18254
18255 /** Used for built-in method references. */
18256 var objectProto$d = Object.prototype;
18257
18258 /** Used to check objects for own properties. */
18259 var hasOwnProperty$a = objectProto$d.hasOwnProperty;
18260
18261 /**
18262 * Checks if `value` is an empty object, collection, map, or set.
18263 *
18264 * Objects are considered empty if they have no own enumerable string keyed
18265 * properties.
18266 *
18267 * Array-like values such as `arguments` objects, arrays, buffers, strings, or
18268 * jQuery-like collections are considered empty if they have a `length` of `0`.
18269 * Similarly, maps and sets are considered empty if they have a `size` of `0`.
18270 *
18271 * @static
18272 * @memberOf _
18273 * @since 0.1.0
18274 * @category Lang
18275 * @param {*} value The value to check.
18276 * @returns {boolean} Returns `true` if `value` is empty, else `false`.
18277 * @example
18278 *
18279 * _.isEmpty(null);
18280 * // => true
18281 *
18282 * _.isEmpty(true);
18283 * // => true
18284 *
18285 * _.isEmpty(1);
18286 * // => true
18287 *
18288 * _.isEmpty([1, 2, 3]);
18289 * // => false
18290 *
18291 * _.isEmpty({ 'a': 1 });
18292 * // => false
18293 */
18294 function isEmpty(value) {
18295 if (value == null) {
18296 return true;
18297 }
18298 if (isArrayLike_1(value) &&
18299 (isArray_1(value) || typeof value == 'string' || typeof value.splice == 'function' ||
18300 isBuffer_1(value) || isTypedArray_1(value) || isArguments_1(value))) {
18301 return !value.length;
18302 }
18303 var tag = _getTag(value);
18304 if (tag == mapTag$3 || tag == setTag$3) {
18305 return !value.size;
18306 }
18307 if (_isPrototype(value)) {
18308 return !_baseKeys(value).length;
18309 }
18310 for (var key in value) {
18311 if (hasOwnProperty$a.call(value, key)) {
18312 return false;
18313 }
18314 }
18315 return true;
18316 }
18317
18318 var isEmpty_1 = isEmpty;
18319
18320 /**
18321 * A specialized version of `_.forEach` for arrays without support for
18322 * iteratee shorthands.
18323 *
18324 * @private
18325 * @param {Array} [array] The array to iterate over.
18326 * @param {Function} iteratee The function invoked per iteration.
18327 * @returns {Array} Returns `array`.
18328 */
18329 function arrayEach(array, iteratee) {
18330 var index = -1,
18331 length = array == null ? 0 : array.length;
18332
18333 while (++index < length) {
18334 if (iteratee(array[index], index, array) === false) {
18335 break;
18336 }
18337 }
18338 return array;
18339 }
18340
18341 var _arrayEach = arrayEach;
18342
18343 var defineProperty$1 = (function() {
18344 try {
18345 var func = _getNative(Object, 'defineProperty');
18346 func({}, '', {});
18347 return func;
18348 } catch (e) {}
18349 }());
18350
18351 var _defineProperty$1 = defineProperty$1;
18352
18353 /**
18354 * The base implementation of `assignValue` and `assignMergeValue` without
18355 * value checks.
18356 *
18357 * @private
18358 * @param {Object} object The object to modify.
18359 * @param {string} key The key of the property to assign.
18360 * @param {*} value The value to assign.
18361 */
18362 function baseAssignValue(object, key, value) {
18363 if (key == '__proto__' && _defineProperty$1) {
18364 _defineProperty$1(object, key, {
18365 'configurable': true,
18366 'enumerable': true,
18367 'value': value,
18368 'writable': true
18369 });
18370 } else {
18371 object[key] = value;
18372 }
18373 }
18374
18375 var _baseAssignValue = baseAssignValue;
18376
18377 /** Used for built-in method references. */
18378 var objectProto$e = Object.prototype;
18379
18380 /** Used to check objects for own properties. */
18381 var hasOwnProperty$b = objectProto$e.hasOwnProperty;
18382
18383 /**
18384 * Assigns `value` to `key` of `object` if the existing value is not equivalent
18385 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
18386 * for equality comparisons.
18387 *
18388 * @private
18389 * @param {Object} object The object to modify.
18390 * @param {string} key The key of the property to assign.
18391 * @param {*} value The value to assign.
18392 */
18393 function assignValue(object, key, value) {
18394 var objValue = object[key];
18395 if (!(hasOwnProperty$b.call(object, key) && eq_1(objValue, value)) ||
18396 (value === undefined && !(key in object))) {
18397 _baseAssignValue(object, key, value);
18398 }
18399 }
18400
18401 var _assignValue = assignValue;
18402
18403 /**
18404 * Copies properties of `source` to `object`.
18405 *
18406 * @private
18407 * @param {Object} source The object to copy properties from.
18408 * @param {Array} props The property identifiers to copy.
18409 * @param {Object} [object={}] The object to copy properties to.
18410 * @param {Function} [customizer] The function to customize copied values.
18411 * @returns {Object} Returns `object`.
18412 */
18413 function copyObject(source, props, object, customizer) {
18414 var isNew = !object;
18415 object || (object = {});
18416
18417 var index = -1,
18418 length = props.length;
18419
18420 while (++index < length) {
18421 var key = props[index];
18422
18423 var newValue = customizer
18424 ? customizer(object[key], source[key], key, object, source)
18425 : undefined;
18426
18427 if (newValue === undefined) {
18428 newValue = source[key];
18429 }
18430 if (isNew) {
18431 _baseAssignValue(object, key, newValue);
18432 } else {
18433 _assignValue(object, key, newValue);
18434 }
18435 }
18436 return object;
18437 }
18438
18439 var _copyObject = copyObject;
18440
18441 /**
18442 * The base implementation of `_.assign` without support for multiple sources
18443 * or `customizer` functions.
18444 *
18445 * @private
18446 * @param {Object} object The destination object.
18447 * @param {Object} source The source object.
18448 * @returns {Object} Returns `object`.
18449 */
18450 function baseAssign(object, source) {
18451 return object && _copyObject(source, keys_1(source), object);
18452 }
18453
18454 var _baseAssign = baseAssign;
18455
18456 /**
18457 * This function is like
18458 * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
18459 * except that it includes inherited enumerable properties.
18460 *
18461 * @private
18462 * @param {Object} object The object to query.
18463 * @returns {Array} Returns the array of property names.
18464 */
18465 function nativeKeysIn(object) {
18466 var result = [];
18467 if (object != null) {
18468 for (var key in Object(object)) {
18469 result.push(key);
18470 }
18471 }
18472 return result;
18473 }
18474
18475 var _nativeKeysIn = nativeKeysIn;
18476
18477 /** Used for built-in method references. */
18478 var objectProto$f = Object.prototype;
18479
18480 /** Used to check objects for own properties. */
18481 var hasOwnProperty$c = objectProto$f.hasOwnProperty;
18482
18483 /**
18484 * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
18485 *
18486 * @private
18487 * @param {Object} object The object to query.
18488 * @returns {Array} Returns the array of property names.
18489 */
18490 function baseKeysIn(object) {
18491 if (!isObject_1(object)) {
18492 return _nativeKeysIn(object);
18493 }
18494 var isProto = _isPrototype(object),
18495 result = [];
18496
18497 for (var key in object) {
18498 if (!(key == 'constructor' && (isProto || !hasOwnProperty$c.call(object, key)))) {
18499 result.push(key);
18500 }
18501 }
18502 return result;
18503 }
18504
18505 var _baseKeysIn = baseKeysIn;
18506
18507 /**
18508 * Creates an array of the own and inherited enumerable property names of `object`.
18509 *
18510 * **Note:** Non-object values are coerced to objects.
18511 *
18512 * @static
18513 * @memberOf _
18514 * @since 3.0.0
18515 * @category Object
18516 * @param {Object} object The object to query.
18517 * @returns {Array} Returns the array of property names.
18518 * @example
18519 *
18520 * function Foo() {
18521 * this.a = 1;
18522 * this.b = 2;
18523 * }
18524 *
18525 * Foo.prototype.c = 3;
18526 *
18527 * _.keysIn(new Foo);
18528 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
18529 */
18530 function keysIn(object) {
18531 return isArrayLike_1(object) ? _arrayLikeKeys(object, true) : _baseKeysIn(object);
18532 }
18533
18534 var keysIn_1 = keysIn;
18535
18536 /**
18537 * The base implementation of `_.assignIn` without support for multiple sources
18538 * or `customizer` functions.
18539 *
18540 * @private
18541 * @param {Object} object The destination object.
18542 * @param {Object} source The source object.
18543 * @returns {Object} Returns `object`.
18544 */
18545 function baseAssignIn(object, source) {
18546 return object && _copyObject(source, keysIn_1(source), object);
18547 }
18548
18549 var _baseAssignIn = baseAssignIn;
18550
18551 var _cloneBuffer = createCommonjsModule(function (module, exports) {
18552 /** Detect free variable `exports`. */
18553 var freeExports = exports && !exports.nodeType && exports;
18554
18555 /** Detect free variable `module`. */
18556 var freeModule = freeExports && 'object' == 'object' && module && !module.nodeType && module;
18557
18558 /** Detect the popular CommonJS extension `module.exports`. */
18559 var moduleExports = freeModule && freeModule.exports === freeExports;
18560
18561 /** Built-in value references. */
18562 var Buffer = moduleExports ? _root.Buffer : undefined,
18563 allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;
18564
18565 /**
18566 * Creates a clone of `buffer`.
18567 *
18568 * @private
18569 * @param {Buffer} buffer The buffer to clone.
18570 * @param {boolean} [isDeep] Specify a deep clone.
18571 * @returns {Buffer} Returns the cloned buffer.
18572 */
18573 function cloneBuffer(buffer, isDeep) {
18574 if (isDeep) {
18575 return buffer.slice();
18576 }
18577 var length = buffer.length,
18578 result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
18579
18580 buffer.copy(result);
18581 return result;
18582 }
18583
18584 module.exports = cloneBuffer;
18585 });
18586
18587 /**
18588 * Copies own symbols of `source` to `object`.
18589 *
18590 * @private
18591 * @param {Object} source The object to copy symbols from.
18592 * @param {Object} [object={}] The object to copy symbols to.
18593 * @returns {Object} Returns `object`.
18594 */
18595 function copySymbols(source, object) {
18596 return _copyObject(source, _getSymbols(source), object);
18597 }
18598
18599 var _copySymbols = copySymbols;
18600
18601 /* Built-in method references for those with the same name as other `lodash` methods. */
18602 var nativeGetSymbols$1 = Object.getOwnPropertySymbols;
18603
18604 /**
18605 * Creates an array of the own and inherited enumerable symbols of `object`.
18606 *
18607 * @private
18608 * @param {Object} object The object to query.
18609 * @returns {Array} Returns the array of symbols.
18610 */
18611 var getSymbolsIn = !nativeGetSymbols$1 ? stubArray_1 : function(object) {
18612 var result = [];
18613 while (object) {
18614 _arrayPush(result, _getSymbols(object));
18615 object = _getPrototype(object);
18616 }
18617 return result;
18618 };
18619
18620 var _getSymbolsIn = getSymbolsIn;
18621
18622 /**
18623 * Copies own and inherited symbols of `source` to `object`.
18624 *
18625 * @private
18626 * @param {Object} source The object to copy symbols from.
18627 * @param {Object} [object={}] The object to copy symbols to.
18628 * @returns {Object} Returns `object`.
18629 */
18630 function copySymbolsIn(source, object) {
18631 return _copyObject(source, _getSymbolsIn(source), object);
18632 }
18633
18634 var _copySymbolsIn = copySymbolsIn;
18635
18636 /**
18637 * Creates an array of own and inherited enumerable property names and
18638 * symbols of `object`.
18639 *
18640 * @private
18641 * @param {Object} object The object to query.
18642 * @returns {Array} Returns the array of property names and symbols.
18643 */
18644 function getAllKeysIn(object) {
18645 return _baseGetAllKeys(object, keysIn_1, _getSymbolsIn);
18646 }
18647
18648 var _getAllKeysIn = getAllKeysIn;
18649
18650 /** Used for built-in method references. */
18651 var objectProto$g = Object.prototype;
18652
18653 /** Used to check objects for own properties. */
18654 var hasOwnProperty$d = objectProto$g.hasOwnProperty;
18655
18656 /**
18657 * Initializes an array clone.
18658 *
18659 * @private
18660 * @param {Array} array The array to clone.
18661 * @returns {Array} Returns the initialized clone.
18662 */
18663 function initCloneArray(array) {
18664 var length = array.length,
18665 result = new array.constructor(length);
18666
18667 // Add properties assigned by `RegExp#exec`.
18668 if (length && typeof array[0] == 'string' && hasOwnProperty$d.call(array, 'index')) {
18669 result.index = array.index;
18670 result.input = array.input;
18671 }
18672 return result;
18673 }
18674
18675 var _initCloneArray = initCloneArray;
18676
18677 /**
18678 * Creates a clone of `arrayBuffer`.
18679 *
18680 * @private
18681 * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
18682 * @returns {ArrayBuffer} Returns the cloned array buffer.
18683 */
18684 function cloneArrayBuffer(arrayBuffer) {
18685 var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
18686 new _Uint8Array(result).set(new _Uint8Array(arrayBuffer));
18687 return result;
18688 }
18689
18690 var _cloneArrayBuffer = cloneArrayBuffer;
18691
18692 /**
18693 * Creates a clone of `dataView`.
18694 *
18695 * @private
18696 * @param {Object} dataView The data view to clone.
18697 * @param {boolean} [isDeep] Specify a deep clone.
18698 * @returns {Object} Returns the cloned data view.
18699 */
18700 function cloneDataView(dataView, isDeep) {
18701 var buffer = isDeep ? _cloneArrayBuffer(dataView.buffer) : dataView.buffer;
18702 return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
18703 }
18704
18705 var _cloneDataView = cloneDataView;
18706
18707 /** Used to match `RegExp` flags from their coerced string values. */
18708 var reFlags = /\w*$/;
18709
18710 /**
18711 * Creates a clone of `regexp`.
18712 *
18713 * @private
18714 * @param {Object} regexp The regexp to clone.
18715 * @returns {Object} Returns the cloned regexp.
18716 */
18717 function cloneRegExp(regexp) {
18718 var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
18719 result.lastIndex = regexp.lastIndex;
18720 return result;
18721 }
18722
18723 var _cloneRegExp = cloneRegExp;
18724
18725 /** Used to convert symbols to primitives and strings. */
18726 var symbolProto$2 = _Symbol ? _Symbol.prototype : undefined,
18727 symbolValueOf$1 = symbolProto$2 ? symbolProto$2.valueOf : undefined;
18728
18729 /**
18730 * Creates a clone of the `symbol` object.
18731 *
18732 * @private
18733 * @param {Object} symbol The symbol object to clone.
18734 * @returns {Object} Returns the cloned symbol object.
18735 */
18736 function cloneSymbol(symbol) {
18737 return symbolValueOf$1 ? Object(symbolValueOf$1.call(symbol)) : {};
18738 }
18739
18740 var _cloneSymbol = cloneSymbol;
18741
18742 /**
18743 * Creates a clone of `typedArray`.
18744 *
18745 * @private
18746 * @param {Object} typedArray The typed array to clone.
18747 * @param {boolean} [isDeep] Specify a deep clone.
18748 * @returns {Object} Returns the cloned typed array.
18749 */
18750 function cloneTypedArray(typedArray, isDeep) {
18751 var buffer = isDeep ? _cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
18752 return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
18753 }
18754
18755 var _cloneTypedArray = cloneTypedArray;
18756
18757 /** `Object#toString` result references. */
18758 var boolTag$2 = '[object Boolean]',
18759 dateTag$2 = '[object Date]',
18760 mapTag$4 = '[object Map]',
18761 numberTag$2 = '[object Number]',
18762 regexpTag$2 = '[object RegExp]',
18763 setTag$4 = '[object Set]',
18764 stringTag$2 = '[object String]',
18765 symbolTag$2 = '[object Symbol]';
18766
18767 var arrayBufferTag$2 = '[object ArrayBuffer]',
18768 dataViewTag$3 = '[object DataView]',
18769 float32Tag$1 = '[object Float32Array]',
18770 float64Tag$1 = '[object Float64Array]',
18771 int8Tag$1 = '[object Int8Array]',
18772 int16Tag$1 = '[object Int16Array]',
18773 int32Tag$1 = '[object Int32Array]',
18774 uint8Tag$1 = '[object Uint8Array]',
18775 uint8ClampedTag$1 = '[object Uint8ClampedArray]',
18776 uint16Tag$1 = '[object Uint16Array]',
18777 uint32Tag$1 = '[object Uint32Array]';
18778
18779 /**
18780 * Initializes an object clone based on its `toStringTag`.
18781 *
18782 * **Note:** This function only supports cloning values with tags of
18783 * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
18784 *
18785 * @private
18786 * @param {Object} object The object to clone.
18787 * @param {string} tag The `toStringTag` of the object to clone.
18788 * @param {boolean} [isDeep] Specify a deep clone.
18789 * @returns {Object} Returns the initialized clone.
18790 */
18791 function initCloneByTag(object, tag, isDeep) {
18792 var Ctor = object.constructor;
18793 switch (tag) {
18794 case arrayBufferTag$2:
18795 return _cloneArrayBuffer(object);
18796
18797 case boolTag$2:
18798 case dateTag$2:
18799 return new Ctor(+object);
18800
18801 case dataViewTag$3:
18802 return _cloneDataView(object, isDeep);
18803
18804 case float32Tag$1: case float64Tag$1:
18805 case int8Tag$1: case int16Tag$1: case int32Tag$1:
18806 case uint8Tag$1: case uint8ClampedTag$1: case uint16Tag$1: case uint32Tag$1:
18807 return _cloneTypedArray(object, isDeep);
18808
18809 case mapTag$4:
18810 return new Ctor;
18811
18812 case numberTag$2:
18813 case stringTag$2:
18814 return new Ctor(object);
18815
18816 case regexpTag$2:
18817 return _cloneRegExp(object);
18818
18819 case setTag$4:
18820 return new Ctor;
18821
18822 case symbolTag$2:
18823 return _cloneSymbol(object);
18824 }
18825 }
18826
18827 var _initCloneByTag = initCloneByTag;
18828
18829 /** Built-in value references. */
18830 var objectCreate = Object.create;
18831
18832 /**
18833 * The base implementation of `_.create` without support for assigning
18834 * properties to the created object.
18835 *
18836 * @private
18837 * @param {Object} proto The object to inherit from.
18838 * @returns {Object} Returns the new object.
18839 */
18840 var baseCreate = (function() {
18841 function object() {}
18842 return function(proto) {
18843 if (!isObject_1(proto)) {
18844 return {};
18845 }
18846 if (objectCreate) {
18847 return objectCreate(proto);
18848 }
18849 object.prototype = proto;
18850 var result = new object;
18851 object.prototype = undefined;
18852 return result;
18853 };
18854 }());
18855
18856 var _baseCreate = baseCreate;
18857
18858 /**
18859 * Initializes an object clone.
18860 *
18861 * @private
18862 * @param {Object} object The object to clone.
18863 * @returns {Object} Returns the initialized clone.
18864 */
18865 function initCloneObject(object) {
18866 return (typeof object.constructor == 'function' && !_isPrototype(object))
18867 ? _baseCreate(_getPrototype(object))
18868 : {};
18869 }
18870
18871 var _initCloneObject = initCloneObject;
18872
18873 /** `Object#toString` result references. */
18874 var mapTag$5 = '[object Map]';
18875
18876 /**
18877 * The base implementation of `_.isMap` without Node.js optimizations.
18878 *
18879 * @private
18880 * @param {*} value The value to check.
18881 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
18882 */
18883 function baseIsMap(value) {
18884 return isObjectLike_1(value) && _getTag(value) == mapTag$5;
18885 }
18886
18887 var _baseIsMap = baseIsMap;
18888
18889 /* Node.js helper references. */
18890 var nodeIsMap = _nodeUtil && _nodeUtil.isMap;
18891
18892 /**
18893 * Checks if `value` is classified as a `Map` object.
18894 *
18895 * @static
18896 * @memberOf _
18897 * @since 4.3.0
18898 * @category Lang
18899 * @param {*} value The value to check.
18900 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
18901 * @example
18902 *
18903 * _.isMap(new Map);
18904 * // => true
18905 *
18906 * _.isMap(new WeakMap);
18907 * // => false
18908 */
18909 var isMap = nodeIsMap ? _baseUnary(nodeIsMap) : _baseIsMap;
18910
18911 var isMap_1 = isMap;
18912
18913 /** `Object#toString` result references. */
18914 var setTag$5 = '[object Set]';
18915
18916 /**
18917 * The base implementation of `_.isSet` without Node.js optimizations.
18918 *
18919 * @private
18920 * @param {*} value The value to check.
18921 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
18922 */
18923 function baseIsSet(value) {
18924 return isObjectLike_1(value) && _getTag(value) == setTag$5;
18925 }
18926
18927 var _baseIsSet = baseIsSet;
18928
18929 /* Node.js helper references. */
18930 var nodeIsSet = _nodeUtil && _nodeUtil.isSet;
18931
18932 /**
18933 * Checks if `value` is classified as a `Set` object.
18934 *
18935 * @static
18936 * @memberOf _
18937 * @since 4.3.0
18938 * @category Lang
18939 * @param {*} value The value to check.
18940 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
18941 * @example
18942 *
18943 * _.isSet(new Set);
18944 * // => true
18945 *
18946 * _.isSet(new WeakSet);
18947 * // => false
18948 */
18949 var isSet = nodeIsSet ? _baseUnary(nodeIsSet) : _baseIsSet;
18950
18951 var isSet_1 = isSet;
18952
18953 /** Used to compose bitmasks for cloning. */
18954 var CLONE_DEEP_FLAG = 1,
18955 CLONE_FLAT_FLAG = 2,
18956 CLONE_SYMBOLS_FLAG = 4;
18957
18958 /** `Object#toString` result references. */
18959 var argsTag$3 = '[object Arguments]',
18960 arrayTag$2 = '[object Array]',
18961 boolTag$3 = '[object Boolean]',
18962 dateTag$3 = '[object Date]',
18963 errorTag$2 = '[object Error]',
18964 funcTag$2 = '[object Function]',
18965 genTag$1 = '[object GeneratorFunction]',
18966 mapTag$6 = '[object Map]',
18967 numberTag$3 = '[object Number]',
18968 objectTag$4 = '[object Object]',
18969 regexpTag$3 = '[object RegExp]',
18970 setTag$6 = '[object Set]',
18971 stringTag$3 = '[object String]',
18972 symbolTag$3 = '[object Symbol]',
18973 weakMapTag$2 = '[object WeakMap]';
18974
18975 var arrayBufferTag$3 = '[object ArrayBuffer]',
18976 dataViewTag$4 = '[object DataView]',
18977 float32Tag$2 = '[object Float32Array]',
18978 float64Tag$2 = '[object Float64Array]',
18979 int8Tag$2 = '[object Int8Array]',
18980 int16Tag$2 = '[object Int16Array]',
18981 int32Tag$2 = '[object Int32Array]',
18982 uint8Tag$2 = '[object Uint8Array]',
18983 uint8ClampedTag$2 = '[object Uint8ClampedArray]',
18984 uint16Tag$2 = '[object Uint16Array]',
18985 uint32Tag$2 = '[object Uint32Array]';
18986
18987 /** Used to identify `toStringTag` values supported by `_.clone`. */
18988 var cloneableTags = {};
18989 cloneableTags[argsTag$3] = cloneableTags[arrayTag$2] =
18990 cloneableTags[arrayBufferTag$3] = cloneableTags[dataViewTag$4] =
18991 cloneableTags[boolTag$3] = cloneableTags[dateTag$3] =
18992 cloneableTags[float32Tag$2] = cloneableTags[float64Tag$2] =
18993 cloneableTags[int8Tag$2] = cloneableTags[int16Tag$2] =
18994 cloneableTags[int32Tag$2] = cloneableTags[mapTag$6] =
18995 cloneableTags[numberTag$3] = cloneableTags[objectTag$4] =
18996 cloneableTags[regexpTag$3] = cloneableTags[setTag$6] =
18997 cloneableTags[stringTag$3] = cloneableTags[symbolTag$3] =
18998 cloneableTags[uint8Tag$2] = cloneableTags[uint8ClampedTag$2] =
18999 cloneableTags[uint16Tag$2] = cloneableTags[uint32Tag$2] = true;
19000 cloneableTags[errorTag$2] = cloneableTags[funcTag$2] =
19001 cloneableTags[weakMapTag$2] = false;
19002
19003 /**
19004 * The base implementation of `_.clone` and `_.cloneDeep` which tracks
19005 * traversed objects.
19006 *
19007 * @private
19008 * @param {*} value The value to clone.
19009 * @param {boolean} bitmask The bitmask flags.
19010 * 1 - Deep clone
19011 * 2 - Flatten inherited properties
19012 * 4 - Clone symbols
19013 * @param {Function} [customizer] The function to customize cloning.
19014 * @param {string} [key] The key of `value`.
19015 * @param {Object} [object] The parent object of `value`.
19016 * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
19017 * @returns {*} Returns the cloned value.
19018 */
19019 function baseClone(value, bitmask, customizer, key, object, stack) {
19020 var result,
19021 isDeep = bitmask & CLONE_DEEP_FLAG,
19022 isFlat = bitmask & CLONE_FLAT_FLAG,
19023 isFull = bitmask & CLONE_SYMBOLS_FLAG;
19024
19025 if (customizer) {
19026 result = object ? customizer(value, key, object, stack) : customizer(value);
19027 }
19028 if (result !== undefined) {
19029 return result;
19030 }
19031 if (!isObject_1(value)) {
19032 return value;
19033 }
19034 var isArr = isArray_1(value);
19035 if (isArr) {
19036 result = _initCloneArray(value);
19037 if (!isDeep) {
19038 return _copyArray(value, result);
19039 }
19040 } else {
19041 var tag = _getTag(value),
19042 isFunc = tag == funcTag$2 || tag == genTag$1;
19043
19044 if (isBuffer_1(value)) {
19045 return _cloneBuffer(value, isDeep);
19046 }
19047 if (tag == objectTag$4 || tag == argsTag$3 || (isFunc && !object)) {
19048 result = (isFlat || isFunc) ? {} : _initCloneObject(value);
19049 if (!isDeep) {
19050 return isFlat
19051 ? _copySymbolsIn(value, _baseAssignIn(result, value))
19052 : _copySymbols(value, _baseAssign(result, value));
19053 }
19054 } else {
19055 if (!cloneableTags[tag]) {
19056 return object ? value : {};
19057 }
19058 result = _initCloneByTag(value, tag, isDeep);
19059 }
19060 }
19061 // Check for circular references and return its corresponding clone.
19062 stack || (stack = new _Stack);
19063 var stacked = stack.get(value);
19064 if (stacked) {
19065 return stacked;
19066 }
19067 stack.set(value, result);
19068
19069 if (isSet_1(value)) {
19070 value.forEach(function(subValue) {
19071 result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
19072 });
19073 } else if (isMap_1(value)) {
19074 value.forEach(function(subValue, key) {
19075 result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
19076 });
19077 }
19078
19079 var keysFunc = isFull
19080 ? (isFlat ? _getAllKeysIn : _getAllKeys)
19081 : (isFlat ? keysIn_1 : keys_1);
19082
19083 var props = isArr ? undefined : keysFunc(value);
19084 _arrayEach(props || value, function(subValue, key) {
19085 if (props) {
19086 key = subValue;
19087 subValue = value[key];
19088 }
19089 // Recursively populate clone (susceptible to call stack limits).
19090 _assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
19091 });
19092 return result;
19093 }
19094
19095 var _baseClone = baseClone;
19096
19097 /** Used to compose bitmasks for cloning. */
19098 var CLONE_DEEP_FLAG$1 = 1,
19099 CLONE_SYMBOLS_FLAG$1 = 4;
19100
19101 /**
19102 * This method is like `_.clone` except that it recursively clones `value`.
19103 *
19104 * @static
19105 * @memberOf _
19106 * @since 1.0.0
19107 * @category Lang
19108 * @param {*} value The value to recursively clone.
19109 * @returns {*} Returns the deep cloned value.
19110 * @see _.clone
19111 * @example
19112 *
19113 * var objects = [{ 'a': 1 }, { 'b': 2 }];
19114 *
19115 * var deep = _.cloneDeep(objects);
19116 * console.log(deep[0] === objects[0]);
19117 * // => false
19118 */
19119 function cloneDeep(value) {
19120 return _baseClone(value, CLONE_DEEP_FLAG$1 | CLONE_SYMBOLS_FLAG$1);
19121 }
19122
19123 var cloneDeep_1 = cloneDeep;
19124
19125 /**
19126 * Creates a `_.find` or `_.findLast` function.
19127 *
19128 * @private
19129 * @param {Function} findIndexFunc The function to find the collection index.
19130 * @returns {Function} Returns the new find function.
19131 */
19132 function createFind(findIndexFunc) {
19133 return function(collection, predicate, fromIndex) {
19134 var iterable = Object(collection);
19135 if (!isArrayLike_1(collection)) {
19136 var iteratee = _baseIteratee(predicate);
19137 collection = keys_1(collection);
19138 predicate = function(key) { return iteratee(iterable[key], key, iterable); };
19139 }
19140 var index = findIndexFunc(collection, predicate, fromIndex);
19141 return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
19142 };
19143 }
19144
19145 var _createFind = createFind;
19146
19147 /**
19148 * The base implementation of `_.findIndex` and `_.findLastIndex` without
19149 * support for iteratee shorthands.
19150 *
19151 * @private
19152 * @param {Array} array The array to inspect.
19153 * @param {Function} predicate The function invoked per iteration.
19154 * @param {number} fromIndex The index to search from.
19155 * @param {boolean} [fromRight] Specify iterating from right to left.
19156 * @returns {number} Returns the index of the matched value, else `-1`.
19157 */
19158 function baseFindIndex(array, predicate, fromIndex, fromRight) {
19159 var length = array.length,
19160 index = fromIndex + (fromRight ? 1 : -1);
19161
19162 while ((fromRight ? index-- : ++index < length)) {
19163 if (predicate(array[index], index, array)) {
19164 return index;
19165 }
19166 }
19167 return -1;
19168 }
19169
19170 var _baseFindIndex = baseFindIndex;
19171
19172 /** Used to match a single whitespace character. */
19173 var reWhitespace = /\s/;
19174
19175 /**
19176 * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
19177 * character of `string`.
19178 *
19179 * @private
19180 * @param {string} string The string to inspect.
19181 * @returns {number} Returns the index of the last non-whitespace character.
19182 */
19183 function trimmedEndIndex(string) {
19184 var index = string.length;
19185
19186 while (index-- && reWhitespace.test(string.charAt(index))) {}
19187 return index;
19188 }
19189
19190 var _trimmedEndIndex = trimmedEndIndex;
19191
19192 /** Used to match leading whitespace. */
19193 var reTrimStart = /^\s+/;
19194
19195 /**
19196 * The base implementation of `_.trim`.
19197 *
19198 * @private
19199 * @param {string} string The string to trim.
19200 * @returns {string} Returns the trimmed string.
19201 */
19202 function baseTrim(string) {
19203 return string
19204 ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '')
19205 : string;
19206 }
19207
19208 var _baseTrim = baseTrim;
19209
19210 /** Used as references for various `Number` constants. */
19211 var NAN = 0 / 0;
19212
19213 /** Used to detect bad signed hexadecimal string values. */
19214 var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
19215
19216 /** Used to detect binary string values. */
19217 var reIsBinary = /^0b[01]+$/i;
19218
19219 /** Used to detect octal string values. */
19220 var reIsOctal = /^0o[0-7]+$/i;
19221
19222 /** Built-in method references without a dependency on `root`. */
19223 var freeParseInt = parseInt;
19224
19225 /**
19226 * Converts `value` to a number.
19227 *
19228 * @static
19229 * @memberOf _
19230 * @since 4.0.0
19231 * @category Lang
19232 * @param {*} value The value to process.
19233 * @returns {number} Returns the number.
19234 * @example
19235 *
19236 * _.toNumber(3.2);
19237 * // => 3.2
19238 *
19239 * _.toNumber(Number.MIN_VALUE);
19240 * // => 5e-324
19241 *
19242 * _.toNumber(Infinity);
19243 * // => Infinity
19244 *
19245 * _.toNumber('3.2');
19246 * // => 3.2
19247 */
19248 function toNumber(value) {
19249 if (typeof value == 'number') {
19250 return value;
19251 }
19252 if (isSymbol_1(value)) {
19253 return NAN;
19254 }
19255 if (isObject_1(value)) {
19256 var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
19257 value = isObject_1(other) ? (other + '') : other;
19258 }
19259 if (typeof value != 'string') {
19260 return value === 0 ? value : +value;
19261 }
19262 value = _baseTrim(value);
19263 var isBinary = reIsBinary.test(value);
19264 return (isBinary || reIsOctal.test(value))
19265 ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
19266 : (reIsBadHex.test(value) ? NAN : +value);
19267 }
19268
19269 var toNumber_1 = toNumber;
19270
19271 /** Used as references for various `Number` constants. */
19272 var INFINITY$2 = 1 / 0,
19273 MAX_INTEGER = 1.7976931348623157e+308;
19274
19275 /**
19276 * Converts `value` to a finite number.
19277 *
19278 * @static
19279 * @memberOf _
19280 * @since 4.12.0
19281 * @category Lang
19282 * @param {*} value The value to convert.
19283 * @returns {number} Returns the converted number.
19284 * @example
19285 *
19286 * _.toFinite(3.2);
19287 * // => 3.2
19288 *
19289 * _.toFinite(Number.MIN_VALUE);
19290 * // => 5e-324
19291 *
19292 * _.toFinite(Infinity);
19293 * // => 1.7976931348623157e+308
19294 *
19295 * _.toFinite('3.2');
19296 * // => 3.2
19297 */
19298 function toFinite(value) {
19299 if (!value) {
19300 return value === 0 ? value : 0;
19301 }
19302 value = toNumber_1(value);
19303 if (value === INFINITY$2 || value === -INFINITY$2) {
19304 var sign = (value < 0 ? -1 : 1);
19305 return sign * MAX_INTEGER;
19306 }
19307 return value === value ? value : 0;
19308 }
19309
19310 var toFinite_1 = toFinite;
19311
19312 /**
19313 * Converts `value` to an integer.
19314 *
19315 * **Note:** This method is loosely based on
19316 * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
19317 *
19318 * @static
19319 * @memberOf _
19320 * @since 4.0.0
19321 * @category Lang
19322 * @param {*} value The value to convert.
19323 * @returns {number} Returns the converted integer.
19324 * @example
19325 *
19326 * _.toInteger(3.2);
19327 * // => 3
19328 *
19329 * _.toInteger(Number.MIN_VALUE);
19330 * // => 0
19331 *
19332 * _.toInteger(Infinity);
19333 * // => 1.7976931348623157e+308
19334 *
19335 * _.toInteger('3.2');
19336 * // => 3
19337 */
19338 function toInteger(value) {
19339 var result = toFinite_1(value),
19340 remainder = result % 1;
19341
19342 return result === result ? (remainder ? result - remainder : result) : 0;
19343 }
19344
19345 var toInteger_1 = toInteger;
19346
19347 /* Built-in method references for those with the same name as other `lodash` methods. */
19348 var nativeMax = Math.max;
19349
19350 /**
19351 * This method is like `_.find` except that it returns the index of the first
19352 * element `predicate` returns truthy for instead of the element itself.
19353 *
19354 * @static
19355 * @memberOf _
19356 * @since 1.1.0
19357 * @category Array
19358 * @param {Array} array The array to inspect.
19359 * @param {Function} [predicate=_.identity] The function invoked per iteration.
19360 * @param {number} [fromIndex=0] The index to search from.
19361 * @returns {number} Returns the index of the found element, else `-1`.
19362 * @example
19363 *
19364 * var users = [
19365 * { 'user': 'barney', 'active': false },
19366 * { 'user': 'fred', 'active': false },
19367 * { 'user': 'pebbles', 'active': true }
19368 * ];
19369 *
19370 * _.findIndex(users, function(o) { return o.user == 'barney'; });
19371 * // => 0
19372 *
19373 * // The `_.matches` iteratee shorthand.
19374 * _.findIndex(users, { 'user': 'fred', 'active': false });
19375 * // => 1
19376 *
19377 * // The `_.matchesProperty` iteratee shorthand.
19378 * _.findIndex(users, ['active', false]);
19379 * // => 0
19380 *
19381 * // The `_.property` iteratee shorthand.
19382 * _.findIndex(users, 'active');
19383 * // => 2
19384 */
19385 function findIndex(array, predicate, fromIndex) {
19386 var length = array == null ? 0 : array.length;
19387 if (!length) {
19388 return -1;
19389 }
19390 var index = fromIndex == null ? 0 : toInteger_1(fromIndex);
19391 if (index < 0) {
19392 index = nativeMax(length + index, 0);
19393 }
19394 return _baseFindIndex(array, _baseIteratee(predicate), index);
19395 }
19396
19397 var findIndex_1 = findIndex;
19398
19399 /**
19400 * Iterates over elements of `collection`, returning the first element
19401 * `predicate` returns truthy for. The predicate is invoked with three
19402 * arguments: (value, index|key, collection).
19403 *
19404 * @static
19405 * @memberOf _
19406 * @since 0.1.0
19407 * @category Collection
19408 * @param {Array|Object} collection The collection to inspect.
19409 * @param {Function} [predicate=_.identity] The function invoked per iteration.
19410 * @param {number} [fromIndex=0] The index to search from.
19411 * @returns {*} Returns the matched element, else `undefined`.
19412 * @example
19413 *
19414 * var users = [
19415 * { 'user': 'barney', 'age': 36, 'active': true },
19416 * { 'user': 'fred', 'age': 40, 'active': false },
19417 * { 'user': 'pebbles', 'age': 1, 'active': true }
19418 * ];
19419 *
19420 * _.find(users, function(o) { return o.age < 40; });
19421 * // => object for 'barney'
19422 *
19423 * // The `_.matches` iteratee shorthand.
19424 * _.find(users, { 'age': 1, 'active': true });
19425 * // => object for 'pebbles'
19426 *
19427 * // The `_.matchesProperty` iteratee shorthand.
19428 * _.find(users, ['active', false]);
19429 * // => object for 'fred'
19430 *
19431 * // The `_.property` iteratee shorthand.
19432 * _.find(users, 'active');
19433 * // => object for 'barney'
19434 */
19435 var find = _createFind(findIndex_1);
19436
19437 var find_1 = find;
19438
19439 // IMClient
19440 var UNREAD_MESSAGES_COUNT_UPDATE = 'unreadmessagescountupdate';
19441 var CLOSE = 'close';
19442 var CONFLICT = 'conflict';
19443 var CONVERSATION_INFO_UPDATED = 'conversationinfoupdated';
19444 var UNHANDLED_MESSAGE = 'unhandledmessage'; // shared
19445
19446 var INVITED = 'invited';
19447 var KICKED = 'kicked';
19448 var MEMBERS_JOINED = 'membersjoined';
19449 var MEMBERS_LEFT = 'membersleft';
19450 var MEMBER_INFO_UPDATED = 'memberinfoupdated';
19451 var BLOCKED = 'blocked';
19452 var UNBLOCKED = 'unblocked';
19453 var MEMBERS_BLOCKED = 'membersblocked';
19454 var MEMBERS_UNBLOCKED = 'membersunblocked';
19455 var MUTED = 'muted';
19456 var UNMUTED = 'unmuted';
19457 var MEMBERS_MUTED = 'membersmuted';
19458 var MEMBERS_UNMUTED = 'membersunmuted';
19459 var MESSAGE$1 = 'message';
19460 var MESSAGE_RECALL = 'messagerecall';
19461 var MESSAGE_UPDATE = 'messageupdate'; // Conversation
19462
19463 var LAST_DELIVERED_AT_UPDATE = 'lastdeliveredatupdate';
19464 var LAST_READ_AT_UPDATE = 'lastreadatupdate';
19465 var INFO_UPDATED = 'infoupdated';
19466
19467 var IMEvent = /*#__PURE__*/Object.freeze({
19468 __proto__: null,
19469 UNREAD_MESSAGES_COUNT_UPDATE: UNREAD_MESSAGES_COUNT_UPDATE,
19470 CLOSE: CLOSE,
19471 CONFLICT: CONFLICT,
19472 CONVERSATION_INFO_UPDATED: CONVERSATION_INFO_UPDATED,
19473 UNHANDLED_MESSAGE: UNHANDLED_MESSAGE,
19474 INVITED: INVITED,
19475 KICKED: KICKED,
19476 MEMBERS_JOINED: MEMBERS_JOINED,
19477 MEMBERS_LEFT: MEMBERS_LEFT,
19478 MEMBER_INFO_UPDATED: MEMBER_INFO_UPDATED,
19479 BLOCKED: BLOCKED,
19480 UNBLOCKED: UNBLOCKED,
19481 MEMBERS_BLOCKED: MEMBERS_BLOCKED,
19482 MEMBERS_UNBLOCKED: MEMBERS_UNBLOCKED,
19483 MUTED: MUTED,
19484 UNMUTED: UNMUTED,
19485 MEMBERS_MUTED: MEMBERS_MUTED,
19486 MEMBERS_UNMUTED: MEMBERS_UNMUTED,
19487 MESSAGE: MESSAGE$1,
19488 MESSAGE_RECALL: MESSAGE_RECALL,
19489 MESSAGE_UPDATE: MESSAGE_UPDATE,
19490 LAST_DELIVERED_AT_UPDATE: LAST_DELIVERED_AT_UPDATE,
19491 LAST_READ_AT_UPDATE: LAST_READ_AT_UPDATE,
19492 INFO_UPDATED: INFO_UPDATED
19493 });
19494
19495 var _rMessageStatus;
19496
19497 function ownKeys$3(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
19498
19499 function _objectSpread$3(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$3(Object(source), true).forEach(function (key) { defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$3(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
19500 /**
19501 * 消息状态枚举
19502 * @enum {Symbol}
19503 * @since 3.2.0
19504 * @memberof module:leancloud-realtime
19505 */
19506
19507 var MessageStatus = {
19508 /** 初始状态、未知状态 */
19509 NONE: Symbol('none'),
19510
19511 /** 正在发送 */
19512 SENDING: Symbol('sending'),
19513
19514 /** 已发送 */
19515 SENT: Symbol('sent'),
19516
19517 /** 已送达 */
19518 DELIVERED: Symbol('delivered'),
19519
19520 /** 发送失败 */
19521 FAILED: Symbol('failed')
19522 };
19523 Object.freeze(MessageStatus);
19524 var rMessageStatus = (_rMessageStatus = {}, defineProperty(_rMessageStatus, MessageStatus.NONE, true), defineProperty(_rMessageStatus, MessageStatus.SENDING, true), defineProperty(_rMessageStatus, MessageStatus.SENT, true), defineProperty(_rMessageStatus, MessageStatus.DELIVERED, true), defineProperty(_rMessageStatus, MessageStatus.READ, true), defineProperty(_rMessageStatus, MessageStatus.FAILED, true), _rMessageStatus);
19525
19526 var Message = /*#__PURE__*/function () {
19527 /**
19528 * @implements AVMessage
19529 * @param {Object|String|ArrayBuffer} content 消息内容
19530 */
19531 function Message(content) {
19532 Object.assign(this, {
19533 content: content
19534 }, {
19535 /**
19536 * @type {String}
19537 * @memberof Message#
19538 */
19539 id: v4_1(),
19540
19541 /**
19542 * 消息所在的 conversation id
19543 * @memberof Message#
19544 * @type {String?}
19545 */
19546 cid: null,
19547
19548 /**
19549 * 消息发送时间
19550 * @memberof Message#
19551 * @type {Date}
19552 */
19553 timestamp: new Date(),
19554
19555 /**
19556 * 消息发送者
19557 * @memberof Message#
19558 * @type {String}
19559 */
19560 from: undefined,
19561
19562 /**
19563 * 消息提及的用户
19564 * @since 4.0.0
19565 * @memberof Message#
19566 * @type {String[]}
19567 */
19568 mentionList: [],
19569
19570 /**
19571 * 消息是否提及了所有人
19572 * @since 4.0.0
19573 * @memberof Message#
19574 * @type {Boolean}
19575 */
19576 mentionedAll: false,
19577 _mentioned: false
19578 });
19579
19580 this._setStatus(MessageStatus.NONE);
19581 }
19582 /**
19583 * 将当前消息的内容序列化为 JSON 对象
19584 * @private
19585 * @return {Object}
19586 */
19587
19588
19589 var _proto = Message.prototype;
19590
19591 _proto.getPayload = function getPayload() {
19592 return this.content;
19593 };
19594
19595 _proto._toJSON = function _toJSON() {
19596 var id = this.id,
19597 cid = this.cid,
19598 from = this.from,
19599 timestamp = this.timestamp,
19600 deliveredAt = this.deliveredAt,
19601 updatedAt = this.updatedAt,
19602 mentionList = this.mentionList,
19603 mentionedAll = this.mentionedAll,
19604 mentioned = this.mentioned;
19605 return {
19606 id: id,
19607 cid: cid,
19608 from: from,
19609 timestamp: timestamp,
19610 deliveredAt: deliveredAt,
19611 updatedAt: updatedAt,
19612 mentionList: mentionList,
19613 mentionedAll: mentionedAll,
19614 mentioned: mentioned
19615 };
19616 }
19617 /**
19618 * 返回 JSON 格式的消息
19619 * @return {Object} 返回值是一个 plain Object
19620 */
19621 ;
19622
19623 _proto.toJSON = function toJSON() {
19624 return _objectSpread$3(_objectSpread$3({}, this._toJSON()), {}, {
19625 data: this.content
19626 });
19627 }
19628 /**
19629 * 返回 JSON 格式的消息,与 toJSON 不同的是,该对象包含了完整的信息,可以通过 {@link IMClient#parseMessage} 反序列化。
19630 * @return {Object} 返回值是一个 plain Object
19631 * @since 4.0.0
19632 */
19633 ;
19634
19635 _proto.toFullJSON = function toFullJSON() {
19636 var content = this.content,
19637 id = this.id,
19638 cid = this.cid,
19639 from = this.from,
19640 timestamp = this.timestamp,
19641 deliveredAt = this.deliveredAt,
19642 _updatedAt = this._updatedAt,
19643 mentionList = this.mentionList,
19644 mentionedAll = this.mentionedAll;
19645 return {
19646 data: content,
19647 id: id,
19648 cid: cid,
19649 from: from,
19650 timestamp: getTime(timestamp),
19651 deliveredAt: getTime(deliveredAt),
19652 updatedAt: getTime(_updatedAt),
19653 mentionList: mentionList,
19654 mentionedAll: mentionedAll
19655 };
19656 }
19657 /**
19658 * 消息状态,值为 {@link module:leancloud-realtime.MessageStatus} 之一
19659 * @type {Symbol}
19660 * @readonly
19661 * @since 3.2.0
19662 */
19663 ;
19664
19665 _proto._setStatus = function _setStatus(status) {
19666 if (!rMessageStatus[status]) {
19667 throw new Error('Invalid message status');
19668 }
19669
19670 this._status = status;
19671 };
19672
19673 _proto._updateMentioned = function _updateMentioned(client) {
19674 this._mentioned = this.from !== client && (this.mentionedAll || this.mentionList.indexOf(client) > -1);
19675 }
19676 /**
19677 * 获取提及用户列表
19678 * @since 4.0.0
19679 * @return {String[]} 提及用户的 id 列表
19680 */
19681 ;
19682
19683 _proto.getMentionList = function getMentionList() {
19684 return this.mentionList;
19685 }
19686 /**
19687 * 设置提及用户列表
19688 * @since 4.0.0
19689 * @param {String[]} clients 提及用户的 id 列表
19690 * @return {this} self
19691 */
19692 ;
19693
19694 _proto.setMentionList = function setMentionList(clients) {
19695 this.mentionList = ensureArray(clients);
19696 return this;
19697 }
19698 /**
19699 * 设置是否提及所有人
19700 * @since 4.0.0
19701 * @param {Boolean} [value=true]
19702 * @return {this} self
19703 */
19704 ;
19705
19706 _proto.mentionAll = function mentionAll() {
19707 var value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
19708 this.mentionedAll = Boolean(value);
19709 return this;
19710 }
19711 /**
19712 * 判断给定的内容是否是有效的 Message,
19713 * 该方法始终返回 true
19714 * @private
19715 * @returns {Boolean}
19716 * @implements AVMessage.validate
19717 */
19718 ;
19719
19720 Message.validate = function validate() {
19721 return true;
19722 }
19723 /**
19724 * 解析处理消息内容
19725 * <pre>
19726 * 如果子类提供了 message,返回该 message
19727 * 如果没有提供,将 json 作为 content 实例化一个 Message
19728 * @private
19729 * @param {Object} json json 格式的消息内容
19730 * @param {Message} message 子类提供的 message
19731 * @return {Message}
19732 * @implements AVMessage.parse
19733 */
19734 ;
19735
19736 Message.parse = function parse(json, message) {
19737 return message || new this(json);
19738 };
19739
19740 createClass(Message, [{
19741 key: "status",
19742 get: function get() {
19743 return this._status;
19744 }
19745 }, {
19746 key: "timestamp",
19747 get: function get() {
19748 return this._timestamp;
19749 },
19750 set: function set(value) {
19751 this._timestamp = decodeDate(value);
19752 }
19753 /**
19754 * 消息送达时间
19755 * @type {?Date}
19756 */
19757
19758 }, {
19759 key: "deliveredAt",
19760 get: function get() {
19761 return this._deliveredAt;
19762 },
19763 set: function set(value) {
19764 this._deliveredAt = decodeDate(value);
19765 }
19766 /**
19767 * 消息修改或撤回时间,可以通过比较其与消息的 timestamp 是否相等判断消息是否被修改过或撤回过。
19768 * @type {Date}
19769 * @since 3.5.0
19770 */
19771
19772 }, {
19773 key: "updatedAt",
19774 get: function get() {
19775 return this._updatedAt || this.timestamp;
19776 },
19777 set: function set(value) {
19778 this._updatedAt = decodeDate(value);
19779 }
19780 /**
19781 * 当前用户是否在该消息中被提及
19782 * @type {Boolean}
19783 * @readonly
19784 * @since 4.0.0
19785 */
19786
19787 }, {
19788 key: "mentioned",
19789 get: function get() {
19790 return this._mentioned;
19791 }
19792 }]);
19793
19794 return Message;
19795 }();
19796
19797 /* eslint-disable no-param-reassign */
19798
19799 var messageType = function messageType(type) {
19800 if (typeof type !== 'number') {
19801 throw new TypeError("".concat(type, " is not a Number"));
19802 }
19803
19804 return function (target) {
19805 target.TYPE = type;
19806
19807 target.validate = function (json) {
19808 return json._lctype === type;
19809 };
19810
19811 target.prototype._getType = function () {
19812 return {
19813 _lctype: type
19814 };
19815 };
19816 };
19817 }; // documented in ../plugin-im.js
19818
19819 var messageField = function messageField(fields) {
19820 if (typeof fields !== 'string') {
19821 if (!Array.isArray(fields)) {
19822 throw new TypeError("".concat(fields, " is not an Array"));
19823 } else if (fields.some(function (value) {
19824 return typeof value !== 'string';
19825 })) {
19826 throw new TypeError('fields contains non-string typed member');
19827 }
19828 }
19829
19830 return function (target) {
19831 // IE10 Hack:
19832 // static properties in IE10 will not be inherited from super
19833 // search for parse method and assign it manually
19834 var originalCustomFields = isIE10 ? getStaticProperty(target, '_customFields') : target._customFields;
19835 originalCustomFields = Array.isArray(originalCustomFields) ? originalCustomFields : [];
19836 target._customFields = originalCustomFields.concat(fields);
19837 };
19838 }; // IE10 Hack:
19839 // static properties in IE10 will not be inherited from super
19840 // search for parse method and assign it manually
19841
19842 var IE10Compatible = function IE10Compatible(target) {
19843 if (isIE10) {
19844 target.parse = getStaticProperty(target, 'parse');
19845 }
19846 };
19847
19848 var _dec, _class$1;
19849
19850 function ownKeys$4(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
19851
19852 function _objectSpread$4(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$4(Object(source), true).forEach(function (key) { defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$4(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
19853
19854 var // jsdoc-ignore-end
19855
19856 /**
19857 * 所有内置的富媒体消息均继承自本类
19858 * @extends Message
19859 */
19860 TypedMessage = (_dec = messageField(['_lctext', '_lcattrs']), _dec(_class$1 = /*#__PURE__*/function (_Message) {
19861 inheritsLoose(TypedMessage, _Message);
19862
19863 function TypedMessage() {
19864 return _Message.apply(this, arguments) || this;
19865 }
19866
19867 var _proto = TypedMessage.prototype;
19868
19869 /**
19870 * @param {String} text
19871 * @return {this} self
19872 */
19873 _proto.setText = function setText(text) {
19874 this._lctext = text;
19875 return this;
19876 }
19877 /**
19878 * @return {String}
19879 */
19880 ;
19881
19882 _proto.getText = function getText() {
19883 return this._lctext;
19884 }
19885 /**
19886 * @param {Object} attributes
19887 * @return {this} self
19888 */
19889 ;
19890
19891 _proto.setAttributes = function setAttributes(attributes) {
19892 this._lcattrs = attributes;
19893 return this;
19894 }
19895 /**
19896 * @return {Object}
19897 */
19898 ;
19899
19900 _proto.getAttributes = function getAttributes() {
19901 return this._lcattrs;
19902 };
19903
19904 _proto._getCustomFields = function _getCustomFields() {
19905 var _this = this;
19906
19907 var fields = Array.isArray(this.constructor._customFields) ? this.constructor._customFields : [];
19908 return fields.reduce(function (result, field) {
19909 if (typeof field !== 'string') return result;
19910 result[field] = _this[field]; // eslint-disable-line no-param-reassign
19911
19912 return result;
19913 }, {});
19914 }
19915 /* eslint-disable class-methods-use-this */
19916 ;
19917
19918 _proto._getType = function _getType() {
19919 throw new Error('not implemented');
19920 }
19921 /* eslint-enable class-methods-use-this */
19922 ;
19923
19924 _proto.getPayload = function getPayload() {
19925 return compact(_objectSpread$4(_objectSpread$4({
19926 _lctext: this.getText(),
19927 _lcattrs: this.getAttributes()
19928 }, this._getCustomFields()), this._getType()));
19929 };
19930
19931 _proto.toJSON = function toJSON() {
19932 var type = this.type,
19933 text = this.text,
19934 attributes = this.attributes,
19935 summary = this.summary;
19936 return _objectSpread$4(_objectSpread$4({}, _Message.prototype._toJSON.call(this)), {}, {
19937 type: type,
19938 text: text,
19939 attributes: attributes,
19940 summary: summary
19941 });
19942 };
19943
19944 _proto.toFullJSON = function toFullJSON() {
19945 return _objectSpread$4(_objectSpread$4({}, _Message.prototype.toFullJSON.call(this)), {}, {
19946 data: this.getPayload()
19947 });
19948 }
19949 /**
19950 * 解析处理消息内容
19951 * <pre>
19952 * 为给定的 message 设置 text 与 attributes 属性,返回该 message
19953 * 如果子类没有提供 message,new this()
19954 * @protected
19955 * @param {Object} json json 格式的消息内容
19956 * @param {TypedMessage} message 子类提供的 message
19957 * @return {TypedMessage}
19958 * @implements AVMessage.parse
19959 */
19960 ;
19961
19962 TypedMessage.parse = function parse(json) {
19963 var message = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new this();
19964 message.content = json; // eslint-disable-line no-param-reassign
19965
19966 var customFields = isIE10 ? getStaticProperty(message.constructor, '_customFields') : message.constructor._customFields;
19967 var fields = Array.isArray(customFields) ? customFields : [];
19968 fields = fields.reduce(function (result, field) {
19969 if (typeof field !== 'string') return result;
19970 result[field] = json[field]; // eslint-disable-line no-param-reassign
19971
19972 return result;
19973 }, {});
19974 Object.assign(message, fields);
19975 return _Message.parse.call(this, json, message);
19976 };
19977
19978 createClass(TypedMessage, [{
19979 key: "type",
19980
19981 /**
19982 * @type {Number}
19983 * @readonly
19984 */
19985 get: function get() {
19986 return this.constructor.TYPE;
19987 }
19988 /** @type {String} */
19989
19990 }, {
19991 key: "text",
19992 set: function set(text) {
19993 return this.setText(text);
19994 },
19995 get: function get() {
19996 return this.getText();
19997 }
19998 /** @type {Object} */
19999
20000 }, {
20001 key: "attributes",
20002 set: function set(attributes) {
20003 return this.setAttributes(attributes);
20004 },
20005 get: function get() {
20006 return this.getAttributes();
20007 }
20008 /**
20009 * 在客户端需要以文本形式展示该消息时显示的文案,
20010 * 如 <code>[红包] 新春快乐</code>。
20011 * 默认值为消息的 text。
20012 * @type {String}
20013 * @readonly
20014 */
20015
20016 }, {
20017 key: "summary",
20018 get: function get() {
20019 return this.text;
20020 }
20021 }]);
20022
20023 return TypedMessage;
20024 }(Message)) || _class$1);
20025
20026 var _dec$1, _class$2;
20027
20028 var // jsdoc-ignore-end
20029
20030 /**
20031 * 已撤回类型消息,当消息被撤回时,SDK 会使用该类型的消息替代原始消息
20032 * @extends TypedMessage
20033 */
20034 RecalledMessage = (_dec$1 = messageType(-127), _dec$1(_class$2 = IE10Compatible(_class$2 = /*#__PURE__*/function (_TypedMessage) {
20035 inheritsLoose(RecalledMessage, _TypedMessage);
20036
20037 function RecalledMessage() {
20038 return _TypedMessage.apply(this, arguments) || this;
20039 }
20040
20041 createClass(RecalledMessage, [{
20042 key: "summary",
20043
20044 /**
20045 * 在客户端需要以文本形式展示该消息时显示的文案,值为 <code>[该消息已撤回]</code>
20046 * @type {String}
20047 * @readonly
20048 */
20049 // eslint-disable-next-line class-methods-use-this
20050 get: function get() {
20051 return '[该消息已撤回]';
20052 }
20053 }]);
20054
20055 return RecalledMessage;
20056 }(TypedMessage)) || _class$2) || _class$2);
20057
20058 function ownKeys$5(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
20059
20060 function _objectSpread$5(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$5(Object(source), true).forEach(function (key) { defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$5(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
20061 var debug$7 = browser('LC:Conversation');
20062
20063 var serializeMessage = function serializeMessage(message) {
20064 var content = message.getPayload();
20065 var msg;
20066 var binaryMsg;
20067
20068 if (content instanceof ArrayBuffer) {
20069 binaryMsg = content;
20070 } else if (typeof content !== 'string') {
20071 msg = JSON.stringify(content);
20072 } else {
20073 msg = content;
20074 }
20075
20076 return {
20077 msg: msg,
20078 binaryMsg: binaryMsg
20079 };
20080 };
20081
20082 var _LogsCommand$QueryDir = LogsCommand.QueryDirection,
20083 NEW = _LogsCommand$QueryDir.NEW,
20084 OLD = _LogsCommand$QueryDir.OLD;
20085 /**
20086 * 历史消息查询方向枚举
20087 * @enum {Number}
20088 * @since 4.0.0
20089 * @memberof module:leancloud-realtime
20090 */
20091
20092 var MessageQueryDirection = {
20093 /** 从后向前 */
20094 NEW_TO_OLD: OLD,
20095
20096 /** 从前向后 */
20097 OLD_TO_NEW: NEW
20098 };
20099 Object.freeze(MessageQueryDirection);
20100
20101 var ConversationBase = /*#__PURE__*/function (_EventEmitter) {
20102 inheritsLoose(ConversationBase, _EventEmitter);
20103
20104 /**
20105 * @extends EventEmitter
20106 * @private
20107 * @abstract
20108 */
20109 function ConversationBase(_ref, client) {
20110 var _this;
20111
20112 var id = _ref.id,
20113 lastMessageAt = _ref.lastMessageAt,
20114 lastMessage = _ref.lastMessage,
20115 lastDeliveredAt = _ref.lastDeliveredAt,
20116 lastReadAt = _ref.lastReadAt,
20117 _ref$unreadMessagesCo = _ref.unreadMessagesCount,
20118 unreadMessagesCount = _ref$unreadMessagesCo === void 0 ? 0 : _ref$unreadMessagesCo,
20119 _ref$members = _ref.members,
20120 members = _ref$members === void 0 ? [] : _ref$members,
20121 _ref$mentioned = _ref.mentioned,
20122 mentioned = _ref$mentioned === void 0 ? false : _ref$mentioned,
20123 properties = objectWithoutProperties(_ref, ["id", "lastMessageAt", "lastMessage", "lastDeliveredAt", "lastReadAt", "unreadMessagesCount", "members", "mentioned"]);
20124
20125 _this = _EventEmitter.call(this) || this;
20126 Object.assign(assertThisInitialized(_this), _objectSpread$5({
20127 /**
20128 * 对话 id,对应 _Conversation 表中的 objectId
20129 * @memberof ConversationBase#
20130 * @type {String}
20131 */
20132 id: id,
20133
20134 /**
20135 * 最后一条消息时间
20136 * @memberof ConversationBase#
20137 * @type {?Date}
20138 */
20139 lastMessageAt: lastMessageAt,
20140
20141 /**
20142 * 最后一条消息
20143 * @memberof ConversationBase#
20144 * @type {?Message}
20145 */
20146 lastMessage: lastMessage,
20147
20148 /**
20149 * 参与该对话的用户列表
20150 * @memberof ConversationBase#
20151 * @type {String[]}
20152 */
20153 members: members
20154 }, properties));
20155 _this.members = Array.from(new Set(_this.members));
20156 Object.assign(internal(assertThisInitialized(_this)), {
20157 messagesWaitingForReceipt: {},
20158 lastDeliveredAt: lastDeliveredAt,
20159 lastReadAt: lastReadAt,
20160 unreadMessagesCount: unreadMessagesCount,
20161 mentioned: mentioned
20162 });
20163 _this._client = client;
20164
20165 if (debug$7.enabled) {
20166 values_1(IMEvent).forEach(function (event) {
20167 return _this.on(event, function () {
20168 for (var _len = arguments.length, payload = new Array(_len), _key = 0; _key < _len; _key++) {
20169 payload[_key] = arguments[_key];
20170 }
20171
20172 return _this._debug("".concat(event, " event emitted. %o"), payload);
20173 });
20174 });
20175 } // onConversationCreate hook
20176
20177
20178 applyDecorators(_this._client._plugins.onConversationCreate, assertThisInitialized(_this));
20179 return _this;
20180 }
20181 /**
20182 * 当前用户是否在该对话的未读消息中被提及
20183 * @type {Boolean}
20184 * @since 4.0.0
20185 */
20186
20187
20188 var _proto = ConversationBase.prototype;
20189
20190 _proto._setUnreadMessagesMentioned = function _setUnreadMessagesMentioned(value) {
20191 internal(this).unreadMessagesMentioned = Boolean(value);
20192 };
20193
20194 _proto._setLastDeliveredAt = function _setLastDeliveredAt(value) {
20195 var date = decodeDate(value);
20196
20197 if (!(date < internal(this).lastDeliveredAt)) {
20198 internal(this).lastDeliveredAt = date;
20199 /**
20200 * 最后消息送达时间更新
20201 * @event ConversationBase#LAST_DELIVERED_AT_UPDATE
20202 * @since 3.4.0
20203 */
20204
20205 this.emit(LAST_DELIVERED_AT_UPDATE);
20206 }
20207 }
20208 /**
20209 * 最后消息被阅读时间,常用来实现发送消息的「已读」标记,可通过 {@link Conversation#fetchReceiptTimestamps} 获取或更新该属性
20210 * @type {?Date}
20211 * @since 3.4.0
20212 */
20213 ;
20214
20215 _proto._setLastReadAt = function _setLastReadAt(value) {
20216 var date = decodeDate(value);
20217
20218 if (!(date < internal(this).lastReadAt)) {
20219 internal(this).lastReadAt = date;
20220 /**
20221 * 最后消息被阅读时间更新
20222 * @event ConversationBase#LAST_READ_AT_UPDATE
20223 * @since 3.4.0
20224 */
20225
20226 this.emit(LAST_READ_AT_UPDATE);
20227 }
20228 }
20229 /**
20230 * 返回 JSON 格式的对话,与 toJSON 不同的是,该对象包含了完整的信息,可以通过 {@link IMClient#parseConversation} 反序列化。
20231 * @return {Object} 返回值是一个 plain Object
20232 * @since 4.0.0
20233 */
20234 ;
20235
20236 _proto.toFullJSON = function toFullJSON() {
20237 var id = this.id,
20238 members = this.members,
20239 lastMessageAt = this.lastMessageAt,
20240 lastDeliveredAt = this.lastDeliveredAt,
20241 lastReadAt = this.lastReadAt,
20242 lastMessage = this.lastMessage,
20243 unreadMessagesCount = this.unreadMessagesCount;
20244 return {
20245 id: id,
20246 members: members,
20247 lastMessageAt: getTime(lastMessageAt),
20248 lastDeliveredAt: getTime(lastDeliveredAt),
20249 lastReadAt: getTime(lastReadAt),
20250 lastMessage: lastMessage ? lastMessage.toFullJSON() : undefined,
20251 unreadMessagesCount: unreadMessagesCount
20252 };
20253 }
20254 /**
20255 * 返回 JSON 格式的对话
20256 * @return {Object} 返回值是一个 plain Object
20257 * @since 4.0.0
20258 */
20259 ;
20260
20261 _proto.toJSON = function toJSON() {
20262 var id = this.id,
20263 members = this.members,
20264 lastMessageAt = this.lastMessageAt,
20265 lastDeliveredAt = this.lastDeliveredAt,
20266 lastReadAt = this.lastReadAt,
20267 lastMessage = this.lastMessage,
20268 unreadMessagesCount = this.unreadMessagesCount,
20269 unreadMessagesMentioned = this.unreadMessagesMentioned;
20270 return {
20271 id: id,
20272 members: members,
20273 lastMessageAt: lastMessageAt,
20274 lastDeliveredAt: lastDeliveredAt,
20275 lastReadAt: lastReadAt,
20276 lastMessage: lastMessage ? lastMessage.toJSON() : undefined,
20277 unreadMessagesCount: unreadMessagesCount,
20278 unreadMessagesMentioned: unreadMessagesMentioned
20279 };
20280 };
20281
20282 _proto._debug = function _debug() {
20283 for (var _len2 = arguments.length, params = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
20284 params[_key2] = arguments[_key2];
20285 }
20286
20287 debug$7.apply(void 0, params.concat(["[".concat(this.id, "]")]));
20288 };
20289
20290 _proto._send = function _send(command) {
20291 var _this$_client;
20292
20293 /* eslint-disable no-param-reassign */
20294 if (command.cmd === null) {
20295 command.cmd = 'conv';
20296 }
20297
20298 if (command.cmd === 'conv' && command.convMessage === null) {
20299 command.convMessage = new ConvCommand();
20300 }
20301
20302 if (command.convMessage && command.convMessage.cid === null) {
20303 command.convMessage.cid = this.id;
20304 }
20305 /* eslint-enable no-param-reassign */
20306
20307
20308 for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
20309 args[_key3 - 1] = arguments[_key3];
20310 }
20311
20312 return (_this$_client = this._client)._send.apply(_this$_client, [command].concat(args));
20313 }
20314 /**
20315 * 发送消息
20316 * @param {Message} message 消息,Message 及其子类的实例
20317 * @param {Object} [options] since v3.3.0,发送选项
20318 * @param {Boolean} [options.transient] since v3.3.1,是否作为暂态消息发送
20319 * @param {Boolean} [options.receipt] 是否需要回执,仅在普通对话中有效
20320 * @param {Boolean} [options.will] since v3.4.0,是否指定该消息作为「掉线消息」发送,
20321 * 「掉线消息」会延迟到当前用户掉线后发送,常用来实现「下线通知」功能
20322 * @param {MessagePriority} [options.priority] 消息优先级,仅在暂态对话中有效,
20323 * see: {@link module:leancloud-realtime.MessagePriority MessagePriority}
20324 * @param {Object} [options.pushData] 消息对应的离线推送内容,如果消息接收方不在线,会推送指定的内容。其结构说明参见: {@link https://url.leanapp.cn/pushData 推送消息内容}
20325 * @return {Promise.<Message>} 发送的消息
20326 */
20327 ;
20328
20329 _proto.send =
20330 /*#__PURE__*/
20331 function () {
20332 var _send2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee(message, options) {
20333 var _message$constructor$, _transient, receipt, priority, pushData, will, _serializeMessage, msg, binaryMsg, command, resCommand, _resCommand$ackMessag, uid, t, code, reason, appCode;
20334
20335 return regenerator.wrap(function _callee$(_context) {
20336 while (1) {
20337 switch (_context.prev = _context.next) {
20338 case 0:
20339 this._debug(message, 'send');
20340
20341 if (message instanceof Message) {
20342 _context.next = 3;
20343 break;
20344 }
20345
20346 throw new TypeError("".concat(message, " is not a Message"));
20347
20348 case 3:
20349 _message$constructor$ = _objectSpread$5(_objectSpread$5(_objectSpread$5({}, message.constructor.sendOptions), typeof message.constructor.getSendOptions === 'function' ? message.constructor.getSendOptions(message) : {}), options), _transient = _message$constructor$["transient"], receipt = _message$constructor$.receipt, priority = _message$constructor$.priority, pushData = _message$constructor$.pushData, will = _message$constructor$.will;
20350
20351 if (receipt) {
20352 if (this["transient"]) {
20353 console.warn('receipt option is ignored as the conversation is transient.');
20354 } else if (_transient) {
20355 console.warn('receipt option is ignored as the message is sent transiently.');
20356 } else if (this.members.length > 2) {
20357 console.warn('receipt option is recommended to be used in one-on-one conversation.'); // eslint-disable-line max-len
20358 }
20359 }
20360
20361 if (priority && !this["transient"]) {
20362 console.warn('priority option is ignored as the conversation is not transient.');
20363 }
20364
20365 Object.assign(message, {
20366 cid: this.id,
20367 from: this._client.id
20368 });
20369
20370 message._setStatus(MessageStatus.SENDING);
20371
20372 _serializeMessage = serializeMessage(message), msg = _serializeMessage.msg, binaryMsg = _serializeMessage.binaryMsg;
20373 command = new GenericCommand({
20374 cmd: 'direct',
20375 directMessage: new DirectCommand({
20376 msg: msg,
20377 binaryMsg: binaryMsg,
20378 cid: this.id,
20379 r: receipt,
20380 "transient": _transient,
20381 dt: message.id,
20382 pushData: JSON.stringify(pushData),
20383 will: will,
20384 mentionPids: message.mentionList,
20385 mentionAll: message.mentionedAll
20386 }),
20387 priority: priority
20388 });
20389 _context.prev = 10;
20390 _context.next = 13;
20391 return this._send(command);
20392
20393 case 13:
20394 resCommand = _context.sent;
20395 _resCommand$ackMessag = resCommand.ackMessage, uid = _resCommand$ackMessag.uid, t = _resCommand$ackMessag.t, code = _resCommand$ackMessag.code, reason = _resCommand$ackMessag.reason, appCode = _resCommand$ackMessag.appCode;
20396
20397 if (!(code !== null)) {
20398 _context.next = 17;
20399 break;
20400 }
20401
20402 throw createError({
20403 code: code,
20404 reason: reason,
20405 appCode: appCode
20406 });
20407
20408 case 17:
20409 Object.assign(message, {
20410 id: uid,
20411 timestamp: t
20412 });
20413
20414 if (!_transient) {
20415 this.lastMessage = message;
20416 this.lastMessageAt = message.timestamp;
20417 }
20418
20419 message._setStatus(MessageStatus.SENT);
20420
20421 if (receipt) {
20422 internal(this).messagesWaitingForReceipt[message.id] = message;
20423 }
20424
20425 return _context.abrupt("return", message);
20426
20427 case 24:
20428 _context.prev = 24;
20429 _context.t0 = _context["catch"](10);
20430
20431 message._setStatus(MessageStatus.FAILED);
20432
20433 throw _context.t0;
20434
20435 case 28:
20436 case "end":
20437 return _context.stop();
20438 }
20439 }
20440 }, _callee, this, [[10, 24]]);
20441 }));
20442
20443 function send(_x, _x2) {
20444 return _send2.apply(this, arguments);
20445 }
20446
20447 return send;
20448 }();
20449
20450 _proto._update = /*#__PURE__*/function () {
20451 var _update2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee2(message, newMessage, recall) {
20452 var msg, binaryMsg, content, id, cid, timestamp, from, _status;
20453
20454 return regenerator.wrap(function _callee2$(_context2) {
20455 while (1) {
20456 switch (_context2.prev = _context2.next) {
20457 case 0:
20458 this._debug('patch %O %O %O', message, newMessage, recall);
20459
20460 if (!(message instanceof Message)) {
20461 _context2.next = 8;
20462 break;
20463 }
20464
20465 if (!(message.from !== this._client.id)) {
20466 _context2.next = 4;
20467 break;
20468 }
20469
20470 throw new Error('Updating message from others is not allowed');
20471
20472 case 4:
20473 if (!(message.status !== MessageStatus.SENT && message.status !== MessageStatus.DELIVERED)) {
20474 _context2.next = 6;
20475 break;
20476 }
20477
20478 throw new Error('Message is not sent');
20479
20480 case 6:
20481 _context2.next = 10;
20482 break;
20483
20484 case 8:
20485 if (message.id && message.timestamp) {
20486 _context2.next = 10;
20487 break;
20488 }
20489
20490 throw new TypeError("".concat(message, " is not a Message"));
20491
20492 case 10:
20493 if (!recall) {
20494 content = serializeMessage(newMessage);
20495 msg = content.msg;
20496 binaryMsg = content.binaryMsg;
20497 }
20498
20499 _context2.next = 13;
20500 return this._send(new GenericCommand({
20501 cmd: CommandType.patch,
20502 op: OpType.modify,
20503 patchMessage: new PatchCommand({
20504 patches: [new PatchItem({
20505 cid: this.id,
20506 mid: message.id,
20507 timestamp: Number(message.timestamp),
20508 recall: recall,
20509 data: msg,
20510 binaryMsg: binaryMsg,
20511 mentionPids: newMessage.mentionList,
20512 mentionAll: newMessage.mentionedAll
20513 })],
20514 lastPatchTime: this._client._lastPatchTime
20515 })
20516 }));
20517
20518 case 13:
20519 id = message.id, cid = message.cid, timestamp = message.timestamp, from = message.from, _status = message._status;
20520 Object.assign(newMessage, {
20521 id: id,
20522 cid: cid,
20523 timestamp: timestamp,
20524 from: from,
20525 _status: _status
20526 });
20527
20528 if (this.lastMessage && this.lastMessage.id === newMessage.id) {
20529 this.lastMessage = newMessage;
20530 }
20531
20532 return _context2.abrupt("return", newMessage);
20533
20534 case 17:
20535 case "end":
20536 return _context2.stop();
20537 }
20538 }
20539 }, _callee2, this);
20540 }));
20541
20542 function _update(_x3, _x4, _x5) {
20543 return _update2.apply(this, arguments);
20544 }
20545
20546 return _update;
20547 }()
20548 /**
20549 * 获取对话人数,或暂态对话的在线人数
20550 * @return {Promise.<Number>}
20551 */
20552 ;
20553
20554 _proto.count =
20555 /*#__PURE__*/
20556 function () {
20557 var _count = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee3() {
20558 var resCommand;
20559 return regenerator.wrap(function _callee3$(_context3) {
20560 while (1) {
20561 switch (_context3.prev = _context3.next) {
20562 case 0:
20563 this._debug('count');
20564
20565 _context3.next = 3;
20566 return this._send(new GenericCommand({
20567 op: 'count'
20568 }));
20569
20570 case 3:
20571 resCommand = _context3.sent;
20572 return _context3.abrupt("return", resCommand.convMessage.count);
20573
20574 case 5:
20575 case "end":
20576 return _context3.stop();
20577 }
20578 }
20579 }, _callee3, this);
20580 }));
20581
20582 function count() {
20583 return _count.apply(this, arguments);
20584 }
20585
20586 return count;
20587 }()
20588 /**
20589 * 应用增加成员的操作,产生副作用
20590 * @param {string[]} members
20591 * @abstract
20592 * @private
20593 */
20594 ;
20595
20596 _proto._addMembers = function _addMembers() {}
20597 /**
20598 * 应用减少成员的操作,产生副作用
20599 * @param {string[]} members
20600 * @abstract
20601 * @private
20602 */
20603 ;
20604
20605 _proto._removeMembers = function _removeMembers() {}
20606 /**
20607 * 修改已发送的消息
20608 * @param {AVMessage} message 要修改的消息,该消息必须是由当前用户发送的。也可以提供一个包含消息 {id, timestamp} 的对象
20609 * @param {AVMessage} newMessage 新的消息
20610 * @return {Promise.<AVMessage>} 更新后的消息
20611 */
20612 ;
20613
20614 _proto.update =
20615 /*#__PURE__*/
20616 function () {
20617 var _update3 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee4(message, newMessage) {
20618 return regenerator.wrap(function _callee4$(_context4) {
20619 while (1) {
20620 switch (_context4.prev = _context4.next) {
20621 case 0:
20622 if (newMessage instanceof Message) {
20623 _context4.next = 2;
20624 break;
20625 }
20626
20627 throw new TypeError("".concat(newMessage, " is not a Message"));
20628
20629 case 2:
20630 return _context4.abrupt("return", this._update(message, newMessage, false));
20631
20632 case 3:
20633 case "end":
20634 return _context4.stop();
20635 }
20636 }
20637 }, _callee4, this);
20638 }));
20639
20640 function update(_x6, _x7) {
20641 return _update3.apply(this, arguments);
20642 }
20643
20644 return update;
20645 }()
20646 /**
20647 * 撤回已发送的消息
20648 * @param {AVMessage} message 要撤回的消息,该消息必须是由当前用户发送的。也可以提供一个包含消息 {id, timestamp} 的对象
20649 * @return {Promise.<RecalledMessage>} 一条已撤回的消息
20650 */
20651 ;
20652
20653 _proto.recall =
20654 /*#__PURE__*/
20655 function () {
20656 var _recall = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee5(message) {
20657 return regenerator.wrap(function _callee5$(_context5) {
20658 while (1) {
20659 switch (_context5.prev = _context5.next) {
20660 case 0:
20661 return _context5.abrupt("return", this._update(message, new RecalledMessage(), true));
20662
20663 case 1:
20664 case "end":
20665 return _context5.stop();
20666 }
20667 }
20668 }, _callee5, this);
20669 }));
20670
20671 function recall(_x8) {
20672 return _recall.apply(this, arguments);
20673 }
20674
20675 return recall;
20676 }()
20677 /**
20678 * 查询消息记录
20679 * 如果仅需实现消息向前记录翻页查询需求,建议使用 {@link Conversation#createMessagesIterator}。
20680 * 不论何种方向,获得的消息都是按照时间升序排列的。
20681 * startClosed 与 endClosed 用于指定查询区间的开闭。
20682 *
20683 * @param {Object} [options]
20684 * @param {Number} [options.limit] 限制查询结果的数量,目前服务端默认为 20
20685 * @param {Number} [options.type] 指定查询的富媒体消息类型,不指定则查询所有消息。
20686 * @param {MessageQueryDirection} [options.direction] 查询的方向。
20687 * 在不指定的情况下如果 startTime 大于 endTime,则为从新到旧查询,可以实现加载聊天记录等场景。
20688 * 如果 startTime 小于 endTime,则为从旧到新查询,可以实现弹幕等场景。
20689 * @param {Date} [options.startTime] 从该时间开始查询,不传则从当前时间开始查询
20690 * @param {String} [options.startMessageId] 从该消息之前开始查询,需要与 startTime 同时使用,为防止某时刻有重复消息
20691 * @param {Boolean}[options.startClosed] 指定查询范围是否包括开始的时间点,默认不包括
20692 * @param {Date} [options.endTime] 查询到该时间为止,不传则查询最早消息为止
20693 * @param {String} [options.endMessageId] 查询到该消息为止,需要与 endTime 同时使用,为防止某时刻有重复消息
20694 * @param {Boolean}[options.endClosed] 指定查询范围是否包括结束的时间点,默认不包括
20695 *
20696 * @param {Date} [options.beforeTime] DEPRECATED: 使用 startTime 代替。限制查询结果为小于该时间之前的消息,不传则为当前时间
20697 * @param {String} [options.beforeMessageId] DEPRECATED: 使用 startMessageId 代替。
20698 * 限制查询结果为该消息之前的消息,需要与 beforeTime 同时使用,为防止某时刻有重复消息
20699 * @param {Date} [options.afterTime] DEPRECATED: 使用 endTime 代替。限制查询结果为大于该时间之前的消息
20700 * @param {String} [options.afterMessageId] DEPRECATED: 使用 endMessageId 代替。
20701 * 限制查询结果为该消息之后的消息,需要与 afterTime 同时使用,为防止某时刻有重复消息
20702 * @return {Promise.<Message[]>} 消息列表
20703 */
20704 ;
20705
20706 _proto.queryMessages =
20707 /*#__PURE__*/
20708 function () {
20709 var _queryMessages = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee7() {
20710 var _this2 = this;
20711
20712 var options,
20713 beforeTime,
20714 beforeMessageId,
20715 afterTime,
20716 afterMessageId,
20717 limit,
20718 direction,
20719 type,
20720 startTime,
20721 startMessageId,
20722 startClosed,
20723 endTime,
20724 endMessageId,
20725 endClosed,
20726 conditions,
20727 resCommand,
20728 _args7 = arguments;
20729 return regenerator.wrap(function _callee7$(_context7) {
20730 while (1) {
20731 switch (_context7.prev = _context7.next) {
20732 case 0:
20733 options = _args7.length > 0 && _args7[0] !== undefined ? _args7[0] : {};
20734
20735 this._debug('query messages %O', options);
20736
20737 beforeTime = options.beforeTime, beforeMessageId = options.beforeMessageId, afterTime = options.afterTime, afterMessageId = options.afterMessageId, limit = options.limit, direction = options.direction, type = options.type, startTime = options.startTime, startMessageId = options.startMessageId, startClosed = options.startClosed, endTime = options.endTime, endMessageId = options.endMessageId, endClosed = options.endClosed;
20738
20739 if (!(beforeMessageId || beforeTime || afterMessageId || afterTime)) {
20740 _context7.next = 6;
20741 break;
20742 }
20743
20744 console.warn('DEPRECATION: queryMessages options beforeTime, beforeMessageId, afterTime and afterMessageId are deprecated in favor of startTime, startMessageId, endTime and endMessageId.');
20745 return _context7.abrupt("return", this.queryMessages({
20746 startTime: beforeTime,
20747 startMessageId: beforeMessageId,
20748 endTime: afterTime,
20749 endMessageId: afterMessageId,
20750 limit: limit
20751 }));
20752
20753 case 6:
20754 if (!(startMessageId && !startTime)) {
20755 _context7.next = 8;
20756 break;
20757 }
20758
20759 throw new Error('query option startMessageId must be used with option startTime');
20760
20761 case 8:
20762 if (!(endMessageId && !endTime)) {
20763 _context7.next = 10;
20764 break;
20765 }
20766
20767 throw new Error('query option endMessageId must be used with option endTime');
20768
20769 case 10:
20770 conditions = {
20771 t: startTime,
20772 mid: startMessageId,
20773 tIncluded: startClosed,
20774 tt: endTime,
20775 tmid: endMessageId,
20776 ttIncluded: endClosed,
20777 l: limit,
20778 lctype: type
20779 };
20780
20781 if (conditions.t instanceof Date) {
20782 conditions.t = conditions.t.getTime();
20783 }
20784
20785 if (conditions.tt instanceof Date) {
20786 conditions.tt = conditions.tt.getTime();
20787 }
20788
20789 if (direction !== undefined) {
20790 conditions.direction = direction;
20791 } else if (conditions.tt > conditions.t) {
20792 conditions.direction = MessageQueryDirection.OLD_TO_NEW;
20793 }
20794
20795 _context7.next = 16;
20796 return this._send(new GenericCommand({
20797 cmd: 'logs',
20798 logsMessage: new LogsCommand(Object.assign(conditions, {
20799 cid: this.id
20800 }))
20801 }));
20802
20803 case 16:
20804 resCommand = _context7.sent;
20805 return _context7.abrupt("return", Promise.all(resCommand.logsMessage.logs.map( /*#__PURE__*/function () {
20806 var _ref3 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee6(_ref2) {
20807 var msgId, timestamp, patchTimestamp, from, ackAt, readAt, data, mentionAll, mentionPids, bin, messageData, message, status;
20808 return regenerator.wrap(function _callee6$(_context6) {
20809 while (1) {
20810 switch (_context6.prev = _context6.next) {
20811 case 0:
20812 msgId = _ref2.msgId, timestamp = _ref2.timestamp, patchTimestamp = _ref2.patchTimestamp, from = _ref2.from, ackAt = _ref2.ackAt, readAt = _ref2.readAt, data = _ref2.data, mentionAll = _ref2.mentionAll, mentionPids = _ref2.mentionPids, bin = _ref2.bin;
20813 messageData = {
20814 data: data,
20815 bin: bin,
20816 id: msgId,
20817 cid: _this2.id,
20818 timestamp: timestamp,
20819 from: from,
20820 deliveredAt: ackAt,
20821 updatedAt: patchTimestamp,
20822 mentionList: mentionPids,
20823 mentionedAll: mentionAll
20824 };
20825 _context6.next = 4;
20826 return _this2._client.parseMessage(messageData);
20827
20828 case 4:
20829 message = _context6.sent;
20830 status = MessageStatus.SENT;
20831
20832 if (_this2.members.length === 2) {
20833 if (ackAt) status = MessageStatus.DELIVERED;
20834 if (ackAt) _this2._setLastDeliveredAt(ackAt);
20835 if (readAt) _this2._setLastReadAt(readAt);
20836 }
20837
20838 message._setStatus(status);
20839
20840 return _context6.abrupt("return", message);
20841
20842 case 9:
20843 case "end":
20844 return _context6.stop();
20845 }
20846 }
20847 }, _callee6);
20848 }));
20849
20850 return function (_x9) {
20851 return _ref3.apply(this, arguments);
20852 };
20853 }())));
20854
20855 case 18:
20856 case "end":
20857 return _context7.stop();
20858 }
20859 }
20860 }, _callee7, this);
20861 }));
20862
20863 function queryMessages() {
20864 return _queryMessages.apply(this, arguments);
20865 }
20866
20867 return queryMessages;
20868 }()
20869 /**
20870 * 获取消息翻页迭代器
20871 * @param {Object} [options]
20872 * @param {Date} [options.beforeTime] 限制起始查询结果为小于该时间之前的消息,不传则为当前时间
20873 * @param {String} [options.beforeMessageId] 限制起始查询结果为该消息之前的消息,需要与 beforeTime 同时使用,为防止某时刻有重复消息
20874 * @param {Number} [options.limit] 限制每页查询结果的数量,目前服务端默认为 20
20875 * @return {AsyncIterater.<Promise.<IteratorResult<Message[]>>>} [AsyncIterator]{@link https://github.com/tc39/proposal-async-iteration},调用其 next 方法返回获取下一页消息的 Promise
20876 * @example
20877 * var messageIterator = conversation.createMessagesIterator({ limit: 10 });
20878 * messageIterator.next().then(function(result) {
20879 * // result: {
20880 * // value: [message1, ..., message10],
20881 * // done: false,
20882 * // }
20883 * });
20884 * messageIterator.next().then(function(result) {
20885 * // result: {
20886 * // value: [message11, ..., message20],
20887 * // done: false,
20888 * // }
20889 * });
20890 * messageIterator.next().then(function(result) {
20891 * // No more messages
20892 * // result: { value: [], done: true }
20893 * });
20894 */
20895 ;
20896
20897 _proto.createMessagesIterator = function createMessagesIterator() {
20898 var _this3 = this;
20899
20900 var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
20901 beforeTime = _ref4.beforeTime,
20902 beforeMessageId = _ref4.beforeMessageId,
20903 limit = _ref4.limit;
20904
20905 var promise;
20906 return {
20907 next: function next() {
20908 if (promise === undefined) {
20909 // first call
20910 promise = _this3.queryMessages({
20911 limit: limit,
20912 startTime: beforeTime,
20913 startMessageId: beforeMessageId
20914 });
20915 } else {
20916 promise = promise.then(function (prevMessages) {
20917 if (prevMessages.length === 0 || prevMessages.length < limit) {
20918 // no more messages
20919 return [];
20920 }
20921
20922 return _this3.queryMessages({
20923 startTime: prevMessages[0].timestamp,
20924 startMessageId: prevMessages[0].id,
20925 limit: limit
20926 });
20927 });
20928 }
20929
20930 return promise.then(function (value) {
20931 return {
20932 value: Array.from(value),
20933 done: value.length === 0 || value.length < limit
20934 };
20935 });
20936 }
20937 };
20938 }
20939 /**
20940 * 将该会话标记为已读
20941 * @return {Promise.<this>} self
20942 */
20943 ;
20944
20945 _proto.read =
20946 /*#__PURE__*/
20947 function () {
20948 var _read = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee8() {
20949 var client;
20950 return regenerator.wrap(function _callee8$(_context8) {
20951 while (1) {
20952 switch (_context8.prev = _context8.next) {
20953 case 0:
20954 this.unreadMessagesCount = 0;
20955
20956 this._setUnreadMessagesMentioned(false); // 跳过暂态会话
20957
20958
20959 if (!this["transient"]) {
20960 _context8.next = 4;
20961 break;
20962 }
20963
20964 return _context8.abrupt("return", this);
20965
20966 case 4:
20967 client = this._client;
20968
20969 if (!internal(client).readConversationsBuffer) {
20970 internal(client).readConversationsBuffer = new Set();
20971 }
20972
20973 internal(client).readConversationsBuffer.add(this);
20974
20975 client._doSendRead();
20976
20977 return _context8.abrupt("return", this);
20978
20979 case 9:
20980 case "end":
20981 return _context8.stop();
20982 }
20983 }
20984 }, _callee8, this);
20985 }));
20986
20987 function read() {
20988 return _read.apply(this, arguments);
20989 }
20990
20991 return read;
20992 }();
20993
20994 _proto._handleReceipt = function _handleReceipt(_ref5) {
20995 var messageId = _ref5.messageId,
20996 timestamp = _ref5.timestamp,
20997 read = _ref5.read;
20998
20999 if (read) {
21000 this._setLastReadAt(timestamp);
21001 } else {
21002 this._setLastDeliveredAt(timestamp);
21003 }
21004
21005 var _internal = internal(this),
21006 messagesWaitingForReceipt = _internal.messagesWaitingForReceipt;
21007
21008 var message = messagesWaitingForReceipt[messageId];
21009 if (!message) return;
21010
21011 message._setStatus(MessageStatus.DELIVERED);
21012
21013 message.deliveredAt = timestamp;
21014 delete messagesWaitingForReceipt[messageId];
21015 }
21016 /**
21017 * 更新对话的最新回执时间戳(lastDeliveredAt、lastReadAt)
21018 * @since 3.4.0
21019 * @return {Promise.<this>} this
21020 */
21021 ;
21022
21023 _proto.fetchReceiptTimestamps =
21024 /*#__PURE__*/
21025 function () {
21026 var _fetchReceiptTimestamps = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee9() {
21027 var _yield$this$_send, _yield$this$_send$con, maxReadTimestamp, maxAckTimestamp;
21028
21029 return regenerator.wrap(function _callee9$(_context9) {
21030 while (1) {
21031 switch (_context9.prev = _context9.next) {
21032 case 0:
21033 if (!(this["transient"] || this.system)) {
21034 _context9.next = 2;
21035 break;
21036 }
21037
21038 return _context9.abrupt("return", this);
21039
21040 case 2:
21041 _context9.next = 4;
21042 return this._send(new GenericCommand({
21043 op: 'max_read'
21044 }));
21045
21046 case 4:
21047 _yield$this$_send = _context9.sent;
21048 _yield$this$_send$con = _yield$this$_send.convMessage;
21049 maxReadTimestamp = _yield$this$_send$con.maxReadTimestamp;
21050 maxAckTimestamp = _yield$this$_send$con.maxAckTimestamp;
21051
21052 this._setLastDeliveredAt(maxAckTimestamp);
21053
21054 this._setLastReadAt(maxReadTimestamp);
21055
21056 return _context9.abrupt("return", this);
21057
21058 case 11:
21059 case "end":
21060 return _context9.stop();
21061 }
21062 }
21063 }, _callee9, this);
21064 }));
21065
21066 function fetchReceiptTimestamps() {
21067 return _fetchReceiptTimestamps.apply(this, arguments);
21068 }
21069
21070 return fetchReceiptTimestamps;
21071 }();
21072
21073 _proto._fetchAllReceiptTimestamps = function _fetchAllReceiptTimestamps() {
21074 // 暂态/系统会话不支持回执
21075 if (this["transient"] || this.system) return this;
21076 var convMessage = new ConvCommand({
21077 queryAllMembers: true
21078 });
21079 return this._send(new GenericCommand({
21080 op: 'max_read',
21081 convMessage: convMessage
21082 })).then(function (_ref6) {
21083 var maxReadTuples = _ref6.convMessage.maxReadTuples;
21084 return maxReadTuples.filter(function (maxReadTuple) {
21085 return maxReadTuple.maxAckTimestamp || maxReadTuple.maxReadTimestamp;
21086 }).map(function (_ref7) {
21087 var pid = _ref7.pid,
21088 maxAckTimestamp = _ref7.maxAckTimestamp,
21089 maxReadTimestamp = _ref7.maxReadTimestamp;
21090 return {
21091 pid: pid,
21092 lastDeliveredAt: decodeDate(maxAckTimestamp),
21093 lastReadAt: decodeDate(maxReadTimestamp)
21094 };
21095 });
21096 });
21097 };
21098
21099 createClass(ConversationBase, [{
21100 key: "unreadMessagesMentioned",
21101 get: function get() {
21102 return internal(this).unreadMessagesMentioned;
21103 }
21104 }, {
21105 key: "unreadMessagesCount",
21106 set: function set(value) {
21107 if (value !== this.unreadMessagesCount) {
21108 internal(this).unreadMessagesCount = value;
21109
21110 this._client.emit(UNREAD_MESSAGES_COUNT_UPDATE, [this]);
21111 }
21112 }
21113 /**
21114 * 当前用户在该对话的未读消息数
21115 * @type {Number}
21116 */
21117 ,
21118 get: function get() {
21119 return internal(this).unreadMessagesCount;
21120 }
21121 }, {
21122 key: "lastMessageAt",
21123 set: function set(value) {
21124 var time = decodeDate(value);
21125 if (time <= this._lastMessageAt) return;
21126 this._lastMessageAt = time;
21127 },
21128 get: function get() {
21129 return this._lastMessageAt;
21130 }
21131 /**
21132 * 最后消息送达时间,常用来实现消息的「已送达」标记,可通过 {@link Conversation#fetchReceiptTimestamps} 获取或更新该属性
21133 * @type {?Date}
21134 * @since 3.4.0
21135 */
21136
21137 }, {
21138 key: "lastDeliveredAt",
21139 get: function get() {
21140 if (this.members.length !== 2) return null;
21141 return internal(this).lastDeliveredAt;
21142 }
21143 }, {
21144 key: "lastReadAt",
21145 get: function get() {
21146 if (this.members.length !== 2) return null;
21147 return internal(this).lastReadAt;
21148 }
21149 }]);
21150
21151 return ConversationBase;
21152 }(eventemitter3);
21153
21154 var debug$8 = browser('LC:SignatureFactoryRunner');
21155
21156 function _validateSignature() {
21157 var signatureResult = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
21158 var signature = signatureResult.signature,
21159 timestamp = signatureResult.timestamp,
21160 nonce = signatureResult.nonce;
21161
21162 if (typeof signature !== 'string' || typeof timestamp !== 'number' || typeof nonce !== 'string') {
21163 throw new Error('malformed signature');
21164 }
21165
21166 return {
21167 signature: signature,
21168 timestamp: timestamp,
21169 nonce: nonce
21170 };
21171 }
21172
21173 var runSignatureFactory = (function (signatureFactory, params) {
21174 return Promise.resolve().then(function () {
21175 debug$8('call signatureFactory with %O', params);
21176 return signatureFactory.apply(void 0, toConsumableArray(params));
21177 }).then(tap(function (signatureResult) {
21178 return debug$8('sign result %O', signatureResult);
21179 }), function (error) {
21180 // eslint-disable-next-line no-param-reassign
21181 error.message = "sign error: ".concat(error.message);
21182 debug$8(error);
21183 throw error;
21184 }).then(_validateSignature);
21185 });
21186
21187 function ownKeys$6(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
21188
21189 function _objectSpread$6(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$6(Object(source), true).forEach(function (key) { defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$6(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
21190 /**
21191 * 部分失败异常
21192 * @typedef OperationFailureError
21193 * @type {Error}
21194 * @property {string} message 异常信息
21195 * @property {string[]} clientIds 因为该原因失败的 client id 列表
21196 * @property {number} [code] 错误码
21197 * @property {string} [detail] 详细信息
21198 */
21199
21200 /**
21201 * 部分成功的结果
21202 * @typedef PartiallySuccess
21203 * @type {Object}
21204 * @property {string[]} successfulClientIds 成功的 client id 列表
21205 * @property {OperationFailureError[]} failures 失败的异常列表
21206 */
21207
21208 /**
21209 * 分页查询结果
21210 * @typedef PagedResults
21211 * @type {Object}
21212 * @property {T[]} results 查询结果
21213 * @property {string} [next] 存在表示还有更多结果,在下次查询中带上可实现翻页。
21214 */
21215
21216 var createPartiallySuccess = function createPartiallySuccess(_ref) {
21217 var allowedPids = _ref.allowedPids,
21218 failedPids = _ref.failedPids;
21219 return {
21220 successfulClientIds: allowedPids,
21221 failures: failedPids.map(function (_ref2) {
21222 var pids = _ref2.pids,
21223 error = objectWithoutProperties(_ref2, ["pids"]);
21224
21225 return Object.assign(createError(error), {
21226 clientIds: pids
21227 });
21228 })
21229 };
21230 };
21231 /**
21232 * @extends ConversationBase
21233 * @private
21234 * @abstract
21235 */
21236
21237
21238 var PersistentConversation = /*#__PURE__*/function (_ConversationBase) {
21239 inheritsLoose(PersistentConversation, _ConversationBase);
21240
21241 function PersistentConversation(data, _ref3, client) {
21242 var _this;
21243
21244 var creator = _ref3.creator,
21245 createdAt = _ref3.createdAt,
21246 updatedAt = _ref3.updatedAt,
21247 _ref3$transient = _ref3["transient"],
21248 _transient = _ref3$transient === void 0 ? false : _ref3$transient,
21249 _ref3$system = _ref3.system,
21250 system = _ref3$system === void 0 ? false : _ref3$system,
21251 _ref3$muted = _ref3.muted,
21252 muted = _ref3$muted === void 0 ? false : _ref3$muted,
21253 _ref3$mutedMembers = _ref3.mutedMembers,
21254 mutedMembers = _ref3$mutedMembers === void 0 ? [] : _ref3$mutedMembers,
21255 attributes = objectWithoutProperties(_ref3, ["creator", "createdAt", "updatedAt", "transient", "system", "muted", "mutedMembers"]);
21256
21257 _this = _ConversationBase.call(this, _objectSpread$6(_objectSpread$6({}, data), {}, {
21258 /**
21259 * 对话创建者
21260 * @memberof PersistentConversation#
21261 * @type {String}
21262 */
21263 creator: creator,
21264
21265 /**
21266 * 对话创建时间
21267 * @memberof PersistentConversation#
21268 * @type {Date}
21269 */
21270 createdAt: createdAt,
21271
21272 /**
21273 * 对话更新时间
21274 * @memberof PersistentConversation#
21275 * @type {Date}
21276 */
21277 updatedAt: updatedAt,
21278
21279 /**
21280 * 对该对话设置了静音的用户列表
21281 * @memberof PersistentConversation#
21282 * @type {?String[]}
21283 */
21284 mutedMembers: mutedMembers,
21285
21286 /**
21287 * 暂态对话标记
21288 * @memberof PersistentConversation#
21289 * @type {Boolean}
21290 */
21291 "transient": _transient,
21292
21293 /**
21294 * 系统对话标记
21295 * @memberof PersistentConversation#
21296 * @type {Boolean}
21297 * @since 3.3.0
21298 */
21299 system: system,
21300
21301 /**
21302 * 当前用户静音该对话标记
21303 * @memberof PersistentConversation#
21304 * @type {Boolean}
21305 */
21306 muted: muted,
21307 _attributes: attributes
21308 }), client) || this;
21309
21310 _this._reset();
21311
21312 return _this;
21313 }
21314
21315 var _proto = PersistentConversation.prototype;
21316
21317 /**
21318 * 获取对话的自定义属性
21319 * @since 3.2.0
21320 * @param {String} key key 属性的键名,'x' 对应 Conversation 表中的 x 列
21321 * @return {Any} 属性的值
21322 */
21323 _proto.get = function get(key) {
21324 return get_1(internal(this).currentAttributes, key);
21325 }
21326 /**
21327 * 设置对话的自定义属性
21328 * @since 3.2.0
21329 * @param {String} key 属性的键名,'x' 对应 Conversation 表中的 x 列,支持使用 'x.y.z' 来修改对象的部分字段。
21330 * @param {Any} value 属性的值
21331 * @return {this} self
21332 * @example
21333 *
21334 * // 设置对话的 color 属性
21335 * conversation.set('color', {
21336 * text: '#000',
21337 * background: '#DDD',
21338 * });
21339 * // 设置对话的 color.text 属性
21340 * conversation.set('color.text', '#333');
21341 */
21342 ;
21343
21344 _proto.set = function set(key, value) {
21345 this._debug("set [".concat(key, "]: ").concat(value));
21346
21347 var _internal = internal(this),
21348 pendingAttributes = _internal.pendingAttributes;
21349
21350 var pendingKeys = Object.keys(pendingAttributes); // suppose pendingAttributes = { 'a.b': {} }
21351 // set 'a' or 'a.b': delete 'a.b'
21352
21353 var re = new RegExp("^".concat(key));
21354 var childKeys = pendingKeys.filter(re.test.bind(re));
21355 childKeys.forEach(function (k) {
21356 delete pendingAttributes[k];
21357 });
21358
21359 if (childKeys.length) {
21360 pendingAttributes[key] = value;
21361 } else {
21362 // set 'a.c': nothing to do
21363 // set 'a.b.c.d': assign c: { d: {} } to 'a.b'
21364 var parentKey = find_1(pendingKeys, function (k) {
21365 return key.indexOf(k) === 0;
21366 }); // 'a.b'
21367
21368 if (parentKey) {
21369 setValue(pendingAttributes[parentKey], key.slice(parentKey.length + 1), value);
21370 } else {
21371 pendingAttributes[key] = value;
21372 }
21373 }
21374
21375 this._buildCurrentAttributes();
21376
21377 return this;
21378 };
21379
21380 _proto._buildCurrentAttributes = function _buildCurrentAttributes() {
21381 var _internal2 = internal(this),
21382 pendingAttributes = _internal2.pendingAttributes;
21383
21384 internal(this).currentAttributes = Object.keys(pendingAttributes).reduce(function (target, k) {
21385 return setValue(target, k, pendingAttributes[k]);
21386 }, cloneDeep_1(this._attributes));
21387 };
21388
21389 _proto._updateServerAttributes = function _updateServerAttributes(attributes) {
21390 var _this2 = this;
21391
21392 Object.keys(attributes).forEach(function (key) {
21393 return setValue(_this2._attributes, key, attributes[key]);
21394 });
21395
21396 this._buildCurrentAttributes();
21397 };
21398
21399 _proto._reset = function _reset() {
21400 Object.assign(internal(this), {
21401 pendingAttributes: {},
21402 currentAttributes: this._attributes
21403 });
21404 }
21405 /**
21406 * 保存当前对话的属性至服务器
21407 * @return {Promise.<this>} self
21408 */
21409 ;
21410
21411 _proto.save =
21412 /*#__PURE__*/
21413 function () {
21414 var _save = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee() {
21415 var attr, convMessage, resCommand;
21416 return regenerator.wrap(function _callee$(_context) {
21417 while (1) {
21418 switch (_context.prev = _context.next) {
21419 case 0:
21420 this._debug('save');
21421
21422 attr = internal(this).pendingAttributes;
21423
21424 if (!isEmpty_1(attr)) {
21425 _context.next = 5;
21426 break;
21427 }
21428
21429 this._debug('nothing touched, resolve with self');
21430
21431 return _context.abrupt("return", this);
21432
21433 case 5:
21434 this._debug('attr: %O', attr);
21435
21436 convMessage = new ConvCommand({
21437 attr: new JsonObjectMessage({
21438 data: JSON.stringify(encode(attr))
21439 })
21440 });
21441 _context.next = 9;
21442 return this._send(new GenericCommand({
21443 op: 'update',
21444 convMessage: convMessage
21445 }));
21446
21447 case 9:
21448 resCommand = _context.sent;
21449 this.updatedAt = resCommand.convMessage.udate;
21450 this._attributes = internal(this).currentAttributes;
21451 internal(this).pendingAttributes = {};
21452 return _context.abrupt("return", this);
21453
21454 case 14:
21455 case "end":
21456 return _context.stop();
21457 }
21458 }
21459 }, _callee, this);
21460 }));
21461
21462 function save() {
21463 return _save.apply(this, arguments);
21464 }
21465
21466 return save;
21467 }()
21468 /**
21469 * 从服务器更新对话的属性
21470 * @return {Promise.<this>} self
21471 */
21472 ;
21473
21474 _proto.fetch =
21475 /*#__PURE__*/
21476 function () {
21477 var _fetch = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee2() {
21478 var query;
21479 return regenerator.wrap(function _callee2$(_context2) {
21480 while (1) {
21481 switch (_context2.prev = _context2.next) {
21482 case 0:
21483 query = this._client.getQuery().equalTo('objectId', this.id);
21484 _context2.next = 3;
21485 return query.find();
21486
21487 case 3:
21488 return _context2.abrupt("return", this);
21489
21490 case 4:
21491 case "end":
21492 return _context2.stop();
21493 }
21494 }
21495 }, _callee2, this);
21496 }));
21497
21498 function fetch() {
21499 return _fetch.apply(this, arguments);
21500 }
21501
21502 return fetch;
21503 }()
21504 /**
21505 * 静音,客户端拒绝收到服务器端的离线推送通知
21506 * @return {Promise.<this>} self
21507 */
21508 ;
21509
21510 _proto.mute =
21511 /*#__PURE__*/
21512 function () {
21513 var _mute = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee3() {
21514 return regenerator.wrap(function _callee3$(_context3) {
21515 while (1) {
21516 switch (_context3.prev = _context3.next) {
21517 case 0:
21518 this._debug('mute');
21519
21520 _context3.next = 3;
21521 return this._send(new GenericCommand({
21522 op: 'mute'
21523 }));
21524
21525 case 3:
21526 if (!this["transient"]) {
21527 this.muted = true;
21528 this.mutedMembers = union(this.mutedMembers, [this._client.id]);
21529 }
21530
21531 return _context3.abrupt("return", this);
21532
21533 case 5:
21534 case "end":
21535 return _context3.stop();
21536 }
21537 }
21538 }, _callee3, this);
21539 }));
21540
21541 function mute() {
21542 return _mute.apply(this, arguments);
21543 }
21544
21545 return mute;
21546 }()
21547 /**
21548 * 取消静音
21549 * @return {Promise.<this>} self
21550 */
21551 ;
21552
21553 _proto.unmute =
21554 /*#__PURE__*/
21555 function () {
21556 var _unmute = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee4() {
21557 return regenerator.wrap(function _callee4$(_context4) {
21558 while (1) {
21559 switch (_context4.prev = _context4.next) {
21560 case 0:
21561 this._debug('unmute');
21562
21563 _context4.next = 3;
21564 return this._send(new GenericCommand({
21565 op: 'unmute'
21566 }));
21567
21568 case 3:
21569 if (!this["transient"]) {
21570 this.muted = false;
21571 this.mutedMembers = difference(this.mutedMembers, [this._client.id]);
21572 }
21573
21574 return _context4.abrupt("return", this);
21575
21576 case 5:
21577 case "end":
21578 return _context4.stop();
21579 }
21580 }
21581 }, _callee4, this);
21582 }));
21583
21584 function unmute() {
21585 return _unmute.apply(this, arguments);
21586 }
21587
21588 return unmute;
21589 }();
21590
21591 _proto._appendConversationSignature = /*#__PURE__*/function () {
21592 var _appendConversationSignature2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee5(command, action, clientIds) {
21593 var params, signatureResult;
21594 return regenerator.wrap(function _callee5$(_context5) {
21595 while (1) {
21596 switch (_context5.prev = _context5.next) {
21597 case 0:
21598 if (!this._client.options.conversationSignatureFactory) {
21599 _context5.next = 6;
21600 break;
21601 }
21602
21603 params = [this.id, this._client.id, clientIds.sort(), action];
21604 _context5.next = 4;
21605 return runSignatureFactory(this._client.options.conversationSignatureFactory, params);
21606
21607 case 4:
21608 signatureResult = _context5.sent;
21609 Object.assign(command.convMessage, keyRemap({
21610 signature: 's',
21611 timestamp: 't',
21612 nonce: 'n'
21613 }, signatureResult));
21614
21615 case 6:
21616 case "end":
21617 return _context5.stop();
21618 }
21619 }
21620 }, _callee5, this);
21621 }));
21622
21623 function _appendConversationSignature(_x, _x2, _x3) {
21624 return _appendConversationSignature2.apply(this, arguments);
21625 }
21626
21627 return _appendConversationSignature;
21628 }();
21629
21630 _proto._appendBlacklistSignature = /*#__PURE__*/function () {
21631 var _appendBlacklistSignature2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee6(command, action, clientIds) {
21632 var params, signatureResult;
21633 return regenerator.wrap(function _callee6$(_context6) {
21634 while (1) {
21635 switch (_context6.prev = _context6.next) {
21636 case 0:
21637 if (!this._client.options.blacklistSignatureFactory) {
21638 _context6.next = 6;
21639 break;
21640 }
21641
21642 params = [this.id, this._client.id, clientIds.sort(), action];
21643 _context6.next = 4;
21644 return runSignatureFactory(this._client.options.blacklistSignatureFactory, params);
21645
21646 case 4:
21647 signatureResult = _context6.sent;
21648 Object.assign(command.blacklistMessage, keyRemap({
21649 signature: 's',
21650 timestamp: 't',
21651 nonce: 'n'
21652 }, signatureResult));
21653
21654 case 6:
21655 case "end":
21656 return _context6.stop();
21657 }
21658 }
21659 }, _callee6, this);
21660 }));
21661
21662 function _appendBlacklistSignature(_x4, _x5, _x6) {
21663 return _appendBlacklistSignature2.apply(this, arguments);
21664 }
21665
21666 return _appendBlacklistSignature;
21667 }()
21668 /**
21669 * 增加成员
21670 * @param {String|String[]} clientIds 新增成员 client id
21671 * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
21672 */
21673 ;
21674
21675 _proto.add =
21676 /*#__PURE__*/
21677 function () {
21678 var _add = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee7(clientIds) {
21679 var command, _yield$this$_send, convMessage, allowedPids;
21680
21681 return regenerator.wrap(function _callee7$(_context7) {
21682 while (1) {
21683 switch (_context7.prev = _context7.next) {
21684 case 0:
21685 this._debug('add', clientIds);
21686
21687 if (typeof clientIds === 'string') {
21688 clientIds = [clientIds]; // eslint-disable-line no-param-reassign
21689 }
21690
21691 command = new GenericCommand({
21692 op: 'add',
21693 convMessage: new ConvCommand({
21694 m: clientIds
21695 })
21696 });
21697 _context7.next = 5;
21698 return this._appendConversationSignature(command, 'invite', clientIds);
21699
21700 case 5:
21701 _context7.next = 7;
21702 return this._send(command);
21703
21704 case 7:
21705 _yield$this$_send = _context7.sent;
21706 convMessage = _yield$this$_send.convMessage;
21707 allowedPids = _yield$this$_send.convMessage.allowedPids;
21708
21709 this._addMembers(allowedPids);
21710
21711 return _context7.abrupt("return", createPartiallySuccess(convMessage));
21712
21713 case 12:
21714 case "end":
21715 return _context7.stop();
21716 }
21717 }
21718 }, _callee7, this);
21719 }));
21720
21721 function add(_x7) {
21722 return _add.apply(this, arguments);
21723 }
21724
21725 return add;
21726 }()
21727 /**
21728 * 剔除成员
21729 * @param {String|String[]} clientIds 成员 client id
21730 * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
21731 */
21732 ;
21733
21734 _proto.remove =
21735 /*#__PURE__*/
21736 function () {
21737 var _remove = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee8(clientIds) {
21738 var command, _yield$this$_send2, convMessage, allowedPids;
21739
21740 return regenerator.wrap(function _callee8$(_context8) {
21741 while (1) {
21742 switch (_context8.prev = _context8.next) {
21743 case 0:
21744 this._debug('remove', clientIds);
21745
21746 if (typeof clientIds === 'string') {
21747 clientIds = [clientIds]; // eslint-disable-line no-param-reassign
21748 }
21749
21750 command = new GenericCommand({
21751 op: 'remove',
21752 convMessage: new ConvCommand({
21753 m: clientIds
21754 })
21755 });
21756 _context8.next = 5;
21757 return this._appendConversationSignature(command, 'kick', clientIds);
21758
21759 case 5:
21760 _context8.next = 7;
21761 return this._send(command);
21762
21763 case 7:
21764 _yield$this$_send2 = _context8.sent;
21765 convMessage = _yield$this$_send2.convMessage;
21766 allowedPids = _yield$this$_send2.convMessage.allowedPids;
21767
21768 this._removeMembers(allowedPids);
21769
21770 return _context8.abrupt("return", createPartiallySuccess(convMessage));
21771
21772 case 12:
21773 case "end":
21774 return _context8.stop();
21775 }
21776 }
21777 }, _callee8, this);
21778 }));
21779
21780 function remove(_x8) {
21781 return _remove.apply(this, arguments);
21782 }
21783
21784 return remove;
21785 }()
21786 /**
21787 * (当前用户)加入该对话
21788 * @return {Promise.<this>} self
21789 */
21790 ;
21791
21792 _proto.join =
21793 /*#__PURE__*/
21794 function () {
21795 var _join = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee9() {
21796 var _this3 = this;
21797
21798 return regenerator.wrap(function _callee9$(_context9) {
21799 while (1) {
21800 switch (_context9.prev = _context9.next) {
21801 case 0:
21802 this._debug('join');
21803
21804 return _context9.abrupt("return", this.add(this._client.id).then(function (_ref4) {
21805 var failures = _ref4.failures;
21806 if (failures[0]) throw failures[0];
21807 return _this3;
21808 }));
21809
21810 case 2:
21811 case "end":
21812 return _context9.stop();
21813 }
21814 }
21815 }, _callee9, this);
21816 }));
21817
21818 function join() {
21819 return _join.apply(this, arguments);
21820 }
21821
21822 return join;
21823 }()
21824 /**
21825 * (当前用户)退出该对话
21826 * @return {Promise.<this>} self
21827 */
21828 ;
21829
21830 _proto.quit =
21831 /*#__PURE__*/
21832 function () {
21833 var _quit = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee10() {
21834 var _this4 = this;
21835
21836 return regenerator.wrap(function _callee10$(_context10) {
21837 while (1) {
21838 switch (_context10.prev = _context10.next) {
21839 case 0:
21840 this._debug('quit');
21841
21842 return _context10.abrupt("return", this.remove(this._client.id).then(function (_ref5) {
21843 var failures = _ref5.failures;
21844 if (failures[0]) throw failures[0];
21845 return _this4;
21846 }));
21847
21848 case 2:
21849 case "end":
21850 return _context10.stop();
21851 }
21852 }
21853 }, _callee10, this);
21854 }));
21855
21856 function quit() {
21857 return _quit.apply(this, arguments);
21858 }
21859
21860 return quit;
21861 }()
21862 /**
21863 * 在该对话中禁言成员
21864 * @param {String|String[]} clientIds 成员 client id
21865 * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
21866 */
21867 ;
21868
21869 _proto.muteMembers =
21870 /*#__PURE__*/
21871 function () {
21872 var _muteMembers = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee11(clientIds) {
21873 var command, _yield$this$_send3, convMessage;
21874
21875 return regenerator.wrap(function _callee11$(_context11) {
21876 while (1) {
21877 switch (_context11.prev = _context11.next) {
21878 case 0:
21879 this._debug('mute', clientIds);
21880
21881 clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
21882
21883 command = new GenericCommand({
21884 op: OpType.add_shutup,
21885 convMessage: new ConvCommand({
21886 m: clientIds
21887 })
21888 });
21889 _context11.next = 5;
21890 return this._send(command);
21891
21892 case 5:
21893 _yield$this$_send3 = _context11.sent;
21894 convMessage = _yield$this$_send3.convMessage;
21895 return _context11.abrupt("return", createPartiallySuccess(convMessage));
21896
21897 case 8:
21898 case "end":
21899 return _context11.stop();
21900 }
21901 }
21902 }, _callee11, this);
21903 }));
21904
21905 function muteMembers(_x9) {
21906 return _muteMembers.apply(this, arguments);
21907 }
21908
21909 return muteMembers;
21910 }()
21911 /**
21912 * 在该对话中解除成员禁言
21913 * @param {String|String[]} clientIds 成员 client id
21914 * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
21915 */
21916 ;
21917
21918 _proto.unmuteMembers =
21919 /*#__PURE__*/
21920 function () {
21921 var _unmuteMembers = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee12(clientIds) {
21922 var command, _yield$this$_send4, convMessage;
21923
21924 return regenerator.wrap(function _callee12$(_context12) {
21925 while (1) {
21926 switch (_context12.prev = _context12.next) {
21927 case 0:
21928 this._debug('unmute', clientIds);
21929
21930 clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
21931
21932 command = new GenericCommand({
21933 op: OpType.remove_shutup,
21934 convMessage: new ConvCommand({
21935 m: clientIds
21936 })
21937 });
21938 _context12.next = 5;
21939 return this._send(command);
21940
21941 case 5:
21942 _yield$this$_send4 = _context12.sent;
21943 convMessage = _yield$this$_send4.convMessage;
21944 return _context12.abrupt("return", createPartiallySuccess(convMessage));
21945
21946 case 8:
21947 case "end":
21948 return _context12.stop();
21949 }
21950 }
21951 }, _callee12, this);
21952 }));
21953
21954 function unmuteMembers(_x10) {
21955 return _unmuteMembers.apply(this, arguments);
21956 }
21957
21958 return unmuteMembers;
21959 }()
21960 /**
21961 * 查询该对话禁言成员列表
21962 * @param {Object} [options]
21963 * @param {Number} [options.limit] 返回的成员数量,服务器默认值 10
21964 * @param {String} [options.next] 从指定 next 开始查询,与 limit 一起使用可以完成翻页。
21965 * @return {PagedResults.<string>} 查询结果。其中的 cureser 存在表示还有更多结果。
21966 */
21967 ;
21968
21969 _proto.queryMutedMembers =
21970 /*#__PURE__*/
21971 function () {
21972 var _queryMutedMembers = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee13() {
21973 var _ref6,
21974 limit,
21975 next,
21976 command,
21977 _yield$this$_send5,
21978 _yield$this$_send5$co,
21979 m,
21980 newNext,
21981 _args13 = arguments;
21982
21983 return regenerator.wrap(function _callee13$(_context13) {
21984 while (1) {
21985 switch (_context13.prev = _context13.next) {
21986 case 0:
21987 _ref6 = _args13.length > 0 && _args13[0] !== undefined ? _args13[0] : {}, limit = _ref6.limit, next = _ref6.next;
21988
21989 this._debug('query muted: limit %O, next: %O', limit, next);
21990
21991 command = new GenericCommand({
21992 op: OpType.query_shutup,
21993 convMessage: new ConvCommand({
21994 limit: limit,
21995 next: next
21996 })
21997 });
21998 _context13.next = 5;
21999 return this._send(command);
22000
22001 case 5:
22002 _yield$this$_send5 = _context13.sent;
22003 _yield$this$_send5$co = _yield$this$_send5.convMessage;
22004 m = _yield$this$_send5$co.m;
22005 newNext = _yield$this$_send5$co.next;
22006 return _context13.abrupt("return", {
22007 results: m,
22008 next: newNext
22009 });
22010
22011 case 10:
22012 case "end":
22013 return _context13.stop();
22014 }
22015 }
22016 }, _callee13, this);
22017 }));
22018
22019 function queryMutedMembers() {
22020 return _queryMutedMembers.apply(this, arguments);
22021 }
22022
22023 return queryMutedMembers;
22024 }()
22025 /**
22026 * 将用户加入该对话黑名单
22027 * @param {String|String[]} clientIds 成员 client id
22028 * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
22029 */
22030 ;
22031
22032 _proto.blockMembers =
22033 /*#__PURE__*/
22034 function () {
22035 var _blockMembers = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee14(clientIds) {
22036 var command, _yield$this$_send6, blacklistMessage;
22037
22038 return regenerator.wrap(function _callee14$(_context14) {
22039 while (1) {
22040 switch (_context14.prev = _context14.next) {
22041 case 0:
22042 this._debug('block', clientIds);
22043
22044 clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
22045
22046 command = new GenericCommand({
22047 cmd: 'blacklist',
22048 op: OpType.block,
22049 blacklistMessage: new BlacklistCommand({
22050 srcCid: this.id,
22051 toPids: clientIds
22052 })
22053 });
22054 _context14.next = 5;
22055 return this._appendBlacklistSignature(command, 'conversation-block-clients', clientIds);
22056
22057 case 5:
22058 _context14.next = 7;
22059 return this._send(command);
22060
22061 case 7:
22062 _yield$this$_send6 = _context14.sent;
22063 blacklistMessage = _yield$this$_send6.blacklistMessage;
22064 return _context14.abrupt("return", createPartiallySuccess(blacklistMessage));
22065
22066 case 10:
22067 case "end":
22068 return _context14.stop();
22069 }
22070 }
22071 }, _callee14, this);
22072 }));
22073
22074 function blockMembers(_x11) {
22075 return _blockMembers.apply(this, arguments);
22076 }
22077
22078 return blockMembers;
22079 }()
22080 /**
22081 * 将用户移出该对话黑名单
22082 * @param {String|String[]} clientIds 成员 client id
22083 * @return {Promise.<PartiallySuccess>} 部分成功结果,包含了成功的 id 列表、失败原因与对应的 id 列表
22084 */
22085 ;
22086
22087 _proto.unblockMembers =
22088 /*#__PURE__*/
22089 function () {
22090 var _unblockMembers = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee15(clientIds) {
22091 var command, _yield$this$_send7, blacklistMessage;
22092
22093 return regenerator.wrap(function _callee15$(_context15) {
22094 while (1) {
22095 switch (_context15.prev = _context15.next) {
22096 case 0:
22097 this._debug('unblock', clientIds);
22098
22099 clientIds = ensureArray(clientIds); // eslint-disable-line no-param-reassign
22100
22101 command = new GenericCommand({
22102 cmd: 'blacklist',
22103 op: OpType.unblock,
22104 blacklistMessage: new BlacklistCommand({
22105 srcCid: this.id,
22106 toPids: clientIds
22107 })
22108 });
22109 _context15.next = 5;
22110 return this._appendBlacklistSignature(command, 'conversation-unblock-clients', clientIds);
22111
22112 case 5:
22113 _context15.next = 7;
22114 return this._send(command);
22115
22116 case 7:
22117 _yield$this$_send7 = _context15.sent;
22118 blacklistMessage = _yield$this$_send7.blacklistMessage;
22119 return _context15.abrupt("return", createPartiallySuccess(blacklistMessage));
22120
22121 case 10:
22122 case "end":
22123 return _context15.stop();
22124 }
22125 }
22126 }, _callee15, this);
22127 }));
22128
22129 function unblockMembers(_x12) {
22130 return _unblockMembers.apply(this, arguments);
22131 }
22132
22133 return unblockMembers;
22134 }()
22135 /**
22136 * 查询该对话黑名单
22137 * @param {Object} [options]
22138 * @param {Number} [options.limit] 返回的成员数量,服务器默认值 10
22139 * @param {String} [options.next] 从指定 next 开始查询,与 limit 一起使用可以完成翻页
22140 * @return {PagedResults.<string>} 查询结果。其中的 cureser 存在表示还有更多结果。
22141 */
22142 ;
22143
22144 _proto.queryBlockedMembers =
22145 /*#__PURE__*/
22146 function () {
22147 var _queryBlockedMembers = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee16() {
22148 var _ref7,
22149 limit,
22150 next,
22151 command,
22152 _yield$this$_send8,
22153 _yield$this$_send8$bl,
22154 blockedPids,
22155 newNext,
22156 _args16 = arguments;
22157
22158 return regenerator.wrap(function _callee16$(_context16) {
22159 while (1) {
22160 switch (_context16.prev = _context16.next) {
22161 case 0:
22162 _ref7 = _args16.length > 0 && _args16[0] !== undefined ? _args16[0] : {}, limit = _ref7.limit, next = _ref7.next;
22163
22164 this._debug('query blocked: limit %O, next: %O', limit, next);
22165
22166 command = new GenericCommand({
22167 cmd: 'blacklist',
22168 op: OpType.query,
22169 blacklistMessage: new BlacklistCommand({
22170 srcCid: this.id,
22171 limit: limit,
22172 next: next
22173 })
22174 });
22175 _context16.next = 5;
22176 return this._send(command);
22177
22178 case 5:
22179 _yield$this$_send8 = _context16.sent;
22180 _yield$this$_send8$bl = _yield$this$_send8.blacklistMessage;
22181 blockedPids = _yield$this$_send8$bl.blockedPids;
22182 newNext = _yield$this$_send8$bl.next;
22183 return _context16.abrupt("return", {
22184 results: blockedPids,
22185 next: newNext
22186 });
22187
22188 case 10:
22189 case "end":
22190 return _context16.stop();
22191 }
22192 }
22193 }, _callee16, this);
22194 }));
22195
22196 function queryBlockedMembers() {
22197 return _queryBlockedMembers.apply(this, arguments);
22198 }
22199
22200 return queryBlockedMembers;
22201 }();
22202
22203 _proto.toFullJSON = function toFullJSON() {
22204 var creator = this.creator,
22205 system = this.system,
22206 _transient2 = this["transient"],
22207 createdAt = this.createdAt,
22208 updatedAt = this.updatedAt,
22209 _attributes = this._attributes;
22210 return _objectSpread$6(_objectSpread$6({}, _ConversationBase.prototype.toFullJSON.call(this)), {}, {
22211 creator: creator,
22212 system: system,
22213 "transient": _transient2,
22214 createdAt: getTime(createdAt),
22215 updatedAt: getTime(updatedAt)
22216 }, _attributes);
22217 };
22218
22219 _proto.toJSON = function toJSON() {
22220 var creator = this.creator,
22221 system = this.system,
22222 _transient3 = this["transient"],
22223 muted = this.muted,
22224 mutedMembers = this.mutedMembers,
22225 createdAt = this.createdAt,
22226 updatedAt = this.updatedAt,
22227 _attributes = this._attributes;
22228 return _objectSpread$6(_objectSpread$6({}, _ConversationBase.prototype.toJSON.call(this)), {}, {
22229 creator: creator,
22230 system: system,
22231 "transient": _transient3,
22232 muted: muted,
22233 mutedMembers: mutedMembers,
22234 createdAt: createdAt,
22235 updatedAt: updatedAt
22236 }, _attributes);
22237 };
22238
22239 createClass(PersistentConversation, [{
22240 key: "createdAt",
22241 set: function set(value) {
22242 this._createdAt = decodeDate(value);
22243 },
22244 get: function get() {
22245 return this._createdAt;
22246 }
22247 }, {
22248 key: "updatedAt",
22249 set: function set(value) {
22250 this._updatedAt = decodeDate(value);
22251 },
22252 get: function get() {
22253 return this._updatedAt;
22254 }
22255 /**
22256 * 对话名字,对应 _Conversation 表中的 name
22257 * @type {String}
22258 */
22259
22260 }, {
22261 key: "name",
22262 get: function get() {
22263 return this.get('name');
22264 },
22265 set: function set(value) {
22266 this.set('name', value);
22267 }
22268 }]);
22269
22270 return PersistentConversation;
22271 }(ConversationBase);
22272
22273 /**
22274 * 对话成员角色枚举
22275 * @enum {String}
22276 * @since 4.0.0
22277 * @memberof module:leancloud-realtime
22278 */
22279
22280 var ConversationMemberRole = {
22281 /** 所有者 */
22282 OWNER: 'Owner',
22283
22284 /** 管理员 */
22285 MANAGER: 'Manager',
22286
22287 /** 成员 */
22288 MEMBER: 'Member'
22289 };
22290 Object.freeze(ConversationMemberRole);
22291
22292 var ConversationMemberInfo = /*#__PURE__*/function () {
22293 /**
22294 * 对话成员属性,保存了成员与某个对话相关的属性,对应 _ConversationMemberInfo 表
22295 * @since 4.0.0
22296 */
22297 function ConversationMemberInfo(_ref) {
22298 var conversation = _ref.conversation,
22299 memberId = _ref.memberId,
22300 role = _ref.role;
22301 if (!conversation) throw new Error('conversation requried');
22302 if (!memberId) throw new Error('memberId requried');
22303 Object.assign(internal(this), {
22304 conversation: conversation,
22305 memberId: memberId,
22306 role: role
22307 });
22308 }
22309 /**
22310 * 对话 Id
22311 * @type {String}
22312 * @readonly
22313 */
22314
22315
22316 var _proto = ConversationMemberInfo.prototype;
22317
22318 _proto.toJSON = function toJSON() {
22319 var conversationId = this.conversationId,
22320 memberId = this.memberId,
22321 role = this.role,
22322 isOwner = this.isOwner;
22323 return {
22324 conversationId: conversationId,
22325 memberId: memberId,
22326 role: role,
22327 isOwner: isOwner
22328 };
22329 };
22330
22331 createClass(ConversationMemberInfo, [{
22332 key: "conversationId",
22333 get: function get() {
22334 return internal(this).conversation.id;
22335 }
22336 /**
22337 * 成员 Id
22338 * @type {String}
22339 * @readonly
22340 */
22341
22342 }, {
22343 key: "memberId",
22344 get: function get() {
22345 return internal(this).memberId;
22346 }
22347 /**
22348 * 角色
22349 * @type {module:leancloud-realtime.ConversationMemberRole | String}
22350 * @readonly
22351 */
22352
22353 }, {
22354 key: "role",
22355 get: function get() {
22356 if (this.isOwner) return ConversationMemberRole.OWNER;
22357 return internal(this).role;
22358 }
22359 /**
22360 * 是否是管理员
22361 * @type {Boolean}
22362 * @readonly
22363 */
22364
22365 }, {
22366 key: "isOwner",
22367 get: function get() {
22368 return this.memberId === internal(this).conversation.creator;
22369 }
22370 }]);
22371
22372 return ConversationMemberInfo;
22373 }();
22374
22375 /**
22376 * 普通对话
22377 *
22378 * 无法直接实例化,请使用 {@link IMClient#createConversation} 创建新的普通对话。
22379 * @extends PersistentConversation
22380 * @public
22381 */
22382
22383 var Conversation = /*#__PURE__*/function (_PersistentConversati) {
22384 inheritsLoose(Conversation, _PersistentConversati);
22385
22386 function Conversation() {
22387 return _PersistentConversati.apply(this, arguments) || this;
22388 }
22389
22390 var _proto = Conversation.prototype;
22391
22392 _proto._addMembers = function _addMembers(members) {
22393 var _this = this;
22394
22395 _PersistentConversati.prototype._addMembers.call(this, members);
22396
22397 this.members = union(this.members, members);
22398
22399 var _internal = internal(this),
22400 memberInfoMap = _internal.memberInfoMap;
22401
22402 if (!memberInfoMap) return;
22403 members.forEach(function (memberId) {
22404 memberInfoMap[memberId] = memberInfoMap[memberId] || new ConversationMemberInfo({
22405 conversation: _this,
22406 memberId: memberId,
22407 role: ConversationMemberRole.MEMBER
22408 });
22409 });
22410 };
22411
22412 _proto._removeMembers = function _removeMembers(members) {
22413 _PersistentConversati.prototype._removeMembers.call(this, members);
22414
22415 this.members = difference(this.members, members);
22416
22417 var _internal2 = internal(this),
22418 memberInfoMap = _internal2.memberInfoMap;
22419
22420 if (!memberInfoMap) return;
22421 members.forEach(function (memberId) {
22422 delete memberInfoMap[memberId];
22423 });
22424 };
22425
22426 _proto._fetchAllMemberInfo = /*#__PURE__*/function () {
22427 var _fetchAllMemberInfo2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee() {
22428 var _this2 = this;
22429
22430 var response, memberInfos, memberInfoMap;
22431 return regenerator.wrap(function _callee$(_context) {
22432 while (1) {
22433 switch (_context.prev = _context.next) {
22434 case 0:
22435 _context.next = 2;
22436 return this._client._requestWithSessionToken({
22437 method: 'GET',
22438 path: '/classes/_ConversationMemberInfo',
22439 query: {
22440 where: {
22441 cid: this.id
22442 }
22443 }
22444 });
22445
22446 case 2:
22447 response = _context.sent;
22448 memberInfos = response.results.map(function (info) {
22449 return new ConversationMemberInfo({
22450 conversation: _this2,
22451 memberId: info.clientId,
22452 role: info.role
22453 });
22454 });
22455 memberInfoMap = {};
22456 memberInfos.forEach(function (memberInfo) {
22457 memberInfoMap[memberInfo.memberId] = memberInfo;
22458 });
22459 this.members.forEach(function (memberId) {
22460 memberInfoMap[memberId] = memberInfoMap[memberId] || new ConversationMemberInfo({
22461 conversation: _this2,
22462 memberId: memberId,
22463 role: ConversationMemberRole.MEMBER
22464 });
22465 });
22466 internal(this).memberInfoMap = memberInfoMap;
22467 return _context.abrupt("return", memberInfoMap);
22468
22469 case 9:
22470 case "end":
22471 return _context.stop();
22472 }
22473 }
22474 }, _callee, this);
22475 }));
22476
22477 function _fetchAllMemberInfo() {
22478 return _fetchAllMemberInfo2.apply(this, arguments);
22479 }
22480
22481 return _fetchAllMemberInfo;
22482 }()
22483 /**
22484 * 获取所有成员的对话属性
22485 * @since 4.0.0
22486 * @return {Promise.<ConversationMemberInfo[]>} 所有成员的对话属性列表
22487 */
22488 ;
22489
22490 _proto.getAllMemberInfo =
22491 /*#__PURE__*/
22492 function () {
22493 var _getAllMemberInfo = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee2() {
22494 var _ref,
22495 _ref$noCache,
22496 noCache,
22497 _internal3,
22498 memberInfoMap,
22499 _args2 = arguments;
22500
22501 return regenerator.wrap(function _callee2$(_context2) {
22502 while (1) {
22503 switch (_context2.prev = _context2.next) {
22504 case 0:
22505 _ref = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {}, _ref$noCache = _ref.noCache, noCache = _ref$noCache === void 0 ? false : _ref$noCache;
22506 _internal3 = internal(this), memberInfoMap = _internal3.memberInfoMap;
22507
22508 if (!(!memberInfoMap || noCache)) {
22509 _context2.next = 6;
22510 break;
22511 }
22512
22513 _context2.next = 5;
22514 return this._fetchAllMemberInfo();
22515
22516 case 5:
22517 memberInfoMap = _context2.sent;
22518
22519 case 6:
22520 return _context2.abrupt("return", this.members.map(function (memberId) {
22521 return memberInfoMap[memberId];
22522 }));
22523
22524 case 7:
22525 case "end":
22526 return _context2.stop();
22527 }
22528 }
22529 }, _callee2, this);
22530 }));
22531
22532 function getAllMemberInfo() {
22533 return _getAllMemberInfo.apply(this, arguments);
22534 }
22535
22536 return getAllMemberInfo;
22537 }()
22538 /**
22539 * 获取指定成员的对话属性
22540 * @since 4.0.0
22541 * @param {String} memberId 成员 Id
22542 * @return {Promise.<ConversationMemberInfo>} 指定成员的对话属性
22543 */
22544 ;
22545
22546 _proto.getMemberInfo =
22547 /*#__PURE__*/
22548 function () {
22549 var _getMemberInfo = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee3(memberId) {
22550 var _internal4, memberInfoMap;
22551
22552 return regenerator.wrap(function _callee3$(_context3) {
22553 while (1) {
22554 switch (_context3.prev = _context3.next) {
22555 case 0:
22556 if (!(this.members.indexOf(memberId) === -1)) {
22557 _context3.next = 2;
22558 break;
22559 }
22560
22561 throw new Error("".concat(memberId, " is not the mumber of conversation[").concat(this.id, "]"));
22562
22563 case 2:
22564 _internal4 = internal(this), memberInfoMap = _internal4.memberInfoMap;
22565
22566 if (memberInfoMap && memberInfoMap[memberId]) {
22567 _context3.next = 6;
22568 break;
22569 }
22570
22571 _context3.next = 6;
22572 return this.getAllMemberInfo();
22573
22574 case 6:
22575 return _context3.abrupt("return", internal(this).memberInfoMap[memberId]);
22576
22577 case 7:
22578 case "end":
22579 return _context3.stop();
22580 }
22581 }
22582 }, _callee3, this);
22583 }));
22584
22585 function getMemberInfo(_x) {
22586 return _getMemberInfo.apply(this, arguments);
22587 }
22588
22589 return getMemberInfo;
22590 }()
22591 /**
22592 * 更新指定用户的角色
22593 * @since 4.0.0
22594 * @param {String} memberId 成员 Id
22595 * @param {module:leancloud-realtime.ConversationMemberRole | String} role 角色
22596 * @return {Promise.<this>} self
22597 */
22598 ;
22599
22600 _proto.updateMemberRole =
22601 /*#__PURE__*/
22602 function () {
22603 var _updateMemberRole = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee4(memberId, role) {
22604 var _internal5, memberInfos;
22605
22606 return regenerator.wrap(function _callee4$(_context4) {
22607 while (1) {
22608 switch (_context4.prev = _context4.next) {
22609 case 0:
22610 this._debug('update member role');
22611
22612 if (!(role === ConversationMemberRole.OWNER)) {
22613 _context4.next = 3;
22614 break;
22615 }
22616
22617 throw createError({
22618 code: ErrorCode.OWNER_PROMOTION_NOT_ALLOWED
22619 });
22620
22621 case 3:
22622 _context4.next = 5;
22623 return this._send(new GenericCommand({
22624 op: OpType.member_info_update,
22625 convMessage: new ConvCommand({
22626 targetClientId: memberId,
22627 info: new ConvMemberInfo({
22628 pid: memberId,
22629 role: role
22630 })
22631 })
22632 }));
22633
22634 case 5:
22635 _internal5 = internal(this), memberInfos = _internal5.memberInfos;
22636
22637 if (memberInfos && memberInfos[memberId]) {
22638 internal(memberInfos[memberId]).role = role;
22639 }
22640
22641 return _context4.abrupt("return", this);
22642
22643 case 8:
22644 case "end":
22645 return _context4.stop();
22646 }
22647 }
22648 }, _callee4, this);
22649 }));
22650
22651 function updateMemberRole(_x2, _x3) {
22652 return _updateMemberRole.apply(this, arguments);
22653 }
22654
22655 return updateMemberRole;
22656 }();
22657
22658 return Conversation;
22659 }(PersistentConversation);
22660
22661 /**
22662 * 聊天室。
22663 *
22664 * 无法直接实例化,请使用 {@link IMClient#createChatRoom} 创建新的聊天室。
22665 * @since 4.0.0
22666 * @extends PersistentConversation
22667 * @public
22668 */
22669
22670 var ChatRoom = /*#__PURE__*/function (_PersistentConversati) {
22671 inheritsLoose(ChatRoom, _PersistentConversati);
22672
22673 function ChatRoom() {
22674 return _PersistentConversati.apply(this, arguments) || this;
22675 }
22676
22677 return ChatRoom;
22678 }(PersistentConversation);
22679
22680 /**
22681 * 服务号。
22682 *
22683 * 服务号不支持在客户端创建。
22684 * @since 4.0.0
22685 * @extends PersistentConversation
22686 * @public
22687 */
22688
22689 var ServiceConversation = /*#__PURE__*/function (_PersistentConversati) {
22690 inheritsLoose(ServiceConversation, _PersistentConversati);
22691
22692 function ServiceConversation() {
22693 return _PersistentConversati.apply(this, arguments) || this;
22694 }
22695
22696 var _proto = ServiceConversation.prototype;
22697
22698 /**
22699 * 订阅该服务号
22700 * @return {Promise.<this>} self
22701 */
22702 _proto.subscribe =
22703 /*#__PURE__*/
22704 function () {
22705 var _subscribe = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee() {
22706 return regenerator.wrap(function _callee$(_context) {
22707 while (1) {
22708 switch (_context.prev = _context.next) {
22709 case 0:
22710 return _context.abrupt("return", this.join());
22711
22712 case 1:
22713 case "end":
22714 return _context.stop();
22715 }
22716 }
22717 }, _callee, this);
22718 }));
22719
22720 function subscribe() {
22721 return _subscribe.apply(this, arguments);
22722 }
22723
22724 return subscribe;
22725 }()
22726 /**
22727 * 退订该服务号
22728 * @return {Promise.<this>} self
22729 */
22730 ;
22731
22732 _proto.unsubscribe =
22733 /*#__PURE__*/
22734 function () {
22735 var _unsubscribe = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee2() {
22736 return regenerator.wrap(function _callee2$(_context2) {
22737 while (1) {
22738 switch (_context2.prev = _context2.next) {
22739 case 0:
22740 return _context2.abrupt("return", this.quit());
22741
22742 case 1:
22743 case "end":
22744 return _context2.stop();
22745 }
22746 }
22747 }, _callee2, this);
22748 }));
22749
22750 function unsubscribe() {
22751 return _unsubscribe.apply(this, arguments);
22752 }
22753
22754 return unsubscribe;
22755 }();
22756
22757 return ServiceConversation;
22758 }(PersistentConversation);
22759
22760 function ownKeys$7(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
22761
22762 function _objectSpread$7(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$7(Object(source), true).forEach(function (key) { defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$7(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
22763
22764 var transformNotFoundError = function transformNotFoundError(error) {
22765 return error.code === ErrorCode.CONVERSATION_NOT_FOUND ? createError({
22766 code: ErrorCode.TEMPORARY_CONVERSATION_EXPIRED
22767 }) : error;
22768 };
22769 /**
22770 * 临时对话
22771 * @since 4.0.0
22772 * @extends ConversationBase
22773 * @public
22774 */
22775
22776
22777 var TemporaryConversation = /*#__PURE__*/function (_ConversationBase) {
22778 inheritsLoose(TemporaryConversation, _ConversationBase);
22779
22780 /**
22781 * 无法直接实例化,请使用 {@link IMClient#createTemporaryConversation} 创建新的临时对话。
22782 */
22783 function TemporaryConversation(data, _ref, client) {
22784 var expiredAt = _ref.expiredAt;
22785 return _ConversationBase.call(this, _objectSpread$7(_objectSpread$7({}, data), {}, {
22786 expiredAt: expiredAt
22787 }), client) || this;
22788 }
22789 /**
22790 * 对话失效时间
22791 * @type {Date}
22792 */
22793
22794
22795 var _proto = TemporaryConversation.prototype;
22796
22797 _proto._send = /*#__PURE__*/function () {
22798 var _send2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee() {
22799 var _ConversationBase$pro,
22800 _len,
22801 args,
22802 _key,
22803 _args = arguments;
22804
22805 return regenerator.wrap(function _callee$(_context) {
22806 while (1) {
22807 switch (_context.prev = _context.next) {
22808 case 0:
22809 if (!this.expired) {
22810 _context.next = 2;
22811 break;
22812 }
22813
22814 throw createError({
22815 code: ErrorCode.TEMPORARY_CONVERSATION_EXPIRED
22816 });
22817
22818 case 2:
22819 _context.prev = 2;
22820
22821 for (_len = _args.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
22822 args[_key] = _args[_key];
22823 }
22824
22825 _context.next = 6;
22826 return (_ConversationBase$pro = _ConversationBase.prototype._send).call.apply(_ConversationBase$pro, [this].concat(args));
22827
22828 case 6:
22829 return _context.abrupt("return", _context.sent);
22830
22831 case 9:
22832 _context.prev = 9;
22833 _context.t0 = _context["catch"](2);
22834 throw transformNotFoundError(_context.t0);
22835
22836 case 12:
22837 case "end":
22838 return _context.stop();
22839 }
22840 }
22841 }, _callee, this, [[2, 9]]);
22842 }));
22843
22844 function _send() {
22845 return _send2.apply(this, arguments);
22846 }
22847
22848 return _send;
22849 }();
22850
22851 _proto.send = /*#__PURE__*/function () {
22852 var _send3 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee2() {
22853 var _ConversationBase$pro2,
22854 _len2,
22855 args,
22856 _key2,
22857 _args2 = arguments;
22858
22859 return regenerator.wrap(function _callee2$(_context2) {
22860 while (1) {
22861 switch (_context2.prev = _context2.next) {
22862 case 0:
22863 _context2.prev = 0;
22864
22865 for (_len2 = _args2.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
22866 args[_key2] = _args2[_key2];
22867 }
22868
22869 _context2.next = 4;
22870 return (_ConversationBase$pro2 = _ConversationBase.prototype.send).call.apply(_ConversationBase$pro2, [this].concat(args));
22871
22872 case 4:
22873 return _context2.abrupt("return", _context2.sent);
22874
22875 case 7:
22876 _context2.prev = 7;
22877 _context2.t0 = _context2["catch"](0);
22878 throw transformNotFoundError(_context2.t0);
22879
22880 case 10:
22881 case "end":
22882 return _context2.stop();
22883 }
22884 }
22885 }, _callee2, this, [[0, 7]]);
22886 }));
22887
22888 function send() {
22889 return _send3.apply(this, arguments);
22890 }
22891
22892 return send;
22893 }();
22894
22895 _proto.toFullJSON = function toFullJSON() {
22896 var expiredAt = this.expiredAt;
22897 return _objectSpread$7(_objectSpread$7({}, _ConversationBase.prototype.toFullJSON.call(this)), {}, {
22898 expiredAt: getTime(expiredAt)
22899 });
22900 };
22901
22902 _proto.toJSON = function toJSON() {
22903 var expiredAt = this.expiredAt,
22904 expired = this.expired;
22905 return _objectSpread$7(_objectSpread$7({}, _ConversationBase.prototype.toJSON.call(this)), {}, {
22906 expiredAt: expiredAt,
22907 expired: expired
22908 });
22909 };
22910
22911 createClass(TemporaryConversation, [{
22912 key: "expiredAt",
22913 set: function set(value) {
22914 this._expiredAt = decodeDate(value);
22915 },
22916 get: function get() {
22917 return this._expiredAt;
22918 }
22919 /**
22920 * 对话是否已失效
22921 * @type {Boolean}
22922 */
22923
22924 }, {
22925 key: "expired",
22926 get: function get() {
22927 return this.expiredAt < new Date();
22928 }
22929 }]);
22930
22931 return TemporaryConversation;
22932 }(ConversationBase);
22933
22934 var debug$9 = browser('LC:ConversationQuery');
22935
22936 var ConversationQuery = /*#__PURE__*/function () {
22937 ConversationQuery._encode = function _encode(value) {
22938 if (value instanceof Date) {
22939 return {
22940 __type: 'Date',
22941 iso: value.toJSON()
22942 };
22943 }
22944
22945 if (value instanceof RegExp) {
22946 return value.source;
22947 }
22948
22949 return value;
22950 };
22951
22952 ConversationQuery._quote = function _quote(s) {
22953 return "\\Q".concat(s.replace('\\E', '\\E\\\\E\\Q'), "\\E");
22954 };
22955
22956 ConversationQuery._calculateFlag = function _calculateFlag(options) {
22957 return ['withLastMessagesRefreshed', 'compact'].reduce( // eslint-disable-next-line no-bitwise
22958 function (prev, key) {
22959 return (prev << 1) + Boolean(options[key]);
22960 }, 0);
22961 }
22962 /**
22963 * 构造一个用 AND 连接所有查询的 ConversationQuery
22964 * @param {...ConversationQuery} queries
22965 * @return {ConversationQuery}
22966 */
22967 ;
22968
22969 ConversationQuery.and = function and() {
22970 for (var _len = arguments.length, queries = new Array(_len), _key = 0; _key < _len; _key++) {
22971 queries[_key] = arguments[_key];
22972 }
22973
22974 if (queries.length < 2) {
22975 throw new Error('The queries must contain at least two elements');
22976 }
22977
22978 if (!queries.every(function (q) {
22979 return q instanceof ConversationQuery;
22980 })) {
22981 throw new Error('The element of queries must be an instance of ConversationQuery');
22982 }
22983
22984 var combined = new ConversationQuery(queries[0]._client);
22985 combined._where.$and = queries.map(function (q) {
22986 return q._where;
22987 });
22988 return combined;
22989 }
22990 /**
22991 * 构造一个用 OR 连接所有查询的 ConversationQuery
22992 * @param {...ConversationQuery} queries
22993 * @return {ConversationQuery}
22994 */
22995 ;
22996
22997 ConversationQuery.or = function or() {
22998 var combined = ConversationQuery.and.apply(ConversationQuery, arguments);
22999 combined._where.$or = combined._where.$and;
23000 delete combined._where.$and;
23001 return combined;
23002 }
23003 /**
23004 * Create a ConversationQuery
23005 * @param {IMClient} client
23006 */
23007 ;
23008
23009 function ConversationQuery(client) {
23010 this._client = client;
23011 this._where = {};
23012 this._extraOptions = {};
23013 }
23014
23015 var _proto = ConversationQuery.prototype;
23016
23017 _proto._addCondition = function _addCondition(key, condition, value) {
23018 // Check if we already have a condition
23019 if (!this._where[key]) {
23020 this._where[key] = {};
23021 }
23022
23023 this._where[key][condition] = this.constructor._encode(value);
23024 return this;
23025 };
23026
23027 _proto.toJSON = function toJSON() {
23028 var json = {
23029 where: this._where,
23030 flag: this.constructor._calculateFlag(this._extraOptions)
23031 };
23032 if (typeof this._skip !== 'undefined') json.skip = this._skip;
23033 if (typeof this._limit !== 'undefined') json.limit = this._limit;
23034 if (typeof this._order !== 'undefined') json.sort = this._order;
23035 debug$9(json);
23036 return json;
23037 }
23038 /**
23039 * 增加查询条件,指定聊天室的组员包含某些成员即可返回
23040 * @param {string[]} peerIds - 成员 ID 列表
23041 * @return {ConversationQuery} self
23042 */
23043 ;
23044
23045 _proto.containsMembers = function containsMembers(peerIds) {
23046 return this.containsAll('m', peerIds);
23047 }
23048 /**
23049 * 增加查询条件,指定聊天室的组员条件满足条件的才返回
23050 *
23051 * @param {string[]} - 成员 ID 列表
23052 * @param {Boolean} includeSelf - 是否包含自己
23053 * @return {ConversationQuery} self
23054 */
23055 ;
23056
23057 _proto.withMembers = function withMembers(peerIds, includeSelf) {
23058 var peerIdsSet = new Set(peerIds);
23059
23060 if (includeSelf) {
23061 peerIdsSet.add(this._client.id);
23062 }
23063
23064 this.sizeEqualTo('m', peerIdsSet.size);
23065 return this.containsMembers(Array.from(peerIdsSet));
23066 }
23067 /**
23068 * 增加查询条件,当 conversation 的属性中对应的字段满足等于条件时即可返回
23069 *
23070 * @param {string} key
23071 * @param value
23072 * @return {ConversationQuery} self
23073 */
23074 ;
23075
23076 _proto.equalTo = function equalTo(key, value) {
23077 this._where[key] = this.constructor._encode(value);
23078 return this;
23079 }
23080 /**
23081 * 增加查询条件,当 conversation 的属性中对应的字段满足小于条件时即可返回
23082 * @param {string} key
23083 * @param value
23084 * @return {ConversationQuery} self
23085 */
23086 ;
23087
23088 _proto.lessThan = function lessThan(key, value) {
23089 return this._addCondition(key, '$lt', value);
23090 }
23091 /**
23092 * 增加查询条件,当 conversation 的属性中对应的字段满足小于等于条件时即可返回
23093 * @param {string} key
23094 * @param value
23095 * @return {ConversationQuery} self
23096 */
23097 ;
23098
23099 _proto.lessThanOrEqualTo = function lessThanOrEqualTo(key, value) {
23100 return this._addCondition(key, '$lte', value);
23101 }
23102 /**
23103 * 增加查询条件,当 conversation 的属性中对应的字段满足大于条件时即可返回
23104 *
23105 * @param {string} key
23106 * @param value
23107 * @return {ConversationQuery} self
23108 */
23109 ;
23110
23111 _proto.greaterThan = function greaterThan(key, value) {
23112 return this._addCondition(key, '$gt', value);
23113 }
23114 /**
23115 * 增加查询条件,当 conversation 的属性中对应的字段满足大于等于条件时即可返回
23116 *
23117 * @param {string} key
23118 * @param value
23119 * @return {ConversationQuery} self
23120 */
23121 ;
23122
23123 _proto.greaterThanOrEqualTo = function greaterThanOrEqualTo(key, value) {
23124 return this._addCondition(key, '$gte', value);
23125 }
23126 /**
23127 * 增加查询条件,当 conversation 的属性中对应的字段满足不等于条件时即可返回
23128 *
23129 * @param {string} key
23130 * @param value
23131 * @return {ConversationQuery} self
23132 */
23133 ;
23134
23135 _proto.notEqualTo = function notEqualTo(key, value) {
23136 return this._addCondition(key, '$ne', value);
23137 }
23138 /**
23139 * 增加查询条件,当 conversation 存在指定的字段时即可返回
23140 *
23141 * @since 3.5.0
23142 * @param {string} key
23143 * @return {ConversationQuery} self
23144 */
23145 ;
23146
23147 _proto.exists = function exists(key) {
23148 return this._addCondition(key, '$exists', true);
23149 }
23150 /**
23151 * 增加查询条件,当 conversation 不存在指定的字段时即可返回
23152 *
23153 * @since 3.5.0
23154 * @param {string} key
23155 * @return {ConversationQuery} self
23156 */
23157 ;
23158
23159 _proto.doesNotExist = function doesNotExist(key) {
23160 return this._addCondition(key, '$exists', false);
23161 }
23162 /**
23163 * 增加查询条件,当 conversation 的属性中对应的字段对应的值包含在指定值中时即可返回
23164 *
23165 * @param {string} key
23166 * @param values
23167 * @return {ConversationQuery} self
23168 */
23169 ;
23170
23171 _proto.containedIn = function containedIn(key, values) {
23172 return this._addCondition(key, '$in', values);
23173 }
23174 /**
23175 * 增加查询条件,当 conversation 的属性中对应的字段对应的值不包含在指定值中时即可返回
23176 *
23177 * @param {string} key
23178 * @param values
23179 * @return {ConversationQuery} self
23180 */
23181 ;
23182
23183 _proto.notContainsIn = function notContainsIn(key, values) {
23184 return this._addCondition(key, '$nin', values);
23185 }
23186 /**
23187 * 增加查询条件,当conversation的属性中对应的字段中的元素包含所有的值才可返回
23188 *
23189 * @param {string} key
23190 * @param values
23191 * @return {ConversationQuery} self
23192 */
23193 ;
23194
23195 _proto.containsAll = function containsAll(key, values) {
23196 return this._addCondition(key, '$all', values);
23197 }
23198 /**
23199 * 增加查询条件,当 conversation 的属性中对应的字段对应的值包含此字符串即可返回
23200 *
23201 * @param {string} key
23202 * @param {string} subString
23203 * @return {ConversationQuery} self
23204 */
23205 ;
23206
23207 _proto.contains = function contains(key, subString) {
23208 return this._addCondition(key, '$regex', ConversationQuery._quote(subString));
23209 }
23210 /**
23211 * 增加查询条件,当 conversation 的属性中对应的字段对应的值以此字符串起始即可返回
23212 *
23213 * @param {string} key
23214 * @param {string} prefix
23215 * @return {ConversationQuery} self
23216 */
23217 ;
23218
23219 _proto.startsWith = function startsWith(key, prefix) {
23220 return this._addCondition(key, '$regex', "^".concat(ConversationQuery._quote(prefix)));
23221 }
23222 /**
23223 * 增加查询条件,当 conversation 的属性中对应的字段对应的值以此字符串结束即可返回
23224 *
23225 * @param {string} key
23226 * @param {string} suffix
23227 * @return {ConversationQuery} self
23228 */
23229 ;
23230
23231 _proto.endsWith = function endsWith(key, suffix) {
23232 return this._addCondition(key, '$regex', "".concat(ConversationQuery._quote(suffix), "$"));
23233 }
23234 /**
23235 * 增加查询条件,当 conversation 的属性中对应的字段对应的值满足提供的正则表达式即可返回
23236 *
23237 * @param {string} key
23238 * @param {RegExp} regex
23239 * @return {ConversationQuery} self
23240 */
23241 ;
23242
23243 _proto.matches = function matches(key, regex) {
23244 this._addCondition(key, '$regex', regex); // Javascript regex options support mig as inline options but store them
23245 // as properties of the object. We support mi & should migrate them to
23246 // modifiers
23247
23248
23249 var _modifiers = '';
23250
23251 if (regex.ignoreCase) {
23252 _modifiers += 'i';
23253 }
23254
23255 if (regex.multiline) {
23256 _modifiers += 'm';
23257 }
23258
23259 if (_modifiers && _modifiers.length) {
23260 this._addCondition(key, '$options', _modifiers);
23261 }
23262
23263 return this;
23264 }
23265 /**
23266 * 添加查询约束条件,查找 key 类型是数组,该数组的长度匹配提供的数值
23267 *
23268 * @param {string} key
23269 * @param {Number} length
23270 * @return {ConversationQuery} self
23271 */
23272 ;
23273
23274 _proto.sizeEqualTo = function sizeEqualTo(key, length) {
23275 return this._addCondition(key, '$size', length);
23276 }
23277 /**
23278 * 设置返回集合的大小上限
23279 *
23280 * @param {Number} limit - 上限
23281 * @return {ConversationQuery} self
23282 */
23283 ;
23284
23285 _proto.limit = function limit(_limit) {
23286 this._limit = _limit;
23287 return this;
23288 }
23289 /**
23290 * 设置返回集合的起始位置,一般用于分页
23291 *
23292 * @param {Number} skip - 起始位置跳过几个对象
23293 * @return {ConversationQuery} self
23294 */
23295 ;
23296
23297 _proto.skip = function skip(_skip) {
23298 this._skip = _skip;
23299 return this;
23300 }
23301 /**
23302 * 设置返回集合按照指定key进行增序排列
23303 *
23304 * @param {string} key
23305 * @return {ConversationQuery} self
23306 */
23307 ;
23308
23309 _proto.ascending = function ascending(key) {
23310 this._order = key;
23311 return this;
23312 }
23313 /**
23314 * 设置返回集合按照指定key进行增序排列,如果已设置其他排序,原排序的优先级较高
23315 *
23316 * @param {string} key
23317 * @return {ConversationQuery} self
23318 */
23319 ;
23320
23321 _proto.addAscending = function addAscending(key) {
23322 if (this._order) {
23323 this._order += ",".concat(key);
23324 } else {
23325 this._order = key;
23326 }
23327
23328 return this;
23329 }
23330 /**
23331 * 设置返回集合按照指定 key 进行降序排列
23332 *
23333 * @param {string} key
23334 * @return {ConversationQuery} self
23335 */
23336 ;
23337
23338 _proto.descending = function descending(key) {
23339 this._order = "-".concat(key);
23340 return this;
23341 }
23342 /**
23343 * 设置返回集合按照指定 key 进行降序排列,如果已设置其他排序,原排序的优先级较高
23344 *
23345 * @param {string} key
23346 * @return {ConversationQuery} self
23347 */
23348 ;
23349
23350 _proto.addDescending = function addDescending(key) {
23351 if (this._order) {
23352 this._order += ",-".concat(key);
23353 } else {
23354 this._order = "-".concat(key);
23355 }
23356
23357 return this;
23358 }
23359 /**
23360 * 设置返回的 conversations 刷新最后一条消息
23361 * @param {Boolean} [enabled=true]
23362 * @return {ConversationQuery} self
23363 */
23364 ;
23365
23366 _proto.withLastMessagesRefreshed = function withLastMessagesRefreshed() {
23367 var enabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
23368 this._extraOptions.withLastMessagesRefreshed = enabled;
23369 return this;
23370 }
23371 /**
23372 * 设置返回的 conversations 为精简模式,即不含成员列表
23373 * @param {Boolean} [enabled=true]
23374 * @return {ConversationQuery} self
23375 */
23376 ;
23377
23378 _proto.compact = function compact() {
23379 var enabled = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
23380 this._extraOptions.compact = enabled;
23381 return this;
23382 }
23383 /**
23384 * 执行查询
23385 * @return {Promise.<ConversationBase[]>}
23386 */
23387 ;
23388
23389 _proto.find =
23390 /*#__PURE__*/
23391 function () {
23392 var _find = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee() {
23393 return regenerator.wrap(function _callee$(_context) {
23394 while (1) {
23395 switch (_context.prev = _context.next) {
23396 case 0:
23397 return _context.abrupt("return", this._client._executeQuery(this));
23398
23399 case 1:
23400 case "end":
23401 return _context.stop();
23402 }
23403 }
23404 }, _callee, this);
23405 }));
23406
23407 function find() {
23408 return _find.apply(this, arguments);
23409 }
23410
23411 return find;
23412 }()
23413 /**
23414 * 返回符合条件的第一个结果
23415 * @return {Promise.<ConversationBase>}
23416 */
23417 ;
23418
23419 _proto.first =
23420 /*#__PURE__*/
23421 function () {
23422 var _first = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee2() {
23423 return regenerator.wrap(function _callee2$(_context2) {
23424 while (1) {
23425 switch (_context2.prev = _context2.next) {
23426 case 0:
23427 _context2.next = 2;
23428 return this.limit(1).find();
23429
23430 case 2:
23431 return _context2.abrupt("return", _context2.sent[0]);
23432
23433 case 3:
23434 case "end":
23435 return _context2.stop();
23436 }
23437 }
23438 }, _callee2, this);
23439 }));
23440
23441 function first() {
23442 return _first.apply(this, arguments);
23443 }
23444
23445 return first;
23446 }();
23447
23448 return ConversationQuery;
23449 }();
23450
23451 var debug$a = browser('LC:SessionManager');
23452
23453 var SessionManager = /*#__PURE__*/function () {
23454 function SessionManager() {
23455 var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
23456 refresh = _ref.refresh,
23457 onBeforeGetSessionToken = _ref.onBeforeGetSessionToken;
23458
23459 this.refresh = refresh;
23460 this._onBeforeGetSessionToken = onBeforeGetSessionToken;
23461 this.setSessionToken(null, 0);
23462 }
23463
23464 var _proto = SessionManager.prototype;
23465
23466 _proto.setSessionToken = function setSessionToken(token, ttl) {
23467 debug$a('set session token', token, ttl);
23468 var sessionToken = new Expirable(token, ttl * 1000);
23469 this._sessionToken = sessionToken;
23470 delete this._pendingSessionTokenPromise;
23471 return sessionToken;
23472 };
23473
23474 _proto.setSessionTokenAsync = /*#__PURE__*/function () {
23475 var _setSessionTokenAsync = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee(promise) {
23476 var _this = this;
23477
23478 var currentSessionToken;
23479 return regenerator.wrap(function _callee$(_context) {
23480 while (1) {
23481 switch (_context.prev = _context.next) {
23482 case 0:
23483 currentSessionToken = this._sessionToken;
23484 this._pendingSessionTokenPromise = promise["catch"](function (error) {
23485 // revert, otherwise the following getSessionToken calls
23486 // will all be rejected
23487 _this._sessionToken = currentSessionToken;
23488 throw error;
23489 });
23490 _context.t0 = this.setSessionToken;
23491 _context.t1 = this;
23492 _context.t2 = toConsumableArray;
23493 _context.next = 7;
23494 return this._pendingSessionTokenPromise;
23495
23496 case 7:
23497 _context.t3 = _context.sent;
23498 _context.t4 = (0, _context.t2)(_context.t3);
23499 return _context.abrupt("return", _context.t0.apply.call(_context.t0, _context.t1, _context.t4));
23500
23501 case 10:
23502 case "end":
23503 return _context.stop();
23504 }
23505 }
23506 }, _callee, this);
23507 }));
23508
23509 function setSessionTokenAsync(_x) {
23510 return _setSessionTokenAsync.apply(this, arguments);
23511 }
23512
23513 return setSessionTokenAsync;
23514 }();
23515
23516 _proto.getSessionToken = /*#__PURE__*/function () {
23517 var _getSessionToken = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee2() {
23518 var _ref2,
23519 _ref2$autoRefresh,
23520 autoRefresh,
23521 _ref3,
23522 value,
23523 originalValue,
23524 _yield$this$setSessio,
23525 newValue,
23526 _args2 = arguments;
23527
23528 return regenerator.wrap(function _callee2$(_context2) {
23529 while (1) {
23530 switch (_context2.prev = _context2.next) {
23531 case 0:
23532 _ref2 = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {}, _ref2$autoRefresh = _ref2.autoRefresh, autoRefresh = _ref2$autoRefresh === void 0 ? true : _ref2$autoRefresh;
23533 debug$a('get session token');
23534
23535 if (this._onBeforeGetSessionToken) {
23536 this._onBeforeGetSessionToken(this);
23537 }
23538
23539 _context2.t0 = this._sessionToken;
23540
23541 if (_context2.t0) {
23542 _context2.next = 8;
23543 break;
23544 }
23545
23546 _context2.next = 7;
23547 return this._pendingSessionTokenPromise;
23548
23549 case 7:
23550 _context2.t0 = _context2.sent;
23551
23552 case 8:
23553 _ref3 = _context2.t0;
23554 value = _ref3.value;
23555 originalValue = _ref3.originalValue;
23556
23557 if (!(value === Expirable.EXPIRED && autoRefresh && this.refresh)) {
23558 _context2.next = 19;
23559 break;
23560 }
23561
23562 debug$a('refresh expired session token');
23563 _context2.next = 15;
23564 return this.setSessionTokenAsync(this.refresh(this, originalValue));
23565
23566 case 15:
23567 _yield$this$setSessio = _context2.sent;
23568 newValue = _yield$this$setSessio.value;
23569 debug$a('session token', newValue);
23570 return _context2.abrupt("return", newValue);
23571
23572 case 19:
23573 debug$a('session token', value);
23574 return _context2.abrupt("return", value);
23575
23576 case 21:
23577 case "end":
23578 return _context2.stop();
23579 }
23580 }
23581 }, _callee2, this);
23582 }));
23583
23584 function getSessionToken() {
23585 return _getSessionToken.apply(this, arguments);
23586 }
23587
23588 return getSessionToken;
23589 }();
23590
23591 _proto.revoke = function revoke() {
23592 if (this._sessionToken) this._sessionToken.expiredAt = -1;
23593 };
23594
23595 return SessionManager;
23596 }();
23597
23598 var _dec$2, _dec2, _class$3;
23599
23600 function ownKeys$8(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
23601
23602 function _objectSpread$8(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$8(Object(source), true).forEach(function (key) { defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$8(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
23603 var debug$b = browser('LC:IMClient');
23604 var INVITED$1 = INVITED,
23605 KICKED$1 = KICKED,
23606 MEMBERS_JOINED$1 = MEMBERS_JOINED,
23607 MEMBERS_LEFT$1 = MEMBERS_LEFT,
23608 MEMBER_INFO_UPDATED$1 = MEMBER_INFO_UPDATED,
23609 BLOCKED$1 = BLOCKED,
23610 UNBLOCKED$1 = UNBLOCKED,
23611 MEMBERS_BLOCKED$1 = MEMBERS_BLOCKED,
23612 MEMBERS_UNBLOCKED$1 = MEMBERS_UNBLOCKED,
23613 MUTED$1 = MUTED,
23614 UNMUTED$1 = UNMUTED,
23615 MEMBERS_MUTED$1 = MEMBERS_MUTED,
23616 MEMBERS_UNMUTED$1 = MEMBERS_UNMUTED,
23617 MESSAGE$2 = MESSAGE$1,
23618 UNREAD_MESSAGES_COUNT_UPDATE$1 = UNREAD_MESSAGES_COUNT_UPDATE,
23619 CLOSE$1 = CLOSE,
23620 CONFLICT$1 = CONFLICT,
23621 UNHANDLED_MESSAGE$1 = UNHANDLED_MESSAGE,
23622 CONVERSATION_INFO_UPDATED$1 = CONVERSATION_INFO_UPDATED,
23623 MESSAGE_RECALL$1 = MESSAGE_RECALL,
23624 MESSAGE_UPDATE$1 = MESSAGE_UPDATE,
23625 INFO_UPDATED$1 = INFO_UPDATED;
23626
23627 var isTemporaryConversatrionId = function isTemporaryConversatrionId(id) {
23628 return /^_tmp:/.test(id);
23629 };
23630 /**
23631 * 1 patch-msg
23632 * 1 temp-conv-msg
23633 * 0 auto-bind-deviceid-and-installation
23634 * 1 transient-msg-ack
23635 * 1 keep-notification
23636 * 1 partial-failed-msg
23637 * 0 group-chat-rcp
23638 * 1 omit-peer-id
23639 * @ignore
23640 */
23641
23642
23643 var configBitmap = 187;
23644 var IMClient = (_dec$2 = throttle(1000), _dec2 = throttle(1000), (_class$3 = /*#__PURE__*/function (_EventEmitter) {
23645 inheritsLoose(IMClient, _EventEmitter);
23646
23647 /**
23648 * 无法直接实例化,请使用 {@link Realtime#createIMClient} 创建新的 IMClient。
23649 *
23650 * @extends EventEmitter
23651 */
23652 function IMClient(id) {
23653 var _this;
23654
23655 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
23656 var props = arguments.length > 2 ? arguments[2] : undefined;
23657
23658 if (!(id === undefined || typeof id === 'string')) {
23659 throw new TypeError("Client id [".concat(id, "] is not a String"));
23660 }
23661
23662 _this = _EventEmitter.call(this) || this;
23663 Object.assign(assertThisInitialized(_this), {
23664 /**
23665 * @var id {String} 客户端 id
23666 * @memberof IMClient#
23667 */
23668 id: id,
23669 options: options
23670 }, props);
23671
23672 if (!_this._messageParser) {
23673 throw new Error('IMClient must be initialized with a MessageParser');
23674 }
23675
23676 _this._conversationCache = new Cache("client:".concat(_this.id));
23677 _this._ackMessageBuffer = {};
23678 internal(assertThisInitialized(_this)).lastPatchTime = Date.now();
23679 internal(assertThisInitialized(_this)).lastNotificationTime = undefined;
23680 internal(assertThisInitialized(_this))._eventemitter = new eventemitter3();
23681
23682 if (debug$b.enabled) {
23683 values_1(IMEvent).forEach(function (event) {
23684 return _this.on(event, function () {
23685 for (var _len = arguments.length, payload = new Array(_len), _key = 0; _key < _len; _key++) {
23686 payload[_key] = arguments[_key];
23687 }
23688
23689 return _this._debug("".concat(event, " event emitted. %o"), payload);
23690 });
23691 });
23692 } // onIMClientCreate hook
23693
23694
23695 applyDecorators(_this._plugins.onIMClientCreate, assertThisInitialized(_this));
23696 return _this;
23697 }
23698
23699 var _proto = IMClient.prototype;
23700
23701 _proto._debug = function _debug() {
23702 for (var _len2 = arguments.length, params = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
23703 params[_key2] = arguments[_key2];
23704 }
23705
23706 debug$b.apply(void 0, params.concat(["[".concat(this.id, "]")]));
23707 }
23708 /**
23709 * @override
23710 * @private
23711 */
23712 ;
23713
23714 _proto._dispatchCommand =
23715 /*#__PURE__*/
23716 function () {
23717 var _dispatchCommand2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee(command) {
23718 return regenerator.wrap(function _callee$(_context) {
23719 while (1) {
23720 switch (_context.prev = _context.next) {
23721 case 0:
23722 this._debug(trim(command), 'received');
23723
23724 if (command.serverTs && command.notificationType === 1) {
23725 internal(this).lastNotificationTime = getTime(decodeDate(command.serverTs));
23726 }
23727
23728 _context.t0 = command.cmd;
23729 _context.next = _context.t0 === CommandType.conv ? 5 : _context.t0 === CommandType.direct ? 6 : _context.t0 === CommandType.session ? 7 : _context.t0 === CommandType.unread ? 8 : _context.t0 === CommandType.rcp ? 9 : _context.t0 === CommandType.patch ? 10 : 11;
23730 break;
23731
23732 case 5:
23733 return _context.abrupt("return", this._dispatchConvMessage(command));
23734
23735 case 6:
23736 return _context.abrupt("return", this._dispatchDirectMessage(command));
23737
23738 case 7:
23739 return _context.abrupt("return", this._dispatchSessionMessage(command));
23740
23741 case 8:
23742 return _context.abrupt("return", this._dispatchUnreadMessage(command));
23743
23744 case 9:
23745 return _context.abrupt("return", this._dispatchRcpMessage(command));
23746
23747 case 10:
23748 return _context.abrupt("return", this._dispatchPatchMessage(command));
23749
23750 case 11:
23751 return _context.abrupt("return", this.emit(UNHANDLED_MESSAGE$1, command));
23752
23753 case 12:
23754 case "end":
23755 return _context.stop();
23756 }
23757 }
23758 }, _callee, this);
23759 }));
23760
23761 function _dispatchCommand(_x) {
23762 return _dispatchCommand2.apply(this, arguments);
23763 }
23764
23765 return _dispatchCommand;
23766 }();
23767
23768 _proto._dispatchSessionMessage = /*#__PURE__*/function () {
23769 var _dispatchSessionMessage2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee2(message) {
23770 var _message$sessionMessa, code, reason;
23771
23772 return regenerator.wrap(function _callee2$(_context2) {
23773 while (1) {
23774 switch (_context2.prev = _context2.next) {
23775 case 0:
23776 _message$sessionMessa = message.sessionMessage, code = _message$sessionMessa.code, reason = _message$sessionMessa.reason;
23777 _context2.t0 = message.op;
23778 _context2.next = _context2.t0 === OpType.closed ? 4 : 8;
23779 break;
23780
23781 case 4:
23782 internal(this)._eventemitter.emit('close');
23783
23784 if (!(code === ErrorCode.SESSION_CONFLICT)) {
23785 _context2.next = 7;
23786 break;
23787 }
23788
23789 return _context2.abrupt("return", this.emit(CONFLICT$1, {
23790 reason: reason
23791 }));
23792
23793 case 7:
23794 return _context2.abrupt("return", this.emit(CLOSE$1, {
23795 code: code,
23796 reason: reason
23797 }));
23798
23799 case 8:
23800 this.emit(UNHANDLED_MESSAGE$1, message);
23801 throw new Error('Unrecognized session command');
23802
23803 case 10:
23804 case "end":
23805 return _context2.stop();
23806 }
23807 }
23808 }, _callee2, this);
23809 }));
23810
23811 function _dispatchSessionMessage(_x2) {
23812 return _dispatchSessionMessage2.apply(this, arguments);
23813 }
23814
23815 return _dispatchSessionMessage;
23816 }();
23817
23818 _proto._dispatchUnreadMessage = function _dispatchUnreadMessage(_ref) {
23819 var _this2 = this;
23820
23821 var _ref$unreadMessage = _ref.unreadMessage,
23822 convs = _ref$unreadMessage.convs,
23823 notifTime = _ref$unreadMessage.notifTime;
23824 internal(this).lastUnreadNotifTime = notifTime; // ensure all converstions are cached
23825
23826 return this.getConversations(convs.map(function (conv) {
23827 return conv.cid;
23828 })).then(function () {
23829 return (// update conversations data
23830 Promise.all(convs.map(function (_ref2) {
23831 var cid = _ref2.cid,
23832 unread = _ref2.unread,
23833 mid = _ref2.mid,
23834 ts = _ref2.timestamp,
23835 from = _ref2.from,
23836 data = _ref2.data,
23837 binaryMsg = _ref2.binaryMsg,
23838 patchTimestamp = _ref2.patchTimestamp,
23839 mentioned = _ref2.mentioned;
23840
23841 var conversation = _this2._conversationCache.get(cid); // deleted conversation
23842
23843
23844 if (!conversation) return null;
23845 var timestamp;
23846
23847 if (ts) {
23848 timestamp = decodeDate(ts);
23849 conversation.lastMessageAt = timestamp; // eslint-disable-line no-param-reassign
23850 }
23851
23852 return (mid ? _this2._messageParser.parse(binaryMsg || data).then(function (message) {
23853 var messageProps = {
23854 id: mid,
23855 cid: cid,
23856 timestamp: timestamp,
23857 updatedAt: patchTimestamp,
23858 from: from
23859 };
23860 Object.assign(message, messageProps);
23861 conversation.lastMessage = message; // eslint-disable-line no-param-reassign
23862 }) : Promise.resolve()).then(function () {
23863 conversation._setUnreadMessagesMentioned(mentioned);
23864
23865 var countNotUpdated = unread === internal(conversation).unreadMessagesCount;
23866 if (countNotUpdated) return null; // to be filtered
23867 // manipulate internal property directly to skip unreadmessagescountupdate event
23868
23869 internal(conversation).unreadMessagesCount = unread;
23870 return conversation;
23871 }); // filter conversations without unread count update
23872 })).then(function (conversations) {
23873 return conversations.filter(function (conversation) {
23874 return conversation;
23875 });
23876 })
23877 );
23878 }).then(function (conversations) {
23879 if (conversations.length) {
23880 /**
23881 * 未读消息数目更新
23882 * @event IMClient#UNREAD_MESSAGES_COUNT_UPDATE
23883 * @since 3.4.0
23884 * @param {Conversation[]} conversations 未读消息数目有更新的对话列表
23885 */
23886 _this2.emit(UNREAD_MESSAGES_COUNT_UPDATE$1, conversations);
23887 }
23888 });
23889 };
23890
23891 _proto._dispatchRcpMessage = /*#__PURE__*/function () {
23892 var _dispatchRcpMessage2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee3(message) {
23893 var rcpMessage, read, conversationId, messageId, timestamp, conversation;
23894 return regenerator.wrap(function _callee3$(_context3) {
23895 while (1) {
23896 switch (_context3.prev = _context3.next) {
23897 case 0:
23898 rcpMessage = message.rcpMessage, read = message.rcpMessage.read;
23899 conversationId = rcpMessage.cid;
23900 messageId = rcpMessage.id;
23901 timestamp = decodeDate(rcpMessage.t);
23902 conversation = this._conversationCache.get(conversationId); // conversation not cached means the client does not send the message
23903 // during this session
23904
23905 if (conversation) {
23906 _context3.next = 7;
23907 break;
23908 }
23909
23910 return _context3.abrupt("return");
23911
23912 case 7:
23913 conversation._handleReceipt({
23914 messageId: messageId,
23915 timestamp: timestamp,
23916 read: read
23917 });
23918
23919 case 8:
23920 case "end":
23921 return _context3.stop();
23922 }
23923 }
23924 }, _callee3, this);
23925 }));
23926
23927 function _dispatchRcpMessage(_x3) {
23928 return _dispatchRcpMessage2.apply(this, arguments);
23929 }
23930
23931 return _dispatchRcpMessage;
23932 }();
23933
23934 _proto._dispatchPatchMessage = function _dispatchPatchMessage(_ref3) {
23935 var _this3 = this;
23936
23937 var patches = _ref3.patchMessage.patches;
23938 // ensure all converstions are cached
23939 return this.getConversations(patches.map(function (patch) {
23940 return patch.cid;
23941 })).then(function () {
23942 return Promise.all(patches.map(function (_ref4) {
23943 var cid = _ref4.cid,
23944 mid = _ref4.mid,
23945 timestamp = _ref4.timestamp,
23946 recall = _ref4.recall,
23947 data = _ref4.data,
23948 patchTimestamp = _ref4.patchTimestamp,
23949 from = _ref4.from,
23950 binaryMsg = _ref4.binaryMsg,
23951 mentionAll = _ref4.mentionAll,
23952 mentionPids = _ref4.mentionPids,
23953 patchCode = _ref4.patchCode,
23954 patchReason = _ref4.patchReason;
23955
23956 var conversation = _this3._conversationCache.get(cid); // deleted conversation
23957
23958
23959 if (!conversation) return null;
23960 return _this3._messageParser.parse(binaryMsg || data).then(function (message) {
23961 var patchTime = getTime(decodeDate(patchTimestamp));
23962 var messageProps = {
23963 id: mid,
23964 cid: cid,
23965 timestamp: timestamp,
23966 updatedAt: patchTime,
23967 from: from,
23968 mentionList: mentionPids,
23969 mentionedAll: mentionAll
23970 };
23971 Object.assign(message, messageProps);
23972
23973 message._setStatus(MessageStatus.SENT);
23974
23975 message._updateMentioned(_this3.id);
23976
23977 if (internal(_this3).lastPatchTime < patchTime) {
23978 internal(_this3).lastPatchTime = patchTime;
23979 } // update conversation lastMessage
23980
23981
23982 if (conversation.lastMessage && conversation.lastMessage.id === mid) {
23983 conversation.lastMessage = message; // eslint-disable-line no-param-reassign
23984 }
23985
23986 var reason;
23987
23988 if (patchCode) {
23989 reason = {
23990 code: patchCode.toNumber(),
23991 detail: patchReason
23992 };
23993 }
23994
23995 if (recall) {
23996 /**
23997 * 消息被撤回
23998 * @event IMClient#MESSAGE_RECALL
23999 * @param {AVMessage} message 被撤回的消息
24000 * @param {ConversationBase} conversation 消息所在的会话
24001 * @param {PatchReason} [reason] 撤回的原因,不存在代表是发送者主动撤回
24002 */
24003 _this3.emit(MESSAGE_RECALL$1, message, conversation, reason);
24004 /**
24005 * 消息被撤回
24006 * @event ConversationBase#MESSAGE_RECALL
24007 * @param {AVMessage} message 被撤回的消息
24008 * @param {PatchReason} [reason] 撤回的原因,不存在代表是发送者主动撤回
24009 */
24010
24011
24012 conversation.emit(MESSAGE_RECALL$1, message, reason);
24013 } else {
24014 /**
24015 * 消息被修改
24016 * @event IMClient#MESSAGE_UPDATE
24017 * @param {AVMessage} message 被修改的消息
24018 * @param {ConversationBase} conversation 消息所在的会话
24019 * @param {PatchReason} [reason] 修改的原因,不存在代表是发送者主动修改
24020 */
24021 _this3.emit(MESSAGE_UPDATE$1, message, conversation, reason);
24022 /**
24023 * 消息被修改
24024 * @event ConversationBase#MESSAGE_UPDATE
24025 * @param {AVMessage} message 被修改的消息
24026 * @param {PatchReason} [reason] 修改的原因,不存在代表是发送者主动修改
24027 */
24028
24029
24030 conversation.emit(MESSAGE_UPDATE$1, message, reason);
24031 }
24032 });
24033 }));
24034 });
24035 };
24036
24037 _proto._dispatchConvMessage = /*#__PURE__*/function () {
24038 var _dispatchConvMessage2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee4(message) {
24039 var convMessage, _message$convMessage, initBy, m, info, attr, conversation, payload, _payload, _payload2, _payload3, _payload4, _payload5, _payload6, _payload7, _payload8, _payload9, _payload10, _payload11, pid, role, _internal, memberInfoMap, memberInfo, _payload12, attributes, _payload13;
24040
24041 return regenerator.wrap(function _callee4$(_context4) {
24042 while (1) {
24043 switch (_context4.prev = _context4.next) {
24044 case 0:
24045 convMessage = message.convMessage, _message$convMessage = message.convMessage, initBy = _message$convMessage.initBy, m = _message$convMessage.m, info = _message$convMessage.info, attr = _message$convMessage.attr;
24046 _context4.next = 3;
24047 return this.getConversation(convMessage.cid);
24048
24049 case 3:
24050 conversation = _context4.sent;
24051 _context4.t0 = message.op;
24052 _context4.next = _context4.t0 === OpType.joined ? 7 : _context4.t0 === OpType.left ? 12 : _context4.t0 === OpType.members_joined ? 17 : _context4.t0 === OpType.members_left ? 22 : _context4.t0 === OpType.members_blocked ? 27 : _context4.t0 === OpType.members_unblocked ? 31 : _context4.t0 === OpType.blocked ? 35 : _context4.t0 === OpType.unblocked ? 39 : _context4.t0 === OpType.members_shutuped ? 43 : _context4.t0 === OpType.members_unshutuped ? 47 : _context4.t0 === OpType.shutuped ? 51 : _context4.t0 === OpType.unshutuped ? 55 : _context4.t0 === OpType.member_info_changed ? 59 : _context4.t0 === OpType.updated ? 71 : 77;
24053 break;
24054
24055 case 7:
24056 conversation._addMembers([this.id]);
24057
24058 payload = {
24059 invitedBy: initBy
24060 };
24061 /**
24062 * 当前用户被添加至某个对话
24063 * @event IMClient#INVITED
24064 * @param {Object} payload
24065 * @param {String} payload.invitedBy 邀请者 id
24066 * @param {ConversationBase} conversation
24067 */
24068
24069 this.emit(INVITED$1, payload, conversation);
24070 /**
24071 * 当前用户被添加至当前对话
24072 * @event ConversationBase#INVITED
24073 * @param {Object} payload
24074 * @param {String} payload.invitedBy 该移除操作的发起者 id
24075 */
24076
24077 conversation.emit(INVITED$1, payload);
24078 return _context4.abrupt("return");
24079
24080 case 12:
24081 conversation._removeMembers([this.id]);
24082
24083 _payload = {
24084 kickedBy: initBy
24085 };
24086 /**
24087 * 当前用户被从某个对话中移除
24088 * @event IMClient#KICKED
24089 * @param {Object} payload
24090 * @param {String} payload.kickedBy 该移除操作的发起者 id
24091 * @param {ConversationBase} conversation
24092 */
24093
24094 this.emit(KICKED$1, _payload, conversation);
24095 /**
24096 * 当前用户被从当前对话中移除
24097 * @event ConversationBase#KICKED
24098 * @param {Object} payload
24099 * @param {String} payload.kickedBy 该移除操作的发起者 id
24100 */
24101
24102 conversation.emit(KICKED$1, _payload);
24103 return _context4.abrupt("return");
24104
24105 case 17:
24106 conversation._addMembers(m);
24107
24108 _payload2 = {
24109 invitedBy: initBy,
24110 members: m
24111 };
24112 /**
24113 * 有用户被添加至某个对话
24114 * @event IMClient#MEMBERS_JOINED
24115 * @param {Object} payload
24116 * @param {String[]} payload.members 被添加的用户 id 列表
24117 * @param {String} payload.invitedBy 邀请者 id
24118 * @param {ConversationBase} conversation
24119 */
24120
24121 this.emit(MEMBERS_JOINED$1, _payload2, conversation);
24122 /**
24123 * 有成员被添加至当前对话
24124 * @event ConversationBase#MEMBERS_JOINED
24125 * @param {Object} payload
24126 * @param {String[]} payload.members 被添加的成员 id 列表
24127 * @param {String} payload.invitedBy 邀请者 id
24128 */
24129
24130 conversation.emit(MEMBERS_JOINED$1, _payload2);
24131 return _context4.abrupt("return");
24132
24133 case 22:
24134 conversation._removeMembers(m);
24135
24136 _payload3 = {
24137 kickedBy: initBy,
24138 members: m
24139 };
24140 /**
24141 * 有成员被从某个对话中移除
24142 * @event IMClient#MEMBERS_LEFT
24143 * @param {Object} payload
24144 * @param {String[]} payload.members 被移除的成员 id 列表
24145 * @param {String} payload.kickedBy 该移除操作的发起者 id
24146 * @param {ConversationBase} conversation
24147 */
24148
24149 this.emit(MEMBERS_LEFT$1, _payload3, conversation);
24150 /**
24151 * 有成员被从当前对话中移除
24152 * @event ConversationBase#MEMBERS_LEFT
24153 * @param {Object} payload
24154 * @param {String[]} payload.members 被移除的成员 id 列表
24155 * @param {String} payload.kickedBy 该移除操作的发起者 id
24156 */
24157
24158 conversation.emit(MEMBERS_LEFT$1, _payload3);
24159 return _context4.abrupt("return");
24160
24161 case 27:
24162 _payload4 = {
24163 blockedBy: initBy,
24164 members: m
24165 };
24166 /**
24167 * 有成员被加入某个对话的黑名单
24168 * @event IMClient#MEMBERS_BLOCKED
24169 * @param {Object} payload
24170 * @param {String[]} payload.members 成员 id 列表
24171 * @param {String} payload.blockedBy 该操作的发起者 id
24172 * @param {ConversationBase} conversation
24173 */
24174
24175 this.emit(MEMBERS_BLOCKED$1, _payload4, conversation);
24176 /**
24177 * 有成员被加入当前对话的黑名单
24178 * @event ConversationBase#MEMBERS_BLOCKED
24179 * @param {Object} payload
24180 * @param {String[]} payload.members 成员 id 列表
24181 * @param {String} payload.blockedBy 该操作的发起者 id
24182 */
24183
24184 conversation.emit(MEMBERS_BLOCKED$1, _payload4);
24185 return _context4.abrupt("return");
24186
24187 case 31:
24188 _payload5 = {
24189 unblockedBy: initBy,
24190 members: m
24191 };
24192 /**
24193 * 有成员被移出某个对话的黑名单
24194 * @event IMClient#MEMBERS_UNBLOCKED
24195 * @param {Object} payload
24196 * @param {String[]} payload.members 成员 id 列表
24197 * @param {String} payload.unblockedBy 该操作的发起者 id
24198 * @param {ConversationBase} conversation
24199 */
24200
24201 this.emit(MEMBERS_UNBLOCKED$1, _payload5, conversation);
24202 /**
24203 * 有成员被移出当前对话的黑名单
24204 * @event ConversationBase#MEMBERS_UNBLOCKED
24205 * @param {Object} payload
24206 * @param {String[]} payload.members 成员 id 列表
24207 * @param {String} payload.unblockedBy 该操作的发起者 id
24208 */
24209
24210 conversation.emit(MEMBERS_UNBLOCKED$1, _payload5);
24211 return _context4.abrupt("return");
24212
24213 case 35:
24214 _payload6 = {
24215 blockedBy: initBy
24216 };
24217 /**
24218 * 当前用户被加入某个对话的黑名单
24219 * @event IMClient#BLOCKED
24220 * @param {Object} payload
24221 * @param {String} payload.blockedBy 该操作的发起者 id
24222 * @param {ConversationBase} conversation
24223 */
24224
24225 this.emit(BLOCKED$1, _payload6, conversation);
24226 /**
24227 * 当前用户被加入当前对话的黑名单
24228 * @event ConversationBase#BLOCKED
24229 * @param {Object} payload
24230 * @param {String} payload.blockedBy 该操作的发起者 id
24231 */
24232
24233 conversation.emit(BLOCKED$1, _payload6);
24234 return _context4.abrupt("return");
24235
24236 case 39:
24237 _payload7 = {
24238 unblockedBy: initBy
24239 };
24240 /**
24241 * 当前用户被移出某个对话的黑名单
24242 * @event IMClient#UNBLOCKED
24243 * @param {Object} payload
24244 * @param {String} payload.unblockedBy 该操作的发起者 id
24245 * @param {ConversationBase} conversation
24246 */
24247
24248 this.emit(UNBLOCKED$1, _payload7, conversation);
24249 /**
24250 * 当前用户被移出当前对话的黑名单
24251 * @event ConversationBase#UNBLOCKED
24252 * @param {Object} payload
24253 * @param {String} payload.unblockedBy 该操作的发起者 id
24254 */
24255
24256 conversation.emit(UNBLOCKED$1, _payload7);
24257 return _context4.abrupt("return");
24258
24259 case 43:
24260 _payload8 = {
24261 mutedBy: initBy,
24262 members: m
24263 };
24264 /**
24265 * 有成员在某个对话中被禁言
24266 * @event IMClient#MEMBERS_MUTED
24267 * @param {Object} payload
24268 * @param {String[]} payload.members 成员 id 列表
24269 * @param {String} payload.mutedBy 该操作的发起者 id
24270 * @param {ConversationBase} conversation
24271 */
24272
24273 this.emit(MEMBERS_MUTED$1, _payload8, conversation);
24274 /**
24275 * 有成员在当前对话中被禁言
24276 * @event ConversationBase#MEMBERS_MUTED
24277 * @param {Object} payload
24278 * @param {String[]} payload.members 成员 id 列表
24279 * @param {String} payload.mutedBy 该操作的发起者 id
24280 */
24281
24282 conversation.emit(MEMBERS_MUTED$1, _payload8);
24283 return _context4.abrupt("return");
24284
24285 case 47:
24286 _payload9 = {
24287 unmutedBy: initBy,
24288 members: m
24289 };
24290 /**
24291 * 有成员在某个对话中被解除禁言
24292 * @event IMClient#MEMBERS_UNMUTED
24293 * @param {Object} payload
24294 * @param {String[]} payload.members 成员 id 列表
24295 * @param {String} payload.unmutedBy 该操作的发起者 id
24296 * @param {ConversationBase} conversation
24297 */
24298
24299 this.emit(MEMBERS_UNMUTED$1, _payload9, conversation);
24300 /**
24301 * 有成员在当前对话中被解除禁言
24302 * @event ConversationBase#MEMBERS_UNMUTED
24303 * @param {Object} payload
24304 * @param {String[]} payload.members 成员 id 列表
24305 * @param {String} payload.unmutedBy 该操作的发起者 id
24306 */
24307
24308 conversation.emit(MEMBERS_UNMUTED$1, _payload9);
24309 return _context4.abrupt("return");
24310
24311 case 51:
24312 _payload10 = {
24313 mutedBy: initBy
24314 };
24315 /**
24316 * 有成员在某个对话中被禁言
24317 * @event IMClient#MUTED
24318 * @param {Object} payload
24319 * @param {String} payload.mutedBy 该操作的发起者 id
24320 * @param {ConversationBase} conversation
24321 */
24322
24323 this.emit(MUTED$1, _payload10, conversation);
24324 /**
24325 * 有成员在当前对话中被禁言
24326 * @event ConversationBase#MUTED
24327 * @param {Object} payload
24328 * @param {String} payload.mutedBy 该操作的发起者 id
24329 */
24330
24331 conversation.emit(MUTED$1, _payload10);
24332 return _context4.abrupt("return");
24333
24334 case 55:
24335 _payload11 = {
24336 unmutedBy: initBy
24337 };
24338 /**
24339 * 有成员在某个对话中被解除禁言
24340 * @event IMClient#UNMUTED
24341 * @param {Object} payload
24342 * @param {String} payload.unmutedBy 该操作的发起者 id
24343 * @param {ConversationBase} conversation
24344 */
24345
24346 this.emit(UNMUTED$1, _payload11, conversation);
24347 /**
24348 * 有成员在当前对话中被解除禁言
24349 * @event ConversationBase#UNMUTED
24350 * @param {Object} payload
24351 * @param {String} payload.unmutedBy 该操作的发起者 id
24352 */
24353
24354 conversation.emit(UNMUTED$1, _payload11);
24355 return _context4.abrupt("return");
24356
24357 case 59:
24358 pid = info.pid, role = info.role;
24359 _internal = internal(conversation), memberInfoMap = _internal.memberInfoMap; // 如果不存在缓存,且不是 role 的更新,则不通知
24360
24361 if (!(!memberInfoMap && !role)) {
24362 _context4.next = 63;
24363 break;
24364 }
24365
24366 return _context4.abrupt("return");
24367
24368 case 63:
24369 _context4.next = 65;
24370 return conversation.getMemberInfo(pid);
24371
24372 case 65:
24373 memberInfo = _context4.sent;
24374 internal(memberInfo).role = role;
24375 _payload12 = {
24376 member: pid,
24377 memberInfo: memberInfo,
24378 updatedBy: initBy
24379 };
24380 /**
24381 * 有成员的对话信息被更新
24382 * @event IMClient#MEMBER_INFO_UPDATED
24383 * @param {Object} payload
24384 * @param {String} payload.member 被更新对话信息的成员 id
24385 * @param {ConversationMumberInfo} payload.memberInfo 被更新的成员对话信息
24386 * @param {String} payload.updatedBy 该操作的发起者 id
24387 * @param {ConversationBase} conversation
24388 */
24389
24390 this.emit(MEMBER_INFO_UPDATED$1, _payload12, conversation);
24391 /**
24392 * 有成员的对话信息被更新
24393 * @event ConversationBase#MEMBER_INFO_UPDATED
24394 * @param {Object} payload
24395 * @param {String} payload.member 被更新对话信息的成员 id
24396 * @param {ConversationMumberInfo} payload.memberInfo 被更新的成员对话信息
24397 * @param {String} payload.updatedBy 该操作的发起者 id
24398 */
24399
24400 conversation.emit(MEMBER_INFO_UPDATED$1, _payload12);
24401 return _context4.abrupt("return");
24402
24403 case 71:
24404 attributes = decode(JSON.parse(attr.data));
24405
24406 conversation._updateServerAttributes(attributes);
24407
24408 _payload13 = {
24409 attributes: attributes,
24410 updatedBy: initBy
24411 };
24412 /**
24413 * 该对话信息被更新
24414 * @event IMClient#CONVERSATION_INFO_UPDATED
24415 * @param {Object} payload
24416 * @param {Object} payload.attributes 被更新的属性
24417 * @param {String} payload.updatedBy 该操作的发起者 id
24418 * @param {ConversationBase} conversation
24419 */
24420
24421 this.emit(CONVERSATION_INFO_UPDATED$1, _payload13, conversation);
24422 /**
24423 * 有对话信息被更新
24424 * @event ConversationBase#INFO_UPDATED
24425 * @param {Object} payload
24426 * @param {Object} payload.attributes 被更新的属性
24427 * @param {String} payload.updatedBy 该操作的发起者 id
24428 */
24429
24430 conversation.emit(INFO_UPDATED$1, _payload13);
24431 return _context4.abrupt("return");
24432
24433 case 77:
24434 this.emit(UNHANDLED_MESSAGE$1, message);
24435 throw new Error('Unrecognized conversation command');
24436
24437 case 79:
24438 case "end":
24439 return _context4.stop();
24440 }
24441 }
24442 }, _callee4, this);
24443 }));
24444
24445 function _dispatchConvMessage(_x4) {
24446 return _dispatchConvMessage2.apply(this, arguments);
24447 }
24448
24449 return _dispatchConvMessage;
24450 }();
24451
24452 _proto._dispatchDirectMessage = function _dispatchDirectMessage(originalMessage) {
24453 var _this4 = this;
24454
24455 var directMessage = originalMessage.directMessage,
24456 _originalMessage$dire = originalMessage.directMessage,
24457 id = _originalMessage$dire.id,
24458 cid = _originalMessage$dire.cid,
24459 fromPeerId = _originalMessage$dire.fromPeerId,
24460 timestamp = _originalMessage$dire.timestamp,
24461 _transient = _originalMessage$dire["transient"],
24462 patchTimestamp = _originalMessage$dire.patchTimestamp,
24463 mentionPids = _originalMessage$dire.mentionPids,
24464 mentionAll = _originalMessage$dire.mentionAll,
24465 binaryMsg = _originalMessage$dire.binaryMsg,
24466 msg = _originalMessage$dire.msg;
24467 var content = binaryMsg ? binaryMsg.toArrayBuffer() : msg;
24468 return Promise.all([this.getConversation(directMessage.cid), this._messageParser.parse(content)]).then(function (_ref5) {
24469 var _ref6 = slicedToArray(_ref5, 2),
24470 conversation = _ref6[0],
24471 message = _ref6[1];
24472
24473 // deleted conversation
24474 if (!conversation) return undefined;
24475 var messageProps = {
24476 id: id,
24477 cid: cid,
24478 timestamp: timestamp,
24479 updatedAt: patchTimestamp,
24480 from: fromPeerId,
24481 mentionList: mentionPids,
24482 mentionedAll: mentionAll
24483 };
24484 Object.assign(message, messageProps);
24485
24486 message._updateMentioned(_this4.id);
24487
24488 message._setStatus(MessageStatus.SENT); // filter outgoing message sent from another device
24489
24490
24491 if (message.from !== _this4.id) {
24492 if (!(_transient || conversation["transient"])) {
24493 _this4._sendAck(message);
24494 }
24495 }
24496
24497 return _this4._dispatchParsedMessage(message, conversation);
24498 });
24499 };
24500
24501 _proto._dispatchParsedMessage = function _dispatchParsedMessage(message, conversation) {
24502 var _this5 = this;
24503
24504 // beforeMessageDispatch hook
24505 return applyDispatcher(this._plugins.beforeMessageDispatch, [message, conversation]).then(function (shouldDispatch) {
24506 if (shouldDispatch === false) return;
24507 conversation.lastMessage = message; // eslint-disable-line no-param-reassign
24508
24509 conversation.lastMessageAt = message.timestamp; // eslint-disable-line no-param-reassign
24510 // filter outgoing message sent from another device
24511
24512 if (message.from !== _this5.id) {
24513 conversation.unreadMessagesCount += 1; // eslint-disable-line no-param-reassign
24514
24515 if (message.mentioned) conversation._setUnreadMessagesMentioned(true);
24516 }
24517 /**
24518 * 当前用户收到消息
24519 * @event IMClient#MESSAGE
24520 * @param {Message} message
24521 * @param {ConversationBase} conversation 收到消息的对话
24522 */
24523
24524
24525 _this5.emit(MESSAGE$2, message, conversation);
24526 /**
24527 * 当前对话收到消息
24528 * @event ConversationBase#MESSAGE
24529 * @param {Message} message
24530 */
24531
24532
24533 conversation.emit(MESSAGE$2, message);
24534 });
24535 };
24536
24537 _proto._sendAck = function _sendAck(message) {
24538 this._debug('send ack for %O', message);
24539
24540 var cid = message.cid;
24541
24542 if (!cid) {
24543 throw new Error('missing cid');
24544 }
24545
24546 if (!this._ackMessageBuffer[cid]) {
24547 this._ackMessageBuffer[cid] = [];
24548 }
24549
24550 this._ackMessageBuffer[cid].push(message);
24551
24552 return this._doSendAck();
24553 } // jsdoc-ignore-start
24554 ;
24555
24556 _proto. // jsdoc-ignore-end
24557 _doSendAck = function _doSendAck() {
24558 var _this6 = this;
24559
24560 // if not connected, just skip everything
24561 if (!this._connection.is('connected')) return;
24562
24563 this._debug('do send ack %O', this._ackMessageBuffer);
24564
24565 Promise.all(Object.keys(this._ackMessageBuffer).map(function (cid) {
24566 var convAckMessages = _this6._ackMessageBuffer[cid];
24567 var timestamps = convAckMessages.map(function (message) {
24568 return message.timestamp;
24569 });
24570 var command = new GenericCommand({
24571 cmd: 'ack',
24572 ackMessage: new AckCommand({
24573 cid: cid,
24574 fromts: Math.min.apply(null, timestamps),
24575 tots: Math.max.apply(null, timestamps)
24576 })
24577 });
24578 delete _this6._ackMessageBuffer[cid];
24579 return _this6._send(command, false)["catch"](function (error) {
24580 _this6._debug('send ack failed: %O', error);
24581
24582 _this6._ackMessageBuffer[cid] = convAckMessages;
24583 });
24584 }));
24585 };
24586
24587 _proto._omitPeerId = function _omitPeerId(value) {
24588 internal(this).peerIdOmittable = value;
24589 };
24590
24591 _proto._send = function _send(cmd) {
24592 var _this$_connection;
24593
24594 var command = cmd;
24595
24596 if (!internal(this).peerIdOmittable && this.id) {
24597 command.peerId = this.id;
24598 }
24599
24600 for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
24601 args[_key3 - 1] = arguments[_key3];
24602 }
24603
24604 return (_this$_connection = this._connection).send.apply(_this$_connection, [command].concat(args));
24605 };
24606
24607 _proto._open = /*#__PURE__*/function () {
24608 var _open2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee5(appId, tag, deviceId) {
24609 var isReconnect,
24610 _internal2,
24611 lastUnreadNotifTime,
24612 lastPatchTime,
24613 lastNotificationTime,
24614 command,
24615 signatureResult,
24616 sessionToken,
24617 resCommand,
24618 _resCommand,
24619 peerId,
24620 sessionMessage,
24621 _resCommand$sessionMe,
24622 token,
24623 tokenTTL,
24624 code,
24625 serverTs,
24626 serverTime,
24627 _args5 = arguments;
24628
24629 return regenerator.wrap(function _callee5$(_context5) {
24630 while (1) {
24631 switch (_context5.prev = _context5.next) {
24632 case 0:
24633 isReconnect = _args5.length > 3 && _args5[3] !== undefined ? _args5[3] : false;
24634
24635 this._debug('open session');
24636
24637 _internal2 = internal(this), lastUnreadNotifTime = _internal2.lastUnreadNotifTime, lastPatchTime = _internal2.lastPatchTime, lastNotificationTime = _internal2.lastNotificationTime;
24638 command = new GenericCommand({
24639 cmd: 'session',
24640 op: 'open',
24641 appId: appId,
24642 peerId: this.id,
24643 sessionMessage: new SessionCommand({
24644 ua: "js/".concat(version),
24645 r: isReconnect,
24646 lastUnreadNotifTime: lastUnreadNotifTime,
24647 lastPatchTime: lastPatchTime,
24648 configBitmap: configBitmap
24649 })
24650 });
24651
24652 if (isReconnect) {
24653 _context5.next = 13;
24654 break;
24655 }
24656
24657 Object.assign(command.sessionMessage, trim({
24658 tag: tag,
24659 deviceId: deviceId
24660 }));
24661
24662 if (!this.options.signatureFactory) {
24663 _context5.next = 11;
24664 break;
24665 }
24666
24667 _context5.next = 9;
24668 return runSignatureFactory(this.options.signatureFactory, [this._identity]);
24669
24670 case 9:
24671 signatureResult = _context5.sent;
24672 Object.assign(command.sessionMessage, keyRemap({
24673 signature: 's',
24674 timestamp: 't',
24675 nonce: 'n'
24676 }, signatureResult));
24677
24678 case 11:
24679 _context5.next = 17;
24680 break;
24681
24682 case 13:
24683 _context5.next = 15;
24684 return this._sessionManager.getSessionToken({
24685 autoRefresh: false
24686 });
24687
24688 case 15:
24689 sessionToken = _context5.sent;
24690
24691 if (sessionToken && sessionToken !== Expirable.EXPIRED) {
24692 Object.assign(command.sessionMessage, {
24693 st: sessionToken
24694 });
24695 }
24696
24697 case 17:
24698 _context5.prev = 17;
24699 _context5.next = 20;
24700 return this._send(command);
24701
24702 case 20:
24703 resCommand = _context5.sent;
24704 _context5.next = 32;
24705 break;
24706
24707 case 23:
24708 _context5.prev = 23;
24709 _context5.t0 = _context5["catch"](17);
24710
24711 if (!(_context5.t0.code === ErrorCode.SESSION_TOKEN_EXPIRED)) {
24712 _context5.next = 31;
24713 break;
24714 }
24715
24716 if (this._sessionManager) {
24717 _context5.next = 28;
24718 break;
24719 }
24720
24721 throw new Error('Unexpected session expiration');
24722
24723 case 28:
24724 debug$b('Session token expired, reopening');
24725
24726 this._sessionManager.revoke();
24727
24728 return _context5.abrupt("return", this._open(appId, tag, deviceId, isReconnect));
24729
24730 case 31:
24731 throw _context5.t0;
24732
24733 case 32:
24734 _resCommand = resCommand, peerId = _resCommand.peerId, sessionMessage = _resCommand.sessionMessage, _resCommand$sessionMe = _resCommand.sessionMessage, token = _resCommand$sessionMe.st, tokenTTL = _resCommand$sessionMe.stTtl, code = _resCommand$sessionMe.code, serverTs = _resCommand.serverTs;
24735
24736 if (!code) {
24737 _context5.next = 35;
24738 break;
24739 }
24740
24741 throw createError(sessionMessage);
24742
24743 case 35:
24744 if (peerId) {
24745 this.id = peerId;
24746 if (!this._identity) this._identity = peerId;
24747
24748 if (token) {
24749 this._sessionManager = this._sessionManager || this._createSessionManager();
24750
24751 this._sessionManager.setSessionToken(token, tokenTTL);
24752 }
24753
24754 serverTime = getTime(decodeDate(serverTs));
24755
24756 if (serverTs) {
24757 internal(this).lastPatchTime = serverTime;
24758 }
24759
24760 if (lastNotificationTime) {
24761 // Do not await for it as this is failable
24762 this._syncNotifications(lastNotificationTime)["catch"](function (error) {
24763 return console.warn('Syncing notifications failed:', error);
24764 });
24765 } else {
24766 // Set timestamp to now for next reconnection
24767 internal(this).lastNotificationTime = serverTime;
24768 }
24769 } else {
24770 console.warn('Unexpected session opened without peerId.');
24771 }
24772
24773 return _context5.abrupt("return", undefined);
24774
24775 case 37:
24776 case "end":
24777 return _context5.stop();
24778 }
24779 }
24780 }, _callee5, this, [[17, 23]]);
24781 }));
24782
24783 function _open(_x5, _x6, _x7) {
24784 return _open2.apply(this, arguments);
24785 }
24786
24787 return _open;
24788 }();
24789
24790 _proto._syncNotifications = /*#__PURE__*/function () {
24791 var _syncNotifications2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee6(timestamp) {
24792 var _this7 = this;
24793
24794 var _yield$this$_fetchNot, hasMore, notifications;
24795
24796 return regenerator.wrap(function _callee6$(_context6) {
24797 while (1) {
24798 switch (_context6.prev = _context6.next) {
24799 case 0:
24800 _context6.next = 2;
24801 return this._fetchNotifications(timestamp);
24802
24803 case 2:
24804 _yield$this$_fetchNot = _context6.sent;
24805 hasMore = _yield$this$_fetchNot.hasMore;
24806 notifications = _yield$this$_fetchNot.notifications;
24807 notifications.forEach(function (notification) {
24808 var cmd = notification.cmd,
24809 op = notification.op,
24810 serverTs = notification.serverTs,
24811 notificationType = notification.notificationType,
24812 payload = objectWithoutProperties(notification, ["cmd", "op", "serverTs", "notificationType"]);
24813
24814 _this7._dispatchCommand(defineProperty({
24815 cmd: CommandType[cmd],
24816 op: OpType[op],
24817 serverTs: serverTs,
24818 notificationType: notificationType
24819 }, "".concat(cmd, "Message"), payload));
24820 });
24821
24822 if (!hasMore) {
24823 _context6.next = 8;
24824 break;
24825 }
24826
24827 return _context6.abrupt("return", this._syncNotifications(internal(this).lastNotificationTime));
24828
24829 case 8:
24830 return _context6.abrupt("return", undefined);
24831
24832 case 9:
24833 case "end":
24834 return _context6.stop();
24835 }
24836 }
24837 }, _callee6, this);
24838 }));
24839
24840 function _syncNotifications(_x8) {
24841 return _syncNotifications2.apply(this, arguments);
24842 }
24843
24844 return _syncNotifications;
24845 }();
24846
24847 _proto._fetchNotifications = /*#__PURE__*/function () {
24848 var _fetchNotifications2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee7(timestamp) {
24849 return regenerator.wrap(function _callee7$(_context7) {
24850 while (1) {
24851 switch (_context7.prev = _context7.next) {
24852 case 0:
24853 return _context7.abrupt("return", this._requestWithSessionToken({
24854 method: 'GET',
24855 path: '/rtm/notifications',
24856 query: {
24857 start_ts: timestamp,
24858 notification_type: 'permanent'
24859 }
24860 }));
24861
24862 case 1:
24863 case "end":
24864 return _context7.stop();
24865 }
24866 }
24867 }, _callee7, this);
24868 }));
24869
24870 function _fetchNotifications(_x9) {
24871 return _fetchNotifications2.apply(this, arguments);
24872 }
24873
24874 return _fetchNotifications;
24875 }();
24876
24877 _proto._createSessionManager = function _createSessionManager() {
24878 var _this8 = this;
24879
24880 debug$b('create SessionManager');
24881 return new SessionManager({
24882 onBeforeGetSessionToken: this._connection.checkConnectionAvailability.bind(this._connection),
24883 refresh: function refresh(manager, expiredSessionToken) {
24884 return manager.setSessionTokenAsync(Promise.resolve(new GenericCommand({
24885 cmd: 'session',
24886 op: 'refresh',
24887 sessionMessage: new SessionCommand({
24888 ua: "js/".concat(version),
24889 st: expiredSessionToken
24890 })
24891 })).then( /*#__PURE__*/function () {
24892 var _ref7 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee8(command) {
24893 var signatureResult;
24894 return regenerator.wrap(function _callee8$(_context8) {
24895 while (1) {
24896 switch (_context8.prev = _context8.next) {
24897 case 0:
24898 if (!_this8.options.signatureFactory) {
24899 _context8.next = 5;
24900 break;
24901 }
24902
24903 _context8.next = 3;
24904 return runSignatureFactory(_this8.options.signatureFactory, [_this8._identity]);
24905
24906 case 3:
24907 signatureResult = _context8.sent;
24908 Object.assign(command.sessionMessage, keyRemap({
24909 signature: 's',
24910 timestamp: 't',
24911 nonce: 'n'
24912 }, signatureResult));
24913
24914 case 5:
24915 return _context8.abrupt("return", command);
24916
24917 case 6:
24918 case "end":
24919 return _context8.stop();
24920 }
24921 }
24922 }, _callee8);
24923 }));
24924
24925 return function (_x10) {
24926 return _ref7.apply(this, arguments);
24927 };
24928 }()).then(_this8._send.bind(_this8)).then(function (_ref8) {
24929 var _ref8$sessionMessage = _ref8.sessionMessage,
24930 token = _ref8$sessionMessage.st,
24931 ttl = _ref8$sessionMessage.stTtl;
24932 return [token, ttl];
24933 }));
24934 }
24935 });
24936 };
24937
24938 _proto._requestWithSessionToken = /*#__PURE__*/function () {
24939 var _requestWithSessionToken2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee9(_ref9) {
24940 var headers, query, params, sessionToken;
24941 return regenerator.wrap(function _callee9$(_context9) {
24942 while (1) {
24943 switch (_context9.prev = _context9.next) {
24944 case 0:
24945 headers = _ref9.headers, query = _ref9.query, params = objectWithoutProperties(_ref9, ["headers", "query"]);
24946 _context9.next = 3;
24947 return this._sessionManager.getSessionToken();
24948
24949 case 3:
24950 sessionToken = _context9.sent;
24951 return _context9.abrupt("return", this._request(_objectSpread$8({
24952 headers: _objectSpread$8({
24953 'X-LC-IM-Session-Token': sessionToken
24954 }, headers),
24955 query: _objectSpread$8({
24956 client_id: this.id
24957 }, query)
24958 }, params)));
24959
24960 case 5:
24961 case "end":
24962 return _context9.stop();
24963 }
24964 }
24965 }, _callee9, this);
24966 }));
24967
24968 function _requestWithSessionToken(_x11) {
24969 return _requestWithSessionToken2.apply(this, arguments);
24970 }
24971
24972 return _requestWithSessionToken;
24973 }()
24974 /**
24975 * 关闭客户端
24976 * @return {Promise}
24977 */
24978 ;
24979
24980 _proto.close =
24981 /*#__PURE__*/
24982 function () {
24983 var _close = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee10() {
24984 var _ee, command;
24985
24986 return regenerator.wrap(function _callee10$(_context10) {
24987 while (1) {
24988 switch (_context10.prev = _context10.next) {
24989 case 0:
24990 this._debug('close session');
24991
24992 _ee = internal(this)._eventemitter;
24993
24994 _ee.emit('beforeclose');
24995
24996 if (!this._connection.is('connected')) {
24997 _context10.next = 7;
24998 break;
24999 }
25000
25001 command = new GenericCommand({
25002 cmd: 'session',
25003 op: 'close'
25004 });
25005 _context10.next = 7;
25006 return this._send(command);
25007
25008 case 7:
25009 _ee.emit('close');
25010
25011 this.emit(CLOSE$1, {
25012 code: 0
25013 });
25014
25015 case 9:
25016 case "end":
25017 return _context10.stop();
25018 }
25019 }
25020 }, _callee10, this);
25021 }));
25022
25023 function close() {
25024 return _close.apply(this, arguments);
25025 }
25026
25027 return close;
25028 }()
25029 /**
25030 * 获取 client 列表中在线的 client,每次查询最多 20 个 clientId,超出部分会被忽略
25031 * @param {String[]} clientIds 要查询的 client ids
25032 * @return {Primse.<String[]>} 在线的 client ids
25033 */
25034 ;
25035
25036 _proto.ping =
25037 /*#__PURE__*/
25038 function () {
25039 var _ping = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee11(clientIds) {
25040 var command, resCommand;
25041 return regenerator.wrap(function _callee11$(_context11) {
25042 while (1) {
25043 switch (_context11.prev = _context11.next) {
25044 case 0:
25045 this._debug('ping');
25046
25047 if (clientIds instanceof Array) {
25048 _context11.next = 3;
25049 break;
25050 }
25051
25052 throw new TypeError("clientIds ".concat(clientIds, " is not an Array"));
25053
25054 case 3:
25055 if (clientIds.length) {
25056 _context11.next = 5;
25057 break;
25058 }
25059
25060 return _context11.abrupt("return", Promise.resolve([]));
25061
25062 case 5:
25063 command = new GenericCommand({
25064 cmd: 'session',
25065 op: 'query',
25066 sessionMessage: new SessionCommand({
25067 sessionPeerIds: clientIds
25068 })
25069 });
25070 _context11.next = 8;
25071 return this._send(command);
25072
25073 case 8:
25074 resCommand = _context11.sent;
25075 return _context11.abrupt("return", resCommand.sessionMessage.onlineSessionPeerIds);
25076
25077 case 10:
25078 case "end":
25079 return _context11.stop();
25080 }
25081 }
25082 }, _callee11, this);
25083 }));
25084
25085 function ping(_x12) {
25086 return _ping.apply(this, arguments);
25087 }
25088
25089 return ping;
25090 }()
25091 /**
25092 * 获取某个特定的对话
25093 * @param {String} id 对话 id,对应 _Conversation 表中的 objectId
25094 * @param {Boolean} [noCache=false] 强制不从缓存中获取
25095 * @return {Promise.<ConversationBase>} 如果 id 对应的对话不存在则返回 null
25096 */
25097 ;
25098
25099 _proto.getConversation =
25100 /*#__PURE__*/
25101 function () {
25102 var _getConversation = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee12(id) {
25103 var noCache,
25104 cachedConversation,
25105 _args12 = arguments;
25106 return regenerator.wrap(function _callee12$(_context12) {
25107 while (1) {
25108 switch (_context12.prev = _context12.next) {
25109 case 0:
25110 noCache = _args12.length > 1 && _args12[1] !== undefined ? _args12[1] : false;
25111
25112 if (!(typeof id !== 'string')) {
25113 _context12.next = 3;
25114 break;
25115 }
25116
25117 throw new TypeError("".concat(id, " is not a String"));
25118
25119 case 3:
25120 if (noCache) {
25121 _context12.next = 7;
25122 break;
25123 }
25124
25125 cachedConversation = this._conversationCache.get(id);
25126
25127 if (!cachedConversation) {
25128 _context12.next = 7;
25129 break;
25130 }
25131
25132 return _context12.abrupt("return", cachedConversation);
25133
25134 case 7:
25135 if (!isTemporaryConversatrionId(id)) {
25136 _context12.next = 14;
25137 break;
25138 }
25139
25140 _context12.next = 10;
25141 return this._getTemporaryConversations([id]);
25142
25143 case 10:
25144 _context12.t0 = _context12.sent[0];
25145
25146 if (_context12.t0) {
25147 _context12.next = 13;
25148 break;
25149 }
25150
25151 _context12.t0 = null;
25152
25153 case 13:
25154 return _context12.abrupt("return", _context12.t0);
25155
25156 case 14:
25157 return _context12.abrupt("return", this.getQuery().equalTo('objectId', id).find().then(function (conversations) {
25158 return conversations[0] || null;
25159 }));
25160
25161 case 15:
25162 case "end":
25163 return _context12.stop();
25164 }
25165 }
25166 }, _callee12, this);
25167 }));
25168
25169 function getConversation(_x13) {
25170 return _getConversation.apply(this, arguments);
25171 }
25172
25173 return getConversation;
25174 }()
25175 /**
25176 * 通过 id 批量获取某个特定的对话
25177 * @since 3.4.0
25178 * @param {String[]} ids 对话 id 列表,对应 _Conversation 表中的 objectId
25179 * @param {Boolean} [noCache=false] 强制不从缓存中获取
25180 * @return {Promise.<ConversationBase[]>} 如果 id 对应的对话不存在则返回 null
25181 */
25182 ;
25183
25184 _proto.getConversations =
25185 /*#__PURE__*/
25186 function () {
25187 var _getConversations = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee13(ids) {
25188 var _this9 = this;
25189
25190 var noCache,
25191 remoteConversationIds,
25192 remoteTemporaryConversationIds,
25193 query,
25194 remoteTemporaryConversationsPromise,
25195 _args13 = arguments;
25196 return regenerator.wrap(function _callee13$(_context13) {
25197 while (1) {
25198 switch (_context13.prev = _context13.next) {
25199 case 0:
25200 noCache = _args13.length > 1 && _args13[1] !== undefined ? _args13[1] : false;
25201 remoteConversationIds = noCache ? ids : ids.filter(function (id) {
25202 return _this9._conversationCache.get(id) === null;
25203 });
25204
25205 if (!remoteConversationIds.length) {
25206 _context13.next = 9;
25207 break;
25208 }
25209
25210 remoteTemporaryConversationIds = remove_1(remoteConversationIds, isTemporaryConversatrionId);
25211 query = [];
25212
25213 if (remoteConversationIds.length) {
25214 query.push(this.getQuery().containedIn('objectId', remoteConversationIds).limit(999).find());
25215 }
25216
25217 if (remoteTemporaryConversationIds.length) {
25218 remoteTemporaryConversationsPromise = remoteTemporaryConversationIds.map(this._getTemporaryConversations.bind(this));
25219 query.push.apply(query, toConsumableArray(remoteTemporaryConversationsPromise));
25220 }
25221
25222 _context13.next = 9;
25223 return Promise.all(query);
25224
25225 case 9:
25226 return _context13.abrupt("return", ids.map(function (id) {
25227 return _this9._conversationCache.get(id);
25228 }));
25229
25230 case 10:
25231 case "end":
25232 return _context13.stop();
25233 }
25234 }
25235 }, _callee13, this);
25236 }));
25237
25238 function getConversations(_x14) {
25239 return _getConversations.apply(this, arguments);
25240 }
25241
25242 return getConversations;
25243 }();
25244
25245 _proto._getTemporaryConversations = /*#__PURE__*/function () {
25246 var _getTemporaryConversations2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee14(ids) {
25247 var command, resCommand;
25248 return regenerator.wrap(function _callee14$(_context14) {
25249 while (1) {
25250 switch (_context14.prev = _context14.next) {
25251 case 0:
25252 command = new GenericCommand({
25253 cmd: 'conv',
25254 op: 'query',
25255 convMessage: new ConvCommand({
25256 tempConvIds: ids
25257 })
25258 });
25259 _context14.next = 3;
25260 return this._send(command);
25261
25262 case 3:
25263 resCommand = _context14.sent;
25264 return _context14.abrupt("return", this._handleQueryResults(resCommand));
25265
25266 case 5:
25267 case "end":
25268 return _context14.stop();
25269 }
25270 }
25271 }, _callee14, this);
25272 }));
25273
25274 function _getTemporaryConversations(_x15) {
25275 return _getTemporaryConversations2.apply(this, arguments);
25276 }
25277
25278 return _getTemporaryConversations;
25279 }()
25280 /**
25281 * 构造一个 ConversationQuery 来查询对话
25282 * @return {ConversationQuery.<PersistentConversation>}
25283 */
25284 ;
25285
25286 _proto.getQuery = function getQuery() {
25287 return new ConversationQuery(this);
25288 }
25289 /**
25290 * 构造一个 ConversationQuery 来查询聊天室
25291 * @return {ConversationQuery.<ChatRoom>}
25292 */
25293 ;
25294
25295 _proto.getChatRoomQuery = function getChatRoomQuery() {
25296 return this.getQuery().equalTo('tr', true);
25297 }
25298 /**
25299 * 构造一个 ConversationQuery 来查询服务号
25300 * @return {ConversationQuery.<ServiceConversation>}
25301 */
25302 ;
25303
25304 _proto.getServiceConversationQuery = function getServiceConversationQuery() {
25305 return this.getQuery().equalTo('sys', true);
25306 };
25307
25308 _proto._executeQuery = /*#__PURE__*/function () {
25309 var _executeQuery2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee15(query) {
25310 var queryJSON, command, resCommand;
25311 return regenerator.wrap(function _callee15$(_context15) {
25312 while (1) {
25313 switch (_context15.prev = _context15.next) {
25314 case 0:
25315 queryJSON = query.toJSON();
25316 queryJSON.where = new JsonObjectMessage({
25317 data: JSON.stringify(encode(queryJSON.where))
25318 });
25319 command = new GenericCommand({
25320 cmd: 'conv',
25321 op: 'query',
25322 convMessage: new ConvCommand(queryJSON)
25323 });
25324 _context15.next = 5;
25325 return this._send(command);
25326
25327 case 5:
25328 resCommand = _context15.sent;
25329 return _context15.abrupt("return", this._handleQueryResults(resCommand));
25330
25331 case 7:
25332 case "end":
25333 return _context15.stop();
25334 }
25335 }
25336 }, _callee15, this);
25337 }));
25338
25339 function _executeQuery(_x16) {
25340 return _executeQuery2.apply(this, arguments);
25341 }
25342
25343 return _executeQuery;
25344 }();
25345
25346 _proto._handleQueryResults = /*#__PURE__*/function () {
25347 var _handleQueryResults2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee16(resCommand) {
25348 var conversations, commandString;
25349 return regenerator.wrap(function _callee16$(_context16) {
25350 while (1) {
25351 switch (_context16.prev = _context16.next) {
25352 case 0:
25353 _context16.prev = 0;
25354 conversations = decode(JSON.parse(resCommand.convMessage.results.data));
25355 _context16.next = 8;
25356 break;
25357
25358 case 4:
25359 _context16.prev = 4;
25360 _context16.t0 = _context16["catch"](0);
25361 commandString = JSON.stringify(trim(resCommand));
25362 throw new Error("Parse query result failed: ".concat(_context16.t0.message, ". Command: ").concat(commandString));
25363
25364 case 8:
25365 _context16.next = 10;
25366 return Promise.all(conversations.map(this._parseConversationFromRawData.bind(this)));
25367
25368 case 10:
25369 conversations = _context16.sent;
25370 return _context16.abrupt("return", conversations.map(this._upsertConversationToCache.bind(this)));
25371
25372 case 12:
25373 case "end":
25374 return _context16.stop();
25375 }
25376 }
25377 }, _callee16, this, [[0, 4]]);
25378 }));
25379
25380 function _handleQueryResults(_x17) {
25381 return _handleQueryResults2.apply(this, arguments);
25382 }
25383
25384 return _handleQueryResults;
25385 }();
25386
25387 _proto._upsertConversationToCache = function _upsertConversationToCache(fetchedConversation) {
25388 var conversation = this._conversationCache.get(fetchedConversation.id);
25389
25390 if (!conversation) {
25391 conversation = fetchedConversation;
25392
25393 this._debug('no match, set cache');
25394
25395 this._conversationCache.set(fetchedConversation.id, fetchedConversation);
25396 } else {
25397 this._debug('update cached conversation');
25398
25399 ['creator', 'createdAt', 'updatedAt', 'lastMessageAt', 'lastMessage', 'mutedMembers', 'members', '_attributes', 'transient', 'muted'].forEach(function (key) {
25400 var value = fetchedConversation[key];
25401 if (value !== undefined) conversation[key] = value;
25402 });
25403 if (conversation._reset) conversation._reset();
25404 }
25405
25406 return conversation;
25407 }
25408 /**
25409 * 反序列化消息,与 {@link Message#toFullJSON} 相对。
25410 * @param {Object}
25411 * @return {AVMessage} 解析后的消息
25412 * @since 4.0.0
25413 */
25414 ;
25415
25416 _proto.parseMessage =
25417 /*#__PURE__*/
25418 function () {
25419 var _parseMessage = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee17(_ref10) {
25420 var data, _ref10$bin, bin, properties, content, message;
25421
25422 return regenerator.wrap(function _callee17$(_context17) {
25423 while (1) {
25424 switch (_context17.prev = _context17.next) {
25425 case 0:
25426 data = _ref10.data, _ref10$bin = _ref10.bin, bin = _ref10$bin === void 0 ? false : _ref10$bin, properties = objectWithoutProperties(_ref10, ["data", "bin"]);
25427 content = bin ? base64Arraybuffer_2(data) : data;
25428 _context17.next = 4;
25429 return this._messageParser.parse(content);
25430
25431 case 4:
25432 message = _context17.sent;
25433 Object.assign(message, properties);
25434
25435 message._updateMentioned(this.id);
25436
25437 return _context17.abrupt("return", message);
25438
25439 case 8:
25440 case "end":
25441 return _context17.stop();
25442 }
25443 }
25444 }, _callee17, this);
25445 }));
25446
25447 function parseMessage(_x18) {
25448 return _parseMessage.apply(this, arguments);
25449 }
25450
25451 return parseMessage;
25452 }()
25453 /**
25454 * 反序列化对话,与 {@link Conversation#toFullJSON} 相对。
25455 * @param {Object}
25456 * @return {ConversationBase} 解析后的对话
25457 * @since 4.0.0
25458 */
25459 ;
25460
25461 _proto.parseConversation =
25462 /*#__PURE__*/
25463 function () {
25464 var _parseConversation = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee18(_ref11) {
25465 var id, lastMessageAt, lastMessage, lastDeliveredAt, lastReadAt, unreadMessagesCount, members, mentioned, properties, conversationData, _transient2, system, expiredAt;
25466
25467 return regenerator.wrap(function _callee18$(_context18) {
25468 while (1) {
25469 switch (_context18.prev = _context18.next) {
25470 case 0:
25471 id = _ref11.id, lastMessageAt = _ref11.lastMessageAt, lastMessage = _ref11.lastMessage, lastDeliveredAt = _ref11.lastDeliveredAt, lastReadAt = _ref11.lastReadAt, unreadMessagesCount = _ref11.unreadMessagesCount, members = _ref11.members, mentioned = _ref11.mentioned, properties = objectWithoutProperties(_ref11, ["id", "lastMessageAt", "lastMessage", "lastDeliveredAt", "lastReadAt", "unreadMessagesCount", "members", "mentioned"]);
25472 conversationData = {
25473 id: id,
25474 lastMessageAt: lastMessageAt,
25475 lastMessage: lastMessage,
25476 lastDeliveredAt: lastDeliveredAt,
25477 lastReadAt: lastReadAt,
25478 unreadMessagesCount: unreadMessagesCount,
25479 members: members,
25480 mentioned: mentioned
25481 };
25482
25483 if (!lastMessage) {
25484 _context18.next = 7;
25485 break;
25486 }
25487
25488 _context18.next = 5;
25489 return this.parseMessage(lastMessage);
25490
25491 case 5:
25492 conversationData.lastMessage = _context18.sent;
25493
25494 conversationData.lastMessage._setStatus(MessageStatus.SENT);
25495
25496 case 7:
25497 _transient2 = properties["transient"], system = properties.system, expiredAt = properties.expiredAt;
25498
25499 if (!_transient2) {
25500 _context18.next = 10;
25501 break;
25502 }
25503
25504 return _context18.abrupt("return", new ChatRoom(conversationData, properties, this));
25505
25506 case 10:
25507 if (!system) {
25508 _context18.next = 12;
25509 break;
25510 }
25511
25512 return _context18.abrupt("return", new ServiceConversation(conversationData, properties, this));
25513
25514 case 12:
25515 if (!(expiredAt || isTemporaryConversatrionId(id))) {
25516 _context18.next = 14;
25517 break;
25518 }
25519
25520 return _context18.abrupt("return", new TemporaryConversation(conversationData, {
25521 expiredAt: expiredAt
25522 }, this));
25523
25524 case 14:
25525 return _context18.abrupt("return", new Conversation(conversationData, properties, this));
25526
25527 case 15:
25528 case "end":
25529 return _context18.stop();
25530 }
25531 }
25532 }, _callee18, this);
25533 }));
25534
25535 function parseConversation(_x19) {
25536 return _parseConversation.apply(this, arguments);
25537 }
25538
25539 return parseConversation;
25540 }();
25541
25542 _proto._parseConversationFromRawData = /*#__PURE__*/function () {
25543 var _parseConversationFromRawData2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee19(rawData) {
25544 var data, ttl;
25545 return regenerator.wrap(function _callee19$(_context19) {
25546 while (1) {
25547 switch (_context19.prev = _context19.next) {
25548 case 0:
25549 data = keyRemap({
25550 objectId: 'id',
25551 lm: 'lastMessageAt',
25552 m: 'members',
25553 tr: 'transient',
25554 sys: 'system',
25555 c: 'creator',
25556 mu: 'mutedMembers'
25557 }, rawData);
25558
25559 if (data.msg) {
25560 data.lastMessage = {
25561 data: data.msg,
25562 bin: data.bin,
25563 from: data.msg_from,
25564 id: data.msg_mid,
25565 timestamp: data.msg_timestamp,
25566 updatedAt: data.patch_timestamp
25567 };
25568 delete data.lastMessageFrom;
25569 delete data.lastMessageId;
25570 delete data.lastMessageTimestamp;
25571 delete data.lastMessagePatchTimestamp;
25572 }
25573
25574 ttl = data.ttl;
25575 if (ttl) data.expiredAt = Date.now() + ttl * 1000;
25576 return _context19.abrupt("return", this.parseConversation(data));
25577
25578 case 5:
25579 case "end":
25580 return _context19.stop();
25581 }
25582 }
25583 }, _callee19, this);
25584 }));
25585
25586 function _parseConversationFromRawData(_x20) {
25587 return _parseConversationFromRawData2.apply(this, arguments);
25588 }
25589
25590 return _parseConversationFromRawData;
25591 }()
25592 /**
25593 * 创建一个对话
25594 * @param {Object} options 除了下列字段外的其他字段将被视为对话的自定义属性
25595 * @param {String[]} options.members 对话的初始成员列表,默认包含当前 client
25596 * @param {String} [options.name] 对话的名字
25597 * @param {Boolean} [options.unique=true] 唯一对话,当其为 true 时,如果当前已经有相同成员的对话存在则返回该对话,否则会创建新的对话
25598 * @return {Promise.<Conversation>}
25599 */
25600 ;
25601
25602 _proto.createConversation =
25603 /*#__PURE__*/
25604 function () {
25605 var _createConversation = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee20() {
25606 var _ref12,
25607 m,
25608 name,
25609 _transient3,
25610 _ref12$unique,
25611 unique,
25612 tempConv,
25613 tempConvTTL,
25614 properties,
25615 members,
25616 attr,
25617 startCommandJson,
25618 command,
25619 params,
25620 signatureResult,
25621 _yield$this$_send,
25622 _yield$this$_send$con,
25623 cid,
25624 cdate,
25625 ttl,
25626 data,
25627 conversation,
25628 _args20 = arguments;
25629
25630 return regenerator.wrap(function _callee20$(_context20) {
25631 while (1) {
25632 switch (_context20.prev = _context20.next) {
25633 case 0:
25634 _ref12 = _args20.length > 0 && _args20[0] !== undefined ? _args20[0] : {}, m = _ref12.members, name = _ref12.name, _transient3 = _ref12["transient"], _ref12$unique = _ref12.unique, unique = _ref12$unique === void 0 ? true : _ref12$unique, tempConv = _ref12._tempConv, tempConvTTL = _ref12._tempConvTTL, properties = objectWithoutProperties(_ref12, ["members", "name", "transient", "unique", "_tempConv", "_tempConvTTL"]);
25635
25636 if (_transient3 || Array.isArray(m)) {
25637 _context20.next = 3;
25638 break;
25639 }
25640
25641 throw new TypeError("conversation members ".concat(m, " is not an array"));
25642
25643 case 3:
25644 members = new Set(m);
25645 members.add(this.id);
25646 members = Array.from(members).sort();
25647 attr = properties || {};
25648
25649 if (!name) {
25650 _context20.next = 11;
25651 break;
25652 }
25653
25654 if (!(typeof name !== 'string')) {
25655 _context20.next = 10;
25656 break;
25657 }
25658
25659 throw new TypeError("conversation name ".concat(name, " is not a string"));
25660
25661 case 10:
25662 attr.name = name;
25663
25664 case 11:
25665 attr = new JsonObjectMessage({
25666 data: JSON.stringify(encode(attr))
25667 });
25668 startCommandJson = {
25669 m: members,
25670 attr: attr,
25671 "transient": _transient3,
25672 unique: unique,
25673 tempConv: tempConv,
25674 tempConvTTL: tempConvTTL
25675 };
25676 command = new GenericCommand({
25677 cmd: 'conv',
25678 op: 'start',
25679 convMessage: new ConvCommand(startCommandJson)
25680 });
25681
25682 if (!this.options.conversationSignatureFactory) {
25683 _context20.next = 20;
25684 break;
25685 }
25686
25687 params = [null, this._identity, members, 'create'];
25688 _context20.next = 18;
25689 return runSignatureFactory(this.options.conversationSignatureFactory, params);
25690
25691 case 18:
25692 signatureResult = _context20.sent;
25693 Object.assign(command.convMessage, keyRemap({
25694 signature: 's',
25695 timestamp: 't',
25696 nonce: 'n'
25697 }, signatureResult));
25698
25699 case 20:
25700 _context20.next = 22;
25701 return this._send(command);
25702
25703 case 22:
25704 _yield$this$_send = _context20.sent;
25705 _yield$this$_send$con = _yield$this$_send.convMessage;
25706 cid = _yield$this$_send$con.cid;
25707 cdate = _yield$this$_send$con.cdate;
25708 ttl = _yield$this$_send$con.tempConvTTL;
25709 data = _objectSpread$8({
25710 name: name,
25711 "transient": _transient3,
25712 unique: unique,
25713 id: cid,
25714 createdAt: cdate,
25715 updatedAt: cdate,
25716 lastMessageAt: null,
25717 creator: this.id,
25718 members: _transient3 ? [] : members
25719 }, properties);
25720 if (ttl) data.expiredAt = Date.now() + ttl * 1000;
25721 _context20.next = 31;
25722 return this.parseConversation(data);
25723
25724 case 31:
25725 conversation = _context20.sent;
25726 return _context20.abrupt("return", this._upsertConversationToCache(conversation));
25727
25728 case 33:
25729 case "end":
25730 return _context20.stop();
25731 }
25732 }
25733 }, _callee20, this);
25734 }));
25735
25736 function createConversation() {
25737 return _createConversation.apply(this, arguments);
25738 }
25739
25740 return createConversation;
25741 }()
25742 /**
25743 * 创建一个聊天室
25744 * @since 4.0.0
25745 * @param {Object} options 除了下列字段外的其他字段将被视为对话的自定义属性
25746 * @param {String} [options.name] 对话的名字
25747 * @return {Promise.<ChatRoom>}
25748 */
25749 ;
25750
25751 _proto.createChatRoom =
25752 /*#__PURE__*/
25753 function () {
25754 var _createChatRoom = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee21(param) {
25755 return regenerator.wrap(function _callee21$(_context21) {
25756 while (1) {
25757 switch (_context21.prev = _context21.next) {
25758 case 0:
25759 return _context21.abrupt("return", this.createConversation(_objectSpread$8(_objectSpread$8({}, param), {}, {
25760 "transient": true,
25761 members: null,
25762 unique: false,
25763 _tempConv: false
25764 })));
25765
25766 case 1:
25767 case "end":
25768 return _context21.stop();
25769 }
25770 }
25771 }, _callee21, this);
25772 }));
25773
25774 function createChatRoom(_x21) {
25775 return _createChatRoom.apply(this, arguments);
25776 }
25777
25778 return createChatRoom;
25779 }()
25780 /**
25781 * 创建一个临时对话
25782 * @since 4.0.0
25783 * @param {Object} options
25784 * @param {String[]} options.members 对话的初始成员列表,默认包含当前 client
25785 * @param {String} [options.ttl] 对话存在时间,单位为秒,最大值与默认值均为 86400(一天),过期后该对话不再可用。
25786 * @return {Promise.<TemporaryConversation>}
25787 */
25788 ;
25789
25790 _proto.createTemporaryConversation =
25791 /*#__PURE__*/
25792 function () {
25793 var _createTemporaryConversation = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee22(_ref13) {
25794 var _tempConvTTL, param;
25795
25796 return regenerator.wrap(function _callee22$(_context22) {
25797 while (1) {
25798 switch (_context22.prev = _context22.next) {
25799 case 0:
25800 _tempConvTTL = _ref13.ttl, param = objectWithoutProperties(_ref13, ["ttl"]);
25801 return _context22.abrupt("return", this.createConversation(_objectSpread$8(_objectSpread$8({}, param), {}, {
25802 _tempConv: true,
25803 _tempConvTTL: _tempConvTTL
25804 })));
25805
25806 case 2:
25807 case "end":
25808 return _context22.stop();
25809 }
25810 }
25811 }, _callee22, this);
25812 }));
25813
25814 function createTemporaryConversation(_x22) {
25815 return _createTemporaryConversation.apply(this, arguments);
25816 }
25817
25818 return createTemporaryConversation;
25819 }() // jsdoc-ignore-start
25820 ;
25821
25822 _proto. // jsdoc-ignore-end
25823 _doSendRead = function _doSendRead() {
25824 var _this10 = this;
25825
25826 // if not connected, just skip everything
25827 if (!this._connection.is('connected')) return;
25828 var buffer = internal(this).readConversationsBuffer;
25829 var conversations = Array.from(buffer);
25830 if (!conversations.length) return;
25831 var ids = conversations.map(function (conversation) {
25832 if (!(conversation instanceof ConversationBase)) {
25833 throw new TypeError("".concat(conversation, " is not a Conversation"));
25834 }
25835
25836 return conversation.id;
25837 });
25838
25839 this._debug("mark [".concat(ids, "] as read"));
25840
25841 buffer.clear();
25842
25843 this._sendReadCommand(conversations)["catch"](function (error) {
25844 _this10._debug('send read failed: %O', error);
25845
25846 conversations.forEach(buffer.add.bind(buffer));
25847 });
25848 };
25849
25850 _proto._sendReadCommand = function _sendReadCommand(conversations) {
25851 var _this11 = this;
25852
25853 return this._send(new GenericCommand({
25854 cmd: 'read',
25855 readMessage: new ReadCommand({
25856 convs: conversations.map(function (conversation) {
25857 return new ReadTuple({
25858 cid: conversation.id,
25859 mid: conversation.lastMessage && conversation.lastMessage.from !== _this11.id ? conversation.lastMessage.id : undefined,
25860 timestamp: (conversation.lastMessageAt || new Date()).getTime()
25861 });
25862 })
25863 })
25864 }), false);
25865 };
25866
25867 return IMClient;
25868 }(eventemitter3), (applyDecoratedDescriptor(_class$3.prototype, "_doSendAck", [_dec$2], Object.getOwnPropertyDescriptor(_class$3.prototype, "_doSendAck"), _class$3.prototype), applyDecoratedDescriptor(_class$3.prototype, "_doSendRead", [_dec2], Object.getOwnPropertyDescriptor(_class$3.prototype, "_doSendRead"), _class$3.prototype)), _class$3));
25869 /**
25870 * 修改、撤回消息的原因
25871 * @typedef PatchReason
25872 * @type {Object}
25873 * @property {number} code 负数为内置 code,正数为开发者在 hook 中自定义的 code。比如因为敏感词过滤被修改的 code 为 -4408。
25874 * @property {string} [detail] 具体的原因说明。
25875 */
25876
25877 var RECONNECT_ERROR = 'reconnecterror';
25878
25879 var CoreEvent = /*#__PURE__*/Object.freeze({
25880 __proto__: null,
25881 RECONNECT_ERROR: RECONNECT_ERROR,
25882 DISCONNECT: DISCONNECT,
25883 RECONNECT: RECONNECT,
25884 RETRY: RETRY,
25885 SCHEDULE: SCHEDULE,
25886 OFFLINE: OFFLINE,
25887 ONLINE: ONLINE
25888 });
25889
25890 var _class$4;
25891
25892 function ownKeys$9(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
25893
25894 function _objectSpread$9(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$9(Object(source), true).forEach(function (key) { defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$9(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
25895
25896 var // jsdoc-ignore-end
25897 BinaryMessage = IE10Compatible(_class$4 = /*#__PURE__*/function (_Message) {
25898 inheritsLoose(BinaryMessage, _Message);
25899
25900 /**
25901 * 二进制消息
25902 * @extends Message
25903 * @param {ArrayBuffer} buffer
25904 * @since 4.0.0
25905 */
25906 function BinaryMessage(buffer) {
25907 if (!(buffer instanceof ArrayBuffer)) {
25908 throw new TypeError("".concat(buffer, " is not an ArrayBuffer"));
25909 }
25910
25911 return _Message.call(this, buffer) || this;
25912 }
25913 /**
25914 * @type ArrayBuffer
25915 */
25916
25917
25918 BinaryMessage.validate = function validate(target) {
25919 return target instanceof ArrayBuffer;
25920 };
25921
25922 var _proto = BinaryMessage.prototype;
25923
25924 _proto.toJSON = function toJSON() {
25925 return _objectSpread$9(_objectSpread$9({}, _Message.prototype._toJSON.call(this)), {}, {
25926 data: base64Arraybuffer_1(this.content)
25927 });
25928 };
25929
25930 _proto.toFullJSON = function toFullJSON() {
25931 return _objectSpread$9(_objectSpread$9({}, _Message.prototype.toFullJSON.call(this)), {}, {
25932 bin: true,
25933 data: base64Arraybuffer_1(this.content)
25934 });
25935 };
25936
25937 createClass(BinaryMessage, [{
25938 key: "buffer",
25939 get: function get() {
25940 return this.content;
25941 },
25942 set: function set(buffer) {
25943 this.content = buffer;
25944 }
25945 }]);
25946
25947 return BinaryMessage;
25948 }(Message)) || _class$4;
25949
25950 var _dec$3, _class$5;
25951
25952 var // jsdoc-ignore-end
25953 TextMessage = (_dec$3 = messageType(-1), _dec$3(_class$5 = IE10Compatible(_class$5 = /*#__PURE__*/function (_TypedMessage) {
25954 inheritsLoose(TextMessage, _TypedMessage);
25955
25956 /**
25957 * 文类类型消息
25958 * @extends TypedMessage
25959 * @param {String} [text='']
25960 * @throws {TypeError} text 不是 String 类型
25961 */
25962 function TextMessage() {
25963 var _this;
25964
25965 var text = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
25966
25967 if (typeof text !== 'string') {
25968 throw new TypeError("".concat(text, " is not a string"));
25969 }
25970
25971 _this = _TypedMessage.call(this) || this;
25972
25973 _this.setText(text);
25974
25975 return _this;
25976 }
25977
25978 return TextMessage;
25979 }(TypedMessage)) || _class$5) || _class$5);
25980 /**
25981 * @name TYPE
25982 * @memberof TextMessage
25983 * @type Number
25984 * @static
25985 * @const
25986 */
25987
25988 var _class$6;
25989
25990 function ownKeys$a(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
25991
25992 function _objectSpread$a(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$a(Object(source), true).forEach(function (key) { defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$a(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
25993
25994 function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray$1(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
25995
25996 function _unsupportedIterableToArray$1(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray$1(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray$1(o, minLen); }
25997
25998 function _arrayLikeToArray$1(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
25999 var debug$c = browser('LC:MessageParser');
26000
26001 var tryParseJson = function tryParseJson(target, key, descriptor) {
26002 var fn = descriptor.value; // eslint-disable-next-line no-param-reassign
26003
26004 descriptor.value = function wrapper(param) {
26005 var content;
26006
26007 if (typeof param !== 'string') {
26008 content = param;
26009 } else {
26010 try {
26011 content = JSON.parse(param);
26012 } catch (error) {
26013 content = param;
26014 }
26015 }
26016
26017 return fn.call(this, content);
26018 };
26019 };
26020
26021 var applyPlugins = function applyPlugins(target, key, descriptor) {
26022 var fn = descriptor.value; // eslint-disable-next-line no-param-reassign
26023
26024 descriptor.value = function wrapper(json) {
26025 var _this = this;
26026
26027 return Promise.resolve(json).then(applyMiddlewares(this._plugins.beforeMessageParse)).then(function (decoratedJson) {
26028 return fn.call(_this, decoratedJson);
26029 }).then(applyMiddlewares(this._plugins.afterMessageParse));
26030 };
26031 };
26032
26033 var MessageParser = (_class$6 = /*#__PURE__*/function () {
26034 /**
26035 * 消息解析器
26036 * @param {Object} plugins 插件,插件的 messageClasses 会自动被注册,在解析时 beforeMessageParse 与 afterMessageParse Middleware 会被应用。
26037 */
26038 function MessageParser() {
26039 var plugins = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
26040 this._plugins = plugins;
26041 this._messageClasses = [];
26042 this.register(plugins.messageClasses);
26043 }
26044 /**
26045 * 注册消息类
26046 *
26047 * @param {Function | Function[]} messageClass 消息类,需要实现 {@link AVMessage} 接口,
26048 * 建议继承自 {@link TypedMessage},也可以传入一个消息类数组。
26049 * @throws {TypeError} 如果 messageClass 没有实现 {@link AVMessage} 接口则抛出异常
26050 */
26051
26052
26053 var _proto = MessageParser.prototype;
26054
26055 _proto.register = function register(messageClasses) {
26056 var _this2 = this;
26057
26058 ensureArray(messageClasses).map(function (klass) {
26059 return _this2._register(klass);
26060 });
26061 };
26062
26063 _proto._register = function _register(messageClass) {
26064 if (messageClass && messageClass.parse && messageClass.prototype && messageClass.prototype.getPayload) {
26065 this._messageClasses.unshift(messageClass);
26066 } else {
26067 throw new TypeError('Invalid messageClass');
26068 }
26069 } // jsdoc-ignore-start
26070 ;
26071
26072 _proto. // jsdoc-ignore-end
26073
26074 /**
26075 * 解析消息内容
26076 * @param {Object | string | any} target 消息内容,如果是字符串会尝试 parse 为 JSON。
26077 * @return {AVMessage} 解析后的消息
26078 * @throws {Error} 如果不匹配任何注册的消息则抛出异常
26079 */
26080 parse = function parse(content) {
26081 debug$c('parsing message: %O', content); // eslint-disable-next-line
26082
26083 var _iterator = _createForOfIteratorHelper(this._messageClasses),
26084 _step;
26085
26086 try {
26087 for (_iterator.s(); !(_step = _iterator.n()).done;) {
26088 var Klass = _step.value;
26089 var contentCopy = isPlainObject_1(content) ? _objectSpread$a({}, content) : content;
26090 var valid = void 0;
26091 var result = void 0;
26092
26093 try {
26094 valid = Klass.validate(contentCopy);
26095 } catch (error) {// eslint-disable-line no-empty
26096 }
26097
26098 if (valid) {
26099 try {
26100 result = Klass.parse(contentCopy);
26101 } catch (error) {
26102 console.warn('parsing a valid message content error', {
26103 error: error,
26104 Klass: Klass,
26105 content: contentCopy
26106 });
26107 }
26108
26109 if (result !== undefined) {
26110 debug$c('parse result: %O', result);
26111 return result;
26112 }
26113 }
26114 }
26115 } catch (err) {
26116 _iterator.e(err);
26117 } finally {
26118 _iterator.f();
26119 }
26120
26121 throw new Error('No Message Class matched');
26122 };
26123
26124 return MessageParser;
26125 }(), (applyDecoratedDescriptor(_class$6.prototype, "parse", [tryParseJson, applyPlugins], Object.getOwnPropertyDescriptor(_class$6.prototype, "parse"), _class$6.prototype)), _class$6);
26126
26127 function ownKeys$b(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
26128
26129 function _objectSpread$b(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$b(Object(source), true).forEach(function (key) { defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$b(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
26130 var debug$d = browser('LC:IMPlugin');
26131 /**
26132 * 消息优先级枚举
26133 * @enum {Number}
26134 * @since 3.3.0
26135 */
26136
26137 var MessagePriority = {
26138 /** 高 */
26139 HIGH: 1,
26140
26141 /** 普通 */
26142 NORMAL: 2,
26143
26144 /** 低 */
26145 LOW: 3
26146 };
26147 Object.freeze(MessagePriority);
26148 /**
26149 * 为 Conversation 定义一个新属性
26150 * @param {String} prop 属性名
26151 * @param {Object} [descriptor] 属性的描述符,参见 {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor#Description getOwnPropertyDescriptor#Description - MDN},默认为该属性名对应的 Conversation 自定义属性的 getter/setter
26152 * @returns void
26153 * @example
26154 *
26155 * conversation.get('type');
26156 * conversation.set('type', 1);
26157 *
26158 * // equals to
26159 * defineConversationProperty('type');
26160 * conversation.type;
26161 * conversation.type = 1;
26162 */
26163
26164 var defineConversationProperty = function defineConversationProperty(prop) {
26165 var descriptor = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
26166 get: function get() {
26167 return this.get(prop);
26168 },
26169 set: function set(value) {
26170 this.set(prop, value);
26171 }
26172 };
26173 Object.defineProperty(Conversation.prototype, prop, descriptor);
26174 };
26175
26176 var onRealtimeCreate = function onRealtimeCreate(realtime) {
26177 /* eslint-disable no-param-reassign */
26178 var deviceId = v4_1();
26179 realtime._IMClients = {};
26180 realtime._IMClientsCreationCount = 0;
26181 var messageParser = new MessageParser(realtime._plugins);
26182 realtime._messageParser = messageParser;
26183
26184 var signAVUser = /*#__PURE__*/function () {
26185 var _ref = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee(user) {
26186 return regenerator.wrap(function _callee$(_context) {
26187 while (1) {
26188 switch (_context.prev = _context.next) {
26189 case 0:
26190 return _context.abrupt("return", realtime._request({
26191 method: 'POST',
26192 path: '/rtm/sign',
26193 data: {
26194 session_token: user.getSessionToken()
26195 }
26196 }));
26197
26198 case 1:
26199 case "end":
26200 return _context.stop();
26201 }
26202 }
26203 }, _callee);
26204 }));
26205
26206 return function signAVUser(_x) {
26207 return _ref.apply(this, arguments);
26208 };
26209 }();
26210 /**
26211 * 注册消息类
26212 *
26213 * 在接收消息、查询消息时,会按照消息类注册顺序的逆序依次尝试解析消息内容
26214 *
26215 * @memberof Realtime
26216 * @instance
26217 * @param {Function | Function[]} messageClass 消息类,需要实现 {@link AVMessage} 接口,
26218 * 建议继承自 {@link TypedMessage}
26219 * @throws {TypeError} 如果 messageClass 没有实现 {@link AVMessage} 接口则抛出异常
26220 */
26221
26222
26223 var register = messageParser.register.bind(messageParser);
26224 /**
26225 * 创建一个即时通讯客户端,多次创建相同 id 的客户端会返回同一个实例
26226 * @memberof Realtime
26227 * @instance
26228 * @param {String|AV.User} [identity] 客户端 identity,如果不指定该参数,服务端会随机生成一个字符串作为 identity,
26229 * 如果传入一个已登录的 AV.User,则会使用该用户的 id 作为客户端 identity 登录。
26230 * @param {Object} [options]
26231 * @param {Function} [options.signatureFactory] open session 时的签名方法 // TODO need details
26232 * @param {Function} [options.conversationSignatureFactory] 对话创建、增减成员操作时的签名方法
26233 * @param {Function} [options.blacklistSignatureFactory] 黑名单操作时的签名方法
26234 * @param {String} [options.tag] 客户端类型标记,以支持单点登录功能
26235 * @param {String} [options.isReconnect=false] 单点登录时标记该次登录是不是应用启动时自动重新登录
26236 * @return {Promise.<IMClient>}
26237 */
26238
26239 var createIMClient = /*#__PURE__*/function () {
26240 var _ref2 = asyncToGenerator( /*#__PURE__*/regenerator.mark(function _callee2(identity) {
26241 var _realtime$_open$then;
26242
26243 var _ref3,
26244 tag,
26245 isReconnect,
26246 clientOptions,
26247 lagecyTag,
26248 id,
26249 buildinOptions,
26250 sessionToken,
26251 _tag,
26252 promise,
26253 _args2 = arguments;
26254
26255 return regenerator.wrap(function _callee2$(_context2) {
26256 while (1) {
26257 switch (_context2.prev = _context2.next) {
26258 case 0:
26259 _ref3 = _args2.length > 1 && _args2[1] !== undefined ? _args2[1] : {}, tag = _ref3.tag, isReconnect = _ref3.isReconnect, clientOptions = objectWithoutProperties(_ref3, ["tag", "isReconnect"]);
26260 lagecyTag = _args2.length > 2 ? _args2[2] : undefined;
26261 buildinOptions = {};
26262
26263 if (!identity) {
26264 _context2.next = 19;
26265 break;
26266 }
26267
26268 if (!(typeof identity === 'string')) {
26269 _context2.next = 8;
26270 break;
26271 }
26272
26273 id = identity;
26274 _context2.next = 17;
26275 break;
26276
26277 case 8:
26278 if (!(identity.id && identity.getSessionToken)) {
26279 _context2.next = 16;
26280 break;
26281 }
26282
26283 id = identity.id;
26284 sessionToken = identity.getSessionToken();
26285
26286 if (sessionToken) {
26287 _context2.next = 13;
26288 break;
26289 }
26290
26291 throw new Error('User must be authenticated');
26292
26293 case 13:
26294 buildinOptions.signatureFactory = signAVUser;
26295 _context2.next = 17;
26296 break;
26297
26298 case 16:
26299 throw new TypeError('Identity must be a String or an AV.User');
26300
26301 case 17:
26302 if (!(realtime._IMClients[id] !== undefined)) {
26303 _context2.next = 19;
26304 break;
26305 }
26306
26307 return _context2.abrupt("return", realtime._IMClients[id]);
26308
26309 case 19:
26310 if (lagecyTag) {
26311 console.warn('DEPRECATION createIMClient tag param: Use options.tag instead.');
26312 }
26313
26314 _tag = tag || lagecyTag;
26315 promise = (_realtime$_open$then = realtime._open().then(function (connection) {
26316 var client = new IMClient(id, _objectSpread$b(_objectSpread$b({}, buildinOptions), clientOptions), {
26317 _connection: connection,
26318 _request: realtime._request.bind(realtime),
26319 _messageParser: messageParser,
26320 _plugins: realtime._plugins,
26321 _identity: identity
26322 });
26323 connection.on(RECONNECT, function () {
26324 return client._open(realtime._options.appId, _tag, deviceId, true)
26325 /**
26326 * 客户端连接恢复正常,该事件通常在 {@link Realtime#event:RECONNECT} 之后发生
26327 * @event IMClient#RECONNECT
26328 * @see Realtime#event:RECONNECT
26329 * @since 3.2.0
26330 */
26331
26332 /**
26333 * 客户端重新登录发生错误(网络连接已恢复,但重新登录错误)
26334 * @event IMClient#RECONNECT_ERROR
26335 * @since 3.2.0
26336 */
26337 .then(function () {
26338 return client.emit(RECONNECT);
26339 }, function (error) {
26340 return client.emit(RECONNECT_ERROR, error);
26341 });
26342 });
26343
26344 internal(client)._eventemitter.on('beforeclose', function () {
26345 delete realtime._IMClients[client.id];
26346
26347 if (realtime._firstIMClient === client) {
26348 delete realtime._firstIMClient;
26349 }
26350 }, realtime);
26351
26352 internal(client)._eventemitter.on('close', function () {
26353 realtime._deregister(client);
26354 }, realtime);
26355
26356 return client._open(realtime._options.appId, _tag, deviceId, isReconnect).then(function () {
26357 realtime._IMClients[client.id] = client;
26358 realtime._IMClientsCreationCount += 1;
26359
26360 if (realtime._IMClientsCreationCount === 1) {
26361 client._omitPeerId(true);
26362
26363 realtime._firstIMClient = client;
26364 } else if (realtime._IMClientsCreationCount > 1 && realtime._firstIMClient) {
26365 realtime._firstIMClient._omitPeerId(false);
26366 }
26367
26368 realtime._register(client);
26369
26370 return client;
26371 })["catch"](function (error) {
26372 delete realtime._IMClients[client.id];
26373 throw error;
26374 });
26375 })).then.apply(_realtime$_open$then, toConsumableArray(finalize(function () {
26376 realtime._deregisterPending(promise);
26377 })))["catch"](function (error) {
26378 delete realtime._IMClients[id];
26379 throw error;
26380 });
26381
26382 if (identity) {
26383 realtime._IMClients[id] = promise;
26384 }
26385
26386 realtime._registerPending(promise);
26387
26388 return _context2.abrupt("return", promise);
26389
26390 case 25:
26391 case "end":
26392 return _context2.stop();
26393 }
26394 }
26395 }, _callee2);
26396 }));
26397
26398 return function createIMClient(_x2) {
26399 return _ref2.apply(this, arguments);
26400 };
26401 }();
26402
26403 Object.assign(realtime, {
26404 register: register,
26405 createIMClient: createIMClient
26406 });
26407 /* eslint-enable no-param-reassign */
26408 };
26409
26410 var beforeCommandDispatch = function beforeCommandDispatch(command, realtime) {
26411 var isIMCommand = command.service === null || command.service === 2;
26412 if (!isIMCommand) return true;
26413 var targetClient = command.peerId ? realtime._IMClients[command.peerId] : realtime._firstIMClient;
26414
26415 if (targetClient) {
26416 Promise.resolve(targetClient).then(function (client) {
26417 return client._dispatchCommand(command);
26418 })["catch"](debug$d);
26419 } else {
26420 debug$d('[WARN] Unexpected message received without any live client match: %O', trim(command));
26421 }
26422
26423 return false;
26424 };
26425
26426 var IMPlugin = {
26427 name: 'leancloud-realtime-plugin-im',
26428 onRealtimeCreate: onRealtimeCreate,
26429 beforeCommandDispatch: beforeCommandDispatch,
26430 messageClasses: [Message, BinaryMessage, RecalledMessage, TextMessage]
26431 };
26432
26433 function ownKeys$c(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
26434
26435 function _objectSpread$c(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$c(Object(source), true).forEach(function (key) { defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$c(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
26436 Realtime.defineConversationProperty = defineConversationProperty;
26437 Realtime.__preRegisteredPlugins = [IMPlugin];
26438
26439 var Event = _objectSpread$c(_objectSpread$c({}, CoreEvent), IMEvent);
26440
26441 exports.BinaryMessage = BinaryMessage;
26442 exports.ChatRoom = ChatRoom;
26443 exports.Conversation = Conversation;
26444 exports.ConversationMemberRole = ConversationMemberRole;
26445 exports.ConversationQuery = ConversationQuery;
26446 exports.ErrorCode = ErrorCode;
26447 exports.Event = Event;
26448 exports.EventEmitter = eventemitter3;
26449 exports.IE10Compatible = IE10Compatible;
26450 exports.IMPlugin = IMPlugin;
26451 exports.Message = Message;
26452 exports.MessageParser = MessageParser;
26453 exports.MessagePriority = MessagePriority;
26454 exports.MessageQueryDirection = MessageQueryDirection;
26455 exports.MessageStatus = MessageStatus;
26456 exports.Promise = polyfilledPromise;
26457 exports.Protocals = message;
26458 exports.Protocols = message;
26459 exports.Realtime = Realtime;
26460 exports.RecalledMessage = RecalledMessage;
26461 exports.ServiceConversation = ServiceConversation;
26462 exports.TemporaryConversation = TemporaryConversation;
26463 exports.TextMessage = TextMessage;
26464 exports.TypedMessage = TypedMessage;
26465 exports.debug = debug$2;
26466 exports.defineConversationProperty = defineConversationProperty;
26467 exports.getAdapter = getAdapter;
26468 exports.messageField = messageField;
26469 exports.messageType = messageType;
26470 exports.setAdapters = setAdapters;
26471
26472 Object.defineProperty(exports, '__esModule', { value: true });
26473
26474})));
26475//# sourceMappingURL=im.js.map