From 052277f16811596ed0109bb832728f596e00d0f6 Mon Sep 17 00:00:00 2001 From: Eden Halperin Date: Tue, 27 Jan 2015 17:15:07 -0800 Subject: [PATCH] initial --- .gitignore | 1 + bundle.js | 24050 +++++++++++++++++++++++++++++++++++++++++++ index.html | 17 + package.json | 29 + src/dark-v7.json | 669 ++ src/draw_layers.js | 54 + src/index.js | 137 + 7 files changed, 24957 insertions(+) create mode 100644 .gitignore create mode 100644 bundle.js create mode 100644 index.html create mode 100644 package.json create mode 100644 src/dark-v7.json create mode 100644 src/draw_layers.js create mode 100644 src/index.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/bundle.js b/bundle.js new file mode 100644 index 0000000..c5f1ea1 --- /dev/null +++ b/bundle.js @@ -0,0 +1,24050 @@ +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 0 ? (+index) : ensureSize(iter) + (+index); + } + + function returnTrue() { + return true; + } + + function wholeSlice(begin, end, size) { + return (begin === 0 || (size !== undefined && begin <= -size)) && + (end === undefined || (size !== undefined && end >= size)); + } + + function resolveBegin(begin, size) { + return resolveIndex(begin, size, 0); + } + + function resolveEnd(end, size) { + return resolveIndex(end, size, size); + } + + function resolveIndex(index, size, defaultIndex) { + return index === undefined ? + defaultIndex : + index < 0 ? + Math.max(0, size + index) : + size === undefined ? + index : + Math.min(size, index); + } + + function Iterable(value) { + return isIterable(value) ? value : Seq(value); + } + + + createClass(KeyedIterable, Iterable); + function KeyedIterable(value) { + return isKeyed(value) ? value : KeyedSeq(value); + } + + + createClass(IndexedIterable, Iterable); + function IndexedIterable(value) { + return isIndexed(value) ? value : IndexedSeq(value); + } + + + createClass(SetIterable, Iterable); + function SetIterable(value) { + return isIterable(value) && !isAssociative(value) ? value : SetSeq(value); + } + + + + function isIterable(maybeIterable) { + return !!(maybeIterable && maybeIterable[IS_ITERABLE_SENTINEL]); + } + + function isKeyed(maybeKeyed) { + return !!(maybeKeyed && maybeKeyed[IS_KEYED_SENTINEL]); + } + + function isIndexed(maybeIndexed) { + return !!(maybeIndexed && maybeIndexed[IS_INDEXED_SENTINEL]); + } + + function isAssociative(maybeAssociative) { + return isKeyed(maybeAssociative) || isIndexed(maybeAssociative); + } + + function isOrdered(maybeOrdered) { + return !!(maybeOrdered && maybeOrdered[IS_ORDERED_SENTINEL]); + } + + Iterable.isIterable = isIterable; + Iterable.isKeyed = isKeyed; + Iterable.isIndexed = isIndexed; + Iterable.isAssociative = isAssociative; + Iterable.isOrdered = isOrdered; + + Iterable.Keyed = KeyedIterable; + Iterable.Indexed = IndexedIterable; + Iterable.Set = SetIterable; + + + var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@'; + var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@'; + var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@'; + var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@'; + + /* global Symbol */ + + var ITERATE_KEYS = 0; + var ITERATE_VALUES = 1; + var ITERATE_ENTRIES = 2; + + var REAL_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; + var FAUX_ITERATOR_SYMBOL = '@@iterator'; + + var ITERATOR_SYMBOL = REAL_ITERATOR_SYMBOL || FAUX_ITERATOR_SYMBOL; + + + function Iterator(next) { + this.next = next; + } + + Iterator.prototype.toString = function() { + return '[Iterator]'; + }; + + + Iterator.KEYS = ITERATE_KEYS; + Iterator.VALUES = ITERATE_VALUES; + Iterator.ENTRIES = ITERATE_ENTRIES; + + Iterator.prototype.inspect = + Iterator.prototype.toSource = function () { return this.toString(); } + Iterator.prototype[ITERATOR_SYMBOL] = function () { + return this; + }; + + + function iteratorValue(type, k, v, iteratorResult) { + var value = type === 0 ? k : type === 1 ? v : [k, v]; + iteratorResult ? (iteratorResult.value = value) : (iteratorResult = { + value: value, done: false + }); + return iteratorResult; + } + + function iteratorDone() { + return { value: undefined, done: true }; + } + + function hasIterator(maybeIterable) { + return !!getIteratorFn(maybeIterable); + } + + function isIterator(maybeIterator) { + return maybeIterator && typeof maybeIterator.next === 'function'; + } + + function getIterator(iterable) { + var iteratorFn = getIteratorFn(iterable); + return iteratorFn && iteratorFn.call(iterable); + } + + function getIteratorFn(iterable) { + var iteratorFn = iterable && ( + (REAL_ITERATOR_SYMBOL && iterable[REAL_ITERATOR_SYMBOL]) || + iterable[FAUX_ITERATOR_SYMBOL] + ); + if (typeof iteratorFn === 'function') { + return iteratorFn; + } + } + + function isArrayLike(value) { + return value && typeof value.length === 'number'; + } + + createClass(Seq, Iterable); + function Seq(value) { + return value === null || value === undefined ? emptySequence() : + isIterable(value) ? value.toSeq() : seqFromValue(value); + } + + Seq.of = function(/*...values*/) { + return Seq(arguments); + }; + + Seq.prototype.toSeq = function() { + return this; + }; + + Seq.prototype.toString = function() { + return this.__toString('Seq {', '}'); + }; + + Seq.prototype.cacheResult = function() { + if (!this._cache && this.__iterateUncached) { + this._cache = this.entrySeq().toArray(); + this.size = this._cache.length; + } + return this; + }; + + // abstract __iterateUncached(fn, reverse) + + Seq.prototype.__iterate = function(fn, reverse) { + return seqIterate(this, fn, reverse, true); + }; + + // abstract __iteratorUncached(type, reverse) + + Seq.prototype.__iterator = function(type, reverse) { + return seqIterator(this, type, reverse, true); + }; + + + + createClass(KeyedSeq, Seq); + function KeyedSeq(value) { + return value === null || value === undefined ? + emptySequence().toKeyedSeq() : + isIterable(value) ? + (isKeyed(value) ? value.toSeq() : value.fromEntrySeq()) : + keyedSeqFromValue(value); + } + + KeyedSeq.of = function(/*...values*/) { + return KeyedSeq(arguments); + }; + + KeyedSeq.prototype.toKeyedSeq = function() { + return this; + }; + + KeyedSeq.prototype.toSeq = function() { + return this; + }; + + + + createClass(IndexedSeq, Seq); + function IndexedSeq(value) { + return value === null || value === undefined ? emptySequence() : + !isIterable(value) ? indexedSeqFromValue(value) : + isKeyed(value) ? value.entrySeq() : value.toIndexedSeq(); + } + + IndexedSeq.of = function(/*...values*/) { + return IndexedSeq(arguments); + }; + + IndexedSeq.prototype.toIndexedSeq = function() { + return this; + }; + + IndexedSeq.prototype.toString = function() { + return this.__toString('Seq [', ']'); + }; + + IndexedSeq.prototype.__iterate = function(fn, reverse) { + return seqIterate(this, fn, reverse, false); + }; + + IndexedSeq.prototype.__iterator = function(type, reverse) { + return seqIterator(this, type, reverse, false); + }; + + + + createClass(SetSeq, Seq); + function SetSeq(value) { + return ( + value === null || value === undefined ? emptySequence() : + !isIterable(value) ? indexedSeqFromValue(value) : + isKeyed(value) ? value.entrySeq() : value + ).toSetSeq(); + } + + SetSeq.of = function(/*...values*/) { + return SetSeq(arguments); + }; + + SetSeq.prototype.toSetSeq = function() { + return this; + }; + + + + Seq.isSeq = isSeq; + Seq.Keyed = KeyedSeq; + Seq.Set = SetSeq; + Seq.Indexed = IndexedSeq; + + var IS_SEQ_SENTINEL = '@@__IMMUTABLE_SEQ__@@'; + + Seq.prototype[IS_SEQ_SENTINEL] = true; + + + + // #pragma Root Sequences + + createClass(ArraySeq, IndexedSeq); + function ArraySeq(array) { + this._array = array; + this.size = array.length; + } + + ArraySeq.prototype.get = function(index, notSetValue) { + return this.has(index) ? this._array[wrapIndex(this, index)] : notSetValue; + }; + + ArraySeq.prototype.__iterate = function(fn, reverse) { + var array = this._array; + var maxIndex = array.length - 1; + for (var ii = 0; ii <= maxIndex; ii++) { + if (fn(array[reverse ? maxIndex - ii : ii], ii, this) === false) { + return ii + 1; + } + } + return ii; + }; + + ArraySeq.prototype.__iterator = function(type, reverse) { + var array = this._array; + var maxIndex = array.length - 1; + var ii = 0; + return new Iterator(function() + {return ii > maxIndex ? + iteratorDone() : + iteratorValue(type, ii, array[reverse ? maxIndex - ii++ : ii++])} + ); + }; + + + + createClass(ObjectSeq, KeyedSeq); + function ObjectSeq(object) { + var keys = Object.keys(object); + this._object = object; + this._keys = keys; + this.size = keys.length; + } + + ObjectSeq.prototype.get = function(key, notSetValue) { + if (notSetValue !== undefined && !this.has(key)) { + return notSetValue; + } + return this._object[key]; + }; + + ObjectSeq.prototype.has = function(key) { + return this._object.hasOwnProperty(key); + }; + + ObjectSeq.prototype.__iterate = function(fn, reverse) { + var object = this._object; + var keys = this._keys; + var maxIndex = keys.length - 1; + for (var ii = 0; ii <= maxIndex; ii++) { + var key = keys[reverse ? maxIndex - ii : ii]; + if (fn(object[key], key, this) === false) { + return ii + 1; + } + } + return ii; + }; + + ObjectSeq.prototype.__iterator = function(type, reverse) { + var object = this._object; + var keys = this._keys; + var maxIndex = keys.length - 1; + var ii = 0; + return new Iterator(function() { + var key = keys[reverse ? maxIndex - ii : ii]; + return ii++ > maxIndex ? + iteratorDone() : + iteratorValue(type, key, object[key]); + }); + }; + + ObjectSeq.prototype[IS_ORDERED_SENTINEL] = true; + + + createClass(IterableSeq, IndexedSeq); + function IterableSeq(iterable) { + this._iterable = iterable; + this.size = iterable.length || iterable.size; + } + + IterableSeq.prototype.__iterateUncached = function(fn, reverse) { + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + var iterable = this._iterable; + var iterator = getIterator(iterable); + var iterations = 0; + if (isIterator(iterator)) { + var step; + while (!(step = iterator.next()).done) { + if (fn(step.value, iterations++, this) === false) { + break; + } + } + } + return iterations; + }; + + IterableSeq.prototype.__iteratorUncached = function(type, reverse) { + if (reverse) { + return this.cacheResult().__iterator(type, reverse); + } + var iterable = this._iterable; + var iterator = getIterator(iterable); + if (!isIterator(iterator)) { + return new Iterator(iteratorDone); + } + var iterations = 0; + return new Iterator(function() { + var step = iterator.next(); + return step.done ? step : iteratorValue(type, iterations++, step.value); + }); + }; + + + + createClass(IteratorSeq, IndexedSeq); + function IteratorSeq(iterator) { + this._iterator = iterator; + this._iteratorCache = []; + } + + IteratorSeq.prototype.__iterateUncached = function(fn, reverse) { + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + var iterator = this._iterator; + var cache = this._iteratorCache; + var iterations = 0; + while (iterations < cache.length) { + if (fn(cache[iterations], iterations++, this) === false) { + return iterations; + } + } + var step; + while (!(step = iterator.next()).done) { + var val = step.value; + cache[iterations] = val; + if (fn(val, iterations++, this) === false) { + break; + } + } + return iterations; + }; + + IteratorSeq.prototype.__iteratorUncached = function(type, reverse) { + if (reverse) { + return this.cacheResult().__iterator(type, reverse); + } + var iterator = this._iterator; + var cache = this._iteratorCache; + var iterations = 0; + return new Iterator(function() { + if (iterations >= cache.length) { + var step = iterator.next(); + if (step.done) { + return step; + } + cache[iterations] = step.value; + } + return iteratorValue(type, iterations, cache[iterations++]); + }); + }; + + + + + // # pragma Helper functions + + function isSeq(maybeSeq) { + return !!(maybeSeq && maybeSeq[IS_SEQ_SENTINEL]); + } + + var EMPTY_SEQ; + + function emptySequence() { + return EMPTY_SEQ || (EMPTY_SEQ = new ArraySeq([])); + } + + function keyedSeqFromValue(value) { + var seq = + Array.isArray(value) ? new ArraySeq(value).fromEntrySeq() : + isIterator(value) ? new IteratorSeq(value).fromEntrySeq() : + hasIterator(value) ? new IterableSeq(value).fromEntrySeq() : + typeof value === 'object' ? new ObjectSeq(value) : + undefined; + if (!seq) { + throw new TypeError( + 'Expected Array or iterable object of [k, v] entries, '+ + 'or keyed object: ' + value + ); + } + return seq; + } + + function indexedSeqFromValue(value) { + var seq = maybeIndexedSeqFromValue(value); + if (!seq) { + throw new TypeError( + 'Expected Array or iterable object of values: ' + value + ); + } + return seq; + } + + function seqFromValue(value) { + var seq = maybeIndexedSeqFromValue(value) || + (typeof value === 'object' && new ObjectSeq(value)); + if (!seq) { + throw new TypeError( + 'Expected Array or iterable object of values, or keyed object: ' + value + ); + } + return seq; + } + + function maybeIndexedSeqFromValue(value) { + return ( + isArrayLike(value) ? new ArraySeq(value) : + isIterator(value) ? new IteratorSeq(value) : + hasIterator(value) ? new IterableSeq(value) : + undefined + ); + } + + function seqIterate(seq, fn, reverse, useKeys) { + var cache = seq._cache; + if (cache) { + var maxIndex = cache.length - 1; + for (var ii = 0; ii <= maxIndex; ii++) { + var entry = cache[reverse ? maxIndex - ii : ii]; + if (fn(entry[1], useKeys ? entry[0] : ii, seq) === false) { + return ii + 1; + } + } + return ii; + } + return seq.__iterateUncached(fn, reverse); + } + + function seqIterator(seq, type, reverse, useKeys) { + var cache = seq._cache; + if (cache) { + var maxIndex = cache.length - 1; + var ii = 0; + return new Iterator(function() { + var entry = cache[reverse ? maxIndex - ii : ii]; + return ii++ > maxIndex ? + iteratorDone() : + iteratorValue(type, useKeys ? entry[0] : ii - 1, entry[1]); + }); + } + return seq.__iteratorUncached(type, reverse); + } + + createClass(Collection, Iterable); + function Collection() { + throw TypeError('Abstract'); + } + + + createClass(KeyedCollection, Collection);function KeyedCollection() {} + + createClass(IndexedCollection, Collection);function IndexedCollection() {} + + createClass(SetCollection, Collection);function SetCollection() {} + + + Collection.Keyed = KeyedCollection; + Collection.Indexed = IndexedCollection; + Collection.Set = SetCollection; + + /** + * An extension of the "same-value" algorithm as [described for use by ES6 Map + * and Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#Key_equality) + * + * NaN is considered the same as NaN, however -0 and 0 are considered the same + * value, which is different from the algorithm described by + * [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is). + * + * This is extended further to allow Objects to describe the values they + * represent, by way of `valueOf` or `equals` (and `hashCode`). + * + * Note: because of this extension, the key equality of Immutable.Map and the + * value equality of Immutable.Set will differ from ES6 Map and Set. + * + * ### Defining custom values + * + * The easiest way to describe the value an object represents is by implementing + * `valueOf`. For example, `Date` represents a value by returning a unix + * timestamp for `valueOf`: + * + * var date1 = new Date(1234567890000); // Fri Feb 13 2009 ... + * var date2 = new Date(1234567890000); + * date1.valueOf(); // 1234567890000 + * assert( date1 !== date2 ); + * assert( Immutable.is( date1, date2 ) ); + * + * Note: overriding `valueOf` may have other implications if you use this object + * where JavaScript expects a primitive, such as implicit string coercion. + * + * For more complex types, especially collections, implementing `valueOf` may + * not be performant. An alternative is to implement `equals` and `hashCode`. + * + * `equals` takes another object, presumably of similar type, and returns true + * if the it is equal. Equality is symmetrical, so the same result should be + * returned if this and the argument are flipped. + * + * assert( a.equals(b) === b.equals(a) ); + * + * `hashCode` returns a 32bit integer number representing the object which will + * be used to determine how to store the value object in a Map or Set. You must + * provide both or neither methods, one must not exist without the other. + * + * Also, an important relationship between these methods must be upheld: if two + * values are equal, they *must* return the same hashCode. If the values are not + * equal, they might have the same hashCode; this is called a hash collision, + * and while undesirable for performance reasons, it is acceptable. + * + * if (a.equals(b)) { + * assert( a.hashCode() === b.hashCode() ); + * } + * + * All Immutable collections implement `equals` and `hashCode`. + * + */ + function is(valueA, valueB) { + if (valueA === valueB || (valueA !== valueA && valueB !== valueB)) { + return true; + } + if (!valueA || !valueB) { + return false; + } + if (typeof valueA.valueOf === 'function' && + typeof valueB.valueOf === 'function') { + valueA = valueA.valueOf(); + valueB = valueB.valueOf(); + } + return typeof valueA.equals === 'function' && + typeof valueB.equals === 'function' ? + valueA.equals(valueB) : + valueA === valueB || (valueA !== valueA && valueB !== valueB); + } + + function fromJS(json, converter) { + return converter ? + fromJSWith(converter, json, '', {'': json}) : + fromJSDefault(json); + } + + function fromJSWith(converter, json, key, parentJSON) { + if (Array.isArray(json)) { + return converter.call(parentJSON, key, IndexedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)})); + } + if (isPlainObj(json)) { + return converter.call(parentJSON, key, KeyedSeq(json).map(function(v, k) {return fromJSWith(converter, v, k, json)})); + } + return json; + } + + function fromJSDefault(json) { + if (Array.isArray(json)) { + return IndexedSeq(json).map(fromJSDefault).toList(); + } + if (isPlainObj(json)) { + return KeyedSeq(json).map(fromJSDefault).toMap(); + } + return json; + } + + function isPlainObj(value) { + return value && value.constructor === Object; + } + + var Math__imul = + typeof Math.imul === 'function' && Math.imul(0xffffffff, 2) === -2 ? + Math.imul : + function Math__imul(a, b) { + a = a | 0; // int + b = b | 0; // int + var c = a & 0xffff; + var d = b & 0xffff; + // Shift by 0 fixes the sign on the high part. + return (c * d) + ((((a >>> 16) * d + c * (b >>> 16)) << 16) >>> 0) | 0; // int + }; + + // v8 has an optimization for storing 31-bit signed numbers. + // Values which have either 00 or 11 as the high order bits qualify. + // This function drops the highest order bit in a signed number, maintaining + // the sign bit. + function smi(i32) { + return ((i32 >>> 1) & 0x40000000) | (i32 & 0xBFFFFFFF); + } + + function hash(o) { + if (o === false || o === null || o === undefined) { + return 0; + } + if (typeof o.valueOf === 'function') { + o = o.valueOf(); + if (o === false || o === null || o === undefined) { + return 0; + } + } + if (o === true) { + return 1; + } + var type = typeof o; + if (type === 'number') { + var h = o | 0; + if (h !== o) { + h ^= o * 0xFFFFFFFF; + } + while (o > 0xFFFFFFFF) { + o /= 0xFFFFFFFF; + h ^= o; + } + return smi(h); + } + if (type === 'string') { + return o.length > STRING_HASH_CACHE_MIN_STRLEN ? cachedHashString(o) : hashString(o); + } + if (typeof o.hashCode === 'function') { + return o.hashCode(); + } + return hashJSObj(o); + } + + function cachedHashString(string) { + var hash = stringHashCache[string]; + if (hash === undefined) { + hash = hashString(string); + if (STRING_HASH_CACHE_SIZE === STRING_HASH_CACHE_MAX_SIZE) { + STRING_HASH_CACHE_SIZE = 0; + stringHashCache = {}; + } + STRING_HASH_CACHE_SIZE++; + stringHashCache[string] = hash; + } + return hash; + } + + // http://jsperf.com/hashing-strings + function hashString(string) { + // This is the hash from JVM + // The hash code for a string is computed as + // s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1], + // where s[i] is the ith character of the string and n is the length of + // the string. We "mod" the result to make it between 0 (inclusive) and 2^31 + // (exclusive) by dropping high bits. + var hash = 0; + for (var ii = 0; ii < string.length; ii++) { + hash = 31 * hash + string.charCodeAt(ii) | 0; + } + return smi(hash); + } + + function hashJSObj(obj) { + var hash = weakMap && weakMap.get(obj); + if (hash) return hash; + + hash = obj[UID_HASH_KEY]; + if (hash) return hash; + + if (!canDefineProperty) { + hash = obj.propertyIsEnumerable && obj.propertyIsEnumerable[UID_HASH_KEY]; + if (hash) return hash; + + hash = getIENodeHash(obj); + if (hash) return hash; + } + + if (Object.isExtensible && !Object.isExtensible(obj)) { + throw new Error('Non-extensible objects are not allowed as keys.'); + } + + hash = ++objHashUID; + if (objHashUID & 0x40000000) { + objHashUID = 0; + } + + if (weakMap) { + weakMap.set(obj, hash); + } else if (canDefineProperty) { + Object.defineProperty(obj, UID_HASH_KEY, { + 'enumerable': false, + 'configurable': false, + 'writable': false, + 'value': hash + }); + } else if (obj.propertyIsEnumerable && + obj.propertyIsEnumerable === obj.constructor.prototype.propertyIsEnumerable) { + // Since we can't define a non-enumerable property on the object + // we'll hijack one of the less-used non-enumerable properties to + // save our hash on it. Since this is a function it will not show up in + // `JSON.stringify` which is what we want. + obj.propertyIsEnumerable = function() { + return this.constructor.prototype.propertyIsEnumerable.apply(this, arguments); + }; + obj.propertyIsEnumerable[UID_HASH_KEY] = hash; + } else if (obj.nodeType) { + // At this point we couldn't get the IE `uniqueID` to use as a hash + // and we couldn't use a non-enumerable property to exploit the + // dontEnum bug so we simply add the `UID_HASH_KEY` on the node + // itself. + obj[UID_HASH_KEY] = hash; + } else { + throw new Error('Unable to set a non-enumerable property on object.'); + } + + return hash; + } + + // True if Object.defineProperty works as expected. IE8 fails this test. + var canDefineProperty = (function() { + try { + Object.defineProperty({}, 'x', {}); + return true; + } catch (e) { + return false; + } + }()); + + // IE has a `uniqueID` property on DOM nodes. We can construct the hash from it + // and avoid memory leaks from the IE cloneNode bug. + function getIENodeHash(node) { + if (node && node.nodeType > 0) { + switch (node.nodeType) { + case 1: // Element + return node.uniqueID; + case 9: // Document + return node.documentElement && node.documentElement.uniqueID; + } + } + } + + // If possible, use a WeakMap. + var weakMap = typeof WeakMap === 'function' && new WeakMap(); + + var objHashUID = 0; + + var UID_HASH_KEY = '__immutablehash__'; + if (typeof Symbol === 'function') { + UID_HASH_KEY = Symbol(UID_HASH_KEY); + } + + var STRING_HASH_CACHE_MIN_STRLEN = 16; + var STRING_HASH_CACHE_MAX_SIZE = 255; + var STRING_HASH_CACHE_SIZE = 0; + var stringHashCache = {}; + + function invariant(condition, error) { + if (!condition) throw new Error(error); + } + + function assertNotInfinite(size) { + invariant( + size !== Infinity, + 'Cannot perform this action with an infinite size.' + ); + } + + createClass(ToKeyedSequence, KeyedSeq); + function ToKeyedSequence(indexed, useKeys) { + this._iter = indexed; + this._useKeys = useKeys; + this.size = indexed.size; + } + + ToKeyedSequence.prototype.get = function(key, notSetValue) { + return this._iter.get(key, notSetValue); + }; + + ToKeyedSequence.prototype.has = function(key) { + return this._iter.has(key); + }; + + ToKeyedSequence.prototype.valueSeq = function() { + return this._iter.valueSeq(); + }; + + ToKeyedSequence.prototype.reverse = function() {var this$0 = this; + var reversedSequence = reverseFactory(this, true); + if (!this._useKeys) { + reversedSequence.valueSeq = function() {return this$0._iter.toSeq().reverse()}; + } + return reversedSequence; + }; + + ToKeyedSequence.prototype.map = function(mapper, context) {var this$0 = this; + var mappedSequence = mapFactory(this, mapper, context); + if (!this._useKeys) { + mappedSequence.valueSeq = function() {return this$0._iter.toSeq().map(mapper, context)}; + } + return mappedSequence; + }; + + ToKeyedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; + var ii; + return this._iter.__iterate( + this._useKeys ? + function(v, k) {return fn(v, k, this$0)} : + ((ii = reverse ? resolveSize(this) : 0), + function(v ) {return fn(v, reverse ? --ii : ii++, this$0)}), + reverse + ); + }; + + ToKeyedSequence.prototype.__iterator = function(type, reverse) { + if (this._useKeys) { + return this._iter.__iterator(type, reverse); + } + var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); + var ii = reverse ? resolveSize(this) : 0; + return new Iterator(function() { + var step = iterator.next(); + return step.done ? step : + iteratorValue(type, reverse ? --ii : ii++, step.value, step); + }); + }; + + ToKeyedSequence.prototype[IS_ORDERED_SENTINEL] = true; + + + createClass(ToIndexedSequence, IndexedSeq); + function ToIndexedSequence(iter) { + this._iter = iter; + this.size = iter.size; + } + + ToIndexedSequence.prototype.contains = function(value) { + return this._iter.contains(value); + }; + + ToIndexedSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; + var iterations = 0; + return this._iter.__iterate(function(v ) {return fn(v, iterations++, this$0)}, reverse); + }; + + ToIndexedSequence.prototype.__iterator = function(type, reverse) { + var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); + var iterations = 0; + return new Iterator(function() { + var step = iterator.next(); + return step.done ? step : + iteratorValue(type, iterations++, step.value, step) + }); + }; + + + + createClass(ToSetSequence, SetSeq); + function ToSetSequence(iter) { + this._iter = iter; + this.size = iter.size; + } + + ToSetSequence.prototype.has = function(key) { + return this._iter.contains(key); + }; + + ToSetSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; + return this._iter.__iterate(function(v ) {return fn(v, v, this$0)}, reverse); + }; + + ToSetSequence.prototype.__iterator = function(type, reverse) { + var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); + return new Iterator(function() { + var step = iterator.next(); + return step.done ? step : + iteratorValue(type, step.value, step.value, step); + }); + }; + + + + createClass(FromEntriesSequence, KeyedSeq); + function FromEntriesSequence(entries) { + this._iter = entries; + this.size = entries.size; + } + + FromEntriesSequence.prototype.entrySeq = function() { + return this._iter.toSeq(); + }; + + FromEntriesSequence.prototype.__iterate = function(fn, reverse) {var this$0 = this; + return this._iter.__iterate(function(entry ) { + // Check if entry exists first so array access doesn't throw for holes + // in the parent iteration. + if (entry) { + validateEntry(entry); + return fn(entry[1], entry[0], this$0); + } + }, reverse); + }; + + FromEntriesSequence.prototype.__iterator = function(type, reverse) { + var iterator = this._iter.__iterator(ITERATE_VALUES, reverse); + return new Iterator(function() { + while (true) { + var step = iterator.next(); + if (step.done) { + return step; + } + var entry = step.value; + // Check if entry exists first so array access doesn't throw for holes + // in the parent iteration. + if (entry) { + validateEntry(entry); + return type === ITERATE_ENTRIES ? step : + iteratorValue(type, entry[0], entry[1], step); + } + } + }); + }; + + + ToIndexedSequence.prototype.cacheResult = + ToKeyedSequence.prototype.cacheResult = + ToSetSequence.prototype.cacheResult = + FromEntriesSequence.prototype.cacheResult = + cacheResultThrough; + + + function flipFactory(iterable) { + var flipSequence = makeSequence(iterable); + flipSequence._iter = iterable; + flipSequence.size = iterable.size; + flipSequence.flip = function() {return iterable}; + flipSequence.reverse = function () { + var reversedSequence = iterable.reverse.apply(this); // super.reverse() + reversedSequence.flip = function() {return iterable.reverse()}; + return reversedSequence; + }; + flipSequence.has = function(key ) {return iterable.contains(key)}; + flipSequence.contains = function(key ) {return iterable.has(key)}; + flipSequence.cacheResult = cacheResultThrough; + flipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; + return iterable.__iterate(function(v, k) {return fn(k, v, this$0) !== false}, reverse); + } + flipSequence.__iteratorUncached = function(type, reverse) { + if (type === ITERATE_ENTRIES) { + var iterator = iterable.__iterator(type, reverse); + return new Iterator(function() { + var step = iterator.next(); + if (!step.done) { + var k = step.value[0]; + step.value[0] = step.value[1]; + step.value[1] = k; + } + return step; + }); + } + return iterable.__iterator( + type === ITERATE_VALUES ? ITERATE_KEYS : ITERATE_VALUES, + reverse + ); + } + return flipSequence; + } + + + function mapFactory(iterable, mapper, context) { + var mappedSequence = makeSequence(iterable); + mappedSequence.size = iterable.size; + mappedSequence.has = function(key ) {return iterable.has(key)}; + mappedSequence.get = function(key, notSetValue) { + var v = iterable.get(key, NOT_SET); + return v === NOT_SET ? + notSetValue : + mapper.call(context, v, key, iterable); + }; + mappedSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; + return iterable.__iterate( + function(v, k, c) {return fn(mapper.call(context, v, k, c), k, this$0) !== false}, + reverse + ); + } + mappedSequence.__iteratorUncached = function (type, reverse) { + var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); + return new Iterator(function() { + var step = iterator.next(); + if (step.done) { + return step; + } + var entry = step.value; + var key = entry[0]; + return iteratorValue( + type, + key, + mapper.call(context, entry[1], key, iterable), + step + ); + }); + } + return mappedSequence; + } + + + function reverseFactory(iterable, useKeys) { + var reversedSequence = makeSequence(iterable); + reversedSequence._iter = iterable; + reversedSequence.size = iterable.size; + reversedSequence.reverse = function() {return iterable}; + if (iterable.flip) { + reversedSequence.flip = function () { + var flipSequence = flipFactory(iterable); + flipSequence.reverse = function() {return iterable.flip()}; + return flipSequence; + }; + } + reversedSequence.get = function(key, notSetValue) + {return iterable.get(useKeys ? key : -1 - key, notSetValue)}; + reversedSequence.has = function(key ) + {return iterable.has(useKeys ? key : -1 - key)}; + reversedSequence.contains = function(value ) {return iterable.contains(value)}; + reversedSequence.cacheResult = cacheResultThrough; + reversedSequence.__iterate = function (fn, reverse) {var this$0 = this; + return iterable.__iterate(function(v, k) {return fn(v, k, this$0)}, !reverse); + }; + reversedSequence.__iterator = + function(type, reverse) {return iterable.__iterator(type, !reverse)}; + return reversedSequence; + } + + + function filterFactory(iterable, predicate, context, useKeys) { + var filterSequence = makeSequence(iterable); + if (useKeys) { + filterSequence.has = function(key ) { + var v = iterable.get(key, NOT_SET); + return v !== NOT_SET && !!predicate.call(context, v, key, iterable); + }; + filterSequence.get = function(key, notSetValue) { + var v = iterable.get(key, NOT_SET); + return v !== NOT_SET && predicate.call(context, v, key, iterable) ? + v : notSetValue; + }; + } + filterSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; + var iterations = 0; + iterable.__iterate(function(v, k, c) { + if (predicate.call(context, v, k, c)) { + iterations++; + return fn(v, useKeys ? k : iterations - 1, this$0); + } + }, reverse); + return iterations; + }; + filterSequence.__iteratorUncached = function (type, reverse) { + var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); + var iterations = 0; + return new Iterator(function() { + while (true) { + var step = iterator.next(); + if (step.done) { + return step; + } + var entry = step.value; + var key = entry[0]; + var value = entry[1]; + if (predicate.call(context, value, key, iterable)) { + return iteratorValue(type, useKeys ? key : iterations++, value, step); + } + } + }); + } + return filterSequence; + } + + + function countByFactory(iterable, grouper, context) { + var groups = Map().asMutable(); + iterable.__iterate(function(v, k) { + groups.update( + grouper.call(context, v, k, iterable), + 0, + function(a ) {return a + 1} + ); + }); + return groups.asImmutable(); + } + + + function groupByFactory(iterable, grouper, context) { + var isKeyedIter = isKeyed(iterable); + var groups = (isOrdered(iterable) ? OrderedMap() : Map()).asMutable(); + iterable.__iterate(function(v, k) { + groups.update( + grouper.call(context, v, k, iterable), + function(a ) {return (a = a || [], a.push(isKeyedIter ? [k, v] : v), a)} + ); + }); + var coerce = iterableClass(iterable); + return groups.map(function(arr ) {return reify(iterable, coerce(arr))}); + } + + + function sliceFactory(iterable, begin, end, useKeys) { + var originalSize = iterable.size; + + if (wholeSlice(begin, end, originalSize)) { + return iterable; + } + + var resolvedBegin = resolveBegin(begin, originalSize); + var resolvedEnd = resolveEnd(end, originalSize); + + // begin or end will be NaN if they were provided as negative numbers and + // this iterable's size is unknown. In that case, cache first so there is + // a known size. + if (resolvedBegin !== resolvedBegin || resolvedEnd !== resolvedEnd) { + return sliceFactory(iterable.toSeq().cacheResult(), begin, end, useKeys); + } + + var sliceSize = resolvedEnd - resolvedBegin; + if (sliceSize < 0) { + sliceSize = 0; + } + + var sliceSeq = makeSequence(iterable); + + sliceSeq.size = sliceSize === 0 ? sliceSize : iterable.size && sliceSize || undefined; + + if (!useKeys && isSeq(iterable) && sliceSize >= 0) { + sliceSeq.get = function (index, notSetValue) { + index = wrapIndex(this, index); + return index >= 0 && index < sliceSize ? + iterable.get(index + resolvedBegin, notSetValue) : + notSetValue; + } + } + + sliceSeq.__iterateUncached = function(fn, reverse) {var this$0 = this; + if (sliceSize === 0) { + return 0; + } + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + var skipped = 0; + var isSkipping = true; + var iterations = 0; + iterable.__iterate(function(v, k) { + if (!(isSkipping && (isSkipping = skipped++ < resolvedBegin))) { + iterations++; + return fn(v, useKeys ? k : iterations - 1, this$0) !== false && + iterations !== sliceSize; + } + }); + return iterations; + }; + + sliceSeq.__iteratorUncached = function(type, reverse) { + if (sliceSize && reverse) { + return this.cacheResult().__iterator(type, reverse); + } + // Don't bother instantiating parent iterator if taking 0. + var iterator = sliceSize && iterable.__iterator(type, reverse); + var skipped = 0; + var iterations = 0; + return new Iterator(function() { + while (skipped++ !== resolvedBegin) { + iterator.next(); + } + if (++iterations > sliceSize) { + return iteratorDone(); + } + var step = iterator.next(); + if (useKeys || type === ITERATE_VALUES) { + return step; + } else if (type === ITERATE_KEYS) { + return iteratorValue(type, iterations - 1, undefined, step); + } else { + return iteratorValue(type, iterations - 1, step.value[1], step); + } + }); + } + + return sliceSeq; + } + + + function takeWhileFactory(iterable, predicate, context) { + var takeSequence = makeSequence(iterable); + takeSequence.__iterateUncached = function(fn, reverse) {var this$0 = this; + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + var iterations = 0; + iterable.__iterate(function(v, k, c) + {return predicate.call(context, v, k, c) && ++iterations && fn(v, k, this$0)} + ); + return iterations; + }; + takeSequence.__iteratorUncached = function(type, reverse) {var this$0 = this; + if (reverse) { + return this.cacheResult().__iterator(type, reverse); + } + var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); + var iterating = true; + return new Iterator(function() { + if (!iterating) { + return iteratorDone(); + } + var step = iterator.next(); + if (step.done) { + return step; + } + var entry = step.value; + var k = entry[0]; + var v = entry[1]; + if (!predicate.call(context, v, k, this$0)) { + iterating = false; + return iteratorDone(); + } + return type === ITERATE_ENTRIES ? step : + iteratorValue(type, k, v, step); + }); + }; + return takeSequence; + } + + + function skipWhileFactory(iterable, predicate, context, useKeys) { + var skipSequence = makeSequence(iterable); + skipSequence.__iterateUncached = function (fn, reverse) {var this$0 = this; + if (reverse) { + return this.cacheResult().__iterate(fn, reverse); + } + var isSkipping = true; + var iterations = 0; + iterable.__iterate(function(v, k, c) { + if (!(isSkipping && (isSkipping = predicate.call(context, v, k, c)))) { + iterations++; + return fn(v, useKeys ? k : iterations - 1, this$0); + } + }); + return iterations; + }; + skipSequence.__iteratorUncached = function(type, reverse) {var this$0 = this; + if (reverse) { + return this.cacheResult().__iterator(type, reverse); + } + var iterator = iterable.__iterator(ITERATE_ENTRIES, reverse); + var skipping = true; + var iterations = 0; + return new Iterator(function() { + var step, k, v; + do { + step = iterator.next(); + if (step.done) { + if (useKeys || type === ITERATE_VALUES) { + return step; + } else if (type === ITERATE_KEYS) { + return iteratorValue(type, iterations++, undefined, step); + } else { + return iteratorValue(type, iterations++, step.value[1], step); + } + } + var entry = step.value; + k = entry[0]; + v = entry[1]; + skipping && (skipping = predicate.call(context, v, k, this$0)); + } while (skipping); + return type === ITERATE_ENTRIES ? step : + iteratorValue(type, k, v, step); + }); + }; + return skipSequence; + } + + + function concatFactory(iterable, values) { + var isKeyedIterable = isKeyed(iterable); + var iters = [iterable].concat(values).map(function(v ) { + if (!isIterable(v)) { + v = isKeyedIterable ? + keyedSeqFromValue(v) : + indexedSeqFromValue(Array.isArray(v) ? v : [v]); + } else if (isKeyedIterable) { + v = KeyedIterable(v); + } + return v; + }).filter(function(v ) {return v.size !== 0}); + + if (iters.length === 0) { + return iterable; + } + + if (iters.length === 1) { + var singleton = iters[0]; + if (singleton === iterable || + isKeyedIterable && isKeyed(singleton) || + isIndexed(iterable) && isIndexed(singleton)) { + return singleton; + } + } + + var concatSeq = new ArraySeq(iters); + if (isKeyedIterable) { + concatSeq = concatSeq.toKeyedSeq(); + } else if (!isIndexed(iterable)) { + concatSeq = concatSeq.toSetSeq(); + } + concatSeq = concatSeq.flatten(true); + concatSeq.size = iters.reduce( + function(sum, seq) { + if (sum !== undefined) { + var size = seq.size; + if (size !== undefined) { + return sum + size; + } + } + }, + 0 + ); + return concatSeq; + } + + + function flattenFactory(iterable, depth, useKeys) { + var flatSequence = makeSequence(iterable); + flatSequence.__iterateUncached = function(fn, reverse) { + var iterations = 0; + var stopped = false; + function flatDeep(iter, currentDepth) {var this$0 = this; + iter.__iterate(function(v, k) { + if ((!depth || currentDepth < depth) && isIterable(v)) { + flatDeep(v, currentDepth + 1); + } else if (fn(v, useKeys ? k : iterations++, this$0) === false) { + stopped = true; + } + return !stopped; + }, reverse); + } + flatDeep(iterable, 0); + return iterations; + } + flatSequence.__iteratorUncached = function(type, reverse) { + var iterator = iterable.__iterator(type, reverse); + var stack = []; + var iterations = 0; + return new Iterator(function() { + while (iterator) { + var step = iterator.next(); + if (step.done !== false) { + iterator = stack.pop(); + continue; + } + var v = step.value; + if (type === ITERATE_ENTRIES) { + v = v[1]; + } + if ((!depth || stack.length < depth) && isIterable(v)) { + stack.push(iterator); + iterator = v.__iterator(type, reverse); + } else { + return useKeys ? step : iteratorValue(type, iterations++, v, step); + } + } + return iteratorDone(); + }); + } + return flatSequence; + } + + + function flatMapFactory(iterable, mapper, context) { + var coerce = iterableClass(iterable); + return iterable.toSeq().map( + function(v, k) {return coerce(mapper.call(context, v, k, iterable))} + ).flatten(true); + } + + + function interposeFactory(iterable, separator) { + var interposedSequence = makeSequence(iterable); + interposedSequence.size = iterable.size && iterable.size * 2 -1; + interposedSequence.__iterateUncached = function(fn, reverse) {var this$0 = this; + var iterations = 0; + iterable.__iterate(function(v, k) + {return (!iterations || fn(separator, iterations++, this$0) !== false) && + fn(v, iterations++, this$0) !== false}, + reverse + ); + return iterations; + }; + interposedSequence.__iteratorUncached = function(type, reverse) { + var iterator = iterable.__iterator(ITERATE_VALUES, reverse); + var iterations = 0; + var step; + return new Iterator(function() { + if (!step || iterations % 2) { + step = iterator.next(); + if (step.done) { + return step; + } + } + return iterations % 2 ? + iteratorValue(type, iterations++, separator) : + iteratorValue(type, iterations++, step.value, step); + }); + }; + return interposedSequence; + } + + + function sortFactory(iterable, comparator, mapper) { + if (!comparator) { + comparator = defaultComparator; + } + var isKeyedIterable = isKeyed(iterable); + var index = 0; + var entries = iterable.toSeq().map( + function(v, k) {return [k, v, index++, mapper ? mapper(v, k, iterable) : v]} + ).toArray(); + entries.sort(function(a, b) {return comparator(a[3], b[3]) || a[2] - b[2]}).forEach( + isKeyedIterable ? + function(v, i) { entries[i].length = 2; } : + function(v, i) { entries[i] = v[1]; } + ); + return isKeyedIterable ? KeyedSeq(entries) : + isIndexed(iterable) ? IndexedSeq(entries) : + SetSeq(entries); + } + + + function maxFactory(iterable, comparator, mapper) { + if (!comparator) { + comparator = defaultComparator; + } + if (mapper) { + var entry = iterable.toSeq() + .map(function(v, k) {return [v, mapper(v, k, iterable)]}) + .reduce(function(a, b) {return maxCompare(comparator, a[1], b[1]) ? b : a}); + return entry && entry[0]; + } else { + return iterable.reduce(function(a, b) {return maxCompare(comparator, a, b) ? b : a}); + } + } + + function maxCompare(comparator, a, b) { + var comp = comparator(b, a); + // b is considered the new max if the comparator declares them equal, but + // they are not equal and b is in fact a nullish value. + return (comp === 0 && b !== a && (b === undefined || b === null || b !== b)) || comp > 0; + } + + + function zipWithFactory(keyIter, zipper, iters) { + var zipSequence = makeSequence(keyIter); + zipSequence.size = new ArraySeq(iters).map(function(i ) {return i.size}).min(); + // Note: this a generic base implementation of __iterate in terms of + // __iterator which may be more generically useful in the future. + zipSequence.__iterate = function(fn, reverse) { + /* generic: + var iterator = this.__iterator(ITERATE_ENTRIES, reverse); + var step; + var iterations = 0; + while (!(step = iterator.next()).done) { + iterations++; + if (fn(step.value[1], step.value[0], this) === false) { + break; + } + } + return iterations; + */ + // indexed: + var iterator = this.__iterator(ITERATE_VALUES, reverse); + var step; + var iterations = 0; + while (!(step = iterator.next()).done) { + if (fn(step.value, iterations++, this) === false) { + break; + } + } + return iterations; + }; + zipSequence.__iteratorUncached = function(type, reverse) { + var iterators = iters.map(function(i ) + {return (i = Iterable(i), getIterator(reverse ? i.reverse() : i))} + ); + var iterations = 0; + var isDone = false; + return new Iterator(function() { + var steps; + if (!isDone) { + steps = iterators.map(function(i ) {return i.next()}); + isDone = steps.some(function(s ) {return s.done}); + } + if (isDone) { + return iteratorDone(); + } + return iteratorValue( + type, + iterations++, + zipper.apply(null, steps.map(function(s ) {return s.value})) + ); + }); + }; + return zipSequence + } + + + // #pragma Helper Functions + + function reify(iter, seq) { + return isSeq(iter) ? seq : iter.constructor(seq); + } + + function validateEntry(entry) { + if (entry !== Object(entry)) { + throw new TypeError('Expected [K, V] tuple: ' + entry); + } + } + + function resolveSize(iter) { + assertNotInfinite(iter.size); + return ensureSize(iter); + } + + function iterableClass(iterable) { + return isKeyed(iterable) ? KeyedIterable : + isIndexed(iterable) ? IndexedIterable : + SetIterable; + } + + function makeSequence(iterable) { + return Object.create( + ( + isKeyed(iterable) ? KeyedSeq : + isIndexed(iterable) ? IndexedSeq : + SetSeq + ).prototype + ); + } + + function cacheResultThrough() { + if (this._iter.cacheResult) { + this._iter.cacheResult(); + this.size = this._iter.size; + return this; + } else { + return Seq.prototype.cacheResult.call(this); + } + } + + function defaultComparator(a, b) { + return a > b ? 1 : a < b ? -1 : 0; + } + + function forceIterator(keyPath) { + var iter = getIterator(keyPath); + if (!iter) { + // Array might not be iterable in this environment, so we need a fallback + // to our wrapped type. + if (!isArrayLike(keyPath)) { + throw new TypeError('Expected iterable or array-like: ' + keyPath); + } + iter = getIterator(Iterable(keyPath)); + } + return iter; + } + + createClass(Map, KeyedCollection); + + // @pragma Construction + + function Map(value) { + return value === null || value === undefined ? emptyMap() : + isMap(value) ? value : + emptyMap().withMutations(function(map ) { + var iter = KeyedIterable(value); + assertNotInfinite(iter.size); + iter.forEach(function(v, k) {return map.set(k, v)}); + }); + } + + Map.prototype.toString = function() { + return this.__toString('Map {', '}'); + }; + + // @pragma Access + + Map.prototype.get = function(k, notSetValue) { + return this._root ? + this._root.get(0, undefined, k, notSetValue) : + notSetValue; + }; + + // @pragma Modification + + Map.prototype.set = function(k, v) { + return updateMap(this, k, v); + }; + + Map.prototype.setIn = function(keyPath, v) { + return this.updateIn(keyPath, NOT_SET, function() {return v}); + }; + + Map.prototype.remove = function(k) { + return updateMap(this, k, NOT_SET); + }; + + Map.prototype.deleteIn = function(keyPath) { + return this.updateIn(keyPath, function() {return NOT_SET}); + }; + + Map.prototype.update = function(k, notSetValue, updater) { + return arguments.length === 1 ? + k(this) : + this.updateIn([k], notSetValue, updater); + }; + + Map.prototype.updateIn = function(keyPath, notSetValue, updater) { + if (!updater) { + updater = notSetValue; + notSetValue = undefined; + } + var updatedValue = updateInDeepMap( + this, + forceIterator(keyPath), + notSetValue, + updater + ); + return updatedValue === NOT_SET ? undefined : updatedValue; + }; + + Map.prototype.clear = function() { + if (this.size === 0) { + return this; + } + if (this.__ownerID) { + this.size = 0; + this._root = null; + this.__hash = undefined; + this.__altered = true; + return this; + } + return emptyMap(); + }; + + // @pragma Composition + + Map.prototype.merge = function(/*...iters*/) { + return mergeIntoMapWith(this, undefined, arguments); + }; + + Map.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1); + return mergeIntoMapWith(this, merger, iters); + }; + + Map.prototype.mergeIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1); + return this.updateIn(keyPath, emptyMap(), function(m ) {return m.merge.apply(m, iters)}); + }; + + Map.prototype.mergeDeep = function(/*...iters*/) { + return mergeIntoMapWith(this, deepMerger(undefined), arguments); + }; + + Map.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1); + return mergeIntoMapWith(this, deepMerger(merger), iters); + }; + + Map.prototype.mergeDeepIn = function(keyPath) {var iters = SLICE$0.call(arguments, 1); + return this.updateIn(keyPath, emptyMap(), function(m ) {return m.mergeDeep.apply(m, iters)}); + }; + + Map.prototype.sort = function(comparator) { + // Late binding + return OrderedMap(sortFactory(this, comparator)); + }; + + Map.prototype.sortBy = function(mapper, comparator) { + // Late binding + return OrderedMap(sortFactory(this, comparator, mapper)); + }; + + // @pragma Mutability + + Map.prototype.withMutations = function(fn) { + var mutable = this.asMutable(); + fn(mutable); + return mutable.wasAltered() ? mutable.__ensureOwner(this.__ownerID) : this; + }; + + Map.prototype.asMutable = function() { + return this.__ownerID ? this : this.__ensureOwner(new OwnerID()); + }; + + Map.prototype.asImmutable = function() { + return this.__ensureOwner(); + }; + + Map.prototype.wasAltered = function() { + return this.__altered; + }; + + Map.prototype.__iterator = function(type, reverse) { + return new MapIterator(this, type, reverse); + }; + + Map.prototype.__iterate = function(fn, reverse) {var this$0 = this; + var iterations = 0; + this._root && this._root.iterate(function(entry ) { + iterations++; + return fn(entry[1], entry[0], this$0); + }, reverse); + return iterations; + }; + + Map.prototype.__ensureOwner = function(ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + if (!ownerID) { + this.__ownerID = ownerID; + this.__altered = false; + return this; + } + return makeMap(this.size, this._root, ownerID, this.__hash); + }; + + + function isMap(maybeMap) { + return !!(maybeMap && maybeMap[IS_MAP_SENTINEL]); + } + + Map.isMap = isMap; + + var IS_MAP_SENTINEL = '@@__IMMUTABLE_MAP__@@'; + + var MapPrototype = Map.prototype; + MapPrototype[IS_MAP_SENTINEL] = true; + MapPrototype[DELETE] = MapPrototype.remove; + MapPrototype.removeIn = MapPrototype.deleteIn; + + + // #pragma Trie Nodes + + + + function ArrayMapNode(ownerID, entries) { + this.ownerID = ownerID; + this.entries = entries; + } + + ArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) { + var entries = this.entries; + for (var ii = 0, len = entries.length; ii < len; ii++) { + if (is(key, entries[ii][0])) { + return entries[ii][1]; + } + } + return notSetValue; + }; + + ArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + var removed = value === NOT_SET; + + var entries = this.entries; + var idx = 0; + for (var len = entries.length; idx < len; idx++) { + if (is(key, entries[idx][0])) { + break; + } + } + var exists = idx < len; + + if (exists ? entries[idx][1] === value : removed) { + return this; + } + + SetRef(didAlter); + (removed || !exists) && SetRef(didChangeSize); + + if (removed && entries.length === 1) { + return; // undefined + } + + if (!exists && !removed && entries.length >= MAX_ARRAY_MAP_SIZE) { + return createNodes(ownerID, entries, key, value); + } + + var isEditable = ownerID && ownerID === this.ownerID; + var newEntries = isEditable ? entries : arrCopy(entries); + + if (exists) { + if (removed) { + idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop()); + } else { + newEntries[idx] = [key, value]; + } + } else { + newEntries.push([key, value]); + } + + if (isEditable) { + this.entries = newEntries; + return this; + } + + return new ArrayMapNode(ownerID, newEntries); + }; + + + + + function BitmapIndexedNode(ownerID, bitmap, nodes) { + this.ownerID = ownerID; + this.bitmap = bitmap; + this.nodes = nodes; + } + + BitmapIndexedNode.prototype.get = function(shift, keyHash, key, notSetValue) { + if (keyHash === undefined) { + keyHash = hash(key); + } + var bit = (1 << ((shift === 0 ? keyHash : keyHash >>> shift) & MASK)); + var bitmap = this.bitmap; + return (bitmap & bit) === 0 ? notSetValue : + this.nodes[popCount(bitmap & (bit - 1))].get(shift + SHIFT, keyHash, key, notSetValue); + }; + + BitmapIndexedNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + if (keyHash === undefined) { + keyHash = hash(key); + } + var keyHashFrag = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; + var bit = 1 << keyHashFrag; + var bitmap = this.bitmap; + var exists = (bitmap & bit) !== 0; + + if (!exists && value === NOT_SET) { + return this; + } + + var idx = popCount(bitmap & (bit - 1)); + var nodes = this.nodes; + var node = exists ? nodes[idx] : undefined; + var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter); + + if (newNode === node) { + return this; + } + + if (!exists && newNode && nodes.length >= MAX_BITMAP_INDEXED_SIZE) { + return expandNodes(ownerID, nodes, bitmap, keyHashFrag, newNode); + } + + if (exists && !newNode && nodes.length === 2 && isLeafNode(nodes[idx ^ 1])) { + return nodes[idx ^ 1]; + } + + if (exists && newNode && nodes.length === 1 && isLeafNode(newNode)) { + return newNode; + } + + var isEditable = ownerID && ownerID === this.ownerID; + var newBitmap = exists ? newNode ? bitmap : bitmap ^ bit : bitmap | bit; + var newNodes = exists ? newNode ? + setIn(nodes, idx, newNode, isEditable) : + spliceOut(nodes, idx, isEditable) : + spliceIn(nodes, idx, newNode, isEditable); + + if (isEditable) { + this.bitmap = newBitmap; + this.nodes = newNodes; + return this; + } + + return new BitmapIndexedNode(ownerID, newBitmap, newNodes); + }; + + + + + function HashArrayMapNode(ownerID, count, nodes) { + this.ownerID = ownerID; + this.count = count; + this.nodes = nodes; + } + + HashArrayMapNode.prototype.get = function(shift, keyHash, key, notSetValue) { + if (keyHash === undefined) { + keyHash = hash(key); + } + var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; + var node = this.nodes[idx]; + return node ? node.get(shift + SHIFT, keyHash, key, notSetValue) : notSetValue; + }; + + HashArrayMapNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + if (keyHash === undefined) { + keyHash = hash(key); + } + var idx = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; + var removed = value === NOT_SET; + var nodes = this.nodes; + var node = nodes[idx]; + + if (removed && !node) { + return this; + } + + var newNode = updateNode(node, ownerID, shift + SHIFT, keyHash, key, value, didChangeSize, didAlter); + if (newNode === node) { + return this; + } + + var newCount = this.count; + if (!node) { + newCount++; + } else if (!newNode) { + newCount--; + if (newCount < MIN_HASH_ARRAY_MAP_SIZE) { + return packNodes(ownerID, nodes, newCount, idx); + } + } + + var isEditable = ownerID && ownerID === this.ownerID; + var newNodes = setIn(nodes, idx, newNode, isEditable); + + if (isEditable) { + this.count = newCount; + this.nodes = newNodes; + return this; + } + + return new HashArrayMapNode(ownerID, newCount, newNodes); + }; + + + + + function HashCollisionNode(ownerID, keyHash, entries) { + this.ownerID = ownerID; + this.keyHash = keyHash; + this.entries = entries; + } + + HashCollisionNode.prototype.get = function(shift, keyHash, key, notSetValue) { + var entries = this.entries; + for (var ii = 0, len = entries.length; ii < len; ii++) { + if (is(key, entries[ii][0])) { + return entries[ii][1]; + } + } + return notSetValue; + }; + + HashCollisionNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + if (keyHash === undefined) { + keyHash = hash(key); + } + + var removed = value === NOT_SET; + + if (keyHash !== this.keyHash) { + if (removed) { + return this; + } + SetRef(didAlter); + SetRef(didChangeSize); + return mergeIntoNode(this, ownerID, shift, keyHash, [key, value]); + } + + var entries = this.entries; + var idx = 0; + for (var len = entries.length; idx < len; idx++) { + if (is(key, entries[idx][0])) { + break; + } + } + var exists = idx < len; + + if (exists ? entries[idx][1] === value : removed) { + return this; + } + + SetRef(didAlter); + (removed || !exists) && SetRef(didChangeSize); + + if (removed && len === 2) { + return new ValueNode(ownerID, this.keyHash, entries[idx ^ 1]); + } + + var isEditable = ownerID && ownerID === this.ownerID; + var newEntries = isEditable ? entries : arrCopy(entries); + + if (exists) { + if (removed) { + idx === len - 1 ? newEntries.pop() : (newEntries[idx] = newEntries.pop()); + } else { + newEntries[idx] = [key, value]; + } + } else { + newEntries.push([key, value]); + } + + if (isEditable) { + this.entries = newEntries; + return this; + } + + return new HashCollisionNode(ownerID, this.keyHash, newEntries); + }; + + + + + function ValueNode(ownerID, keyHash, entry) { + this.ownerID = ownerID; + this.keyHash = keyHash; + this.entry = entry; + } + + ValueNode.prototype.get = function(shift, keyHash, key, notSetValue) { + return is(key, this.entry[0]) ? this.entry[1] : notSetValue; + }; + + ValueNode.prototype.update = function(ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + var removed = value === NOT_SET; + var keyMatch = is(key, this.entry[0]); + if (keyMatch ? value === this.entry[1] : removed) { + return this; + } + + SetRef(didAlter); + + if (removed) { + SetRef(didChangeSize); + return; // undefined + } + + if (keyMatch) { + if (ownerID && ownerID === this.ownerID) { + this.entry[1] = value; + return this; + } + return new ValueNode(ownerID, this.keyHash, [key, value]); + } + + SetRef(didChangeSize); + return mergeIntoNode(this, ownerID, shift, hash(key), [key, value]); + }; + + + + // #pragma Iterators + + ArrayMapNode.prototype.iterate = + HashCollisionNode.prototype.iterate = function (fn, reverse) { + var entries = this.entries; + for (var ii = 0, maxIndex = entries.length - 1; ii <= maxIndex; ii++) { + if (fn(entries[reverse ? maxIndex - ii : ii]) === false) { + return false; + } + } + } + + BitmapIndexedNode.prototype.iterate = + HashArrayMapNode.prototype.iterate = function (fn, reverse) { + var nodes = this.nodes; + for (var ii = 0, maxIndex = nodes.length - 1; ii <= maxIndex; ii++) { + var node = nodes[reverse ? maxIndex - ii : ii]; + if (node && node.iterate(fn, reverse) === false) { + return false; + } + } + } + + ValueNode.prototype.iterate = function (fn, reverse) { + return fn(this.entry); + } + + createClass(MapIterator, Iterator); + + function MapIterator(map, type, reverse) { + this._type = type; + this._reverse = reverse; + this._stack = map._root && mapIteratorFrame(map._root); + } + + MapIterator.prototype.next = function() { + var type = this._type; + var stack = this._stack; + while (stack) { + var node = stack.node; + var index = stack.index++; + var maxIndex; + if (node.entry) { + if (index === 0) { + return mapIteratorValue(type, node.entry); + } + } else if (node.entries) { + maxIndex = node.entries.length - 1; + if (index <= maxIndex) { + return mapIteratorValue(type, node.entries[this._reverse ? maxIndex - index : index]); + } + } else { + maxIndex = node.nodes.length - 1; + if (index <= maxIndex) { + var subNode = node.nodes[this._reverse ? maxIndex - index : index]; + if (subNode) { + if (subNode.entry) { + return mapIteratorValue(type, subNode.entry); + } + stack = this._stack = mapIteratorFrame(subNode, stack); + } + continue; + } + } + stack = this._stack = this._stack.__prev; + } + return iteratorDone(); + }; + + + function mapIteratorValue(type, entry) { + return iteratorValue(type, entry[0], entry[1]); + } + + function mapIteratorFrame(node, prev) { + return { + node: node, + index: 0, + __prev: prev + }; + } + + function makeMap(size, root, ownerID, hash) { + var map = Object.create(MapPrototype); + map.size = size; + map._root = root; + map.__ownerID = ownerID; + map.__hash = hash; + map.__altered = false; + return map; + } + + var EMPTY_MAP; + function emptyMap() { + return EMPTY_MAP || (EMPTY_MAP = makeMap(0)); + } + + function updateMap(map, k, v) { + var newRoot; + var newSize; + if (!map._root) { + if (v === NOT_SET) { + return map; + } + newSize = 1; + newRoot = new ArrayMapNode(map.__ownerID, [[k, v]]); + } else { + var didChangeSize = MakeRef(CHANGE_LENGTH); + var didAlter = MakeRef(DID_ALTER); + newRoot = updateNode(map._root, map.__ownerID, 0, undefined, k, v, didChangeSize, didAlter); + if (!didAlter.value) { + return map; + } + newSize = map.size + (didChangeSize.value ? v === NOT_SET ? -1 : 1 : 0); + } + if (map.__ownerID) { + map.size = newSize; + map._root = newRoot; + map.__hash = undefined; + map.__altered = true; + return map; + } + return newRoot ? makeMap(newSize, newRoot) : emptyMap(); + } + + function updateNode(node, ownerID, shift, keyHash, key, value, didChangeSize, didAlter) { + if (!node) { + if (value === NOT_SET) { + return node; + } + SetRef(didAlter); + SetRef(didChangeSize); + return new ValueNode(ownerID, keyHash, [key, value]); + } + return node.update(ownerID, shift, keyHash, key, value, didChangeSize, didAlter); + } + + function isLeafNode(node) { + return node.constructor === ValueNode || node.constructor === HashCollisionNode; + } + + function mergeIntoNode(node, ownerID, shift, keyHash, entry) { + if (node.keyHash === keyHash) { + return new HashCollisionNode(ownerID, keyHash, [node.entry, entry]); + } + + var idx1 = (shift === 0 ? node.keyHash : node.keyHash >>> shift) & MASK; + var idx2 = (shift === 0 ? keyHash : keyHash >>> shift) & MASK; + + var newNode; + var nodes = idx1 === idx2 ? + [mergeIntoNode(node, ownerID, shift + SHIFT, keyHash, entry)] : + ((newNode = new ValueNode(ownerID, keyHash, entry)), idx1 < idx2 ? [node, newNode] : [newNode, node]); + + return new BitmapIndexedNode(ownerID, (1 << idx1) | (1 << idx2), nodes); + } + + function createNodes(ownerID, entries, key, value) { + if (!ownerID) { + ownerID = new OwnerID(); + } + var node = new ValueNode(ownerID, hash(key), [key, value]); + for (var ii = 0; ii < entries.length; ii++) { + var entry = entries[ii]; + node = node.update(ownerID, 0, undefined, entry[0], entry[1]); + } + return node; + } + + function packNodes(ownerID, nodes, count, excluding) { + var bitmap = 0; + var packedII = 0; + var packedNodes = new Array(count); + for (var ii = 0, bit = 1, len = nodes.length; ii < len; ii++, bit <<= 1) { + var node = nodes[ii]; + if (node !== undefined && ii !== excluding) { + bitmap |= bit; + packedNodes[packedII++] = node; + } + } + return new BitmapIndexedNode(ownerID, bitmap, packedNodes); + } + + function expandNodes(ownerID, nodes, bitmap, including, node) { + var count = 0; + var expandedNodes = new Array(SIZE); + for (var ii = 0; bitmap !== 0; ii++, bitmap >>>= 1) { + expandedNodes[ii] = bitmap & 1 ? nodes[count++] : undefined; + } + expandedNodes[including] = node; + return new HashArrayMapNode(ownerID, count + 1, expandedNodes); + } + + function mergeIntoMapWith(map, merger, iterables) { + var iters = []; + for (var ii = 0; ii < iterables.length; ii++) { + var value = iterables[ii]; + var iter = KeyedIterable(value); + if (!isIterable(value)) { + iter = iter.map(function(v ) {return fromJS(v)}); + } + iters.push(iter); + } + return mergeIntoCollectionWith(map, merger, iters); + } + + function deepMerger(merger) { + return function(existing, value) + {return existing && existing.mergeDeepWith && isIterable(value) ? + existing.mergeDeepWith(merger, value) : + merger ? merger(existing, value) : value}; + } + + function mergeIntoCollectionWith(collection, merger, iters) { + iters = iters.filter(function(x ) {return x.size !== 0}); + if (iters.length === 0) { + return collection; + } + if (collection.size === 0 && iters.length === 1) { + return collection.constructor(iters[0]); + } + return collection.withMutations(function(collection ) { + var mergeIntoMap = merger ? + function(value, key) { + collection.update(key, NOT_SET, function(existing ) + {return existing === NOT_SET ? value : merger(existing, value)} + ); + } : + function(value, key) { + collection.set(key, value); + } + for (var ii = 0; ii < iters.length; ii++) { + iters[ii].forEach(mergeIntoMap); + } + }); + } + + function updateInDeepMap(existing, keyPathIter, notSetValue, updater) { + var isNotSet = existing === NOT_SET; + var step = keyPathIter.next(); + if (step.done) { + var existingValue = isNotSet ? notSetValue : existing; + var newValue = updater(existingValue); + return newValue === existingValue ? existing : newValue; + } + invariant( + isNotSet || (existing && existing.set), + 'invalid keyPath' + ); + var key = step.value; + var nextExisting = isNotSet ? NOT_SET : existing.get(key, NOT_SET); + var nextUpdated = updateInDeepMap( + nextExisting, + keyPathIter, + notSetValue, + updater + ); + return nextUpdated === nextExisting ? existing : + nextUpdated === NOT_SET ? existing.remove(key) : + (isNotSet ? emptyMap() : existing).set(key, nextUpdated); + } + + function popCount(x) { + x = x - ((x >> 1) & 0x55555555); + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0f0f0f0f; + x = x + (x >> 8); + x = x + (x >> 16); + return x & 0x7f; + } + + function setIn(array, idx, val, canEdit) { + var newArray = canEdit ? array : arrCopy(array); + newArray[idx] = val; + return newArray; + } + + function spliceIn(array, idx, val, canEdit) { + var newLen = array.length + 1; + if (canEdit && idx + 1 === newLen) { + array[idx] = val; + return array; + } + var newArray = new Array(newLen); + var after = 0; + for (var ii = 0; ii < newLen; ii++) { + if (ii === idx) { + newArray[ii] = val; + after = -1; + } else { + newArray[ii] = array[ii + after]; + } + } + return newArray; + } + + function spliceOut(array, idx, canEdit) { + var newLen = array.length - 1; + if (canEdit && idx === newLen) { + array.pop(); + return array; + } + var newArray = new Array(newLen); + var after = 0; + for (var ii = 0; ii < newLen; ii++) { + if (ii === idx) { + after = 1; + } + newArray[ii] = array[ii + after]; + } + return newArray; + } + + var MAX_ARRAY_MAP_SIZE = SIZE / 4; + var MAX_BITMAP_INDEXED_SIZE = SIZE / 2; + var MIN_HASH_ARRAY_MAP_SIZE = SIZE / 4; + + createClass(List, IndexedCollection); + + // @pragma Construction + + function List(value) { + var empty = emptyList(); + if (value === null || value === undefined) { + return empty; + } + if (isList(value)) { + return value; + } + var iter = IndexedIterable(value); + var size = iter.size; + if (size === 0) { + return empty; + } + assertNotInfinite(size); + if (size > 0 && size < SIZE) { + return makeList(0, size, SHIFT, null, new VNode(iter.toArray())); + } + return empty.withMutations(function(list ) { + list.setSize(size); + iter.forEach(function(v, i) {return list.set(i, v)}); + }); + } + + List.of = function(/*...values*/) { + return this(arguments); + }; + + List.prototype.toString = function() { + return this.__toString('List [', ']'); + }; + + // @pragma Access + + List.prototype.get = function(index, notSetValue) { + index = wrapIndex(this, index); + if (index < 0 || index >= this.size) { + return notSetValue; + } + index += this._origin; + var node = listNodeFor(this, index); + return node && node.array[index & MASK]; + }; + + // @pragma Modification + + List.prototype.set = function(index, value) { + return updateList(this, index, value); + }; + + List.prototype.remove = function(index) { + return !this.has(index) ? this : + index === 0 ? this.shift() : + index === this.size - 1 ? this.pop() : + this.splice(index, 1); + }; + + List.prototype.clear = function() { + if (this.size === 0) { + return this; + } + if (this.__ownerID) { + this.size = this._origin = this._capacity = 0; + this._level = SHIFT; + this._root = this._tail = null; + this.__hash = undefined; + this.__altered = true; + return this; + } + return emptyList(); + }; + + List.prototype.push = function(/*...values*/) { + var values = arguments; + var oldSize = this.size; + return this.withMutations(function(list ) { + setListBounds(list, 0, oldSize + values.length); + for (var ii = 0; ii < values.length; ii++) { + list.set(oldSize + ii, values[ii]); + } + }); + }; + + List.prototype.pop = function() { + return setListBounds(this, 0, -1); + }; + + List.prototype.unshift = function(/*...values*/) { + var values = arguments; + return this.withMutations(function(list ) { + setListBounds(list, -values.length); + for (var ii = 0; ii < values.length; ii++) { + list.set(ii, values[ii]); + } + }); + }; + + List.prototype.shift = function() { + return setListBounds(this, 1); + }; + + // @pragma Composition + + List.prototype.merge = function(/*...iters*/) { + return mergeIntoListWith(this, undefined, arguments); + }; + + List.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1); + return mergeIntoListWith(this, merger, iters); + }; + + List.prototype.mergeDeep = function(/*...iters*/) { + return mergeIntoListWith(this, deepMerger(undefined), arguments); + }; + + List.prototype.mergeDeepWith = function(merger) {var iters = SLICE$0.call(arguments, 1); + return mergeIntoListWith(this, deepMerger(merger), iters); + }; + + List.prototype.setSize = function(size) { + return setListBounds(this, 0, size); + }; + + // @pragma Iteration + + List.prototype.slice = function(begin, end) { + var size = this.size; + if (wholeSlice(begin, end, size)) { + return this; + } + return setListBounds( + this, + resolveBegin(begin, size), + resolveEnd(end, size) + ); + }; + + List.prototype.__iterator = function(type, reverse) { + var index = 0; + var values = iterateList(this, reverse); + return new Iterator(function() { + var value = values(); + return value === DONE ? + iteratorDone() : + iteratorValue(type, index++, value); + }); + }; + + List.prototype.__iterate = function(fn, reverse) { + var index = 0; + var values = iterateList(this, reverse); + var value; + while ((value = values()) !== DONE) { + if (fn(value, index++, this) === false) { + break; + } + } + return index; + }; + + List.prototype.__ensureOwner = function(ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + if (!ownerID) { + this.__ownerID = ownerID; + return this; + } + return makeList(this._origin, this._capacity, this._level, this._root, this._tail, ownerID, this.__hash); + }; + + + function isList(maybeList) { + return !!(maybeList && maybeList[IS_LIST_SENTINEL]); + } + + List.isList = isList; + + var IS_LIST_SENTINEL = '@@__IMMUTABLE_LIST__@@'; + + var ListPrototype = List.prototype; + ListPrototype[IS_LIST_SENTINEL] = true; + ListPrototype[DELETE] = ListPrototype.remove; + ListPrototype.setIn = MapPrototype.setIn; + ListPrototype.deleteIn = + ListPrototype.removeIn = MapPrototype.removeIn; + ListPrototype.update = MapPrototype.update; + ListPrototype.updateIn = MapPrototype.updateIn; + ListPrototype.mergeIn = MapPrototype.mergeIn; + ListPrototype.mergeDeepIn = MapPrototype.mergeDeepIn; + ListPrototype.withMutations = MapPrototype.withMutations; + ListPrototype.asMutable = MapPrototype.asMutable; + ListPrototype.asImmutable = MapPrototype.asImmutable; + ListPrototype.wasAltered = MapPrototype.wasAltered; + + + + function VNode(array, ownerID) { + this.array = array; + this.ownerID = ownerID; + } + + // TODO: seems like these methods are very similar + + VNode.prototype.removeBefore = function(ownerID, level, index) { + if (index === level ? 1 << level : 0 || this.array.length === 0) { + return this; + } + var originIndex = (index >>> level) & MASK; + if (originIndex >= this.array.length) { + return new VNode([], ownerID); + } + var removingFirst = originIndex === 0; + var newChild; + if (level > 0) { + var oldChild = this.array[originIndex]; + newChild = oldChild && oldChild.removeBefore(ownerID, level - SHIFT, index); + if (newChild === oldChild && removingFirst) { + return this; + } + } + if (removingFirst && !newChild) { + return this; + } + var editable = editableVNode(this, ownerID); + if (!removingFirst) { + for (var ii = 0; ii < originIndex; ii++) { + editable.array[ii] = undefined; + } + } + if (newChild) { + editable.array[originIndex] = newChild; + } + return editable; + }; + + VNode.prototype.removeAfter = function(ownerID, level, index) { + if (index === level ? 1 << level : 0 || this.array.length === 0) { + return this; + } + var sizeIndex = ((index - 1) >>> level) & MASK; + if (sizeIndex >= this.array.length) { + return this; + } + var removingLast = sizeIndex === this.array.length - 1; + var newChild; + if (level > 0) { + var oldChild = this.array[sizeIndex]; + newChild = oldChild && oldChild.removeAfter(ownerID, level - SHIFT, index); + if (newChild === oldChild && removingLast) { + return this; + } + } + if (removingLast && !newChild) { + return this; + } + var editable = editableVNode(this, ownerID); + if (!removingLast) { + editable.array.pop(); + } + if (newChild) { + editable.array[sizeIndex] = newChild; + } + return editable; + }; + + + + var DONE = {}; + + function iterateList(list, reverse) { + var left = list._origin; + var right = list._capacity; + var tailPos = getTailOffset(right); + var tail = list._tail; + + return iterateNodeOrLeaf(list._root, list._level, 0); + + function iterateNodeOrLeaf(node, level, offset) { + return level === 0 ? + iterateLeaf(node, offset) : + iterateNode(node, level, offset); + } + + function iterateLeaf(node, offset) { + var array = offset === tailPos ? tail && tail.array : node && node.array; + var from = offset > left ? 0 : left - offset; + var to = right - offset; + if (to > SIZE) { + to = SIZE; + } + return function() { + if (from === to) { + return DONE; + } + var idx = reverse ? --to : from++; + return array && array[idx]; + }; + } + + function iterateNode(node, level, offset) { + var values; + var array = node && node.array; + var from = offset > left ? 0 : (left - offset) >> level; + var to = ((right - offset) >> level) + 1; + if (to > SIZE) { + to = SIZE; + } + return function() { + do { + if (values) { + var value = values(); + if (value !== DONE) { + return value; + } + values = null; + } + if (from === to) { + return DONE; + } + var idx = reverse ? --to : from++; + values = iterateNodeOrLeaf( + array && array[idx], level - SHIFT, offset + (idx << level) + ); + } while (true); + }; + } + } + + function makeList(origin, capacity, level, root, tail, ownerID, hash) { + var list = Object.create(ListPrototype); + list.size = capacity - origin; + list._origin = origin; + list._capacity = capacity; + list._level = level; + list._root = root; + list._tail = tail; + list.__ownerID = ownerID; + list.__hash = hash; + list.__altered = false; + return list; + } + + var EMPTY_LIST; + function emptyList() { + return EMPTY_LIST || (EMPTY_LIST = makeList(0, 0, SHIFT)); + } + + function updateList(list, index, value) { + index = wrapIndex(list, index); + + if (index >= list.size || index < 0) { + return list.withMutations(function(list ) { + index < 0 ? + setListBounds(list, index).set(0, value) : + setListBounds(list, 0, index + 1).set(index, value) + }); + } + + index += list._origin; + + var newTail = list._tail; + var newRoot = list._root; + var didAlter = MakeRef(DID_ALTER); + if (index >= getTailOffset(list._capacity)) { + newTail = updateVNode(newTail, list.__ownerID, 0, index, value, didAlter); + } else { + newRoot = updateVNode(newRoot, list.__ownerID, list._level, index, value, didAlter); + } + + if (!didAlter.value) { + return list; + } + + if (list.__ownerID) { + list._root = newRoot; + list._tail = newTail; + list.__hash = undefined; + list.__altered = true; + return list; + } + return makeList(list._origin, list._capacity, list._level, newRoot, newTail); + } + + function updateVNode(node, ownerID, level, index, value, didAlter) { + var idx = (index >>> level) & MASK; + var nodeHas = node && idx < node.array.length; + if (!nodeHas && value === undefined) { + return node; + } + + var newNode; + + if (level > 0) { + var lowerNode = node && node.array[idx]; + var newLowerNode = updateVNode(lowerNode, ownerID, level - SHIFT, index, value, didAlter); + if (newLowerNode === lowerNode) { + return node; + } + newNode = editableVNode(node, ownerID); + newNode.array[idx] = newLowerNode; + return newNode; + } + + if (nodeHas && node.array[idx] === value) { + return node; + } + + SetRef(didAlter); + + newNode = editableVNode(node, ownerID); + if (value === undefined && idx === newNode.array.length - 1) { + newNode.array.pop(); + } else { + newNode.array[idx] = value; + } + return newNode; + } + + function editableVNode(node, ownerID) { + if (ownerID && node && ownerID === node.ownerID) { + return node; + } + return new VNode(node ? node.array.slice() : [], ownerID); + } + + function listNodeFor(list, rawIndex) { + if (rawIndex >= getTailOffset(list._capacity)) { + return list._tail; + } + if (rawIndex < 1 << (list._level + SHIFT)) { + var node = list._root; + var level = list._level; + while (node && level > 0) { + node = node.array[(rawIndex >>> level) & MASK]; + level -= SHIFT; + } + return node; + } + } + + function setListBounds(list, begin, end) { + var owner = list.__ownerID || new OwnerID(); + var oldOrigin = list._origin; + var oldCapacity = list._capacity; + var newOrigin = oldOrigin + begin; + var newCapacity = end === undefined ? oldCapacity : end < 0 ? oldCapacity + end : oldOrigin + end; + if (newOrigin === oldOrigin && newCapacity === oldCapacity) { + return list; + } + + // If it's going to end after it starts, it's empty. + if (newOrigin >= newCapacity) { + return list.clear(); + } + + var newLevel = list._level; + var newRoot = list._root; + + // New origin might require creating a higher root. + var offsetShift = 0; + while (newOrigin + offsetShift < 0) { + newRoot = new VNode(newRoot && newRoot.array.length ? [undefined, newRoot] : [], owner); + newLevel += SHIFT; + offsetShift += 1 << newLevel; + } + if (offsetShift) { + newOrigin += offsetShift; + oldOrigin += offsetShift; + newCapacity += offsetShift; + oldCapacity += offsetShift; + } + + var oldTailOffset = getTailOffset(oldCapacity); + var newTailOffset = getTailOffset(newCapacity); + + // New size might require creating a higher root. + while (newTailOffset >= 1 << (newLevel + SHIFT)) { + newRoot = new VNode(newRoot && newRoot.array.length ? [newRoot] : [], owner); + newLevel += SHIFT; + } + + // Locate or create the new tail. + var oldTail = list._tail; + var newTail = newTailOffset < oldTailOffset ? + listNodeFor(list, newCapacity - 1) : + newTailOffset > oldTailOffset ? new VNode([], owner) : oldTail; + + // Merge Tail into tree. + if (oldTail && newTailOffset > oldTailOffset && newOrigin < oldCapacity && oldTail.array.length) { + newRoot = editableVNode(newRoot, owner); + var node = newRoot; + for (var level = newLevel; level > SHIFT; level -= SHIFT) { + var idx = (oldTailOffset >>> level) & MASK; + node = node.array[idx] = editableVNode(node.array[idx], owner); + } + node.array[(oldTailOffset >>> SHIFT) & MASK] = oldTail; + } + + // If the size has been reduced, there's a chance the tail needs to be trimmed. + if (newCapacity < oldCapacity) { + newTail = newTail && newTail.removeAfter(owner, 0, newCapacity); + } + + // If the new origin is within the tail, then we do not need a root. + if (newOrigin >= newTailOffset) { + newOrigin -= newTailOffset; + newCapacity -= newTailOffset; + newLevel = SHIFT; + newRoot = null; + newTail = newTail && newTail.removeBefore(owner, 0, newOrigin); + + // Otherwise, if the root has been trimmed, garbage collect. + } else if (newOrigin > oldOrigin || newTailOffset < oldTailOffset) { + offsetShift = 0; + + // Identify the new top root node of the subtree of the old root. + while (newRoot) { + var beginIndex = (newOrigin >>> newLevel) & MASK; + if (beginIndex !== (newTailOffset >>> newLevel) & MASK) { + break; + } + if (beginIndex) { + offsetShift += (1 << newLevel) * beginIndex; + } + newLevel -= SHIFT; + newRoot = newRoot.array[beginIndex]; + } + + // Trim the new sides of the new root. + if (newRoot && newOrigin > oldOrigin) { + newRoot = newRoot.removeBefore(owner, newLevel, newOrigin - offsetShift); + } + if (newRoot && newTailOffset < oldTailOffset) { + newRoot = newRoot.removeAfter(owner, newLevel, newTailOffset - offsetShift); + } + if (offsetShift) { + newOrigin -= offsetShift; + newCapacity -= offsetShift; + } + } + + if (list.__ownerID) { + list.size = newCapacity - newOrigin; + list._origin = newOrigin; + list._capacity = newCapacity; + list._level = newLevel; + list._root = newRoot; + list._tail = newTail; + list.__hash = undefined; + list.__altered = true; + return list; + } + return makeList(newOrigin, newCapacity, newLevel, newRoot, newTail); + } + + function mergeIntoListWith(list, merger, iterables) { + var iters = []; + var maxSize = 0; + for (var ii = 0; ii < iterables.length; ii++) { + var value = iterables[ii]; + var iter = IndexedIterable(value); + if (iter.size > maxSize) { + maxSize = iter.size; + } + if (!isIterable(value)) { + iter = iter.map(function(v ) {return fromJS(v)}); + } + iters.push(iter); + } + if (maxSize > list.size) { + list = list.setSize(maxSize); + } + return mergeIntoCollectionWith(list, merger, iters); + } + + function getTailOffset(size) { + return size < SIZE ? 0 : (((size - 1) >>> SHIFT) << SHIFT); + } + + createClass(OrderedMap, Map); + + // @pragma Construction + + function OrderedMap(value) { + return value === null || value === undefined ? emptyOrderedMap() : + isOrderedMap(value) ? value : + emptyOrderedMap().withMutations(function(map ) { + var iter = KeyedIterable(value); + assertNotInfinite(iter.size); + iter.forEach(function(v, k) {return map.set(k, v)}); + }); + } + + OrderedMap.of = function(/*...values*/) { + return this(arguments); + }; + + OrderedMap.prototype.toString = function() { + return this.__toString('OrderedMap {', '}'); + }; + + // @pragma Access + + OrderedMap.prototype.get = function(k, notSetValue) { + var index = this._map.get(k); + return index !== undefined ? this._list.get(index)[1] : notSetValue; + }; + + // @pragma Modification + + OrderedMap.prototype.clear = function() { + if (this.size === 0) { + return this; + } + if (this.__ownerID) { + this.size = 0; + this._map.clear(); + this._list.clear(); + return this; + } + return emptyOrderedMap(); + }; + + OrderedMap.prototype.set = function(k, v) { + return updateOrderedMap(this, k, v); + }; + + OrderedMap.prototype.remove = function(k) { + return updateOrderedMap(this, k, NOT_SET); + }; + + OrderedMap.prototype.wasAltered = function() { + return this._map.wasAltered() || this._list.wasAltered(); + }; + + OrderedMap.prototype.__iterate = function(fn, reverse) {var this$0 = this; + return this._list.__iterate( + function(entry ) {return entry && fn(entry[1], entry[0], this$0)}, + reverse + ); + }; + + OrderedMap.prototype.__iterator = function(type, reverse) { + return this._list.fromEntrySeq().__iterator(type, reverse); + }; + + OrderedMap.prototype.__ensureOwner = function(ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + var newMap = this._map.__ensureOwner(ownerID); + var newList = this._list.__ensureOwner(ownerID); + if (!ownerID) { + this.__ownerID = ownerID; + this._map = newMap; + this._list = newList; + return this; + } + return makeOrderedMap(newMap, newList, ownerID, this.__hash); + }; + + + function isOrderedMap(maybeOrderedMap) { + return isMap(maybeOrderedMap) && isOrdered(maybeOrderedMap); + } + + OrderedMap.isOrderedMap = isOrderedMap; + + OrderedMap.prototype[IS_ORDERED_SENTINEL] = true; + OrderedMap.prototype[DELETE] = OrderedMap.prototype.remove; + + + + function makeOrderedMap(map, list, ownerID, hash) { + var omap = Object.create(OrderedMap.prototype); + omap.size = map ? map.size : 0; + omap._map = map; + omap._list = list; + omap.__ownerID = ownerID; + omap.__hash = hash; + return omap; + } + + var EMPTY_ORDERED_MAP; + function emptyOrderedMap() { + return EMPTY_ORDERED_MAP || (EMPTY_ORDERED_MAP = makeOrderedMap(emptyMap(), emptyList())); + } + + function updateOrderedMap(omap, k, v) { + var map = omap._map; + var list = omap._list; + var i = map.get(k); + var has = i !== undefined; + var newMap; + var newList; + if (v === NOT_SET) { // removed + if (!has) { + return omap; + } + if (list.size >= SIZE && list.size >= map.size * 2) { + newList = list.filter(function(entry, idx) {return entry !== undefined && i !== idx}); + newMap = newList.toKeyedSeq().map(function(entry ) {return entry[0]}).flip().toMap(); + if (omap.__ownerID) { + newMap.__ownerID = newList.__ownerID = omap.__ownerID; + } + } else { + newMap = map.remove(k); + newList = i === list.size - 1 ? list.pop() : list.set(i, undefined); + } + } else { + if (has) { + if (v === list.get(i)[1]) { + return omap; + } + newMap = map; + newList = list.set(i, [k, v]); + } else { + newMap = map.set(k, list.size); + newList = list.set(list.size, [k, v]); + } + } + if (omap.__ownerID) { + omap.size = newMap.size; + omap._map = newMap; + omap._list = newList; + omap.__hash = undefined; + return omap; + } + return makeOrderedMap(newMap, newList); + } + + createClass(Stack, IndexedCollection); + + // @pragma Construction + + function Stack(value) { + return value === null || value === undefined ? emptyStack() : + isStack(value) ? value : + emptyStack().unshiftAll(value); + } + + Stack.of = function(/*...values*/) { + return this(arguments); + }; + + Stack.prototype.toString = function() { + return this.__toString('Stack [', ']'); + }; + + // @pragma Access + + Stack.prototype.get = function(index, notSetValue) { + var head = this._head; + while (head && index--) { + head = head.next; + } + return head ? head.value : notSetValue; + }; + + Stack.prototype.peek = function() { + return this._head && this._head.value; + }; + + // @pragma Modification + + Stack.prototype.push = function(/*...values*/) { + if (arguments.length === 0) { + return this; + } + var newSize = this.size + arguments.length; + var head = this._head; + for (var ii = arguments.length - 1; ii >= 0; ii--) { + head = { + value: arguments[ii], + next: head + }; + } + if (this.__ownerID) { + this.size = newSize; + this._head = head; + this.__hash = undefined; + this.__altered = true; + return this; + } + return makeStack(newSize, head); + }; + + Stack.prototype.pushAll = function(iter) { + iter = IndexedIterable(iter); + if (iter.size === 0) { + return this; + } + assertNotInfinite(iter.size); + var newSize = this.size; + var head = this._head; + iter.reverse().forEach(function(value ) { + newSize++; + head = { + value: value, + next: head + }; + }); + if (this.__ownerID) { + this.size = newSize; + this._head = head; + this.__hash = undefined; + this.__altered = true; + return this; + } + return makeStack(newSize, head); + }; + + Stack.prototype.pop = function() { + return this.slice(1); + }; + + Stack.prototype.unshift = function(/*...values*/) { + return this.push.apply(this, arguments); + }; + + Stack.prototype.unshiftAll = function(iter) { + return this.pushAll(iter); + }; + + Stack.prototype.shift = function() { + return this.pop.apply(this, arguments); + }; + + Stack.prototype.clear = function() { + if (this.size === 0) { + return this; + } + if (this.__ownerID) { + this.size = 0; + this._head = undefined; + this.__hash = undefined; + this.__altered = true; + return this; + } + return emptyStack(); + }; + + Stack.prototype.slice = function(begin, end) { + if (wholeSlice(begin, end, this.size)) { + return this; + } + var resolvedBegin = resolveBegin(begin, this.size); + var resolvedEnd = resolveEnd(end, this.size); + if (resolvedEnd !== this.size) { + // super.slice(begin, end); + return IndexedCollection.prototype.slice.call(this, begin, end); + } + var newSize = this.size - resolvedBegin; + var head = this._head; + while (resolvedBegin--) { + head = head.next; + } + if (this.__ownerID) { + this.size = newSize; + this._head = head; + this.__hash = undefined; + this.__altered = true; + return this; + } + return makeStack(newSize, head); + }; + + // @pragma Mutability + + Stack.prototype.__ensureOwner = function(ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + if (!ownerID) { + this.__ownerID = ownerID; + this.__altered = false; + return this; + } + return makeStack(this.size, this._head, ownerID, this.__hash); + }; + + // @pragma Iteration + + Stack.prototype.__iterate = function(fn, reverse) { + if (reverse) { + return this.toSeq().cacheResult.__iterate(fn, reverse); + } + var iterations = 0; + var node = this._head; + while (node) { + if (fn(node.value, iterations++, this) === false) { + break; + } + node = node.next; + } + return iterations; + }; + + Stack.prototype.__iterator = function(type, reverse) { + if (reverse) { + return this.toSeq().cacheResult().__iterator(type, reverse); + } + var iterations = 0; + var node = this._head; + return new Iterator(function() { + if (node) { + var value = node.value; + node = node.next; + return iteratorValue(type, iterations++, value); + } + return iteratorDone(); + }); + }; + + + function isStack(maybeStack) { + return !!(maybeStack && maybeStack[IS_STACK_SENTINEL]); + } + + Stack.isStack = isStack; + + var IS_STACK_SENTINEL = '@@__IMMUTABLE_STACK__@@'; + + var StackPrototype = Stack.prototype; + StackPrototype[IS_STACK_SENTINEL] = true; + StackPrototype.withMutations = MapPrototype.withMutations; + StackPrototype.asMutable = MapPrototype.asMutable; + StackPrototype.asImmutable = MapPrototype.asImmutable; + StackPrototype.wasAltered = MapPrototype.wasAltered; + + + function makeStack(size, head, ownerID, hash) { + var map = Object.create(StackPrototype); + map.size = size; + map._head = head; + map.__ownerID = ownerID; + map.__hash = hash; + map.__altered = false; + return map; + } + + var EMPTY_STACK; + function emptyStack() { + return EMPTY_STACK || (EMPTY_STACK = makeStack(0)); + } + + createClass(Set, SetCollection); + + // @pragma Construction + + function Set(value) { + return value === null || value === undefined ? emptySet() : + isSet(value) ? value : + emptySet().withMutations(function(set ) { + var iter = SetIterable(value); + assertNotInfinite(iter.size); + iter.forEach(function(v ) {return set.add(v)}); + }); + } + + Set.of = function(/*...values*/) { + return this(arguments); + }; + + Set.fromKeys = function(value) { + return this(KeyedIterable(value).keySeq()); + }; + + Set.prototype.toString = function() { + return this.__toString('Set {', '}'); + }; + + // @pragma Access + + Set.prototype.has = function(value) { + return this._map.has(value); + }; + + // @pragma Modification + + Set.prototype.add = function(value) { + return updateSet(this, this._map.set(value, true)); + }; + + Set.prototype.remove = function(value) { + return updateSet(this, this._map.remove(value)); + }; + + Set.prototype.clear = function() { + return updateSet(this, this._map.clear()); + }; + + // @pragma Composition + + Set.prototype.union = function() {var iters = SLICE$0.call(arguments, 0); + iters = iters.filter(function(x ) {return x.size !== 0}); + if (iters.length === 0) { + return this; + } + if (this.size === 0 && iters.length === 1) { + return this.constructor(iters[0]); + } + return this.withMutations(function(set ) { + for (var ii = 0; ii < iters.length; ii++) { + SetIterable(iters[ii]).forEach(function(value ) {return set.add(value)}); + } + }); + }; + + Set.prototype.intersect = function() {var iters = SLICE$0.call(arguments, 0); + if (iters.length === 0) { + return this; + } + iters = iters.map(function(iter ) {return SetIterable(iter)}); + var originalSet = this; + return this.withMutations(function(set ) { + originalSet.forEach(function(value ) { + if (!iters.every(function(iter ) {return iter.contains(value)})) { + set.remove(value); + } + }); + }); + }; + + Set.prototype.subtract = function() {var iters = SLICE$0.call(arguments, 0); + if (iters.length === 0) { + return this; + } + iters = iters.map(function(iter ) {return SetIterable(iter)}); + var originalSet = this; + return this.withMutations(function(set ) { + originalSet.forEach(function(value ) { + if (iters.some(function(iter ) {return iter.contains(value)})) { + set.remove(value); + } + }); + }); + }; + + Set.prototype.merge = function() { + return this.union.apply(this, arguments); + }; + + Set.prototype.mergeWith = function(merger) {var iters = SLICE$0.call(arguments, 1); + return this.union.apply(this, iters); + }; + + Set.prototype.sort = function(comparator) { + // Late binding + return OrderedSet(sortFactory(this, comparator)); + }; + + Set.prototype.sortBy = function(mapper, comparator) { + // Late binding + return OrderedSet(sortFactory(this, comparator, mapper)); + }; + + Set.prototype.wasAltered = function() { + return this._map.wasAltered(); + }; + + Set.prototype.__iterate = function(fn, reverse) {var this$0 = this; + return this._map.__iterate(function(_, k) {return fn(k, k, this$0)}, reverse); + }; + + Set.prototype.__iterator = function(type, reverse) { + return this._map.map(function(_, k) {return k}).__iterator(type, reverse); + }; + + Set.prototype.__ensureOwner = function(ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + var newMap = this._map.__ensureOwner(ownerID); + if (!ownerID) { + this.__ownerID = ownerID; + this._map = newMap; + return this; + } + return this.__make(newMap, ownerID); + }; + + + function isSet(maybeSet) { + return !!(maybeSet && maybeSet[IS_SET_SENTINEL]); + } + + Set.isSet = isSet; + + var IS_SET_SENTINEL = '@@__IMMUTABLE_SET__@@'; + + var SetPrototype = Set.prototype; + SetPrototype[IS_SET_SENTINEL] = true; + SetPrototype[DELETE] = SetPrototype.remove; + SetPrototype.mergeDeep = SetPrototype.merge; + SetPrototype.mergeDeepWith = SetPrototype.mergeWith; + SetPrototype.withMutations = MapPrototype.withMutations; + SetPrototype.asMutable = MapPrototype.asMutable; + SetPrototype.asImmutable = MapPrototype.asImmutable; + + SetPrototype.__empty = emptySet; + SetPrototype.__make = makeSet; + + function updateSet(set, newMap) { + if (set.__ownerID) { + set.size = newMap.size; + set._map = newMap; + return set; + } + return newMap === set._map ? set : + newMap.size === 0 ? set.__empty() : + set.__make(newMap); + } + + function makeSet(map, ownerID) { + var set = Object.create(SetPrototype); + set.size = map ? map.size : 0; + set._map = map; + set.__ownerID = ownerID; + return set; + } + + var EMPTY_SET; + function emptySet() { + return EMPTY_SET || (EMPTY_SET = makeSet(emptyMap())); + } + + createClass(OrderedSet, Set); + + // @pragma Construction + + function OrderedSet(value) { + return value === null || value === undefined ? emptyOrderedSet() : + isOrderedSet(value) ? value : + emptyOrderedSet().withMutations(function(set ) { + var iter = SetIterable(value); + assertNotInfinite(iter.size); + iter.forEach(function(v ) {return set.add(v)}); + }); + } + + OrderedSet.of = function(/*...values*/) { + return this(arguments); + }; + + OrderedSet.fromKeys = function(value) { + return this(KeyedIterable(value).keySeq()); + }; + + OrderedSet.prototype.toString = function() { + return this.__toString('OrderedSet {', '}'); + }; + + + function isOrderedSet(maybeOrderedSet) { + return isSet(maybeOrderedSet) && isOrdered(maybeOrderedSet); + } + + OrderedSet.isOrderedSet = isOrderedSet; + + var OrderedSetPrototype = OrderedSet.prototype; + OrderedSetPrototype[IS_ORDERED_SENTINEL] = true; + + OrderedSetPrototype.__empty = emptyOrderedSet; + OrderedSetPrototype.__make = makeOrderedSet; + + function makeOrderedSet(map, ownerID) { + var set = Object.create(OrderedSetPrototype); + set.size = map ? map.size : 0; + set._map = map; + set.__ownerID = ownerID; + return set; + } + + var EMPTY_ORDERED_SET; + function emptyOrderedSet() { + return EMPTY_ORDERED_SET || (EMPTY_ORDERED_SET = makeOrderedSet(emptyOrderedMap())); + } + + createClass(Record, KeyedCollection); + + function Record(defaultValues, name) { + var RecordType = function Record(values) { + if (!(this instanceof RecordType)) { + return new RecordType(values); + } + this._map = Map(values); + }; + + var keys = Object.keys(defaultValues); + + var RecordTypePrototype = RecordType.prototype = Object.create(RecordPrototype); + RecordTypePrototype.constructor = RecordType; + name && (RecordTypePrototype._name = name); + RecordTypePrototype._defaultValues = defaultValues; + RecordTypePrototype._keys = keys; + RecordTypePrototype.size = keys.length; + + try { + keys.forEach(function(key ) { + Object.defineProperty(RecordType.prototype, key, { + get: function() { + return this.get(key); + }, + set: function(value) { + invariant(this.__ownerID, 'Cannot set on an immutable record.'); + this.set(key, value); + } + }); + }); + } catch (error) { + // Object.defineProperty failed. Probably IE8. + } + + return RecordType; + } + + Record.prototype.toString = function() { + return this.__toString(recordName(this) + ' {', '}'); + }; + + // @pragma Access + + Record.prototype.has = function(k) { + return this._defaultValues.hasOwnProperty(k); + }; + + Record.prototype.get = function(k, notSetValue) { + if (!this.has(k)) { + return notSetValue; + } + var defaultVal = this._defaultValues[k]; + return this._map ? this._map.get(k, defaultVal) : defaultVal; + }; + + // @pragma Modification + + Record.prototype.clear = function() { + if (this.__ownerID) { + this._map && this._map.clear(); + return this; + } + var SuperRecord = Object.getPrototypeOf(this).constructor; + return SuperRecord._empty || (SuperRecord._empty = makeRecord(this, emptyMap())); + }; + + Record.prototype.set = function(k, v) { + if (!this.has(k)) { + throw new Error('Cannot set unknown key "' + k + '" on ' + recordName(this)); + } + var newMap = this._map && this._map.set(k, v); + if (this.__ownerID || newMap === this._map) { + return this; + } + return makeRecord(this, newMap); + }; + + Record.prototype.remove = function(k) { + if (!this.has(k)) { + return this; + } + var newMap = this._map && this._map.remove(k); + if (this.__ownerID || newMap === this._map) { + return this; + } + return makeRecord(this, newMap); + }; + + Record.prototype.wasAltered = function() { + return this._map.wasAltered(); + }; + + Record.prototype.__iterator = function(type, reverse) {var this$0 = this; + return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterator(type, reverse); + }; + + Record.prototype.__iterate = function(fn, reverse) {var this$0 = this; + return KeyedIterable(this._defaultValues).map(function(_, k) {return this$0.get(k)}).__iterate(fn, reverse); + }; + + Record.prototype.__ensureOwner = function(ownerID) { + if (ownerID === this.__ownerID) { + return this; + } + var newMap = this._map && this._map.__ensureOwner(ownerID); + if (!ownerID) { + this.__ownerID = ownerID; + this._map = newMap; + return this; + } + return makeRecord(this, newMap, ownerID); + }; + + + var RecordPrototype = Record.prototype; + RecordPrototype[DELETE] = RecordPrototype.remove; + RecordPrototype.deleteIn = + RecordPrototype.removeIn = MapPrototype.removeIn; + RecordPrototype.merge = MapPrototype.merge; + RecordPrototype.mergeWith = MapPrototype.mergeWith; + RecordPrototype.mergeIn = MapPrototype.mergeIn; + RecordPrototype.mergeDeep = MapPrototype.mergeDeep; + RecordPrototype.mergeDeepWith = MapPrototype.mergeDeepWith; + RecordPrototype.mergeDeepIn = MapPrototype.mergeDeepIn; + RecordPrototype.setIn = MapPrototype.setIn; + RecordPrototype.update = MapPrototype.update; + RecordPrototype.updateIn = MapPrototype.updateIn; + RecordPrototype.withMutations = MapPrototype.withMutations; + RecordPrototype.asMutable = MapPrototype.asMutable; + RecordPrototype.asImmutable = MapPrototype.asImmutable; + + + function makeRecord(likeRecord, map, ownerID) { + var record = Object.create(Object.getPrototypeOf(likeRecord)); + record._map = map; + record.__ownerID = ownerID; + return record; + } + + function recordName(record) { + return record._name || record.constructor.name; + } + + function deepEqual(a, b) { + if (a === b) { + return true; + } + + if ( + !isIterable(b) || + a.size !== undefined && b.size !== undefined && a.size !== b.size || + a.__hash !== undefined && b.__hash !== undefined && a.__hash !== b.__hash || + isKeyed(a) !== isKeyed(b) || + isIndexed(a) !== isIndexed(b) || + isOrdered(a) !== isOrdered(b) + ) { + return false; + } + + if (a.size === 0 && b.size === 0) { + return true; + } + + var notAssociative = !isAssociative(a); + + if (isOrdered(a)) { + var entries = a.entries(); + return b.every(function(v, k) { + var entry = entries.next().value; + return entry && is(entry[1], v) && (notAssociative || is(entry[0], k)); + }) && entries.next().done; + } + + var flipped = false; + + if (a.size === undefined) { + if (b.size === undefined) { + a.cacheResult(); + } else { + flipped = true; + var _ = a; + a = b; + b = _; + } + } + + var allEqual = true; + var bSize = b.__iterate(function(v, k) { + if (notAssociative ? !a.has(v) : + flipped ? !is(v, a.get(k, NOT_SET)) : !is(a.get(k, NOT_SET), v)) { + allEqual = false; + return false; + } + }); + + return allEqual && a.size === bSize; + } + + createClass(Range, IndexedSeq); + + function Range(start, end, step) { + if (!(this instanceof Range)) { + return new Range(start, end, step); + } + invariant(step !== 0, 'Cannot step a Range by 0'); + start = start || 0; + if (end === undefined) { + end = Infinity; + } + step = step === undefined ? 1 : Math.abs(step); + if (end < start) { + step = -step; + } + this._start = start; + this._end = end; + this._step = step; + this.size = Math.max(0, Math.ceil((end - start) / step - 1) + 1); + if (this.size === 0) { + if (EMPTY_RANGE) { + return EMPTY_RANGE; + } + EMPTY_RANGE = this; + } + } + + Range.prototype.toString = function() { + if (this.size === 0) { + return 'Range []'; + } + return 'Range [ ' + + this._start + '...' + this._end + + (this._step > 1 ? ' by ' + this._step : '') + + ' ]'; + }; + + Range.prototype.get = function(index, notSetValue) { + return this.has(index) ? + this._start + wrapIndex(this, index) * this._step : + notSetValue; + }; + + Range.prototype.contains = function(searchValue) { + var possibleIndex = (searchValue - this._start) / this._step; + return possibleIndex >= 0 && + possibleIndex < this.size && + possibleIndex === Math.floor(possibleIndex); + }; + + Range.prototype.slice = function(begin, end) { + if (wholeSlice(begin, end, this.size)) { + return this; + } + begin = resolveBegin(begin, this.size); + end = resolveEnd(end, this.size); + if (end <= begin) { + return new Range(0, 0); + } + return new Range(this.get(begin, this._end), this.get(end, this._end), this._step); + }; + + Range.prototype.indexOf = function(searchValue) { + var offsetValue = searchValue - this._start; + if (offsetValue % this._step === 0) { + var index = offsetValue / this._step; + if (index >= 0 && index < this.size) { + return index + } + } + return -1; + }; + + Range.prototype.lastIndexOf = function(searchValue) { + return this.indexOf(searchValue); + }; + + Range.prototype.__iterate = function(fn, reverse) { + var maxIndex = this.size - 1; + var step = this._step; + var value = reverse ? this._start + maxIndex * step : this._start; + for (var ii = 0; ii <= maxIndex; ii++) { + if (fn(value, ii, this) === false) { + return ii + 1; + } + value += reverse ? -step : step; + } + return ii; + }; + + Range.prototype.__iterator = function(type, reverse) { + var maxIndex = this.size - 1; + var step = this._step; + var value = reverse ? this._start + maxIndex * step : this._start; + var ii = 0; + return new Iterator(function() { + var v = value; + value += reverse ? -step : step; + return ii > maxIndex ? iteratorDone() : iteratorValue(type, ii++, v); + }); + }; + + Range.prototype.equals = function(other) { + return other instanceof Range ? + this._start === other._start && + this._end === other._end && + this._step === other._step : + deepEqual(this, other); + }; + + + var EMPTY_RANGE; + + createClass(Repeat, IndexedSeq); + + function Repeat(value, times) { + if (!(this instanceof Repeat)) { + return new Repeat(value, times); + } + this._value = value; + this.size = times === undefined ? Infinity : Math.max(0, times); + if (this.size === 0) { + if (EMPTY_REPEAT) { + return EMPTY_REPEAT; + } + EMPTY_REPEAT = this; + } + } + + Repeat.prototype.toString = function() { + if (this.size === 0) { + return 'Repeat []'; + } + return 'Repeat [ ' + this._value + ' ' + this.size + ' times ]'; + }; + + Repeat.prototype.get = function(index, notSetValue) { + return this.has(index) ? this._value : notSetValue; + }; + + Repeat.prototype.contains = function(searchValue) { + return is(this._value, searchValue); + }; + + Repeat.prototype.slice = function(begin, end) { + var size = this.size; + return wholeSlice(begin, end, size) ? this : + new Repeat(this._value, resolveEnd(end, size) - resolveBegin(begin, size)); + }; + + Repeat.prototype.reverse = function() { + return this; + }; + + Repeat.prototype.indexOf = function(searchValue) { + if (is(this._value, searchValue)) { + return 0; + } + return -1; + }; + + Repeat.prototype.lastIndexOf = function(searchValue) { + if (is(this._value, searchValue)) { + return this.size; + } + return -1; + }; + + Repeat.prototype.__iterate = function(fn, reverse) { + for (var ii = 0; ii < this.size; ii++) { + if (fn(this._value, ii, this) === false) { + return ii + 1; + } + } + return ii; + }; + + Repeat.prototype.__iterator = function(type, reverse) {var this$0 = this; + var ii = 0; + return new Iterator(function() + {return ii < this$0.size ? iteratorValue(type, ii++, this$0._value) : iteratorDone()} + ); + }; + + Repeat.prototype.equals = function(other) { + return other instanceof Repeat ? + is(this._value, other._value) : + deepEqual(other); + }; + + + var EMPTY_REPEAT; + + /** + * Contributes additional methods to a constructor + */ + function mixin(ctor, methods) { + var keyCopier = function(key ) { ctor.prototype[key] = methods[key]; }; + Object.keys(methods).forEach(keyCopier); + Object.getOwnPropertySymbols && + Object.getOwnPropertySymbols(methods).forEach(keyCopier); + return ctor; + } + + Iterable.Iterator = Iterator; + + mixin(Iterable, { + + // ### Conversion to other types + + toArray: function() { + assertNotInfinite(this.size); + var array = new Array(this.size || 0); + this.valueSeq().__iterate(function(v, i) { array[i] = v; }); + return array; + }, + + toIndexedSeq: function() { + return new ToIndexedSequence(this); + }, + + toJS: function() { + return this.toSeq().map( + function(value ) {return value && typeof value.toJS === 'function' ? value.toJS() : value} + ).__toJS(); + }, + + toJSON: function() { + return this.toSeq().map( + function(value ) {return value && typeof value.toJSON === 'function' ? value.toJSON() : value} + ).__toJS(); + }, + + toKeyedSeq: function() { + return new ToKeyedSequence(this, true); + }, + + toMap: function() { + // Use Late Binding here to solve the circular dependency. + return Map(this.toKeyedSeq()); + }, + + toObject: function() { + assertNotInfinite(this.size); + var object = {}; + this.__iterate(function(v, k) { object[k] = v; }); + return object; + }, + + toOrderedMap: function() { + // Use Late Binding here to solve the circular dependency. + return OrderedMap(this.toKeyedSeq()); + }, + + toOrderedSet: function() { + // Use Late Binding here to solve the circular dependency. + return OrderedSet(isKeyed(this) ? this.valueSeq() : this); + }, + + toSet: function() { + // Use Late Binding here to solve the circular dependency. + return Set(isKeyed(this) ? this.valueSeq() : this); + }, + + toSetSeq: function() { + return new ToSetSequence(this); + }, + + toSeq: function() { + return isIndexed(this) ? this.toIndexedSeq() : + isKeyed(this) ? this.toKeyedSeq() : + this.toSetSeq(); + }, + + toStack: function() { + // Use Late Binding here to solve the circular dependency. + return Stack(isKeyed(this) ? this.valueSeq() : this); + }, + + toList: function() { + // Use Late Binding here to solve the circular dependency. + return List(isKeyed(this) ? this.valueSeq() : this); + }, + + + // ### Common JavaScript methods and properties + + toString: function() { + return '[Iterable]'; + }, + + __toString: function(head, tail) { + if (this.size === 0) { + return head + tail; + } + return head + ' ' + this.toSeq().map(this.__toStringMapper).join(', ') + ' ' + tail; + }, + + + // ### ES6 Collection methods (ES6 Array and Map) + + concat: function() {var values = SLICE$0.call(arguments, 0); + return reify(this, concatFactory(this, values)); + }, + + contains: function(searchValue) { + return this.some(function(value ) {return is(value, searchValue)}); + }, + + entries: function() { + return this.__iterator(ITERATE_ENTRIES); + }, + + every: function(predicate, context) { + assertNotInfinite(this.size); + var returnValue = true; + this.__iterate(function(v, k, c) { + if (!predicate.call(context, v, k, c)) { + returnValue = false; + return false; + } + }); + return returnValue; + }, + + filter: function(predicate, context) { + return reify(this, filterFactory(this, predicate, context, true)); + }, + + find: function(predicate, context, notSetValue) { + var entry = this.findEntry(predicate, context); + return entry ? entry[1] : notSetValue; + }, + + findEntry: function(predicate, context) { + var found; + this.__iterate(function(v, k, c) { + if (predicate.call(context, v, k, c)) { + found = [k, v]; + return false; + } + }); + return found; + }, + + findLastEntry: function(predicate, context) { + return this.toSeq().reverse().findEntry(predicate, context); + }, + + forEach: function(sideEffect, context) { + assertNotInfinite(this.size); + return this.__iterate(context ? sideEffect.bind(context) : sideEffect); + }, + + join: function(separator) { + assertNotInfinite(this.size); + separator = separator !== undefined ? '' + separator : ','; + var joined = ''; + var isFirst = true; + this.__iterate(function(v ) { + isFirst ? (isFirst = false) : (joined += separator); + joined += v !== null && v !== undefined ? v : ''; + }); + return joined; + }, + + keys: function() { + return this.__iterator(ITERATE_KEYS); + }, + + map: function(mapper, context) { + return reify(this, mapFactory(this, mapper, context)); + }, + + reduce: function(reducer, initialReduction, context) { + assertNotInfinite(this.size); + var reduction; + var useFirst; + if (arguments.length < 2) { + useFirst = true; + } else { + reduction = initialReduction; + } + this.__iterate(function(v, k, c) { + if (useFirst) { + useFirst = false; + reduction = v; + } else { + reduction = reducer.call(context, reduction, v, k, c); + } + }); + return reduction; + }, + + reduceRight: function(reducer, initialReduction, context) { + var reversed = this.toKeyedSeq().reverse(); + return reversed.reduce.apply(reversed, arguments); + }, + + reverse: function() { + return reify(this, reverseFactory(this, true)); + }, + + slice: function(begin, end) { + return reify(this, sliceFactory(this, begin, end, true)); + }, + + some: function(predicate, context) { + return !this.every(not(predicate), context); + }, + + sort: function(comparator) { + return reify(this, sortFactory(this, comparator)); + }, + + values: function() { + return this.__iterator(ITERATE_VALUES); + }, + + + // ### More sequential methods + + butLast: function() { + return this.slice(0, -1); + }, + + isEmpty: function() { + return this.size !== undefined ? this.size === 0 : !this.some(function() {return true}); + }, + + count: function(predicate, context) { + return ensureSize( + predicate ? this.toSeq().filter(predicate, context) : this + ); + }, + + countBy: function(grouper, context) { + return countByFactory(this, grouper, context); + }, + + equals: function(other) { + return deepEqual(this, other); + }, + + entrySeq: function() { + var iterable = this; + if (iterable._cache) { + // We cache as an entries array, so we can just return the cache! + return new ArraySeq(iterable._cache); + } + var entriesSequence = iterable.toSeq().map(entryMapper).toIndexedSeq(); + entriesSequence.fromEntrySeq = function() {return iterable.toSeq()}; + return entriesSequence; + }, + + filterNot: function(predicate, context) { + return this.filter(not(predicate), context); + }, + + findLast: function(predicate, context, notSetValue) { + return this.toKeyedSeq().reverse().find(predicate, context, notSetValue); + }, + + first: function() { + return this.find(returnTrue); + }, + + flatMap: function(mapper, context) { + return reify(this, flatMapFactory(this, mapper, context)); + }, + + flatten: function(depth) { + return reify(this, flattenFactory(this, depth, true)); + }, + + fromEntrySeq: function() { + return new FromEntriesSequence(this); + }, + + get: function(searchKey, notSetValue) { + return this.find(function(_, key) {return is(key, searchKey)}, undefined, notSetValue); + }, + + getIn: function(searchKeyPath, notSetValue) { + var nested = this; + // Note: in an ES6 environment, we would prefer: + // for (var key of searchKeyPath) { + var iter = forceIterator(searchKeyPath); + var step; + while (!(step = iter.next()).done) { + var key = step.value; + nested = nested && nested.get ? nested.get(key, NOT_SET) : NOT_SET; + if (nested === NOT_SET) { + return notSetValue; + } + } + return nested; + }, + + groupBy: function(grouper, context) { + return groupByFactory(this, grouper, context); + }, + + has: function(searchKey) { + return this.get(searchKey, NOT_SET) !== NOT_SET; + }, + + hasIn: function(searchKeyPath) { + return this.getIn(searchKeyPath, NOT_SET) !== NOT_SET; + }, + + isSubset: function(iter) { + iter = typeof iter.contains === 'function' ? iter : Iterable(iter); + return this.every(function(value ) {return iter.contains(value)}); + }, + + isSuperset: function(iter) { + return iter.isSubset(this); + }, + + keySeq: function() { + return this.toSeq().map(keyMapper).toIndexedSeq(); + }, + + last: function() { + return this.toSeq().reverse().first(); + }, + + max: function(comparator) { + return maxFactory(this, comparator); + }, + + maxBy: function(mapper, comparator) { + return maxFactory(this, comparator, mapper); + }, + + min: function(comparator) { + return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator); + }, + + minBy: function(mapper, comparator) { + return maxFactory(this, comparator ? neg(comparator) : defaultNegComparator, mapper); + }, + + rest: function() { + return this.slice(1); + }, + + skip: function(amount) { + return this.slice(Math.max(0, amount)); + }, + + skipLast: function(amount) { + return reify(this, this.toSeq().reverse().skip(amount).reverse()); + }, + + skipWhile: function(predicate, context) { + return reify(this, skipWhileFactory(this, predicate, context, true)); + }, + + skipUntil: function(predicate, context) { + return this.skipWhile(not(predicate), context); + }, + + sortBy: function(mapper, comparator) { + return reify(this, sortFactory(this, comparator, mapper)); + }, + + take: function(amount) { + return this.slice(0, Math.max(0, amount)); + }, + + takeLast: function(amount) { + return reify(this, this.toSeq().reverse().take(amount).reverse()); + }, + + takeWhile: function(predicate, context) { + return reify(this, takeWhileFactory(this, predicate, context)); + }, + + takeUntil: function(predicate, context) { + return this.takeWhile(not(predicate), context); + }, + + valueSeq: function() { + return this.toIndexedSeq(); + }, + + + // ### Hashable Object + + hashCode: function() { + return this.__hash || (this.__hash = hashIterable(this)); + }, + + + // ### Internal + + // abstract __iterate(fn, reverse) + + // abstract __iterator(type, reverse) + }); + + // var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@'; + // var IS_KEYED_SENTINEL = '@@__IMMUTABLE_KEYED__@@'; + // var IS_INDEXED_SENTINEL = '@@__IMMUTABLE_INDEXED__@@'; + // var IS_ORDERED_SENTINEL = '@@__IMMUTABLE_ORDERED__@@'; + + var IterablePrototype = Iterable.prototype; + IterablePrototype[IS_ITERABLE_SENTINEL] = true; + IterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.values; + IterablePrototype.__toJS = IterablePrototype.toArray; + IterablePrototype.__toStringMapper = quoteString; + IterablePrototype.inspect = + IterablePrototype.toSource = function() { return this.toString(); }; + IterablePrototype.chain = IterablePrototype.flatMap; + + // Temporary warning about using length + (function () { + try { + Object.defineProperty(IterablePrototype, 'length', { + get: function () { + if (!Iterable.noLengthWarning) { + var stack; + try { + throw new Error(); + } catch (error) { + stack = error.stack; + } + if (stack.indexOf('_wrapObject') === -1) { + console && console.warn && console.warn( + 'iterable.length has been deprecated, '+ + 'use iterable.size or iterable.count(). '+ + 'This warning will become a silent error in a future version. ' + + stack + ); + return this.size; + } + } + } + }); + } catch (e) {} + })(); + + + + mixin(KeyedIterable, { + + // ### More sequential methods + + flip: function() { + return reify(this, flipFactory(this)); + }, + + findKey: function(predicate, context) { + var entry = this.findEntry(predicate, context); + return entry && entry[0]; + }, + + findLastKey: function(predicate, context) { + return this.toSeq().reverse().findKey(predicate, context); + }, + + keyOf: function(searchValue) { + return this.findKey(function(value ) {return is(value, searchValue)}); + }, + + lastKeyOf: function(searchValue) { + return this.findLastKey(function(value ) {return is(value, searchValue)}); + }, + + mapEntries: function(mapper, context) {var this$0 = this; + var iterations = 0; + return reify(this, + this.toSeq().map( + function(v, k) {return mapper.call(context, [k, v], iterations++, this$0)} + ).fromEntrySeq() + ); + }, + + mapKeys: function(mapper, context) {var this$0 = this; + return reify(this, + this.toSeq().flip().map( + function(k, v) {return mapper.call(context, k, v, this$0)} + ).flip() + ); + }, + + }); + + var KeyedIterablePrototype = KeyedIterable.prototype; + KeyedIterablePrototype[IS_KEYED_SENTINEL] = true; + KeyedIterablePrototype[ITERATOR_SYMBOL] = IterablePrototype.entries; + KeyedIterablePrototype.__toJS = IterablePrototype.toObject; + KeyedIterablePrototype.__toStringMapper = function(v, k) {return k + ': ' + quoteString(v)}; + + + + mixin(IndexedIterable, { + + // ### Conversion to other types + + toKeyedSeq: function() { + return new ToKeyedSequence(this, false); + }, + + + // ### ES6 Collection methods (ES6 Array and Map) + + filter: function(predicate, context) { + return reify(this, filterFactory(this, predicate, context, false)); + }, + + findIndex: function(predicate, context) { + var entry = this.findEntry(predicate, context); + return entry ? entry[0] : -1; + }, + + indexOf: function(searchValue) { + var key = this.toKeyedSeq().keyOf(searchValue); + return key === undefined ? -1 : key; + }, + + lastIndexOf: function(searchValue) { + return this.toSeq().reverse().indexOf(searchValue); + }, + + reverse: function() { + return reify(this, reverseFactory(this, false)); + }, + + slice: function(begin, end) { + return reify(this, sliceFactory(this, begin, end, false)); + }, + + splice: function(index, removeNum /*, ...values*/) { + var numArgs = arguments.length; + removeNum = Math.max(removeNum | 0, 0); + if (numArgs === 0 || (numArgs === 2 && !removeNum)) { + return this; + } + index = resolveBegin(index, this.size); + var spliced = this.slice(0, index); + return reify( + this, + numArgs === 1 ? + spliced : + spliced.concat(arrCopy(arguments, 2), this.slice(index + removeNum)) + ); + }, + + + // ### More collection methods + + findLastIndex: function(predicate, context) { + var key = this.toKeyedSeq().findLastKey(predicate, context); + return key === undefined ? -1 : key; + }, + + first: function() { + return this.get(0); + }, + + flatten: function(depth) { + return reify(this, flattenFactory(this, depth, false)); + }, + + get: function(index, notSetValue) { + index = wrapIndex(this, index); + return (index < 0 || (this.size === Infinity || + (this.size !== undefined && index > this.size))) ? + notSetValue : + this.find(function(_, key) {return key === index}, undefined, notSetValue); + }, + + has: function(index) { + index = wrapIndex(this, index); + return index >= 0 && (this.size !== undefined ? + this.size === Infinity || index < this.size : + this.indexOf(index) !== -1 + ); + }, + + interpose: function(separator) { + return reify(this, interposeFactory(this, separator)); + }, + + interleave: function(/*...iterables*/) { + var iterables = [this].concat(arrCopy(arguments)); + var zipped = zipWithFactory(this.toSeq(), IndexedSeq.of, iterables); + var interleaved = zipped.flatten(true); + if (zipped.size) { + interleaved.size = zipped.size * iterables.length; + } + return reify(this, interleaved); + }, + + last: function() { + return this.get(-1); + }, + + skipWhile: function(predicate, context) { + return reify(this, skipWhileFactory(this, predicate, context, false)); + }, + + zip: function(/*, ...iterables */) { + var iterables = [this].concat(arrCopy(arguments)); + return reify(this, zipWithFactory(this, defaultZipper, iterables)); + }, + + zipWith: function(zipper/*, ...iterables */) { + var iterables = arrCopy(arguments); + iterables[0] = this; + return reify(this, zipWithFactory(this, zipper, iterables)); + }, + + }); + + IndexedIterable.prototype[IS_INDEXED_SENTINEL] = true; + IndexedIterable.prototype[IS_ORDERED_SENTINEL] = true; + + + + mixin(SetIterable, { + + // ### ES6 Collection methods (ES6 Array and Map) + + get: function(value, notSetValue) { + return this.has(value) ? value : notSetValue; + }, + + contains: function(value) { + return this.has(value); + }, + + + // ### More sequential methods + + keySeq: function() { + return this.valueSeq(); + }, + + }); + + SetIterable.prototype.has = IterablePrototype.contains; + + + // Mixin subclasses + + mixin(KeyedSeq, KeyedIterable.prototype); + mixin(IndexedSeq, IndexedIterable.prototype); + mixin(SetSeq, SetIterable.prototype); + + mixin(KeyedCollection, KeyedIterable.prototype); + mixin(IndexedCollection, IndexedIterable.prototype); + mixin(SetCollection, SetIterable.prototype); + + + // #pragma Helper functions + + function keyMapper(v, k) { + return k; + } + + function entryMapper(v, k) { + return [k, v]; + } + + function not(predicate) { + return function() { + return !predicate.apply(this, arguments); + } + } + + function neg(predicate) { + return function() { + return -predicate.apply(this, arguments); + } + } + + function quoteString(value) { + return typeof value === 'string' ? JSON.stringify(value) : value; + } + + function defaultZipper() { + return arrCopy(arguments); + } + + function defaultNegComparator(a, b) { + return a < b ? 1 : a > b ? -1 : 0; + } + + function hashIterable(iterable) { + if (iterable.size === Infinity) { + return 0; + } + var ordered = isOrdered(iterable); + var keyed = isKeyed(iterable); + var h = ordered ? 1 : 0; + var size = iterable.__iterate( + keyed ? + ordered ? + function(v, k) { h = 31 * h + hashMerge(hash(v), hash(k)) | 0; } : + function(v, k) { h = h + hashMerge(hash(v), hash(k)) | 0; } : + ordered ? + function(v ) { h = 31 * h + hash(v) | 0; } : + function(v ) { h = h + hash(v) | 0; } + ); + return murmurHashOfSize(size, h); + } + + function murmurHashOfSize(size, h) { + h = Math__imul(h, 0xCC9E2D51); + h = Math__imul(h << 15 | h >>> -15, 0x1B873593); + h = Math__imul(h << 13 | h >>> -13, 5); + h = (h + 0xE6546B64 | 0) ^ size; + h = Math__imul(h ^ h >>> 16, 0x85EBCA6B); + h = Math__imul(h ^ h >>> 13, 0xC2B2AE35); + h = smi(h ^ h >>> 16); + return h; + } + + function hashMerge(a, b) { + return a ^ b + 0x9E3779B9 + (a << 6) + (a >> 2) | 0; // int + } + + var Immutable = { + + Iterable: Iterable, + + Seq: Seq, + Collection: Collection, + Map: Map, + OrderedMap: OrderedMap, + List: List, + Stack: Stack, + Set: Set, + OrderedSet: OrderedSet, + + Record: Record, + Range: Range, + Repeat: Repeat, + + is: is, + fromJS: fromJS, + + }; + + return Immutable; + +})); +},{}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/AutoFocusMixin.js":[function(require,module,exports){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule AutoFocusMixin + * @typechecks static-only + */ + +"use strict"; + +var focusNode = require("./focusNode"); + +var AutoFocusMixin = { + componentDidMount: function() { + if (this.props.autoFocus) { + focusNode(this.getDOMNode()); + } + } +}; + +module.exports = AutoFocusMixin; + +},{"./focusNode":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/focusNode.js"}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/BeforeInputEventPlugin.js":[function(require,module,exports){ +/** + * Copyright 2013 Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule BeforeInputEventPlugin + * @typechecks static-only + */ + +"use strict"; + +var EventConstants = require("./EventConstants"); +var EventPropagators = require("./EventPropagators"); +var ExecutionEnvironment = require("./ExecutionEnvironment"); +var SyntheticInputEvent = require("./SyntheticInputEvent"); + +var keyOf = require("./keyOf"); + +var canUseTextInputEvent = ( + ExecutionEnvironment.canUseDOM && + 'TextEvent' in window && + !('documentMode' in document || isPresto()) +); + +/** + * Opera <= 12 includes TextEvent in window, but does not fire + * text input events. Rely on keypress instead. + */ +function isPresto() { + var opera = window.opera; + return ( + typeof opera === 'object' && + typeof opera.version === 'function' && + parseInt(opera.version(), 10) <= 12 + ); +} + +var SPACEBAR_CODE = 32; +var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); + +var topLevelTypes = EventConstants.topLevelTypes; + +// Events and their corresponding property names. +var eventTypes = { + beforeInput: { + phasedRegistrationNames: { + bubbled: keyOf({onBeforeInput: null}), + captured: keyOf({onBeforeInputCapture: null}) + }, + dependencies: [ + topLevelTypes.topCompositionEnd, + topLevelTypes.topKeyPress, + topLevelTypes.topTextInput, + topLevelTypes.topPaste + ] + } +}; + +// Track characters inserted via keypress and composition events. +var fallbackChars = null; + +// Track whether we've ever handled a keypress on the space key. +var hasSpaceKeypress = false; + +/** + * Return whether a native keypress event is assumed to be a command. + * This is required because Firefox fires `keypress` events for key commands + * (cut, copy, select-all, etc.) even though no character is inserted. + */ +function isKeypressCommand(nativeEvent) { + return ( + (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && + // ctrlKey && altKey is equivalent to AltGr, and is not a command. + !(nativeEvent.ctrlKey && nativeEvent.altKey) + ); +} + +/** + * Create an `onBeforeInput` event to match + * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. + * + * This event plugin is based on the native `textInput` event + * available in Chrome, Safari, Opera, and IE. This event fires after + * `onKeyPress` and `onCompositionEnd`, but before `onInput`. + * + * `beforeInput` is spec'd but not implemented in any browsers, and + * the `input` event does not provide any useful information about what has + * actually been added, contrary to the spec. Thus, `textInput` is the best + * available event to identify the characters that have actually been inserted + * into the target node. + */ +var BeforeInputEventPlugin = { + + eventTypes: eventTypes, + + /** + * @param {string} topLevelType Record from `EventConstants`. + * @param {DOMEventTarget} topLevelTarget The listening component root node. + * @param {string} topLevelTargetID ID of `topLevelTarget`. + * @param {object} nativeEvent Native browser event. + * @return {*} An accumulation of synthetic events. + * @see {EventPluginHub.extractEvents} + */ + extractEvents: function( + topLevelType, + topLevelTarget, + topLevelTargetID, + nativeEvent) { + + var chars; + + if (canUseTextInputEvent) { + switch (topLevelType) { + case topLevelTypes.topKeyPress: + /** + * If native `textInput` events are available, our goal is to make + * use of them. However, there is a special case: the spacebar key. + * In Webkit, preventing default on a spacebar `textInput` event + * cancels character insertion, but it *also* causes the browser + * to fall back to its default spacebar behavior of scrolling the + * page. + * + * Tracking at: + * https://code.google.com/p/chromium/issues/detail?id=355103 + * + * To avoid this issue, use the keypress event as if no `textInput` + * event is available. + */ + var which = nativeEvent.which; + if (which !== SPACEBAR_CODE) { + return; + } + + hasSpaceKeypress = true; + chars = SPACEBAR_CHAR; + break; + + case topLevelTypes.topTextInput: + // Record the characters to be added to the DOM. + chars = nativeEvent.data; + + // If it's a spacebar character, assume that we have already handled + // it at the keypress level and bail immediately. Android Chrome + // doesn't give us keycodes, so we need to blacklist it. + if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { + return; + } + + // Otherwise, carry on. + break; + + default: + // For other native event types, do nothing. + return; + } + } else { + switch (topLevelType) { + case topLevelTypes.topPaste: + // If a paste event occurs after a keypress, throw out the input + // chars. Paste events should not lead to BeforeInput events. + fallbackChars = null; + break; + case topLevelTypes.topKeyPress: + /** + * As of v27, Firefox may fire keypress events even when no character + * will be inserted. A few possibilities: + * + * - `which` is `0`. Arrow keys, Esc key, etc. + * + * - `which` is the pressed key code, but no char is available. + * Ex: 'AltGr + d` in Polish. There is no modified character for + * this key combination and no character is inserted into the + * document, but FF fires the keypress for char code `100` anyway. + * No `input` event will occur. + * + * - `which` is the pressed key code, but a command combination is + * being used. Ex: `Cmd+C`. No character is inserted, and no + * `input` event will occur. + */ + if (nativeEvent.which && !isKeypressCommand(nativeEvent)) { + fallbackChars = String.fromCharCode(nativeEvent.which); + } + break; + case topLevelTypes.topCompositionEnd: + fallbackChars = nativeEvent.data; + break; + } + + // If no changes have occurred to the fallback string, no relevant + // event has fired and we're done. + if (fallbackChars === null) { + return; + } + + chars = fallbackChars; + } + + // If no characters are being inserted, no BeforeInput event should + // be fired. + if (!chars) { + return; + } + + var event = SyntheticInputEvent.getPooled( + eventTypes.beforeInput, + topLevelTargetID, + nativeEvent + ); + + event.data = chars; + fallbackChars = null; + EventPropagators.accumulateTwoPhaseDispatches(event); + return event; + } +}; + +module.exports = BeforeInputEventPlugin; + +},{"./EventConstants":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/EventConstants.js","./EventPropagators":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/EventPropagators.js","./ExecutionEnvironment":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ExecutionEnvironment.js","./SyntheticInputEvent":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/SyntheticInputEvent.js","./keyOf":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/keyOf.js"}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/CSSProperty.js":[function(require,module,exports){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule CSSProperty + */ + +"use strict"; + +/** + * CSS properties which accept numbers but are not in units of "px". + */ +var isUnitlessNumber = { + columnCount: true, + flex: true, + flexGrow: true, + flexShrink: true, + fontWeight: true, + lineClamp: true, + lineHeight: true, + opacity: true, + order: true, + orphans: true, + widows: true, + zIndex: true, + zoom: true, + + // SVG-related properties + fillOpacity: true, + strokeOpacity: true +}; + +/** + * @param {string} prefix vendor-specific prefix, eg: Webkit + * @param {string} key style name, eg: transitionDuration + * @return {string} style name prefixed with `prefix`, properly camelCased, eg: + * WebkitTransitionDuration + */ +function prefixKey(prefix, key) { + return prefix + key.charAt(0).toUpperCase() + key.substring(1); +} + +/** + * Support style names that may come passed in prefixed by adding permutations + * of vendor prefixes. + */ +var prefixes = ['Webkit', 'ms', 'Moz', 'O']; + +// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an +// infinite loop, because it iterates over the newly added props too. +Object.keys(isUnitlessNumber).forEach(function(prop) { + prefixes.forEach(function(prefix) { + isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; + }); +}); + +/** + * Most style properties can be unset by doing .style[prop] = '' but IE8 + * doesn't like doing that with shorthand properties so for the properties that + * IE8 breaks on, which are listed here, we instead unset each of the + * individual properties. See http://bugs.jquery.com/ticket/12385. + * The 4-value 'clock' properties like margin, padding, border-width seem to + * behave without any problems. Curiously, list-style works too without any + * special prodding. + */ +var shorthandPropertyExpansions = { + background: { + backgroundImage: true, + backgroundPosition: true, + backgroundRepeat: true, + backgroundColor: true + }, + border: { + borderWidth: true, + borderStyle: true, + borderColor: true + }, + borderBottom: { + borderBottomWidth: true, + borderBottomStyle: true, + borderBottomColor: true + }, + borderLeft: { + borderLeftWidth: true, + borderLeftStyle: true, + borderLeftColor: true + }, + borderRight: { + borderRightWidth: true, + borderRightStyle: true, + borderRightColor: true + }, + borderTop: { + borderTopWidth: true, + borderTopStyle: true, + borderTopColor: true + }, + font: { + fontStyle: true, + fontVariant: true, + fontWeight: true, + fontSize: true, + lineHeight: true, + fontFamily: true + } +}; + +var CSSProperty = { + isUnitlessNumber: isUnitlessNumber, + shorthandPropertyExpansions: shorthandPropertyExpansions +}; + +module.exports = CSSProperty; + +},{}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/CSSPropertyOperations.js":[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule CSSPropertyOperations + * @typechecks static-only + */ + +"use strict"; + +var CSSProperty = require("./CSSProperty"); +var ExecutionEnvironment = require("./ExecutionEnvironment"); + +var camelizeStyleName = require("./camelizeStyleName"); +var dangerousStyleValue = require("./dangerousStyleValue"); +var hyphenateStyleName = require("./hyphenateStyleName"); +var memoizeStringOnly = require("./memoizeStringOnly"); +var warning = require("./warning"); + +var processStyleName = memoizeStringOnly(function(styleName) { + return hyphenateStyleName(styleName); +}); + +var styleFloatAccessor = 'cssFloat'; +if (ExecutionEnvironment.canUseDOM) { + // IE8 only supports accessing cssFloat (standard) as styleFloat + if (document.documentElement.style.cssFloat === undefined) { + styleFloatAccessor = 'styleFloat'; + } +} + +if ("production" !== process.env.NODE_ENV) { + var warnedStyleNames = {}; + + var warnHyphenatedStyleName = function(name) { + if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { + return; + } + + warnedStyleNames[name] = true; + ("production" !== process.env.NODE_ENV ? warning( + false, + 'Unsupported style property ' + name + '. Did you mean ' + + camelizeStyleName(name) + '?' + ) : null); + }; +} + +/** + * Operations for dealing with CSS properties. + */ +var CSSPropertyOperations = { + + /** + * Serializes a mapping of style properties for use as inline styles: + * + * > createMarkupForStyles({width: '200px', height: 0}) + * "width:200px;height:0;" + * + * Undefined values are ignored so that declarative programming is easier. + * The result should be HTML-escaped before insertion into the DOM. + * + * @param {object} styles + * @return {?string} + */ + createMarkupForStyles: function(styles) { + var serialized = ''; + for (var styleName in styles) { + if (!styles.hasOwnProperty(styleName)) { + continue; + } + if ("production" !== process.env.NODE_ENV) { + if (styleName.indexOf('-') > -1) { + warnHyphenatedStyleName(styleName); + } + } + var styleValue = styles[styleName]; + if (styleValue != null) { + serialized += processStyleName(styleName) + ':'; + serialized += dangerousStyleValue(styleName, styleValue) + ';'; + } + } + return serialized || null; + }, + + /** + * Sets the value for multiple styles on a node. If a value is specified as + * '' (empty string), the corresponding style property will be unset. + * + * @param {DOMElement} node + * @param {object} styles + */ + setValueForStyles: function(node, styles) { + var style = node.style; + for (var styleName in styles) { + if (!styles.hasOwnProperty(styleName)) { + continue; + } + if ("production" !== process.env.NODE_ENV) { + if (styleName.indexOf('-') > -1) { + warnHyphenatedStyleName(styleName); + } + } + var styleValue = dangerousStyleValue(styleName, styles[styleName]); + if (styleName === 'float') { + styleName = styleFloatAccessor; + } + if (styleValue) { + style[styleName] = styleValue; + } else { + var expansion = CSSProperty.shorthandPropertyExpansions[styleName]; + if (expansion) { + // Shorthand property that IE8 won't like unsetting, so unset each + // component to placate it + for (var individualStyleName in expansion) { + style[individualStyleName] = ''; + } + } else { + style[styleName] = ''; + } + } + } + } + +}; + +module.exports = CSSPropertyOperations; + +}).call(this,require('_process')) +},{"./CSSProperty":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/CSSProperty.js","./ExecutionEnvironment":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ExecutionEnvironment.js","./camelizeStyleName":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/camelizeStyleName.js","./dangerousStyleValue":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/dangerousStyleValue.js","./hyphenateStyleName":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/hyphenateStyleName.js","./memoizeStringOnly":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/memoizeStringOnly.js","./warning":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/warning.js","_process":"/Users/eden/mapbox/gl-draw/node_modules/watchify/node_modules/browserify/node_modules/process/browser.js"}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/CallbackQueue.js":[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule CallbackQueue + */ + +"use strict"; + +var PooledClass = require("./PooledClass"); + +var assign = require("./Object.assign"); +var invariant = require("./invariant"); + +/** + * A specialized pseudo-event module to help keep track of components waiting to + * be notified when their DOM representations are available for use. + * + * This implements `PooledClass`, so you should never need to instantiate this. + * Instead, use `CallbackQueue.getPooled()`. + * + * @class ReactMountReady + * @implements PooledClass + * @internal + */ +function CallbackQueue() { + this._callbacks = null; + this._contexts = null; +} + +assign(CallbackQueue.prototype, { + + /** + * Enqueues a callback to be invoked when `notifyAll` is invoked. + * + * @param {function} callback Invoked when `notifyAll` is invoked. + * @param {?object} context Context to call `callback` with. + * @internal + */ + enqueue: function(callback, context) { + this._callbacks = this._callbacks || []; + this._contexts = this._contexts || []; + this._callbacks.push(callback); + this._contexts.push(context); + }, + + /** + * Invokes all enqueued callbacks and clears the queue. This is invoked after + * the DOM representation of a component has been created or updated. + * + * @internal + */ + notifyAll: function() { + var callbacks = this._callbacks; + var contexts = this._contexts; + if (callbacks) { + ("production" !== process.env.NODE_ENV ? invariant( + callbacks.length === contexts.length, + "Mismatched list of contexts in callback queue" + ) : invariant(callbacks.length === contexts.length)); + this._callbacks = null; + this._contexts = null; + for (var i = 0, l = callbacks.length; i < l; i++) { + callbacks[i].call(contexts[i]); + } + callbacks.length = 0; + contexts.length = 0; + } + }, + + /** + * Resets the internal queue. + * + * @internal + */ + reset: function() { + this._callbacks = null; + this._contexts = null; + }, + + /** + * `PooledClass` looks for this. + */ + destructor: function() { + this.reset(); + } + +}); + +PooledClass.addPoolingTo(CallbackQueue); + +module.exports = CallbackQueue; + +}).call(this,require('_process')) +},{"./Object.assign":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/Object.assign.js","./PooledClass":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/PooledClass.js","./invariant":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/invariant.js","_process":"/Users/eden/mapbox/gl-draw/node_modules/watchify/node_modules/browserify/node_modules/process/browser.js"}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ChangeEventPlugin.js":[function(require,module,exports){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ChangeEventPlugin + */ + +"use strict"; + +var EventConstants = require("./EventConstants"); +var EventPluginHub = require("./EventPluginHub"); +var EventPropagators = require("./EventPropagators"); +var ExecutionEnvironment = require("./ExecutionEnvironment"); +var ReactUpdates = require("./ReactUpdates"); +var SyntheticEvent = require("./SyntheticEvent"); + +var isEventSupported = require("./isEventSupported"); +var isTextInputElement = require("./isTextInputElement"); +var keyOf = require("./keyOf"); + +var topLevelTypes = EventConstants.topLevelTypes; + +var eventTypes = { + change: { + phasedRegistrationNames: { + bubbled: keyOf({onChange: null}), + captured: keyOf({onChangeCapture: null}) + }, + dependencies: [ + topLevelTypes.topBlur, + topLevelTypes.topChange, + topLevelTypes.topClick, + topLevelTypes.topFocus, + topLevelTypes.topInput, + topLevelTypes.topKeyDown, + topLevelTypes.topKeyUp, + topLevelTypes.topSelectionChange + ] + } +}; + +/** + * For IE shims + */ +var activeElement = null; +var activeElementID = null; +var activeElementValue = null; +var activeElementValueProp = null; + +/** + * SECTION: handle `change` event + */ +function shouldUseChangeEvent(elem) { + return ( + elem.nodeName === 'SELECT' || + (elem.nodeName === 'INPUT' && elem.type === 'file') + ); +} + +var doesChangeEventBubble = false; +if (ExecutionEnvironment.canUseDOM) { + // See `handleChange` comment below + doesChangeEventBubble = isEventSupported('change') && ( + !('documentMode' in document) || document.documentMode > 8 + ); +} + +function manualDispatchChangeEvent(nativeEvent) { + var event = SyntheticEvent.getPooled( + eventTypes.change, + activeElementID, + nativeEvent + ); + EventPropagators.accumulateTwoPhaseDispatches(event); + + // If change and propertychange bubbled, we'd just bind to it like all the + // other events and have it go through ReactBrowserEventEmitter. Since it + // doesn't, we manually listen for the events and so we have to enqueue and + // process the abstract event manually. + // + // Batching is necessary here in order to ensure that all event handlers run + // before the next rerender (including event handlers attached to ancestor + // elements instead of directly on the input). Without this, controlled + // components don't work properly in conjunction with event bubbling because + // the component is rerendered and the value reverted before all the event + // handlers can run. See https://github.com/facebook/react/issues/708. + ReactUpdates.batchedUpdates(runEventInBatch, event); +} + +function runEventInBatch(event) { + EventPluginHub.enqueueEvents(event); + EventPluginHub.processEventQueue(); +} + +function startWatchingForChangeEventIE8(target, targetID) { + activeElement = target; + activeElementID = targetID; + activeElement.attachEvent('onchange', manualDispatchChangeEvent); +} + +function stopWatchingForChangeEventIE8() { + if (!activeElement) { + return; + } + activeElement.detachEvent('onchange', manualDispatchChangeEvent); + activeElement = null; + activeElementID = null; +} + +function getTargetIDForChangeEvent( + topLevelType, + topLevelTarget, + topLevelTargetID) { + if (topLevelType === topLevelTypes.topChange) { + return topLevelTargetID; + } +} +function handleEventsForChangeEventIE8( + topLevelType, + topLevelTarget, + topLevelTargetID) { + if (topLevelType === topLevelTypes.topFocus) { + // stopWatching() should be a noop here but we call it just in case we + // missed a blur event somehow. + stopWatchingForChangeEventIE8(); + startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID); + } else if (topLevelType === topLevelTypes.topBlur) { + stopWatchingForChangeEventIE8(); + } +} + + +/** + * SECTION: handle `input` event + */ +var isInputEventSupported = false; +if (ExecutionEnvironment.canUseDOM) { + // IE9 claims to support the input event but fails to trigger it when + // deleting text, so we ignore its input events + isInputEventSupported = isEventSupported('input') && ( + !('documentMode' in document) || document.documentMode > 9 + ); +} + +/** + * (For old IE.) Replacement getter/setter for the `value` property that gets + * set on the active element. + */ +var newValueProp = { + get: function() { + return activeElementValueProp.get.call(this); + }, + set: function(val) { + // Cast to a string so we can do equality checks. + activeElementValue = '' + val; + activeElementValueProp.set.call(this, val); + } +}; + +/** + * (For old IE.) Starts tracking propertychange events on the passed-in element + * and override the value property so that we can distinguish user events from + * value changes in JS. + */ +function startWatchingForValueChange(target, targetID) { + activeElement = target; + activeElementID = targetID; + activeElementValue = target.value; + activeElementValueProp = Object.getOwnPropertyDescriptor( + target.constructor.prototype, + 'value' + ); + + Object.defineProperty(activeElement, 'value', newValueProp); + activeElement.attachEvent('onpropertychange', handlePropertyChange); +} + +/** + * (For old IE.) Removes the event listeners from the currently-tracked element, + * if any exists. + */ +function stopWatchingForValueChange() { + if (!activeElement) { + return; + } + + // delete restores the original property definition + delete activeElement.value; + activeElement.detachEvent('onpropertychange', handlePropertyChange); + + activeElement = null; + activeElementID = null; + activeElementValue = null; + activeElementValueProp = null; +} + +/** + * (For old IE.) Handles a propertychange event, sending a `change` event if + * the value of the active element has changed. + */ +function handlePropertyChange(nativeEvent) { + if (nativeEvent.propertyName !== 'value') { + return; + } + var value = nativeEvent.srcElement.value; + if (value === activeElementValue) { + return; + } + activeElementValue = value; + + manualDispatchChangeEvent(nativeEvent); +} + +/** + * If a `change` event should be fired, returns the target's ID. + */ +function getTargetIDForInputEvent( + topLevelType, + topLevelTarget, + topLevelTargetID) { + if (topLevelType === topLevelTypes.topInput) { + // In modern browsers (i.e., not IE8 or IE9), the input event is exactly + // what we want so fall through here and trigger an abstract event + return topLevelTargetID; + } +} + +// For IE8 and IE9. +function handleEventsForInputEventIE( + topLevelType, + topLevelTarget, + topLevelTargetID) { + if (topLevelType === topLevelTypes.topFocus) { + // In IE8, we can capture almost all .value changes by adding a + // propertychange handler and looking for events with propertyName + // equal to 'value' + // In IE9, propertychange fires for most input events but is buggy and + // doesn't fire when text is deleted, but conveniently, selectionchange + // appears to fire in all of the remaining cases so we catch those and + // forward the event if the value has changed + // In either case, we don't want to call the event handler if the value + // is changed from JS so we redefine a setter for `.value` that updates + // our activeElementValue variable, allowing us to ignore those changes + // + // stopWatching() should be a noop here but we call it just in case we + // missed a blur event somehow. + stopWatchingForValueChange(); + startWatchingForValueChange(topLevelTarget, topLevelTargetID); + } else if (topLevelType === topLevelTypes.topBlur) { + stopWatchingForValueChange(); + } +} + +// For IE8 and IE9. +function getTargetIDForInputEventIE( + topLevelType, + topLevelTarget, + topLevelTargetID) { + if (topLevelType === topLevelTypes.topSelectionChange || + topLevelType === topLevelTypes.topKeyUp || + topLevelType === topLevelTypes.topKeyDown) { + // On the selectionchange event, the target is just document which isn't + // helpful for us so just check activeElement instead. + // + // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire + // propertychange on the first input event after setting `value` from a + // script and fires only keydown, keypress, keyup. Catching keyup usually + // gets it and catching keydown lets us fire an event for the first + // keystroke if user does a key repeat (it'll be a little delayed: right + // before the second keystroke). Other input methods (e.g., paste) seem to + // fire selectionchange normally. + if (activeElement && activeElement.value !== activeElementValue) { + activeElementValue = activeElement.value; + return activeElementID; + } + } +} + + +/** + * SECTION: handle `click` event + */ +function shouldUseClickEvent(elem) { + // Use the `click` event to detect changes to checkbox and radio inputs. + // This approach works across all browsers, whereas `change` does not fire + // until `blur` in IE8. + return ( + elem.nodeName === 'INPUT' && + (elem.type === 'checkbox' || elem.type === 'radio') + ); +} + +function getTargetIDForClickEvent( + topLevelType, + topLevelTarget, + topLevelTargetID) { + if (topLevelType === topLevelTypes.topClick) { + return topLevelTargetID; + } +} + +/** + * This plugin creates an `onChange` event that normalizes change events + * across form elements. This event fires at a time when it's possible to + * change the element's value without seeing a flicker. + * + * Supported elements are: + * - input (see `isTextInputElement`) + * - textarea + * - select + */ +var ChangeEventPlugin = { + + eventTypes: eventTypes, + + /** + * @param {string} topLevelType Record from `EventConstants`. + * @param {DOMEventTarget} topLevelTarget The listening component root node. + * @param {string} topLevelTargetID ID of `topLevelTarget`. + * @param {object} nativeEvent Native browser event. + * @return {*} An accumulation of synthetic events. + * @see {EventPluginHub.extractEvents} + */ + extractEvents: function( + topLevelType, + topLevelTarget, + topLevelTargetID, + nativeEvent) { + + var getTargetIDFunc, handleEventFunc; + if (shouldUseChangeEvent(topLevelTarget)) { + if (doesChangeEventBubble) { + getTargetIDFunc = getTargetIDForChangeEvent; + } else { + handleEventFunc = handleEventsForChangeEventIE8; + } + } else if (isTextInputElement(topLevelTarget)) { + if (isInputEventSupported) { + getTargetIDFunc = getTargetIDForInputEvent; + } else { + getTargetIDFunc = getTargetIDForInputEventIE; + handleEventFunc = handleEventsForInputEventIE; + } + } else if (shouldUseClickEvent(topLevelTarget)) { + getTargetIDFunc = getTargetIDForClickEvent; + } + + if (getTargetIDFunc) { + var targetID = getTargetIDFunc( + topLevelType, + topLevelTarget, + topLevelTargetID + ); + if (targetID) { + var event = SyntheticEvent.getPooled( + eventTypes.change, + targetID, + nativeEvent + ); + EventPropagators.accumulateTwoPhaseDispatches(event); + return event; + } + } + + if (handleEventFunc) { + handleEventFunc( + topLevelType, + topLevelTarget, + topLevelTargetID + ); + } + } + +}; + +module.exports = ChangeEventPlugin; + +},{"./EventConstants":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/EventConstants.js","./EventPluginHub":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/EventPluginHub.js","./EventPropagators":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/EventPropagators.js","./ExecutionEnvironment":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ExecutionEnvironment.js","./ReactUpdates":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactUpdates.js","./SyntheticEvent":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/SyntheticEvent.js","./isEventSupported":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/isEventSupported.js","./isTextInputElement":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/isTextInputElement.js","./keyOf":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/keyOf.js"}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ClientReactRootIndex.js":[function(require,module,exports){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ClientReactRootIndex + * @typechecks + */ + +"use strict"; + +var nextReactRootIndex = 0; + +var ClientReactRootIndex = { + createReactRootIndex: function() { + return nextReactRootIndex++; + } +}; + +module.exports = ClientReactRootIndex; + +},{}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/CompositionEventPlugin.js":[function(require,module,exports){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule CompositionEventPlugin + * @typechecks static-only + */ + +"use strict"; + +var EventConstants = require("./EventConstants"); +var EventPropagators = require("./EventPropagators"); +var ExecutionEnvironment = require("./ExecutionEnvironment"); +var ReactInputSelection = require("./ReactInputSelection"); +var SyntheticCompositionEvent = require("./SyntheticCompositionEvent"); + +var getTextContentAccessor = require("./getTextContentAccessor"); +var keyOf = require("./keyOf"); + +var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space +var START_KEYCODE = 229; + +var useCompositionEvent = ( + ExecutionEnvironment.canUseDOM && + 'CompositionEvent' in window +); + +// In IE9+, we have access to composition events, but the data supplied +// by the native compositionend event may be incorrect. In Korean, for example, +// the compositionend event contains only one character regardless of +// how many characters have been composed since compositionstart. +// We therefore use the fallback data while still using the native +// events as triggers. +var useFallbackData = ( + !useCompositionEvent || + ( + 'documentMode' in document && + document.documentMode > 8 && + document.documentMode <= 11 + ) +); + +var topLevelTypes = EventConstants.topLevelTypes; +var currentComposition = null; + +// Events and their corresponding property names. +var eventTypes = { + compositionEnd: { + phasedRegistrationNames: { + bubbled: keyOf({onCompositionEnd: null}), + captured: keyOf({onCompositionEndCapture: null}) + }, + dependencies: [ + topLevelTypes.topBlur, + topLevelTypes.topCompositionEnd, + topLevelTypes.topKeyDown, + topLevelTypes.topKeyPress, + topLevelTypes.topKeyUp, + topLevelTypes.topMouseDown + ] + }, + compositionStart: { + phasedRegistrationNames: { + bubbled: keyOf({onCompositionStart: null}), + captured: keyOf({onCompositionStartCapture: null}) + }, + dependencies: [ + topLevelTypes.topBlur, + topLevelTypes.topCompositionStart, + topLevelTypes.topKeyDown, + topLevelTypes.topKeyPress, + topLevelTypes.topKeyUp, + topLevelTypes.topMouseDown + ] + }, + compositionUpdate: { + phasedRegistrationNames: { + bubbled: keyOf({onCompositionUpdate: null}), + captured: keyOf({onCompositionUpdateCapture: null}) + }, + dependencies: [ + topLevelTypes.topBlur, + topLevelTypes.topCompositionUpdate, + topLevelTypes.topKeyDown, + topLevelTypes.topKeyPress, + topLevelTypes.topKeyUp, + topLevelTypes.topMouseDown + ] + } +}; + +/** + * Translate native top level events into event types. + * + * @param {string} topLevelType + * @return {object} + */ +function getCompositionEventType(topLevelType) { + switch (topLevelType) { + case topLevelTypes.topCompositionStart: + return eventTypes.compositionStart; + case topLevelTypes.topCompositionEnd: + return eventTypes.compositionEnd; + case topLevelTypes.topCompositionUpdate: + return eventTypes.compositionUpdate; + } +} + +/** + * Does our fallback best-guess model think this event signifies that + * composition has begun? + * + * @param {string} topLevelType + * @param {object} nativeEvent + * @return {boolean} + */ +function isFallbackStart(topLevelType, nativeEvent) { + return ( + topLevelType === topLevelTypes.topKeyDown && + nativeEvent.keyCode === START_KEYCODE + ); +} + +/** + * Does our fallback mode think that this event is the end of composition? + * + * @param {string} topLevelType + * @param {object} nativeEvent + * @return {boolean} + */ +function isFallbackEnd(topLevelType, nativeEvent) { + switch (topLevelType) { + case topLevelTypes.topKeyUp: + // Command keys insert or clear IME input. + return (END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1); + case topLevelTypes.topKeyDown: + // Expect IME keyCode on each keydown. If we get any other + // code we must have exited earlier. + return (nativeEvent.keyCode !== START_KEYCODE); + case topLevelTypes.topKeyPress: + case topLevelTypes.topMouseDown: + case topLevelTypes.topBlur: + // Events are not possible without cancelling IME. + return true; + default: + return false; + } +} + +/** + * Helper class stores information about selection and document state + * so we can figure out what changed at a later date. + * + * @param {DOMEventTarget} root + */ +function FallbackCompositionState(root) { + this.root = root; + this.startSelection = ReactInputSelection.getSelection(root); + this.startValue = this.getText(); +} + +/** + * Get current text of input. + * + * @return {string} + */ +FallbackCompositionState.prototype.getText = function() { + return this.root.value || this.root[getTextContentAccessor()]; +}; + +/** + * Text that has changed since the start of composition. + * + * @return {string} + */ +FallbackCompositionState.prototype.getData = function() { + var endValue = this.getText(); + var prefixLength = this.startSelection.start; + var suffixLength = this.startValue.length - this.startSelection.end; + + return endValue.substr( + prefixLength, + endValue.length - suffixLength - prefixLength + ); +}; + +/** + * This plugin creates `onCompositionStart`, `onCompositionUpdate` and + * `onCompositionEnd` events on inputs, textareas and contentEditable + * nodes. + */ +var CompositionEventPlugin = { + + eventTypes: eventTypes, + + /** + * @param {string} topLevelType Record from `EventConstants`. + * @param {DOMEventTarget} topLevelTarget The listening component root node. + * @param {string} topLevelTargetID ID of `topLevelTarget`. + * @param {object} nativeEvent Native browser event. + * @return {*} An accumulation of synthetic events. + * @see {EventPluginHub.extractEvents} + */ + extractEvents: function( + topLevelType, + topLevelTarget, + topLevelTargetID, + nativeEvent) { + + var eventType; + var data; + + if (useCompositionEvent) { + eventType = getCompositionEventType(topLevelType); + } else if (!currentComposition) { + if (isFallbackStart(topLevelType, nativeEvent)) { + eventType = eventTypes.compositionStart; + } + } else if (isFallbackEnd(topLevelType, nativeEvent)) { + eventType = eventTypes.compositionEnd; + } + + if (useFallbackData) { + // The current composition is stored statically and must not be + // overwritten while composition continues. + if (!currentComposition && eventType === eventTypes.compositionStart) { + currentComposition = new FallbackCompositionState(topLevelTarget); + } else if (eventType === eventTypes.compositionEnd) { + if (currentComposition) { + data = currentComposition.getData(); + currentComposition = null; + } + } + } + + if (eventType) { + var event = SyntheticCompositionEvent.getPooled( + eventType, + topLevelTargetID, + nativeEvent + ); + if (data) { + // Inject data generated from fallback path into the synthetic event. + // This matches the property of native CompositionEventInterface. + event.data = data; + } + EventPropagators.accumulateTwoPhaseDispatches(event); + return event; + } + } +}; + +module.exports = CompositionEventPlugin; + +},{"./EventConstants":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/EventConstants.js","./EventPropagators":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/EventPropagators.js","./ExecutionEnvironment":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ExecutionEnvironment.js","./ReactInputSelection":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactInputSelection.js","./SyntheticCompositionEvent":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/SyntheticCompositionEvent.js","./getTextContentAccessor":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/getTextContentAccessor.js","./keyOf":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/keyOf.js"}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/DOMChildrenOperations.js":[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule DOMChildrenOperations + * @typechecks static-only + */ + +"use strict"; + +var Danger = require("./Danger"); +var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes"); + +var getTextContentAccessor = require("./getTextContentAccessor"); +var invariant = require("./invariant"); + +/** + * The DOM property to use when setting text content. + * + * @type {string} + * @private + */ +var textContentAccessor = getTextContentAccessor(); + +/** + * Inserts `childNode` as a child of `parentNode` at the `index`. + * + * @param {DOMElement} parentNode Parent node in which to insert. + * @param {DOMElement} childNode Child node to insert. + * @param {number} index Index at which to insert the child. + * @internal + */ +function insertChildAt(parentNode, childNode, index) { + // By exploiting arrays returning `undefined` for an undefined index, we can + // rely exclusively on `insertBefore(node, null)` instead of also using + // `appendChild(node)`. However, using `undefined` is not allowed by all + // browsers so we must replace it with `null`. + parentNode.insertBefore( + childNode, + parentNode.childNodes[index] || null + ); +} + +var updateTextContent; +if (textContentAccessor === 'textContent') { + /** + * Sets the text content of `node` to `text`. + * + * @param {DOMElement} node Node to change + * @param {string} text New text content + */ + updateTextContent = function(node, text) { + node.textContent = text; + }; +} else { + /** + * Sets the text content of `node` to `text`. + * + * @param {DOMElement} node Node to change + * @param {string} text New text content + */ + updateTextContent = function(node, text) { + // In order to preserve newlines correctly, we can't use .innerText to set + // the contents (see #1080), so we empty the element then append a text node + while (node.firstChild) { + node.removeChild(node.firstChild); + } + if (text) { + var doc = node.ownerDocument || document; + node.appendChild(doc.createTextNode(text)); + } + }; +} + +/** + * Operations for updating with DOM children. + */ +var DOMChildrenOperations = { + + dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup, + + updateTextContent: updateTextContent, + + /** + * Updates a component's children by processing a series of updates. The + * update configurations are each expected to have a `parentNode` property. + * + * @param {array} updates List of update configurations. + * @param {array} markupList List of markup strings. + * @internal + */ + processUpdates: function(updates, markupList) { + var update; + // Mapping from parent IDs to initial child orderings. + var initialChildren = null; + // List of children that will be moved or removed. + var updatedChildren = null; + + for (var i = 0; update = updates[i]; i++) { + if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || + update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) { + var updatedIndex = update.fromIndex; + var updatedChild = update.parentNode.childNodes[updatedIndex]; + var parentID = update.parentID; + + ("production" !== process.env.NODE_ENV ? invariant( + updatedChild, + 'processUpdates(): Unable to find child %s of element. This ' + + 'probably means the DOM was unexpectedly mutated (e.g., by the ' + + 'browser), usually due to forgetting a when using tables, ' + + 'nesting tags like
,

, or , or using non-SVG elements '+ + 'in an parent. Try inspecting the child nodes of the element ' + + 'with React ID `%s`.', + updatedIndex, + parentID + ) : invariant(updatedChild)); + + initialChildren = initialChildren || {}; + initialChildren[parentID] = initialChildren[parentID] || []; + initialChildren[parentID][updatedIndex] = updatedChild; + + updatedChildren = updatedChildren || []; + updatedChildren.push(updatedChild); + } + } + + var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); + + // Remove updated children first so that `toIndex` is consistent. + if (updatedChildren) { + for (var j = 0; j < updatedChildren.length; j++) { + updatedChildren[j].parentNode.removeChild(updatedChildren[j]); + } + } + + for (var k = 0; update = updates[k]; k++) { + switch (update.type) { + case ReactMultiChildUpdateTypes.INSERT_MARKUP: + insertChildAt( + update.parentNode, + renderedMarkup[update.markupIndex], + update.toIndex + ); + break; + case ReactMultiChildUpdateTypes.MOVE_EXISTING: + insertChildAt( + update.parentNode, + initialChildren[update.parentID][update.fromIndex], + update.toIndex + ); + break; + case ReactMultiChildUpdateTypes.TEXT_CONTENT: + updateTextContent( + update.parentNode, + update.textContent + ); + break; + case ReactMultiChildUpdateTypes.REMOVE_NODE: + // Already removed by the for-loop above. + break; + } + } + } + +}; + +module.exports = DOMChildrenOperations; + +}).call(this,require('_process')) +},{"./Danger":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/Danger.js","./ReactMultiChildUpdateTypes":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactMultiChildUpdateTypes.js","./getTextContentAccessor":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/getTextContentAccessor.js","./invariant":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/invariant.js","_process":"/Users/eden/mapbox/gl-draw/node_modules/watchify/node_modules/browserify/node_modules/process/browser.js"}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/DOMProperty.js":[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule DOMProperty + * @typechecks static-only + */ + +/*jslint bitwise: true */ + +"use strict"; + +var invariant = require("./invariant"); + +function checkMask(value, bitmask) { + return (value & bitmask) === bitmask; +} + +var DOMPropertyInjection = { + /** + * Mapping from normalized, camelcased property names to a configuration that + * specifies how the associated DOM property should be accessed or rendered. + */ + MUST_USE_ATTRIBUTE: 0x1, + MUST_USE_PROPERTY: 0x2, + HAS_SIDE_EFFECTS: 0x4, + HAS_BOOLEAN_VALUE: 0x8, + HAS_NUMERIC_VALUE: 0x10, + HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10, + HAS_OVERLOADED_BOOLEAN_VALUE: 0x40, + + /** + * Inject some specialized knowledge about the DOM. This takes a config object + * with the following properties: + * + * isCustomAttribute: function that given an attribute name will return true + * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* + * attributes where it's impossible to enumerate all of the possible + * attribute names, + * + * Properties: object mapping DOM property name to one of the + * DOMPropertyInjection constants or null. If your attribute isn't in here, + * it won't get written to the DOM. + * + * DOMAttributeNames: object mapping React attribute name to the DOM + * attribute name. Attribute names not specified use the **lowercase** + * normalized name. + * + * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. + * Property names not specified use the normalized name. + * + * DOMMutationMethods: Properties that require special mutation methods. If + * `value` is undefined, the mutation method should unset the property. + * + * @param {object} domPropertyConfig the config as described above. + */ + injectDOMPropertyConfig: function(domPropertyConfig) { + var Properties = domPropertyConfig.Properties || {}; + var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; + var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; + var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; + + if (domPropertyConfig.isCustomAttribute) { + DOMProperty._isCustomAttributeFunctions.push( + domPropertyConfig.isCustomAttribute + ); + } + + for (var propName in Properties) { + ("production" !== process.env.NODE_ENV ? invariant( + !DOMProperty.isStandardName.hasOwnProperty(propName), + 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + + '\'%s\' which has already been injected. You may be accidentally ' + + 'injecting the same DOM property config twice, or you may be ' + + 'injecting two configs that have conflicting property names.', + propName + ) : invariant(!DOMProperty.isStandardName.hasOwnProperty(propName))); + + DOMProperty.isStandardName[propName] = true; + + var lowerCased = propName.toLowerCase(); + DOMProperty.getPossibleStandardName[lowerCased] = propName; + + if (DOMAttributeNames.hasOwnProperty(propName)) { + var attributeName = DOMAttributeNames[propName]; + DOMProperty.getPossibleStandardName[attributeName] = propName; + DOMProperty.getAttributeName[propName] = attributeName; + } else { + DOMProperty.getAttributeName[propName] = lowerCased; + } + + DOMProperty.getPropertyName[propName] = + DOMPropertyNames.hasOwnProperty(propName) ? + DOMPropertyNames[propName] : + propName; + + if (DOMMutationMethods.hasOwnProperty(propName)) { + DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName]; + } else { + DOMProperty.getMutationMethod[propName] = null; + } + + var propConfig = Properties[propName]; + DOMProperty.mustUseAttribute[propName] = + checkMask(propConfig, DOMPropertyInjection.MUST_USE_ATTRIBUTE); + DOMProperty.mustUseProperty[propName] = + checkMask(propConfig, DOMPropertyInjection.MUST_USE_PROPERTY); + DOMProperty.hasSideEffects[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_SIDE_EFFECTS); + DOMProperty.hasBooleanValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_BOOLEAN_VALUE); + DOMProperty.hasNumericValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_NUMERIC_VALUE); + DOMProperty.hasPositiveNumericValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE); + DOMProperty.hasOverloadedBooleanValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE); + + ("production" !== process.env.NODE_ENV ? invariant( + !DOMProperty.mustUseAttribute[propName] || + !DOMProperty.mustUseProperty[propName], + 'DOMProperty: Cannot require using both attribute and property: %s', + propName + ) : invariant(!DOMProperty.mustUseAttribute[propName] || + !DOMProperty.mustUseProperty[propName])); + ("production" !== process.env.NODE_ENV ? invariant( + DOMProperty.mustUseProperty[propName] || + !DOMProperty.hasSideEffects[propName], + 'DOMProperty: Properties that have side effects must use property: %s', + propName + ) : invariant(DOMProperty.mustUseProperty[propName] || + !DOMProperty.hasSideEffects[propName])); + ("production" !== process.env.NODE_ENV ? invariant( + !!DOMProperty.hasBooleanValue[propName] + + !!DOMProperty.hasNumericValue[propName] + + !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1, + 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + + 'numeric value, but not a combination: %s', + propName + ) : invariant(!!DOMProperty.hasBooleanValue[propName] + + !!DOMProperty.hasNumericValue[propName] + + !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1)); + } + } +}; +var defaultValueCache = {}; + +/** + * DOMProperty exports lookup objects that can be used like functions: + * + * > DOMProperty.isValid['id'] + * true + * > DOMProperty.isValid['foobar'] + * undefined + * + * Although this may be confusing, it performs better in general. + * + * @see http://jsperf.com/key-exists + * @see http://jsperf.com/key-missing + */ +var DOMProperty = { + + ID_ATTRIBUTE_NAME: 'data-reactid', + + /** + * Checks whether a property name is a standard property. + * @type {Object} + */ + isStandardName: {}, + + /** + * Mapping from lowercase property names to the properly cased version, used + * to warn in the case of missing properties. + * @type {Object} + */ + getPossibleStandardName: {}, + + /** + * Mapping from normalized names to attribute names that differ. Attribute + * names are used when rendering markup or with `*Attribute()`. + * @type {Object} + */ + getAttributeName: {}, + + /** + * Mapping from normalized names to properties on DOM node instances. + * (This includes properties that mutate due to external factors.) + * @type {Object} + */ + getPropertyName: {}, + + /** + * Mapping from normalized names to mutation methods. This will only exist if + * mutation cannot be set simply by the property or `setAttribute()`. + * @type {Object} + */ + getMutationMethod: {}, + + /** + * Whether the property must be accessed and mutated as an object property. + * @type {Object} + */ + mustUseAttribute: {}, + + /** + * Whether the property must be accessed and mutated using `*Attribute()`. + * (This includes anything that fails ` in `.) + * @type {Object} + */ + mustUseProperty: {}, + + /** + * Whether or not setting a value causes side effects such as triggering + * resources to be loaded or text selection changes. We must ensure that + * the value is only set if it has changed. + * @type {Object} + */ + hasSideEffects: {}, + + /** + * Whether the property should be removed when set to a falsey value. + * @type {Object} + */ + hasBooleanValue: {}, + + /** + * Whether the property must be numeric or parse as a + * numeric and should be removed when set to a falsey value. + * @type {Object} + */ + hasNumericValue: {}, + + /** + * Whether the property must be positive numeric or parse as a positive + * numeric and should be removed when set to a falsey value. + * @type {Object} + */ + hasPositiveNumericValue: {}, + + /** + * Whether the property can be used as a flag as well as with a value. Removed + * when strictly equal to false; present without a value when strictly equal + * to true; present with a value otherwise. + * @type {Object} + */ + hasOverloadedBooleanValue: {}, + + /** + * All of the isCustomAttribute() functions that have been injected. + */ + _isCustomAttributeFunctions: [], + + /** + * Checks whether a property name is a custom attribute. + * @method + */ + isCustomAttribute: function(attributeName) { + for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { + var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; + if (isCustomAttributeFn(attributeName)) { + return true; + } + } + return false; + }, + + /** + * Returns the default property value for a DOM property (i.e., not an + * attribute). Most default values are '' or false, but not all. Worse yet, + * some (in particular, `type`) vary depending on the type of element. + * + * TODO: Is it better to grab all the possible properties when creating an + * element to avoid having to create the same element twice? + */ + getDefaultValueForProperty: function(nodeName, prop) { + var nodeDefaults = defaultValueCache[nodeName]; + var testElement; + if (!nodeDefaults) { + defaultValueCache[nodeName] = nodeDefaults = {}; + } + if (!(prop in nodeDefaults)) { + testElement = document.createElement(nodeName); + nodeDefaults[prop] = testElement[prop]; + } + return nodeDefaults[prop]; + }, + + injection: DOMPropertyInjection +}; + +module.exports = DOMProperty; + +}).call(this,require('_process')) +},{"./invariant":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/invariant.js","_process":"/Users/eden/mapbox/gl-draw/node_modules/watchify/node_modules/browserify/node_modules/process/browser.js"}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/DOMPropertyOperations.js":[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule DOMPropertyOperations + * @typechecks static-only + */ + +"use strict"; + +var DOMProperty = require("./DOMProperty"); + +var escapeTextForBrowser = require("./escapeTextForBrowser"); +var memoizeStringOnly = require("./memoizeStringOnly"); +var warning = require("./warning"); + +function shouldIgnoreValue(name, value) { + return value == null || + (DOMProperty.hasBooleanValue[name] && !value) || + (DOMProperty.hasNumericValue[name] && isNaN(value)) || + (DOMProperty.hasPositiveNumericValue[name] && (value < 1)) || + (DOMProperty.hasOverloadedBooleanValue[name] && value === false); +} + +var processAttributeNameAndPrefix = memoizeStringOnly(function(name) { + return escapeTextForBrowser(name) + '="'; +}); + +if ("production" !== process.env.NODE_ENV) { + var reactProps = { + children: true, + dangerouslySetInnerHTML: true, + key: true, + ref: true + }; + var warnedProperties = {}; + + var warnUnknownProperty = function(name) { + if (reactProps.hasOwnProperty(name) && reactProps[name] || + warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { + return; + } + + warnedProperties[name] = true; + var lowerCasedName = name.toLowerCase(); + + // data-* attributes should be lowercase; suggest the lowercase version + var standardName = ( + DOMProperty.isCustomAttribute(lowerCasedName) ? + lowerCasedName : + DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? + DOMProperty.getPossibleStandardName[lowerCasedName] : + null + ); + + // For now, only warn when we have a suggested correction. This prevents + // logging too much when using transferPropsTo. + ("production" !== process.env.NODE_ENV ? warning( + standardName == null, + 'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?' + ) : null); + + }; +} + +/** + * Operations for dealing with DOM properties. + */ +var DOMPropertyOperations = { + + /** + * Creates markup for the ID property. + * + * @param {string} id Unescaped ID. + * @return {string} Markup string. + */ + createMarkupForID: function(id) { + return processAttributeNameAndPrefix(DOMProperty.ID_ATTRIBUTE_NAME) + + escapeTextForBrowser(id) + '"'; + }, + + /** + * Creates markup for a property. + * + * @param {string} name + * @param {*} value + * @return {?string} Markup string, or null if the property was invalid. + */ + createMarkupForProperty: function(name, value) { + if (DOMProperty.isStandardName.hasOwnProperty(name) && + DOMProperty.isStandardName[name]) { + if (shouldIgnoreValue(name, value)) { + return ''; + } + var attributeName = DOMProperty.getAttributeName[name]; + if (DOMProperty.hasBooleanValue[name] || + (DOMProperty.hasOverloadedBooleanValue[name] && value === true)) { + return escapeTextForBrowser(attributeName); + } + return processAttributeNameAndPrefix(attributeName) + + escapeTextForBrowser(value) + '"'; + } else if (DOMProperty.isCustomAttribute(name)) { + if (value == null) { + return ''; + } + return processAttributeNameAndPrefix(name) + + escapeTextForBrowser(value) + '"'; + } else if ("production" !== process.env.NODE_ENV) { + warnUnknownProperty(name); + } + return null; + }, + + /** + * Sets the value for a property on a node. + * + * @param {DOMElement} node + * @param {string} name + * @param {*} value + */ + setValueForProperty: function(node, name, value) { + if (DOMProperty.isStandardName.hasOwnProperty(name) && + DOMProperty.isStandardName[name]) { + var mutationMethod = DOMProperty.getMutationMethod[name]; + if (mutationMethod) { + mutationMethod(node, value); + } else if (shouldIgnoreValue(name, value)) { + this.deleteValueForProperty(node, name); + } else if (DOMProperty.mustUseAttribute[name]) { + // `setAttribute` with objects becomes only `[object]` in IE8/9, + // ('' + value) makes it output the correct toString()-value. + node.setAttribute(DOMProperty.getAttributeName[name], '' + value); + } else { + var propName = DOMProperty.getPropertyName[name]; + // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the + // property type before comparing; only `value` does and is string. + if (!DOMProperty.hasSideEffects[name] || + ('' + node[propName]) !== ('' + value)) { + // Contrary to `setAttribute`, object properties are properly + // `toString`ed by IE8/9. + node[propName] = value; + } + } + } else if (DOMProperty.isCustomAttribute(name)) { + if (value == null) { + node.removeAttribute(name); + } else { + node.setAttribute(name, '' + value); + } + } else if ("production" !== process.env.NODE_ENV) { + warnUnknownProperty(name); + } + }, + + /** + * Deletes the value for a property on a node. + * + * @param {DOMElement} node + * @param {string} name + */ + deleteValueForProperty: function(node, name) { + if (DOMProperty.isStandardName.hasOwnProperty(name) && + DOMProperty.isStandardName[name]) { + var mutationMethod = DOMProperty.getMutationMethod[name]; + if (mutationMethod) { + mutationMethod(node, undefined); + } else if (DOMProperty.mustUseAttribute[name]) { + node.removeAttribute(DOMProperty.getAttributeName[name]); + } else { + var propName = DOMProperty.getPropertyName[name]; + var defaultValue = DOMProperty.getDefaultValueForProperty( + node.nodeName, + propName + ); + if (!DOMProperty.hasSideEffects[name] || + ('' + node[propName]) !== defaultValue) { + node[propName] = defaultValue; + } + } + } else if (DOMProperty.isCustomAttribute(name)) { + node.removeAttribute(name); + } else if ("production" !== process.env.NODE_ENV) { + warnUnknownProperty(name); + } + } + +}; + +module.exports = DOMPropertyOperations; + +}).call(this,require('_process')) +},{"./DOMProperty":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/DOMProperty.js","./escapeTextForBrowser":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/escapeTextForBrowser.js","./memoizeStringOnly":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/memoizeStringOnly.js","./warning":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/warning.js","_process":"/Users/eden/mapbox/gl-draw/node_modules/watchify/node_modules/browserify/node_modules/process/browser.js"}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/Danger.js":[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule Danger + * @typechecks static-only + */ + +/*jslint evil: true, sub: true */ + +"use strict"; + +var ExecutionEnvironment = require("./ExecutionEnvironment"); + +var createNodesFromMarkup = require("./createNodesFromMarkup"); +var emptyFunction = require("./emptyFunction"); +var getMarkupWrap = require("./getMarkupWrap"); +var invariant = require("./invariant"); + +var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/; +var RESULT_INDEX_ATTR = 'data-danger-index'; + +/** + * Extracts the `nodeName` from a string of markup. + * + * NOTE: Extracting the `nodeName` does not require a regular expression match + * because we make assumptions about React-generated markup (i.e. there are no + * spaces surrounding the opening tag and there is at least one attribute). + * + * @param {string} markup String of markup. + * @return {string} Node name of the supplied markup. + * @see http://jsperf.com/extract-nodename + */ +function getNodeName(markup) { + return markup.substring(1, markup.indexOf(' ')); +} + +var Danger = { + + /** + * Renders markup into an array of nodes. The markup is expected to render + * into a list of root nodes. Also, the length of `resultList` and + * `markupList` should be the same. + * + * @param {array} markupList List of markup strings to render. + * @return {array} List of rendered nodes. + * @internal + */ + dangerouslyRenderMarkup: function(markupList) { + ("production" !== process.env.NODE_ENV ? invariant( + ExecutionEnvironment.canUseDOM, + 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + + 'thread. Make sure `window` and `document` are available globally ' + + 'before requiring React when unit testing or use ' + + 'React.renderToString for server rendering.' + ) : invariant(ExecutionEnvironment.canUseDOM)); + var nodeName; + var markupByNodeName = {}; + // Group markup by `nodeName` if a wrap is necessary, else by '*'. + for (var i = 0; i < markupList.length; i++) { + ("production" !== process.env.NODE_ENV ? invariant( + markupList[i], + 'dangerouslyRenderMarkup(...): Missing markup.' + ) : invariant(markupList[i])); + nodeName = getNodeName(markupList[i]); + nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; + markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; + markupByNodeName[nodeName][i] = markupList[i]; + } + var resultList = []; + var resultListAssignmentCount = 0; + for (nodeName in markupByNodeName) { + if (!markupByNodeName.hasOwnProperty(nodeName)) { + continue; + } + var markupListByNodeName = markupByNodeName[nodeName]; + + // This for-in loop skips the holes of the sparse array. The order of + // iteration should follow the order of assignment, which happens to match + // numerical index order, but we don't rely on that. + for (var resultIndex in markupListByNodeName) { + if (markupListByNodeName.hasOwnProperty(resultIndex)) { + var markup = markupListByNodeName[resultIndex]; + + // Push the requested markup with an additional RESULT_INDEX_ATTR + // attribute. If the markup does not start with a < character, it + // will be discarded below (with an appropriate console.error). + markupListByNodeName[resultIndex] = markup.replace( + OPEN_TAG_NAME_EXP, + // This index will be parsed back out below. + '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" ' + ); + } + } + + // Render each group of markup with similar wrapping `nodeName`. + var renderNodes = createNodesFromMarkup( + markupListByNodeName.join(''), + emptyFunction // Do nothing special with

; + * } + * }); + * + * The class specification supports a specific protocol of methods that have + * special meaning (e.g. `render`). See `ReactCompositeComponentInterface` for + * more the comprehensive protocol. Any other properties and methods in the + * class specification will available on the prototype. + * + * @interface ReactCompositeComponentInterface + * @internal + */ +var ReactCompositeComponentInterface = { + + /** + * An array of Mixin objects to include when defining your component. + * + * @type {array} + * @optional + */ + mixins: SpecPolicy.DEFINE_MANY, + + /** + * An object containing properties and methods that should be defined on + * the component's constructor instead of its prototype (static methods). + * + * @type {object} + * @optional + */ + statics: SpecPolicy.DEFINE_MANY, + + /** + * Definition of prop types for this component. + * + * @type {object} + * @optional + */ + propTypes: SpecPolicy.DEFINE_MANY, + + /** + * Definition of context types for this component. + * + * @type {object} + * @optional + */ + contextTypes: SpecPolicy.DEFINE_MANY, + + /** + * Definition of context types this component sets for its children. + * + * @type {object} + * @optional + */ + childContextTypes: SpecPolicy.DEFINE_MANY, + + // ==== Definition methods ==== + + /** + * Invoked when the component is mounted. Values in the mapping will be set on + * `this.props` if that prop is not specified (i.e. using an `in` check). + * + * This method is invoked before `getInitialState` and therefore cannot rely + * on `this.state` or use `this.setState`. + * + * @return {object} + * @optional + */ + getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED, + + /** + * Invoked once before the component is mounted. The return value will be used + * as the initial value of `this.state`. + * + * getInitialState: function() { + * return { + * isOn: false, + * fooBaz: new BazFoo() + * } + * } + * + * @return {object} + * @optional + */ + getInitialState: SpecPolicy.DEFINE_MANY_MERGED, + + /** + * @return {object} + * @optional + */ + getChildContext: SpecPolicy.DEFINE_MANY_MERGED, + + /** + * Uses props from `this.props` and state from `this.state` to render the + * structure of the component. + * + * No guarantees are made about when or how often this method is invoked, so + * it must not have side effects. + * + * render: function() { + * var name = this.props.name; + * return
Hello, {name}!
; + * } + * + * @return {ReactComponent} + * @nosideeffects + * @required + */ + render: SpecPolicy.DEFINE_ONCE, + + + + // ==== Delegate methods ==== + + /** + * Invoked when the component is initially created and about to be mounted. + * This may have side effects, but any external subscriptions or data created + * by this method must be cleaned up in `componentWillUnmount`. + * + * @optional + */ + componentWillMount: SpecPolicy.DEFINE_MANY, + + /** + * Invoked when the component has been mounted and has a DOM representation. + * However, there is no guarantee that the DOM node is in the document. + * + * Use this as an opportunity to operate on the DOM when the component has + * been mounted (initialized and rendered) for the first time. + * + * @param {DOMElement} rootNode DOM element representing the component. + * @optional + */ + componentDidMount: SpecPolicy.DEFINE_MANY, + + /** + * Invoked before the component receives new props. + * + * Use this as an opportunity to react to a prop transition by updating the + * state using `this.setState`. Current props are accessed via `this.props`. + * + * componentWillReceiveProps: function(nextProps, nextContext) { + * this.setState({ + * likesIncreasing: nextProps.likeCount > this.props.likeCount + * }); + * } + * + * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop + * transition may cause a state change, but the opposite is not true. If you + * need it, you are probably looking for `componentWillUpdate`. + * + * @param {object} nextProps + * @optional + */ + componentWillReceiveProps: SpecPolicy.DEFINE_MANY, + + /** + * Invoked while deciding if the component should be updated as a result of + * receiving new props, state and/or context. + * + * Use this as an opportunity to `return false` when you're certain that the + * transition to the new props/state/context will not require a component + * update. + * + * shouldComponentUpdate: function(nextProps, nextState, nextContext) { + * return !equal(nextProps, this.props) || + * !equal(nextState, this.state) || + * !equal(nextContext, this.context); + * } + * + * @param {object} nextProps + * @param {?object} nextState + * @param {?object} nextContext + * @return {boolean} True if the component should update. + * @optional + */ + shouldComponentUpdate: SpecPolicy.DEFINE_ONCE, + + /** + * Invoked when the component is about to update due to a transition from + * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState` + * and `nextContext`. + * + * Use this as an opportunity to perform preparation before an update occurs. + * + * NOTE: You **cannot** use `this.setState()` in this method. + * + * @param {object} nextProps + * @param {?object} nextState + * @param {?object} nextContext + * @param {ReactReconcileTransaction} transaction + * @optional + */ + componentWillUpdate: SpecPolicy.DEFINE_MANY, + + /** + * Invoked when the component's DOM representation has been updated. + * + * Use this as an opportunity to operate on the DOM when the component has + * been updated. + * + * @param {object} prevProps + * @param {?object} prevState + * @param {?object} prevContext + * @param {DOMElement} rootNode DOM element representing the component. + * @optional + */ + componentDidUpdate: SpecPolicy.DEFINE_MANY, + + /** + * Invoked when the component is about to be removed from its parent and have + * its DOM representation destroyed. + * + * Use this as an opportunity to deallocate any external resources. + * + * NOTE: There is no `componentDidUnmount` since your component will have been + * destroyed by that point. + * + * @optional + */ + componentWillUnmount: SpecPolicy.DEFINE_MANY, + + + + // ==== Advanced methods ==== + + /** + * Updates the component's currently mounted DOM representation. + * + * By default, this implements React's rendering and reconciliation algorithm. + * Sophisticated clients may wish to override this. + * + * @param {ReactReconcileTransaction} transaction + * @internal + * @overridable + */ + updateComponent: SpecPolicy.OVERRIDE_BASE + +}; + +/** + * Mapping from class specification keys to special processing functions. + * + * Although these are declared like instance properties in the specification + * when defining classes using `React.createClass`, they are actually static + * and are accessible on the constructor instead of the prototype. Despite + * being static, they must be defined outside of the "statics" key under + * which all other static methods are defined. + */ +var RESERVED_SPEC_KEYS = { + displayName: function(Constructor, displayName) { + Constructor.displayName = displayName; + }, + mixins: function(Constructor, mixins) { + if (mixins) { + for (var i = 0; i < mixins.length; i++) { + mixSpecIntoComponent(Constructor, mixins[i]); + } + } + }, + childContextTypes: function(Constructor, childContextTypes) { + validateTypeDef( + Constructor, + childContextTypes, + ReactPropTypeLocations.childContext + ); + Constructor.childContextTypes = assign( + {}, + Constructor.childContextTypes, + childContextTypes + ); + }, + contextTypes: function(Constructor, contextTypes) { + validateTypeDef( + Constructor, + contextTypes, + ReactPropTypeLocations.context + ); + Constructor.contextTypes = assign( + {}, + Constructor.contextTypes, + contextTypes + ); + }, + /** + * Special case getDefaultProps which should move into statics but requires + * automatic merging. + */ + getDefaultProps: function(Constructor, getDefaultProps) { + if (Constructor.getDefaultProps) { + Constructor.getDefaultProps = createMergedResultFunction( + Constructor.getDefaultProps, + getDefaultProps + ); + } else { + Constructor.getDefaultProps = getDefaultProps; + } + }, + propTypes: function(Constructor, propTypes) { + validateTypeDef( + Constructor, + propTypes, + ReactPropTypeLocations.prop + ); + Constructor.propTypes = assign( + {}, + Constructor.propTypes, + propTypes + ); + }, + statics: function(Constructor, statics) { + mixStaticSpecIntoComponent(Constructor, statics); + } +}; + +function getDeclarationErrorAddendum(component) { + var owner = component._owner || null; + if (owner && owner.constructor && owner.constructor.displayName) { + return ' Check the render method of `' + owner.constructor.displayName + + '`.'; + } + return ''; +} + +function validateTypeDef(Constructor, typeDef, location) { + for (var propName in typeDef) { + if (typeDef.hasOwnProperty(propName)) { + ("production" !== process.env.NODE_ENV ? invariant( + typeof typeDef[propName] == 'function', + '%s: %s type `%s` is invalid; it must be a function, usually from ' + + 'React.PropTypes.', + Constructor.displayName || 'ReactCompositeComponent', + ReactPropTypeLocationNames[location], + propName + ) : invariant(typeof typeDef[propName] == 'function')); + } + } +} + +function validateMethodOverride(proto, name) { + var specPolicy = ReactCompositeComponentInterface.hasOwnProperty(name) ? + ReactCompositeComponentInterface[name] : + null; + + // Disallow overriding of base class methods unless explicitly allowed. + if (ReactCompositeComponentMixin.hasOwnProperty(name)) { + ("production" !== process.env.NODE_ENV ? invariant( + specPolicy === SpecPolicy.OVERRIDE_BASE, + 'ReactCompositeComponentInterface: You are attempting to override ' + + '`%s` from your class specification. Ensure that your method names ' + + 'do not overlap with React methods.', + name + ) : invariant(specPolicy === SpecPolicy.OVERRIDE_BASE)); + } + + // Disallow defining methods more than once unless explicitly allowed. + if (proto.hasOwnProperty(name)) { + ("production" !== process.env.NODE_ENV ? invariant( + specPolicy === SpecPolicy.DEFINE_MANY || + specPolicy === SpecPolicy.DEFINE_MANY_MERGED, + 'ReactCompositeComponentInterface: You are attempting to define ' + + '`%s` on your component more than once. This conflict may be due ' + + 'to a mixin.', + name + ) : invariant(specPolicy === SpecPolicy.DEFINE_MANY || + specPolicy === SpecPolicy.DEFINE_MANY_MERGED)); + } +} + +function validateLifeCycleOnReplaceState(instance) { + var compositeLifeCycleState = instance._compositeLifeCycleState; + ("production" !== process.env.NODE_ENV ? invariant( + instance.isMounted() || + compositeLifeCycleState === CompositeLifeCycle.MOUNTING, + 'replaceState(...): Can only update a mounted or mounting component.' + ) : invariant(instance.isMounted() || + compositeLifeCycleState === CompositeLifeCycle.MOUNTING)); + ("production" !== process.env.NODE_ENV ? invariant( + ReactCurrentOwner.current == null, + 'replaceState(...): Cannot update during an existing state transition ' + + '(such as within `render`). Render methods should be a pure function ' + + 'of props and state.' + ) : invariant(ReactCurrentOwner.current == null)); + ("production" !== process.env.NODE_ENV ? invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING, + 'replaceState(...): Cannot update while unmounting component. This ' + + 'usually means you called setState() on an unmounted component.' + ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING)); +} + +/** + * Mixin helper which handles policy validation and reserved + * specification keys when building `ReactCompositeComponent` classses. + */ +function mixSpecIntoComponent(Constructor, spec) { + if (!spec) { + return; + } + + ("production" !== process.env.NODE_ENV ? invariant( + !ReactLegacyElement.isValidFactory(spec), + 'ReactCompositeComponent: You\'re attempting to ' + + 'use a component class as a mixin. Instead, just use a regular object.' + ) : invariant(!ReactLegacyElement.isValidFactory(spec))); + ("production" !== process.env.NODE_ENV ? invariant( + !ReactElement.isValidElement(spec), + 'ReactCompositeComponent: You\'re attempting to ' + + 'use a component as a mixin. Instead, just use a regular object.' + ) : invariant(!ReactElement.isValidElement(spec))); + + var proto = Constructor.prototype; + + // By handling mixins before any other properties, we ensure the same + // chaining order is applied to methods with DEFINE_MANY policy, whether + // mixins are listed before or after these methods in the spec. + if (spec.hasOwnProperty(MIXINS_KEY)) { + RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins); + } + + for (var name in spec) { + if (!spec.hasOwnProperty(name)) { + continue; + } + + if (name === MIXINS_KEY) { + // We have already handled mixins in a special case above + continue; + } + + var property = spec[name]; + validateMethodOverride(proto, name); + + if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) { + RESERVED_SPEC_KEYS[name](Constructor, property); + } else { + // Setup methods on prototype: + // The following member methods should not be automatically bound: + // 1. Expected ReactCompositeComponent methods (in the "interface"). + // 2. Overridden methods (that were mixed in). + var isCompositeComponentMethod = + ReactCompositeComponentInterface.hasOwnProperty(name); + var isAlreadyDefined = proto.hasOwnProperty(name); + var markedDontBind = property && property.__reactDontBind; + var isFunction = typeof property === 'function'; + var shouldAutoBind = + isFunction && + !isCompositeComponentMethod && + !isAlreadyDefined && + !markedDontBind; + + if (shouldAutoBind) { + if (!proto.__reactAutoBindMap) { + proto.__reactAutoBindMap = {}; + } + proto.__reactAutoBindMap[name] = property; + proto[name] = property; + } else { + if (isAlreadyDefined) { + var specPolicy = ReactCompositeComponentInterface[name]; + + // These cases should already be caught by validateMethodOverride + ("production" !== process.env.NODE_ENV ? invariant( + isCompositeComponentMethod && ( + specPolicy === SpecPolicy.DEFINE_MANY_MERGED || + specPolicy === SpecPolicy.DEFINE_MANY + ), + 'ReactCompositeComponent: Unexpected spec policy %s for key %s ' + + 'when mixing in component specs.', + specPolicy, + name + ) : invariant(isCompositeComponentMethod && ( + specPolicy === SpecPolicy.DEFINE_MANY_MERGED || + specPolicy === SpecPolicy.DEFINE_MANY + ))); + + // For methods which are defined more than once, call the existing + // methods before calling the new property, merging if appropriate. + if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) { + proto[name] = createMergedResultFunction(proto[name], property); + } else if (specPolicy === SpecPolicy.DEFINE_MANY) { + proto[name] = createChainedFunction(proto[name], property); + } + } else { + proto[name] = property; + if ("production" !== process.env.NODE_ENV) { + // Add verbose displayName to the function, which helps when looking + // at profiling tools. + if (typeof property === 'function' && spec.displayName) { + proto[name].displayName = spec.displayName + '_' + name; + } + } + } + } + } + } +} + +function mixStaticSpecIntoComponent(Constructor, statics) { + if (!statics) { + return; + } + for (var name in statics) { + var property = statics[name]; + if (!statics.hasOwnProperty(name)) { + continue; + } + + var isReserved = name in RESERVED_SPEC_KEYS; + ("production" !== process.env.NODE_ENV ? invariant( + !isReserved, + 'ReactCompositeComponent: You are attempting to define a reserved ' + + 'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' + + 'as an instance property instead; it will still be accessible on the ' + + 'constructor.', + name + ) : invariant(!isReserved)); + + var isInherited = name in Constructor; + ("production" !== process.env.NODE_ENV ? invariant( + !isInherited, + 'ReactCompositeComponent: You are attempting to define ' + + '`%s` on your component more than once. This conflict may be ' + + 'due to a mixin.', + name + ) : invariant(!isInherited)); + Constructor[name] = property; + } +} + +/** + * Merge two objects, but throw if both contain the same key. + * + * @param {object} one The first object, which is mutated. + * @param {object} two The second object + * @return {object} one after it has been mutated to contain everything in two. + */ +function mergeObjectsWithNoDuplicateKeys(one, two) { + ("production" !== process.env.NODE_ENV ? invariant( + one && two && typeof one === 'object' && typeof two === 'object', + 'mergeObjectsWithNoDuplicateKeys(): Cannot merge non-objects' + ) : invariant(one && two && typeof one === 'object' && typeof two === 'object')); + + mapObject(two, function(value, key) { + ("production" !== process.env.NODE_ENV ? invariant( + one[key] === undefined, + 'mergeObjectsWithNoDuplicateKeys(): ' + + 'Tried to merge two objects with the same key: `%s`. This conflict ' + + 'may be due to a mixin; in particular, this may be caused by two ' + + 'getInitialState() or getDefaultProps() methods returning objects ' + + 'with clashing keys.', + key + ) : invariant(one[key] === undefined)); + one[key] = value; + }); + return one; +} + +/** + * Creates a function that invokes two functions and merges their return values. + * + * @param {function} one Function to invoke first. + * @param {function} two Function to invoke second. + * @return {function} Function that invokes the two argument functions. + * @private + */ +function createMergedResultFunction(one, two) { + return function mergedResult() { + var a = one.apply(this, arguments); + var b = two.apply(this, arguments); + if (a == null) { + return b; + } else if (b == null) { + return a; + } + return mergeObjectsWithNoDuplicateKeys(a, b); + }; +} + +/** + * Creates a function that invokes two functions and ignores their return vales. + * + * @param {function} one Function to invoke first. + * @param {function} two Function to invoke second. + * @return {function} Function that invokes the two argument functions. + * @private + */ +function createChainedFunction(one, two) { + return function chainedFunction() { + one.apply(this, arguments); + two.apply(this, arguments); + }; +} + +/** + * `ReactCompositeComponent` maintains an auxiliary life cycle state in + * `this._compositeLifeCycleState` (which can be null). + * + * This is different from the life cycle state maintained by `ReactComponent` in + * `this._lifeCycleState`. The following diagram shows how the states overlap in + * time. There are times when the CompositeLifeCycle is null - at those times it + * is only meaningful to look at ComponentLifeCycle alone. + * + * Top Row: ReactComponent.ComponentLifeCycle + * Low Row: ReactComponent.CompositeLifeCycle + * + * +-------+---------------------------------+--------+ + * | UN | MOUNTED | UN | + * |MOUNTED| | MOUNTED| + * +-------+---------------------------------+--------+ + * | ^--------+ +-------+ +--------^ | + * | | | | | | | | + * | 0--|MOUNTING|-0-|RECEIVE|-0-| UN |--->0 | + * | | | |PROPS | |MOUNTING| | + * | | | | | | | | + * | | | | | | | | + * | +--------+ +-------+ +--------+ | + * | | | | + * +-------+---------------------------------+--------+ + */ +var CompositeLifeCycle = keyMirror({ + /** + * Components in the process of being mounted respond to state changes + * differently. + */ + MOUNTING: null, + /** + * Components in the process of being unmounted are guarded against state + * changes. + */ + UNMOUNTING: null, + /** + * Components that are mounted and receiving new props respond to state + * changes differently. + */ + RECEIVING_PROPS: null +}); + +/** + * @lends {ReactCompositeComponent.prototype} + */ +var ReactCompositeComponentMixin = { + + /** + * Base constructor for all composite component. + * + * @param {ReactElement} element + * @final + * @internal + */ + construct: function(element) { + // Children can be either an array or more than one argument + ReactComponent.Mixin.construct.apply(this, arguments); + ReactOwner.Mixin.construct.apply(this, arguments); + + this.state = null; + this._pendingState = null; + + // This is the public post-processed context. The real context and pending + // context lives on the element. + this.context = null; + + this._compositeLifeCycleState = null; + }, + + /** + * Checks whether or not this composite component is mounted. + * @return {boolean} True if mounted, false otherwise. + * @protected + * @final + */ + isMounted: function() { + return ReactComponent.Mixin.isMounted.call(this) && + this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING; + }, + + /** + * Initializes the component, renders markup, and registers event listeners. + * + * @param {string} rootID DOM ID of the root node. + * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction + * @param {number} mountDepth number of components in the owner hierarchy + * @return {?string} Rendered markup to be inserted into the DOM. + * @final + * @internal + */ + mountComponent: ReactPerf.measure( + 'ReactCompositeComponent', + 'mountComponent', + function(rootID, transaction, mountDepth) { + ReactComponent.Mixin.mountComponent.call( + this, + rootID, + transaction, + mountDepth + ); + this._compositeLifeCycleState = CompositeLifeCycle.MOUNTING; + + if (this.__reactAutoBindMap) { + this._bindAutoBindMethods(); + } + + this.context = this._processContext(this._currentElement._context); + this.props = this._processProps(this.props); + + this.state = this.getInitialState ? this.getInitialState() : null; + ("production" !== process.env.NODE_ENV ? invariant( + typeof this.state === 'object' && !Array.isArray(this.state), + '%s.getInitialState(): must return an object or null', + this.constructor.displayName || 'ReactCompositeComponent' + ) : invariant(typeof this.state === 'object' && !Array.isArray(this.state))); + + this._pendingState = null; + this._pendingForceUpdate = false; + + if (this.componentWillMount) { + this.componentWillMount(); + // When mounting, calls to `setState` by `componentWillMount` will set + // `this._pendingState` without triggering a re-render. + if (this._pendingState) { + this.state = this._pendingState; + this._pendingState = null; + } + } + + this._renderedComponent = instantiateReactComponent( + this._renderValidatedComponent(), + this._currentElement.type // The wrapping type + ); + + // Done with mounting, `setState` will now trigger UI changes. + this._compositeLifeCycleState = null; + var markup = this._renderedComponent.mountComponent( + rootID, + transaction, + mountDepth + 1 + ); + if (this.componentDidMount) { + transaction.getReactMountReady().enqueue(this.componentDidMount, this); + } + return markup; + } + ), + + /** + * Releases any resources allocated by `mountComponent`. + * + * @final + * @internal + */ + unmountComponent: function() { + this._compositeLifeCycleState = CompositeLifeCycle.UNMOUNTING; + if (this.componentWillUnmount) { + this.componentWillUnmount(); + } + this._compositeLifeCycleState = null; + + this._renderedComponent.unmountComponent(); + this._renderedComponent = null; + + ReactComponent.Mixin.unmountComponent.call(this); + + // Some existing components rely on this.props even after they've been + // destroyed (in event handlers). + // TODO: this.props = null; + // TODO: this.state = null; + }, + + /** + * Sets a subset of the state. Always use this or `replaceState` to mutate + * state. You should treat `this.state` as immutable. + * + * There is no guarantee that `this.state` will be immediately updated, so + * accessing `this.state` after calling this method may return the old value. + * + * There is no guarantee that calls to `setState` will run synchronously, + * as they may eventually be batched together. You can provide an optional + * callback that will be executed when the call to setState is actually + * completed. + * + * @param {object} partialState Next partial state to be merged with state. + * @param {?function} callback Called after state is updated. + * @final + * @protected + */ + setState: function(partialState, callback) { + ("production" !== process.env.NODE_ENV ? invariant( + typeof partialState === 'object' || partialState == null, + 'setState(...): takes an object of state variables to update.' + ) : invariant(typeof partialState === 'object' || partialState == null)); + if ("production" !== process.env.NODE_ENV){ + ("production" !== process.env.NODE_ENV ? warning( + partialState != null, + 'setState(...): You passed an undefined or null state object; ' + + 'instead, use forceUpdate().' + ) : null); + } + // Merge with `_pendingState` if it exists, otherwise with existing state. + this.replaceState( + assign({}, this._pendingState || this.state, partialState), + callback + ); + }, + + /** + * Replaces all of the state. Always use this or `setState` to mutate state. + * You should treat `this.state` as immutable. + * + * There is no guarantee that `this.state` will be immediately updated, so + * accessing `this.state` after calling this method may return the old value. + * + * @param {object} completeState Next state. + * @param {?function} callback Called after state is updated. + * @final + * @protected + */ + replaceState: function(completeState, callback) { + validateLifeCycleOnReplaceState(this); + this._pendingState = completeState; + if (this._compositeLifeCycleState !== CompositeLifeCycle.MOUNTING) { + // If we're in a componentWillMount handler, don't enqueue a rerender + // because ReactUpdates assumes we're in a browser context (which is wrong + // for server rendering) and we're about to do a render anyway. + // TODO: The callback here is ignored when setState is called from + // componentWillMount. Either fix it or disallow doing so completely in + // favor of getInitialState. + ReactUpdates.enqueueUpdate(this, callback); + } + }, + + /** + * Filters the context object to only contain keys specified in + * `contextTypes`, and asserts that they are valid. + * + * @param {object} context + * @return {?object} + * @private + */ + _processContext: function(context) { + var maskedContext = null; + var contextTypes = this.constructor.contextTypes; + if (contextTypes) { + maskedContext = {}; + for (var contextName in contextTypes) { + maskedContext[contextName] = context[contextName]; + } + if ("production" !== process.env.NODE_ENV) { + this._checkPropTypes( + contextTypes, + maskedContext, + ReactPropTypeLocations.context + ); + } + } + return maskedContext; + }, + + /** + * @param {object} currentContext + * @return {object} + * @private + */ + _processChildContext: function(currentContext) { + var childContext = this.getChildContext && this.getChildContext(); + var displayName = this.constructor.displayName || 'ReactCompositeComponent'; + if (childContext) { + ("production" !== process.env.NODE_ENV ? invariant( + typeof this.constructor.childContextTypes === 'object', + '%s.getChildContext(): childContextTypes must be defined in order to ' + + 'use getChildContext().', + displayName + ) : invariant(typeof this.constructor.childContextTypes === 'object')); + if ("production" !== process.env.NODE_ENV) { + this._checkPropTypes( + this.constructor.childContextTypes, + childContext, + ReactPropTypeLocations.childContext + ); + } + for (var name in childContext) { + ("production" !== process.env.NODE_ENV ? invariant( + name in this.constructor.childContextTypes, + '%s.getChildContext(): key "%s" is not defined in childContextTypes.', + displayName, + name + ) : invariant(name in this.constructor.childContextTypes)); + } + return assign({}, currentContext, childContext); + } + return currentContext; + }, + + /** + * Processes props by setting default values for unspecified props and + * asserting that the props are valid. Does not mutate its argument; returns + * a new props object with defaults merged in. + * + * @param {object} newProps + * @return {object} + * @private + */ + _processProps: function(newProps) { + if ("production" !== process.env.NODE_ENV) { + var propTypes = this.constructor.propTypes; + if (propTypes) { + this._checkPropTypes(propTypes, newProps, ReactPropTypeLocations.prop); + } + } + return newProps; + }, + + /** + * Assert that the props are valid + * + * @param {object} propTypes Map of prop name to a ReactPropType + * @param {object} props + * @param {string} location e.g. "prop", "context", "child context" + * @private + */ + _checkPropTypes: function(propTypes, props, location) { + // TODO: Stop validating prop types here and only use the element + // validation. + var componentName = this.constructor.displayName; + for (var propName in propTypes) { + if (propTypes.hasOwnProperty(propName)) { + var error = + propTypes[propName](props, propName, componentName, location); + if (error instanceof Error) { + // We may want to extend this logic for similar errors in + // renderComponent calls, so I'm abstracting it away into + // a function to minimize refactoring in the future + var addendum = getDeclarationErrorAddendum(this); + ("production" !== process.env.NODE_ENV ? warning(false, error.message + addendum) : null); + } + } + } + }, + + /** + * If any of `_pendingElement`, `_pendingState`, or `_pendingForceUpdate` + * is set, update the component. + * + * @param {ReactReconcileTransaction} transaction + * @internal + */ + performUpdateIfNecessary: function(transaction) { + var compositeLifeCycleState = this._compositeLifeCycleState; + // Do not trigger a state transition if we are in the middle of mounting or + // receiving props because both of those will already be doing this. + if (compositeLifeCycleState === CompositeLifeCycle.MOUNTING || + compositeLifeCycleState === CompositeLifeCycle.RECEIVING_PROPS) { + return; + } + + if (this._pendingElement == null && + this._pendingState == null && + !this._pendingForceUpdate) { + return; + } + + var nextContext = this.context; + var nextProps = this.props; + var nextElement = this._currentElement; + if (this._pendingElement != null) { + nextElement = this._pendingElement; + nextContext = this._processContext(nextElement._context); + nextProps = this._processProps(nextElement.props); + this._pendingElement = null; + + this._compositeLifeCycleState = CompositeLifeCycle.RECEIVING_PROPS; + if (this.componentWillReceiveProps) { + this.componentWillReceiveProps(nextProps, nextContext); + } + } + + this._compositeLifeCycleState = null; + + var nextState = this._pendingState || this.state; + this._pendingState = null; + + var shouldUpdate = + this._pendingForceUpdate || + !this.shouldComponentUpdate || + this.shouldComponentUpdate(nextProps, nextState, nextContext); + + if ("production" !== process.env.NODE_ENV) { + if (typeof shouldUpdate === "undefined") { + console.warn( + (this.constructor.displayName || 'ReactCompositeComponent') + + '.shouldComponentUpdate(): Returned undefined instead of a ' + + 'boolean value. Make sure to return true or false.' + ); + } + } + + if (shouldUpdate) { + this._pendingForceUpdate = false; + // Will set `this.props`, `this.state` and `this.context`. + this._performComponentUpdate( + nextElement, + nextProps, + nextState, + nextContext, + transaction + ); + } else { + // If it's determined that a component should not update, we still want + // to set props and state. + this._currentElement = nextElement; + this.props = nextProps; + this.state = nextState; + this.context = nextContext; + + // Owner cannot change because shouldUpdateReactComponent doesn't allow + // it. TODO: Remove this._owner completely. + this._owner = nextElement._owner; + } + }, + + /** + * Merges new props and state, notifies delegate methods of update and + * performs update. + * + * @param {ReactElement} nextElement Next element + * @param {object} nextProps Next public object to set as properties. + * @param {?object} nextState Next object to set as state. + * @param {?object} nextContext Next public object to set as context. + * @param {ReactReconcileTransaction} transaction + * @private + */ + _performComponentUpdate: function( + nextElement, + nextProps, + nextState, + nextContext, + transaction + ) { + var prevElement = this._currentElement; + var prevProps = this.props; + var prevState = this.state; + var prevContext = this.context; + + if (this.componentWillUpdate) { + this.componentWillUpdate(nextProps, nextState, nextContext); + } + + this._currentElement = nextElement; + this.props = nextProps; + this.state = nextState; + this.context = nextContext; + + // Owner cannot change because shouldUpdateReactComponent doesn't allow + // it. TODO: Remove this._owner completely. + this._owner = nextElement._owner; + + this.updateComponent( + transaction, + prevElement + ); + + if (this.componentDidUpdate) { + transaction.getReactMountReady().enqueue( + this.componentDidUpdate.bind(this, prevProps, prevState, prevContext), + this + ); + } + }, + + receiveComponent: function(nextElement, transaction) { + if (nextElement === this._currentElement && + nextElement._owner != null) { + // Since elements are immutable after the owner is rendered, + // we can do a cheap identity compare here to determine if this is a + // superfluous reconcile. It's possible for state to be mutable but such + // change should trigger an update of the owner which would recreate + // the element. We explicitly check for the existence of an owner since + // it's possible for a element created outside a composite to be + // deeply mutated and reused. + return; + } + + ReactComponent.Mixin.receiveComponent.call( + this, + nextElement, + transaction + ); + }, + + /** + * Updates the component's currently mounted DOM representation. + * + * By default, this implements React's rendering and reconciliation algorithm. + * Sophisticated clients may wish to override this. + * + * @param {ReactReconcileTransaction} transaction + * @param {ReactElement} prevElement + * @internal + * @overridable + */ + updateComponent: ReactPerf.measure( + 'ReactCompositeComponent', + 'updateComponent', + function(transaction, prevParentElement) { + ReactComponent.Mixin.updateComponent.call( + this, + transaction, + prevParentElement + ); + + var prevComponentInstance = this._renderedComponent; + var prevElement = prevComponentInstance._currentElement; + var nextElement = this._renderValidatedComponent(); + if (shouldUpdateReactComponent(prevElement, nextElement)) { + prevComponentInstance.receiveComponent(nextElement, transaction); + } else { + // These two IDs are actually the same! But nothing should rely on that. + var thisID = this._rootNodeID; + var prevComponentID = prevComponentInstance._rootNodeID; + prevComponentInstance.unmountComponent(); + this._renderedComponent = instantiateReactComponent( + nextElement, + this._currentElement.type + ); + var nextMarkup = this._renderedComponent.mountComponent( + thisID, + transaction, + this._mountDepth + 1 + ); + ReactComponent.BackendIDOperations.dangerouslyReplaceNodeWithMarkupByID( + prevComponentID, + nextMarkup + ); + } + } + ), + + /** + * Forces an update. This should only be invoked when it is known with + * certainty that we are **not** in a DOM transaction. + * + * You may want to call this when you know that some deeper aspect of the + * component's state has changed but `setState` was not called. + * + * This will not invoke `shouldUpdateComponent`, but it will invoke + * `componentWillUpdate` and `componentDidUpdate`. + * + * @param {?function} callback Called after update is complete. + * @final + * @protected + */ + forceUpdate: function(callback) { + var compositeLifeCycleState = this._compositeLifeCycleState; + ("production" !== process.env.NODE_ENV ? invariant( + this.isMounted() || + compositeLifeCycleState === CompositeLifeCycle.MOUNTING, + 'forceUpdate(...): Can only force an update on mounted or mounting ' + + 'components.' + ) : invariant(this.isMounted() || + compositeLifeCycleState === CompositeLifeCycle.MOUNTING)); + ("production" !== process.env.NODE_ENV ? invariant( + compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING && + ReactCurrentOwner.current == null, + 'forceUpdate(...): Cannot force an update while unmounting component ' + + 'or within a `render` function.' + ) : invariant(compositeLifeCycleState !== CompositeLifeCycle.UNMOUNTING && + ReactCurrentOwner.current == null)); + this._pendingForceUpdate = true; + ReactUpdates.enqueueUpdate(this, callback); + }, + + /** + * @private + */ + _renderValidatedComponent: ReactPerf.measure( + 'ReactCompositeComponent', + '_renderValidatedComponent', + function() { + var renderedComponent; + var previousContext = ReactContext.current; + ReactContext.current = this._processChildContext( + this._currentElement._context + ); + ReactCurrentOwner.current = this; + try { + renderedComponent = this.render(); + if (renderedComponent === null || renderedComponent === false) { + renderedComponent = ReactEmptyComponent.getEmptyComponent(); + ReactEmptyComponent.registerNullComponentID(this._rootNodeID); + } else { + ReactEmptyComponent.deregisterNullComponentID(this._rootNodeID); + } + } finally { + ReactContext.current = previousContext; + ReactCurrentOwner.current = null; + } + ("production" !== process.env.NODE_ENV ? invariant( + ReactElement.isValidElement(renderedComponent), + '%s.render(): A valid ReactComponent must be returned. You may have ' + + 'returned undefined, an array or some other invalid object.', + this.constructor.displayName || 'ReactCompositeComponent' + ) : invariant(ReactElement.isValidElement(renderedComponent))); + return renderedComponent; + } + ), + + /** + * @private + */ + _bindAutoBindMethods: function() { + for (var autoBindKey in this.__reactAutoBindMap) { + if (!this.__reactAutoBindMap.hasOwnProperty(autoBindKey)) { + continue; + } + var method = this.__reactAutoBindMap[autoBindKey]; + this[autoBindKey] = this._bindAutoBindMethod(ReactErrorUtils.guard( + method, + this.constructor.displayName + '.' + autoBindKey + )); + } + }, + + /** + * Binds a method to the component. + * + * @param {function} method Method to be bound. + * @private + */ + _bindAutoBindMethod: function(method) { + var component = this; + var boundMethod = method.bind(component); + if ("production" !== process.env.NODE_ENV) { + boundMethod.__reactBoundContext = component; + boundMethod.__reactBoundMethod = method; + boundMethod.__reactBoundArguments = null; + var componentName = component.constructor.displayName; + var _bind = boundMethod.bind; + boundMethod.bind = function(newThis ) {for (var args=[],$__0=1,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); + // User is trying to bind() an autobound method; we effectively will + // ignore the value of "this" that the user is trying to use, so + // let's warn. + if (newThis !== component && newThis !== null) { + monitorCodeUse('react_bind_warning', { component: componentName }); + console.warn( + 'bind(): React component methods may only be bound to the ' + + 'component instance. See ' + componentName + ); + } else if (!args.length) { + monitorCodeUse('react_bind_warning', { component: componentName }); + console.warn( + 'bind(): You are binding a component method to the component. ' + + 'React does this for you automatically in a high-performance ' + + 'way, so you can safely remove this call. See ' + componentName + ); + return boundMethod; + } + var reboundMethod = _bind.apply(boundMethod, arguments); + reboundMethod.__reactBoundContext = component; + reboundMethod.__reactBoundMethod = method; + reboundMethod.__reactBoundArguments = args; + return reboundMethod; + }; + } + return boundMethod; + } +}; + +var ReactCompositeComponentBase = function() {}; +assign( + ReactCompositeComponentBase.prototype, + ReactComponent.Mixin, + ReactOwner.Mixin, + ReactPropTransferer.Mixin, + ReactCompositeComponentMixin +); + +/** + * Module for creating composite components. + * + * @class ReactCompositeComponent + * @extends ReactComponent + * @extends ReactOwner + * @extends ReactPropTransferer + */ +var ReactCompositeComponent = { + + LifeCycle: CompositeLifeCycle, + + Base: ReactCompositeComponentBase, + + /** + * Creates a composite component class given a class specification. + * + * @param {object} spec Class specification (which must define `render`). + * @return {function} Component constructor function. + * @public + */ + createClass: function(spec) { + var Constructor = function(props) { + // This constructor is overridden by mocks. The argument is used + // by mocks to assert on what gets mounted. This will later be used + // by the stand-alone class implementation. + }; + Constructor.prototype = new ReactCompositeComponentBase(); + Constructor.prototype.constructor = Constructor; + + injectedMixins.forEach( + mixSpecIntoComponent.bind(null, Constructor) + ); + + mixSpecIntoComponent(Constructor, spec); + + // Initialize the defaultProps property after all mixins have been merged + if (Constructor.getDefaultProps) { + Constructor.defaultProps = Constructor.getDefaultProps(); + } + + ("production" !== process.env.NODE_ENV ? invariant( + Constructor.prototype.render, + 'createClass(...): Class specification must implement a `render` method.' + ) : invariant(Constructor.prototype.render)); + + if ("production" !== process.env.NODE_ENV) { + if (Constructor.prototype.componentShouldUpdate) { + monitorCodeUse( + 'react_component_should_update_warning', + { component: spec.displayName } + ); + console.warn( + (spec.displayName || 'A component') + ' has a method called ' + + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + + 'The name is phrased as a question because the function is ' + + 'expected to return a value.' + ); + } + } + + // Reduce time spent doing lookups by setting these on the prototype. + for (var methodName in ReactCompositeComponentInterface) { + if (!Constructor.prototype[methodName]) { + Constructor.prototype[methodName] = null; + } + } + + if ("production" !== process.env.NODE_ENV) { + return ReactLegacyElement.wrapFactory( + ReactElementValidator.createFactory(Constructor) + ); + } + return ReactLegacyElement.wrapFactory( + ReactElement.createFactory(Constructor) + ); + }, + + injection: { + injectMixin: function(mixin) { + injectedMixins.push(mixin); + } + } +}; + +module.exports = ReactCompositeComponent; + +}).call(this,require('_process')) +},{"./Object.assign":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/Object.assign.js","./ReactComponent":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactComponent.js","./ReactContext":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactContext.js","./ReactCurrentOwner":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactCurrentOwner.js","./ReactElement":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactElement.js","./ReactElementValidator":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactElementValidator.js","./ReactEmptyComponent":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactEmptyComponent.js","./ReactErrorUtils":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactErrorUtils.js","./ReactLegacyElement":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactLegacyElement.js","./ReactOwner":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactOwner.js","./ReactPerf":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactPerf.js","./ReactPropTransferer":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactPropTransferer.js","./ReactPropTypeLocationNames":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactPropTypeLocationNames.js","./ReactPropTypeLocations":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactPropTypeLocations.js","./ReactUpdates":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactUpdates.js","./instantiateReactComponent":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/instantiateReactComponent.js","./invariant":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/invariant.js","./keyMirror":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/keyMirror.js","./keyOf":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/keyOf.js","./mapObject":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/mapObject.js","./monitorCodeUse":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/monitorCodeUse.js","./shouldUpdateReactComponent":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/shouldUpdateReactComponent.js","./warning":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/warning.js","_process":"/Users/eden/mapbox/gl-draw/node_modules/watchify/node_modules/browserify/node_modules/process/browser.js"}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactContext.js":[function(require,module,exports){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactContext + */ + +"use strict"; + +var assign = require("./Object.assign"); + +/** + * Keeps track of the current context. + * + * The context is automatically passed down the component ownership hierarchy + * and is accessible via `this.context` on ReactCompositeComponents. + */ +var ReactContext = { + + /** + * @internal + * @type {object} + */ + current: {}, + + /** + * Temporarily extends the current context while executing scopedCallback. + * + * A typical use case might look like + * + * render: function() { + * var children = ReactContext.withContext({foo: 'foo'}, () => ( + * + * )); + * return
{children}
; + * } + * + * @param {object} newContext New context to merge into the existing context + * @param {function} scopedCallback Callback to run with the new context + * @return {ReactComponent|array} + */ + withContext: function(newContext, scopedCallback) { + var result; + var previousContext = ReactContext.current; + ReactContext.current = assign({}, previousContext, newContext); + try { + result = scopedCallback(); + } finally { + ReactContext.current = previousContext; + } + return result; + } + +}; + +module.exports = ReactContext; + +},{"./Object.assign":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/Object.assign.js"}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactCurrentOwner.js":[function(require,module,exports){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactCurrentOwner + */ + +"use strict"; + +/** + * Keeps track of the current owner. + * + * The current owner is the component who should own any components that are + * currently being constructed. + * + * The depth indicate how many composite components are above this render level. + */ +var ReactCurrentOwner = { + + /** + * @internal + * @type {ReactComponent} + */ + current: null + +}; + +module.exports = ReactCurrentOwner; + +},{}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactDOM.js":[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactDOM + * @typechecks static-only + */ + +"use strict"; + +var ReactElement = require("./ReactElement"); +var ReactElementValidator = require("./ReactElementValidator"); +var ReactLegacyElement = require("./ReactLegacyElement"); + +var mapObject = require("./mapObject"); + +/** + * Create a factory that creates HTML tag elements. + * + * @param {string} tag Tag name (e.g. `div`). + * @private + */ +function createDOMFactory(tag) { + if ("production" !== process.env.NODE_ENV) { + return ReactLegacyElement.markNonLegacyFactory( + ReactElementValidator.createFactory(tag) + ); + } + return ReactLegacyElement.markNonLegacyFactory( + ReactElement.createFactory(tag) + ); +} + +/** + * Creates a mapping from supported HTML tags to `ReactDOMComponent` classes. + * This is also accessible via `React.DOM`. + * + * @public + */ +var ReactDOM = mapObject({ + a: 'a', + abbr: 'abbr', + address: 'address', + area: 'area', + article: 'article', + aside: 'aside', + audio: 'audio', + b: 'b', + base: 'base', + bdi: 'bdi', + bdo: 'bdo', + big: 'big', + blockquote: 'blockquote', + body: 'body', + br: 'br', + button: 'button', + canvas: 'canvas', + caption: 'caption', + cite: 'cite', + code: 'code', + col: 'col', + colgroup: 'colgroup', + data: 'data', + datalist: 'datalist', + dd: 'dd', + del: 'del', + details: 'details', + dfn: 'dfn', + dialog: 'dialog', + div: 'div', + dl: 'dl', + dt: 'dt', + em: 'em', + embed: 'embed', + fieldset: 'fieldset', + figcaption: 'figcaption', + figure: 'figure', + footer: 'footer', + form: 'form', + h1: 'h1', + h2: 'h2', + h3: 'h3', + h4: 'h4', + h5: 'h5', + h6: 'h6', + head: 'head', + header: 'header', + hr: 'hr', + html: 'html', + i: 'i', + iframe: 'iframe', + img: 'img', + input: 'input', + ins: 'ins', + kbd: 'kbd', + keygen: 'keygen', + label: 'label', + legend: 'legend', + li: 'li', + link: 'link', + main: 'main', + map: 'map', + mark: 'mark', + menu: 'menu', + menuitem: 'menuitem', + meta: 'meta', + meter: 'meter', + nav: 'nav', + noscript: 'noscript', + object: 'object', + ol: 'ol', + optgroup: 'optgroup', + option: 'option', + output: 'output', + p: 'p', + param: 'param', + picture: 'picture', + pre: 'pre', + progress: 'progress', + q: 'q', + rp: 'rp', + rt: 'rt', + ruby: 'ruby', + s: 's', + samp: 'samp', + script: 'script', + section: 'section', + select: 'select', + small: 'small', + source: 'source', + span: 'span', + strong: 'strong', + style: 'style', + sub: 'sub', + summary: 'summary', + sup: 'sup', + table: 'table', + tbody: 'tbody', + td: 'td', + textarea: 'textarea', + tfoot: 'tfoot', + th: 'th', + thead: 'thead', + time: 'time', + title: 'title', + tr: 'tr', + track: 'track', + u: 'u', + ul: 'ul', + 'var': 'var', + video: 'video', + wbr: 'wbr', + + // SVG + circle: 'circle', + defs: 'defs', + ellipse: 'ellipse', + g: 'g', + line: 'line', + linearGradient: 'linearGradient', + mask: 'mask', + path: 'path', + pattern: 'pattern', + polygon: 'polygon', + polyline: 'polyline', + radialGradient: 'radialGradient', + rect: 'rect', + stop: 'stop', + svg: 'svg', + text: 'text', + tspan: 'tspan' + +}, createDOMFactory); + +module.exports = ReactDOM; + +}).call(this,require('_process')) +},{"./ReactElement":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactElement.js","./ReactElementValidator":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactElementValidator.js","./ReactLegacyElement":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactLegacyElement.js","./mapObject":"/Users/eden/mapbox/gl-draw/node_modules/react/lib/mapObject.js","_process":"/Users/eden/mapbox/gl-draw/node_modules/watchify/node_modules/browserify/node_modules/process/browser.js"}],"/Users/eden/mapbox/gl-draw/node_modules/react/lib/ReactDOMButton.js":[function(require,module,exports){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + * @providesModule ReactDOMButton + */ + +"use strict"; + +var AutoFocusMixin = require("./AutoFocusMixin"); +var ReactBrowserComponentMixin = require("./ReactBrowserComponentMixin"); +var ReactCompositeComponent = require("./ReactCompositeComponent"); +var ReactElement = require("./ReactElement"); +var ReactDOM = require("./ReactDOM"); + +var keyMirror = require("./keyMirror"); + +// Store a reference to the