diff options
Diffstat (limited to 'www/crm/wp-content/plugins/civicrm/civicrm/bower_components/crossfilter2/crossfilter.js')
-rw-r--r-- | www/crm/wp-content/plugins/civicrm/civicrm/bower_components/crossfilter2/crossfilter.js | 3167 |
1 files changed, 3167 insertions, 0 deletions
diff --git a/www/crm/wp-content/plugins/civicrm/civicrm/bower_components/crossfilter2/crossfilter.js b/www/crm/wp-content/plugins/civicrm/civicrm/bower_components/crossfilter2/crossfilter.js new file mode 100644 index 00000000..cb70794b --- /dev/null +++ b/www/crm/wp-content/plugins/civicrm/civicrm/bower_components/crossfilter2/crossfilter.js @@ -0,0 +1,3167 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.crossfilter = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ +module.exports = require("./src/crossfilter").crossfilter; + +},{"./src/crossfilter":6}],2:[function(require,module,exports){ +(function (global){ +/** + * lodash (Custom Build) <https://lodash.com/> + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors <https://jquery.org/> + * Released under MIT license <https://lodash.com/license> + * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE> + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + +/** Used as the `TypeError` message for "Functions" methods. */ +var FUNC_ERROR_TEXT = 'Expected a function'; + +/** Used to stand-in for `undefined` hash values. */ +var HASH_UNDEFINED = '__lodash_hash_undefined__'; + +/** Used as references for various `Number` constants. */ +var INFINITY = 1 / 0; + +/** `Object#toString` result references. */ +var funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + symbolTag = '[object Symbol]'; + +/** Used to match property names within property paths. */ +var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + reLeadingDot = /^\./, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + +/** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). + */ +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; + +/** Used to match backslashes in property paths. */ +var reEscapeChar = /\\(\\)?/g; + +/** Used to detect host constructors (Safari). */ +var reIsHostCtor = /^\[object .+?Constructor\]$/; + +/** Detect free variable `global` from Node.js. */ +var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + +/** Detect free variable `self`. */ +var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + +/** Used as a reference to the global object. */ +var root = freeGlobal || freeSelf || Function('return this')(); + +/** + * Gets the value at `key` of `object`. + * + * @private + * @param {Object} [object] The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ +function getValue(object, key) { + return object == null ? undefined : object[key]; +} + +/** + * Checks if `value` is a host object in IE < 9. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a host object, else `false`. + */ +function isHostObject(value) { + // Many host objects are `Object` objects that can coerce to strings + // despite having improperly defined `toString` methods. + var result = false; + if (value != null && typeof value.toString != 'function') { + try { + result = !!(value + ''); + } catch (e) {} + } + return result; +} + +/** Used for built-in method references. */ +var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + +/** Used to detect overreaching core-js shims. */ +var coreJsData = root['__core-js_shared__']; + +/** Used to detect methods masquerading as native. */ +var maskSrcKey = (function() { + var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); + return uid ? ('Symbol(src)_1.' + uid) : ''; +}()); + +/** Used to resolve the decompiled source of functions. */ +var funcToString = funcProto.toString; + +/** Used to check objects for own properties. */ +var hasOwnProperty = objectProto.hasOwnProperty; + +/** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ +var objectToString = objectProto.toString; + +/** Used to detect if a method is native. */ +var reIsNative = RegExp('^' + + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') + .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' +); + +/** Built-in value references. */ +var Symbol = root.Symbol, + splice = arrayProto.splice; + +/* Built-in method references that are verified to be native. */ +var Map = getNative(root, 'Map'), + nativeCreate = getNative(Object, 'create'); + +/** Used to convert symbols to primitives and strings. */ +var symbolProto = Symbol ? Symbol.prototype : undefined, + symbolToString = symbolProto ? symbolProto.toString : undefined; + +/** + * Creates a hash object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function Hash(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the hash. + * + * @private + * @name clear + * @memberOf Hash + */ +function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; +} + +/** + * Removes `key` and its value from the hash. + * + * @private + * @name delete + * @memberOf Hash + * @param {Object} hash The hash to modify. + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; +} + +/** + * Gets the hash value for `key`. + * + * @private + * @name get + * @memberOf Hash + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function hashGet(key) { + var data = this.__data__; + if (nativeCreate) { + var result = data[key]; + return result === HASH_UNDEFINED ? undefined : result; + } + return hasOwnProperty.call(data, key) ? data[key] : undefined; +} + +/** + * Checks if a hash value for `key` exists. + * + * @private + * @name has + * @memberOf Hash + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function hashHas(key) { + var data = this.__data__; + return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); +} + +/** + * Sets the hash `key` to `value`. + * + * @private + * @name set + * @memberOf Hash + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the hash instance. + */ +function hashSet(key, value) { + var data = this.__data__; + data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; + return this; +} + +// Add methods to `Hash`. +Hash.prototype.clear = hashClear; +Hash.prototype['delete'] = hashDelete; +Hash.prototype.get = hashGet; +Hash.prototype.has = hashHas; +Hash.prototype.set = hashSet; + +/** + * Creates an list cache object. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function ListCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the list cache. + * + * @private + * @name clear + * @memberOf ListCache + */ +function listCacheClear() { + this.__data__ = []; +} + +/** + * Removes `key` and its value from the list cache. + * + * @private + * @name delete + * @memberOf ListCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function listCacheDelete(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + return false; + } + var lastIndex = data.length - 1; + if (index == lastIndex) { + data.pop(); + } else { + splice.call(data, index, 1); + } + return true; +} + +/** + * Gets the list cache value for `key`. + * + * @private + * @name get + * @memberOf ListCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function listCacheGet(key) { + var data = this.__data__, + index = assocIndexOf(data, key); + + return index < 0 ? undefined : data[index][1]; +} + +/** + * Checks if a list cache value for `key` exists. + * + * @private + * @name has + * @memberOf ListCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; +} + +/** + * Sets the list cache `key` to `value`. + * + * @private + * @name set + * @memberOf ListCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the list cache instance. + */ +function listCacheSet(key, value) { + var data = this.__data__, + index = assocIndexOf(data, key); + + if (index < 0) { + data.push([key, value]); + } else { + data[index][1] = value; + } + return this; +} + +// Add methods to `ListCache`. +ListCache.prototype.clear = listCacheClear; +ListCache.prototype['delete'] = listCacheDelete; +ListCache.prototype.get = listCacheGet; +ListCache.prototype.has = listCacheHas; +ListCache.prototype.set = listCacheSet; + +/** + * Creates a map cache object to store key-value pairs. + * + * @private + * @constructor + * @param {Array} [entries] The key-value pairs to cache. + */ +function MapCache(entries) { + var index = -1, + length = entries ? entries.length : 0; + + this.clear(); + while (++index < length) { + var entry = entries[index]; + this.set(entry[0], entry[1]); + } +} + +/** + * Removes all key-value entries from the map. + * + * @private + * @name clear + * @memberOf MapCache + */ +function mapCacheClear() { + this.__data__ = { + 'hash': new Hash, + 'map': new (Map || ListCache), + 'string': new Hash + }; +} + +/** + * Removes `key` and its value from the map. + * + * @private + * @name delete + * @memberOf MapCache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed, else `false`. + */ +function mapCacheDelete(key) { + return getMapData(this, key)['delete'](key); +} + +/** + * Gets the map value for `key`. + * + * @private + * @name get + * @memberOf MapCache + * @param {string} key The key of the value to get. + * @returns {*} Returns the entry value. + */ +function mapCacheGet(key) { + return getMapData(this, key).get(key); +} + +/** + * Checks if a map value for `key` exists. + * + * @private + * @name has + * @memberOf MapCache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ +function mapCacheHas(key) { + return getMapData(this, key).has(key); +} + +/** + * Sets the map `key` to `value`. + * + * @private + * @name set + * @memberOf MapCache + * @param {string} key The key of the value to set. + * @param {*} value The value to set. + * @returns {Object} Returns the map cache instance. + */ +function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; +} + +// Add methods to `MapCache`. +MapCache.prototype.clear = mapCacheClear; +MapCache.prototype['delete'] = mapCacheDelete; +MapCache.prototype.get = mapCacheGet; +MapCache.prototype.has = mapCacheHas; +MapCache.prototype.set = mapCacheSet; + +/** + * Gets the index at which the `key` is found in `array` of key-value pairs. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} key The key to search for. + * @returns {number} Returns the index of the matched value, else `-1`. + */ +function assocIndexOf(array, key) { + var length = array.length; + while (length--) { + if (eq(array[length][0], key)) { + return length; + } + } + return -1; +} + +/** + * The base implementation of `_.isNative` without bad shim checks. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, + * else `false`. + */ +function baseIsNative(value) { + if (!isObject(value) || isMasked(value)) { + return false; + } + var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); +} + +/** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ +function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/** + * Casts `value` to a path array if it's not one. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast property path array. + */ +function castPath(value) { + return isArray(value) ? value : stringToPath(value); +} + +/** + * Gets the data for `map`. + * + * @private + * @param {Object} map The map to query. + * @param {string} key The reference key. + * @returns {*} Returns the map data. + */ +function getMapData(map, key) { + var data = map.__data__; + return isKeyable(key) + ? data[typeof key == 'string' ? 'string' : 'hash'] + : data.map; +} + +/** + * Gets the native function at `key` of `object`. + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the method to get. + * @returns {*} Returns the function if it's native, else `undefined`. + */ +function getNative(object, key) { + var value = getValue(object, key); + return baseIsNative(value) ? value : undefined; +} + +/** + * Checks if `value` is a property name and not a property path. + * + * @private + * @param {*} value The value to check. + * @param {Object} [object] The object to query keys on. + * @returns {boolean} Returns `true` if `value` is a property name, else `false`. + */ +function isKey(value, object) { + if (isArray(value)) { + return false; + } + var type = typeof value; + if (type == 'number' || type == 'symbol' || type == 'boolean' || + value == null || isSymbol(value)) { + return true; + } + return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || + (object != null && value in Object(object)); +} + +/** + * Checks if `value` is suitable for use as unique object key. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is suitable, else `false`. + */ +function isKeyable(value) { + var type = typeof value; + return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') + ? (value !== '__proto__') + : (value === null); +} + +/** + * Checks if `func` has its source masked. + * + * @private + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` is masked, else `false`. + */ +function isMasked(func) { + return !!maskSrcKey && (maskSrcKey in func); +} + +/** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ +var stringToPath = memoize(function(string) { + string = toString(string); + + var result = []; + if (reLeadingDot.test(string)) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; +}); + +/** + * Converts `value` to a string key if it's not a string or symbol. + * + * @private + * @param {*} value The value to inspect. + * @returns {string|symbol} Returns the key. + */ +function toKey(value) { + if (typeof value == 'string' || isSymbol(value)) { + return value; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; +} + +/** + * Converts `func` to its source code. + * + * @private + * @param {Function} func The function to process. + * @returns {string} Returns the source code. + */ +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e) {} + try { + return (func + ''); + } catch (e) {} + } + return ''; +} + +/** + * Creates a function that memoizes the result of `func`. If `resolver` is + * provided, it determines the cache key for storing the result based on the + * arguments provided to the memoized function. By default, the first argument + * provided to the memoized function is used as the map cache key. The `func` + * is invoked with the `this` binding of the memoized function. + * + * **Note:** The cache is exposed as the `cache` property on the memoized + * function. Its creation may be customized by replacing the `_.memoize.Cache` + * constructor with one whose instances implement the + * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `delete`, `get`, `has`, and `set`. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Function + * @param {Function} func The function to have its output memoized. + * @param {Function} [resolver] The function to resolve the cache key. + * @returns {Function} Returns the new memoized function. + * @example + * + * var object = { 'a': 1, 'b': 2 }; + * var other = { 'c': 3, 'd': 4 }; + * + * var values = _.memoize(_.values); + * values(object); + * // => [1, 2] + * + * values(other); + * // => [3, 4] + * + * object.a = 2; + * values(object); + * // => [1, 2] + * + * // Modify the result cache. + * values.cache.set(object, ['a', 'b']); + * values(object); + * // => ['a', 'b'] + * + * // Replace `_.memoize.Cache`. + * _.memoize.Cache = WeakMap; + */ +function memoize(func, resolver) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); + } + var memoized = function() { + var args = arguments, + key = resolver ? resolver.apply(this, args) : args[0], + cache = memoized.cache; + + if (cache.has(key)) { + return cache.get(key); + } + var result = func.apply(this, args); + memoized.cache = cache.set(key, result); + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; +} + +// Assign cache to `_.memoize`. +memoize.Cache = MapCache; + +/** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'a': 1 }; + * var other = { 'a': 1 }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ +function eq(value, other) { + return value === other || (value !== value && other !== other); +} + +/** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ +var isArray = Array.isArray; + +/** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ +function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8-9 which returns 'object' for typed array and other constructors. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; +} + +/** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @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(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ +function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); +} + +/** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ +function isObjectLike(value) { + return !!value && typeof value == 'object'; +} + +/** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ +function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); +} + +/** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {string} Returns the string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ +function toString(value) { + return value == null ? '' : baseToString(value); +} + +/** + * This method is like `_.get` except that if the resolved value is a + * function it's invoked with the `this` binding of its parent object and + * its result is returned. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path of the property to resolve. + * @param {*} [defaultValue] The value returned for `undefined` resolved values. + * @returns {*} Returns the resolved value. + * @example + * + * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; + * + * _.result(object, 'a[0].b.c1'); + * // => 3 + * + * _.result(object, 'a[0].b.c2'); + * // => 4 + * + * _.result(object, 'a[0].b.c3', 'default'); + * // => 'default' + * + * _.result(object, 'a[0].b.c3', _.constant('default')); + * // => 'default' + */ +function result(object, path, defaultValue) { + path = isKey(path, object) ? [path] : castPath(path); + + var index = -1, + length = path.length; + + // Ensure the loop is entered when path is empty. + if (!length) { + object = undefined; + length = 1; + } + while (++index < length) { + var value = object == null ? undefined : object[toKey(path[index])]; + if (value === undefined) { + index = length; + value = defaultValue; + } + object = isFunction(value) ? value.call(object) : value; + } + return object; +} + +module.exports = result; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],3:[function(require,module,exports){ +module.exports={"version":"1.4.7"} +},{}],4:[function(require,module,exports){ +if (typeof Uint8Array !== "undefined") { + var crossfilter_array8 = function(n) { return new Uint8Array(n); }; + var crossfilter_array16 = function(n) { return new Uint16Array(n); }; + var crossfilter_array32 = function(n) { return new Uint32Array(n); }; + + var crossfilter_arrayLengthen = function(array, length) { + if (array.length >= length) return array; + var copy = new array.constructor(length); + copy.set(array); + return copy; + }; + + var crossfilter_arrayWiden = function(array, width) { + var copy; + switch (width) { + case 16: copy = crossfilter_array16(array.length); break; + case 32: copy = crossfilter_array32(array.length); break; + default: throw new Error("invalid array width!"); + } + copy.set(array); + return copy; + }; +} + +function crossfilter_arrayUntyped(n) { + var array = new Array(n), i = -1; + while (++i < n) array[i] = 0; + return array; +} + +function crossfilter_arrayLengthenUntyped(array, length) { + var n = array.length; + while (n < length) array[n++] = 0; + return array; +} + +function crossfilter_arrayWidenUntyped(array, width) { + if (width > 32) throw new Error("invalid array width!"); + return array; +} + +// An arbitrarily-wide array of bitmasks +function crossfilter_bitarray(n) { + this.length = n; + this.subarrays = 1; + this.width = 8; + this.masks = { + 0: 0 + } + + this[0] = crossfilter_array8(n); +} + +crossfilter_bitarray.prototype.lengthen = function(n) { + var i, len; + for (i = 0, len = this.subarrays; i < len; ++i) { + this[i] = crossfilter_arrayLengthen(this[i], n); + } + this.length = n; +}; + +// Reserve a new bit index in the array, returns {offset, one} +crossfilter_bitarray.prototype.add = function() { + var m, w, one, i, len; + + for (i = 0, len = this.subarrays; i < len; ++i) { + m = this.masks[i]; + w = this.width - (32 * i); + one = ~m & -~m; + + if (w >= 32 && !one) { + continue; + } + + if (w < 32 && (one & (1 << w))) { + // widen this subarray + this[i] = crossfilter_arrayWiden(this[i], w <<= 1); + this.width = 32 * i + w; + } + + this.masks[i] |= one; + + return { + offset: i, + one: one + }; + } + + // add a new subarray + this[this.subarrays] = crossfilter_array8(this.length); + this.masks[this.subarrays] = 1; + this.width += 8; + return { + offset: this.subarrays++, + one: 1 + }; +}; + +// Copy record from index src to index dest +crossfilter_bitarray.prototype.copy = function(dest, src) { + var i, len; + for (i = 0, len = this.subarrays; i < len; ++i) { + this[i][dest] = this[i][src]; + } +}; + +// Truncate the array to the given length +crossfilter_bitarray.prototype.truncate = function(n) { + var i, len; + for (i = 0, len = this.subarrays; i < len; ++i) { + for (var j = this.length - 1; j >= n; j--) { + this[i][j] = 0; + } + this[i].length = n; + } + this.length = n; +}; + +// Checks that all bits for the given index are 0 +crossfilter_bitarray.prototype.zero = function(n) { + var i, len; + for (i = 0, len = this.subarrays; i < len; ++i) { + if (this[i][n]) { + return false; + } + } + return true; +}; + +// Checks that all bits for the given index are 0 except for possibly one +crossfilter_bitarray.prototype.zeroExcept = function(n, offset, zero) { + var i, len; + for (i = 0, len = this.subarrays; i < len; ++i) { + if (i === offset ? this[i][n] & zero : this[i][n]) { + return false; + } + } + return true; +}; + +// Checks that all bits for the given indez are 0 except for the specified mask. +// The mask should be an array of the same size as the filter subarrays width. +crossfilter_bitarray.prototype.zeroExceptMask = function(n, mask) { + var i, len; + for (i = 0, len = this.subarrays; i < len; ++i) { + if (this[i][n] & mask[i]) { + return false; + } + } + return true; +} + +// Checks that only the specified bit is set for the given index +crossfilter_bitarray.prototype.only = function(n, offset, one) { + var i, len; + for (i = 0, len = this.subarrays; i < len; ++i) { + if (this[i][n] != (i === offset ? one : 0)) { + return false; + } + } + return true; +}; + +// Checks that only the specified bit is set for the given index except for possibly one other +crossfilter_bitarray.prototype.onlyExcept = function(n, offset, zero, onlyOffset, onlyOne) { + var mask; + var i, len; + for (i = 0, len = this.subarrays; i < len; ++i) { + mask = this[i][n]; + if (i === offset) + mask &= zero; + if (mask != (i === onlyOffset ? onlyOne : 0)) { + return false; + } + } + return true; +}; + +module.exports = { + array8: crossfilter_arrayUntyped, + array16: crossfilter_arrayUntyped, + array32: crossfilter_arrayUntyped, + arrayLengthen: crossfilter_arrayLengthenUntyped, + arrayWiden: crossfilter_arrayWidenUntyped, + bitarray: crossfilter_bitarray +}; + +},{}],5:[function(require,module,exports){ +'use strict'; + +var crossfilter_identity = require('./identity'); + +function bisect_by(f) { + + // Locate the insertion point for x in a to maintain sorted order. The + // arguments lo and hi may be used to specify a subset of the array which + // should be considered; by default the entire array is used. If x is already + // present in a, the insertion point will be before (to the left of) any + // existing entries. The return value is suitable for use as the first + // argument to `array.splice` assuming that a is already sorted. + // + // The returned insertion point i partitions the array a into two halves so + // that all v < x for v in a[lo:i] for the left side and all v >= x for v in + // a[i:hi] for the right side. + function bisectLeft(a, x, lo, hi) { + while (lo < hi) { + var mid = lo + hi >>> 1; + if (f(a[mid]) < x) lo = mid + 1; + else hi = mid; + } + return lo; + } + + // Similar to bisectLeft, but returns an insertion point which comes after (to + // the right of) any existing entries of x in a. + // + // The returned insertion point i partitions the array into two halves so that + // all v <= x for v in a[lo:i] for the left side and all v > x for v in + // a[i:hi] for the right side. + function bisectRight(a, x, lo, hi) { + while (lo < hi) { + var mid = lo + hi >>> 1; + if (x < f(a[mid])) hi = mid; + else lo = mid + 1; + } + return lo; + } + + bisectRight.right = bisectRight; + bisectRight.left = bisectLeft; + return bisectRight; +} + +module.exports = bisect_by(crossfilter_identity); +module.exports.by = bisect_by; // assign the raw function to the export as well + +},{"./identity":10}],6:[function(require,module,exports){ +'use strict'; + +var xfilterArray = require('./array'); +var xfilterFilter = require('./filter'); +var crossfilter_identity = require('./identity'); +var crossfilter_null = require('./null'); +var crossfilter_zero = require('./zero'); +var xfilterHeapselect = require('./heapselect'); +var xfilterHeap = require('./heap'); +var bisect = require('./bisect'); +var insertionsort = require('./insertionsort'); +var permute = require('./permute'); +var quicksort = require('./quicksort'); +var xfilterReduce = require('./reduce'); +var packageJson = require('./../package.json'); // require own package.json for the version field +var result = require('lodash.result'); + +// constants +var REMOVED_INDEX = -1; + +// expose API exports +exports.crossfilter = crossfilter; +exports.crossfilter.heap = xfilterHeap; +exports.crossfilter.heapselect = xfilterHeapselect; +exports.crossfilter.bisect = bisect; +exports.crossfilter.insertionsort = insertionsort; +exports.crossfilter.permute = permute; +exports.crossfilter.quicksort = quicksort; +exports.crossfilter.version = packageJson.version; // please note use of "package-json-versionify" transform + +function crossfilter() { + var crossfilter = { + add: add, + remove: removeData, + dimension: dimension, + groupAll: groupAll, + size: size, + all: all, + allFiltered: allFiltered, + onChange: onChange, + isElementFiltered: isElementFiltered + }; + + var data = [], // the records + n = 0, // the number of records; data.length + filters, // 1 is filtered out + filterListeners = [], // when the filters change + dataListeners = [], // when data is added + removeDataListeners = [], // when data is removed + callbacks = []; + + filters = new xfilterArray.bitarray(0); + + // Adds the specified new records to this crossfilter. + function add(newData) { + var n0 = n, + n1 = newData.length; + + // If there's actually new data to add… + // Merge the new data into the existing data. + // Lengthen the filter bitset to handle the new records. + // Notify listeners (dimensions and groups) that new data is available. + if (n1) { + data = data.concat(newData); + filters.lengthen(n += n1); + dataListeners.forEach(function(l) { l(newData, n0, n1); }); + triggerOnChange('dataAdded'); + } + + return crossfilter; + } + + // Removes all records that match the current filters, or if a predicate function is passed, + // removes all records matching the predicate (ignoring filters). + function removeData(predicate) { + var // Mapping from old record indexes to new indexes (after records removed) + newIndex = crossfilter_index(n, n), + removed = [], + usePred = typeof predicate === 'function', + shouldRemove = function (i) { + return usePred ? predicate(data[i], i) : filters.zero(i) + }; + + for (var index1 = 0, index2 = 0; index1 < n; ++index1) { + if ( shouldRemove(index1) ) { + removed.push(index1); + newIndex[index1] = REMOVED_INDEX; + } else { + newIndex[index1] = index2++; + } + } + + // Remove all matching records from groups. + filterListeners.forEach(function(l) { l(-1, -1, [], removed, true); }); + + // Update indexes. + removeDataListeners.forEach(function(l) { l(newIndex); }); + + // Remove old filters and data by overwriting. + for (var index3 = 0, index4 = 0; index3 < n; ++index3) { + if ( newIndex[index3] !== REMOVED_INDEX ) { + if (index3 !== index4) filters.copy(index4, index3), data[index4] = data[index3]; + ++index4; + } + } + + data.length = n = index4; + filters.truncate(index4); + triggerOnChange('dataRemoved'); + } + + function maskForDimensions(dimensions) { + var n, + d, + len, + id, + mask = Array(filters.subarrays); + for (n = 0; n < filters.subarrays; n++) { mask[n] = ~0; } + for (d = 0, len = dimensions.length; d < len; d++) { + // The top bits of the ID are the subarray offset and the lower bits are the bit + // offset of the "one" mask. + id = dimensions[d].id(); + mask[id >> 7] &= ~(0x1 << (id & 0x3f)); + } + return mask; + } + + // Return true if the data element at index i is filtered IN. + // Optionally, ignore the filters of any dimensions in the ignore_dimensions list. + function isElementFiltered(i, ignore_dimensions) { + var mask = maskForDimensions(ignore_dimensions || []); + return filters.zeroExceptMask(i,mask); + } + + // Adds a new dimension with the specified value accessor function. + function dimension(value, iterable) { + + if (typeof value === 'string') { + var accessorPath = value; + value = function(d) { return result(d, accessorPath); }; + } + + var dimension = { + filter: filter, + filterExact: filterExact, + filterRange: filterRange, + filterFunction: filterFunction, + filterAll: filterAll, + currentFilter: currentFilter, + hasCurrentFilter: hasCurrentFilter, + top: top, + bottom: bottom, + group: group, + groupAll: groupAll, + dispose: dispose, + remove: dispose, // for backwards-compatibility + accessor: value, + id: function() { return id; } + }; + + var one, // lowest unset bit as mask, e.g., 00001000 + zero, // inverted one, e.g., 11110111 + offset, // offset into the filters arrays + id, // unique ID for this dimension (reused when dimensions are disposed) + values, // sorted, cached array + index, // maps sorted value index -> record index (in data) + newValues, // temporary array storing newly-added values + newIndex, // temporary array storing newly-added index + iterablesIndexCount, + newIterablesIndexCount, + iterablesIndexFilterStatus, + newIterablesIndexFilterStatus, + iterablesEmptyRows = [], + sort = quicksort.by(function(i) { return newValues[i]; }), + refilter = xfilterFilter.filterAll, // for recomputing filter + refilterFunction, // the custom filter function in use + filterValue, // the value used for filtering (value, array, function or undefined) + filterValuePresent, // true if filterValue contains something + indexListeners = [], // when data is added + dimensionGroups = [], + lo0 = 0, + hi0 = 0, + t = 0, + k; + + // Updating a dimension is a two-stage process. First, we must update the + // associated filters for the newly-added records. Once all dimensions have + // updated their filters, the groups are notified to update. + dataListeners.unshift(preAdd); + dataListeners.push(postAdd); + + removeDataListeners.push(removeData); + + // Add a new dimension in the filter bitmap and store the offset and bitmask. + var tmp = filters.add(); + offset = tmp.offset; + one = tmp.one; + zero = ~one; + + // Create a unique ID for the dimension + // IDs will be re-used if dimensions are disposed. + // For internal use the ID is the subarray offset shifted left 7 bits or'd with the + // bit offset of the set bit in the dimension's "one" mask. + id = (offset << 7) | (Math.log(one) / Math.log(2)); + + preAdd(data, 0, n); + postAdd(data, 0, n); + + // Incorporates the specified new records into this dimension. + // This function is responsible for updating filters, values, and index. + function preAdd(newData, n0, n1) { + + if (iterable){ + // Count all the values + t = 0; + j = 0; + k = []; + + for (var i0 = 0; i0 < newData.length; i0++) { + for(j = 0, k = value(newData[i0]); j < k.length; j++) { + t++; + } + } + + newValues = []; + newIterablesIndexCount = crossfilter_range(newData.length); + newIterablesIndexFilterStatus = crossfilter_index(t,1); + var unsortedIndex = crossfilter_range(t); + + for (var l = 0, index1 = 0; index1 < newData.length; index1++) { + k = value(newData[index1]) + // + if(!k.length){ + newIterablesIndexCount[index1] = 0; + iterablesEmptyRows.push(index1 + n0); + continue; + } + newIterablesIndexCount[index1] = k.length + for (j = 0; j < k.length; j++) { + newValues.push(k[j]); + unsortedIndex[l] = index1; + l++; + } + } + + // Create the Sort map used to sort both the values and the valueToData indices + var sortMap = sort(crossfilter_range(t), 0, t); + + // Use the sortMap to sort the newValues + newValues = permute(newValues, sortMap); + + + // Use the sortMap to sort the unsortedIndex map + // newIndex should be a map of sortedValue -> crossfilterData + newIndex = permute(unsortedIndex, sortMap) + + } else{ + // Permute new values into natural order using a standard sorted index. + newValues = newData.map(value); + newIndex = sort(crossfilter_range(n1), 0, n1); + newValues = permute(newValues, newIndex); + } + + if(iterable) { + n1 = t; + } + + // Bisect newValues to determine which new records are selected. + var bounds = refilter(newValues), lo1 = bounds[0], hi1 = bounds[1]; + if (refilterFunction) { + for (var index2 = 0; index2 < n1; ++index2) { + if (!refilterFunction(newValues[index2], index2)) { + filters[offset][newIndex[index2] + n0] |= one; + if(iterable) newIterablesIndexFilterStatus[index2] = 1; + } + } + } else { + for (var index3 = 0; index3 < lo1; ++index3) { + filters[offset][newIndex[index3] + n0] |= one; + if(iterable) newIterablesIndexFilterStatus[index3] = 1; + } + for (var index4 = hi1; index4 < n1; ++index4) { + filters[offset][newIndex[index4] + n0] |= one; + if(iterable) newIterablesIndexFilterStatus[index4] = 1; + } + } + + // If this dimension previously had no data, then we don't need to do the + // more expensive merge operation; use the new values and index as-is. + if (!n0) { + values = newValues; + index = newIndex; + iterablesIndexCount = newIterablesIndexCount; + iterablesIndexFilterStatus = newIterablesIndexFilterStatus; + lo0 = lo1; + hi0 = hi1; + return; + } + + + + var oldValues = values, + oldIndex = index, + oldIterablesIndexFilterStatus = iterablesIndexFilterStatus, + old_n0, + i1 = 0; + + i0 = 0; + + if(iterable){ + old_n0 = n0 + n0 = oldValues.length; + n1 = t + } + + // Otherwise, create new arrays into which to merge new and old. + values = iterable ? new Array(n0 + n1) : new Array(n); + index = iterable ? new Array(n0 + n1) : crossfilter_index(n, n); + if(iterable) iterablesIndexFilterStatus = crossfilter_index(n0 + n1, 1); + + // Concatenate the newIterablesIndexCount onto the old one. + if(iterable) { + var oldiiclength = iterablesIndexCount.length; + iterablesIndexCount = xfilterArray.arrayLengthen(iterablesIndexCount, n); + for(var j=0; j+oldiiclength < n; j++) { + iterablesIndexCount[j+oldiiclength] = newIterablesIndexCount[j]; + } + } + + // Merge the old and new sorted values, and old and new index. + var index5 = 0; + for (; i0 < n0 && i1 < n1; ++index5) { + if (oldValues[i0] < newValues[i1]) { + values[index5] = oldValues[i0]; + if(iterable) iterablesIndexFilterStatus[index5] = oldIterablesIndexFilterStatus[i0]; + index[index5] = oldIndex[i0++]; + } else { + values[index5] = newValues[i1]; + if(iterable) iterablesIndexFilterStatus[index5] = newIterablesIndexFilterStatus[i1]; + index[index5] = newIndex[i1++] + (iterable ? old_n0 : n0); + } + } + + // Add any remaining old values. + for (; i0 < n0; ++i0, ++index5) { + values[index5] = oldValues[i0]; + if(iterable) iterablesIndexFilterStatus[index5] = oldIterablesIndexFilterStatus[i0]; + index[index5] = oldIndex[i0]; + } + + // Add any remaining new values. + for (; i1 < n1; ++i1, ++index5) { + values[index5] = newValues[i1]; + if(iterable) iterablesIndexFilterStatus[index5] = newIterablesIndexFilterStatus[i1]; + index[index5] = newIndex[i1] + (iterable ? old_n0 : n0); + } + + // Bisect again to recompute lo0 and hi0. + bounds = refilter(values), lo0 = bounds[0], hi0 = bounds[1]; + } + + // When all filters have updated, notify index listeners of the new values. + function postAdd(newData, n0, n1) { + indexListeners.forEach(function(l) { l(newValues, newIndex, n0, n1); }); + newValues = newIndex = null; + } + + function removeData(reIndex) { + if (iterable) { + for (var i0 = 0, i1 = 0; i0 < iterablesEmptyRows.length; i0++) { + if (reIndex[iterablesEmptyRows[i0]] !== REMOVED_INDEX) { + iterablesEmptyRows[i1] = reIndex[iterablesEmptyRows[i0]]; + i1++; + } + } + iterablesEmptyRows.length = i1; + for (i0 = 0, i1 = 0; i0 < n; i0++) { + if (reIndex[i0] !== REMOVED_INDEX) { + if (i1 !== i0) iterablesIndexCount[i1] = iterablesIndexCount[i0]; + i1++; + } + } + iterablesIndexCount.length = i1; + } + // Rewrite our index, overwriting removed values + var n0 = values.length; + for (var i = 0, j = 0, oldDataIndex; i < n0; ++i) { + oldDataIndex = index[i]; + if (reIndex[oldDataIndex] !== REMOVED_INDEX) { + if (i !== j) values[j] = values[i]; + index[j] = reIndex[oldDataIndex]; + if (iterable) { + iterablesIndexFilterStatus[j] = iterablesIndexFilterStatus[i]; + } + ++j; + } + } + values.length = j; + if (iterable) iterablesIndexFilterStatus.length = j; + while (j < n0) index[j++] = 0; + + // Bisect again to recompute lo0 and hi0. + var bounds = refilter(values); + lo0 = bounds[0], hi0 = bounds[1]; + } + + // Updates the selected values based on the specified bounds [lo, hi]. + // This implementation is used by all the public filter methods. + function filterIndexBounds(bounds) { + + var lo1 = bounds[0], + hi1 = bounds[1]; + + if (refilterFunction) { + refilterFunction = null; + filterIndexFunction(function(d, i) { return lo1 <= i && i < hi1; }, bounds[0] === 0 && bounds[1] === values.length); + lo0 = lo1; + hi0 = hi1; + return dimension; + } + + var i, + j, + k, + added = [], + removed = [], + valueIndexAdded = [], + valueIndexRemoved = []; + + + // Fast incremental update based on previous lo index. + if (lo1 < lo0) { + for (i = lo1, j = Math.min(lo0, hi1); i < j; ++i) { + added.push(index[i]); + valueIndexAdded.push(i); + } + } else if (lo1 > lo0) { + for (i = lo0, j = Math.min(lo1, hi0); i < j; ++i) { + removed.push(index[i]); + valueIndexRemoved.push(i); + } + } + + // Fast incremental update based on previous hi index. + if (hi1 > hi0) { + for (i = Math.max(lo1, hi0), j = hi1; i < j; ++i) { + added.push(index[i]); + valueIndexAdded.push(i); + } + } else if (hi1 < hi0) { + for (i = Math.max(lo0, hi1), j = hi0; i < j; ++i) { + removed.push(index[i]); + valueIndexRemoved.push(i); + } + } + + if(!iterable) { + // Flip filters normally. + + for(i=0; i<added.length; i++) { + filters[offset][added[i]] ^= one; + } + + for(i=0; i<removed.length; i++) { + filters[offset][removed[i]] ^= one; + } + + } else { + // For iterables, we need to figure out if the row has been completely removed vs partially included + // Only count a row as added if it is not already being aggregated. Only count a row + // as removed if the last element being aggregated is removed. + + var newAdded = []; + var newRemoved = []; + for (i = 0; i < added.length; i++) { + iterablesIndexCount[added[i]]++ + iterablesIndexFilterStatus[valueIndexAdded[i]] = 0; + if(iterablesIndexCount[added[i]] === 1) { + filters[offset][added[i]] ^= one; + newAdded.push(added[i]); + } + } + for (i = 0; i < removed.length; i++) { + iterablesIndexCount[removed[i]]-- + iterablesIndexFilterStatus[valueIndexRemoved[i]] = 1; + if(iterablesIndexCount[removed[i]] === 0) { + filters[offset][removed[i]] ^= one; + newRemoved.push(removed[i]); + } + } + + added = newAdded; + removed = newRemoved; + + // Now handle empty rows. + if(bounds[0] === 0 && bounds[1] === values.length) { + for(i = 0; i < iterablesEmptyRows.length; i++) { + if((filters[offset][k = iterablesEmptyRows[i]] & one)) { + // Was not in the filter, so set the filter and add + filters[offset][k] ^= one; + added.push(k); + } + } + } else { + // filter in place - remove empty rows if necessary + for(i = 0; i < iterablesEmptyRows.length; i++) { + if(!(filters[offset][k = iterablesEmptyRows[i]] & one)) { + // Was in the filter, so set the filter and remove + filters[offset][k] ^= one; + removed.push(k); + } + } + } + } + + lo0 = lo1; + hi0 = hi1; + filterListeners.forEach(function(l) { l(one, offset, added, removed); }); + triggerOnChange('filtered'); + return dimension; + } + + // Filters this dimension using the specified range, value, or null. + // If the range is null, this is equivalent to filterAll. + // If the range is an array, this is equivalent to filterRange. + // Otherwise, this is equivalent to filterExact. + function filter(range) { + return range == null + ? filterAll() : Array.isArray(range) + ? filterRange(range) : typeof range === "function" + ? filterFunction(range) + : filterExact(range); + } + + // Filters this dimension to select the exact value. + function filterExact(value) { + filterValue = value; + filterValuePresent = true; + return filterIndexBounds((refilter = xfilterFilter.filterExact(bisect, value))(values)); + } + + // Filters this dimension to select the specified range [lo, hi]. + // The lower bound is inclusive, and the upper bound is exclusive. + function filterRange(range) { + filterValue = range; + filterValuePresent = true; + return filterIndexBounds((refilter = xfilterFilter.filterRange(bisect, range))(values)); + } + + // Clears any filters on this dimension. + function filterAll() { + filterValue = undefined; + filterValuePresent = false; + return filterIndexBounds((refilter = xfilterFilter.filterAll)(values)); + } + + // Filters this dimension using an arbitrary function. + function filterFunction(f) { + filterValue = f; + filterValuePresent = true; + + refilterFunction = f; + refilter = xfilterFilter.filterAll; + + filterIndexFunction(f, false); + + var bounds = refilter(values); + lo0 = bounds[0], hi0 = bounds[1]; + + return dimension; + } + + function filterIndexFunction(f, filterAll) { + var i, + k, + x, + added = [], + removed = [], + valueIndexAdded = [], + valueIndexRemoved = [], + indexLength = values.length; + + if(!iterable) { + for (i = 0; i < indexLength; ++i) { + if (!(filters[offset][k = index[i]] & one) ^ !!(x = f(values[i], i))) { + if (x) added.push(k); + else removed.push(k); + } + } + } + + if(iterable) { + for(i=0; i < indexLength; ++i) { + if(f(values[i], i)) { + added.push(index[i]); + valueIndexAdded.push(i); + } else { + removed.push(index[i]); + valueIndexRemoved.push(i); + } + } + } + + if(!iterable) { + for(i=0; i<added.length; i++) { + if(filters[offset][added[i]] & one) filters[offset][added[i]] &= zero; + } + + for(i=0; i<removed.length; i++) { + if(!(filters[offset][removed[i]] & one)) filters[offset][removed[i]] |= one; + } + } else { + + var newAdded = []; + var newRemoved = []; + for (i = 0; i < added.length; i++) { + // First check this particular value needs to be added + if(iterablesIndexFilterStatus[valueIndexAdded[i]] === 1) { + iterablesIndexCount[added[i]]++ + iterablesIndexFilterStatus[valueIndexAdded[i]] = 0; + if(iterablesIndexCount[added[i]] === 1) { + filters[offset][added[i]] ^= one; + newAdded.push(added[i]); + } + } + } + for (i = 0; i < removed.length; i++) { + // First check this particular value needs to be removed + if(iterablesIndexFilterStatus[valueIndexRemoved[i]] === 0) { + iterablesIndexCount[removed[i]]-- + iterablesIndexFilterStatus[valueIndexRemoved[i]] = 1; + if(iterablesIndexCount[removed[i]] === 0) { + filters[offset][removed[i]] ^= one; + newRemoved.push(removed[i]); + } + } + } + + added = newAdded; + removed = newRemoved; + + // Now handle empty rows. + if(filterAll) { + for(i = 0; i < iterablesEmptyRows.length; i++) { + if((filters[offset][k = iterablesEmptyRows[i]] & one)) { + // Was not in the filter, so set the filter and add + filters[offset][k] ^= one; + added.push(k); + } + } + } else { + // filter in place - remove empty rows if necessary + for(i = 0; i < iterablesEmptyRows.length; i++) { + if(!(filters[offset][k = iterablesEmptyRows[i]] & one)) { + // Was in the filter, so set the filter and remove + filters[offset][k] ^= one; + removed.push(k); + } + } + } + } + + filterListeners.forEach(function(l) { l(one, offset, added, removed); }); + triggerOnChange('filtered'); + } + + function currentFilter() { + return filterValue; + } + + function hasCurrentFilter() { + return filterValuePresent; + } + + // Returns the top K selected records based on this dimension's order. + // Note: observes this dimension's filter, unlike group and groupAll. + function top(k, top_offset) { + var array = [], + i = hi0, + j, + toSkip = 0; + + if(top_offset && top_offset > 0) toSkip = top_offset; + + while (--i >= lo0 && k > 0) { + if (filters.zero(j = index[i])) { + if(toSkip > 0) { + //skip matching row + --toSkip; + } else { + array.push(data[j]); + --k; + } + } + } + + if(iterable){ + for(i = 0; i < iterablesEmptyRows.length && k > 0; i++) { + // Add row with empty iterable column at the end + if(filters.zero(j = iterablesEmptyRows[i])) { + if(toSkip > 0) { + //skip matching row + --toSkip; + } else { + array.push(data[j]); + --k; + } + } + } + } + + return array; + } + + // Returns the bottom K selected records based on this dimension's order. + // Note: observes this dimension's filter, unlike group and groupAll. + function bottom(k, bottom_offset) { + var array = [], + i, + j, + toSkip = 0; + + if(bottom_offset && bottom_offset > 0) toSkip = bottom_offset; + + if(iterable) { + // Add row with empty iterable column at the top + for(i = 0; i < iterablesEmptyRows.length && k > 0; i++) { + if(filters.zero(j = iterablesEmptyRows[i])) { + if(toSkip > 0) { + //skip matching row + --toSkip; + } else { + array.push(data[j]); + --k; + } + } + } + } + + i = lo0; + + while (i < hi0 && k > 0) { + if (filters.zero(j = index[i])) { + if(toSkip > 0) { + //skip matching row + --toSkip; + } else { + array.push(data[j]); + --k; + } + } + i++; + } + + return array; + } + + // Adds a new group to this dimension, using the specified key function. + function group(key) { + var group = { + top: top, + all: all, + reduce: reduce, + reduceCount: reduceCount, + reduceSum: reduceSum, + order: order, + orderNatural: orderNatural, + size: size, + dispose: dispose, + remove: dispose // for backwards-compatibility + }; + + // Ensure that this group will be removed when the dimension is removed. + dimensionGroups.push(group); + + var groups, // array of {key, value} + groupIndex, // object id ↦ group id + groupWidth = 8, + groupCapacity = crossfilter_capacity(groupWidth), + k = 0, // cardinality + select, + heap, + reduceAdd, + reduceRemove, + reduceInitial, + update = crossfilter_null, + reset = crossfilter_null, + resetNeeded = true, + groupAll = key === crossfilter_null, + n0old; + + if (arguments.length < 1) key = crossfilter_identity; + + // The group listens to the crossfilter for when any dimension changes, so + // that it can update the associated reduce values. It must also listen to + // the parent dimension for when data is added, and compute new keys. + filterListeners.push(update); + indexListeners.push(add); + removeDataListeners.push(removeData); + + // Incorporate any existing data into the grouping. + add(values, index, 0, n); + + // Incorporates the specified new values into this group. + // This function is responsible for updating groups and groupIndex. + function add(newValues, newIndex, n0, n1) { + + if(iterable) { + n0old = n0 + n0 = values.length - newValues.length + n1 = newValues.length; + } + + var oldGroups = groups, + reIndex = iterable ? [] : crossfilter_index(k, groupCapacity), + add = reduceAdd, + remove = reduceRemove, + initial = reduceInitial, + k0 = k, // old cardinality + i0 = 0, // index of old group + i1 = 0, // index of new record + j, // object id + g0, // old group + x0, // old key + x1, // new key + g, // group to add + x; // key of group to add + + // If a reset is needed, we don't need to update the reduce values. + if (resetNeeded) add = initial = crossfilter_null; + if (resetNeeded) remove = initial = crossfilter_null; + + // Reset the new groups (k is a lower bound). + // Also, make sure that groupIndex exists and is long enough. + groups = new Array(k), k = 0; + if(iterable){ + groupIndex = k0 ? groupIndex : []; + } + else{ + groupIndex = k0 > 1 ? xfilterArray.arrayLengthen(groupIndex, n) : crossfilter_index(n, groupCapacity); + } + + + // Get the first old key (x0 of g0), if it exists. + if (k0) x0 = (g0 = oldGroups[0]).key; + + // Find the first new key (x1), skipping NaN keys. + while (i1 < n1 && !((x1 = key(newValues[i1])) >= x1)) ++i1; + + // While new keys remain… + while (i1 < n1) { + + // Determine the lesser of the two current keys; new and old. + // If there are no old keys remaining, then always add the new key. + if (g0 && x0 <= x1) { + g = g0, x = x0; + + // Record the new index of the old group. + reIndex[i0] = k; + + // Retrieve the next old key. + g0 = oldGroups[++i0]; + if (g0) x0 = g0.key; + } else { + g = {key: x1, value: initial()}, x = x1; + } + + // Add the lesser group. + groups[k] = g; + + // Add any selected records belonging to the added group, while + // advancing the new key and populating the associated group index. + + while (x1 <= x) { + j = newIndex[i1] + (iterable ? n0old : n0) + + + if(iterable){ + if(groupIndex[j]){ + groupIndex[j].push(k) + } + else{ + groupIndex[j] = [k] + } + } + else{ + groupIndex[j] = k; + } + + // Always add new values to groups. Only remove when not in filter. + // This gives groups full information on data life-cycle. + g.value = add(g.value, data[j], true); + if (!filters.zeroExcept(j, offset, zero)) g.value = remove(g.value, data[j], false); + if (++i1 >= n1) break; + x1 = key(newValues[i1]); + } + + groupIncrement(); + } + + // Add any remaining old groups that were greater th1an all new keys. + // No incremental reduce is needed; these groups have no new records. + // Also record the new index of the old group. + while (i0 < k0) { + groups[reIndex[i0] = k] = oldGroups[i0++]; + groupIncrement(); + } + + + // Fill in gaps with empty arrays where there may have been rows with empty iterables + if(iterable){ + for (var index1 = 0; index1 < n; index1++) { + if(!groupIndex[index1]){ + groupIndex[index1] = []; + } + } + } + + // If we added any new groups before any old groups, + // update the group index of all the old records. + if(k > i0){ + if(iterable){ + for (i0 = 0; i0 < n0old; ++i0) { + for (index1 = 0; index1 < groupIndex[i0].length; index1++) { + groupIndex[i0][index1] = reIndex[groupIndex[i0][index1]]; + } + } + } + else{ + for (i0 = 0; i0 < n0; ++i0) { + groupIndex[i0] = reIndex[groupIndex[i0]]; + } + } + } + + // Modify the update and reset behavior based on the cardinality. + // If the cardinality is less than or equal to one, then the groupIndex + // is not needed. If the cardinality is zero, then there are no records + // and therefore no groups to update or reset. Note that we also must + // change the registered listener to point to the new method. + j = filterListeners.indexOf(update); + if (k > 1 || iterable) { + update = updateMany; + reset = resetMany; + } else { + if (!k && groupAll) { + k = 1; + groups = [{key: null, value: initial()}]; + } + if (k === 1) { + update = updateOne; + reset = resetOne; + } else { + update = crossfilter_null; + reset = crossfilter_null; + } + groupIndex = null; + } + filterListeners[j] = update; + + // Count the number of added groups, + // and widen the group index as needed. + function groupIncrement() { + if(iterable){ + k++ + return + } + if (++k === groupCapacity) { + reIndex = xfilterArray.arrayWiden(reIndex, groupWidth <<= 1); + groupIndex = xfilterArray.arrayWiden(groupIndex, groupWidth); + groupCapacity = crossfilter_capacity(groupWidth); + } + } + } + + function removeData(reIndex) { + if (k > 1 || iterable) { + var oldK = k, + oldGroups = groups, + seenGroups = crossfilter_index(oldK, oldK), + i, + i0, + j; + + // Filter out non-matches by copying matching group index entries to + // the beginning of the array. + if (!iterable) { + for (i = 0, j = 0; i < n; ++i) { + if (reIndex[i] !== REMOVED_INDEX) { + seenGroups[groupIndex[j] = groupIndex[i]] = 1; + ++j; + } + } + } else { + for (i = 0, j = 0; i < n; ++i) { + if (reIndex[i] !== REMOVED_INDEX) { + groupIndex[j] = groupIndex[i]; + for (i0 = 0; i0 < groupIndex[j].length; i0++) { + seenGroups[groupIndex[j][i0]] = 1; + } + ++j; + } + } + } + + // Reassemble groups including only those groups that were referred + // to by matching group index entries. Note the new group index in + // seenGroups. + groups = [], k = 0; + for (i = 0; i < oldK; ++i) { + if (seenGroups[i]) { + seenGroups[i] = k++; + groups.push(oldGroups[i]); + } + } + + if (k > 1 || iterable) { + // Reindex the group index using seenGroups to find the new index. + if (!iterable) { + for (i = 0; i < j; ++i) groupIndex[i] = seenGroups[groupIndex[i]]; + } else { + for (i = 0; i < j; ++i) { + for (i0 = 0; i0 < groupIndex[i].length; ++i0) { + groupIndex[i][i0] = seenGroups[groupIndex[i][i0]]; + } + } + } + } else { + groupIndex = null; + } + filterListeners[filterListeners.indexOf(update)] = k > 1 || iterable + ? (reset = resetMany, update = updateMany) + : k === 1 ? (reset = resetOne, update = updateOne) + : reset = update = crossfilter_null; + } else if (k === 1) { + if (groupAll) return; + for (var index3 = 0; index3 < n; ++index3) if (reIndex[index3] !== REMOVED_INDEX) return; + groups = [], k = 0; + filterListeners[filterListeners.indexOf(update)] = + update = reset = crossfilter_null; + } + } + + // Reduces the specified selected or deselected records. + // This function is only used when the cardinality is greater than 1. + // notFilter indicates a crossfilter.add/remove operation. + function updateMany(filterOne, filterOffset, added, removed, notFilter) { + + if ((filterOne === one && filterOffset === offset) || resetNeeded) return; + + var i, + j, + k, + n, + g; + + if(iterable){ + // Add the added values. + for (i = 0, n = added.length; i < n; ++i) { + if (filters.zeroExcept(k = added[i], offset, zero)) { + for (j = 0; j < groupIndex[k].length; j++) { + g = groups[groupIndex[k][j]]; + g.value = reduceAdd(g.value, data[k], false, j); + } + } + } + + // Remove the removed values. + for (i = 0, n = removed.length; i < n; ++i) { + if (filters.onlyExcept(k = removed[i], offset, zero, filterOffset, filterOne)) { + for (j = 0; j < groupIndex[k].length; j++) { + g = groups[groupIndex[k][j]]; + g.value = reduceRemove(g.value, data[k], notFilter, j); + } + } + } + return; + } + + // Add the added values. + for (i = 0, n = added.length; i < n; ++i) { + if (filters.zeroExcept(k = added[i], offset, zero)) { + g = groups[groupIndex[k]]; + g.value = reduceAdd(g.value, data[k], false); + } + } + + // Remove the removed values. + for (i = 0, n = removed.length; i < n; ++i) { + if (filters.onlyExcept(k = removed[i], offset, zero, filterOffset, filterOne)) { + g = groups[groupIndex[k]]; + g.value = reduceRemove(g.value, data[k], notFilter); + } + } + } + + // Reduces the specified selected or deselected records. + // This function is only used when the cardinality is 1. + // notFilter indicates a crossfilter.add/remove operation. + function updateOne(filterOne, filterOffset, added, removed, notFilter) { + if ((filterOne === one && filterOffset === offset) || resetNeeded) return; + + var i, + k, + n, + g = groups[0]; + + // Add the added values. + for (i = 0, n = added.length; i < n; ++i) { + if (filters.zeroExcept(k = added[i], offset, zero)) { + g.value = reduceAdd(g.value, data[k], false); + } + } + + // Remove the removed values. + for (i = 0, n = removed.length; i < n; ++i) { + if (filters.onlyExcept(k = removed[i], offset, zero, filterOffset, filterOne)) { + g.value = reduceRemove(g.value, data[k], notFilter); + } + } + } + + // Recomputes the group reduce values from scratch. + // This function is only used when the cardinality is greater than 1. + function resetMany() { + var i, + j, + g; + + // Reset all group values. + for (i = 0; i < k; ++i) { + groups[i].value = reduceInitial(); + } + + // We add all records and then remove filtered records so that reducers + // can build an 'unfiltered' view even if there are already filters in + // place on other dimensions. + if(iterable){ + for (i = 0; i < n; ++i) { + for (j = 0; j < groupIndex[i].length; j++) { + g = groups[groupIndex[i][j]]; + g.value = reduceAdd(g.value, data[i], true, j); + } + } + for (i = 0; i < n; ++i) { + if (!filters.zeroExcept(i, offset, zero)) { + for (j = 0; j < groupIndex[i].length; j++) { + g = groups[groupIndex[i][j]]; + g.value = reduceRemove(g.value, data[i], false, j); + } + } + } + return; + } + + for (i = 0; i < n; ++i) { + g = groups[groupIndex[i]]; + g.value = reduceAdd(g.value, data[i], true); + } + for (i = 0; i < n; ++i) { + if (!filters.zeroExcept(i, offset, zero)) { + g = groups[groupIndex[i]]; + g.value = reduceRemove(g.value, data[i], false); + } + } + } + + // Recomputes the group reduce values from scratch. + // This function is only used when the cardinality is 1. + function resetOne() { + var i, + g = groups[0]; + + // Reset the singleton group values. + g.value = reduceInitial(); + + // We add all records and then remove filtered records so that reducers + // can build an 'unfiltered' view even if there are already filters in + // place on other dimensions. + for (i = 0; i < n; ++i) { + g.value = reduceAdd(g.value, data[i], true); + } + + for (i = 0; i < n; ++i) { + if (!filters.zeroExcept(i, offset, zero)) { + g.value = reduceRemove(g.value, data[i], false); + } + } + } + + // Returns the array of group values, in the dimension's natural order. + function all() { + if (resetNeeded) reset(), resetNeeded = false; + return groups; + } + + // Returns a new array containing the top K group values, in reduce order. + function top(k) { + var top = select(all(), 0, groups.length, k); + return heap.sort(top, 0, top.length); + } + + // Sets the reduce behavior for this group to use the specified functions. + // This method lazily recomputes the reduce values, waiting until needed. + function reduce(add, remove, initial) { + reduceAdd = add; + reduceRemove = remove; + reduceInitial = initial; + resetNeeded = true; + return group; + } + + // A convenience method for reducing by count. + function reduceCount() { + return reduce(xfilterReduce.reduceIncrement, xfilterReduce.reduceDecrement, crossfilter_zero); + } + + // A convenience method for reducing by sum(value). + function reduceSum(value) { + return reduce(xfilterReduce.reduceAdd(value), xfilterReduce.reduceSubtract(value), crossfilter_zero); + } + + // Sets the reduce order, using the specified accessor. + function order(value) { + select = xfilterHeapselect.by(valueOf); + heap = xfilterHeap.by(valueOf); + function valueOf(d) { return value(d.value); } + return group; + } + + // A convenience method for natural ordering by reduce value. + function orderNatural() { + return order(crossfilter_identity); + } + + // Returns the cardinality of this group, irrespective of any filters. + function size() { + return k; + } + + // Removes this group and associated event listeners. + function dispose() { + var i = filterListeners.indexOf(update); + if (i >= 0) filterListeners.splice(i, 1); + i = indexListeners.indexOf(add); + if (i >= 0) indexListeners.splice(i, 1); + i = removeDataListeners.indexOf(removeData); + if (i >= 0) removeDataListeners.splice(i, 1); + i = dimensionGroups.indexOf(group); + if (i >= 0) dimensionGroups.splice(i, 1); + return group; + } + + return reduceCount().orderNatural(); + } + + // A convenience function for generating a singleton group. + function groupAll() { + var g = group(crossfilter_null), all = g.all; + delete g.all; + delete g.top; + delete g.order; + delete g.orderNatural; + delete g.size; + g.value = function() { return all()[0].value; }; + return g; + } + + // Removes this dimension and associated groups and event listeners. + function dispose() { + dimensionGroups.forEach(function(group) { group.dispose(); }); + var i = dataListeners.indexOf(preAdd); + if (i >= 0) dataListeners.splice(i, 1); + i = dataListeners.indexOf(postAdd); + if (i >= 0) dataListeners.splice(i, 1); + i = removeDataListeners.indexOf(removeData); + if (i >= 0) removeDataListeners.splice(i, 1); + filters.masks[offset] &= zero; + return filterAll(); + } + + return dimension; + } + + // A convenience method for groupAll on a dummy dimension. + // This implementation can be optimized since it always has cardinality 1. + function groupAll() { + var group = { + reduce: reduce, + reduceCount: reduceCount, + reduceSum: reduceSum, + value: value, + dispose: dispose, + remove: dispose // for backwards-compatibility + }; + + var reduceValue, + reduceAdd, + reduceRemove, + reduceInitial, + resetNeeded = true; + + // The group listens to the crossfilter for when any dimension changes, so + // that it can update the reduce value. It must also listen to the parent + // dimension for when data is added. + filterListeners.push(update); + dataListeners.push(add); + + // For consistency; actually a no-op since resetNeeded is true. + add(data, 0, n); + + // Incorporates the specified new values into this group. + function add(newData, n0) { + var i; + + if (resetNeeded) return; + + // Cycle through all the values. + for (i = n0; i < n; ++i) { + + // Add all values all the time. + reduceValue = reduceAdd(reduceValue, data[i], true); + + // Remove the value if filtered. + if (!filters.zero(i)) { + reduceValue = reduceRemove(reduceValue, data[i], false); + } + } + } + + // Reduces the specified selected or deselected records. + function update(filterOne, filterOffset, added, removed, notFilter) { + var i, + k, + n; + + if (resetNeeded) return; + + // Add the added values. + for (i = 0, n = added.length; i < n; ++i) { + if (filters.zero(k = added[i])) { + reduceValue = reduceAdd(reduceValue, data[k], notFilter); + } + } + + // Remove the removed values. + for (i = 0, n = removed.length; i < n; ++i) { + if (filters.only(k = removed[i], filterOffset, filterOne)) { + reduceValue = reduceRemove(reduceValue, data[k], notFilter); + } + } + } + + // Recomputes the group reduce value from scratch. + function reset() { + var i; + + reduceValue = reduceInitial(); + + // Cycle through all the values. + for (i = 0; i < n; ++i) { + + // Add all values all the time. + reduceValue = reduceAdd(reduceValue, data[i], true); + + // Remove the value if it is filtered. + if (!filters.zero(i)) { + reduceValue = reduceRemove(reduceValue, data[i], false); + } + } + } + + // Sets the reduce behavior for this group to use the specified functions. + // This method lazily recomputes the reduce value, waiting until needed. + function reduce(add, remove, initial) { + reduceAdd = add; + reduceRemove = remove; + reduceInitial = initial; + resetNeeded = true; + return group; + } + + // A convenience method for reducing by count. + function reduceCount() { + return reduce(xfilterReduce.reduceIncrement, xfilterReduce.reduceDecrement, crossfilter_zero); + } + + // A convenience method for reducing by sum(value). + function reduceSum(value) { + return reduce(xfilterReduce.reduceAdd(value), xfilterReduce.reduceSubtract(value), crossfilter_zero); + } + + // Returns the computed reduce value. + function value() { + if (resetNeeded) reset(), resetNeeded = false; + return reduceValue; + } + + // Removes this group and associated event listeners. + function dispose() { + var i = filterListeners.indexOf(update); + if (i >= 0) filterListeners.splice(i, 1); + i = dataListeners.indexOf(add); + if (i >= 0) dataListeners.splice(i, 1); + return group; + } + + return reduceCount(); + } + + // Returns the number of records in this crossfilter, irrespective of any filters. + function size() { + return n; + } + + // Returns the raw row data contained in this crossfilter + function all(){ + return data; + } + + // Returns row data with all dimension filters applied, except for filters in ignore_dimensions + function allFiltered(ignore_dimensions) { + var array = [], + i = 0, + mask = maskForDimensions(ignore_dimensions || []); + + for (i = 0; i < n; i++) { + if (filters.zeroExceptMask(i, mask)) { + array.push(data[i]); + } + } + + return array; + } + + function onChange(cb){ + if(typeof cb !== 'function'){ + /* eslint no-console: 0 */ + console.warn('onChange callback parameter must be a function!'); + return; + } + callbacks.push(cb); + return function(){ + callbacks.splice(callbacks.indexOf(cb), 1); + }; + } + + function triggerOnChange(eventName){ + for (var i = 0; i < callbacks.length; i++) { + callbacks[i](eventName); + } + } + + return arguments.length + ? add(arguments[0]) + : crossfilter; +} + +// Returns an array of size n, big enough to store ids up to m. +function crossfilter_index(n, m) { + return (m < 0x101 + ? xfilterArray.array8 : m < 0x10001 + ? xfilterArray.array16 + : xfilterArray.array32)(n); +} + +// Constructs a new array of size n, with sequential values from 0 to n - 1. +function crossfilter_range(n) { + var range = crossfilter_index(n, n); + for (var i = -1; ++i < n;) range[i] = i; + return range; +} + +function crossfilter_capacity(w) { + return w === 8 + ? 0x100 : w === 16 + ? 0x10000 + : 0x100000000; +} + +},{"./../package.json":3,"./array":4,"./bisect":5,"./filter":7,"./heap":8,"./heapselect":9,"./identity":10,"./insertionsort":11,"./null":12,"./permute":13,"./quicksort":14,"./reduce":15,"./zero":16,"lodash.result":2}],7:[function(require,module,exports){ +'use strict'; + +function crossfilter_filterExact(bisect, value) { + return function(values) { + var n = values.length; + return [bisect.left(values, value, 0, n), bisect.right(values, value, 0, n)]; + }; +} + +function crossfilter_filterRange(bisect, range) { + var min = range[0], + max = range[1]; + return function(values) { + var n = values.length; + return [bisect.left(values, min, 0, n), bisect.left(values, max, 0, n)]; + }; +} + +function crossfilter_filterAll(values) { + return [0, values.length]; +} + +module.exports = { + filterExact: crossfilter_filterExact, + filterRange: crossfilter_filterRange, + filterAll: crossfilter_filterAll +}; + +},{}],8:[function(require,module,exports){ +'use strict'; + +var crossfilter_identity = require('./identity'); + +function heap_by(f) { + + // Builds a binary heap within the specified array a[lo:hi]. The heap has the + // property such that the parent a[lo+i] is always less than or equal to its + // two children: a[lo+2*i+1] and a[lo+2*i+2]. + function heap(a, lo, hi) { + var n = hi - lo, + i = (n >>> 1) + 1; + while (--i > 0) sift(a, i, n, lo); + return a; + } + + // Sorts the specified array a[lo:hi] in descending order, assuming it is + // already a heap. + function sort(a, lo, hi) { + var n = hi - lo, + t; + while (--n > 0) t = a[lo], a[lo] = a[lo + n], a[lo + n] = t, sift(a, 1, n, lo); + return a; + } + + // Sifts the element a[lo+i-1] down the heap, where the heap is the contiguous + // slice of array a[lo:lo+n]. This method can also be used to update the heap + // incrementally, without incurring the full cost of reconstructing the heap. + function sift(a, i, n, lo) { + var d = a[--lo + i], + x = f(d), + child; + while ((child = i << 1) <= n) { + if (child < n && f(a[lo + child]) > f(a[lo + child + 1])) child++; + if (x <= f(a[lo + child])) break; + a[lo + i] = a[lo + child]; + i = child; + } + a[lo + i] = d; + } + + heap.sort = sort; + return heap; +} + +module.exports = heap_by(crossfilter_identity); +module.exports.by = heap_by; + +},{"./identity":10}],9:[function(require,module,exports){ +'use strict'; + +var crossfilter_identity = require('./identity'); +var xFilterHeap = require('./heap'); + +function heapselect_by(f) { + var heap = xFilterHeap.by(f); + + // Returns a new array containing the top k elements in the array a[lo:hi]. + // The returned array is not sorted, but maintains the heap property. If k is + // greater than hi - lo, then fewer than k elements will be returned. The + // order of elements in a is unchanged by this operation. + function heapselect(a, lo, hi, k) { + var queue = new Array(k = Math.min(hi - lo, k)), + min, + i, + d; + + for (i = 0; i < k; ++i) queue[i] = a[lo++]; + heap(queue, 0, k); + + if (lo < hi) { + min = f(queue[0]); + do { + if (f(d = a[lo]) > min) { + queue[0] = d; + min = f(heap(queue, 0, k)[0]); + } + } while (++lo < hi); + } + + return queue; + } + + return heapselect; +} + +module.exports = heapselect_by(crossfilter_identity); +module.exports.by = heapselect_by; // assign the raw function to the export as well + +},{"./heap":8,"./identity":10}],10:[function(require,module,exports){ +'use strict'; + +function crossfilter_identity(d) { + return d; +} + +module.exports = crossfilter_identity; + +},{}],11:[function(require,module,exports){ +'use strict'; + +var crossfilter_identity = require('./identity'); + +function insertionsort_by(f) { + + function insertionsort(a, lo, hi) { + for (var i = lo + 1; i < hi; ++i) { + for (var j = i, t = a[i], x = f(t); j > lo && f(a[j - 1]) > x; --j) { + a[j] = a[j - 1]; + } + a[j] = t; + } + return a; + } + + return insertionsort; +} + +module.exports = insertionsort_by(crossfilter_identity); +module.exports.by = insertionsort_by; + +},{"./identity":10}],12:[function(require,module,exports){ +'use strict'; + +function crossfilter_null() { + return null; +} + +module.exports = crossfilter_null; + +},{}],13:[function(require,module,exports){ +'use strict'; + +function permute(array, index, deep) { + for (var i = 0, n = index.length, copy = deep ? JSON.parse(JSON.stringify(array)) : new Array(n); i < n; ++i) { + copy[i] = array[index[i]]; + } + return copy; +} + +module.exports = permute; + +},{}],14:[function(require,module,exports){ +var crossfilter_identity = require('./identity'); +var xFilterInsertionsort = require('./insertionsort'); + +// Algorithm designed by Vladimir Yaroslavskiy. +// Implementation based on the Dart project; see NOTICE and AUTHORS for details. + +function quicksort_by(f) { + var insertionsort = xFilterInsertionsort.by(f); + + function sort(a, lo, hi) { + return (hi - lo < quicksort_sizeThreshold + ? insertionsort + : quicksort)(a, lo, hi); + } + + function quicksort(a, lo, hi) { + // Compute the two pivots by looking at 5 elements. + var sixth = (hi - lo) / 6 | 0, + i1 = lo + sixth, + i5 = hi - 1 - sixth, + i3 = lo + hi - 1 >> 1, // The midpoint. + i2 = i3 - sixth, + i4 = i3 + sixth; + + var e1 = a[i1], x1 = f(e1), + e2 = a[i2], x2 = f(e2), + e3 = a[i3], x3 = f(e3), + e4 = a[i4], x4 = f(e4), + e5 = a[i5], x5 = f(e5); + + var t; + + // Sort the selected 5 elements using a sorting network. + if (x1 > x2) t = e1, e1 = e2, e2 = t, t = x1, x1 = x2, x2 = t; + if (x4 > x5) t = e4, e4 = e5, e5 = t, t = x4, x4 = x5, x5 = t; + if (x1 > x3) t = e1, e1 = e3, e3 = t, t = x1, x1 = x3, x3 = t; + if (x2 > x3) t = e2, e2 = e3, e3 = t, t = x2, x2 = x3, x3 = t; + if (x1 > x4) t = e1, e1 = e4, e4 = t, t = x1, x1 = x4, x4 = t; + if (x3 > x4) t = e3, e3 = e4, e4 = t, t = x3, x3 = x4, x4 = t; + if (x2 > x5) t = e2, e2 = e5, e5 = t, t = x2, x2 = x5, x5 = t; + if (x2 > x3) t = e2, e2 = e3, e3 = t, t = x2, x2 = x3, x3 = t; + if (x4 > x5) t = e4, e4 = e5, e5 = t, t = x4, x4 = x5, x5 = t; + + var pivot1 = e2, pivotValue1 = x2, + pivot2 = e4, pivotValue2 = x4; + + // e2 and e4 have been saved in the pivot variables. They will be written + // back, once the partitioning is finished. + a[i1] = e1; + a[i2] = a[lo]; + a[i3] = e3; + a[i4] = a[hi - 1]; + a[i5] = e5; + + var less = lo + 1, // First element in the middle partition. + great = hi - 2; // Last element in the middle partition. + + // Note that for value comparison, <, <=, >= and > coerce to a primitive via + // Object.prototype.valueOf; == and === do not, so in order to be consistent + // with natural order (such as for Date objects), we must do two compares. + var pivotsEqual = pivotValue1 <= pivotValue2 && pivotValue1 >= pivotValue2; + if (pivotsEqual) { + + // Degenerated case where the partitioning becomes a dutch national flag + // problem. + // + // [ | < pivot | == pivot | unpartitioned | > pivot | ] + // ^ ^ ^ ^ ^ + // left less k great right + // + // a[left] and a[right] are undefined and are filled after the + // partitioning. + // + // Invariants: + // 1) for x in ]left, less[ : x < pivot. + // 2) for x in [less, k[ : x == pivot. + // 3) for x in ]great, right[ : x > pivot. + for (var k = less; k <= great; ++k) { + var ek = a[k], xk = f(ek); + if (xk < pivotValue1) { + if (k !== less) { + a[k] = a[less]; + a[less] = ek; + } + ++less; + } else if (xk > pivotValue1) { + + // Find the first element <= pivot in the range [k - 1, great] and + // put [:ek:] there. We know that such an element must exist: + // When k == less, then el3 (which is equal to pivot) lies in the + // interval. Otherwise a[k - 1] == pivot and the search stops at k-1. + // Note that in the latter case invariant 2 will be violated for a + // short amount of time. The invariant will be restored when the + // pivots are put into their final positions. + /* eslint no-constant-condition: 0 */ + while (true) { + var greatValue = f(a[great]); + if (greatValue > pivotValue1) { + great--; + // This is the only location in the while-loop where a new + // iteration is started. + continue; + } else if (greatValue < pivotValue1) { + // Triple exchange. + a[k] = a[less]; + a[less++] = a[great]; + a[great--] = ek; + break; + } else { + a[k] = a[great]; + a[great--] = ek; + // Note: if great < k then we will exit the outer loop and fix + // invariant 2 (which we just violated). + break; + } + } + } + } + } else { + + // We partition the list into three parts: + // 1. < pivot1 + // 2. >= pivot1 && <= pivot2 + // 3. > pivot2 + // + // During the loop we have: + // [ | < pivot1 | >= pivot1 && <= pivot2 | unpartitioned | > pivot2 | ] + // ^ ^ ^ ^ ^ + // left less k great right + // + // a[left] and a[right] are undefined and are filled after the + // partitioning. + // + // Invariants: + // 1. for x in ]left, less[ : x < pivot1 + // 2. for x in [less, k[ : pivot1 <= x && x <= pivot2 + // 3. for x in ]great, right[ : x > pivot2 + (function () { // isolate scope + for (var k = less; k <= great; k++) { + var ek = a[k], xk = f(ek); + if (xk < pivotValue1) { + if (k !== less) { + a[k] = a[less]; + a[less] = ek; + } + ++less; + } else { + if (xk > pivotValue2) { + while (true) { + var greatValue = f(a[great]); + if (greatValue > pivotValue2) { + great--; + if (great < k) break; + // This is the only location inside the loop where a new + // iteration is started. + continue; + } else { + // a[great] <= pivot2. + if (greatValue < pivotValue1) { + // Triple exchange. + a[k] = a[less]; + a[less++] = a[great]; + a[great--] = ek; + } else { + // a[great] >= pivot1. + a[k] = a[great]; + a[great--] = ek; + } + break; + } + } + } + } + } + })(); // isolate scope + } + + // Move pivots into their final positions. + // We shrunk the list from both sides (a[left] and a[right] have + // meaningless values in them) and now we move elements from the first + // and third partition into these locations so that we can store the + // pivots. + a[lo] = a[less - 1]; + a[less - 1] = pivot1; + a[hi - 1] = a[great + 1]; + a[great + 1] = pivot2; + + // The list is now partitioned into three partitions: + // [ < pivot1 | >= pivot1 && <= pivot2 | > pivot2 ] + // ^ ^ ^ ^ + // left less great right + + // Recursive descent. (Don't include the pivot values.) + sort(a, lo, less - 1); + sort(a, great + 2, hi); + + if (pivotsEqual) { + // All elements in the second partition are equal to the pivot. No + // need to sort them. + return a; + } + + // In theory it should be enough to call _doSort recursively on the second + // partition. + // The Android source however removes the pivot elements from the recursive + // call if the second partition is too large (more than 2/3 of the list). + if (less < i1 && great > i5) { + + (function () { // isolate scope + var lessValue, greatValue; + while ((lessValue = f(a[less])) <= pivotValue1 && lessValue >= pivotValue1) ++less; + while ((greatValue = f(a[great])) <= pivotValue2 && greatValue >= pivotValue2) --great; + + // Copy paste of the previous 3-way partitioning with adaptions. + // + // We partition the list into three parts: + // 1. == pivot1 + // 2. > pivot1 && < pivot2 + // 3. == pivot2 + // + // During the loop we have: + // [ == pivot1 | > pivot1 && < pivot2 | unpartitioned | == pivot2 ] + // ^ ^ ^ + // less k great + // + // Invariants: + // 1. for x in [ *, less[ : x == pivot1 + // 2. for x in [less, k[ : pivot1 < x && x < pivot2 + // 3. for x in ]great, * ] : x == pivot2 + for (var k = less; k <= great; k++) { + var ek = a[k], xk = f(ek); + if (xk <= pivotValue1 && xk >= pivotValue1) { + if (k !== less) { + a[k] = a[less]; + a[less] = ek; + } + less++; + } else { + if (xk <= pivotValue2 && xk >= pivotValue2) { + /* eslint no-constant-condition: 0 */ + while (true) { + greatValue = f(a[great]); + if (greatValue <= pivotValue2 && greatValue >= pivotValue2) { + great--; + if (great < k) break; + // This is the only location inside the loop where a new + // iteration is started. + continue; + } else { + // a[great] < pivot2. + if (greatValue < pivotValue1) { + // Triple exchange. + a[k] = a[less]; + a[less++] = a[great]; + a[great--] = ek; + } else { + // a[great] == pivot1. + a[k] = a[great]; + a[great--] = ek; + } + break; + } + } + } + } + } + })(); // isolate scope + + } + + // The second partition has now been cleared of pivot elements and looks + // as follows: + // [ * | > pivot1 && < pivot2 | * ] + // ^ ^ + // less great + // Sort the second partition using recursive descent. + + // The second partition looks as follows: + // [ * | >= pivot1 && <= pivot2 | * ] + // ^ ^ + // less great + // Simply sort it by recursive descent. + + return sort(a, less, great + 1); + } + + return sort; +} + +var quicksort_sizeThreshold = 32; + +module.exports = quicksort_by(crossfilter_identity); +module.exports.by = quicksort_by; + +},{"./identity":10,"./insertionsort":11}],15:[function(require,module,exports){ +'use strict'; + +function crossfilter_reduceIncrement(p) { + return p + 1; +} + +function crossfilter_reduceDecrement(p) { + return p - 1; +} + +function crossfilter_reduceAdd(f) { + return function(p, v) { + return p + +f(v); + }; +} + +function crossfilter_reduceSubtract(f) { + return function(p, v) { + return p - f(v); + }; +} + +module.exports = { + reduceIncrement: crossfilter_reduceIncrement, + reduceDecrement: crossfilter_reduceDecrement, + reduceAdd: crossfilter_reduceAdd, + reduceSubtract: crossfilter_reduceSubtract +}; + +},{}],16:[function(require,module,exports){ +'use strict'; + +function crossfilter_zero() { + return 0; +} + +module.exports = crossfilter_zero; + +},{}]},{},[1])(1) +}); |