source: node_modules/immutable/dist/immutable.js

main
Last change on this file was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 139.0 KB
Line 
1/**
2 * Copyright (c) 2014-present, Facebook, Inc.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8(function (global, factory) {
9 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
10 typeof define === 'function' && define.amd ? define(factory) :
11 (global.Immutable = factory());
12}(this, function () { 'use strict';var SLICE$0 = Array.prototype.slice;
13
14 function createClass(ctor, superClass) {
15 if (superClass) {
16 ctor.prototype = Object.create(superClass.prototype);
17 }
18 ctor.prototype.constructor = ctor;
19 }
20
21 function Iterable(value) {
22 return isIterable(value) ? value : Seq(value);
23 }
24
25
26 createClass(KeyedIterable, Iterable);
27 function KeyedIterable(value) {
28 return isKeyed(value) ? value : KeyedSeq(value);
29 }
30
31
32 createClass(IndexedIterable, Iterable);
33 function IndexedIterable(value) {
34 return isIndexed(value) ? value : IndexedSeq(value);
35 }
36
37
38 createClass(SetIterable, Iterable);
39 function SetIterable(value) {
40 return isIterable(value) && !isAssociative(value) ? value : SetSeq(value);
41 }
42
43
44
45 function isIterable(maybeIterable) {
46 return !!(maybeIterable && maybeIterable[IS_ITERABLE_SENTINEL]);
47 }
48
49 function isKeyed(maybeKeyed) {
50 return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL]);
51 }
52
53 function isIndexed(maybeIndexed) {
54 return !!(maybeIndexed && maybeIndexed[IS_INDEXED_SENTINEL]);
55 }
56
57 function isAssociative(maybeAssociative) {
58 return isKeyed(maybeAssociative) || isIndexed(maybeAssociative);
59 }
60
61 function isOrdered(maybeOrdered) {
62 return !!(maybeOrdered && maybeOrdered[IS_ORDERED_SENTINEL]);
63 }
64
65 Iterable.isIterable = isIterable;
66 Iterable.isKeyed = isKeyed;
67 Iterable.isIndexed = isIndexed;
68 Iterable.isAssociative = isAssociative;
69 Iterable.isOrdered = isOrdered;
70
71 Iterable.Keyed = KeyedIterable;
72 Iterable.Indexed = IndexedIterable;
73 Iterable.Set = SetIterable;
74
75
76 var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@';
77 var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@';
78 var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@';
79 var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@';
80
81 // Used for setting prototype methods that IE8 chokes on.
82 var DELETE = 'delete';
83
84 // Constants describing the size of trie nodes.
85 var SHIFT = 5; // Resulted in best performance after ______?
86 var SIZE = 1 << SHIFT;
87 var MASK = SIZE - 1;
88
89 // A consistent shared value representing "not set" which equals nothing other
90 // than itself, and nothing that could be provided externally.
91 var NOT_SET = {};
92
93 // Boolean references, Rough equivalent of `bool &`.
94 var CHANGE_LENGTH = { value: false };
95 var DID_ALTER = { value: false };
96
97 function MakeRef(ref) {
98 ref.value = false;
99 return ref;
100 }
101
102 function SetRef(ref) {
103 ref && (ref.value = true);
104 }
105
106 // A function which returns a value representing an "owner" for transient writes
107 // to tries. The return value will only ever equal itself, and will not equal
108 // the return of any subsequent call of this function.
109 function OwnerID() {}
110
111 // http://jsperf.com/copy-array-inline
112 function arrCopy(arr, offset) {
113 offset = offset || 0;
114 var len = Math.max(0, arr.length - offset);
115 var newArr = new Array(len);
116 for (var ii = 0; ii < len; ii++) {
117 newArr[ii] = arr[ii + offset];
118 }
119 return newArr;
120 }
121
122 function ensureSize(iter) {
123 if (iter.size === undefined) {
124 iter.size = iter.__iterate(returnTrue);
125 }
126 return iter.size;
127 }
128
129 function wrapIndex(iter, index) {
130 // This implements "is array index" which the ECMAString spec defines as:
131 //
132 // A String property name P is an array index if and only if
133 // ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal
134 // to 2^32−1.
135 //
136 // http://www.ecma-international.org/ecma-262/6.0/#sec-array-exotic-objects
137 if (typeof index !== 'number') {
138 var uint32Index = index >>> 0; // N >>> 0 is shorthand for ToUint32
139 if ('' + uint32Index !== index || uint32Index === 4294967295) {
140 return NaN;
141 }
142 index = uint32Index;
143 }
144 return index < 0 ? ensureSize(iter) + index : index;
145 }
146
147 function returnTrue() {
148 return true;
149 }
150
151 function wholeSlice(begin, end, size) {
152 return (begin === 0 || (size !== undefined && begin <= -size)) &&
153 (end === undefined || (size !== undefined && end >= size));
154 }
155
156 function resolveBegin(begin, size) {
157 return resolveIndex(begin, size, 0);
158 }
159
160 function resolveEnd(end, size) {
161 return resolveIndex(end, size, size);
162 }
163
164 function resolveIndex(index, size, defaultIndex) {
165 return index === undefined ?
166 defaultIndex :
167 index < 0 ?
168 Math.max(0, size + index) :
169 size === undefined ?
170 index :
171 Math.min(size, index);
172 }
173
174 /* global Symbol */
175
176 var ITERATE_KEYS = 0;
177 var ITERATE_VALUES = 1;
178 var ITERATE_ENTRIES = 2;
179
180 var REAL_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
181 var FAUX_ITERATOR_SYMBOL = '@@iterator';
182
183 var ITERATOR_SYMBOL = REAL_ITERATOR_SYMBOL || FAUX_ITERATOR_SYMBOL;
184
185
186 function Iterator(next) {
187 this.next = next;
188 }
189
190 Iterator.prototype.toString = function() {
191 return '[Iterator]';
192 };
193
194
195 Iterator.KEYS = ITERATE_KEYS;
196 Iterator.VALUES = ITERATE_VALUES;
197 Iterator.ENTRIES = ITERATE_ENTRIES;
198
199 Iterator.prototype.inspect =
200 Iterator.prototype.toSource = function () { return this.toString(); }
201 Iterator.prototype[ITERATOR_SYMBOL] = function () {
202 return this;
203 };
204
205
206 function iteratorValue(type, k, v, iteratorResult) {
207 var value = type === 0 ? k : type === 1 ? v : [k, v];
208 iteratorResult ? (iteratorResult.value = value) : (iteratorResult = {
209 value: value, done: false
210 });
211 return iteratorResult;
212 }
213
214 function iteratorDone() {
215 return { value: undefined, done: true };
216 }
217
218 function hasIterator(maybeIterable) {
219 return !!getIteratorFn(maybeIterable);
220 }
221
222 function isIterator(maybeIterator) {
223 return maybeIterator && typeof maybeIterator.next === 'function';
224 }
225
226 function getIterator(iterable) {
227 var iteratorFn = getIteratorFn(iterable);
228 return iteratorFn && iteratorFn.call(iterable);
229 }
230
231 function getIteratorFn(iterable) {
232 var iteratorFn = iterable && (
233 (REAL_ITERATOR_SYMBOL && iterable[REAL_ITERATOR_SYMBOL]) ||
234 iterable[FAUX_ITERATOR_SYMBOL]
235 );
236 if (typeof iteratorFn === 'function') {
237 return iteratorFn;
238 }
239 }
240
241 function isArrayLike(value) {
242 return value && typeof value.length === 'number';
243 }
244
245 createClass(Seq, Iterable);
246 function Seq(value) {
247 return value === null || value === undefined ? emptySequence() :
248 isIterable(value) ? value.toSeq() : seqFromValue(value);
249 }
250
251 Seq.of = function(/*...values*/) {
252 return Seq(arguments);
253 };
254
255 Seq.prototype.toSeq = function() {
256 return this;
257 };
258
259 Seq.prototype.toString = function() {
260 return this.__toString('Seq {', '}');
261 };
262
263 Seq.prototype.cacheResult = function() {
264 if (!this._cache && this.__iterateUncached) {
265 this._cache = this.entrySeq().toArray();
266 this.size = this._cache.length;
267 }
268 return this;
269 };
270
271 // abstract __iterateUncached(fn, reverse)
272
273 Seq.prototype.__iterate = function(fn, reverse) {
274 return seqIterate(this, fn, reverse, true);
275 };
276
277 // abstract __iteratorUncached(type, reverse)
278
279 Seq.prototype.__iterator = function(type, reverse) {
280 return seqIterator(this, type, reverse, true);
281 };
282
283
284
285 createClass(KeyedSeq, Seq);
286 function KeyedSeq(value) {
287 return value === null || value === undefined ?
288 emptySequence().toKeyedSeq() :
289 isIterable(value) ?
290 (isKeyed(value) ? value.toSeq() : value.fromEntrySeq()) :
291 keyedSeqFromValue(value);
292 }
293
294 KeyedSeq.prototype.toKeyedSeq = function() {
295 return this;
296 };
297
298
299
300 createClass(IndexedSeq, Seq);
301 function IndexedSeq(value) {
302 return value === null || value === undefined ? emptySequence() :
303 !isIterable(value) ? indexedSeqFromValue(value) :
304 isKeyed(value) ? value.entrySeq() : value.toIndexedSeq();
305 }
306
307 IndexedSeq.of = function(/*...values*/) {
308 return IndexedSeq(arguments);
309 };
310
311 IndexedSeq.prototype.toIndexedSeq = function() {
312 return this;
313 };
314
315 IndexedSeq.prototype.toString = function() {
316 return this.__toString('Seq [', ']');
317 };
318
319 IndexedSeq.prototype.__iterate = function(fn, reverse) {
320 return seqIterate(this, fn, reverse, false);
321 };
322
323 IndexedSeq.prototype.__iterator = function(type, reverse) {
324 return seqIterator(this, type, reverse, false);
325 };
326
327
328
329 createClass(SetSeq, Seq);
330 function SetSeq(value) {
331 return (
332 value === null || value === undefined ? emptySequence() :
333 !isIterable(value) ? indexedSeqFromValue(value) :
334 isKeyed(value) ? value.entrySeq() : value
335 ).toSetSeq();
336 }
337
338 SetSeq.of = function(/*...values*/) {
339 return SetSeq(arguments);
340 };
341
342 SetSeq.prototype.toSetSeq = function() {
343 return this;
344 };
345
346
347
348 Seq.isSeq = isSeq;
349 Seq.Keyed = KeyedSeq;
350 Seq.Set = SetSeq;
351 Seq.Indexed = IndexedSeq;
352
353 var IS_SEQ_SENTINEL = '@@__IMMUTABLE_SEQ__@@';
354
355 Seq.prototype[IS_SEQ_SENTINEL] = true;
356
357
358
359 createClass(ArraySeq, IndexedSeq);
360 function ArraySeq(array) {
361 this._array = array;
362 this.size = array.length;
363 }
364
365 ArraySeq.prototype.get = function(index, notSetValue) {
366 return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue;
367 };
368
369 ArraySeq.prototype.__iterate = function(fn, reverse) {
370 var array = this._array;
371 var maxIndex = array.length - 1;
372 for (var ii = 0; ii <= maxIndex; ii++) {
373 if (fn(array[reverse ? maxIndex - ii : ii], ii, this) === false) {
374 return ii + 1;
375 }
376 }
377 return ii;
378 };
379
380 ArraySeq.prototype.__iterator = function(type, reverse) {
381 var array = this._array;
382 var maxIndex = array.length - 1;
383 var ii = 0;
384 return new Iterator(function()
385 {return ii > maxIndex ?
386 iteratorDone() :
387 iteratorValue(type, ii, array[reverse ? maxIndex - ii++ : ii++])}
388 );
389 };
390
391
392
393 createClass(ObjectSeq, KeyedSeq);
394 function ObjectSeq(object) {
395 var keys = Object.keys(object);
396 this._object = object;
397 this._keys = keys;
398 this.size = keys.length;
399 }
400
401 ObjectSeq.prototype.get = function(key, notSetValue) {
402 if (notSetValue !== undefined && !this.has(key)) {
403 return notSetValue;
404 }
405 return this._object[key];
406 };
407
408 ObjectSeq.prototype.has = function(key) {
409 return this._object.hasOwnProperty(key);
410 };
411
412 ObjectSeq.prototype.__iterate = function(fn, reverse) {
413 var object = this._object;
414 var keys = this._keys;
415 var maxIndex = keys.length - 1;
416 for (var ii = 0; ii <= maxIndex; ii++) {
417 var key = keys[reverse ? maxIndex - ii : ii];
418 if (fn(object[key], key, this) === false) {
419 return ii + 1;
420 }
421 }
422 return ii;
423 };
424
425 ObjectSeq.prototype.__iterator = function(type, reverse) {
426 var object = this._object;
427 var keys = this._keys;
428 var maxIndex = keys.length - 1;
429 var ii = 0;
430 return new Iterator(function() {
431 var key = keys[reverse ? maxIndex - ii : ii];
432 return ii++ > maxIndex ?
433 iteratorDone() :
434 iteratorValue(type, key, object[key]);
435 });
436 };
437
438 ObjectSeq.prototype[IS_ORDERED_SENTINEL] = true;
439
440
441 createClass(IterableSeq, IndexedSeq);
442 function IterableSeq(iterable) {
443 this._iterable = iterable;
444 this.size = iterable.length || iterable.size;
445 }
446
447 IterableSeq.prototype.__iterateUncached = function(fn, reverse) {
448 if (reverse) {
449 return this.cacheResult().__iterate(fn, reverse);
450 }
451 var iterable = this._iterable;
452 var iterator = getIterator(iterable);
453 var iterations = 0;
454 if (isIterator(iterator)) {
455 var step;
456 while (!(step = iterator.next()).done) {
457 if (fn(step.value, iterations++, this) === false) {
458 break;
459 }
460 }
461 }
462 return iterations;
463 };
464
465 IterableSeq.prototype.__iteratorUncached = function(type, reverse) {
466 if (reverse) {
467 return this.cacheResult().__iterator(type, reverse);
468 }
469 var iterable = this._iterable;
470 var iterator = getIterator(iterable);
471 if (!isIterator(iterator)) {
472 return new Iterator(iteratorDone);
473 }
474 var iterations = 0;
475 return new Iterator(function() {
476 var step = iterator.next();
477 return step.done ? step : iteratorValue(type, iterations++, step.value);
478 });
479 };
480
481
482
483 createClass(IteratorSeq, IndexedSeq);
484 function IteratorSeq(iterator) {
485 this._iterator = iterator;
486 this._iteratorCache = [];
487 }
488
489 IteratorSeq.prototype.__iterateUncached = function(fn, reverse) {
490 if (reverse) {
491 return this.cacheResult().__iterate(fn, reverse);
492 }
493 var iterator = this._iterator;
494 var cache = this._iteratorCache;
495 var iterations = 0;
496 while (iterations < cache.length) {
497 if (fn(cache[iterations], iterations++, this) === false) {
498 return iterations;
499 }
500 }
501 var step;
502 while (!(step = iterator.next()).done) {
503 var val = step.value;
504 cache[iterations] = val;
505 if (fn(val, iterations++, this) === false) {
506 break;
507 }
508 }
509 return iterations;
510 };
511
512 IteratorSeq.prototype.__iteratorUncached = function(type, reverse) {
513 if (reverse) {
514 return this.cacheResult().__iterator(type, reverse);
515 }
516 var iterator = this._iterator;
517 var cache = this._iteratorCache;
518 var iterations = 0;
519 return new Iterator(function() {
520 if (iterations >= cache.length) {
521 var step = iterator.next();
522 if (step.done) {
523 return step;
524 }
525 cache[iterations] = step.value;
526 }
527 return iteratorValue(type, iterations, cache[iterations++]);
528 });
529 };
530
531
532
533
534 // # pragma Helper functions
535
536 function isSeq(maybeSeq) {
537 return !!(maybeSeq && maybeSeq[IS_SEQ_SENTINEL]);
538 }
539
540 var EMPTY_SEQ;
541
542 function emptySequence() {
543 return EMPTY_SEQ || (EMPTY_SEQ = new ArraySeq([]));
544 }
545
546 function keyedSeqFromValue(value) {
547 var seq =
548 Array.isArray(value) ? new ArraySeq(value).fromEntrySeq() :
549 isIterator(value) ? new IteratorSeq(value).fromEntrySeq() :
550 hasIterator(value) ? new IterableSeq(value).fromEntrySeq() :
551 typeof value === 'object' ? new ObjectSeq(value) :
552 undefined;
553 if (!seq) {
554 throw new TypeError(
555 'Expected Array or iterable object of [k, v] entries, '+
556 'or keyed object: ' + value
557 );
558 }
559 return seq;
560 }
561
562 function indexedSeqFromValue(value) {
563 var seq = maybeIndexedSeqFromValue(value);
564 if (!seq) {
565 throw new TypeError(
566 'Expected Array or iterable object of values: ' + value
567 );
568 }
569 return seq;
570 }
571
572 function seqFromValue(value) {
573 var seq = maybeIndexedSeqFromValue(value) ||
574 (typeof value === 'object' && new ObjectSeq(value));
575 if (!seq) {
576 throw new TypeError(
577 'Expected Array or iterable object of values, or keyed object: ' + value
578 );
579 }
580 return seq;
581 }
582
583 function maybeIndexedSeqFromValue(value) {
584 return (
585 isArrayLike(value) ? new ArraySeq(value) :
586 isIterator(value) ? new IteratorSeq(value) :
587 hasIterator(value) ? new IterableSeq(value) :
588 undefined
589 );
590 }
591
592 function seqIterate(seq, fn, reverse, useKeys) {
593 var cache = seq._cache;
594 if (cache) {
595 var maxIndex = cache.length - 1;
596 for (var ii = 0; ii <= maxIndex; ii++) {
597 var entry = cache[reverse ? maxIndex - ii : ii];
598 if (fn(entry[1], useKeys ? entry[0] : ii, seq) === false) {
599 return ii + 1;
600 }
601 }
602 return ii;
603 }
604 return seq.__iterateUncached(fn, reverse);
605 }
606
607 function seqIterator(seq, type, reverse, useKeys) {
608 var cache = seq._cache;
609 if (cache) {
610 var maxIndex = cache.length - 1;
611 var ii = 0;
612 return new Iterator(function() {
613 var entry = cache[reverse ? maxIndex - ii : ii];
614 return ii++ > maxIndex ?
615 iteratorDone() :
616 iteratorValue(type, useKeys ? entry[0] : ii - 1, entry[1]);
617 });
618 }
619 return seq.__iteratorUncached(type, reverse);
620 }
621
622 function fromJS(json, converter) {
623 return converter ?
624 fromJSWith(converter, json, '', {'': json}) :
625 fromJSDefault(json);
626 }
627
628 function fromJSWith(converter, json, key, parentJSON) {
629 if (Array.isArray(json)) {
630 return converter.call(parentJSON, key, IndexedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)}));
631 }
632 if (isPlainObj(json)) {
633 return converter.call(parentJSON, key, KeyedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)}));
634 }
635 return json;
636 }
637
638 function fromJSDefault(json) {
639 if (Array.isArray(json)) {
640 return IndexedSeq(json).map(fromJSDefault).toList();
641 }
642 if (isPlainObj(json)) {
643 return KeyedSeq(json).map(fromJSDefault).toMap();
644 }
645 return json;
646 }
647
648 function isPlainObj(value) {
649 return value && (value.constructor === Object || value.constructor === undefined);
650 }
651
652 /**
653 * An extension of the "same-value" algorithm as [described for use by ES6 Map
654 * and Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Key_equality)
655 *
656 * NaN is considered the same as NaN, however -0 and 0 are considered the same
657 * value, which is different from the algorithm described by
658 * [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is).
659 *
660 * This is extended further to allow Objects to describe the values they
661 * represent, by way of `valueOf` or `equals` (and `hashCode`).
662 *
663 * Note: because of this extension, the key equality of Immutable.Map and the
664 * value equality of Immutable.Set will differ from ES6 Map and Set.
665 *
666 * ### Defining custom values
667 *
668 * The easiest way to describe the value an object represents is by implementing
669 * `valueOf`. For example, `Date` represents a value by returning a unix
670 * timestamp for `valueOf`:
671 *
672 * var date1 = new Date(1234567890000); // Fri Feb 13 2009 ...
673 * var date2 = new Date(1234567890000);
674 * date1.valueOf(); // 1234567890000
675 * assert( date1 !== date2 );
676 * assert( Immutable.is( date1, date2 ) );
677 *
678 * Note: overriding `valueOf` may have other implications if you use this object
679 * where JavaScript expects a primitive, such as implicit string coercion.
680 *
681 * For more complex types, especially collections, implementing `valueOf` may
682 * not be performant. An alternative is to implement `equals` and `hashCode`.
683 *
684 * `equals` takes another object, presumably of similar type, and returns true
685 * if the it is equal. Equality is symmetrical, so the same result should be
686 * returned if this and the argument are flipped.
687 *
688 * assert( a.equals(b) === b.equals(a) );
689 *
690 * `hashCode` returns a 32bit integer number representing the object which will
691 * be used to determine how to store the value object in a Map or Set. You must
692 * provide both or neither methods, one must not exist without the other.
693 *
694 * Also, an important relationship between these methods must be upheld: if two
695 * values are equal, they *must* return the same hashCode. If the values are not
696 * equal, they might have the same hashCode; this is called a hash collision,
697 * and while undesirable for performance reasons, it is acceptable.
698 *
699 * if (a.equals(b)) {
700 * assert( a.hashCode() === b.hashCode() );
701 * }
702 *
703 * All Immutable collections implement `equals` and `hashCode`.
704 *
705 */
706 function is(valueA, valueB) {
707 if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) {
708 return true;
709 }
710 if (!valueA || !valueB) {
711 return false;
712 }
713 if (typeof valueA.valueOf === 'function' &&
714 typeof valueB.valueOf === 'function') {
715 valueA = valueA.valueOf();
716 valueB = valueB.valueOf();
717 if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) {
718 return true;
719 }
720 if (!valueA || !valueB) {
721 return false;
722 }
723 }
724 if (typeof valueA.equals === 'function' &&
725 typeof valueB.equals === 'function' &&
726 valueA.equals(valueB)) {
727 return true;
728 }
729 return false;
730 }
731
732 function deepEqual(a, b) {
733 if (a === b) {
734 return true;
735 }
736
737 if (
738 !isIterable(b) ||
739 a.size !== undefined && b.size !== undefined && a.size !== b.size ||
740 a.__hash !== undefined && b.__hash !== undefined && a.__hash !== b.__hash ||
741 isKeyed(a) !== isKeyed(b) ||
742 isIndexed(a) !== isIndexed(b) ||
743 isOrdered(a) !== isOrdered(b)
744 ) {
745 return false;
746 }
747
748 if (a.size === 0 && b.size === 0) {
749 return true;
750 }
751
752 var notAssociative = !isAssociative(a);
753
754 if (isOrdered(a)) {
755 var entries = a.entries();
756 return b.every(function(v, k) {
757 var entry = entries.next().value;
758 return entry && is(entry[1], v) && (notAssociative || is(entry[0], k));
759 }) && entries.next().done;
760 }
761
762 var flipped = false;
763
764 if (a.size === undefined) {
765 if (b.size === undefined) {
766 if (typeof a.cacheResult === 'function') {
767 a.cacheResult();
768 }
769 } else {
770 flipped = true;
771 var _ = a;
772 a = b;
773 b = _;
774 }
775 }
776
777 var allEqual = true;
778 var bSize = b.__iterate(function(v, k) {
779 if (notAssociative ? !a.has(v) :
780 flipped ? !is(v, a.get(k, NOT_SET)) : !is(a.get(k, NOT_SET), v)) {
781 allEqual = false;
782 return false;
783 }
784 });
785
786 return allEqual && a.size === bSize;
787 }
788
789 createClass(Repeat, IndexedSeq);
790
791 function Repeat(value, times) {
792 if (!(this instanceof Repeat)) {
793 return new Repeat(value, times);
794 }
795 this._value = value;
796 this.size = times === undefined ? Infinity : Math.max(0, times);
797 if (this.size === 0) {
798 if (EMPTY_REPEAT) {
799 return EMPTY_REPEAT;
800 }
801 EMPTY_REPEAT = this;
802 }
803 }
804
805 Repeat.prototype.toString = function() {
806 if (this.size === 0) {
807 return 'Repeat []';
808 }
809 return 'Repeat [ ' + this._value + ' ' + this.size + ' times ]';
810 };
811
812 Repeat.prototype.get = function(index, notSetValue) {
813 return this.has(index) ? this._value : notSetValue;
814 };
815
816 Repeat.prototype.includes = function(searchValue) {
817 return is(this._value, searchValue);
818 };
819
820 Repeat.prototype.slice = function(begin, end) {
821 var size = this.size;
822 return wholeSlice(begin, end, size) ? this :
823 new Repeat(this._value, resolveEnd(end, size) - resolveBegin(begin, size));
824 };
825
826 Repeat.prototype.reverse = function() {
827 return this;
828 };
829
830 Repeat.prototype.indexOf = function(searchValue) {
831 if (is(this._value, searchValue)) {
832 return 0;
833 }
834 return -1;
835 };
836
837 Repeat.prototype.lastIndexOf = function(searchValue) {
838 if (is(this._value, searchValue)) {
839 return this.size;
840 }
841 return -1;
842 };
843
844 Repeat.prototype.__iterate = function(fn, reverse) {
845 for (var ii = 0; ii < this.size; ii++) {
846 if (fn(this._value, ii, this) === false) {
847 return ii + 1;
848 }
849 }
850 return ii;
851 };
852
853 Repeat.prototype.__iterator = function(type, reverse) {var this$0 = this;
854 var ii = 0;
855 return new Iterator(function()
856 {return ii < this$0.size ? iteratorValue(type, ii++, this$0._value) : iteratorDone()}
857 );
858 };
859
860 Repeat.prototype.equals = function(other) {
861 return other instanceof Repeat ?
862 is(this._value, other._value) :
863 deepEqual(other);
864 };
865
866
867 var EMPTY_REPEAT;
868
869 function invariant(condition, error) {
870 if (!condition) throw new Error(error);
871 }
872
873 createClass(Range, IndexedSeq);
874
875 function Range(start, end, step) {
876 if (!(this instanceof Range)) {
877 return new Range(start, end, step);
878 }
879 invariant(step !== 0, 'Cannot step a Range by 0');
880 start = start || 0;
881 if (end === undefined) {
882 end = Infinity;
883 }
884 step = step === undefined ? 1 : Math.abs(step);
885 if (end < start) {
886 step = -step;
887 }
888 this._start = start;
889 this._end = end;
890 this._step = step;
891 this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1);
892 if (this.size === 0) {
893 if (EMPTY_RANGE) {
894 return EMPTY_RANGE;
895 }
896 EMPTY_RANGE = this;
897 }
898 }
899
900 Range.prototype.toString = function() {
901 if (this.size === 0) {
902 return 'Range []';
903 }
904 return 'Range [ ' +
905 this._start + '...' + this._end +
906 (this._step !== 1 ? ' by ' + this._step : '') +
907 ' ]';
908 };
909
910 Range.prototype.get = function(index, notSetValue) {
911 return this.has(index) ?
912 this._start + wrapIndex(this, index) * this._step :
913 notSetValue;
914 };
915
916 Range.prototype.includes = function(searchValue) {
917 var possibleIndex = (searchValue - this._start) / this._step;
918 return possibleIndex >= 0 &&
919 possibleIndex < this.size &&
920 possibleIndex === Math.floor(possibleIndex);
921 };
922
923 Range.prototype.slice = function(begin, end) {
924 if (wholeSlice(begin, end, this.size)) {
925 return this;
926 }
927 begin = resolveBegin(begin, this.size);
928 end = resolveEnd(end, this.size);
929 if (end <= begin) {
930 return new Range(0, 0);
931 }
932 return new Range(this.get(begin, this._end), this.get(end, this._end), this._step);
933 };
934
935 Range.prototype.indexOf = function(searchValue) {
936 var offsetValue = searchValue - this._start;
937 if (offsetValue % this._step === 0) {
938 var index = offsetValue / this._step;
939 if (index >= 0 && index < this.size) {
940 return index
941 }
942 }
943 return -1;
944 };
945
946 Range.prototype.lastIndexOf = function(searchValue) {
947 return this.indexOf(searchValue);
948 };
949
950 Range.prototype.__iterate = function(fn, reverse) {
951 var maxIndex = this.size - 1;
952 var step = this._step;
953 var value = reverse ? this._start + maxIndex * step : this._start;
954 for (var ii = 0; ii <= maxIndex; ii++) {
955 if (fn(value, ii, this) === false) {
956 return ii + 1;
957 }
958 value += reverse ? -step : step;
959 }
960 return ii;
961 };
962
963 Range.prototype.__iterator = function(type, reverse) {
964 var maxIndex = this.size - 1;
965 var step = this._step;
966 var value = reverse ? this._start + maxIndex * step : this._start;
967 var ii = 0;
968 return new Iterator(function() {
969 var v = value;
970 value += reverse ? -step : step;
971 return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii++, v);
972 });
973 };
974
975 Range.prototype.equals = function(other) {
976 return other instanceof Range ?
977 this._start === other._start &&
978 this._end === other._end &&
979 this._step === other._step :
980 deepEqual(this, other);
981 };
982
983
984 var EMPTY_RANGE;
985
986 createClass(Collection, Iterable);
987 function Collection() {
988 throw TypeError('Abstract');
989 }
990
991
992 createClass(KeyedCollection, Collection);function KeyedCollection() {}
993
994 createClass(IndexedCollection, Collection);function IndexedCollection() {}
995
996 createClass(SetCollection, Collection);function SetCollection() {}
997
998
999 Collection.Keyed = KeyedCollection;
1000 Collection.Indexed = IndexedCollection;
1001 Collection.Set = SetCollection;
1002
1003 var imul =
1004 typeof Math.imul === 'function' && Math.imul(0xffffffff, 2) === -2 ?
1005 Math.imul :
1006 function imul(a, b) {
1007 a = a | 0; // int
1008 b = b | 0; // int
1009 var c = a & 0xffff;
1010 var d = b & 0xffff;
1011 // Shift by 0 fixes the sign on the high part.
1012 return (c * d) + ((((a >>> 16) * d + c * (b >>> 16)) << 16) >>> 0) | 0; // int
1013 };
1014
1015 // v8 has an optimization for storing 31-bit signed numbers.
1016 // Values which have either 00 or 11 as the high order bits qualify.
1017 // This function drops the highest order bit in a signed number, maintaining
1018 // the sign bit.
1019 function smi(i32) {
1020 return ((i32 >>> 1) & 0x40000000) | (i32 & 0xBFFFFFFF);
1021 }
1022
1023 function hash(o) {
1024 if (o === false || o === null || o === undefined) {
1025 return 0;
1026 }
1027 if (typeof o.valueOf === 'function') {
1028 o = o.valueOf();
1029 if (o === false || o === null || o === undefined) {
1030 return 0;
1031 }
1032 }
1033 if (o === true) {
1034 return 1;
1035 }
1036 var type = typeof o;
1037 if (type === 'number') {
1038 if (o !== o || o === Infinity) {
1039 return 0;
1040 }
1041 var h = o | 0;
1042 if (h !== o) {
1043 h ^= o * 0xFFFFFFFF;
1044 }
1045 while (o > 0xFFFFFFFF) {
1046 o /= 0xFFFFFFFF;
1047 h ^= o;
1048 }
1049 return smi(h);
1050 }
1051 if (type === 'string') {
1052 return o.length > STRING_HASH_CACHE_MIN_STRLEN ? cachedHashString(o) : hashString(o);
1053 }
1054 if (typeof o.hashCode === 'function') {
1055 return o.hashCode();
1056 }
1057 if (type === 'object') {
1058 return hashJSObj(o);
1059 }
1060 if (typeof o.toString === 'function') {
1061 return hashString(o.toString());
1062 }
1063 throw new Error('Value type ' + type + ' cannot be hashed.');
1064 }
1065
1066 function cachedHashString(string) {
1067 var hash = stringHashCache[string];
1068 if (hash === undefined) {
1069 hash = hashString(string);
1070 if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) {
1071 STRING_HASH_CACHE_SIZE = 0;
1072 stringHashCache = {};
1073 }
1074 STRING_HASH_CACHE_SIZE++;
1075 stringHashCache[string] = hash;
1076 }
1077 return hash;
1078 }
1079
1080 // http://jsperf.com/hashing-strings
1081 function hashString(string) {
1082 // This is the hash from JVM
1083 // The hash code for a string is computed as
1084 // s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1],
1085 // where s[i] is the ith character of the string and n is the length of
1086 // the string. We "mod" the result to make it between 0 (inclusive) and 2^31
1087 // (exclusive) by dropping high bits.
1088 var hash = 0;
1089 for (var ii = 0; ii < string.length; ii++) {
1090 hash = 31 * hash + string.charCodeAt(ii) | 0;
1091 }
1092 return smi(hash);
1093 }
1094
1095 function hashJSObj(obj) {
1096 var hash;
1097 if (usingWeakMap) {
1098 hash = weakMap.get(obj);
1099 if (hash !== undefined) {
1100 return hash;
1101 }
1102 }
1103
1104 hash = obj[UID_HASH_KEY];
1105 if (hash !== undefined) {
1106 return hash;
1107 }
1108
1109 if (!canDefineProperty) {
1110 hash = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY];
1111 if (hash !== undefined) {
1112 return hash;
1113 }
1114
1115 hash = getIENodeHash(obj);
1116 if (hash !== undefined) {
1117 return hash;
1118 }
1119 }
1120
1121 hash = ++objHashUID;
1122 if (objHashUID & 0x40000000) {
1123 objHashUID = 0;
1124 }
1125
1126 if (usingWeakMap) {
1127 weakMap.set(obj, hash);
1128 } else if (isExtensible !== undefined && isExtensible(obj) === false) {
1129 throw new Error('Non-extensible objects are not allowed as keys.');
1130 } else if (canDefineProperty) {
1131 Object.defineProperty(obj, UID_HASH_KEY, {
1132 'enumerable': false,
1133 'configurable': false,
1134 'writable': false,
1135 'value': hash
1136 });
1137 } else if (obj.propertyIsEnumerable !== undefined &&
1138 obj.propertyIsEnumerable === obj.constructor.prototype.propertyIsEnumerable) {
1139 // Since we can't define a non-enumerable property on the object
1140 // we'll hijack one of the less-used non-enumerable properties to
1141 // save our hash on it. Since this is a function it will not show up in
1142 // `JSON.stringify` which is what we want.
1143 obj.propertyIsEnumerable = function() {
1144 return this.constructor.prototype.propertyIsEnumerable.apply(this, arguments);
1145 };
1146 obj.propertyIsEnumerable[UID_HASH_KEY] = hash;
1147 } else if (obj.nodeType !== undefined) {
1148 // At this point we couldn't get the IE `uniqueID` to use as a hash
1149 // and we couldn't use a non-enumerable property to exploit the
1150 // dontEnum bug so we simply add the `UID_HASH_KEY` on the node
1151 // itself.
1152 obj[UID_HASH_KEY] = hash;
1153 } else {
1154 throw new Error('Unable to set a non-enumerable property on object.');
1155 }
1156
1157 return hash;
1158 }
1159
1160 // Get references to ES5 object methods.
1161 var isExtensible = Object.isExtensible;
1162
1163 // True if Object.defineProperty works as expected. IE8 fails this test.
1164 var canDefineProperty = (function() {
1165 try {
1166 Object.defineProperty({}, '@', {});
1167 return true;
1168 } catch (e) {
1169 return false;
1170 }
1171 }());
1172
1173 // IE has a `uniqueID` property on DOM nodes. We can construct the hash from it
1174 // and avoid memory leaks from the IE cloneNode bug.
1175 function getIENodeHash(node) {
1176 if (node && node.nodeType > 0) {
1177 switch (node.nodeType) {
1178 case 1: // Element
1179 return node.uniqueID;
1180 case 9: // Document
1181 return node.documentElement && node.documentElement.uniqueID;
1182 }
1183 }
1184 }
1185
1186 // If possible, use a WeakMap.
1187 var usingWeakMap = typeof WeakMap === 'function';
1188 var weakMap;
1189 if (usingWeakMap) {
1190 weakMap = new WeakMap();
1191 }
1192
1193 var objHashUID = 0;
1194
1195 var UID_HASH_KEY = '__immutablehash__';
1196 if (typeof Symbol === 'function') {
1197 UID_HASH_KEY = Symbol(UID_HASH_KEY);
1198 }
1199
1200 var STRING_HASH_CACHE_MIN_STRLEN = 16;
1201 var STRING_HASH_CACHE_MAX_SIZE = 255;
1202 var STRING_HASH_CACHE_SIZE = 0;
1203 var stringHashCache = {};
1204
1205 function assertNotInfinite(size) {
1206 invariant(
1207 size !== Infinity,
1208 'Cannot perform this action with an infinite size.'
1209 );
1210 }
1211
1212 createClass(Map, KeyedCollection);
1213
1214 // @pragma Construction
1215
1216 function Map(value) {
1217 return value === null || value === undefined ? emptyMap() :
1218 isMap(value) && !isOrdered(value) ? value :
1219 emptyMap().withMutations(function(map ) {
1220 var iter = KeyedIterable(value);
1221 assertNotInfinite(iter.size);
1222 iter.forEach(function(v, k) {return map.set(k, v)});
1223 });
1224 }
1225
1226 Map.of = function() {var keyValues = SLICE$0.call(arguments, 0);
1227 return emptyMap().withMutations(function(map ) {
1228 for (var i = 0; i < keyValues.length; i += 2) {
1229 if (i + 1 >= keyValues.length) {
1230 throw new Error('Missing value for key: ' + keyValues[i]);
1231 }
1232 map.set(keyValues[i], keyValues[i + 1]);
1233 }
1234 });
1235 };
1236
1237 Map.prototype.toString = function() {
1238 return this.__toString('Map {', '}');
1239 };
1240
1241 // @pragma Access
1242
1243 Map.prototype.get = function(k, notSetValue) {
1244 return this._root ?
1245 this._root.get(0, undefined, k, notSetValue) :
1246 notSetValue;
1247 };
1248
1249 // @pragma Modification
1250
1251 Map.prototype.set = function(k, v) {
1252 return updateMap(this, k, v);
1253 };
1254
1255 Map.prototype.setIn = function(keyPath, v) {
1256 return this.updateIn(keyPath, NOT_SET, function() {return v});
1257 };
1258
1259 Map.prototype.remove = function(k) {
1260 return updateMap(this, k, NOT_SET);
1261 };
1262
1263 Map.prototype.deleteIn = function(keyPath) {
1264 return this.updateIn(keyPath, function() {return NOT_SET});
1265 };
1266
1267 Map.prototype.update = function(k, notSetValue, updater) {
1268 return arguments.length === 1 ?
1269 k(this) :
1270 this.updateIn([k], notSetValue, updater);
1271 };
1272
1273 Map.prototype.updateIn = function(keyPath, notSetValue, updater) {
1274 if (!updater) {
1275 updater = notSetValue;
1276 notSetValue = undefined;
1277 }
1278 var updatedValue = updateInDeepMap(
1279 this,
1280 forceIterator(keyPath),
1281 notSetValue,
1282 updater
1283 );
1284 return updatedValue === NOT_SET ? undefined : updatedValue;
1285 };
1286
1287 Map.prototype.clear = function() {
1288 if (this.size === 0) {
1289 return this;
1290 }
1291 if (this.__ownerID) {
1292 this.size = 0;
1293 this._root = null;
1294 this.__hash = undefined;
1295 this.__altered = true;
1296 return this;
1297 }
1298 return emptyMap();
1299 };
1300
1301 // @pragma Composition
1302
1303 Map.prototype.merge = function(/*...iters*/) {
1304 return mergeIntoMapWith(this, undefined, arguments);
1305 };
1306
1307 Map.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
1308 return mergeIntoMapWith(this, merger, iters);
1309 };
1310
1311 Map.prototype.mergeIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1);
1312 return this.updateIn(
1313 keyPath,
1314 emptyMap(),
1315 function(m ) {return typeof m.merge === 'function' ?
1316 m.merge.apply(m, iters) :
1317 iters[iters.length - 1]}
1318 );
1319 };
1320
1321 Map.prototype.mergeDeep = function(/*...iters*/) {
1322 return mergeIntoMapWith(this, deepMerger, arguments);
1323 };
1324
1325 Map.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
1326 return mergeIntoMapWith(this, deepMergerWith(merger), iters);
1327 };
1328
1329 Map.prototype.mergeDeepIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1);
1330 return this.updateIn(
1331 keyPath,
1332 emptyMap(),
1333 function(m ) {return typeof m.mergeDeep === 'function' ?
1334 m.mergeDeep.apply(m, iters) :
1335 iters[iters.length - 1]}
1336 );
1337 };
1338
1339 Map.prototype.sort = function(comparator) {
1340 // Late binding
1341 return OrderedMap(sortFactory(this, comparator));
1342 };
1343
1344 Map.prototype.sortBy = function(mapper, comparator) {
1345 // Late binding
1346 return OrderedMap(sortFactory(this, comparator, mapper));
1347 };
1348
1349 // @pragma Mutability
1350
1351 Map.prototype.withMutations = function(fn) {
1352 var mutable = this.asMutable();
1353 fn(mutable);
1354 return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this;
1355 };
1356
1357 Map.prototype.asMutable = function() {
1358 return this.__ownerID ? this : this.__ensureOwner(new OwnerID());
1359 };
1360
1361 Map.prototype.asImmutable = function() {
1362 return this.__ensureOwner();
1363 };
1364
1365 Map.prototype.wasAltered = function() {
1366 return this.__altered;
1367 };
1368
1369 Map.prototype.__iterator = function(type, reverse) {
1370 return new MapIterator(this, type, reverse);
1371 };
1372
1373 Map.prototype.__iterate = function(fn, reverse) {var this$0 = this;
1374 var iterations = 0;
1375 this._root && this._root.iterate(function(entry ) {
1376 iterations++;
1377 return fn(entry[1], entry[0], this$0);
1378 }, reverse);
1379 return iterations;
1380 };
1381
1382 Map.prototype.__ensureOwner = function(ownerID) {
1383 if (ownerID === this.__ownerID) {
1384 return this;
1385 }
1386 if (!ownerID) {
1387 this.__ownerID = ownerID;
1388 this.__altered = false;
1389 return this;
1390 }
1391 return makeMap(this.size, this._root, ownerID, this.__hash);
1392 };
1393
1394
1395 function isMap(maybeMap) {
1396 return !!(maybeMap && maybeMap[IS_MAP_SENTINEL]);
1397 }
1398
1399 Map.isMap = isMap;
1400
1401 var IS_MAP_SENTINEL = '@@__IMMUTABLE_MAP__@@';
1402
1403 var MapPrototype = Map.prototype;
1404 MapPrototype[IS_MAP_SENTINEL] = true;
1405 MapPrototype[DELETE] = MapPrototype.remove;
1406 MapPrototype.removeIn = MapPrototype.deleteIn;
1407
1408
1409 // #pragma Trie Nodes
1410
1411
1412
1413 function ArrayMapNode(ownerID, entries) {
1414 this.ownerID = ownerID;
1415 this.entries = entries;
1416 }
1417
1418 ArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) {
1419 var entries = this.entries;
1420 for (var ii = 0, len = entries.length; ii < len; ii++) {
1421 if (is(key, entries[ii][0])) {
1422 return entries[ii][1];
1423 }
1424 }
1425 return notSetValue;
1426 };
1427
1428 ArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
1429 var removed = value === NOT_SET;
1430
1431 var entries = this.entries;
1432 var idx = 0;
1433 for (var len = entries.length; idx < len; idx++) {
1434 if (is(key, entries[idx][0])) {
1435 break;
1436 }
1437 }
1438 var exists = idx < len;
1439
1440 if (exists ? entries[idx][1] === value : removed) {
1441 return this;
1442 }
1443
1444 SetRef(didAlter);
1445 (removed || !exists) && SetRef(didChangeSize);
1446
1447 if (removed && entries.length === 1) {
1448 return; // undefined
1449 }
1450
1451 if (!exists && !removed && entries.length >= MAX_ARRAY_MAP_SIZE) {
1452 return createNodes(ownerID, entries, key, value);
1453 }
1454
1455 var isEditable = ownerID && ownerID === this.ownerID;
1456 var newEntries = isEditable ? entries : arrCopy(entries);
1457
1458 if (exists) {
1459 if (removed) {
1460 idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop());
1461 } else {
1462 newEntries[idx] = [key, value];
1463 }
1464 } else {
1465 newEntries.push([key, value]);
1466 }
1467
1468 if (isEditable) {
1469 this.entries = newEntries;
1470 return this;
1471 }
1472
1473 return new ArrayMapNode(ownerID, newEntries);
1474 };
1475
1476
1477
1478
1479 function BitmapIndexedNode(ownerID, bitmap, nodes) {
1480 this.ownerID = ownerID;
1481 this.bitmap = bitmap;
1482 this.nodes = nodes;
1483 }
1484
1485 BitmapIndexedNode.prototype.get = function(shift, keyHash, key, notSetValue) {
1486 if (keyHash === undefined) {
1487 keyHash = hash(key);
1488 }
1489 var bit = (1 << ((shift === 0 ? keyHash : keyHash >>> shift) & MASK));
1490 var bitmap = this.bitmap;
1491 return (bitmap & bit) === 0 ? notSetValue :
1492 this.nodes[popCount(bitmap & (bit - 1))].get(shift + SHIFT, keyHash, key, notSetValue);
1493 };
1494
1495 BitmapIndexedNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
1496 if (keyHash === undefined) {
1497 keyHash = hash(key);
1498 }
1499 var keyHashFrag = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
1500 var bit = 1 << keyHashFrag;
1501 var bitmap = this.bitmap;
1502 var exists = (bitmap & bit) !== 0;
1503
1504 if (!exists && value === NOT_SET) {
1505 return this;
1506 }
1507
1508 var idx = popCount(bitmap & (bit - 1));
1509 var nodes = this.nodes;
1510 var node = exists ? nodes[idx] : undefined;
1511 var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter);
1512
1513 if (newNode === node) {
1514 return this;
1515 }
1516
1517 if (!exists && newNode && nodes.length >= MAX_BITMAP_INDEXED_SIZE) {
1518 return expandNodes(ownerID, nodes, bitmap, keyHashFrag, newNode);
1519 }
1520
1521 if (exists && !newNode && nodes.length === 2 && isLeafNode(nodes[idx ^ 1])) {
1522 return nodes[idx ^ 1];
1523 }
1524
1525 if (exists && newNode && nodes.length === 1 && isLeafNode(newNode)) {
1526 return newNode;
1527 }
1528
1529 var isEditable = ownerID && ownerID === this.ownerID;
1530 var newBitmap = exists ? newNode ? bitmap : bitmap ^ bit : bitmap | bit;
1531 var newNodes = exists ? newNode ?
1532 setIn(nodes, idx, newNode, isEditable) :
1533 spliceOut(nodes, idx, isEditable) :
1534 spliceIn(nodes, idx, newNode, isEditable);
1535
1536 if (isEditable) {
1537 this.bitmap = newBitmap;
1538 this.nodes = newNodes;
1539 return this;
1540 }
1541
1542 return new BitmapIndexedNode(ownerID, newBitmap, newNodes);
1543 };
1544
1545
1546
1547
1548 function HashArrayMapNode(ownerID, count, nodes) {
1549 this.ownerID = ownerID;
1550 this.count = count;
1551 this.nodes = nodes;
1552 }
1553
1554 HashArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) {
1555 if (keyHash === undefined) {
1556 keyHash = hash(key);
1557 }
1558 var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
1559 var node = this.nodes[idx];
1560 return node ? node.get(shift + SHIFT, keyHash, key, notSetValue) : notSetValue;
1561 };
1562
1563 HashArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
1564 if (keyHash === undefined) {
1565 keyHash = hash(key);
1566 }
1567 var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
1568 var removed = value === NOT_SET;
1569 var nodes = this.nodes;
1570 var node = nodes[idx];
1571
1572 if (removed && !node) {
1573 return this;
1574 }
1575
1576 var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter);
1577 if (newNode === node) {
1578 return this;
1579 }
1580
1581 var newCount = this.count;
1582 if (!node) {
1583 newCount++;
1584 } else if (!newNode) {
1585 newCount--;
1586 if (newCount < MIN_HASH_ARRAY_MAP_SIZE) {
1587 return packNodes(ownerID, nodes, newCount, idx);
1588 }
1589 }
1590
1591 var isEditable = ownerID && ownerID === this.ownerID;
1592 var newNodes = setIn(nodes, idx, newNode, isEditable);
1593
1594 if (isEditable) {
1595 this.count = newCount;
1596 this.nodes = newNodes;
1597 return this;
1598 }
1599
1600 return new HashArrayMapNode(ownerID, newCount, newNodes);
1601 };
1602
1603
1604
1605
1606 function HashCollisionNode(ownerID, keyHash, entries) {
1607 this.ownerID = ownerID;
1608 this.keyHash = keyHash;
1609 this.entries = entries;
1610 }
1611
1612 HashCollisionNode.prototype.get = function(shift, keyHash, key, notSetValue) {
1613 var entries = this.entries;
1614 for (var ii = 0, len = entries.length; ii < len; ii++) {
1615 if (is(key, entries[ii][0])) {
1616 return entries[ii][1];
1617 }
1618 }
1619 return notSetValue;
1620 };
1621
1622 HashCollisionNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
1623 if (keyHash === undefined) {
1624 keyHash = hash(key);
1625 }
1626
1627 var removed = value === NOT_SET;
1628
1629 if (keyHash !== this.keyHash) {
1630 if (removed) {
1631 return this;
1632 }
1633 SetRef(didAlter);
1634 SetRef(didChangeSize);
1635 return mergeIntoNode(this, ownerID, shift, keyHash, [key, value]);
1636 }
1637
1638 var entries = this.entries;
1639 var idx = 0;
1640 for (var len = entries.length; idx < len; idx++) {
1641 if (is(key, entries[idx][0])) {
1642 break;
1643 }
1644 }
1645 var exists = idx < len;
1646
1647 if (exists ? entries[idx][1] === value : removed) {
1648 return this;
1649 }
1650
1651 SetRef(didAlter);
1652 (removed || !exists) && SetRef(didChangeSize);
1653
1654 if (removed && len === 2) {
1655 return new ValueNode(ownerID, this.keyHash, entries[idx ^ 1]);
1656 }
1657
1658 var isEditable = ownerID && ownerID === this.ownerID;
1659 var newEntries = isEditable ? entries : arrCopy(entries);
1660
1661 if (exists) {
1662 if (removed) {
1663 idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop());
1664 } else {
1665 newEntries[idx] = [key, value];
1666 }
1667 } else {
1668 newEntries.push([key, value]);
1669 }
1670
1671 if (isEditable) {
1672 this.entries = newEntries;
1673 return this;
1674 }
1675
1676 return new HashCollisionNode(ownerID, this.keyHash, newEntries);
1677 };
1678
1679
1680
1681
1682 function ValueNode(ownerID, keyHash, entry) {
1683 this.ownerID = ownerID;
1684 this.keyHash = keyHash;
1685 this.entry = entry;
1686 }
1687
1688 ValueNode.prototype.get = function(shift, keyHash, key, notSetValue) {
1689 return is(key, this.entry[0]) ? this.entry[1] : notSetValue;
1690 };
1691
1692 ValueNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
1693 var removed = value === NOT_SET;
1694 var keyMatch = is(key, this.entry[0]);
1695 if (keyMatch ? value === this.entry[1] : removed) {
1696 return this;
1697 }
1698
1699 SetRef(didAlter);
1700
1701 if (removed) {
1702 SetRef(didChangeSize);
1703 return; // undefined
1704 }
1705
1706 if (keyMatch) {
1707 if (ownerID && ownerID === this.ownerID) {
1708 this.entry[1] = value;
1709 return this;
1710 }
1711 return new ValueNode(ownerID, this.keyHash, [key, value]);
1712 }
1713
1714 SetRef(didChangeSize);
1715 return mergeIntoNode(this, ownerID, shift, hash(key), [key, value]);
1716 };
1717
1718
1719
1720 // #pragma Iterators
1721
1722 ArrayMapNode.prototype.iterate =
1723 HashCollisionNode.prototype.iterate = function (fn, reverse) {
1724 var entries = this.entries;
1725 for (var ii = 0, maxIndex = entries.length - 1; ii <= maxIndex; ii++) {
1726 if (fn(entries[reverse ? maxIndex - ii : ii]) === false) {
1727 return false;
1728 }
1729 }
1730 }
1731
1732 BitmapIndexedNode.prototype.iterate =
1733 HashArrayMapNode.prototype.iterate = function (fn, reverse) {
1734 var nodes = this.nodes;
1735 for (var ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) {
1736 var node = nodes[reverse ? maxIndex - ii : ii];
1737 if (node && node.iterate(fn, reverse) === false) {
1738 return false;
1739 }
1740 }
1741 }
1742
1743 ValueNode.prototype.iterate = function (fn, reverse) {
1744 return fn(this.entry);
1745 }
1746
1747 createClass(MapIterator, Iterator);
1748
1749 function MapIterator(map, type, reverse) {
1750 this._type = type;
1751 this._reverse = reverse;
1752 this._stack = map._root && mapIteratorFrame(map._root);
1753 }
1754
1755 MapIterator.prototype.next = function() {
1756 var type = this._type;
1757 var stack = this._stack;
1758 while (stack) {
1759 var node = stack.node;
1760 var index = stack.index++;
1761 var maxIndex;
1762 if (node.entry) {
1763 if (index === 0) {
1764 return mapIteratorValue(type, node.entry);
1765 }
1766 } else if (node.entries) {
1767 maxIndex = node.entries.length - 1;
1768 if (index <= maxIndex) {
1769 return mapIteratorValue(type, node.entries[this._reverse ? maxIndex - index : index]);
1770 }
1771 } else {
1772 maxIndex = node.nodes.length - 1;
1773 if (index <= maxIndex) {
1774 var subNode = node.nodes[this._reverse ? maxIndex - index : index];
1775 if (subNode) {
1776 if (subNode.entry) {
1777 return mapIteratorValue(type, subNode.entry);
1778 }
1779 stack = this._stack = mapIteratorFrame(subNode, stack);
1780 }
1781 continue;
1782 }
1783 }
1784 stack = this._stack = this._stack.__prev;
1785 }
1786 return iteratorDone();
1787 };
1788
1789
1790 function mapIteratorValue(type, entry) {
1791 return iteratorValue(type, entry[0], entry[1]);
1792 }
1793
1794 function mapIteratorFrame(node, prev) {
1795 return {
1796 node: node,
1797 index: 0,
1798 __prev: prev
1799 };
1800 }
1801
1802 function makeMap(size, root, ownerID, hash) {
1803 var map = Object.create(MapPrototype);
1804 map.size = size;
1805 map._root = root;
1806 map.__ownerID = ownerID;
1807 map.__hash = hash;
1808 map.__altered = false;
1809 return map;
1810 }
1811
1812 var EMPTY_MAP;
1813 function emptyMap() {
1814 return EMPTY_MAP || (EMPTY_MAP = makeMap(0));
1815 }
1816
1817 function updateMap(map, k, v) {
1818 var newRoot;
1819 var newSize;
1820 if (!map._root) {
1821 if (v === NOT_SET) {
1822 return map;
1823 }
1824 newSize = 1;
1825 newRoot = new ArrayMapNode(map.__ownerID, [[k, v]]);
1826 } else {
1827 var didChangeSize = MakeRef(CHANGE_LENGTH);
1828 var didAlter = MakeRef(DID_ALTER);
1829 newRoot = updateNode(map._root, map.__ownerID, 0, undefined, k, v, didChangeSize, didAlter);
1830 if (!didAlter.value) {
1831 return map;
1832 }
1833 newSize = map.size + (didChangeSize.value ? v === NOT_SET ? -1 : 1 : 0);
1834 }
1835 if (map.__ownerID) {
1836 map.size = newSize;
1837 map._root = newRoot;
1838 map.__hash = undefined;
1839 map.__altered = true;
1840 return map;
1841 }
1842 return newRoot ? makeMap(newSize, newRoot) : emptyMap();
1843 }
1844
1845 function updateNode(node, ownerID, shift, keyHash, key, value, didChangeSize, didAlter) {
1846 if (!node) {
1847 if (value === NOT_SET) {
1848 return node;
1849 }
1850 SetRef(didAlter);
1851 SetRef(didChangeSize);
1852 return new ValueNode(ownerID, keyHash, [key, value]);
1853 }
1854 return node.update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter);
1855 }
1856
1857 function isLeafNode(node) {
1858 return node.constructor === ValueNode || node.constructor === HashCollisionNode;
1859 }
1860
1861 function mergeIntoNode(node, ownerID, shift, keyHash, entry) {
1862 if (node.keyHash === keyHash) {
1863 return new HashCollisionNode(ownerID, keyHash, [node.entry, entry]);
1864 }
1865
1866 var idx1 = (shift === 0 ? node.keyHash : node.keyHash >>> shift) & MASK;
1867 var idx2 = (shift === 0 ? keyHash : keyHash >>> shift) & MASK;
1868
1869 var newNode;
1870 var nodes = idx1 === idx2 ?
1871 [mergeIntoNode(node, ownerID, shift + SHIFT, keyHash, entry)] :
1872 ((newNode = new ValueNode(ownerID, keyHash, entry)), idx1 < idx2 ? [node, newNode] : [newNode, node]);
1873
1874 return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes);
1875 }
1876
1877 function createNodes(ownerID, entries, key, value) {
1878 if (!ownerID) {
1879 ownerID = new OwnerID();
1880 }
1881 var node = new ValueNode(ownerID, hash(key), [key, value]);
1882 for (var ii = 0; ii < entries.length; ii++) {
1883 var entry = entries[ii];
1884 node = node.update(ownerID, 0, undefined, entry[0], entry[1]);
1885 }
1886 return node;
1887 }
1888
1889 function packNodes(ownerID, nodes, count, excluding) {
1890 var bitmap = 0;
1891 var packedII = 0;
1892 var packedNodes = new Array(count);
1893 for (var ii = 0, bit = 1, len = nodes.length; ii < len; ii++, bit <<= 1) {
1894 var node = nodes[ii];
1895 if (node !== undefined && ii !== excluding) {
1896 bitmap |= bit;
1897 packedNodes[packedII++] = node;
1898 }
1899 }
1900 return new BitmapIndexedNode(ownerID, bitmap, packedNodes);
1901 }
1902
1903 function expandNodes(ownerID, nodes, bitmap, including, node) {
1904 var count = 0;
1905 var expandedNodes = new Array(SIZE);
1906 for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) {
1907 expandedNodes[ii] = bitmap & 1 ? nodes[count++] : undefined;
1908 }
1909 expandedNodes[including] = node;
1910 return new HashArrayMapNode(ownerID, count + 1, expandedNodes);
1911 }
1912
1913 function mergeIntoMapWith(map, merger, iterables) {
1914 var iters = [];
1915 for (var ii = 0; ii < iterables.length; ii++) {
1916 var value = iterables[ii];
1917 var iter = KeyedIterable(value);
1918 if (!isIterable(value)) {
1919 iter = iter.map(function(v ) {return fromJS(v)});
1920 }
1921 iters.push(iter);
1922 }
1923 return mergeIntoCollectionWith(map, merger, iters);
1924 }
1925
1926 function deepMerger(existing, value, key) {
1927 return existing && existing.mergeDeep && isIterable(value) ?
1928 existing.mergeDeep(value) :
1929 is(existing, value) ? existing : value;
1930 }
1931
1932 function deepMergerWith(merger) {
1933 return function(existing, value, key) {
1934 if (existing && existing.mergeDeepWith && isIterable(value)) {
1935 return existing.mergeDeepWith(merger, value);
1936 }
1937 var nextValue = merger(existing, value, key);
1938 return is(existing, nextValue) ? existing : nextValue;
1939 };
1940 }
1941
1942 function mergeIntoCollectionWith(collection, merger, iters) {
1943 iters = iters.filter(function(x ) {return x.size !== 0});
1944 if (iters.length === 0) {
1945 return collection;
1946 }
1947 if (collection.size === 0 && !collection.__ownerID && iters.length === 1) {
1948 return collection.constructor(iters[0]);
1949 }
1950 return collection.withMutations(function(collection ) {
1951 var mergeIntoMap = merger ?
1952 function(value, key) {
1953 collection.update(key, NOT_SET, function(existing )
1954 {return existing === NOT_SET ? value : merger(existing, value, key)}
1955 );
1956 } :
1957 function(value, key) {
1958 collection.set(key, value);
1959 }
1960 for (var ii = 0; ii < iters.length; ii++) {
1961 iters[ii].forEach(mergeIntoMap);
1962 }
1963 });
1964 }
1965
1966 function updateInDeepMap(existing, keyPathIter, notSetValue, updater) {
1967 var isNotSet = existing === NOT_SET;
1968 var step = keyPathIter.next();
1969 if (step.done) {
1970 var existingValue = isNotSet ? notSetValue : existing;
1971 var newValue = updater(existingValue);
1972 return newValue === existingValue ? existing : newValue;
1973 }
1974 invariant(
1975 isNotSet || (existing && existing.set),
1976 'invalid keyPath'
1977 );
1978 var key = step.value;
1979 var nextExisting = isNotSet ? NOT_SET : existing.get(key, NOT_SET);
1980 var nextUpdated = updateInDeepMap(
1981 nextExisting,
1982 keyPathIter,
1983 notSetValue,
1984 updater
1985 );
1986 return nextUpdated === nextExisting ? existing :
1987 nextUpdated === NOT_SET ? existing.remove(key) :
1988 (isNotSet ? emptyMap() : existing).set(key, nextUpdated);
1989 }
1990
1991 function popCount(x) {
1992 x = x - ((x >> 1) & 0x55555555);
1993 x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
1994 x = (x + (x >> 4)) & 0x0f0f0f0f;
1995 x = x + (x >> 8);
1996 x = x + (x >> 16);
1997 return x & 0x7f;
1998 }
1999
2000 function setIn(array, idx, val, canEdit) {
2001 var newArray = canEdit ? array : arrCopy(array);
2002 newArray[idx] = val;
2003 return newArray;
2004 }
2005
2006 function spliceIn(array, idx, val, canEdit) {
2007 var newLen = array.length + 1;
2008 if (canEdit && idx + 1 === newLen) {
2009 array[idx] = val;
2010 return array;
2011 }
2012 var newArray = new Array(newLen);
2013 var after = 0;
2014 for (var ii = 0; ii < newLen; ii++) {
2015 if (ii === idx) {
2016 newArray[ii] = val;
2017 after = -1;
2018 } else {
2019 newArray[ii] = array[ii + after];
2020 }
2021 }
2022 return newArray;
2023 }
2024
2025 function spliceOut(array, idx, canEdit) {
2026 var newLen = array.length - 1;
2027 if (canEdit && idx === newLen) {
2028 array.pop();
2029 return array;
2030 }
2031 var newArray = new Array(newLen);
2032 var after = 0;
2033 for (var ii = 0; ii < newLen; ii++) {
2034 if (ii === idx) {
2035 after = 1;
2036 }
2037 newArray[ii] = array[ii + after];
2038 }
2039 return newArray;
2040 }
2041
2042 var MAX_ARRAY_MAP_SIZE = SIZE / 4;
2043 var MAX_BITMAP_INDEXED_SIZE = SIZE / 2;
2044 var MIN_HASH_ARRAY_MAP_SIZE = SIZE / 4;
2045
2046 createClass(List, IndexedCollection);
2047
2048 // @pragma Construction
2049
2050 function List(value) {
2051 var empty = emptyList();
2052 if (value === null || value === undefined) {
2053 return empty;
2054 }
2055 if (isList(value)) {
2056 return value;
2057 }
2058 var iter = IndexedIterable(value);
2059 var size = iter.size;
2060 if (size === 0) {
2061 return empty;
2062 }
2063 assertNotInfinite(size);
2064 if (size > 0 && size < SIZE) {
2065 return makeList(0, size, SHIFT, null, new VNode(iter.toArray()));
2066 }
2067 return empty.withMutations(function(list ) {
2068 list.setSize(size);
2069 iter.forEach(function(v, i) {return list.set(i, v)});
2070 });
2071 }
2072
2073 List.of = function(/*...values*/) {
2074 return this(arguments);
2075 };
2076
2077 List.prototype.toString = function() {
2078 return this.__toString('List [', ']');
2079 };
2080
2081 // @pragma Access
2082
2083 List.prototype.get = function(index, notSetValue) {
2084 index = wrapIndex(this, index);
2085 if (index >= 0 && index < this.size) {
2086 index += this._origin;
2087 var node = listNodeFor(this, index);
2088 return node && node.array[index & MASK];
2089 }
2090 return notSetValue;
2091 };
2092
2093 // @pragma Modification
2094
2095 List.prototype.set = function(index, value) {
2096 return updateList(this, index, value);
2097 };
2098
2099 List.prototype.remove = function(index) {
2100 return !this.has(index) ? this :
2101 index === 0 ? this.shift() :
2102 index === this.size - 1 ? this.pop() :
2103 this.splice(index, 1);
2104 };
2105
2106 List.prototype.insert = function(index, value) {
2107 return this.splice(index, 0, value);
2108 };
2109
2110 List.prototype.clear = function() {
2111 if (this.size === 0) {
2112 return this;
2113 }
2114 if (this.__ownerID) {
2115 this.size = this._origin = this._capacity = 0;
2116 this._level = SHIFT;
2117 this._root = this._tail = null;
2118 this.__hash = undefined;
2119 this.__altered = true;
2120 return this;
2121 }
2122 return emptyList();
2123 };
2124
2125 List.prototype.push = function(/*...values*/) {
2126 var values = arguments;
2127 var oldSize = this.size;
2128 return this.withMutations(function(list ) {
2129 setListBounds(list, 0, oldSize + values.length);
2130 for (var ii = 0; ii < values.length; ii++) {
2131 list.set(oldSize + ii, values[ii]);
2132 }
2133 });
2134 };
2135
2136 List.prototype.pop = function() {
2137 return setListBounds(this, 0, -1);
2138 };
2139
2140 List.prototype.unshift = function(/*...values*/) {
2141 var values = arguments;
2142 return this.withMutations(function(list ) {
2143 setListBounds(list, -values.length);
2144 for (var ii = 0; ii < values.length; ii++) {
2145 list.set(ii, values[ii]);
2146 }
2147 });
2148 };
2149
2150 List.prototype.shift = function() {
2151 return setListBounds(this, 1);
2152 };
2153
2154 // @pragma Composition
2155
2156 List.prototype.merge = function(/*...iters*/) {
2157 return mergeIntoListWith(this, undefined, arguments);
2158 };
2159
2160 List.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
2161 return mergeIntoListWith(this, merger, iters);
2162 };
2163
2164 List.prototype.mergeDeep = function(/*...iters*/) {
2165 return mergeIntoListWith(this, deepMerger, arguments);
2166 };
2167
2168 List.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
2169 return mergeIntoListWith(this, deepMergerWith(merger), iters);
2170 };
2171
2172 List.prototype.setSize = function(size) {
2173 return setListBounds(this, 0, size);
2174 };
2175
2176 // @pragma Iteration
2177
2178 List.prototype.slice = function(begin, end) {
2179 var size = this.size;
2180 if (wholeSlice(begin, end, size)) {
2181 return this;
2182 }
2183 return setListBounds(
2184 this,
2185 resolveBegin(begin, size),
2186 resolveEnd(end, size)
2187 );
2188 };
2189
2190 List.prototype.__iterator = function(type, reverse) {
2191 var index = 0;
2192 var values = iterateList(this, reverse);
2193 return new Iterator(function() {
2194 var value = values();
2195 return value === DONE ?
2196 iteratorDone() :
2197 iteratorValue(type, index++, value);
2198 });
2199 };
2200
2201 List.prototype.__iterate = function(fn, reverse) {
2202 var index = 0;
2203 var values = iterateList(this, reverse);
2204 var value;
2205 while ((value = values()) !== DONE) {
2206 if (fn(value, index++, this) === false) {
2207 break;
2208 }
2209 }
2210 return index;
2211 };
2212
2213 List.prototype.__ensureOwner = function(ownerID) {
2214 if (ownerID === this.__ownerID) {
2215 return this;
2216 }
2217 if (!ownerID) {
2218 this.__ownerID = ownerID;
2219 return this;
2220 }
2221 return makeList(this._origin, this._capacity, this._level, this._root, this._tail, ownerID, this.__hash);
2222 };
2223
2224
2225 function isList(maybeList) {
2226 return !!(maybeList && maybeList[IS_LIST_SENTINEL]);
2227 }
2228
2229 List.isList = isList;
2230
2231 var IS_LIST_SENTINEL = '@@__IMMUTABLE_LIST__@@';
2232
2233 var ListPrototype = List.prototype;
2234 ListPrototype[IS_LIST_SENTINEL] = true;
2235 ListPrototype[DELETE] = ListPrototype.remove;
2236 ListPrototype.setIn = MapPrototype.setIn;
2237 ListPrototype.deleteIn =
2238 ListPrototype.removeIn = MapPrototype.removeIn;
2239 ListPrototype.update = MapPrototype.update;
2240 ListPrototype.updateIn = MapPrototype.updateIn;
2241 ListPrototype.mergeIn = MapPrototype.mergeIn;
2242 ListPrototype.mergeDeepIn = MapPrototype.mergeDeepIn;
2243 ListPrototype.withMutations = MapPrototype.withMutations;
2244 ListPrototype.asMutable = MapPrototype.asMutable;
2245 ListPrototype.asImmutable = MapPrototype.asImmutable;
2246 ListPrototype.wasAltered = MapPrototype.wasAltered;
2247
2248
2249
2250 function VNode(array, ownerID) {
2251 this.array = array;
2252 this.ownerID = ownerID;
2253 }
2254
2255 // TODO: seems like these methods are very similar
2256
2257 VNode.prototype.removeBefore = function(ownerID, level, index) {
2258 if (index === level ? 1 << level : 0 || this.array.length === 0) {
2259 return this;
2260 }
2261 var originIndex = (index >>> level) & MASK;
2262 if (originIndex >= this.array.length) {
2263 return new VNode([], ownerID);
2264 }
2265 var removingFirst = originIndex === 0;
2266 var newChild;
2267 if (level > 0) {
2268 var oldChild = this.array[originIndex];
2269 newChild = oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index);
2270 if (newChild === oldChild && removingFirst) {
2271 return this;
2272 }
2273 }
2274 if (removingFirst && !newChild) {
2275 return this;
2276 }
2277 var editable = editableVNode(this, ownerID);
2278 if (!removingFirst) {
2279 for (var ii = 0; ii < originIndex; ii++) {
2280 editable.array[ii] = undefined;
2281 }
2282 }
2283 if (newChild) {
2284 editable.array[originIndex] = newChild;
2285 }
2286 return editable;
2287 };
2288
2289 VNode.prototype.removeAfter = function(ownerID, level, index) {
2290 if (index === (level ? 1 << level : 0) || this.array.length === 0) {
2291 return this;
2292 }
2293 var sizeIndex = ((index - 1) >>> level) & MASK;
2294 if (sizeIndex >= this.array.length) {
2295 return this;
2296 }
2297
2298 var newChild;
2299 if (level > 0) {
2300 var oldChild = this.array[sizeIndex];
2301 newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index);
2302 if (newChild === oldChild && sizeIndex === this.array.length - 1) {
2303 return this;
2304 }
2305 }
2306
2307 var editable = editableVNode(this, ownerID);
2308 editable.array.splice(sizeIndex + 1);
2309 if (newChild) {
2310 editable.array[sizeIndex] = newChild;
2311 }
2312 return editable;
2313 };
2314
2315
2316
2317 var DONE = {};
2318
2319 function iterateList(list, reverse) {
2320 var left = list._origin;
2321 var right = list._capacity;
2322 var tailPos = getTailOffset(right);
2323 var tail = list._tail;
2324
2325 return iterateNodeOrLeaf(list._root, list._level, 0);
2326
2327 function iterateNodeOrLeaf(node, level, offset) {
2328 return level === 0 ?
2329 iterateLeaf(node, offset) :
2330 iterateNode(node, level, offset);
2331 }
2332
2333 function iterateLeaf(node, offset) {
2334 var array = offset === tailPos ? tail && tail.array : node && node.array;
2335 var from = offset > left ? 0 : left - offset;
2336 var to = right - offset;
2337 if (to > SIZE) {
2338 to = SIZE;
2339 }
2340 return function() {
2341 if (from === to) {
2342 return DONE;
2343 }
2344 var idx = reverse ? --to : from++;
2345 return array && array[idx];
2346 };
2347 }
2348
2349 function iterateNode(node, level, offset) {
2350 var values;
2351 var array = node && node.array;
2352 var from = offset > left ? 0 : (left - offset) >> level;
2353 var to = ((right - offset) >> level) + 1;
2354 if (to > SIZE) {
2355 to = SIZE;
2356 }
2357 return function() {
2358 do {
2359 if (values) {
2360 var value = values();
2361 if (value !== DONE) {
2362 return value;
2363 }
2364 values = null;
2365 }
2366 if (from === to) {
2367 return DONE;
2368 }
2369 var idx = reverse ? --to : from++;
2370 values = iterateNodeOrLeaf(
2371 array && array[idx], level - SHIFT, offset + (idx << level)
2372 );
2373 } while (true);
2374 };
2375 }
2376 }
2377
2378 function makeList(origin, capacity, level, root, tail, ownerID, hash) {
2379 var list = Object.create(ListPrototype);
2380 list.size = capacity - origin;
2381 list._origin = origin;
2382 list._capacity = capacity;
2383 list._level = level;
2384 list._root = root;
2385 list._tail = tail;
2386 list.__ownerID = ownerID;
2387 list.__hash = hash;
2388 list.__altered = false;
2389 return list;
2390 }
2391
2392 var EMPTY_LIST;
2393 function emptyList() {
2394 return EMPTY_LIST || (EMPTY_LIST = makeList(0, 0, SHIFT));
2395 }
2396
2397 function updateList(list, index, value) {
2398 index = wrapIndex(list, index);
2399
2400 if (index !== index) {
2401 return list;
2402 }
2403
2404 if (index >= list.size || index < 0) {
2405 return list.withMutations(function(list ) {
2406 index < 0 ?
2407 setListBounds(list, index).set(0, value) :
2408 setListBounds(list, 0, index + 1).set(index, value)
2409 });
2410 }
2411
2412 index += list._origin;
2413
2414 var newTail = list._tail;
2415 var newRoot = list._root;
2416 var didAlter = MakeRef(DID_ALTER);
2417 if (index >= getTailOffset(list._capacity)) {
2418 newTail = updateVNode(newTail, list.__ownerID, 0, index, value, didAlter);
2419 } else {
2420 newRoot = updateVNode(newRoot, list.__ownerID, list._level, index, value, didAlter);
2421 }
2422
2423 if (!didAlter.value) {
2424 return list;
2425 }
2426
2427 if (list.__ownerID) {
2428 list._root = newRoot;
2429 list._tail = newTail;
2430 list.__hash = undefined;
2431 list.__altered = true;
2432 return list;
2433 }
2434 return makeList(list._origin, list._capacity, list._level, newRoot, newTail);
2435 }
2436
2437 function updateVNode(node, ownerID, level, index, value, didAlter) {
2438 var idx = (index >>> level) & MASK;
2439 var nodeHas = node && idx < node.array.length;
2440 if (!nodeHas && value === undefined) {
2441 return node;
2442 }
2443
2444 var newNode;
2445
2446 if (level > 0) {
2447 var lowerNode = node && node.array[idx];
2448 var newLowerNode = updateVNode(lowerNode, ownerID, level - SHIFT, index, value, didAlter);
2449 if (newLowerNode === lowerNode) {
2450 return node;
2451 }
2452 newNode = editableVNode(node, ownerID);
2453 newNode.array[idx] = newLowerNode;
2454 return newNode;
2455 }
2456
2457 if (nodeHas && node.array[idx] === value) {
2458 return node;
2459 }
2460
2461 SetRef(didAlter);
2462
2463 newNode = editableVNode(node, ownerID);
2464 if (value === undefined && idx === newNode.array.length - 1) {
2465 newNode.array.pop();
2466 } else {
2467 newNode.array[idx] = value;
2468 }
2469 return newNode;
2470 }
2471
2472 function editableVNode(node, ownerID) {
2473 if (ownerID && node && ownerID === node.ownerID) {
2474 return node;
2475 }
2476 return new VNode(node ? node.array.slice() : [], ownerID);
2477 }
2478
2479 function listNodeFor(list, rawIndex) {
2480 if (rawIndex >= getTailOffset(list._capacity)) {
2481 return list._tail;
2482 }
2483 if (rawIndex < 1 << (list._level + SHIFT)) {
2484 var node = list._root;
2485 var level = list._level;
2486 while (node && level > 0) {
2487 node = node.array[(rawIndex >>> level) & MASK];
2488 level -= SHIFT;
2489 }
2490 return node;
2491 }
2492 }
2493
2494 function setListBounds(list, begin, end) {
2495 // Sanitize begin & end using this shorthand for ToInt32(argument)
2496 // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32
2497 if (begin !== undefined) {
2498 begin = begin | 0;
2499 }
2500 if (end !== undefined) {
2501 end = end | 0;
2502 }
2503 var owner = list.__ownerID || new OwnerID();
2504 var oldOrigin = list._origin;
2505 var oldCapacity = list._capacity;
2506 var newOrigin = oldOrigin + begin;
2507 var newCapacity = end === undefined ? oldCapacity : end < 0 ? oldCapacity + end : oldOrigin + end;
2508 if (newOrigin === oldOrigin && newCapacity === oldCapacity) {
2509 return list;
2510 }
2511
2512 // If it's going to end after it starts, it's empty.
2513 if (newOrigin >= newCapacity) {
2514 return list.clear();
2515 }
2516
2517 var newLevel = list._level;
2518 var newRoot = list._root;
2519
2520 // New origin might need creating a higher root.
2521 var offsetShift = 0;
2522 while (newOrigin + offsetShift < 0) {
2523 newRoot = new VNode(newRoot && newRoot.array.length ? [undefined, newRoot] : [], owner);
2524 newLevel += SHIFT;
2525 offsetShift += 1 << newLevel;
2526 }
2527 if (offsetShift) {
2528 newOrigin += offsetShift;
2529 oldOrigin += offsetShift;
2530 newCapacity += offsetShift;
2531 oldCapacity += offsetShift;
2532 }
2533
2534 var oldTailOffset = getTailOffset(oldCapacity);
2535 var newTailOffset = getTailOffset(newCapacity);
2536
2537 // New size might need creating a higher root.
2538 while (newTailOffset >= 1 << (newLevel + SHIFT)) {
2539 newRoot = new VNode(newRoot && newRoot.array.length ? [newRoot] : [], owner);
2540 newLevel += SHIFT;
2541 }
2542
2543 // Locate or create the new tail.
2544 var oldTail = list._tail;
2545 var newTail = newTailOffset < oldTailOffset ?
2546 listNodeFor(list, newCapacity - 1) :
2547 newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail;
2548
2549 // Merge Tail into tree.
2550 if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldCapacity && oldTail.array.length) {
2551 newRoot = editableVNode(newRoot, owner);
2552 var node = newRoot;
2553 for (var level = newLevel; level > SHIFT; level -= SHIFT) {
2554 var idx = (oldTailOffset >>> level) & MASK;
2555 node = node.array[idx] = editableVNode(node.array[idx], owner);
2556 }
2557 node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail;
2558 }
2559
2560 // If the size has been reduced, there's a chance the tail needs to be trimmed.
2561 if (newCapacity < oldCapacity) {
2562 newTail = newTail && newTail.removeAfter(owner, 0, newCapacity);
2563 }
2564
2565 // If the new origin is within the tail, then we do not need a root.
2566 if (newOrigin >= newTailOffset) {
2567 newOrigin -= newTailOffset;
2568 newCapacity -= newTailOffset;
2569 newLevel = SHIFT;
2570 newRoot = null;
2571 newTail = newTail && newTail.removeBefore(owner, 0, newOrigin);
2572
2573 // Otherwise, if the root has been trimmed, garbage collect.
2574 } else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) {
2575 offsetShift = 0;
2576
2577 // Identify the new top root node of the subtree of the old root.
2578 while (newRoot) {
2579 var beginIndex = (newOrigin >>> newLevel) & MASK;
2580 if (beginIndex !== (newTailOffset >>> newLevel) & MASK) {
2581 break;
2582 }
2583 if (beginIndex) {
2584 offsetShift += (1 << newLevel) * beginIndex;
2585 }
2586 newLevel -= SHIFT;
2587 newRoot = newRoot.array[beginIndex];
2588 }
2589
2590 // Trim the new sides of the new root.
2591 if (newRoot && newOrigin > oldOrigin) {
2592 newRoot = newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift);
2593 }
2594 if (newRoot && newTailOffset < oldTailOffset) {
2595 newRoot = newRoot.removeAfter(owner, newLevel, newTailOffset - offsetShift);
2596 }
2597 if (offsetShift) {
2598 newOrigin -= offsetShift;
2599 newCapacity -= offsetShift;
2600 }
2601 }
2602
2603 if (list.__ownerID) {
2604 list.size = newCapacity - newOrigin;
2605 list._origin = newOrigin;
2606 list._capacity = newCapacity;
2607 list._level = newLevel;
2608 list._root = newRoot;
2609 list._tail = newTail;
2610 list.__hash = undefined;
2611 list.__altered = true;
2612 return list;
2613 }
2614 return makeList(newOrigin, newCapacity, newLevel, newRoot, newTail);
2615 }
2616
2617 function mergeIntoListWith(list, merger, iterables) {
2618 var iters = [];
2619 var maxSize = 0;
2620 for (var ii = 0; ii < iterables.length; ii++) {
2621 var value = iterables[ii];
2622 var iter = IndexedIterable(value);
2623 if (iter.size > maxSize) {
2624 maxSize = iter.size;
2625 }
2626 if (!isIterable(value)) {
2627 iter = iter.map(function(v ) {return fromJS(v)});
2628 }
2629 iters.push(iter);
2630 }
2631 if (maxSize > list.size) {
2632 list = list.setSize(maxSize);
2633 }
2634 return mergeIntoCollectionWith(list, merger, iters);
2635 }
2636
2637 function getTailOffset(size) {
2638 return size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT);
2639 }
2640
2641 createClass(OrderedMap, Map);
2642
2643 // @pragma Construction
2644
2645 function OrderedMap(value) {
2646 return value === null || value === undefined ? emptyOrderedMap() :
2647 isOrderedMap(value) ? value :
2648 emptyOrderedMap().withMutations(function(map ) {
2649 var iter = KeyedIterable(value);
2650 assertNotInfinite(iter.size);
2651 iter.forEach(function(v, k) {return map.set(k, v)});
2652 });
2653 }
2654
2655 OrderedMap.of = function(/*...values*/) {
2656 return this(arguments);
2657 };
2658
2659 OrderedMap.prototype.toString = function() {
2660 return this.__toString('OrderedMap {', '}');
2661 };
2662
2663 // @pragma Access
2664
2665 OrderedMap.prototype.get = function(k, notSetValue) {
2666 var index = this._map.get(k);
2667 return index !== undefined ? this._list.get(index)[1] : notSetValue;
2668 };
2669
2670 // @pragma Modification
2671
2672 OrderedMap.prototype.clear = function() {
2673 if (this.size === 0) {
2674 return this;
2675 }
2676 if (this.__ownerID) {
2677 this.size = 0;
2678 this._map.clear();
2679 this._list.clear();
2680 return this;
2681 }
2682 return emptyOrderedMap();
2683 };
2684
2685 OrderedMap.prototype.set = function(k, v) {
2686 return updateOrderedMap(this, k, v);
2687 };
2688
2689 OrderedMap.prototype.remove = function(k) {
2690 return updateOrderedMap(this, k, NOT_SET);
2691 };
2692
2693 OrderedMap.prototype.wasAltered = function() {
2694 return this._map.wasAltered() || this._list.wasAltered();
2695 };
2696
2697 OrderedMap.prototype.__iterate = function(fn, reverse) {var this$0 = this;
2698 return this._list.__iterate(
2699 function(entry ) {return entry && fn(entry[1], entry[0], this$0)},
2700 reverse
2701 );
2702 };
2703
2704 OrderedMap.prototype.__iterator = function(type, reverse) {
2705 return this._list.fromEntrySeq().__iterator(type, reverse);
2706 };
2707
2708 OrderedMap.prototype.__ensureOwner = function(ownerID) {
2709 if (ownerID === this.__ownerID) {
2710 return this;
2711 }
2712 var newMap = this._map.__ensureOwner(ownerID);
2713 var newList = this._list.__ensureOwner(ownerID);
2714 if (!ownerID) {
2715 this.__ownerID = ownerID;
2716 this._map = newMap;
2717 this._list = newList;
2718 return this;
2719 }
2720 return makeOrderedMap(newMap, newList, ownerID, this.__hash);
2721 };
2722
2723
2724 function isOrderedMap(maybeOrderedMap) {
2725 return isMap(maybeOrderedMap) && isOrdered(maybeOrderedMap);
2726 }
2727
2728 OrderedMap.isOrderedMap = isOrderedMap;
2729
2730 OrderedMap.prototype[IS_ORDERED_SENTINEL] = true;
2731 OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove;
2732
2733
2734
2735 function makeOrderedMap(map, list, ownerID, hash) {
2736 var omap = Object.create(OrderedMap.prototype);
2737 omap.size = map ? map.size : 0;
2738 omap._map = map;
2739 omap._list = list;
2740 omap.__ownerID = ownerID;
2741 omap.__hash = hash;
2742 return omap;
2743 }
2744
2745 var EMPTY_ORDERED_MAP;
2746 function emptyOrderedMap() {
2747 return EMPTY_ORDERED_MAP || (EMPTY_ORDERED_MAP = makeOrderedMap(emptyMap(), emptyList()));
2748 }
2749
2750 function updateOrderedMap(omap, k, v) {
2751 var map = omap._map;
2752 var list = omap._list;
2753 var i = map.get(k);
2754 var has = i !== undefined;
2755 var newMap;
2756 var newList;
2757 if (v === NOT_SET) { // removed
2758 if (!has) {
2759 return omap;
2760 }
2761 if (list.size >= SIZE && list.size >= map.size * 2) {
2762 newList = list.filter(function(entry, idx) {return entry !== undefined && i !== idx});
2763 newMap = newList.toKeyedSeq().map(function(entry ) {return entry[0]}).flip().toMap();
2764 if (omap.__ownerID) {
2765 newMap.__ownerID = newList.__ownerID = omap.__ownerID;
2766 }
2767 } else {
2768 newMap = map.remove(k);
2769 newList = i === list.size - 1 ? list.pop() : list.set(i, undefined);
2770 }
2771 } else {
2772 if (has) {
2773 if (v === list.get(i)[1]) {
2774 return omap;
2775 }
2776 newMap = map;
2777 newList = list.set(i, [k, v]);
2778 } else {
2779 newMap = map.set(k, list.size);
2780 newList = list.set(list.size, [k, v]);
2781 }
2782 }
2783 if (omap.__ownerID) {
2784 omap.size = newMap.size;
2785 omap._map = newMap;
2786 omap._list = newList;
2787 omap.__hash = undefined;
2788 return omap;
2789 }
2790 return makeOrderedMap(newMap, newList);
2791 }
2792
2793 createClass(ToKeyedSequence, KeyedSeq);
2794 function ToKeyedSequence(indexed, useKeys) {
2795 this._iter = indexed;
2796 this._useKeys = useKeys;
2797 this.size = indexed.size;
2798 }
2799
2800 ToKeyedSequence.prototype.get = function(key, notSetValue) {
2801 return this._iter.get(key, notSetValue);
2802 };
2803
2804 ToKeyedSequence.prototype.has = function(key) {
2805 return this._iter.has(key);
2806 };
2807
2808 ToKeyedSequence.prototype.valueSeq = function() {
2809 return this._iter.valueSeq();
2810 };
2811
2812 ToKeyedSequence.prototype.reverse = function() {var this$0 = this;
2813 var reversedSequence = reverseFactory(this, true);
2814 if (!this._useKeys) {
2815 reversedSequence.valueSeq = function() {return this$0._iter.toSeq().reverse()};
2816 }
2817 return reversedSequence;
2818 };
2819
2820 ToKeyedSequence.prototype.map = function(mapper, context) {var this$0 = this;
2821 var mappedSequence = mapFactory(this, mapper, context);
2822 if (!this._useKeys) {
2823 mappedSequence.valueSeq = function() {return this$0._iter.toSeq().map(mapper, context)};
2824 }
2825 return mappedSequence;
2826 };
2827
2828 ToKeyedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
2829 var ii;
2830 return this._iter.__iterate(
2831 this._useKeys ?
2832 function(v, k) {return fn(v, k, this$0)} :
2833 ((ii = reverse ? resolveSize(this) : 0),
2834 function(v ) {return fn(v, reverse ? --ii : ii++, this$0)}),
2835 reverse
2836 );
2837 };
2838
2839 ToKeyedSequence.prototype.__iterator = function(type, reverse) {
2840 if (this._useKeys) {
2841 return this._iter.__iterator(type, reverse);
2842 }
2843 var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
2844 var ii = reverse ? resolveSize(this) : 0;
2845 return new Iterator(function() {
2846 var step = iterator.next();
2847 return step.done ? step :
2848 iteratorValue(type, reverse ? --ii : ii++, step.value, step);
2849 });
2850 };
2851
2852 ToKeyedSequence.prototype[IS_ORDERED_SENTINEL] = true;
2853
2854
2855 createClass(ToIndexedSequence, IndexedSeq);
2856 function ToIndexedSequence(iter) {
2857 this._iter = iter;
2858 this.size = iter.size;
2859 }
2860
2861 ToIndexedSequence.prototype.includes = function(value) {
2862 return this._iter.includes(value);
2863 };
2864
2865 ToIndexedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
2866 var iterations = 0;
2867 return this._iter.__iterate(function(v ) {return fn(v, iterations++, this$0)}, reverse);
2868 };
2869
2870 ToIndexedSequence.prototype.__iterator = function(type, reverse) {
2871 var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
2872 var iterations = 0;
2873 return new Iterator(function() {
2874 var step = iterator.next();
2875 return step.done ? step :
2876 iteratorValue(type, iterations++, step.value, step)
2877 });
2878 };
2879
2880
2881
2882 createClass(ToSetSequence, SetSeq);
2883 function ToSetSequence(iter) {
2884 this._iter = iter;
2885 this.size = iter.size;
2886 }
2887
2888 ToSetSequence.prototype.has = function(key) {
2889 return this._iter.includes(key);
2890 };
2891
2892 ToSetSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
2893 return this._iter.__iterate(function(v ) {return fn(v, v, this$0)}, reverse);
2894 };
2895
2896 ToSetSequence.prototype.__iterator = function(type, reverse) {
2897 var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
2898 return new Iterator(function() {
2899 var step = iterator.next();
2900 return step.done ? step :
2901 iteratorValue(type, step.value, step.value, step);
2902 });
2903 };
2904
2905
2906
2907 createClass(FromEntriesSequence, KeyedSeq);
2908 function FromEntriesSequence(entries) {
2909 this._iter = entries;
2910 this.size = entries.size;
2911 }
2912
2913 FromEntriesSequence.prototype.entrySeq = function() {
2914 return this._iter.toSeq();
2915 };
2916
2917 FromEntriesSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this;
2918 return this._iter.__iterate(function(entry ) {
2919 // Check if entry exists first so array access doesn't throw for holes
2920 // in the parent iteration.
2921 if (entry) {
2922 validateEntry(entry);
2923 var indexedIterable = isIterable(entry);
2924 return fn(
2925 indexedIterable ? entry.get(1) : entry[1],
2926 indexedIterable ? entry.get(0) : entry[0],
2927 this$0
2928 );
2929 }
2930 }, reverse);
2931 };
2932
2933 FromEntriesSequence.prototype.__iterator = function(type, reverse) {
2934 var iterator = this._iter.__iterator(ITERATE_VALUES, reverse);
2935 return new Iterator(function() {
2936 while (true) {
2937 var step = iterator.next();
2938 if (step.done) {
2939 return step;
2940 }
2941 var entry = step.value;
2942 // Check if entry exists first so array access doesn't throw for holes
2943 // in the parent iteration.
2944 if (entry) {
2945 validateEntry(entry);
2946 var indexedIterable = isIterable(entry);
2947 return iteratorValue(
2948 type,
2949 indexedIterable ? entry.get(0) : entry[0],
2950 indexedIterable ? entry.get(1) : entry[1],
2951 step
2952 );
2953 }
2954 }
2955 });
2956 };
2957
2958
2959 ToIndexedSequence.prototype.cacheResult =
2960 ToKeyedSequence.prototype.cacheResult =
2961 ToSetSequence.prototype.cacheResult =
2962 FromEntriesSequence.prototype.cacheResult =
2963 cacheResultThrough;
2964
2965
2966 function flipFactory(iterable) {
2967 var flipSequence = makeSequence(iterable);
2968 flipSequence._iter = iterable;
2969 flipSequence.size = iterable.size;
2970 flipSequence.flip = function() {return iterable};
2971 flipSequence.reverse = function () {
2972 var reversedSequence = iterable.reverse.apply(this); // super.reverse()
2973 reversedSequence.flip = function() {return iterable.reverse()};
2974 return reversedSequence;
2975 };
2976 flipSequence.has = function(key ) {return iterable.includes(key)};
2977 flipSequence.includes = function(key ) {return iterable.has(key)};
2978 flipSequence.cacheResult = cacheResultThrough;
2979 flipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
2980 return iterable.__iterate(function(v, k) {return fn(k, v, this$0) !== false}, reverse);
2981 }
2982 flipSequence.__iteratorUncached = function(type, reverse) {
2983 if (type === ITERATE_ENTRIES) {
2984 var iterator = iterable.__iterator(type, reverse);
2985 return new Iterator(function() {
2986 var step = iterator.next();
2987 if (!step.done) {
2988 var k = step.value[0];
2989 step.value[0] = step.value[1];
2990 step.value[1] = k;
2991 }
2992 return step;
2993 });
2994 }
2995 return iterable.__iterator(
2996 type === ITERATE_VALUES ? ITERATE_KEYS : ITERATE_VALUES,
2997 reverse
2998 );
2999 }
3000 return flipSequence;
3001 }
3002
3003
3004 function mapFactory(iterable, mapper, context) {
3005 var mappedSequence = makeSequence(iterable);
3006 mappedSequence.size = iterable.size;
3007 mappedSequence.has = function(key ) {return iterable.has(key)};
3008 mappedSequence.get = function(key, notSetValue) {
3009 var v = iterable.get(key, NOT_SET);
3010 return v === NOT_SET ?
3011 notSetValue :
3012 mapper.call(context, v, key, iterable);
3013 };
3014 mappedSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
3015 return iterable.__iterate(
3016 function(v, k, c) {return fn(mapper.call(context, v, k, c), k, this$0) !== false},
3017 reverse
3018 );
3019 }
3020 mappedSequence.__iteratorUncached = function (type, reverse) {
3021 var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
3022 return new Iterator(function() {
3023 var step = iterator.next();
3024 if (step.done) {
3025 return step;
3026 }
3027 var entry = step.value;
3028 var key = entry[0];
3029 return iteratorValue(
3030 type,
3031 key,
3032 mapper.call(context, entry[1], key, iterable),
3033 step
3034 );
3035 });
3036 }
3037 return mappedSequence;
3038 }
3039
3040
3041 function reverseFactory(iterable, useKeys) {
3042 var reversedSequence = makeSequence(iterable);
3043 reversedSequence._iter = iterable;
3044 reversedSequence.size = iterable.size;
3045 reversedSequence.reverse = function() {return iterable};
3046 if (iterable.flip) {
3047 reversedSequence.flip = function () {
3048 var flipSequence = flipFactory(iterable);
3049 flipSequence.reverse = function() {return iterable.flip()};
3050 return flipSequence;
3051 };
3052 }
3053 reversedSequence.get = function(key, notSetValue)
3054 {return iterable.get(useKeys ? key : -1 - key, notSetValue)};
3055 reversedSequence.has = function(key )
3056 {return iterable.has(useKeys ? key : -1 - key)};
3057 reversedSequence.includes = function(value ) {return iterable.includes(value)};
3058 reversedSequence.cacheResult = cacheResultThrough;
3059 reversedSequence.__iterate = function (fn, reverse) {var this$0 = this;
3060 return iterable.__iterate(function(v, k) {return fn(v, k, this$0)}, !reverse);
3061 };
3062 reversedSequence.__iterator =
3063 function(type, reverse) {return iterable.__iterator(type, !reverse)};
3064 return reversedSequence;
3065 }
3066
3067
3068 function filterFactory(iterable, predicate, context, useKeys) {
3069 var filterSequence = makeSequence(iterable);
3070 if (useKeys) {
3071 filterSequence.has = function(key ) {
3072 var v = iterable.get(key, NOT_SET);
3073 return v !== NOT_SET && !!predicate.call(context, v, key, iterable);
3074 };
3075 filterSequence.get = function(key, notSetValue) {
3076 var v = iterable.get(key, NOT_SET);
3077 return v !== NOT_SET && predicate.call(context, v, key, iterable) ?
3078 v : notSetValue;
3079 };
3080 }
3081 filterSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
3082 var iterations = 0;
3083 iterable.__iterate(function(v, k, c) {
3084 if (predicate.call(context, v, k, c)) {
3085 iterations++;
3086 return fn(v, useKeys ? k : iterations - 1, this$0);
3087 }
3088 }, reverse);
3089 return iterations;
3090 };
3091 filterSequence.__iteratorUncached = function (type, reverse) {
3092 var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
3093 var iterations = 0;
3094 return new Iterator(function() {
3095 while (true) {
3096 var step = iterator.next();
3097 if (step.done) {
3098 return step;
3099 }
3100 var entry = step.value;
3101 var key = entry[0];
3102 var value = entry[1];
3103 if (predicate.call(context, value, key, iterable)) {
3104 return iteratorValue(type, useKeys ? key : iterations++, value, step);
3105 }
3106 }
3107 });
3108 }
3109 return filterSequence;
3110 }
3111
3112
3113 function countByFactory(iterable, grouper, context) {
3114 var groups = Map().asMutable();
3115 iterable.__iterate(function(v, k) {
3116 groups.update(
3117 grouper.call(context, v, k, iterable),
3118 0,
3119 function(a ) {return a + 1}
3120 );
3121 });
3122 return groups.asImmutable();
3123 }
3124
3125
3126 function groupByFactory(iterable, grouper, context) {
3127 var isKeyedIter = isKeyed(iterable);
3128 var groups = (isOrdered(iterable) ? OrderedMap() : Map()).asMutable();
3129 iterable.__iterate(function(v, k) {
3130 groups.update(
3131 grouper.call(context, v, k, iterable),
3132 function(a ) {return (a = a || [], a.push(isKeyedIter ? [k, v] : v), a)}
3133 );
3134 });
3135 var coerce = iterableClass(iterable);
3136 return groups.map(function(arr ) {return reify(iterable, coerce(arr))});
3137 }
3138
3139
3140 function sliceFactory(iterable, begin, end, useKeys) {
3141 var originalSize = iterable.size;
3142
3143 // Sanitize begin & end using this shorthand for ToInt32(argument)
3144 // http://www.ecma-international.org/ecma-262/6.0/#sec-toint32
3145 if (begin !== undefined) {
3146 begin = begin | 0;
3147 }
3148 if (end !== undefined) {
3149 if (end === Infinity) {
3150 end = originalSize;
3151 } else {
3152 end = end | 0;
3153 }
3154 }
3155
3156 if (wholeSlice(begin, end, originalSize)) {
3157 return iterable;
3158 }
3159
3160 var resolvedBegin = resolveBegin(begin, originalSize);
3161 var resolvedEnd = resolveEnd(end, originalSize);
3162
3163 // begin or end will be NaN if they were provided as negative numbers and
3164 // this iterable's size is unknown. In that case, cache first so there is
3165 // a known size and these do not resolve to NaN.
3166 if (resolvedBegin !== resolvedBegin || resolvedEnd !== resolvedEnd) {
3167 return sliceFactory(iterable.toSeq().cacheResult(), begin, end, useKeys);
3168 }
3169
3170 // Note: resolvedEnd is undefined when the original sequence's length is
3171 // unknown and this slice did not supply an end and should contain all
3172 // elements after resolvedBegin.
3173 // In that case, resolvedSize will be NaN and sliceSize will remain undefined.
3174 var resolvedSize = resolvedEnd - resolvedBegin;
3175 var sliceSize;
3176 if (resolvedSize === resolvedSize) {
3177 sliceSize = resolvedSize < 0 ? 0 : resolvedSize;
3178 }
3179
3180 var sliceSeq = makeSequence(iterable);
3181
3182 // If iterable.size is undefined, the size of the realized sliceSeq is
3183 // unknown at this point unless the number of items to slice is 0
3184 sliceSeq.size = sliceSize === 0 ? sliceSize : iterable.size && sliceSize || undefined;
3185
3186 if (!useKeys && isSeq(iterable) && sliceSize >= 0) {
3187 sliceSeq.get = function (index, notSetValue) {
3188 index = wrapIndex(this, index);
3189 return index >= 0 && index < sliceSize ?
3190 iterable.get(index + resolvedBegin, notSetValue) :
3191 notSetValue;
3192 }
3193 }
3194
3195 sliceSeq.__iterateUncached = function(fn, reverse) {var this$0 = this;
3196 if (sliceSize === 0) {
3197 return 0;
3198 }
3199 if (reverse) {
3200 return this.cacheResult().__iterate(fn, reverse);
3201 }
3202 var skipped = 0;
3203 var isSkipping = true;
3204 var iterations = 0;
3205 iterable.__iterate(function(v, k) {
3206 if (!(isSkipping && (isSkipping = skipped++ < resolvedBegin))) {
3207 iterations++;
3208 return fn(v, useKeys ? k : iterations - 1, this$0) !== false &&
3209 iterations !== sliceSize;
3210 }
3211 });
3212 return iterations;
3213 };
3214
3215 sliceSeq.__iteratorUncached = function(type, reverse) {
3216 if (sliceSize !== 0 && reverse) {
3217 return this.cacheResult().__iterator(type, reverse);
3218 }
3219 // Don't bother instantiating parent iterator if taking 0.
3220 var iterator = sliceSize !== 0 && iterable.__iterator(type, reverse);
3221 var skipped = 0;
3222 var iterations = 0;
3223 return new Iterator(function() {
3224 while (skipped++ < resolvedBegin) {
3225 iterator.next();
3226 }
3227 if (++iterations > sliceSize) {
3228 return iteratorDone();
3229 }
3230 var step = iterator.next();
3231 if (useKeys || type === ITERATE_VALUES) {
3232 return step;
3233 } else if (type === ITERATE_KEYS) {
3234 return iteratorValue(type, iterations - 1, undefined, step);
3235 } else {
3236 return iteratorValue(type, iterations - 1, step.value[1], step);
3237 }
3238 });
3239 }
3240
3241 return sliceSeq;
3242 }
3243
3244
3245 function takeWhileFactory(iterable, predicate, context) {
3246 var takeSequence = makeSequence(iterable);
3247 takeSequence.__iterateUncached = function(fn, reverse) {var this$0 = this;
3248 if (reverse) {
3249 return this.cacheResult().__iterate(fn, reverse);
3250 }
3251 var iterations = 0;
3252 iterable.__iterate(function(v, k, c)
3253 {return predicate.call(context, v, k, c) && ++iterations && fn(v, k, this$0)}
3254 );
3255 return iterations;
3256 };
3257 takeSequence.__iteratorUncached = function(type, reverse) {var this$0 = this;
3258 if (reverse) {
3259 return this.cacheResult().__iterator(type, reverse);
3260 }
3261 var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
3262 var iterating = true;
3263 return new Iterator(function() {
3264 if (!iterating) {
3265 return iteratorDone();
3266 }
3267 var step = iterator.next();
3268 if (step.done) {
3269 return step;
3270 }
3271 var entry = step.value;
3272 var k = entry[0];
3273 var v = entry[1];
3274 if (!predicate.call(context, v, k, this$0)) {
3275 iterating = false;
3276 return iteratorDone();
3277 }
3278 return type === ITERATE_ENTRIES ? step :
3279 iteratorValue(type, k, v, step);
3280 });
3281 };
3282 return takeSequence;
3283 }
3284
3285
3286 function skipWhileFactory(iterable, predicate, context, useKeys) {
3287 var skipSequence = makeSequence(iterable);
3288 skipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this;
3289 if (reverse) {
3290 return this.cacheResult().__iterate(fn, reverse);
3291 }
3292 var isSkipping = true;
3293 var iterations = 0;
3294 iterable.__iterate(function(v, k, c) {
3295 if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) {
3296 iterations++;
3297 return fn(v, useKeys ? k : iterations - 1, this$0);
3298 }
3299 });
3300 return iterations;
3301 };
3302 skipSequence.__iteratorUncached = function(type, reverse) {var this$0 = this;
3303 if (reverse) {
3304 return this.cacheResult().__iterator(type, reverse);
3305 }
3306 var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse);
3307 var skipping = true;
3308 var iterations = 0;
3309 return new Iterator(function() {
3310 var step, k, v;
3311 do {
3312 step = iterator.next();
3313 if (step.done) {
3314 if (useKeys || type === ITERATE_VALUES) {
3315 return step;
3316 } else if (type === ITERATE_KEYS) {
3317 return iteratorValue(type, iterations++, undefined, step);
3318 } else {
3319 return iteratorValue(type, iterations++, step.value[1], step);
3320 }
3321 }
3322 var entry = step.value;
3323 k = entry[0];
3324 v = entry[1];
3325 skipping && (skipping = predicate.call(context, v, k, this$0));
3326 } while (skipping);
3327 return type === ITERATE_ENTRIES ? step :
3328 iteratorValue(type, k, v, step);
3329 });
3330 };
3331 return skipSequence;
3332 }
3333
3334
3335 function concatFactory(iterable, values) {
3336 var isKeyedIterable = isKeyed(iterable);
3337 var iters = [iterable].concat(values).map(function(v ) {
3338 if (!isIterable(v)) {
3339 v = isKeyedIterable ?
3340 keyedSeqFromValue(v) :
3341 indexedSeqFromValue(Array.isArray(v) ? v : [v]);
3342 } else if (isKeyedIterable) {
3343 v = KeyedIterable(v);
3344 }
3345 return v;
3346 }).filter(function(v ) {return v.size !== 0});
3347
3348 if (iters.length === 0) {
3349 return iterable;
3350 }
3351
3352 if (iters.length === 1) {
3353 var singleton = iters[0];
3354 if (singleton === iterable ||
3355 isKeyedIterable && isKeyed(singleton) ||
3356 isIndexed(iterable) && isIndexed(singleton)) {
3357 return singleton;
3358 }
3359 }
3360
3361 var concatSeq = new ArraySeq(iters);
3362 if (isKeyedIterable) {
3363 concatSeq = concatSeq.toKeyedSeq();
3364 } else if (!isIndexed(iterable)) {
3365 concatSeq = concatSeq.toSetSeq();
3366 }
3367 concatSeq = concatSeq.flatten(true);
3368 concatSeq.size = iters.reduce(
3369 function(sum, seq) {
3370 if (sum !== undefined) {
3371 var size = seq.size;
3372 if (size !== undefined) {
3373 return sum + size;
3374 }
3375 }
3376 },
3377 0
3378 );
3379 return concatSeq;
3380 }
3381
3382
3383 function flattenFactory(iterable, depth, useKeys) {
3384 var flatSequence = makeSequence(iterable);
3385 flatSequence.__iterateUncached = function(fn, reverse) {
3386 var iterations = 0;
3387 var stopped = false;
3388 function flatDeep(iter, currentDepth) {var this$0 = this;
3389 iter.__iterate(function(v, k) {
3390 if ((!depth || currentDepth < depth) && isIterable(v)) {
3391 flatDeep(v, currentDepth + 1);
3392 } else if (fn(v, useKeys ? k : iterations++, this$0) === false) {
3393 stopped = true;
3394 }
3395 return !stopped;
3396 }, reverse);
3397 }
3398 flatDeep(iterable, 0);
3399 return iterations;
3400 }
3401 flatSequence.__iteratorUncached = function(type, reverse) {
3402 var iterator = iterable.__iterator(type, reverse);
3403 var stack = [];
3404 var iterations = 0;
3405 return new Iterator(function() {
3406 while (iterator) {
3407 var step = iterator.next();
3408 if (step.done !== false) {
3409 iterator = stack.pop();
3410 continue;
3411 }
3412 var v = step.value;
3413 if (type === ITERATE_ENTRIES) {
3414 v = v[1];
3415 }
3416 if ((!depth || stack.length < depth) && isIterable(v)) {
3417 stack.push(iterator);
3418 iterator = v.__iterator(type, reverse);
3419 } else {
3420 return useKeys ? step : iteratorValue(type, iterations++, v, step);
3421 }
3422 }
3423 return iteratorDone();
3424 });
3425 }
3426 return flatSequence;
3427 }
3428
3429
3430 function flatMapFactory(iterable, mapper, context) {
3431 var coerce = iterableClass(iterable);
3432 return iterable.toSeq().map(
3433 function(v, k) {return coerce(mapper.call(context, v, k, iterable))}
3434 ).flatten(true);
3435 }
3436
3437
3438 function interposeFactory(iterable, separator) {
3439 var interposedSequence = makeSequence(iterable);
3440 interposedSequence.size = iterable.size && iterable.size * 2 -1;
3441 interposedSequence.__iterateUncached = function(fn, reverse) {var this$0 = this;
3442 var iterations = 0;
3443 iterable.__iterate(function(v, k)
3444 {return (!iterations || fn(separator, iterations++, this$0) !== false) &&
3445 fn(v, iterations++, this$0) !== false},
3446 reverse
3447 );
3448 return iterations;
3449 };
3450 interposedSequence.__iteratorUncached = function(type, reverse) {
3451 var iterator = iterable.__iterator(ITERATE_VALUES, reverse);
3452 var iterations = 0;
3453 var step;
3454 return new Iterator(function() {
3455 if (!step || iterations % 2) {
3456 step = iterator.next();
3457 if (step.done) {
3458 return step;
3459 }
3460 }
3461 return iterations % 2 ?
3462 iteratorValue(type, iterations++, separator) :
3463 iteratorValue(type, iterations++, step.value, step);
3464 });
3465 };
3466 return interposedSequence;
3467 }
3468
3469
3470 function sortFactory(iterable, comparator, mapper) {
3471 if (!comparator) {
3472 comparator = defaultComparator;
3473 }
3474 var isKeyedIterable = isKeyed(iterable);
3475 var index = 0;
3476 var entries = iterable.toSeq().map(
3477 function(v, k) {return [k, v, index++, mapper ? mapper(v, k, iterable) : v]}
3478 ).toArray();
3479 entries.sort(function(a, b) {return comparator(a[3], b[3]) || a[2] - b[2]}).forEach(
3480 isKeyedIterable ?
3481 function(v, i) { entries[i].length = 2; } :
3482 function(v, i) { entries[i] = v[1]; }
3483 );
3484 return isKeyedIterable ? KeyedSeq(entries) :
3485 isIndexed(iterable) ? IndexedSeq(entries) :
3486 SetSeq(entries);
3487 }
3488
3489
3490 function maxFactory(iterable, comparator, mapper) {
3491 if (!comparator) {
3492 comparator = defaultComparator;
3493 }
3494 if (mapper) {
3495 var entry = iterable.toSeq()
3496 .map(function(v, k) {return [v, mapper(v, k, iterable)]})
3497 .reduce(function(a, b) {return maxCompare(comparator, a[1], b[1]) ? b : a});
3498 return entry && entry[0];
3499 } else {
3500 return iterable.reduce(function(a, b) {return maxCompare(comparator, a, b) ? b : a});
3501 }
3502 }
3503
3504 function maxCompare(comparator, a, b) {
3505 var comp = comparator(b, a);
3506 // b is considered the new max if the comparator declares them equal, but
3507 // they are not equal and b is in fact a nullish value.
3508 return (comp === 0 && b !== a && (b === undefined || b === null || b !== b)) || comp > 0;
3509 }
3510
3511
3512 function zipWithFactory(keyIter, zipper, iters) {
3513 var zipSequence = makeSequence(keyIter);
3514 zipSequence.size = new ArraySeq(iters).map(function(i ) {return i.size}).min();
3515 // Note: this a generic base implementation of __iterate in terms of
3516 // __iterator which may be more generically useful in the future.
3517 zipSequence.__iterate = function(fn, reverse) {
3518 /* generic:
3519 var iterator = this.__iterator(ITERATE_ENTRIES, reverse);
3520 var step;
3521 var iterations = 0;
3522 while (!(step = iterator.next()).done) {
3523 iterations++;
3524 if (fn(step.value[1], step.value[0], this) === false) {
3525 break;
3526 }
3527 }
3528 return iterations;
3529 */
3530 // indexed:
3531 var iterator = this.__iterator(ITERATE_VALUES, reverse);
3532 var step;
3533 var iterations = 0;
3534 while (!(step = iterator.next()).done) {
3535 if (fn(step.value, iterations++, this) === false) {
3536 break;
3537 }
3538 }
3539 return iterations;
3540 };
3541 zipSequence.__iteratorUncached = function(type, reverse) {
3542 var iterators = iters.map(function(i )
3543 {return (i = Iterable(i), getIterator(reverse ? i.reverse() : i))}
3544 );
3545 var iterations = 0;
3546 var isDone = false;
3547 return new Iterator(function() {
3548 var steps;
3549 if (!isDone) {
3550 steps = iterators.map(function(i ) {return i.next()});
3551 isDone = steps.some(function(s ) {return s.done});
3552 }
3553 if (isDone) {
3554 return iteratorDone();
3555 }
3556 return iteratorValue(
3557 type,
3558 iterations++,
3559 zipper.apply(null, steps.map(function(s ) {return s.value}))
3560 );
3561 });
3562 };
3563 return zipSequence
3564 }
3565
3566
3567 // #pragma Helper Functions
3568
3569 function reify(iter, seq) {
3570 return isSeq(iter) ? seq : iter.constructor(seq);
3571 }
3572
3573 function validateEntry(entry) {
3574 if (entry !== Object(entry)) {
3575 throw new TypeError('Expected [K, V] tuple: ' + entry);
3576 }
3577 }
3578
3579 function resolveSize(iter) {
3580 assertNotInfinite(iter.size);
3581 return ensureSize(iter);
3582 }
3583
3584 function iterableClass(iterable) {
3585 return isKeyed(iterable) ? KeyedIterable :
3586 isIndexed(iterable) ? IndexedIterable :
3587 SetIterable;
3588 }
3589
3590 function makeSequence(iterable) {
3591 return Object.create(
3592 (
3593 isKeyed(iterable) ? KeyedSeq :
3594 isIndexed(iterable) ? IndexedSeq :
3595 SetSeq
3596 ).prototype
3597 );
3598 }
3599
3600 function cacheResultThrough() {
3601 if (this._iter.cacheResult) {
3602 this._iter.cacheResult();
3603 this.size = this._iter.size;
3604 return this;
3605 } else {
3606 return Seq.prototype.cacheResult.call(this);
3607 }
3608 }
3609
3610 function defaultComparator(a, b) {
3611 return a > b ? 1 : a < b ? -1 : 0;
3612 }
3613
3614 function forceIterator(keyPath) {
3615 var iter = getIterator(keyPath);
3616 if (!iter) {
3617 // Array might not be iterable in this environment, so we need a fallback
3618 // to our wrapped type.
3619 if (!isArrayLike(keyPath)) {
3620 throw new TypeError('Expected iterable or array-like: ' + keyPath);
3621 }
3622 iter = getIterator(Iterable(keyPath));
3623 }
3624 return iter;
3625 }
3626
3627 createClass(Record, KeyedCollection);
3628
3629 function Record(defaultValues, name) {
3630 var hasInitialized;
3631
3632 var RecordType = function Record(values) {
3633 if (values instanceof RecordType) {
3634 return values;
3635 }
3636 if (!(this instanceof RecordType)) {
3637 return new RecordType(values);
3638 }
3639 if (!hasInitialized) {
3640 hasInitialized = true;
3641 var keys = Object.keys(defaultValues);
3642 setProps(RecordTypePrototype, keys);
3643 RecordTypePrototype.size = keys.length;
3644 RecordTypePrototype._name = name;
3645 RecordTypePrototype._keys = keys;
3646 RecordTypePrototype._defaultValues = defaultValues;
3647 }
3648 this._map = Map(values);
3649 };
3650
3651 var RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype);
3652 RecordTypePrototype.constructor = RecordType;
3653
3654 return RecordType;
3655 }
3656
3657 Record.prototype.toString = function() {
3658 return this.__toString(recordName(this) + ' {', '}');
3659 };
3660
3661 // @pragma Access
3662
3663 Record.prototype.has = function(k) {
3664 return this._defaultValues.hasOwnProperty(k);
3665 };
3666
3667 Record.prototype.get = function(k, notSetValue) {
3668 if (!this.has(k)) {
3669 return notSetValue;
3670 }
3671 var defaultVal = this._defaultValues[k];
3672 return this._map ? this._map.get(k, defaultVal) : defaultVal;
3673 };
3674
3675 // @pragma Modification
3676
3677 Record.prototype.clear = function() {
3678 if (this.__ownerID) {
3679 this._map && this._map.clear();
3680 return this;
3681 }
3682 var RecordType = this.constructor;
3683 return RecordType._empty || (RecordType._empty = makeRecord(this, emptyMap()));
3684 };
3685
3686 Record.prototype.set = function(k, v) {
3687 if (!this.has(k)) {
3688 throw new Error('Cannot set unknown key "' + k + '" on ' + recordName(this));
3689 }
3690 if (this._map && !this._map.has(k)) {
3691 var defaultVal = this._defaultValues[k];
3692 if (v === defaultVal) {
3693 return this;
3694 }
3695 }
3696 var newMap = this._map && this._map.set(k, v);
3697 if (this.__ownerID || newMap === this._map) {
3698 return this;
3699 }
3700 return makeRecord(this, newMap);
3701 };
3702
3703 Record.prototype.remove = function(k) {
3704 if (!this.has(k)) {
3705 return this;
3706 }
3707 var newMap = this._map && this._map.remove(k);
3708 if (this.__ownerID || newMap === this._map) {
3709 return this;
3710 }
3711 return makeRecord(this, newMap);
3712 };
3713
3714 Record.prototype.wasAltered = function() {
3715 return this._map.wasAltered();
3716 };
3717
3718 Record.prototype.__iterator = function(type, reverse) {var this$0 = this;
3719 return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterator(type, reverse);
3720 };
3721
3722 Record.prototype.__iterate = function(fn, reverse) {var this$0 = this;
3723 return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterate(fn, reverse);
3724 };
3725
3726 Record.prototype.__ensureOwner = function(ownerID) {
3727 if (ownerID === this.__ownerID) {
3728 return this;
3729 }
3730 var newMap = this._map && this._map.__ensureOwner(ownerID);
3731 if (!ownerID) {
3732 this.__ownerID = ownerID;
3733 this._map = newMap;
3734 return this;
3735 }
3736 return makeRecord(this, newMap, ownerID);
3737 };
3738
3739
3740 var RecordPrototype = Record.prototype;
3741 RecordPrototype[DELETE] = RecordPrototype.remove;
3742 RecordPrototype.deleteIn =
3743 RecordPrototype.removeIn = MapPrototype.removeIn;
3744 RecordPrototype.merge = MapPrototype.merge;
3745 RecordPrototype.mergeWith = MapPrototype.mergeWith;
3746 RecordPrototype.mergeIn = MapPrototype.mergeIn;
3747 RecordPrototype.mergeDeep = MapPrototype.mergeDeep;
3748 RecordPrototype.mergeDeepWith = MapPrototype.mergeDeepWith;
3749 RecordPrototype.mergeDeepIn = MapPrototype.mergeDeepIn;
3750 RecordPrototype.setIn = MapPrototype.setIn;
3751 RecordPrototype.update = MapPrototype.update;
3752 RecordPrototype.updateIn = MapPrototype.updateIn;
3753 RecordPrototype.withMutations = MapPrototype.withMutations;
3754 RecordPrototype.asMutable = MapPrototype.asMutable;
3755 RecordPrototype.asImmutable = MapPrototype.asImmutable;
3756
3757
3758 function makeRecord(likeRecord, map, ownerID) {
3759 var record = Object.create(Object.getPrototypeOf(likeRecord));
3760 record._map = map;
3761 record.__ownerID = ownerID;
3762 return record;
3763 }
3764
3765 function recordName(record) {
3766 return record._name || record.constructor.name || 'Record';
3767 }
3768
3769 function setProps(prototype, names) {
3770 try {
3771 names.forEach(setProp.bind(undefined, prototype));
3772 } catch (error) {
3773 // Object.defineProperty failed. Probably IE8.
3774 }
3775 }
3776
3777 function setProp(prototype, name) {
3778 Object.defineProperty(prototype, name, {
3779 get: function() {
3780 return this.get(name);
3781 },
3782 set: function(value) {
3783 invariant(this.__ownerID, 'Cannot set on an immutable record.');
3784 this.set(name, value);
3785 }
3786 });
3787 }
3788
3789 createClass(Set, SetCollection);
3790
3791 // @pragma Construction
3792
3793 function Set(value) {
3794 return value === null || value === undefined ? emptySet() :
3795 isSet(value) && !isOrdered(value) ? value :
3796 emptySet().withMutations(function(set ) {
3797 var iter = SetIterable(value);
3798 assertNotInfinite(iter.size);
3799 iter.forEach(function(v ) {return set.add(v)});
3800 });
3801 }
3802
3803 Set.of = function(/*...values*/) {
3804 return this(arguments);
3805 };
3806
3807 Set.fromKeys = function(value) {
3808 return this(KeyedIterable(value).keySeq());
3809 };
3810
3811 Set.prototype.toString = function() {
3812 return this.__toString('Set {', '}');
3813 };
3814
3815 // @pragma Access
3816
3817 Set.prototype.has = function(value) {
3818 return this._map.has(value);
3819 };
3820
3821 // @pragma Modification
3822
3823 Set.prototype.add = function(value) {
3824 return updateSet(this, this._map.set(value, true));
3825 };
3826
3827 Set.prototype.remove = function(value) {
3828 return updateSet(this, this._map.remove(value));
3829 };
3830
3831 Set.prototype.clear = function() {
3832 return updateSet(this, this._map.clear());
3833 };
3834
3835 // @pragma Composition
3836
3837 Set.prototype.union = function() {var iters = SLICE$0.call(arguments, 0);
3838 iters = iters.filter(function(x ) {return x.size !== 0});
3839 if (iters.length === 0) {
3840 return this;
3841 }
3842 if (this.size === 0 && !this.__ownerID && iters.length === 1) {
3843 return this.constructor(iters[0]);
3844 }
3845 return this.withMutations(function(set ) {
3846 for (var ii = 0; ii < iters.length; ii++) {
3847 SetIterable(iters[ii]).forEach(function(value ) {return set.add(value)});
3848 }
3849 });
3850 };
3851
3852 Set.prototype.intersect = function() {var iters = SLICE$0.call(arguments, 0);
3853 if (iters.length === 0) {
3854 return this;
3855 }
3856 iters = iters.map(function(iter ) {return SetIterable(iter)});
3857 var originalSet = this;
3858 return this.withMutations(function(set ) {
3859 originalSet.forEach(function(value ) {
3860 if (!iters.every(function(iter ) {return iter.includes(value)})) {
3861 set.remove(value);
3862 }
3863 });
3864 });
3865 };
3866
3867 Set.prototype.subtract = function() {var iters = SLICE$0.call(arguments, 0);
3868 if (iters.length === 0) {
3869 return this;
3870 }
3871 iters = iters.map(function(iter ) {return SetIterable(iter)});
3872 var originalSet = this;
3873 return this.withMutations(function(set ) {
3874 originalSet.forEach(function(value ) {
3875 if (iters.some(function(iter ) {return iter.includes(value)})) {
3876 set.remove(value);
3877 }
3878 });
3879 });
3880 };
3881
3882 Set.prototype.merge = function() {
3883 return this.union.apply(this, arguments);
3884 };
3885
3886 Set.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1);
3887 return this.union.apply(this, iters);
3888 };
3889
3890 Set.prototype.sort = function(comparator) {
3891 // Late binding
3892 return OrderedSet(sortFactory(this, comparator));
3893 };
3894
3895 Set.prototype.sortBy = function(mapper, comparator) {
3896 // Late binding
3897 return OrderedSet(sortFactory(this, comparator, mapper));
3898 };
3899
3900 Set.prototype.wasAltered = function() {
3901 return this._map.wasAltered();
3902 };
3903
3904 Set.prototype.__iterate = function(fn, reverse) {var this$0 = this;
3905 return this._map.__iterate(function(_, k) {return fn(k, k, this$0)}, reverse);
3906 };
3907
3908 Set.prototype.__iterator = function(type, reverse) {
3909 return this._map.map(function(_, k) {return k}).__iterator(type, reverse);
3910 };
3911
3912 Set.prototype.__ensureOwner = function(ownerID) {
3913 if (ownerID === this.__ownerID) {
3914 return this;
3915 }
3916 var newMap = this._map.__ensureOwner(ownerID);
3917 if (!ownerID) {
3918 this.__ownerID = ownerID;
3919 this._map = newMap;
3920 return this;
3921 }
3922 return this.__make(newMap, ownerID);
3923 };
3924
3925
3926 function isSet(maybeSet) {
3927 return !!(maybeSet && maybeSet[IS_SET_SENTINEL]);
3928 }
3929
3930 Set.isSet = isSet;
3931
3932 var IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@';
3933
3934 var SetPrototype = Set.prototype;
3935 SetPrototype[IS_SET_SENTINEL] = true;
3936 SetPrototype[DELETE] = SetPrototype.remove;
3937 SetPrototype.mergeDeep = SetPrototype.merge;
3938 SetPrototype.mergeDeepWith = SetPrototype.mergeWith;
3939 SetPrototype.withMutations = MapPrototype.withMutations;
3940 SetPrototype.asMutable = MapPrototype.asMutable;
3941 SetPrototype.asImmutable = MapPrototype.asImmutable;
3942
3943 SetPrototype.__empty = emptySet;
3944 SetPrototype.__make = makeSet;
3945
3946 function updateSet(set, newMap) {
3947 if (set.__ownerID) {
3948 set.size = newMap.size;
3949 set._map = newMap;
3950 return set;
3951 }
3952 return newMap === set._map ? set :
3953 newMap.size === 0 ? set.__empty() :
3954 set.__make(newMap);
3955 }
3956
3957 function makeSet(map, ownerID) {
3958 var set = Object.create(SetPrototype);
3959 set.size = map ? map.size : 0;
3960 set._map = map;
3961 set.__ownerID = ownerID;
3962 return set;
3963 }
3964
3965 var EMPTY_SET;
3966 function emptySet() {
3967 return EMPTY_SET || (EMPTY_SET = makeSet(emptyMap()));
3968 }
3969
3970 createClass(OrderedSet, Set);
3971
3972 // @pragma Construction
3973
3974 function OrderedSet(value) {
3975 return value === null || value === undefined ? emptyOrderedSet() :
3976 isOrderedSet(value) ? value :
3977 emptyOrderedSet().withMutations(function(set ) {
3978 var iter = SetIterable(value);
3979 assertNotInfinite(iter.size);
3980 iter.forEach(function(v ) {return set.add(v)});
3981 });
3982 }
3983
3984 OrderedSet.of = function(/*...values*/) {
3985 return this(arguments);
3986 };
3987
3988 OrderedSet.fromKeys = function(value) {
3989 return this(KeyedIterable(value).keySeq());
3990 };
3991
3992 OrderedSet.prototype.toString = function() {
3993 return this.__toString('OrderedSet {', '}');
3994 };
3995
3996
3997 function isOrderedSet(maybeOrderedSet) {
3998 return isSet(maybeOrderedSet) && isOrdered(maybeOrderedSet);
3999 }
4000
4001 OrderedSet.isOrderedSet = isOrderedSet;
4002
4003 var OrderedSetPrototype = OrderedSet.prototype;
4004 OrderedSetPrototype[IS_ORDERED_SENTINEL] = true;
4005
4006 OrderedSetPrototype.__empty = emptyOrderedSet;
4007 OrderedSetPrototype.__make = makeOrderedSet;
4008
4009 function makeOrderedSet(map, ownerID) {
4010 var set = Object.create(OrderedSetPrototype);
4011 set.size = map ? map.size : 0;
4012 set._map = map;
4013 set.__ownerID = ownerID;
4014 return set;
4015 }
4016
4017 var EMPTY_ORDERED_SET;
4018 function emptyOrderedSet() {
4019 return EMPTY_ORDERED_SET || (EMPTY_ORDERED_SET = makeOrderedSet(emptyOrderedMap()));
4020 }
4021
4022 createClass(Stack, IndexedCollection);
4023
4024 // @pragma Construction
4025
4026 function Stack(value) {
4027 return value === null || value === undefined ? emptyStack() :
4028 isStack(value) ? value :
4029 emptyStack().unshiftAll(value);
4030 }
4031
4032 Stack.of = function(/*...values*/) {
4033 return this(arguments);
4034 };
4035
4036 Stack.prototype.toString = function() {
4037 return this.__toString('Stack [', ']');
4038 };
4039
4040 // @pragma Access
4041
4042 Stack.prototype.get = function(index, notSetValue) {
4043 var head = this._head;
4044 index = wrapIndex(this, index);
4045 while (head && index--) {
4046 head = head.next;
4047 }
4048 return head ? head.value : notSetValue;
4049 };
4050
4051 Stack.prototype.peek = function() {
4052 return this._head && this._head.value;
4053 };
4054
4055 // @pragma Modification
4056
4057 Stack.prototype.push = function(/*...values*/) {
4058 if (arguments.length === 0) {
4059 return this;
4060 }
4061 var newSize = this.size + arguments.length;
4062 var head = this._head;
4063 for (var ii = arguments.length - 1; ii >= 0; ii--) {
4064 head = {
4065 value: arguments[ii],
4066 next: head
4067 };
4068 }
4069 if (this.__ownerID) {
4070 this.size = newSize;
4071 this._head = head;
4072 this.__hash = undefined;
4073 this.__altered = true;
4074 return this;
4075 }
4076 return makeStack(newSize, head);
4077 };
4078
4079 Stack.prototype.pushAll = function(iter) {
4080 iter = IndexedIterable(iter);
4081 if (iter.size === 0) {
4082 return this;
4083 }
4084 assertNotInfinite(iter.size);
4085 var newSize = this.size;
4086 var head = this._head;
4087 iter.reverse().forEach(function(value ) {
4088 newSize++;
4089 head = {
4090 value: value,
4091 next: head
4092 };
4093 });
4094 if (this.__ownerID) {
4095 this.size = newSize;
4096 this._head = head;
4097 this.__hash = undefined;
4098 this.__altered = true;
4099 return this;
4100 }
4101 return makeStack(newSize, head);
4102 };
4103
4104 Stack.prototype.pop = function() {
4105 return this.slice(1);
4106 };
4107
4108 Stack.prototype.unshift = function(/*...values*/) {
4109 return this.push.apply(this, arguments);
4110 };
4111
4112 Stack.prototype.unshiftAll = function(iter) {
4113 return this.pushAll(iter);
4114 };
4115
4116 Stack.prototype.shift = function() {
4117 return this.pop.apply(this, arguments);
4118 };
4119
4120 Stack.prototype.clear = function() {
4121 if (this.size === 0) {
4122 return this;
4123 }
4124 if (this.__ownerID) {
4125 this.size = 0;
4126 this._head = undefined;
4127 this.__hash = undefined;
4128 this.__altered = true;
4129 return this;
4130 }
4131 return emptyStack();
4132 };
4133
4134 Stack.prototype.slice = function(begin, end) {
4135 if (wholeSlice(begin, end, this.size)) {
4136 return this;
4137 }
4138 var resolvedBegin = resolveBegin(begin, this.size);
4139 var resolvedEnd = resolveEnd(end, this.size);
4140 if (resolvedEnd !== this.size) {
4141 // super.slice(begin, end);
4142 return IndexedCollection.prototype.slice.call(this, begin, end);
4143 }
4144 var newSize = this.size - resolvedBegin;
4145 var head = this._head;
4146 while (resolvedBegin--) {
4147 head = head.next;
4148 }
4149 if (this.__ownerID) {
4150 this.size = newSize;
4151 this._head = head;
4152 this.__hash = undefined;
4153 this.__altered = true;
4154 return this;
4155 }
4156 return makeStack(newSize, head);
4157 };
4158
4159 // @pragma Mutability
4160
4161 Stack.prototype.__ensureOwner = function(ownerID) {
4162 if (ownerID === this.__ownerID) {
4163 return this;
4164 }
4165 if (!ownerID) {
4166 this.__ownerID = ownerID;
4167 this.__altered = false;
4168 return this;
4169 }
4170 return makeStack(this.size, this._head, ownerID, this.__hash);
4171 };
4172
4173 // @pragma Iteration
4174
4175 Stack.prototype.__iterate = function(fn, reverse) {
4176 if (reverse) {
4177 return this.reverse().__iterate(fn);
4178 }
4179 var iterations = 0;
4180 var node = this._head;
4181 while (node) {
4182 if (fn(node.value, iterations++, this) === false) {
4183 break;
4184 }
4185 node = node.next;
4186 }
4187 return iterations;
4188 };
4189
4190 Stack.prototype.__iterator = function(type, reverse) {
4191 if (reverse) {
4192 return this.reverse().__iterator(type);
4193 }
4194 var iterations = 0;
4195 var node = this._head;
4196 return new Iterator(function() {
4197 if (node) {
4198 var value = node.value;
4199 node = node.next;
4200 return iteratorValue(type, iterations++, value);
4201 }
4202 return iteratorDone();
4203 });
4204 };
4205
4206
4207 function isStack(maybeStack) {
4208 return !!(maybeStack && maybeStack[IS_STACK_SENTINEL]);
4209 }
4210
4211 Stack.isStack = isStack;
4212
4213 var IS_STACK_SENTINEL = '@@__IMMUTABLE_STACK__@@';
4214
4215 var StackPrototype = Stack.prototype;
4216 StackPrototype[IS_STACK_SENTINEL] = true;
4217 StackPrototype.withMutations = MapPrototype.withMutations;
4218 StackPrototype.asMutable = MapPrototype.asMutable;
4219 StackPrototype.asImmutable = MapPrototype.asImmutable;
4220 StackPrototype.wasAltered = MapPrototype.wasAltered;
4221
4222
4223 function makeStack(size, head, ownerID, hash) {
4224 var map = Object.create(StackPrototype);
4225 map.size = size;
4226 map._head = head;
4227 map.__ownerID = ownerID;
4228 map.__hash = hash;
4229 map.__altered = false;
4230 return map;
4231 }
4232
4233 var EMPTY_STACK;
4234 function emptyStack() {
4235 return EMPTY_STACK || (EMPTY_STACK = makeStack(0));
4236 }
4237
4238 /**
4239 * Contributes additional methods to a constructor
4240 */
4241 function mixin(ctor, methods) {
4242 var keyCopier = function(key ) { ctor.prototype[key] = methods[key]; };
4243 Object.keys(methods).forEach(keyCopier);
4244 Object.getOwnPropertySymbols &&
4245 Object.getOwnPropertySymbols(methods).forEach(keyCopier);
4246 return ctor;
4247 }
4248
4249 Iterable.Iterator = Iterator;
4250
4251 mixin(Iterable, {
4252
4253 // ### Conversion to other types
4254
4255 toArray: function() {
4256 assertNotInfinite(this.size);
4257 var array = new Array(this.size || 0);
4258 this.valueSeq().__iterate(function(v, i) { array[i] = v; });
4259 return array;
4260 },
4261
4262 toIndexedSeq: function() {
4263 return new ToIndexedSequence(this);
4264 },
4265
4266 toJS: function() {
4267 return this.toSeq().map(
4268 function(value ) {return value && typeof value.toJS === 'function' ? value.toJS() : value}
4269 ).__toJS();
4270 },
4271
4272 toJSON: function() {
4273 return this.toSeq().map(
4274 function(value ) {return value && typeof value.toJSON === 'function' ? value.toJSON() : value}
4275 ).__toJS();
4276 },
4277
4278 toKeyedSeq: function() {
4279 return new ToKeyedSequence(this, true);
4280 },
4281
4282 toMap: function() {
4283 // Use Late Binding here to solve the circular dependency.
4284 return Map(this.toKeyedSeq());
4285 },
4286
4287 toObject: function() {
4288 assertNotInfinite(this.size);
4289 var object = {};
4290 this.__iterate(function(v, k) { object[k] = v; });
4291 return object;
4292 },
4293
4294 toOrderedMap: function() {
4295 // Use Late Binding here to solve the circular dependency.
4296 return OrderedMap(this.toKeyedSeq());
4297 },
4298
4299 toOrderedSet: function() {
4300 // Use Late Binding here to solve the circular dependency.
4301 return OrderedSet(isKeyed(this) ? this.valueSeq() : this);
4302 },
4303
4304 toSet: function() {
4305 // Use Late Binding here to solve the circular dependency.
4306 return Set(isKeyed(this) ? this.valueSeq() : this);
4307 },
4308
4309 toSetSeq: function() {
4310 return new ToSetSequence(this);
4311 },
4312
4313 toSeq: function() {
4314 return isIndexed(this) ? this.toIndexedSeq() :
4315 isKeyed(this) ? this.toKeyedSeq() :
4316 this.toSetSeq();
4317 },
4318
4319 toStack: function() {
4320 // Use Late Binding here to solve the circular dependency.
4321 return Stack(isKeyed(this) ? this.valueSeq() : this);
4322 },
4323
4324 toList: function() {
4325 // Use Late Binding here to solve the circular dependency.
4326 return List(isKeyed(this) ? this.valueSeq() : this);
4327 },
4328
4329
4330 // ### Common JavaScript methods and properties
4331
4332 toString: function() {
4333 return '[Iterable]';
4334 },
4335
4336 __toString: function(head, tail) {
4337 if (this.size === 0) {
4338 return head + tail;
4339 }
4340 return head + ' ' + this.toSeq().map(this.__toStringMapper).join(', ') + ' ' + tail;
4341 },
4342
4343
4344 // ### ES6 Collection methods (ES6 Array and Map)
4345
4346 concat: function() {var values = SLICE$0.call(arguments, 0);
4347 return reify(this, concatFactory(this, values));
4348 },
4349
4350 includes: function(searchValue) {
4351 return this.some(function(value ) {return is(value, searchValue)});
4352 },
4353
4354 entries: function() {
4355 return this.__iterator(ITERATE_ENTRIES);
4356 },
4357
4358 every: function(predicate, context) {
4359 assertNotInfinite(this.size);
4360 var returnValue = true;
4361 this.__iterate(function(v, k, c) {
4362 if (!predicate.call(context, v, k, c)) {
4363 returnValue = false;
4364 return false;
4365 }
4366 });
4367 return returnValue;
4368 },
4369
4370 filter: function(predicate, context) {
4371 return reify(this, filterFactory(this, predicate, context, true));
4372 },
4373
4374 find: function(predicate, context, notSetValue) {
4375 var entry = this.findEntry(predicate, context);
4376 return entry ? entry[1] : notSetValue;
4377 },
4378
4379 forEach: function(sideEffect, context) {
4380 assertNotInfinite(this.size);
4381 return this.__iterate(context ? sideEffect.bind(context) : sideEffect);
4382 },
4383
4384 join: function(separator) {
4385 assertNotInfinite(this.size);
4386 separator = separator !== undefined ? '' + separator : ',';
4387 var joined = '';
4388 var isFirst = true;
4389 this.__iterate(function(v ) {
4390 isFirst ? (isFirst = false) : (joined += separator);
4391 joined += v !== null && v !== undefined ? v.toString() : '';
4392 });
4393 return joined;
4394 },
4395
4396 keys: function() {
4397 return this.__iterator(ITERATE_KEYS);
4398 },
4399
4400 map: function(mapper, context) {
4401 return reify(this, mapFactory(this, mapper, context));
4402 },
4403
4404 reduce: function(reducer, initialReduction, context) {
4405 assertNotInfinite(this.size);
4406 var reduction;
4407 var useFirst;
4408 if (arguments.length < 2) {
4409 useFirst = true;
4410 } else {
4411 reduction = initialReduction;
4412 }
4413 this.__iterate(function(v, k, c) {
4414 if (useFirst) {
4415 useFirst = false;
4416 reduction = v;
4417 } else {
4418 reduction = reducer.call(context, reduction, v, k, c);
4419 }
4420 });
4421 return reduction;
4422 },
4423
4424 reduceRight: function(reducer, initialReduction, context) {
4425 var reversed = this.toKeyedSeq().reverse();
4426 return reversed.reduce.apply(reversed, arguments);
4427 },
4428
4429 reverse: function() {
4430 return reify(this, reverseFactory(this, true));
4431 },
4432
4433 slice: function(begin, end) {
4434 return reify(this, sliceFactory(this, begin, end, true));
4435 },
4436
4437 some: function(predicate, context) {
4438 return !this.every(not(predicate), context);
4439 },
4440
4441 sort: function(comparator) {
4442 return reify(this, sortFactory(this, comparator));
4443 },
4444
4445 values: function() {
4446 return this.__iterator(ITERATE_VALUES);
4447 },
4448
4449
4450 // ### More sequential methods
4451
4452 butLast: function() {
4453 return this.slice(0, -1);
4454 },
4455
4456 isEmpty: function() {
4457 return this.size !== undefined ? this.size === 0 : !this.some(function() {return true});
4458 },
4459
4460 count: function(predicate, context) {
4461 return ensureSize(
4462 predicate ? this.toSeq().filter(predicate, context) : this
4463 );
4464 },
4465
4466 countBy: function(grouper, context) {
4467 return countByFactory(this, grouper, context);
4468 },
4469
4470 equals: function(other) {
4471 return deepEqual(this, other);
4472 },
4473
4474 entrySeq: function() {
4475 var iterable = this;
4476 if (iterable._cache) {
4477 // We cache as an entries array, so we can just return the cache!
4478 return new ArraySeq(iterable._cache);
4479 }
4480 var entriesSequence = iterable.toSeq().map(entryMapper).toIndexedSeq();
4481 entriesSequence.fromEntrySeq = function() {return iterable.toSeq()};
4482 return entriesSequence;
4483 },
4484
4485 filterNot: function(predicate, context) {
4486 return this.filter(not(predicate), context);
4487 },
4488
4489 findEntry: function(predicate, context, notSetValue) {
4490 var found = notSetValue;
4491 this.__iterate(function(v, k, c) {
4492 if (predicate.call(context, v, k, c)) {
4493 found = [k, v];
4494 return false;
4495 }
4496 });
4497 return found;
4498 },
4499
4500 findKey: function(predicate, context) {
4501 var entry = this.findEntry(predicate, context);
4502 return entry && entry[0];
4503 },
4504
4505 findLast: function(predicate, context, notSetValue) {
4506 return this.toKeyedSeq().reverse().find(predicate, context, notSetValue);
4507 },
4508
4509 findLastEntry: function(predicate, context, notSetValue) {
4510 return this.toKeyedSeq().reverse().findEntry(predicate, context, notSetValue);
4511 },
4512
4513 findLastKey: function(predicate, context) {
4514 return this.toKeyedSeq().reverse().findKey(predicate, context);
4515 },
4516
4517 first: function() {
4518 return this.find(returnTrue);
4519 },
4520
4521 flatMap: function(mapper, context) {
4522 return reify(this, flatMapFactory(this, mapper, context));
4523 },
4524
4525 flatten: function(depth) {
4526 return reify(this, flattenFactory(this, depth, true));
4527 },
4528
4529 fromEntrySeq: function() {
4530 return new FromEntriesSequence(this);
4531 },
4532
4533 get: function(searchKey, notSetValue) {
4534 return this.find(function(_, key) {return is(key, searchKey)}, undefined, notSetValue);
4535 },
4536
4537 getIn: function(searchKeyPath, notSetValue) {
4538 var nested = this;
4539 // Note: in an ES6 environment, we would prefer:
4540 // for (var key of searchKeyPath) {
4541 var iter = forceIterator(searchKeyPath);
4542 var step;
4543 while (!(step = iter.next()).done) {
4544 var key = step.value;
4545 nested = nested && nested.get ? nested.get(key, NOT_SET) : NOT_SET;
4546 if (nested === NOT_SET) {
4547 return notSetValue;
4548 }
4549 }
4550 return nested;
4551 },
4552
4553 groupBy: function(grouper, context) {
4554 return groupByFactory(this, grouper, context);
4555 },
4556
4557 has: function(searchKey) {
4558 return this.get(searchKey, NOT_SET) !== NOT_SET;
4559 },
4560
4561 hasIn: function(searchKeyPath) {
4562 return this.getIn(searchKeyPath, NOT_SET) !== NOT_SET;
4563 },
4564
4565 isSubset: function(iter) {
4566 iter = typeof iter.includes === 'function' ? iter : Iterable(iter);
4567 return this.every(function(value ) {return iter.includes(value)});
4568 },
4569
4570 isSuperset: function(iter) {
4571 iter = typeof iter.isSubset === 'function' ? iter : Iterable(iter);
4572 return iter.isSubset(this);
4573 },
4574
4575 keyOf: function(searchValue) {
4576 return this.findKey(function(value ) {return is(value, searchValue)});
4577 },
4578
4579 keySeq: function() {
4580 return this.toSeq().map(keyMapper).toIndexedSeq();
4581 },
4582
4583 last: function() {
4584 return this.toSeq().reverse().first();
4585 },
4586
4587 lastKeyOf: function(searchValue) {
4588 return this.toKeyedSeq().reverse().keyOf(searchValue);
4589 },
4590
4591 max: function(comparator) {
4592 return maxFactory(this, comparator);
4593 },
4594
4595 maxBy: function(mapper, comparator) {
4596 return maxFactory(this, comparator, mapper);
4597 },
4598
4599 min: function(comparator) {
4600 return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator);
4601 },
4602
4603 minBy: function(mapper, comparator) {
4604 return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator, mapper);
4605 },
4606
4607 rest: function() {
4608 return this.slice(1);
4609 },
4610
4611 skip: function(amount) {
4612 return this.slice(Math.max(0, amount));
4613 },
4614
4615 skipLast: function(amount) {
4616 return reify(this, this.toSeq().reverse().skip(amount).reverse());
4617 },
4618
4619 skipWhile: function(predicate, context) {
4620 return reify(this, skipWhileFactory(this, predicate, context, true));
4621 },
4622
4623 skipUntil: function(predicate, context) {
4624 return this.skipWhile(not(predicate), context);
4625 },
4626
4627 sortBy: function(mapper, comparator) {
4628 return reify(this, sortFactory(this, comparator, mapper));
4629 },
4630
4631 take: function(amount) {
4632 return this.slice(0, Math.max(0, amount));
4633 },
4634
4635 takeLast: function(amount) {
4636 return reify(this, this.toSeq().reverse().take(amount).reverse());
4637 },
4638
4639 takeWhile: function(predicate, context) {
4640 return reify(this, takeWhileFactory(this, predicate, context));
4641 },
4642
4643 takeUntil: function(predicate, context) {
4644 return this.takeWhile(not(predicate), context);
4645 },
4646
4647 valueSeq: function() {
4648 return this.toIndexedSeq();
4649 },
4650
4651
4652 // ### Hashable Object
4653
4654 hashCode: function() {
4655 return this.__hash || (this.__hash = hashIterable(this));
4656 }
4657
4658
4659 // ### Internal
4660
4661 // abstract __iterate(fn, reverse)
4662
4663 // abstract __iterator(type, reverse)
4664 });
4665
4666 // var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@';
4667 // var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@';
4668 // var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@';
4669 // var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@';
4670
4671 var IterablePrototype = Iterable.prototype;
4672 IterablePrototype[IS_ITERABLE_SENTINEL] = true;
4673 IterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.values;
4674 IterablePrototype.__toJS = IterablePrototype.toArray;
4675 IterablePrototype.__toStringMapper = quoteString;
4676 IterablePrototype.inspect =
4677 IterablePrototype.toSource = function() { return this.toString(); };
4678 IterablePrototype.chain = IterablePrototype.flatMap;
4679 IterablePrototype.contains = IterablePrototype.includes;
4680
4681 mixin(KeyedIterable, {
4682
4683 // ### More sequential methods
4684
4685 flip: function() {
4686 return reify(this, flipFactory(this));
4687 },
4688
4689 mapEntries: function(mapper, context) {var this$0 = this;
4690 var iterations = 0;
4691 return reify(this,
4692 this.toSeq().map(
4693 function(v, k) {return mapper.call(context, [k, v], iterations++, this$0)}
4694 ).fromEntrySeq()
4695 );
4696 },
4697
4698 mapKeys: function(mapper, context) {var this$0 = this;
4699 return reify(this,
4700 this.toSeq().flip().map(
4701 function(k, v) {return mapper.call(context, k, v, this$0)}
4702 ).flip()
4703 );
4704 }
4705
4706 });
4707
4708 var KeyedIterablePrototype = KeyedIterable.prototype;
4709 KeyedIterablePrototype[IS_KEYED_SENTINEL] = true;
4710 KeyedIterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.entries;
4711 KeyedIterablePrototype.__toJS = IterablePrototype.toObject;
4712 KeyedIterablePrototype.__toStringMapper = function(v, k) {return JSON.stringify(k) + ': ' + quoteString(v)};
4713
4714
4715
4716 mixin(IndexedIterable, {
4717
4718 // ### Conversion to other types
4719
4720 toKeyedSeq: function() {
4721 return new ToKeyedSequence(this, false);
4722 },
4723
4724
4725 // ### ES6 Collection methods (ES6 Array and Map)
4726
4727 filter: function(predicate, context) {
4728 return reify(this, filterFactory(this, predicate, context, false));
4729 },
4730
4731 findIndex: function(predicate, context) {
4732 var entry = this.findEntry(predicate, context);
4733 return entry ? entry[0] : -1;
4734 },
4735
4736 indexOf: function(searchValue) {
4737 var key = this.keyOf(searchValue);
4738 return key === undefined ? -1 : key;
4739 },
4740
4741 lastIndexOf: function(searchValue) {
4742 var key = this.lastKeyOf(searchValue);
4743 return key === undefined ? -1 : key;
4744 },
4745
4746 reverse: function() {
4747 return reify(this, reverseFactory(this, false));
4748 },
4749
4750 slice: function(begin, end) {
4751 return reify(this, sliceFactory(this, begin, end, false));
4752 },
4753
4754 splice: function(index, removeNum /*, ...values*/) {
4755 var numArgs = arguments.length;
4756 removeNum = Math.max(removeNum | 0, 0);
4757 if (numArgs === 0 || (numArgs === 2 && !removeNum)) {
4758 return this;
4759 }
4760 // If index is negative, it should resolve relative to the size of the
4761 // collection. However size may be expensive to compute if not cached, so
4762 // only call count() if the number is in fact negative.
4763 index = resolveBegin(index, index < 0 ? this.count() : this.size);
4764 var spliced = this.slice(0, index);
4765 return reify(
4766 this,
4767 numArgs === 1 ?
4768 spliced :
4769 spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum))
4770 );
4771 },
4772
4773
4774 // ### More collection methods
4775
4776 findLastIndex: function(predicate, context) {
4777 var entry = this.findLastEntry(predicate, context);
4778 return entry ? entry[0] : -1;
4779 },
4780
4781 first: function() {
4782 return this.get(0);
4783 },
4784
4785 flatten: function(depth) {
4786 return reify(this, flattenFactory(this, depth, false));
4787 },
4788
4789 get: function(index, notSetValue) {
4790 index = wrapIndex(this, index);
4791 return (index < 0 || (this.size === Infinity ||
4792 (this.size !== undefined && index > this.size))) ?
4793 notSetValue :
4794 this.find(function(_, key) {return key === index}, undefined, notSetValue);
4795 },
4796
4797 has: function(index) {
4798 index = wrapIndex(this, index);
4799 return index >= 0 && (this.size !== undefined ?
4800 this.size === Infinity || index < this.size :
4801 this.indexOf(index) !== -1
4802 );
4803 },
4804
4805 interpose: function(separator) {
4806 return reify(this, interposeFactory(this, separator));
4807 },
4808
4809 interleave: function(/*...iterables*/) {
4810 var iterables = [this].concat(arrCopy(arguments));
4811 var zipped = zipWithFactory(this.toSeq(), IndexedSeq.of, iterables);
4812 var interleaved = zipped.flatten(true);
4813 if (zipped.size) {
4814 interleaved.size = zipped.size * iterables.length;
4815 }
4816 return reify(this, interleaved);
4817 },
4818
4819 keySeq: function() {
4820 return Range(0, this.size);
4821 },
4822
4823 last: function() {
4824 return this.get(-1);
4825 },
4826
4827 skipWhile: function(predicate, context) {
4828 return reify(this, skipWhileFactory(this, predicate, context, false));
4829 },
4830
4831 zip: function(/*, ...iterables */) {
4832 var iterables = [this].concat(arrCopy(arguments));
4833 return reify(this, zipWithFactory(this, defaultZipper, iterables));
4834 },
4835
4836 zipWith: function(zipper/*, ...iterables */) {
4837 var iterables = arrCopy(arguments);
4838 iterables[0] = this;
4839 return reify(this, zipWithFactory(this, zipper, iterables));
4840 }
4841
4842 });
4843
4844 IndexedIterable.prototype[IS_INDEXED_SENTINEL] = true;
4845 IndexedIterable.prototype[IS_ORDERED_SENTINEL] = true;
4846
4847
4848
4849 mixin(SetIterable, {
4850
4851 // ### ES6 Collection methods (ES6 Array and Map)
4852
4853 get: function(value, notSetValue) {
4854 return this.has(value) ? value : notSetValue;
4855 },
4856
4857 includes: function(value) {
4858 return this.has(value);
4859 },
4860
4861
4862 // ### More sequential methods
4863
4864 keySeq: function() {
4865 return this.valueSeq();
4866 }
4867
4868 });
4869
4870 SetIterable.prototype.has = IterablePrototype.includes;
4871 SetIterable.prototype.contains = SetIterable.prototype.includes;
4872
4873
4874 // Mixin subclasses
4875
4876 mixin(KeyedSeq, KeyedIterable.prototype);
4877 mixin(IndexedSeq, IndexedIterable.prototype);
4878 mixin(SetSeq, SetIterable.prototype);
4879
4880 mixin(KeyedCollection, KeyedIterable.prototype);
4881 mixin(IndexedCollection, IndexedIterable.prototype);
4882 mixin(SetCollection, SetIterable.prototype);
4883
4884
4885 // #pragma Helper functions
4886
4887 function keyMapper(v, k) {
4888 return k;
4889 }
4890
4891 function entryMapper(v, k) {
4892 return [k, v];
4893 }
4894
4895 function not(predicate) {
4896 return function() {
4897 return !predicate.apply(this, arguments);
4898 }
4899 }
4900
4901 function neg(predicate) {
4902 return function() {
4903 return -predicate.apply(this, arguments);
4904 }
4905 }
4906
4907 function quoteString(value) {
4908 return typeof value === 'string' ? JSON.stringify(value) : String(value);
4909 }
4910
4911 function defaultZipper() {
4912 return arrCopy(arguments);
4913 }
4914
4915 function defaultNegComparator(a, b) {
4916 return a < b ? 1 : a > b ? -1 : 0;
4917 }
4918
4919 function hashIterable(iterable) {
4920 if (iterable.size === Infinity) {
4921 return 0;
4922 }
4923 var ordered = isOrdered(iterable);
4924 var keyed = isKeyed(iterable);
4925 var h = ordered ? 1 : 0;
4926 var size = iterable.__iterate(
4927 keyed ?
4928 ordered ?
4929 function(v, k) { h = 31 * h + hashMerge(hash(v), hash(k)) | 0; } :
4930 function(v, k) { h = h + hashMerge(hash(v), hash(k)) | 0; } :
4931 ordered ?
4932 function(v ) { h = 31 * h + hash(v) | 0; } :
4933 function(v ) { h = h + hash(v) | 0; }
4934 );
4935 return murmurHashOfSize(size, h);
4936 }
4937
4938 function murmurHashOfSize(size, h) {
4939 h = imul(h, 0xCC9E2D51);
4940 h = imul(h << 15 | h >>> -15, 0x1B873593);
4941 h = imul(h << 13 | h >>> -13, 5);
4942 h = (h + 0xE6546B64 | 0) ^ size;
4943 h = imul(h ^ h >>> 16, 0x85EBCA6B);
4944 h = imul(h ^ h >>> 13, 0xC2B2AE35);
4945 h = smi(h ^ h >>> 16);
4946 return h;
4947 }
4948
4949 function hashMerge(a, b) {
4950 return a ^ b + 0x9E3779B9 + (a << 6) + (a >> 2) | 0; // int
4951 }
4952
4953 var Immutable = {
4954
4955 Iterable: Iterable,
4956
4957 Seq: Seq,
4958 Collection: Collection,
4959 Map: Map,
4960 OrderedMap: OrderedMap,
4961 List: List,
4962 Stack: Stack,
4963 Set: Set,
4964 OrderedSet: OrderedSet,
4965
4966 Record: Record,
4967 Range: Range,
4968 Repeat: Repeat,
4969
4970 is: is,
4971 fromJS: fromJS
4972
4973 };
4974
4975 return Immutable;
4976
4977}));
Note: See TracBrowser for help on using the repository browser.