diff --git a/dist/omniscient.js b/dist/omniscient.js index 8c1ac08..849cd80 100644 --- a/dist/omniscient.js +++ b/dist/omniscient.js @@ -1,32 +1,141 @@ /** -* Omniscient.js v3.0.1 +* Omniscient.js v3.1.0 * Authors: @torgeir,@mikaelbr ***************************************/ !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var n;"undefined"!=typeof window?n=window:"undefined"!=typeof global?n=global:"undefined"!=typeof self&&(n=self),n.omniscient=e()}}(function(){var define,module,exports;return (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;oHello! + * }); + * React.render(, document.body); + * ``` + * + * #### Un-wrapping curors + * ```jsx + * var localComponent = component.withDefaults({ + * cursorField: 'foobar' + * }); + * + * var Component = localComponent(function (myCursor) { + * // Now you have myCursor directly instead of having to do props.foobar + * }); + * + * React.render(, document.body); + * ``` + * + * @param {Object} Options Options with defaults to override + * + * @property {Function} shouldComponentUpdate Get default shouldComponentUpdate + + * @module omniscient.withDefaults + * @returns {Component} + * @api public + */ module.exports.withDefaults = factory; + function factory (options) { var debug; options = options || {}; - var _shouldComponentUpdate = options.shouldComponentUpdate; + var _shouldComponentUpdate = options.shouldComponentUpdate || + shouldComponentUpdate.withDefaults(options); var _isCursor = options.isCursor || shouldComponentUpdate.isCursor; var _isImmutable = options.isImmutable || shouldComponentUpdate.isImmutable; var _isJsx = !!options.jsx; + var _hiddenCursorField = options.cursorField || '__singleCursor'; + var _isNode = options.isNode || isNode; + var _cached = cached.withDefaults(_shouldComponentUpdate); - if (!_shouldComponentUpdate) { - _shouldComponentUpdate = shouldComponentUpdate.withDefaults(options); - } + /** + * Activate debugging for components. Will log when a component renders, + * the outcome of `shouldComponentUpdate`, and why the component re-renders. + * + * ### Example + * ```js + * Search>: shouldComponentUpdate => true (cursors have changed) + * Search>: render + * SearchBox>: shouldComponentUpdate => true (cursors have changed) + * SearchBox>: render + * ``` + * + * @example omniscient.debug(/Search/i); + * + * @param {RegExp} pattern Filter pattern. Only show messages matching pattern + * + * @property {Object} jsx Get component for use in JSX + * + * @module omniscient.debug + * @returns {Immstruct} + * @api public + */ ComponentCreator.debug = debugFn; + ComponentCreator.cached = _cached; ComponentCreator.shouldComponentUpdate = _shouldComponentUpdate; return ComponentCreator; @@ -39,9 +148,10 @@ function factory (options) { mixins: options.mixins, render: function render () { if (debug) debug.call(this, 'render'); - // If `props[cursor]` is defined than it's just boxed cursor - // in which case we unbox it. - var input = this.props[hiddenCursorField] || this.props; + // If `props['__singleCursor']` is set a single cursor was passed + // to the component, pick it out and pass it. + var input = this.props[_hiddenCursorField] || this.props; + this.cursor = this.props[_hiddenCursorField]; return options.render.call(this, input, this.props.statics); } }; @@ -56,9 +166,24 @@ function factory (options) { return Component; } + /** + * Invoke component (rendering it) + * + * @param {String} displayName Component display name. Used in debug and by React + * @param {Object} props Properties that **do** trigger update when changed. Can be cursors, object and immutable structures + * @param {Object} statics Properties that do not trigger update when changed. Can be cursors, object and immutable structuress + * @param {Object} ..rest Child components (React elements, scalar values) + * + * @property {Object} jsx Get component for use in JSX + + * @module Component + * @returns {ReactElement} + * @api public + */ var create = function (key, props, statics) { + var _props; var inputCursor; - var children = toArray(arguments).filter(React.isValidElement); + var children; if (typeof key === 'object') { statics = props; @@ -66,47 +191,49 @@ function factory (options) { key = void 0; } - if (!props) { - props = { }; - } + children = flatten(sliceFrom(arguments, statics).filter(_isNode)); - // If passed props is just a cursor we box it by making - // props with `props[hiddenCursorField]` set to given `props` so that - // render will know how to unbox it. Note that __singleCursor proprety - // name is used to make sure that render won't unbox props in case user - // passed on with conflicting proprety name. + // If passed props is a signle cursor we move it to `props[_hiddenCursorField]` + // to simplify should component update. The render function will move it back. + // The name '__singleCursor' is used to not clash with names of user passed properties if (_isCursor(props) || _isImmutable(props)) { inputCursor = props; - props = {}; - props[hiddenCursorField] = inputCursor; + _props = {}; + _props[_hiddenCursorField] = inputCursor; + } else { + _props = assign({}, props); } - if (!!statics && !props.statics) { - props.statics = statics; + // If statics is a node (due to it being optional) + // don't attach the node to the statics prop + if (!!statics && !props.statics && !_isNode(statics)) { + _props.statics = statics; } if (key) { - props.key = key; + _props.key = key; } if (!!children.length) { - props.children = children; + _props.children = children; } - return React.createElement(Component, props); + return React.createElement(Component, _props); }; create.jsx = Component; if (methodStatics) { - create = extend(create, methodStatics); + create = assign(create, methodStatics); } return create; } function debugFn (pattern, logFn) { - debug = shouldComponentUpdate.withDefaults().debug(pattern, logFn); + if (_shouldComponentUpdate.debug) { + debug = _shouldComponentUpdate.debug(pattern, logFn); + } } function createDefaultArguments (displayName, mixins, render) { @@ -137,10 +264,14 @@ function factory (options) { mixins = [mixins]; } + // Add built-in lifetime methods to keep `statics` up to date. + mixins.unshift(componentWillMount.asMixin, + componentWillReceiveProps.asMixin); + if (!hasShouldComponentUpdate(mixins)) { - mixins = [{ + mixins.unshift({ shouldComponentUpdate: _shouldComponentUpdate - }].concat(mixins); + }); } return { @@ -162,7 +293,7 @@ function pickStaticMixins (mixins) { var statics = {}; filtered.forEach(function (obj) { - statics = extend(statics, obj.statics); + statics = assign(statics, obj.statics); }); return statics; @@ -186,25 +317,184 @@ function toArray (args) { return Array.prototype.slice.call(args); } -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{"./shouldupdate":22,"extend-object":2}],2:[function(_dereq_,module,exports){ -var arr = []; -var each = arr.forEach; -var slice = arr.slice; - - -module.exports = function(obj) { - each.call(slice.call(arguments, 1), function(source) { - if (source) { - for (var prop in source) { - obj[prop] = source[prop]; - } +function sliceFrom (args, value) { + var array = toArray(args); + var index = Math.max(array.indexOf(value), 0); + return array.slice(index); +} + +// Just a shallow flatten +function flatten (array) { + return Array.prototype.concat.apply([], array); +} + +/** + * Predicate showing whether or not the argument is a valid React Node + * or not. Can be numbers, strings, bools, and React Elements. + * + * React's isNode check from ReactPropTypes validator + * but adjusted to not accept objects to avoid collision with props & statics. + * + * @param {String} propValue Property value to check if is valid React Node + * + * @returns {Boolean} + * @api private + */ +function isNode (propValue) { + switch (typeof propValue) { + case 'number': + case 'string': + return true; + case 'boolean': + return !propValue; + case 'object': + if (Array.isArray(propValue)) { + return propValue.every(isNode); + } + if (React.isValidElement(propValue)) { + return true; + } + return false; + default: + return false; + } +} + +function delegate(delegee) { + var delegate = function() { + return delegate.delegee.apply(this, arguments); + } + delegate.delegee = delegee; + delegate.isDelegate = true; + return delegate; +} + +function wrapWithDelegate (key) { + var statics = this; + var delegee = statics[key]; + if (typeof delegee === 'function') { + statics[key] = isDelegate(delegee) ? delegee : delegate(delegee); + } +} + +function isDelegate (value) { + return value && value.isDelegate; +} + +function componentWillMount () { + var statics = this.props.statics; + if (statics && typeof statics === 'object') { + Object.keys(statics).forEach(wrapWithDelegate, statics); + } +} +// `asMixin` will let us reuse same objcet instead of re-creating +// it per each component. +componentWillMount.asMixin = { + componentWillMount: componentWillMount +}; + +function componentWillReceiveProps (newProps) { + var currentProps = this.props; + var currentStatics = currentProps.statics; + var newStatics = newProps.statics; + var haveChangedStatics = newStatics !== currentStatics && + newStatics && + typeof newStatics === 'object'; + + if (haveChangedStatics) { + Object.keys(newStatics).forEach(function(key) { + var newMember = newStatics[key]; + if (typeof(newMember) == 'function') { + var currentMember = currentStatics && currentStatics[key]; + if (isDelegate(currentMember)) { + var delegee = isDelegate(newMember) ? newMember.delegee : newMember; + currentMember.delegee = delegee; + newStatics[key] = currentMember; + } else { + newStatics[key] = delegate(newMember); } + } }); - return obj; + } +} +// `asMixin` will let us reuse same objcet instead of re-creating +// it per each component. +componentWillReceiveProps.asMixin = { + componentWillReceiveProps: componentWillReceiveProps }; -},{}],3:[function(_dereq_,module,exports){ +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{"./cached":2,"./shouldupdate":32,"lodash.assign":3}],2:[function(_dereq_,module,exports){ +"use strict"; + +var shouldupdate = _dereq_('./shouldupdate'); + +/** + * Directly fetch `cache` to use outside of Omniscient. + * You can do this if you want to define functions that caches computed + * result to avoid recomputing if invoked with equal arguments as last time. + * + * @param {Function} Function that does a computation. + * + * @module cached + * @returns {Function} + * @api public + */ +module.exports = factory(); + +/** + * Create a “local” instance of the `cache` with overriden defaults. + * + * ### Options + * ```js + * { + * isEqualProps: function (currentProps, nextProps), // check props + * } + * ``` + * + * @param {Object} [Options] Options with defaults to override + * + * @module cached.withDefaults + * @returns {Function} cached with overriden defaults + * @api public + */ +module.exports.withDefaults = factory; + +function factory (methods) { + var isEqual = (methods && methods.isEqualProps) || shouldupdate.isEqualProps; + + /** + * Returns optimized version of given `f` function for repeated + * calls with an equal inputs. Returned function caches last input + * and a result of the computation for it, which is handy for + * optimizing `render` when computations are run on unchanged parts + * of state. Although note that only last result is cached so it is + * not practical to call it mulitple times with in the same `render` + * call. + * + * @param {Function} function doing computation + * + * @module shouldComponentUpdate.isEqualState + * @returns {Function} Optimized function. + * @api public + */ + return function cached (f) { + var input, + output; + + return function () { + if (!isEqual(arguments, input)) { + output = f.apply(this, arguments); + } + // Update input either way to allow GC reclaim it unless + // anything else is referring to it. + input = arguments; + return output + } + }; +} + +},{"./shouldupdate":32}],3:[function(_dereq_,module,exports){ /** * lodash 3.0.0 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` @@ -213,124 +503,135 @@ module.exports = function(obj) { * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license */ -var baseIsEqual = _dereq_('lodash._baseisequal'), - bindCallback = _dereq_('lodash._bindcallback'); - -/** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. - */ -function isStrictComparable(value) { - return value === value && (value === 0 ? ((1 / value) > 0) : !isObject(value)); -} +var baseAssign = _dereq_('lodash._baseassign'), + createAssigner = _dereq_('lodash._createassigner'); /** - * Performs a deep comparison between two values to determine if they are - * equivalent. If `customizer` is provided it is invoked to compare values. - * If `customizer` returns `undefined` comparisons are handled by the method - * instead. The `customizer` is bound to `thisArg` and invoked with three - * arguments; (value, other [, index|key]). - * - * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Functions and DOM nodes - * are **not** supported. Provide a customizer function to extend support - * for comparing other values. + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources overwrite property assignments of previous sources. + * If `customizer` is provided it is invoked to produce the assigned values. + * The `customizer` is bound to `thisArg` and invoked with five arguments; + * (objectValue, sourceValue, key, object, source). * * @static * @memberOf _ - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize comparing values. + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigning values. * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @returns {Object} Returns `object`. * @example * - * var object = { 'user': 'fred' }; - * var other = { 'user': 'fred' }; - * - * object == other; - * // => false - * - * _.isEqual(object, other); - * // => true + * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); + * // => { 'user': 'fred', 'age': 40 } * * // using a customizer callback - * var array = ['hello', 'goodbye']; - * var other = ['hi', 'goodbye']; - * - * _.isEqual(array, other, function(value, other) { - * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; + * var defaults = _.partialRight(_.assign, function(value, other) { + * return typeof value == 'undefined' ? other : value; * }); - * // => true + * + * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } */ -function isEqual(value, other, customizer, thisArg) { - customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3); - if (!customizer && isStrictComparable(value) && isStrictComparable(other)) { - return value === other; +var assign = createAssigner(baseAssign); + +module.exports = assign; + +},{"lodash._baseassign":4,"lodash._createassigner":10}],4:[function(_dereq_,module,exports){ +/** + * lodash 3.0.1 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.7.0 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var baseCopy = _dereq_('lodash._basecopy'), + keys = _dereq_('lodash.keys'); + +/** + * The base implementation of `_.assign` without support for argument juggling, + * multiple sources, and `this` binding `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} [customizer] The function to customize assigning values. + * @returns {Object} Returns the destination object. + */ +function baseAssign(object, source, customizer) { + var props = keys(source); + if (!customizer) { + return baseCopy(source, object, props); } - var result = customizer ? customizer(value, other) : undefined; - return typeof result == 'undefined' ? baseIsEqual(value, other, customizer) : !!result; + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index], + value = object[key], + result = customizer(value, source[key], key, object, source); + + if ((result === result ? result !== value : value === value) || + (typeof value == 'undefined' && !(key in object))) { + object[key] = result; + } + } + return object; } +module.exports = baseAssign; + +},{"lodash._basecopy":5,"lodash.keys":6}],5:[function(_dereq_,module,exports){ /** - * Checks if `value` is the language type of `Object`. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * **Note:** See the [ES5 spec](https://es5.github.io/#x8) for more details. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true + * lodash 3.0.0 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.7.0 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** + * Copies the properties of `source` to `object`. * - * _.isObject(1); - * // => false + * @private + * @param {Object} source The object to copy properties from. + * @param {Object} [object={}] The object to copy properties to. + * @param {Array} props The property names to copy. + * @returns {Object} Returns `object`. */ -function isObject(value) { - // Avoid a V8 JIT bug in Chrome 19-20. - // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. - var type = typeof value; - return type == 'function' || (value && type == 'object') || false; +function baseCopy(source, object, props) { + if (!props) { + props = object; + object = {}; + } + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + object[key] = source[key]; + } + return object; } -module.exports = isEqual; +module.exports = baseCopy; -},{"lodash._baseisequal":4,"lodash._bindcallback":10}],4:[function(_dereq_,module,exports){ +},{}],6:[function(_dereq_,module,exports){ /** - * lodash 3.0.0 (Custom Build) + * lodash 3.0.3 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` * Copyright 2012-2015 The Dojo Foundation * Based on Underscore.js 1.7.0 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license */ -var isArray = _dereq_('lodash.isarray'), - isTypedArray = _dereq_('lodash.istypedarray'), - keys = _dereq_('lodash.keys'); - -/** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - numberTag = '[object Number]', - objectTag = '[object Object]', - regexpTag = '[object RegExp]', - stringTag = '[object String]'; +var isArguments = _dereq_('lodash.isarguments'), + isArray = _dereq_('lodash.isarray'), + isNative = _dereq_('lodash.isnative'); /** Used for native method references. */ var objectProto = Object.prototype; @@ -338,279 +639,303 @@ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; +/** Native method references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys; + /** - * Used to resolve the `toStringTag` of values. - * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) + * Used as the maximum length of an array-like value. + * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) * for more details. */ -var objToString = objectProto.toString; +var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; /** - * The base implementation of `_.isEqual` without support for `this` binding - * `customizer` functions. + * An object environment feature flags. * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize comparing values. - * @param {boolean} [isWhere] Specify performing partial comparisons. - * @param {Array} [stackA] Tracks traversed `value` objects. - * @param {Array} [stackB] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @static + * @memberOf _ + * @type Object */ -function baseIsEqual(value, other, customizer, isWhere, stackA, stackB) { - // Exit early for identical values. - if (value === other) { - // Treat `+0` vs. `-0` as not equal. - return value !== 0 || (1 / value == 1 / other); - } - var valType = typeof value, - othType = typeof other; +var support = {}; - // Exit early for unlike primitive values. - if ((valType != 'function' && valType != 'object' && othType != 'function' && othType != 'object') || - value == null || other == null) { - // Return `false` unless both values are `NaN`. - return value !== value && other !== other; +(function(x) { + + /** + * Detect if `arguments` object indexes are non-enumerable. + * + * In Firefox < 4, IE < 9, PhantomJS, and Safari < 5.1 `arguments` object + * indexes are non-enumerable. Chrome < 25 and Node.js < 0.11.0 treat + * `arguments` object indexes as non-enumerable and fail `hasOwnProperty` + * checks for indexes that exceed their function's formal parameters with + * associated values of `0`. + * + * @memberOf _.support + * @type boolean + */ + try { + support.nonEnumArgs = !propertyIsEnumerable.call(arguments, 1); + } catch(e) { + support.nonEnumArgs = true; } - return baseIsEqualDeep(value, other, baseIsEqual, customizer, isWhere, stackA, stackB); -} +}(0, 0)); /** - * A specialized version of `baseIsEqual` for arrays and objects which performs - * deep comparisons and tracks traversed objects enabling objects with circular - * references to be compared. + * Checks if `value` is a valid array-like index. * * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparing objects. - * @param {boolean} [isWhere] Specify performing partial comparisons. - * @param {Array} [stackA=[]] Tracks traversed `value` objects. - * @param {Array} [stackB=[]] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. */ -function baseIsEqualDeep(object, other, equalFunc, customizer, isWhere, stackA, stackB) { - var objIsArr = isArray(object), - othIsArr = isArray(other), - objTag = arrayTag, - othTag = arrayTag; - - if (!objIsArr) { - objTag = objToString.call(object); - if (objTag == argsTag) { - objTag = objectTag; - } else if (objTag != objectTag) { - objIsArr = isTypedArray(object); - } - } - if (!othIsArr) { - othTag = objToString.call(other); - if (othTag == argsTag) { - othTag = objectTag; - } else if (othTag != objectTag) { - othIsArr = isTypedArray(other); - } - } - var objIsObj = objTag == objectTag, - othIsObj = othTag == objectTag, - isSameTag = objTag == othTag; - - if (isSameTag && !(objIsArr || objIsObj)) { - return equalByTag(object, other, objTag); - } - var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); - - if (valWrapped || othWrapped) { - return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isWhere, stackA, stackB); - } - if (!isSameTag) { - return false; - } - // Assume cyclic values are equal. - // For more information on detecting circular references see https://es5.github.io/#JO. - stackA || (stackA = []); - stackB || (stackB = []); - - var length = stackA.length; - while (length--) { - if (stackA[length] == object) { - return stackB[length] == other; - } - } - // Add `object` and `other` to the stack of traversed objects. - stackA.push(object); - stackB.push(other); - - var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isWhere, stackA, stackB); - - stackA.pop(); - stackB.pop(); - - return result; +function isIndex(value, length) { + value = +value; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; } /** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on ES `ToLength`. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) + * for more details. * * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparing arrays. - * @param {boolean} [isWhere] Specify performing partial comparisons. - * @param {Array} [stackA] Tracks traversed `value` objects. - * @param {Array} [stackB] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. */ -function equalArrays(array, other, equalFunc, customizer, isWhere, stackA, stackB) { - var index = -1, - arrLength = array.length, - othLength = other.length, - result = true; - - if (arrLength != othLength && !(isWhere && othLength > arrLength)) { - return false; - } - // Deep compare the contents, ignoring non-numeric properties. - while (result && ++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; - - result = undefined; - if (customizer) { - result = isWhere - ? customizer(othValue, arrValue, index) - : customizer(arrValue, othValue, index); - } - if (typeof result == 'undefined') { - // Recursively compare arrays (susceptible to call stack limits). - if (isWhere) { - var othIndex = othLength; - while (othIndex--) { - othValue = other[othIndex]; - result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isWhere, stackA, stackB); - if (result) { - break; - } - } - } else { - result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isWhere, stackA, stackB); - } - } - } - return !!result; +function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } /** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. - * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. * * @private - * @param {Object} value The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + * @param {Object} object The object to inspect. + * @returns {Array} Returns the array of property names. */ -function equalByTag(object, other, tag) { - switch (tag) { - case boolTag: - case dateTag: - // Coerce dates and booleans to numbers, dates to milliseconds and booleans - // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. - return +object == +other; +function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length; - case errorTag: - return object.name == other.name && object.message == other.message; + var allowIndexes = length && isLength(length) && + (isArray(object) || (support.nonEnumArgs && isArguments(object))); - case numberTag: - // Treat `NaN` vs. `NaN` as equal. - return (object != +object) - ? other != +other - // But, treat `-0` vs. `+0` as not equal. - : (object == 0 ? ((1 / object) == (1 / other)) : object == +other); + var index = -1, + result = []; - case regexpTag: - case stringTag: - // Coerce regexes to strings and treat strings primitives and string - // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. - return object == (other + ''); + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); + } } - return false; + return result; } /** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. + * Checks if `value` is the language type of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparing values. - * @param {boolean} [isWhere] Specify performing partial comparisons. - * @param {Array} [stackA] Tracks traversed `value` objects. - * @param {Array} [stackB] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + * **Note:** See the [ES5 spec](https://es5.github.io/#x8) for more details. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false */ -function equalObjects(object, other, equalFunc, customizer, isWhere, stackA, stackB) { - var objProps = keys(object), - objLength = objProps.length, - othProps = keys(other), - othLength = othProps.length; +function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return type == 'function' || (value && type == 'object') || false; +} - if (objLength != othLength && !isWhere) { - return false; +/** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys) + * for more details. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ +var keys = !nativeKeys ? shimKeys : function(object) { + if (object) { + var Ctor = object.constructor, + length = object.length; } - var hasCtor, - index = -1; + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && (length && isLength(length)))) { + return shimKeys(object); + } + return isObject(object) ? nativeKeys(object) : []; +}; - while (++index < objLength) { - var key = objProps[index], - result = hasOwnProperty.call(other, key); +/** + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. + * + * @static + * @memberOf _ + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + */ +function keysIn(object) { + if (object == null) { + return []; + } + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || (support.nonEnumArgs && isArguments(object))) && length) || 0; - if (result) { - var objValue = object[key], - othValue = other[key]; + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, + result = Array(length), + skipIndexes = length > 0; - result = undefined; - if (customizer) { - result = isWhere - ? customizer(othValue, objValue, key) - : customizer(objValue, othValue, key); - } - if (typeof result == 'undefined') { - // Recursively compare objects (susceptible to call stack limits). - result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isWhere, stackA, stackB); - } - } - if (!result) { - return false; - } - hasCtor || (hasCtor = key == 'constructor'); + while (++index < length) { + result[index] = (index + ''); } - if (!hasCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; - - // Non `Object` object instances with different constructors are not equal. - if (objCtor != othCtor && ('constructor' in object && 'constructor' in other) && - !(typeof objCtor == 'function' && objCtor instanceof objCtor && typeof othCtor == 'function' && othCtor instanceof othCtor)) { - return false; + for (var key in object) { + if (!(skipIndexes && isIndex(key, length)) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); } } - return true; + return result; } -module.exports = baseIsEqual; +module.exports = keys; + +},{"lodash.isarguments":7,"lodash.isarray":8,"lodash.isnative":9}],7:[function(_dereq_,module,exports){ +/** + * lodash 3.0.0 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.7.0 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]'; + +/** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ +function isObjectLike(value) { + return (value && typeof value == 'object') || false; +} + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** + * Used to resolve the `toStringTag` of values. + * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) + * for more details. + */ +var objToString = objectProto.toString; + +/** + * Used as the maximum length of an array-like value. + * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) + * for more details. + */ +var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; + +/** + * Checks if `value` is a valid array-like length. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + */ +function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} + +/** + * Checks if `value` is classified as an `arguments` object. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example + * + * (function() { return _.isArguments(arguments); })(); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ +function isArguments(value) { + var length = isObjectLike(value) ? value.length : undefined; + return (isLength(length) && objToString.call(value) == argsTag) || false; +} + +module.exports = isArguments; -},{"lodash.isarray":5,"lodash.istypedarray":6,"lodash.keys":7}],5:[function(_dereq_,module,exports){ +},{}],8:[function(_dereq_,module,exports){ /** * lodash 3.0.0 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` @@ -770,7 +1095,7 @@ function escapeRegExp(string) { module.exports = isArray; -},{}],6:[function(_dereq_,module,exports){ +},{}],9:[function(_dereq_,module,exports){ /** * lodash 3.0.0 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` @@ -781,52 +1106,40 @@ module.exports = isArray; */ /** `Object#toString` result references. */ -var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag = '[object Function]', - mapTag = '[object Map]', - numberTag = '[object Number]', - objectTag = '[object Object]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - weakMapTag = '[object WeakMap]'; +var funcTag = '[object Function]'; -var arrayBufferTag = '[object ArrayBuffer]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; +/** Used to detect host constructors (Safari > 5). */ +var reHostCtor = /^\[object .+?Constructor\]$/; -/** Used to identify `toStringTag` values of typed arrays. */ -var typedArrayTags = {}; -typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = -typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = -typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = -typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = -typedArrayTags[uint32Tag] = true; -typedArrayTags[argsTag] = typedArrayTags[arrayTag] = -typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = -typedArrayTags[dateTag] = typedArrayTags[errorTag] = -typedArrayTags[funcTag] = typedArrayTags[mapTag] = -typedArrayTags[numberTag] = typedArrayTags[objectTag] = -typedArrayTags[regexpTag] = typedArrayTags[setTag] = -typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; +/** + * Used to match `RegExp` special characters. + * See this [article on `RegExp` characters](http://www.regular-expressions.info/characters.html#special) + * for more details. + */ +var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g, + reHasRegExpChars = RegExp(reRegExpChars.source); /** - * Checks if `value` is object-like. + * Converts `value` to a string if it is not one. An empty string is returned + * for `null` or `undefined` values. * * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + if (typeof value == 'string') { + return value; + } + return value == null ? '' : (value + ''); +} + +/** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. */ function isObjectLike(value) { return (value && typeof value == 'object') || false; @@ -835,6 +1148,9 @@ function isObjectLike(value) { /** Used for native method references. */ var objectProto = Object.prototype; +/** Used to resolve the decompiled source of functions. */ +var fnToString = Function.prototype.toString; + /** * Used to resolve the `toStringTag` of values. * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) @@ -842,107 +1158,193 @@ var objectProto = Object.prototype; */ var objToString = objectProto.toString; -/** - * Used as the maximum length of an array-like value. - * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) - * for more details. - */ -var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; +/** Used to detect if a method is native. */ +var reNative = RegExp('^' + + escapeRegExp(objToString) + .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); /** - * Checks if `value` is a valid array-like length. + * Checks if `value` is a native function. * - * @private + * @static + * @memberOf _ + * @category Lang * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @example + * + * _.isNative(Array.prototype.push); + * // => true + * + * _.isNative(_); + * // => false */ -function isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +function isNative(value) { + if (value == null) { + return false; + } + if (objToString.call(value) == funcTag) { + return reNative.test(fnToString.call(value)); + } + return (isObjectLike(value) && reHostCtor.test(value)) || false; } /** - * Checks if `value` is classified as a typed array. + * Escapes the `RegExp` special characters "\", "^", "$", ".", "|", "?", "*", + * "+", "(", ")", "[", "]", "{" and "}" in `string`. * * @static * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @category String + * @param {string} [string=''] The string to escape. + * @returns {string} Returns the escaped string. * @example * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false + * _.escapeRegExp('[lodash](https://lodash.com/)'); + * // => '\[lodash\]\(https://lodash\.com/\)' */ -function isTypedArray(value) { - return (isObjectLike(value) && isLength(value.length) && typedArrayTags[objToString.call(value)]) || false; +function escapeRegExp(string) { + string = baseToString(string); + return (string && reHasRegExpChars.test(string)) + ? string.replace(reRegExpChars, '\\$&') + : string; } -module.exports = isTypedArray; +module.exports = isNative; -},{}],7:[function(_dereq_,module,exports){ +},{}],10:[function(_dereq_,module,exports){ /** - * lodash 3.0.2 (Custom Build) + * lodash 3.0.0 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` * Copyright 2012-2015 The Dojo Foundation * Based on Underscore.js 1.7.0 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license */ -var isArguments = _dereq_('lodash.isarguments'), - isArray = _dereq_('lodash.isarray'), - isNative = _dereq_('lodash.isnative'); +var bindCallback = _dereq_('lodash._bindcallback'), + isIterateeCall = _dereq_('lodash._isiterateecall'); -/** Used for native method references. */ -var objectProto = Object.prototype; +/** + * Creates a function that assigns properties of source object(s) to a given + * destination object. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ +function createAssigner(assigner) { + return function() { + var length = arguments.length, + object = arguments[0]; -/** Used to check objects for own properties. */ -var hasOwnProperty = objectProto.hasOwnProperty; + if (length < 2 || object == null) { + return object; + } + if (length > 3 && isIterateeCall(arguments[1], arguments[2], arguments[3])) { + length = 2; + } + // Juggle arguments. + if (length > 3 && typeof arguments[length - 2] == 'function') { + var customizer = bindCallback(arguments[--length - 1], arguments[length--], 5); + } else if (length > 2 && typeof arguments[length - 1] == 'function') { + customizer = arguments[--length]; + } + var index = 0; + while (++index < length) { + var source = arguments[index]; + if (source) { + assigner(object, source, customizer); + } + } + return object; + }; +} -/** Native method references. */ -var propertyIsEnumerable = objectProto.propertyIsEnumerable; +module.exports = createAssigner; -/* Native method references for those with the same name as other `lodash` methods. */ -var nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys; +},{"lodash._bindcallback":11,"lodash._isiterateecall":12}],11:[function(_dereq_,module,exports){ +/** + * lodash 3.0.0 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.7.0 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ /** - * Used as the maximum length of an array-like value. - * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) - * for more details. + * A specialized version of `baseCallback` which only supports `this` binding + * and specifying the number of arguments to provide to `func`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. */ -var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; +function bindCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + if (typeof thisArg == 'undefined') { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + case 5: return function(value, other, key, object, source) { + return func.call(thisArg, value, other, key, object, source); + }; + } + return function() { + return func.apply(thisArg, arguments); + }; +} /** - * An object environment feature flags. + * This method returns the first argument provided to it. * * @static * @memberOf _ - * @type Object + * @category Utility + * @param {*} value Any value. + * @returns {*} Returns `value`. + * @example + * + * var object = { 'user': 'fred' }; + * _.identity(object) === object; + * // => true */ -var support = {}; +function identity(value) { + return value; +} -(function(x) { +module.exports = bindCallback; - /** - * Detect if `arguments` object indexes are non-enumerable. - * - * In Firefox < 4, IE < 9, PhantomJS, and Safari < 5.1 `arguments` object - * indexes are non-enumerable. Chrome < 25 and Node.js < 0.11.0 treat - * `arguments` object indexes as non-enumerable and fail `hasOwnProperty` - * checks for indexes that exceed their function's formal parameters with - * associated values of `0`. - * - * @memberOf _.support - * @type boolean - */ - try { - support.nonEnumArgs = !propertyIsEnumerable.call(arguments, 1); - } catch(e) { - support.nonEnumArgs = true; - } -}(0, 0)); +},{}],12:[function(_dereq_,module,exports){ +/** + * lodash 3.0.2 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.7.0 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + +/** + * Used as the maximum length of an array-like value. + * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) + * for more details. + */ +var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; /** * Checks if `value` is a valid array-like index. @@ -958,6 +1360,30 @@ function isIndex(value, length) { return value > -1 && value % 1 == 0 && value < length; } +/** + * Checks if the provided arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. + */ +function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number') { + var length = object.length, + prereq = isLength(length) && isIndex(index, length); + } else { + prereq = type == 'string' && index in object; + } + var other = object[index]; + return prereq && (value === value ? value === other : other !== other); +} + /** * Checks if `value` is a valid array-like length. * @@ -973,34 +1399,6 @@ function isLength(value) { return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } -/** - * A fallback implementation of `Object.keys` which creates an array of the - * own enumerable property names of `object`. - * - * @private - * @param {Object} object The object to inspect. - * @returns {Array} Returns the array of property names. - */ -function shimKeys(object) { - var props = keysIn(object), - propsLength = props.length, - length = propsLength && object.length; - - var allowIndexes = length && isLength(length) && - (isArray(object) || (support.nonEnumArgs && isArguments(object))); - - var index = -1, - result = []; - - while (++index < propsLength) { - var key = props[index]; - if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { - result.push(key); - } - } - return result; -} - /** * Checks if `value` is the language type of `Object`. * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) @@ -1030,99 +1428,417 @@ function isObject(value) { return type == 'function' || (value && type == 'object') || false; } +module.exports = isIterateeCall; + +},{}],13:[function(_dereq_,module,exports){ /** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys) - * for more details. + * lodash 3.0.0 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.7.0 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var baseIsEqual = _dereq_('lodash._baseisequal'), + bindCallback = _dereq_('lodash._bindcallback'); + +/** + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. * - * @static + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. + */ +function isStrictComparable(value) { + return value === value && (value === 0 ? ((1 / value) > 0) : !isObject(value)); +} + +/** + * Performs a deep comparison between two values to determine if they are + * equivalent. If `customizer` is provided it is invoked to compare values. + * If `customizer` returns `undefined` comparisons are handled by the method + * instead. The `customizer` is bound to `thisArg` and invoked with three + * arguments; (value, other [, index|key]). + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Functions and DOM nodes + * are **not** supported. Provide a customizer function to extend support + * for comparing other values. + * + * @static * @memberOf _ - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the array of property names. + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparing values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; * - * Foo.prototype.c = 3; + * object == other; + * // => false * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) + * _.isEqual(object, other); + * // => true * - * _.keys('hi'); - * // => ['0', '1'] + * // using a customizer callback + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; + * + * _.isEqual(array, other, function(value, other) { + * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; + * }); + * // => true */ -var keys = !nativeKeys ? shimKeys : function(object) { - if (object) { - var Ctor = object.constructor, - length = object.length; - } - if ((typeof Ctor == 'function' && Ctor.prototype === object) || - (typeof object != 'function' && (length && isLength(length)))) { - return shimKeys(object); +function isEqual(value, other, customizer, thisArg) { + customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3); + if (!customizer && isStrictComparable(value) && isStrictComparable(other)) { + return value === other; } - return isObject(object) ? nativeKeys(object) : []; -}; + var result = customizer ? customizer(value, other) : undefined; + return typeof result == 'undefined' ? baseIsEqual(value, other, customizer) : !!result; +} /** - * Creates an array of the own and inherited enumerable property names of `object`. + * Checks if `value` is the language type of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * - * **Note:** Non-object values are coerced to objects. + * **Note:** See the [ES5 spec](https://es5.github.io/#x8) for more details. * * @static * @memberOf _ - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the array of property names. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } + * _.isObject({}); + * // => true * - * Foo.prototype.c = 3; + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false + */ +function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return type == 'function' || (value && type == 'object') || false; +} + +module.exports = isEqual; + +},{"lodash._baseisequal":14,"lodash._bindcallback":20}],14:[function(_dereq_,module,exports){ +/** + * lodash 3.0.0 (Custom Build) + * Build: `lodash modern modularize exports="npm" -o ./` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.7.0 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ +var isArray = _dereq_('lodash.isarray'), + isTypedArray = _dereq_('lodash.istypedarray'), + keys = _dereq_('lodash.keys'); + +/** `Object#toString` result references. */ +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + stringTag = '[object String]'; + +/** Used for native method references. */ +var objectProto = Object.prototype; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the `toStringTag` of values. + * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) + * for more details. + */ +var objToString = objectProto.toString; + +/** + * The base implementation of `_.isEqual` without support for `this` binding + * `customizer` functions. + * + * @private + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isWhere] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ +function baseIsEqual(value, other, customizer, isWhere, stackA, stackB) { + // Exit early for identical values. + if (value === other) { + // Treat `+0` vs. `-0` as not equal. + return value !== 0 || (1 / value == 1 / other); + } + var valType = typeof value, + othType = typeof other; + + // Exit early for unlike primitive values. + if ((valType != 'function' && valType != 'object' && othType != 'function' && othType != 'object') || + value == null || other == null) { + // Return `false` unless both values are `NaN`. + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, baseIsEqual, customizer, isWhere, stackA, stackB); +} + +/** + * A specialized version of `baseIsEqual` for arrays and objects which performs + * deep comparisons and tracks traversed objects enabling objects with circular + * references to be compared. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing objects. + * @param {boolean} [isWhere] Specify performing partial comparisons. + * @param {Array} [stackA=[]] Tracks traversed `value` objects. + * @param {Array} [stackB=[]] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function baseIsEqualDeep(object, other, equalFunc, customizer, isWhere, stackA, stackB) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = arrayTag, + othTag = arrayTag; + + if (!objIsArr) { + objTag = objToString.call(object); + if (objTag == argsTag) { + objTag = objectTag; + } else if (objTag != objectTag) { + objIsArr = isTypedArray(object); + } + } + if (!othIsArr) { + othTag = objToString.call(other); + if (othTag == argsTag) { + othTag = objectTag; + } else if (othTag != objectTag) { + othIsArr = isTypedArray(other); + } + } + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && !(objIsArr || objIsObj)) { + return equalByTag(object, other, objTag); + } + var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), + othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); + + if (valWrapped || othWrapped) { + return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isWhere, stackA, stackB); + } + if (!isSameTag) { + return false; + } + // Assume cyclic values are equal. + // For more information on detecting circular references see https://es5.github.io/#JO. + stackA || (stackA = []); + stackB || (stackB = []); + + var length = stackA.length; + while (length--) { + if (stackA[length] == object) { + return stackB[length] == other; + } + } + // Add `object` and `other` to the stack of traversed objects. + stackA.push(object); + stackB.push(other); + + var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isWhere, stackA, stackB); + + stackA.pop(); + stackB.pop(); + + return result; +} + +/** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing arrays. + * @param {boolean} [isWhere] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ +function equalArrays(array, other, equalFunc, customizer, isWhere, stackA, stackB) { + var index = -1, + arrLength = array.length, + othLength = other.length, + result = true; + + if (arrLength != othLength && !(isWhere && othLength > arrLength)) { + return false; + } + // Deep compare the contents, ignoring non-numeric properties. + while (result && ++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; + + result = undefined; + if (customizer) { + result = isWhere + ? customizer(othValue, arrValue, index) + : customizer(arrValue, othValue, index); + } + if (typeof result == 'undefined') { + // Recursively compare arrays (susceptible to call stack limits). + if (isWhere) { + var othIndex = othLength; + while (othIndex--) { + othValue = other[othIndex]; + result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isWhere, stackA, stackB); + if (result) { + break; + } + } + } else { + result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isWhere, stackA, stackB); + } + } + } + return !!result; +} + +/** + * A specialized version of `baseIsEqualDeep` for comparing objects of + * the same `toStringTag`. + * + * **Note:** This function only supports comparing values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} value The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ +function equalByTag(object, other, tag) { + switch (tag) { + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; + + case errorTag: + return object.name == other.name && object.message == other.message; + + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) + ? other != +other + // But, treat `-0` vs. `+0` as not equal. + : (object == 0 ? ((1 / object) == (1 / other)) : object == +other); + + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + } + return false; +} + +/** + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isWhere] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ -function keysIn(object) { - if (object == null) { - return []; - } - if (!isObject(object)) { - object = Object(object); +function equalObjects(object, other, equalFunc, customizer, isWhere, stackA, stackB) { + var objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; + + if (objLength != othLength && !isWhere) { + return false; } - var length = object.length; - length = (length && isLength(length) && - (isArray(object) || (support.nonEnumArgs && isArguments(object))) && length) || 0; + var hasCtor, + index = -1; - var Ctor = object.constructor, - index = -1, - isProto = typeof Ctor == 'function' && Ctor.prototype == object, - result = Array(length), - skipIndexes = length > 0; + while (++index < objLength) { + var key = objProps[index], + result = hasOwnProperty.call(other, key); - while (++index < length) { - result[index] = (index + ''); + if (result) { + var objValue = object[key], + othValue = other[key]; + + result = undefined; + if (customizer) { + result = isWhere + ? customizer(othValue, objValue, key) + : customizer(objValue, othValue, key); + } + if (typeof result == 'undefined') { + // Recursively compare objects (susceptible to call stack limits). + result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isWhere, stackA, stackB); + } + } + if (!result) { + return false; + } + hasCtor || (hasCtor = key == 'constructor'); } - for (var key in object) { - if (!(skipIndexes && isIndex(key, length)) && - !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); + if (!hasCtor) { + var objCtor = object.constructor, + othCtor = other.constructor; + + // Non `Object` object instances with different constructors are not equal. + if (objCtor != othCtor && ('constructor' in object && 'constructor' in other) && + !(typeof objCtor == 'function' && objCtor instanceof objCtor && typeof othCtor == 'function' && othCtor instanceof othCtor)) { + return false; } } - return result; + return true; } -module.exports = keys; +module.exports = baseIsEqual; -},{"lodash.isarguments":8,"lodash.isarray":5,"lodash.isnative":9}],8:[function(_dereq_,module,exports){ +},{"lodash.isarray":15,"lodash.istypedarray":16,"lodash.keys":17}],15:[function(_dereq_,module,exports){ +arguments[4][8][0].apply(exports,arguments) +},{"dup":8}],16:[function(_dereq_,module,exports){ /** * lodash 3.0.0 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` @@ -1133,7 +1849,45 @@ module.exports = keys; */ /** `Object#toString` result references. */ -var argsTag = '[object Arguments]'; +var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; + +var arrayBufferTag = '[object ArrayBuffer]', + float32Tag = '[object Float32Array]', + float64Tag = '[object Float64Array]', + int8Tag = '[object Int8Array]', + int16Tag = '[object Int16Array]', + int32Tag = '[object Int32Array]', + uint8Tag = '[object Uint8Array]', + uint8ClampedTag = '[object Uint8ClampedArray]', + uint16Tag = '[object Uint16Array]', + uint32Tag = '[object Uint32Array]'; + +/** Used to identify `toStringTag` values of typed arrays. */ +var typedArrayTags = {}; +typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = +typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = +typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = +typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = +typedArrayTags[uint32Tag] = true; +typedArrayTags[argsTag] = typedArrayTags[arrayTag] = +typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = +typedArrayTags[dateTag] = typedArrayTags[errorTag] = +typedArrayTags[funcTag] = typedArrayTags[mapTag] = +typedArrayTags[numberTag] = typedArrayTags[objectTag] = +typedArrayTags[regexpTag] = typedArrayTags[setTag] = +typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; /** * Checks if `value` is object-like. @@ -1175,7 +1929,7 @@ function isLength(value) { } /** - * Checks if `value` is classified as an `arguments` object. + * Checks if `value` is classified as a typed array. * * @static * @memberOf _ @@ -1184,204 +1938,265 @@ function isLength(value) { * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * (function() { return _.isArguments(arguments); })(); + * _.isTypedArray(new Uint8Array); * // => true * - * _.isArguments([1, 2, 3]); + * _.isTypedArray([]); * // => false */ -function isArguments(value) { - var length = isObjectLike(value) ? value.length : undefined; - return (isLength(length) && objToString.call(value) == argsTag) || false; +function isTypedArray(value) { + return (isObjectLike(value) && isLength(value.length) && typedArrayTags[objToString.call(value)]) || false; } -module.exports = isArguments; +module.exports = isTypedArray; -},{}],9:[function(_dereq_,module,exports){ +},{}],17:[function(_dereq_,module,exports){ /** - * lodash 3.0.0 (Custom Build) + * lodash 3.0.2 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` * Copyright 2012-2015 The Dojo Foundation * Based on Underscore.js 1.7.0 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license */ +var isArguments = _dereq_('lodash.isarguments'), + isArray = _dereq_('lodash.isarray'), + isNative = _dereq_('lodash.isnative'); -/** `Object#toString` result references. */ -var funcTag = '[object Function]'; +/** Used for native method references. */ +var objectProto = Object.prototype; -/** Used to detect host constructors (Safari > 5). */ -var reHostCtor = /^\[object .+?Constructor\]$/; +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** Native method references. */ +var propertyIsEnumerable = objectProto.propertyIsEnumerable; + +/* Native method references for those with the same name as other `lodash` methods. */ +var nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys; /** - * Used to match `RegExp` special characters. - * See this [article on `RegExp` characters](http://www.regular-expressions.info/characters.html#special) + * Used as the maximum length of an array-like value. + * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) * for more details. */ -var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g, - reHasRegExpChars = RegExp(reRegExpChars.source); +var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; /** - * Converts `value` to a string if it is not one. An empty string is returned - * for `null` or `undefined` values. + * An object environment feature flags. * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. + * @static + * @memberOf _ + * @type Object */ -function baseToString(value) { - if (typeof value == 'string') { - return value; +var support = {}; + +(function(x) { + + /** + * Detect if `arguments` object indexes are non-enumerable. + * + * In Firefox < 4, IE < 9, PhantomJS, and Safari < 5.1 `arguments` object + * indexes are non-enumerable. Chrome < 25 and Node.js < 0.11.0 treat + * `arguments` object indexes as non-enumerable and fail `hasOwnProperty` + * checks for indexes that exceed their function's formal parameters with + * associated values of `0`. + * + * @memberOf _.support + * @type boolean + */ + try { + support.nonEnumArgs = !propertyIsEnumerable.call(arguments, 1); + } catch(e) { + support.nonEnumArgs = true; } - return value == null ? '' : (value + ''); -} +}(0, 0)); /** - * Checks if `value` is object-like. + * Checks if `value` is a valid array-like index. * * @private * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. */ -function isObjectLike(value) { - return (value && typeof value == 'object') || false; +function isIndex(value, length) { + value = +value; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; } -/** Used for native method references. */ -var objectProto = Object.prototype; - -/** Used to resolve the decompiled source of functions. */ -var fnToString = Function.prototype.toString; - /** - * Used to resolve the `toStringTag` of values. - * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on ES `ToLength`. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) * for more details. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. */ -var objToString = objectProto.toString; +function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; +} -/** Used to detect if a method is native. */ -var reNative = RegExp('^' + - escapeRegExp(objToString) - .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' -); +/** + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. + * + * @private + * @param {Object} object The object to inspect. + * @returns {Array} Returns the array of property names. + */ +function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length; + + var allowIndexes = length && isLength(length) && + (isArray(object) || (support.nonEnumArgs && isArguments(object))); + + var index = -1, + result = []; + + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); + } + } + return result; +} /** - * Checks if `value` is a native function. + * Checks if `value` is the language type of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * **Note:** See the [ES5 spec](https://es5.github.io/#x8) for more details. * * @static * @memberOf _ * @category Lang * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, else `false`. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * - * _.isNative(Array.prototype.push); + * _.isObject({}); * // => true * - * _.isNative(_); + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); * // => false */ -function isNative(value) { - if (value == null) { - return false; - } - if (objToString.call(value) == funcTag) { - return reNative.test(fnToString.call(value)); - } - return (isObjectLike(value) && reHostCtor.test(value)) || false; +function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return type == 'function' || (value && type == 'object') || false; } /** - * Escapes the `RegExp` special characters "\", "^", "$", ".", "|", "?", "*", - * "+", "(", ")", "[", "]", "{" and "}" in `string`. + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys) + * for more details. * * @static * @memberOf _ - * @category String - * @param {string} [string=''] The string to escape. - * @returns {string} Returns the escaped string. + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the array of property names. * @example * - * _.escapeRegExp('[lodash](https://lodash.com/)'); - * // => '\[lodash\]\(https://lodash\.com/\)' - */ -function escapeRegExp(string) { - string = baseToString(string); - return (string && reHasRegExpChars.test(string)) - ? string.replace(reRegExpChars, '\\$&') - : string; -} - -module.exports = isNative; - -},{}],10:[function(_dereq_,module,exports){ -/** - * lodash 3.0.0 (Custom Build) - * Build: `lodash modern modularize exports="npm" -o ./` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.7.0 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ - -/** - * A specialized version of `baseCallback` which only supports `this` binding - * and specifying the number of arguments to provide to `func`. + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * @private - * @param {Function} func The function to bind. - * @param {*} thisArg The `this` binding of `func`. - * @param {number} [argCount] The number of arguments to provide to `func`. - * @returns {Function} Returns the callback. + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] */ -function bindCallback(func, thisArg, argCount) { - if (typeof func != 'function') { - return identity; - } - if (typeof thisArg == 'undefined') { - return func; +var keys = !nativeKeys ? shimKeys : function(object) { + if (object) { + var Ctor = object.constructor, + length = object.length; } - switch (argCount) { - case 1: return function(value) { - return func.call(thisArg, value); - }; - case 3: return function(value, index, collection) { - return func.call(thisArg, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(thisArg, accumulator, value, index, collection); - }; - case 5: return function(value, other, key, object, source) { - return func.call(thisArg, value, other, key, object, source); - }; + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && (length && isLength(length)))) { + return shimKeys(object); } - return function() { - return func.apply(thisArg, arguments); - }; -} + return isObject(object) ? nativeKeys(object) : []; +}; /** - * This method returns the first argument provided to it. + * Creates an array of the own and inherited enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. * * @static * @memberOf _ - * @category Utility - * @param {*} value Any value. - * @returns {*} Returns `value`. + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the array of property names. * @example * - * var object = { 'user': 'fred' }; - * _.identity(object) === object; - * // => true + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) */ -function identity(value) { - return value; +function keysIn(object) { + if (object == null) { + return []; + } + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || (support.nonEnumArgs && isArguments(object))) && length) || 0; + + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype == object, + result = Array(length), + skipIndexes = length > 0; + + while (++index < length) { + result[index] = (index + ''); + } + for (var key in object) { + if (!(skipIndexes && isIndex(key, length)) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; } -module.exports = bindCallback; +module.exports = keys; -},{}],11:[function(_dereq_,module,exports){ +},{"lodash.isarguments":18,"lodash.isarray":15,"lodash.isnative":19}],18:[function(_dereq_,module,exports){ +arguments[4][7][0].apply(exports,arguments) +},{"dup":7}],19:[function(_dereq_,module,exports){ +arguments[4][9][0].apply(exports,arguments) +},{"dup":9}],20:[function(_dereq_,module,exports){ +arguments[4][11][0].apply(exports,arguments) +},{"dup":11}],21:[function(_dereq_,module,exports){ /** * lodash 3.0.0 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` @@ -1432,7 +2247,7 @@ function pick(object, predicate, thisArg) { module.exports = pick; -},{"lodash._baseflatten":12,"lodash._bindcallback":15,"lodash._pickbyarray":16,"lodash._pickbycallback":17}],12:[function(_dereq_,module,exports){ +},{"lodash._baseflatten":22,"lodash._bindcallback":25,"lodash._pickbyarray":26,"lodash._pickbycallback":27}],22:[function(_dereq_,module,exports){ /** * lodash 3.0.0 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` @@ -1514,13 +2329,13 @@ function isLength(value) { module.exports = baseFlatten; -},{"lodash.isarguments":13,"lodash.isarray":14}],13:[function(_dereq_,module,exports){ +},{"lodash.isarguments":23,"lodash.isarray":24}],23:[function(_dereq_,module,exports){ +arguments[4][7][0].apply(exports,arguments) +},{"dup":7}],24:[function(_dereq_,module,exports){ arguments[4][8][0].apply(exports,arguments) -},{"dup":8}],14:[function(_dereq_,module,exports){ -arguments[4][5][0].apply(exports,arguments) -},{"dup":5}],15:[function(_dereq_,module,exports){ -arguments[4][10][0].apply(exports,arguments) -},{"dup":10}],16:[function(_dereq_,module,exports){ +},{"dup":8}],25:[function(_dereq_,module,exports){ +arguments[4][11][0].apply(exports,arguments) +},{"dup":11}],26:[function(_dereq_,module,exports){ /** * lodash 3.0.0 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` @@ -1597,7 +2412,7 @@ function isObject(value) { module.exports = pickByArray; -},{}],17:[function(_dereq_,module,exports){ +},{}],27:[function(_dereq_,module,exports){ /** * lodash 3.0.0 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` @@ -1643,7 +2458,7 @@ function pickByCallback(object, predicate) { module.exports = pickByCallback; -},{"lodash._basefor":18,"lodash.keysin":19}],18:[function(_dereq_,module,exports){ +},{"lodash._basefor":28,"lodash.keysin":29}],28:[function(_dereq_,module,exports){ /** * lodash 3.0.0 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` @@ -1722,7 +2537,7 @@ function isObject(value) { module.exports = baseFor; -},{}],19:[function(_dereq_,module,exports){ +},{}],29:[function(_dereq_,module,exports){ /** * lodash 3.0.2 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` @@ -1891,17 +2706,59 @@ function keysIn(object) { module.exports = keysIn; -},{"lodash.isarguments":20,"lodash.isarray":21}],20:[function(_dereq_,module,exports){ +},{"lodash.isarguments":30,"lodash.isarray":31}],30:[function(_dereq_,module,exports){ +arguments[4][7][0].apply(exports,arguments) +},{"dup":7}],31:[function(_dereq_,module,exports){ arguments[4][8][0].apply(exports,arguments) -},{"dup":8}],21:[function(_dereq_,module,exports){ -arguments[4][5][0].apply(exports,arguments) -},{"dup":5}],22:[function(_dereq_,module,exports){ +},{"dup":8}],32:[function(_dereq_,module,exports){ "use strict"; var filter = _dereq_('lodash.pick'), isEqual = _dereq_('lodash.isequal'); +var isNotIgnorable = not(or(isStatics, isChildren)); + +/** + * Directly fetch `shouldComponentUpdate` mixin to use outside of Omniscient. + * You can do this if you don't want to use Omniscients syntactic sugar. + * + * @param {Object} nextProps Next props. Can be objects of cursors, values or immutable structures + * @param {Object} nextState Next state. Can be objects of values or immutable structures + * + * @property {Function} isCursor Get default isCursor + * @property {Function} isEqualState Get default isEqualState + * @property {Function} isEqualProps Get default isEqualProps + * @property {Function} isEqualCursor Get default isEqualCursor + * @property {Function} isImmutable Get default isImmutable + * @property {Function} debug Get default debug + * + * @module shouldComponentUpdate + * @returns {Component} + * @api public + */ module.exports = factory(); + +/** + * Create a “local” instance of the shouldComponentUpdate with overriden defaults. + * + * ### Options + * ```js + * { + * isCursor: function(cursor), // check if is props + * isEqualCursor: function (oneCursor, otherCursor), // check cursor + * isEqualState: function (currentState, nextState), // check state + * isImmutable: function (currentState, nextState), // check if object is immutable + * isEqualProps: function (currentProps, nextProps), // check props + * unCursor: function (cursor) // convert from cursor to object + * } + * ``` + * + * @param {Object} [Options] Options with defaults to override + * + * @module shouldComponentUpdate.withDefaults + * @returns {Function} shouldComponentUpdate with overriden defaults + * @api public + */ module.exports.withDefaults = factory; function factory (methods) { @@ -1925,27 +2782,9 @@ function factory (methods) { return shouldComponentUpdate; function shouldComponentUpdate (nextProps, nextState) { - var isNotIgnorable = not(or(isStatics, isChildren)); - - var nextCursors = filter(nextProps, isNotIgnorable), - currentCursors = filter(this.props, isNotIgnorable); - - var nextCursorsKeys = Object.keys(nextCursors), - currentCursorsKeys = Object.keys(currentCursors); - - if (currentCursorsKeys.length !== nextCursorsKeys.length) { - if (debug) debug.call(this, 'shouldComponentUpdate => true (number of cursors differ)'); - return true; - } - - if (hasDifferentKeys(currentCursorsKeys, currentCursors, nextCursors)) { - if (debug) debug.call(this, 'shouldComponentUpdate => true (cursors have different keys)'); - return true; - } - - if (hasChangedCursors(currentCursors, nextCursors)) { - if (debug) debug.call(this, 'shouldComponentUpdate => true (cursors have changed)'); - return true; + if (nextProps === this.props && nextState === this.state) { + if (debug) debug.call(this, 'shouldComponentUpdate => false (equal input)'); + return false; } if (!_isEqualState(this.state, nextState)) { @@ -1953,8 +2792,11 @@ function factory (methods) { return true; } - if (hasChangedProperties(currentCursors, nextCursors)) { - if (debug) debug.call(this, 'shouldComponentUpdate => true (properties have changed)'); + var nextProps = filter(nextProps, isNotIgnorable), + currentProps = filter(this.props, isNotIgnorable); + + if (!_isEqualProps(currentProps, nextProps)) { + if (debug) debug.call(this, 'shouldComponentUpdate => true (props have changed)'); return true; } @@ -1963,60 +2805,70 @@ function factory (methods) { return false; } - function hasChangedCursors (current, next) { - current = filter(current, _isCursor); - next = filter(next, _isCursor); - - for (var key in current) { - if (!_isEqualCursor(current[key], next[key])) { - return true; - } - } - return false; - } - - function hasChangedProperties (current, next) { - current = filter(current, not(_isCursor)); - next = filter(next, not(_isCursor)); - - for (var key in current) { - if (!_isEqualProps(current[key], next[key])) { - return true; - } - } - return false; - } - + /** + * Predicate to check if state is equal. Checks in the tree for immutable structures + * and if it is, check by reference. Does not support cursors. + * + * Override through `shouldComponentUpdate.withDefaults`. + * + * @param {Object} value + * @param {Object} other + * + * @module shouldComponentUpdate.isEqualState + * @returns {Boolean} + * @api public + */ function isEqualState (value, other) { return isEqual(value, other, function (current, next) { - if (_isImmutable(current) && _isImmutable(next)) { - return current === next; - } - if (_isImmutable(current) || _isImmutable(next)) { - return false; - } - return void 0; + if (current === next) return true; + return compare(current, next, _isImmutable, isEqualImmutable); }); } + /** + * Predicate to check if props are equal. Checks in the tree for cursors and immutable structures + * and if it is, check by reference. + * + * Override through `shouldComponentUpdate.withDefaults`. + * + * @param {Object} value + * @param {Object} other + * + * @module shouldComponentUpdate.isEqualProps + * @returns {Boolean} + * @api public + */ function isEqualProps (value, other) { + if (value === other) return true; + + var cursorsEqual = compare(value, other, _isCursor, _isEqualCursor); + if (cursorsEqual !== void 0) return cursorsEqual; + + var immutableEqual = compare(value, other, _isImmutable, isEqualImmutable); + if (immutableEqual !== void 0) return immutableEqual; + return isEqual(value, other, function (current, next) { - if (_isCursor(current) && _isCursor(next)) { - return isEqualCursor(current, next); - } - if (_isCursor(current) || _isCursor(next)) { - return false; - } - if (_isImmutable(current) && _isImmutable(next)) { - return current === next; - } - if (_isImmutable(current) || _isImmutable(next)) { - return false; - } - return void 0; + if (current === next) return true; + + var cursorsEqual = compare(current, next, _isCursor, _isEqualCursor); + if (cursorsEqual !== void 0) return cursorsEqual; + + return compare(current, next, _isImmutable, isEqualImmutable); }); } + /** + * Predicate to check if cursors are equal through reference checks. Uses `unCursor`. + * Override through `shouldComponentUpdate.withDefaults` to support different cursor + * implementations. + * + * @param {Cursor} a + * @param {Cursor} b + * + * @module shouldComponentUpdate.isEqualCursor + * @returns {Boolean} + * @api public + */ function isEqualCursor (a, b) { return _unCursor(a) === _unCursor(b); } @@ -2053,24 +2905,67 @@ function factory (methods) { } } +function compare (current, next, typeCheck, equalCheck) { + var isCurrent = typeCheck(current); + var isNext = typeCheck(next); + + if (isCurrent && isNext) { + return equalCheck(current, next); + } + if (isCurrent || isNext) { + return false; + } + return void 0; +} + +function isEqualImmutable (a, b) { + return a === b; +} +/** + * Predicate to check if a potential is an immutable structure or not. + * Override through `shouldComponentUpdate.withDefaults` to support different cursor + * implementations. + * + * @param {maybeImmutable} value to check if it is immutable. + * + * @module shouldComponentUpdate.isImmutable + * @returns {Boolean} + * @api public + */ var IS_ITERABLE_SENTINEL = '@@__IMMUTABLE_ITERABLE__@@'; -function isImmutable(maybeIterable) { - return !!(maybeIterable && maybeIterable[IS_ITERABLE_SENTINEL]); +function isImmutable(maybeImmutable) { + return !!(maybeImmutable && maybeImmutable[IS_ITERABLE_SENTINEL]); } +/** + * Transforming function to take in cursor and return a non-cursor. + * Override through `shouldComponentUpdate.withDefaults` to support different cursor + * implementations. + * + * @param {cursor} cursor to transform + * + * @module shouldComponentUpdate.unCursor + * @returns {Object|Number|String|Boolean} + * @api public + */ function unCursor(cursor) { + if (!cursor || !cursor.deref) return cursor; return cursor.deref(); } +/** + * Predicate to check if `potential` is Immutable cursor or not (defaults to duck testing + * Immutable.js cursors). Can override through `.withDefaults()`. + * + * @param {potential} potential to check if is cursor + * + * @module shouldComponentUpdate.isCursor + * @returns {Boolean} + * @api public + */ function isCursor (potential) { - return potential && typeof potential.deref === 'function'; -} - -function hasDifferentKeys (currentCursorsKeys, currentCursors, nextCursors) { - return !currentCursorsKeys.every(function existsInBoth (key) { - return typeof currentCursors[key] !== 'undefined' && typeof nextCursors[key] !== 'undefined'; - }); + return !!(potential && typeof potential.deref === 'function'); } function not (fn) { @@ -2093,5 +2988,5 @@ function or (fn1, fn2) { }; } -},{"lodash.isequal":3,"lodash.pick":11}]},{},[1])(1) +},{"lodash.isequal":13,"lodash.pick":21}]},{},[1])(1) }); \ No newline at end of file diff --git a/dist/omniscient.min.js b/dist/omniscient.min.js index eb9538b..f342978 100644 --- a/dist/omniscient.min.js +++ b/dist/omniscient.min.js @@ -1,5 +1,5 @@ /** -* Omniscient.js v3.0.1 +* Omniscient.js v3.1.0 * Authors: @torgeir,@mikaelbr ***************************************/ -!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n;"undefined"!=typeof window?n=window:"undefined"!=typeof global?n=global:"undefined"!=typeof self&&(n=self),n.omniscient=t()}}(function(){return function t(n,r,e){function o(a,i){if(!r[a]){if(!n[a]){var c="function"==typeof require&&require;if(!i&&c)return c(a,!0);if(u)return u(a,!0);var s=new Error("Cannot find module '"+a+"'");throw s.code="MODULE_NOT_FOUND",s}var f=r[a]={exports:{}};n[a][0].call(f.exports,function(t){var r=n[a][1][t];return o(r?r:t)},f,f.exports,t,n,r,e)}return r[a].exports}for(var u="function"==typeof require&&require,a=0;a0:!o(t))}function e(t,n,e,o){if(e="function"==typeof e&&a(e,o,3),!e&&r(t)&&r(n))return t===n;var i=e?e(t,n):void 0;return"undefined"==typeof i?u(t,n,e):!!i}function o(t){var n=typeof t;return"function"==n||t&&"object"==n||!1}var u=t("lodash._baseisequal"),a=t("lodash._bindcallback");n.exports=e},{"lodash._baseisequal":4,"lodash._bindcallback":10}],4:[function(t,n){function r(t,n,o,u,a,i){if(t===n)return 0!==t||1/t==1/n;var c=typeof t,s=typeof n;return"function"!=c&&"object"!=c&&"function"!=s&&"object"!=s||null==t||null==n?t!==t&&n!==n:e(t,n,r,o,u,a,i)}function e(t,n,r,e,s,p,d){var y=i(t),h=i(n),v=l,g=l;y||(v=x.call(t),v==f?v=b:v!=b&&(y=c(t))),h||(g=x.call(n),g==f?g=b:g!=b&&(h=c(n)));var m=v==b,E=g==b,_=v==g;if(_&&!y&&!m)return u(t,n,v);var w=m&&j.call(t,"__wrapped__"),A=E&&j.call(n,"__wrapped__");if(w||A)return r(w?t.value():t,A?n.value():n,e,s,p,d);if(!_)return!1;p||(p=[]),d||(d=[]);for(var k=p.length;k--;)if(p[k]==t)return d[k]==n;p.push(t),d.push(n);var C=(y?o:a)(t,n,r,e,s,p,d);return p.pop(),d.pop(),C}function o(t,n,r,e,o,u,a){var i=-1,c=t.length,s=n.length,f=!0;if(c!=s&&!(o&&s>c))return!1;for(;f&&++i-1&&t%1==0&&v>=t}function u(t){return null==t?!1:y.call(t)==c?h.test(d.call(t)):e(t)&&s.test(t)||!1}function a(t){return t=r(t),t&&l.test(t)?t.replace(f,"\\$&"):t}var i="[object Array]",c="[object Function]",s=/^\[object .+?Constructor\]$/,f=/[.*+?^${}()|[\]\/\\]/g,l=RegExp(f.source),p=Object.prototype,d=Function.prototype.toString,y=p.toString,h=RegExp("^"+a(y).replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),b=u(b=Array.isArray)&&b,v=Math.pow(2,53)-1,g=b||function(t){return e(t)&&o(t.length)&&y.call(t)==i||!1};n.exports=g},{}],6:[function(t,n){function r(t){return t&&"object"==typeof t||!1}function e(t){return"number"==typeof t&&t>-1&&t%1==0&&q>=t}function o(t){return r(t)&&e(t.length)&&O[I.call(t)]||!1}var u="[object Arguments]",a="[object Array]",i="[object Boolean]",c="[object Date]",s="[object Error]",f="[object Function]",l="[object Map]",p="[object Number]",d="[object Object]",y="[object RegExp]",h="[object Set]",b="[object String]",v="[object WeakMap]",g="[object ArrayBuffer]",m="[object Float32Array]",j="[object Float64Array]",x="[object Int8Array]",E="[object Int16Array]",_="[object Int32Array]",w="[object Uint8Array]",A="[object Uint8ClampedArray]",k="[object Uint16Array]",C="[object Uint32Array]",O={};O[m]=O[j]=O[x]=O[E]=O[_]=O[w]=O[A]=O[k]=O[C]=!0,O[u]=O[a]=O[g]=O[i]=O[c]=O[s]=O[f]=O[l]=O[p]=O[d]=O[y]=O[h]=O[b]=O[v]=!1;var U=Object.prototype,I=U.toString,q=Math.pow(2,53)-1;n.exports=o},{}],7:[function(t,n){function r(t,n){return t=+t,n=null==n?y:n,t>-1&&t%1==0&&n>t}function e(t){return"number"==typeof t&&t>-1&&t%1==0&&y>=t}function o(t){for(var n=a(t),o=n.length,u=o&&t.length,s=u&&e(u)&&(c(t)||h.nonEnumArgs&&i(t)),f=-1,p=[];++f0;++a-1&&t%1==0&&c>=t}function o(t){var n=r(t)?t.length:void 0;return e(n)&&i.call(t)==u||!1}var u="[object Arguments]",a=Object.prototype,i=a.toString,c=Math.pow(2,53)-1;n.exports=o},{}],9:[function(t,n){function r(t){return"string"==typeof t?t:null==t?"":t+""}function e(t){return t&&"object"==typeof t||!1}function o(t){return null==t?!1:p.call(t)==a?d.test(l.call(t)):e(t)&&i.test(t)||!1}function u(t){return t=r(t),t&&s.test(t)?t.replace(c,"\\$&"):t}var a="[object Function]",i=/^\[object .+?Constructor\]$/,c=/[.*+?^${}()|[\]\/\\]/g,s=RegExp(c.source),f=Object.prototype,l=Function.prototype.toString,p=f.toString,d=RegExp("^"+u(p).replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");n.exports=o},{}],10:[function(t,n){function r(t,n,r){if("function"!=typeof t)return e;if("undefined"==typeof n)return t;switch(r){case 1:return function(r){return t.call(n,r)};case 3:return function(r,e,o){return t.call(n,r,e,o)};case 4:return function(r,e,o,u){return t.call(n,r,e,o,u)};case 5:return function(r,e,o,u,a){return t.call(n,r,e,o,u,a)}}return function(){return t.apply(n,arguments)}}function e(t){return t}n.exports=r},{}],11:[function(t,n){function r(t,n,r){return null==t?{}:"function"==typeof n?a(t,o(n,r,3)):u(t,e(arguments,!1,!1,1))}var e=t("lodash._baseflatten"),o=t("lodash._bindcallback"),u=t("lodash._pickbyarray"),a=t("lodash._pickbycallback");n.exports=r},{"lodash._baseflatten":12,"lodash._bindcallback":15,"lodash._pickbyarray":16,"lodash._pickbycallback":17}],12:[function(t,n){function r(t){return t&&"object"==typeof t||!1}function e(t,n,i,c){for(var s=(c||0)-1,f=t.length,l=-1,p=[];++s-1&&t%1==0&&i>=t}var u=t("lodash.isarguments"),a=t("lodash.isarray"),i=Math.pow(2,53)-1;n.exports=e},{"lodash.isarguments":13,"lodash.isarray":14}],13:[function(t,n,r){arguments[4][8][0].apply(r,arguments)},{dup:8}],14:[function(t,n,r){arguments[4][5][0].apply(r,arguments)},{dup:5}],15:[function(t,n,r){arguments[4][10][0].apply(r,arguments)},{dup:10}],16:[function(t,n){function r(t,n){t=e(t);for(var r=-1,o=n.length,u={};++r-1&&t%1==0&&n>t}function e(t){return"number"==typeof t&&t>-1&&t%1==0&&l>=t}function o(t){var n=typeof t;return"function"==n||t&&"object"==n||!1}function u(t){if(null==t)return[];o(t)||(t=Object(t));var n=t.length;n=n&&e(n)&&(i(t)||p.nonEnumArgs&&a(t))&&n||0;for(var u=t.constructor,c=-1,f="function"==typeof u&&u.prototype==t,l=Array(n),d=n>0;++c true (number of cursors differ)"),!0):a(y,u,o)?(g&&g.call(this,"shouldComponentUpdate => true (cursors have different keys)"),!0):r(u,o)?(g&&g.call(this,"shouldComponentUpdate => true (cursors have changed)"),!0):x(this.state,n)?d(u,o)?(g&&g.call(this,"shouldComponentUpdate => true (properties have changed)"),!0):(g&&g.call(this,"shouldComponentUpdate => false"),!1):(g&&g.call(this,"shouldComponentUpdate => true (state has changed)"),!0)}function r(t,n){t=l(t,m),n=l(n,m);for(var r in t)if(!j(t[r],n[r]))return!0;return!1}function d(t,n){t=l(t,i(m)),n=l(n,i(m));for(var r in t)if(!E(t[r],n[r]))return!0;return!1}function y(t,n){return p(t,n,function(t,n){return _(t)&&_(n)?t===n:_(t)||_(n)?!1:void 0})}function h(t,n){return p(t,n,function(t,n){return m(t)&&m(n)?b(t,n):m(t)||m(n)?!1:_(t)&&_(n)?t===n:_(t)||_(n)?!1:void 0})}function b(t,n){return w(t)===w(n)}function v(t,n){"function"==typeof t&&(n=t,t=void 0);var r=n;!r&&console.debug&&(r=console.debug.bind(console)),!r&&console.info&&(r=console.info.bind(console));var e=new RegExp(t||".*");return g=function(t){var n=this._currentElement;this._reactInternalInstance&&this._reactInternalInstance._currentElement&&(n=this._reactInternalInstance._currentElement);var o=n&&n.key?" key="+n.key:"",u=this.constructor.displayName;o||u||(u="Unknown");var a=u+o;e.test(a)&&r("<"+a+">: "+t)}}var g;t=t||{};var m=t.isCursor||u,j=t.isEqualCursor||b,x=t.isEqualState||y,E=t.isEqualProps||h,_=t.isImmutable||e,w=t.unCursor||o;return n.isCursor=m,n.isEqualState=x,n.isEqualProps=E,n.isEqualCursor=j,n.isImmutable=_,n.debug=v,n}function e(t){return!(!t||!t[d])}function o(t){return t.deref()}function u(t){return t&&"function"==typeof t.deref}function a(t,n,r){return!t.every(function(t){return"undefined"!=typeof n[t]&&"undefined"!=typeof r[t]})}function i(t){return function(){return!t.apply(t,arguments)}}function c(t,n){return"statics"===n}function s(t,n){return"children"===n}function f(t,n){return function(){return t.apply(null,arguments)||n.apply(null,arguments)}}var l=t("lodash.pick"),p=t("lodash.isequal");n.exports=r(),n.exports.withDefaults=r;var d="@@__IMMUTABLE_ITERABLE__@@"},{"lodash.isequal":3,"lodash.pick":11}]},{},[1])(1)}); \ No newline at end of file +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var n;"undefined"!=typeof window?n=window:"undefined"!=typeof global?n=global:"undefined"!=typeof self&&(n=self),n.omniscient=t()}}(function(){return function t(n,r,e){function o(a,i){if(!r[a]){if(!n[a]){var c="function"==typeof require&&require;if(!i&&c)return c(a,!0);if(u)return u(a,!0);var s=new Error("Cannot find module '"+a+"'");throw s.code="MODULE_NOT_FOUND",s}var f=r[a]={exports:{}};n[a][0].call(f.exports,function(t){var r=n[a][1][t];return o(r?r:t)},f,f.exports,t,n,r,e)}return r[a].exports}for(var u="function"==typeof require&&require,a=0;a-1&&t%1==0&&n>t}function e(t){return"number"==typeof t&&t>-1&&t%1==0&&y>=t}function o(t){for(var n=a(t),o=n.length,u=o&&t.length,s=u&&e(u)&&(c(t)||h.nonEnumArgs&&i(t)),f=-1,p=[];++f0;++a-1&&t%1==0&&c>=t}function o(t){var n=r(t)?t.length:void 0;return e(n)&&i.call(t)==u||!1}var u="[object Arguments]",a=Object.prototype,i=a.toString,c=Math.pow(2,53)-1;n.exports=o},{}],8:[function(t,n){function r(t){return"string"==typeof t?t:null==t?"":t+""}function e(t){return t&&"object"==typeof t||!1}function o(t){return"number"==typeof t&&t>-1&&t%1==0&&v>=t}function u(t){return null==t?!1:y.call(t)==c?h.test(d.call(t)):e(t)&&s.test(t)||!1}function a(t){return t=r(t),t&&l.test(t)?t.replace(f,"\\$&"):t}var i="[object Array]",c="[object Function]",s=/^\[object .+?Constructor\]$/,f=/[.*+?^${}()|[\]\/\\]/g,l=RegExp(f.source),p=Object.prototype,d=Function.prototype.toString,y=p.toString,h=RegExp("^"+a(y).replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),g=u(g=Array.isArray)&&g,v=Math.pow(2,53)-1,b=g||function(t){return e(t)&&o(t.length)&&y.call(t)==i||!1};n.exports=b},{}],9:[function(t,n){function r(t){return"string"==typeof t?t:null==t?"":t+""}function e(t){return t&&"object"==typeof t||!1}function o(t){return null==t?!1:p.call(t)==a?d.test(l.call(t)):e(t)&&i.test(t)||!1}function u(t){return t=r(t),t&&s.test(t)?t.replace(c,"\\$&"):t}var a="[object Function]",i=/^\[object .+?Constructor\]$/,c=/[.*+?^${}()|[\]\/\\]/g,s=RegExp(c.source),f=Object.prototype,l=Function.prototype.toString,p=f.toString,d=RegExp("^"+u(p).replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");n.exports=o},{}],10:[function(t,n){function r(t){return function(){var n=arguments.length,r=arguments[0];if(2>n||null==r)return r;if(n>3&&o(arguments[1],arguments[2],arguments[3])&&(n=2),n>3&&"function"==typeof arguments[n-2])var u=e(arguments[--n-1],arguments[n--],5);else n>2&&"function"==typeof arguments[n-1]&&(u=arguments[--n]);for(var a=0;++a-1&&t%1==0&&n>t}function e(t,n,e){if(!u(e))return!1;var a=typeof n;if("number"==a)var i=e.length,c=o(i)&&r(n,i);else c="string"==a&&n in e;var s=e[n];return c&&(t===t?t===s:s!==s)}function o(t){return"number"==typeof t&&t>-1&&t%1==0&&a>=t}function u(t){var n=typeof t;return"function"==n||t&&"object"==n||!1}var a=Math.pow(2,53)-1;n.exports=e},{}],13:[function(t,n){function r(t){return t===t&&(0===t?1/t>0:!o(t))}function e(t,n,e,o){if(e="function"==typeof e&&a(e,o,3),!e&&r(t)&&r(n))return t===n;var i=e?e(t,n):void 0;return"undefined"==typeof i?u(t,n,e):!!i}function o(t){var n=typeof t;return"function"==n||t&&"object"==n||!1}var u=t("lodash._baseisequal"),a=t("lodash._bindcallback");n.exports=e},{"lodash._baseisequal":14,"lodash._bindcallback":20}],14:[function(t,n){function r(t,n,o,u,a,i){if(t===n)return 0!==t||1/t==1/n;var c=typeof t,s=typeof n;return"function"!=c&&"object"!=c&&"function"!=s&&"object"!=s||null==t||null==n?t!==t&&n!==n:e(t,n,r,o,u,a,i)}function e(t,n,r,e,s,p,d){var y=i(t),h=i(n),v=l,b=l;y||(v=x.call(t),v==f?v=g:v!=g&&(y=c(t))),h||(b=x.call(n),b==f?b=g:b!=g&&(h=c(n)));var m=v==g,_=b==g,E=v==b;if(E&&!y&&!m)return u(t,n,v);var A=m&&j.call(t,"__wrapped__"),w=_&&j.call(n,"__wrapped__");if(A||w)return r(A?t.value():t,w?n.value():n,e,s,p,d);if(!E)return!1;p||(p=[]),d||(d=[]);for(var k=p.length;k--;)if(p[k]==t)return d[k]==n;p.push(t),d.push(n);var O=(y?o:a)(t,n,r,e,s,p,d);return p.pop(),d.pop(),O}function o(t,n,r,e,o,u,a){var i=-1,c=t.length,s=n.length,f=!0;if(c!=s&&!(o&&s>c))return!1;for(;f&&++i-1&&t%1==0&&q>=t}function o(t){return r(t)&&e(t.length)&&C[I.call(t)]||!1}var u="[object Arguments]",a="[object Array]",i="[object Boolean]",c="[object Date]",s="[object Error]",f="[object Function]",l="[object Map]",p="[object Number]",d="[object Object]",y="[object RegExp]",h="[object Set]",g="[object String]",v="[object WeakMap]",b="[object ArrayBuffer]",m="[object Float32Array]",j="[object Float64Array]",x="[object Int8Array]",_="[object Int16Array]",E="[object Int32Array]",A="[object Uint8Array]",w="[object Uint8ClampedArray]",k="[object Uint16Array]",O="[object Uint32Array]",C={};C[m]=C[j]=C[x]=C[_]=C[E]=C[A]=C[w]=C[k]=C[O]=!0,C[u]=C[a]=C[b]=C[i]=C[c]=C[s]=C[f]=C[l]=C[p]=C[d]=C[y]=C[h]=C[g]=C[v]=!1;var M=Object.prototype,I=M.toString,q=Math.pow(2,53)-1;n.exports=o},{}],17:[function(t,n){function r(t,n){return t=+t,n=null==n?y:n,t>-1&&t%1==0&&n>t}function e(t){return"number"==typeof t&&t>-1&&t%1==0&&y>=t}function o(t){for(var n=a(t),o=n.length,u=o&&t.length,s=u&&e(u)&&(c(t)||h.nonEnumArgs&&i(t)),f=-1,p=[];++f0;++a-1&&t%1==0&&i>=t}var u=t("lodash.isarguments"),a=t("lodash.isarray"),i=Math.pow(2,53)-1;n.exports=e},{"lodash.isarguments":23,"lodash.isarray":24}],23:[function(t,n,r){arguments[4][7][0].apply(r,arguments)},{dup:7}],24:[function(t,n,r){arguments[4][8][0].apply(r,arguments)},{dup:8}],25:[function(t,n,r){arguments[4][11][0].apply(r,arguments)},{dup:11}],26:[function(t,n){function r(t,n){t=e(t);for(var r=-1,o=n.length,u={};++r-1&&t%1==0&&n>t}function e(t){return"number"==typeof t&&t>-1&&t%1==0&&l>=t}function o(t){var n=typeof t;return"function"==n||t&&"object"==n||!1}function u(t){if(null==t)return[];o(t)||(t=Object(t));var n=t.length;n=n&&e(n)&&(i(t)||p.nonEnumArgs&&a(t))&&n||0;for(var u=t.constructor,c=-1,f="function"==typeof u&&u.prototype==t,l=Array(n),d=n>0;++c false (equal input)"),!1;if(!v(this.state,n))return l&&l.call(this,"shouldComponentUpdate => true (state has changed)"),!0;var t=p(t,y),r=p(this.props,y);return b(r,t)?(l&&l.call(this,"shouldComponentUpdate => false"),!1):(l&&l.call(this,"shouldComponentUpdate => true (props have changed)"),!0)}function r(t,n){return d(t,n,function(t,n){return t===n?!0:e(t,n,m,o)})}function c(t,n){if(t===n)return!0;var r=e(t,n,h,g);if(void 0!==r)return r;var u=e(t,n,m,o);return void 0!==u?u:d(t,n,function(t,n){if(t===n)return!0;var r=e(t,n,h,g);return void 0!==r?r:e(t,n,m,o)})}function s(t,n){return j(t)===j(n)}function f(t,n){"function"==typeof t&&(n=t,t=void 0);var r=n;!r&&console.debug&&(r=console.debug.bind(console)),!r&&console.info&&(r=console.info.bind(console));var e=new RegExp(t||".*");return l=function(t){var n=this._currentElement;this._reactInternalInstance&&this._reactInternalInstance._currentElement&&(n=this._reactInternalInstance._currentElement);var o=n&&n.key?" key="+n.key:"",u=this.constructor.displayName;o||u||(u="Unknown");var a=u+o;e.test(a)&&r("<"+a+">: "+t)}}var l;t=t||{};var h=t.isCursor||i,g=t.isEqualCursor||s,v=t.isEqualState||r,b=t.isEqualProps||c,m=t.isImmutable||u,j=t.unCursor||a;return n.isCursor=h,n.isEqualState=v,n.isEqualProps=b,n.isEqualCursor=g,n.isImmutable=m,n.debug=f,n}function e(t,n,r,e){var o=r(t),u=r(n);return o&&u?e(t,n):o||u?!1:void 0}function o(t,n){return t===n}function u(t){return!(!t||!t[h])}function a(t){return t&&t.deref?t.deref():t}function i(t){return!(!t||"function"!=typeof t.deref)}function c(t){return function(){return!t.apply(t,arguments)}}function s(t,n){return"statics"===n}function f(t,n){return"children"===n}function l(t,n){return function(){return t.apply(null,arguments)||n.apply(null,arguments)}}var p=t("lodash.pick"),d=t("lodash.isequal"),y=c(l(s,f));n.exports=r(),n.exports.withDefaults=r;var h="@@__IMMUTABLE_ITERABLE__@@"},{"lodash.isequal":13,"lodash.pick":21}]},{},[1])(1)}); \ No newline at end of file diff --git a/package.json b/package.json index a6cb024..dd440f8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "omniscient", - "version": "3.0.1", + "version": "3.1.0", "description": "A library providing an abstraction for React components for passing the same data structure through the entire component flow using cursors and immutable data structures.", "main": "component.js", "directories": {