PageSourceSearch

https://trainfo.ca/wp-content/plugins/relish-freemium/js/vendor/crossfilter.js?ver=6.5.12

js trainfo.ca collected 2026-10-03 21:01:21 UTC 95,893 bytes, 3,194 lines download raw bytes

vendor: 3,552 bytes, lines 1-78
1(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){
2module.exports = require("./src/crossfilter").crossfilter;
3
4},{"./src/crossfilter":6}],2:[function(require,module,exports){
5(function (global){
6/**
7 * lodash (Custom Build) <https://lodash.com/>
8 * Build: `lodash modularize exports="npm" -o ./`
9 * Copyright jQuery Foundation and other contributors <https://jquery.org/>
10 * Released under MIT license <https://lodash.com/license>
11 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
12 * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
13 */
14
15/** Used as the `TypeError` message for "Functions" methods. */
16var FUNC_ERROR_TEXT = 'Expected a function';
17
18/** Used to stand-in for `undefined` hash values. */
19var HASH_UNDEFINED = '__lodash_hash_undefined__';
20
21/** Used as references for various `Number` constants. */
22var INFINITY = 1 / 0;
23
24/** `Object#toString` result references. */
25var funcTag = '[object Function]',
26    genTag = '[object GeneratorFunction]',
27    symbolTag = '[object Symbol]';
28
29/** Used to match property names within property paths. */
30var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
31    reIsPlainProp = /^\w*$/,
32    reLeadingDot = /^\./,
33    rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
34
35/**
36 * Used to match `RegExp`
37 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
38 */
39var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
40
41/** Used to match backslashes in property paths. */
42var reEscapeChar = /\\(\\)?/g;
43
44/** Used to detect host constructors (Safari). */
45var reIsHostCtor = /^\[object .+?Constructor\]$/;
46
47/** Detect free variable `global` from Node.js. */
48var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
49
50/** Detect free variable `self`. */
51var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
52
53/** Used as a reference to the global object. */
54var root = freeGlobal || freeSelf || Function('return this')();
55
56/**
57 * Gets the value at `key` of `object`.
58 *
59 * @private
60 * @param {Object} [object] The object to query.
61 * @param {string} key The key of the property to get.
62 * @returns {*} Returns the property value.
63 */
64function getValue(object, key) {
65  return object == null ? undefined : object[key];
66}
67
68/**
69 * Checks if `value` is a host object in IE < 9.
70 *
71 * @private
72 * @param {*} value The value to check.
73 * @returns {boolean} Returns `true` if `value` is a host object, else `false`.
74 */
75function isHostObject(value) {
76  // Many host objects are `Object` objects that can coerce to strings
77  // despite having improperly defined `toString` methods.
78  var result = false;
vendor: 4,788 bytes, lines 79-273
79  if (value != null && typeof value.toString != 'function') {
80    try {
81      result = !!(value + '');
82    } catch (e) {}
83  }
84  return result;
85}
86
87/** Used for built-in method references. */
88var arrayProto = Array.prototype,
89    funcProto = Function.prototype,
90    objectProto = Object.prototype;
91
92/** Used to detect overreaching core-js shims. */
93var coreJsData = root['__core-js_shared__'];
94
95/** Used to detect methods masquerading as native. */
96var maskSrcKey = (function() {
97  var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
98  return uid ? ('Symbol(src)_1.' + uid) : '';
99}());
100
101/** Used to resolve the decompiled source of functions. */
102var funcToString = funcProto.toString;
103
104/** Used to check objects for own properties. */
105var hasOwnProperty = objectProto.hasOwnProperty;
106
107/**
108 * Used to resolve the
109 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
110 * of values.
111 */
112var objectToString = objectProto.toString;
113
114/** Used to detect if a method is native. */
115var reIsNative = RegExp('^' +
116  funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&')
117  .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
118);
119
120/** Built-in value references. */
121var Symbol = root.Symbol,
122    splice = arrayProto.splice;
123
124/* Built-in method references that are verified to be native. */
125var Map = getNative(root, 'Map'),
126    nativeCreate = getNative(Object, 'create');
127
128/** Used to convert symbols to primitives and strings. */
129var symbolProto = Symbol ? Symbol.prototype : undefined,
130    symbolToString = symbolProto ? symbolProto.toString : undefined;
131
132/**
133 * Creates a hash object.
134 *
135 * @private
136 * @constructor
137 * @param {Array} [entries] The key-value pairs to cache.
138 */
139function Hash(entries) {
140  var index = -1,
141      length = entries ? entries.length : 0;
142
143  this.clear();
144  while (++index < length) {
145    var entry = entries[index];
146    this.set(entry[0], entry[1]);
147  }
148}
149
150/**
151 * Removes all key-value entries from the hash.
152 *
153 * @private
154 * @name clear
155 * @memberOf Hash
156 */
157function hashClear() {
158  this.__data__ = nativeCreate ? nativeCreate(null) : {};
159}
160
161/**
162 * Removes `key` and its value from the hash.
163 *
164 * @private
165 * @name delete
166 * @memberOf Hash
167 * @param {Object} hash The hash to modify.
168 * @param {string} key The key of the value to remove.
169 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
170 */
171function hashDelete(key) {
172  return this.has(key) && delete this.__data__[key];
173}
174
175/**
176 * Gets the hash value for `key`.
177 *
178 * @private
179 * @name get
180 * @memberOf Hash
181 * @param {string} key The key of the value to get.
182 * @returns {*} Returns the entry value.
183 */
184function hashGet(key) {
185  var data = this.__data__;
186  if (nativeCreate) {
187    var result = data[key];
188    return result === HASH_UNDEFINED ? undefined : result;
189  }
190  return hasOwnProperty.call(data, key) ? data[key] : undefined;
191}
192
193/**
194 * Checks if a hash value for `key` exists.
195 *
196 * @private
197 * @name has
198 * @memberOf Hash
199 * @param {string} key The key of the entry to check.
200 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
201 */
202function hashHas(key) {
203  var data = this.__data__;
204  return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);
205}
206
207/**
208 * Sets the hash `key` to `value`.
209 *
210 * @private
211 * @name set
212 * @memberOf Hash
213 * @param {string} key The key of the value to set.
214 * @param {*} value The value to set.
215 * @returns {Object} Returns the hash instance.
216 */
217function hashSet(key, value) {
218  var data = this.__data__;
219  data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
220  return this;
221}
222
223// Add methods to `Hash`.
224Hash.prototype.clear = hashClear;
225Hash.prototype['delete'] = hashDelete;
226Hash.prototype.get = hashGet;
227Hash.prototype.has = hashHas;
228Hash.prototype.set = hashSet;
229
230/**
231 * Creates an list cache object.
232 *
233 * @private
234 * @constructor
235 * @param {Array} [entries] The key-value pairs to cache.
236 */
237function ListCache(entries) {
238  var index = -1,
239      length = entries ? entries.length : 0;
240
241  this.clear();
242  while (++index < length) {
243    var entry = entries[index];
244    this.set(entry[0], entry[1]);
245  }
246}
247
248/**
249 * Removes all key-value entries from the list cache.
250 *
251 * @private
252 * @name clear
253 * @memberOf ListCache
254 */
255function listCacheClear() {
256  this.__data__ = [];
257}
258
259/**
260 * Removes `key` and its value from the list cache.
261 *
262 * @private
263 * @name delete
264 * @memberOf ListCache
265 * @param {string} key The key of the value to remove.
266 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
267 */
268function listCacheDelete(key) {
269  var data = this.__data__,
270      index = assocIndexOf(data, key);
271
272  if (index < 0) {
273    return false;
vendor: 3,992 bytes, lines 274-451
274  }
275  var lastIndex = data.length - 1;
276  if (index == lastIndex) {
277    data.pop();
278  } else {
279    splice.call(data, index, 1);
280  }
281  return true;
282}
283
284/**
285 * Gets the list cache value for `key`.
286 *
287 * @private
288 * @name get
289 * @memberOf ListCache
290 * @param {string} key The key of the value to get.
291 * @returns {*} Returns the entry value.
292 */
293function listCacheGet(key) {
294  var data = this.__data__,
295      index = assocIndexOf(data, key);
296
297  return index < 0 ? undefined : data[index][1];
298}
299
300/**
301 * Checks if a list cache value for `key` exists.
302 *
303 * @private
304 * @name has
305 * @memberOf ListCache
306 * @param {string} key The key of the entry to check.
307 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
308 */
309function listCacheHas(key) {
310  return assocIndexOf(this.__data__, key) > -1;
311}
312
313/**
314 * Sets the list cache `key` to `value`.
315 *
316 * @private
317 * @name set
318 * @memberOf ListCache
319 * @param {string} key The key of the value to set.
320 * @param {*} value The value to set.
321 * @returns {Object} Returns the list cache instance.
322 */
323function listCacheSet(key, value) {
324  var data = this.__data__,
325      index = assocIndexOf(data, key);
326
327  if (index < 0) {
328    data.push([key, value]);
329  } else {
330    data[index][1] = value;
331  }
332  return this;
333}
334
335// Add methods to `ListCache`.
336ListCache.prototype.clear = listCacheClear;
337ListCache.prototype['delete'] = listCacheDelete;
338ListCache.prototype.get = listCacheGet;
339ListCache.prototype.has = listCacheHas;
340ListCache.prototype.set = listCacheSet;
341
342/**
343 * Creates a map cache object to store key-value pairs.
344 *
345 * @private
346 * @constructor
347 * @param {Array} [entries] The key-value pairs to cache.
348 */
349function MapCache(entries) {
350  var index = -1,
351      length = entries ? entries.length : 0;
352
353  this.clear();
354  while (++index < length) {
355    var entry = entries[index];
356    this.set(entry[0], entry[1]);
357  }
358}
359
360/**
361 * Removes all key-value entries from the map.
362 *
363 * @private
364 * @name clear
365 * @memberOf MapCache
366 */
367function mapCacheClear() {
368  this.__data__ = {
369    'hash': new Hash,
370    'map': new (Map || ListCache),
371    'string': new Hash
372  };
373}
374
375/**
376 * Removes `key` and its value from the map.
377 *
378 * @private
379 * @name delete
380 * @memberOf MapCache
381 * @param {string} key The key of the value to remove.
382 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
383 */
384function mapCacheDelete(key) {
385  return getMapData(this, key)['delete'](key);
386}
387
388/**
389 * Gets the map value for `key`.
390 *
391 * @private
392 * @name get
393 * @memberOf MapCache
394 * @param {string} key The key of the value to get.
395 * @returns {*} Returns the entry value.
396 */
397function mapCacheGet(key) {
398  return getMapData(this, key).get(key);
399}
400
401/**
402 * Checks if a map value for `key` exists.
403 *
404 * @private
405 * @name has
406 * @memberOf MapCache
407 * @param {string} key The key of the entry to check.
408 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
409 */
410function mapCacheHas(key) {
411  return getMapData(this, key).has(key);
412}
413
414/**
415 * Sets the map `key` to `value`.
416 *
417 * @private
418 * @name set
419 * @memberOf MapCache
420 * @param {string} key The key of the value to set.
421 * @param {*} value The value to set.
422 * @returns {Object} Returns the map cache instance.
423 */
424function mapCacheSet(key, value) {
425  getMapData(this, key).set(key, value);
426  return this;
427}
428
429// Add methods to `MapCache`.
430MapCache.prototype.clear = mapCacheClear;
431MapCache.prototype['delete'] = mapCacheDelete;
432MapCache.prototype.get = mapCacheGet;
433MapCache.prototype.has = mapCacheHas;
434MapCache.prototype.set = mapCacheSet;
435
436/**
437 * Gets the index at which the `key` is found in `array` of key-value pairs.
438 *
439 * @private
440 * @param {Array} array The array to inspect.
441 * @param {*} key The key to search for.
442 * @returns {number} Returns the index of the matched value, else `-1`.
443 */
444function assocIndexOf(array, key) {
445  var length = array.length;
446  while (length--) {
447    if (eq(array[length][0], key)) {
448      return length;
449    }
450  }
451  return -1
vendor: 10,700 bytes, lines 451-887
451;
452}
453
454/**
455 * The base implementation of `_.isNative` without bad shim checks.
456 *
457 * @private
458 * @param {*} value The value to check.
459 * @returns {boolean} Returns `true` if `value` is a native function,
460 *  else `false`.
461 */
462function baseIsNative(value) {
463  if (!isObject(value) || isMasked(value)) {
464    return false;
465  }
466  var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;
467  return pattern.test(toSource(value));
468}
469
470/**
471 * The base implementation of `_.toString` which doesn't convert nullish
472 * values to empty strings.
473 *
474 * @private
475 * @param {*} value The value to process.
476 * @returns {string} Returns the string.
477 */
478function baseToString(value) {
479  // Exit early for strings to avoid a performance hit in some environments.
480  if (typeof value == 'string') {
481    return value;
482  }
483  if (isSymbol(value)) {
484    return symbolToString ? symbolToString.call(value) : '';
485  }
486  var result = (value + '');
487  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
488}
489
490/**
491 * Casts `value` to a path array if it's not one.
492 *
493 * @private
494 * @param {*} value The value to inspect.
495 * @returns {Array} Returns the cast property path array.
496 */
497function castPath(value) {
498  return isArray(value) ? value : stringToPath(value);
499}
500
501/**
502 * Gets the data for `map`.
503 *
504 * @private
505 * @param {Object} map The map to query.
506 * @param {string} key The reference key.
507 * @returns {*} Returns the map data.
508 */
509function getMapData(map, key) {
510  var data = map.__data__;
511  return isKeyable(key)
512    ? data[typeof key == 'string' ? 'string' : 'hash']
513    : data.map;
514}
515
516/**
517 * Gets the native function at `key` of `object`.
518 *
519 * @private
520 * @param {Object} object The object to query.
521 * @param {string} key The key of the method to get.
522 * @returns {*} Returns the function if it's native, else `undefined`.
523 */
524function getNative(object, key) {
525  var value = getValue(object, key);
526  return baseIsNative(value) ? value : undefined;
527}
528
529/**
530 * Checks if `value` is a property name and not a property path.
531 *
532 * @private
533 * @param {*} value The value to check.
534 * @param {Object} [object] The object to query keys on.
535 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
536 */
537function isKey(value, object) {
538  if (isArray(value)) {
539    return false;
540  }
541  var type = typeof value;
542  if (type == 'number' || type == 'symbol' || type == 'boolean' ||
543      value == null || isSymbol(value)) {
544    return true;
545  }
546  return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
547    (object != null && value in Object(object));
548}
549
550/**
551 * Checks if `value` is suitable for use as unique object key.
552 *
553 * @private
554 * @param {*} value The value to check.
555 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
556 */
557function isKeyable(value) {
558  var type = typeof value;
559  return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
560    ? (value !== '__proto__')
561    : (value === null);
562}
563
564/**
565 * Checks if `func` has its source masked.
566 *
567 * @private
568 * @param {Function} func The function to check.
569 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
570 */
571function isMasked(func) {
572  return !!maskSrcKey && (maskSrcKey in func);
573}
574
575/**
576 * Converts `string` to a property path array.
577 *
578 * @private
579 * @param {string} string The string to convert.
580 * @returns {Array} Returns the property path array.
581 */
582var stringToPath = memoize(function(string) {
583  string = toString(string);
584
585  var result = [];
586  if (reLeadingDot.test(string)) {
587    result.push('');
588  }
589  string.replace(rePropName, function(match, number, quote, string) {
590    result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
591  });
592  return result;
593});
594
595/**
596 * Converts `value` to a string key if it's not a string or symbol.
597 *
598 * @private
599 * @param {*} value The value to inspect.
600 * @returns {string|symbol} Returns the key.
601 */
602function toKey(value) {
603  if (typeof value == 'string' || isSymbol(value)) {
604    return value;
605  }
606  var result = (value + '');
607  return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
608}
609
610/**
611 * Converts `func` to its source code.
612 *
613 * @private
614 * @param {Function} func The function to process.
615 * @returns {string} Returns the source code.
616 */
617function toSource(func) {
618  if (func != null) {
619    try {
620      return funcToString.call(func);
621    } catch (e) {}
622    try {
623      return (func + '');
624    } catch (e) {}
625  }
626  return '';
627}
628
629/**
630 * Creates a function that memoizes the result of `func`. If `resolver` is
631 * provided, it determines the cache key for storing the result based on the
632 * arguments provided to the memoized function. By default, the first argument
633 * provided to the memoized function is used as the map cache key. The `func`
634 * is invoked with the `this` binding of the memoized function.
635 *
636 * **Note:** The cache is exposed as the `cache` property on the memoized
637 * function. Its creation may be customized by replacing the `_.memoize.Cache`
638 * constructor with one whose instances implement the
639 * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
640 * method interface of `delete`, `get`, `has`, and `set`.
641 *
642 * @static
643 * @memberOf _
644 * @since 0.1.0
645 * @category Function
646 * @param {Function} func The function to have its output memoized.
647 * @param {Function} [resolver] The function to resolve the cache key.
648 * @returns {Function} Returns the new memoized function.
649 * @example
650 *
651 * var object = { 'a': 1, 'b': 2 };
652 * var other = { 'c': 3, 'd': 4 };
653 *
654 * var values = _.memoize(_.values);
655 * values(object);
656 * // => [1, 2]
657 *
658 * values(other);
659 * // => [3, 4]
660 *
661 * object.a = 2;
662 * values(object);
663 * // => [1, 2]
664 *
665 * // Modify the result cache.
666 * values.cache.set(object, ['a', 'b']);
667 * values(object);
668 * // => ['a', 'b']
669 *
670 * // Replace `_.memoize.Cache`.
671 * _.memoize.Cache = WeakMap;
672 */
673function memoize(func, resolver) {
674  if (typeof func != 'function' || (resolver && typeof resolver != 'function')) {
675    throw new TypeError(FUNC_ERROR_TEXT);
676  }
677  var memoized = function() {
678    var args = arguments,
679        key = resolver ? resolver.apply(this, args) : args[0],
680        cache = memoized.cache;
681
682    if (cache.has(key)) {
683      return cache.get(key);
684    }
685    var result = func.apply(this, args);
686    memoized.cache = cache.set(key, result);
687    return result;
688  };
689  memoized.cache = new (memoize.Cache || MapCache);
690  return memoized;
691}
692
693// Assign cache to `_.memoize`.
694memoize.Cache = MapCache;
695
696/**
697 * Performs a
698 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
699 * comparison between two values to determine if they are equivalent.
700 *
701 * @static
702 * @memberOf _
703 * @since 4.0.0
704 * @category Lang
705 * @param {*} value The value to compare.
706 * @param {*} other The other value to compare.
707 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
708 * @example
709 *
710 * var object = { 'a': 1 };
711 * var other = { 'a': 1 };
712 *
713 * _.eq(object, object);
714 * // => true
715 *
716 * _.eq(object, other);
717 * // => false
718 *
719 * _.eq('a', 'a');
720 * // => true
721 *
722 * _.eq('a', Object('a'));
723 * // => false
724 *
725 * _.eq(NaN, NaN);
726 * // => true
727 */
728function eq(value, other) {
729  return value === other || (value !== value && other !== other);
730}
731
732/**
733 * Checks if `value` is classified as an `Array` object.
734 *
735 * @static
736 * @memberOf _
737 * @since 0.1.0
738 * @category Lang
739 * @param {*} value The value to check.
740 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
741 * @example
742 *
743 * _.isArray([1, 2, 3]);
744 * // => true
745 *
746 * _.isArray(document.body.children);
747 * // => false
748 *
749 * _.isArray('abc');
750 * // => false
751 *
752 * _.isArray(_.noop);
753 * // => false
754 */
755var isArray = Array.isArray;
756
757/**
758 * Checks if `value` is classified as a `Function` object.
759 *
760 * @static
761 * @memberOf _
762 * @since 0.1.0
763 * @category Lang
764 * @param {*} value The value to check.
765 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
766 * @example
767 *
768 * _.isFunction(_);
769 * // => true
770 *
771 * _.isFunction(/abc/);
772 * // => false
773 */
774function isFunction(value) {
775  // The use of `Object#toString` avoids issues with the `typeof` operator
776  // in Safari 8-9 which returns 'object' for typed array and other constructors.
777  var tag = isObject(value) ? objectToString.call(value) : '';
778  return tag == funcTag || tag == genTag;
779}
780
781/**
782 * Checks if `value` is the
783 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
784 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
785 *
786 * @static
787 * @memberOf _
788 * @since 0.1.0
789 * @category Lang
790 * @param {*} value The value to check.
791 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
792 * @example
793 *
794 * _.isObject({});
795 * // => true
796 *
797 * _.isObject([1, 2, 3]);
798 * // => true
799 *
800 * _.isObject(_.noop);
801 * // => true
802 *
803 * _.isObject(null);
804 * // => false
805 */
806function isObject(value) {
807  var type = typeof value;
808  return !!value && (type == 'object' || type == 'function');
809}
810
811/**
812 * Checks if `value` is object-like. A value is object-like if it's not `null`
813 * and has a `typeof` result of "object".
814 *
815 * @static
816 * @memberOf _
817 * @since 4.0.0
818 * @category Lang
819 * @param {*} value The value to check.
820 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
821 * @example
822 *
823 * _.isObjectLike({});
824 * // => true
825 *
826 * _.isObjectLike([1, 2, 3]);
827 * // => true
828 *
829 * _.isObjectLike(_.noop);
830 * // => false
831 *
832 * _.isObjectLike(null);
833 * // => false
834 */
835function isObjectLike(value) {
836  return !!value && typeof value == 'object';
837}
838
839/**
840 * Checks if `value` is classified as a `Symbol` primitive or object.
841 *
842 * @static
843 * @memberOf _
844 * @since 4.0.0
845 * @category Lang
846 * @param {*} value The value to check.
847 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
848 * @example
849 *
850 * _.isSymbol(Symbol.iterator);
851 * // => true
852 *
853 * _.isSymbol('abc');
854 * // => false
855 */
856function isSymbol(value) {
857  return typeof value == 'symbol' ||
858    (isObjectLike(value) && objectToString.call(value) == symbolTag);
859}
860
861/**
862 * Converts `value` to a string. An empty string is returned for `null`
863 * and `undefined` values. The sign of `-0` is preserved.
864 *
865 * @static
866 * @memberOf _
867 * @since 4.0.0
868 * @category Lang
869 * @param {*} value The value to process.
870 * @returns {string} Returns the string.
871 * @example
872 *
873 * _.toString(null);
874 * // => ''
875 *
876 * _.toString(-0);
877 * // => '-0'
878 *
879 * _.toString([1, 2, 3]);
880 * // => '1,2,3'
881 */
882function toString(value) {
883  return value == null ? '' : baseToString(value);
884}
885
886/**
887 * 
887This method is like `_.get` except that if the resolved value is a
888 * function it's invoked with the `this` binding of its parent object and
889 * its result is returned.
890 *
891 * @static
892 * @since 0.1.0
893 * @memberOf _
894 * @category Object
895 * @param {Object} object The object to query.
896 * @param {Array|string} path The path of the property to resolve.
897 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
898 * @returns {*} Returns the resolved value.
899 * @example
900 *
901 * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
902 *
903 * _.result(object, 'a[0].b.c1');
904 * // => 3
905 *
906 * _.result(object, 'a[0].b.c2');
907 * // => 4
908 *
909 * _.result(object, 'a[0].b.c3', 'default');
910 * // => 'default'
911 *
912 * _.result(object, 'a[0].b.c3', _.constant('default'));
913 * // => 'default'
914 */
915function result(object, path, defaultValue) {
916  path = isKey(path, object) ? [path] : castPath(path);
917
918  var index = -1,
919      length = path.length;
920
921  // Ensure the loop is entered when path is empty.
922  if (!length) {
923    object = undefined;
924    length = 1;
925  }
926  while (++index < length) {
927    var value = object == null ? undefined : object[toKey(path[index])];
928    if (value === undefined) {
929      index = length;
930      value = defaultValue;
931    }
932    object = isFunction(value) ? value.call(object) : value;
933  }
934  return object;
935}
936
937module.exports = result;
938
939}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
940},{}],3:[function(require,module,exports){
941module.exports={"version":"1.4.8"}
942},{}],4:[function(require,module,exports){
943var crossfilter_array8 = crossfilter_arrayUntyped,
944    crossfilter_array16 = crossfilter_arrayUntyped,
945    crossfilter_array32 = crossfilter_arrayUntyped,
946    crossfilter_arrayLengthen = crossfilter_arrayLengthenUntyped,
947    crossfilter_arrayWiden = crossfilter_arrayWidenUntyped;
948if (typeof Uint8Array !== "undefined") {
949  crossfilter_array8 = function(n) { return new Uint8Array(n); };
950  crossfilter_array16 = function(n) { return new Uint16Array(n); };
951  crossfilter_array32 = function(n) { return new Uint32Array(n); };
952
953  crossfilter_arrayLengthen = function(array, length) {
954    if (array.length >= length) return array;
955    var copy = new array.constructor(length);
956    copy.set(array);
957    return copy;
958  };
959
960  crossfilter_arrayWiden = function(array, width) {
961    var copy;
962    switch (width) {
963      case 16: copy = crossfilter_array16(array.length); break;
964      case 32: copy = crossfilter_array32(array.length); break;
965      default: throw new Error("invalid array width!");
966    }
967    copy.set(array);
968    return copy;
969  };
970}
971
972function crossfilter_arrayUntyped(n) {
973  var array = new Array(n), i = -1;
974  while (++i < n) array[i] = 0;
975  return array;
976}
977
978function crossfilter_arrayLengthenUntyped(array, length) {
979  var n = array.length;
980  while (n < length) array[n++] = 0;
981  return array;
982}
983
984function crossfilter_arrayWidenUntyped(array, width) {
985  if (width > 32) throw new Error("invalid array width!");
986  return array;
987}
988
989// An arbitrarily-wide array of bitmasks
990function crossfilter_bitarray(n) {
991  this.length = n;
992  this.subarrays = 1;
993  this.width = 8;
994  this.masks = {
995    0: 0
996  }
997
998  this[0] = crossfilter_array8(n);
999}
1000
1001crossfilter_bitarray.prototype.lengthen = function(n) {
1002  var i, len;
1003  for (i = 0, len = this.subarrays; i < len; ++i) {
1004    this[i] = crossfilter_arrayLengthen(this[i], n);
1005  }
1006  this.length = n;
1007};
1008
1009// Reserve a new bit index in the array, returns {offset, one}
1010crossfilter_bitarray.prototype.add = function() {
1011  var m, w, one, i, len;
1012
1013  for (i = 0, len = this.subarrays; i < len; ++i) {
1014    m = this.masks[i];
1015    w = this.width - (32 * i);
1016    // isolate the rightmost zero bit and return it as an unsigned int of 32 bits, if NaN or -1, return a 0 
1017    one = (~m & (m + 1)) >>> 0;
1018
1019    if (w >= 32 && !one) {
1020      continue;
1021    }
1022
1023    if (w < 32 && (one & (1 << w))) {
1024      // widen this subarray
1025      this[i] = crossfilter_arrayWiden(this[i], w <<= 1);
1026      this.width = 32 * i + w;
1027    }
1028
1029    this.masks[i] |= one;
1030
1031    return {
1032      offset: i,
1033      one: one
1034    };
1035  }
1036
1037  // add a new subarray
1038  this[this.subarrays] = crossfilter_array8(this.length);
1039  this.masks[this.subarrays] = 1;
1040  this.width += 8;
1041  return {
1042    offset: this.subarrays++,
1043    one: 1
1044  };
1045};
1046
1047// Copy record from index src to index dest
1048crossfilter_bitarray.prototype.copy = function(dest, src) {
1049  var i, len;
1050  for (i = 0, len = this.subarrays; i < len; ++i) {
1051    this[i][dest] = this[i][src];
1052  }
1053};
1054
1055// Truncate the array to the given length
1056crossfilter_bitarray.prototype.truncate = function(n) {
1057  var i, len;
1058  for (i = 0, len = this.subarrays; i < len; ++i) {
1059    for (var j = this.length - 1; j >= n; j--) {
1060      this[i][j] = 0;
1061    }
1062  }
1063  this.length = n;
1064};
1065
1066// Checks that all bits for the given index are 0
1067crossfilter_bitarray.prototype.zero = function(n) {
1068  var i, len;
1069  for (i = 0, len = this.subarrays; i < len; ++i) {
1070    if (this[i][n]) {
1071      return false;
1072    }
1073  }
1074  return true;
1075};
1076
1077// Checks that all bits for the given index are 0 except for possibly one
1078crossfilter_bitarray.prototype.zeroExcept = function(n, offset, zero) {
1079  var i, len;
1080  for (i = 0, len = this.subarrays; i < len; ++i) {
1081    if (i === offset ? this[i][n] & zero : this[i][n]) {
1082      return false;
1083    }
1084  }
1085  return true;
1086};
1087
1088// Checks that all bits for the given index are 0 except for the specified mask.
1089// The mask should be an array of the same size as the filter subarrays width.
1090crossfilter_bitarray.prototype.zeroExceptMask = function(n, mask) {
1091  var i, len;
1092  for (i = 0, len = this.subarrays; i < len; ++i) {
1093    if (this[i][n] & mask[i]) {
1094      return false;
1095    }
1096  }
1097  return true;
1098}
1099
1100// Checks that only the specified bit is set for the given index
1101crossfilter_bitarray.prototype.only = function(n, offset, one) {
1102  var i, len;
1103  for (i = 0, len = this.subarrays; i < len; ++i) {
1104    if (this[i][n] != (i === offset ? one : 0)) {
1105      return false;
1106    }
1107  }
1108  return true;
1109};
1110
1111// Checks that only the specified bit is set for the given index except for possibly one other
1112crossfilter_bitarray.prototype.onlyExcept = function(n, offset, zero, onlyOffset, onlyOne) {
1113  var mask;
1114  var i, len;
1115  for (i = 0, len = this.subarrays; i < len; ++i) {
1116    mask = this[i][n];
1117    if (i === offset)
1118      mask &= zero;
1119    if (mask != (i === onlyOffset ? onlyOne : 0)) {
1120      return false;
1121    }
1122  }
1123  return true;
1124};
1125
1126module.exports = {
1127  array8: crossfilter_array8,
1128  array16: crossfilter_array16,
1129  array32: crossfilter_array32,
1130  arrayLengthen: crossfilter_arrayLengthen,
1131  arrayWiden: crossfilter_arrayWiden,
1132  bitarray: crossfilter_bitarray
1133};
1134
1135},{}],5:[function(require,module,exports){
1136'use strict';
1137
1138var crossfilter_identity = require('./identity');
1139
1140function bisect_by(f) {
1141
1142  // Locate the insertion point for x in a to maintain sorted order. The
1143  // arguments lo and hi may be used to specify a subset of the array which
1144  // should be considered; by default the entire array is used. If x is already
1145  // present in a, the insertion point will be before (to the left of) any
1146  // existing entries. The return value is suitable for use as the first
1147  // argument to `array.splice` assuming that a is already sorted.
1148  //
1149  // The returned insertion point i partitions the array a into two halves so
1150  // that all v < x for v in a[lo:i] for the left side and all v >= x for v in
1151  // a[i:hi] for the right side.
1152  function bisectLeft(a, x, lo, hi) {
1153    while (lo < hi) {
1154      var mid = lo + hi >>> 1;
1155      if (f(a[mid]) < x) lo = mid + 1;
1156      else hi = mid;
1157    }
1158    return lo;
1159  }
1160
1161  // Similar to bisectLeft, but returns an insertion point which comes after (to
1162  // the right of) any existing entries of x in a.
1163  //
1164  // The returned insertion point i partitions the array into two halves so that
1165  // all v <= x for v in a[lo:i] for the left side and all v > x for v in
1166  // a[i:hi] for the right side.
1167  function bisectRight(a, x, lo, hi) {
1168    while (lo < hi) {
1169      var mid = lo + hi >>> 1;
1170      if (x < f(a[mid])) hi = mid;
1171      else lo = mid + 1;
1172    }
1173    return lo;
1174  }
1175
1176  bisectRight.right = bisectRight;
1177  bisectRight.left = bisectLeft;
1178  return bisectRight;
1179}
1180
1181module.exports = bisect_by(crossfilter_identity);
1182module.exports.by = bisect_by; // assign the raw function to the export as well
1183
1184},{"./identity":10}],6:[function(require,module,exports){
1185'use strict';
1186
1187var xfilterArray = require('./array');
1188var xfilterFilter = require('./filter');
1189var crossfilter_identity = require('./identity');
1190var crossfilter_null = require('./null');
1191var crossfilter_zero = require('./zero');
1192var xfilterHeapselect = require('./heapselect');
1193var xfilterHeap = require('./heap');
1194var bisect = require('./bisect');
1195var insertionsort = require('./insertionsort');
1196var permute = require('./permute');
1197var quicksort = require('./quicksort');
1198var xfilterReduce = require('./reduce');
1199var packageJson = require('./../package.json'); // require own package.json for the version field
1200var result = require('lodash.result');
1201
1202// constants
1203var REMOVED_INDEX = -1;
1204
1205// expose API exports
1206exports.crossfilter = crossfilter;
1207exports.crossfilter.heap = xfilterHeap;
1208exports.crossfilter.heapselect = xfilterHeapselect;
1209exports.crossfilter.bisect = bisect;
1210exports.crossfilter.insertionsort = insertionsort;
1211exports.crossfilter.permute = permute;
1212exports.crossfilter.quicksort = quicksort;
1213exports.crossfilter.version = packageJson.version; // please note use of "package-json-versionify" transform
1214
1215function crossfilter() {
1216  var crossfilter = {
1217    add: add,
1218    remove: removeData,
1219    dimension: dimension,
1220    groupAll: groupAll,
1221    size: size,
1222    all: all,
1223    allFiltered: allFiltered,
1224    onChange: onChange,
1225    isElementFiltered: isElementFiltered
1226  };
1227
1228  var data = [], // the records
1229      n = 0, // the number of records; data.length
1230      filters, // 1 is filtered out
1231      filterListeners = [], // when the filters change
1232      dataListeners = [], // when data is added
1233      removeDataListeners = [], // when data is removed
1234      callbacks = [];
1235
1236  filters = new xfilterArray.bitarray(0);
1237
1238  // Adds the specified new records to this crossfilter.
1239  function add(newData) {
1240    var n0 = n,
1241        n1 = newData.length;
1242
1243    // If there's actually new data to add…
1244    // Merge the new data into the existing data.
1245    // Lengthen the filter bitset to handle the new records.
1246    // Notify listeners (dimensions and groups) that new data is available.
1247    if (n1) {
1248      data = data.concat(newData);
1249      filters.lengthen(n += n1);
1250      dataListeners.forEach(function(l) { l(newData, n0, n1); });
1251      triggerOnChange('dataAdded');
1252    }
1253
1254    return crossfilter;
1255  }
1256
1257  // Removes all records that match the current filters, or if a predicate function is passed,
1258  // removes all records matching the predicate (ignoring filters).
1259  function removeData(predicate) {
1260    var // Mapping from old record indexes to new indexes (after records removed)
1261        newIndex = new Array(n),
1262        removed = [],
1263        usePred = typeof predicate === 'function',
1264        shouldRemove = function (i) {
1265          return usePred ? predicate(data[i], i) : filters.zero(i)
1266        };
1267
1268    for (var index1 = 0, index2 = 0; index1 < n; ++index1) {
1269      if ( shouldRemove(index1) ) {
1270        removed.push(index1);
1271        newIndex[index1] = REMOVED_INDEX;
1272      } else {
1273        newIndex[index1] = index2++;
1274      }
1275    }
1276
1277    // Remove all matching records from groups.
1278    filterListeners.forEach(function(l) { l(-1, -1, [], removed, true); });
1279
1280    // Update indexes.
1281    removeDataListeners.forEach(function(l) { l(newIndex); });
1282
1283    // Remove old filters and data by overwriting.
1284    for (var index3 = 0, index4 = 0; index3 < n; ++index3) {
1285      if ( newIndex[index3] !== REMOVED_INDEX ) {
1286        if (index3 !== index4) filters.copy(index4, index3), data[index4] = data[index3];
1287        ++index4;
1288      }
1289    }
1290
1291    data.length = n = index4;
1292    filters.truncate(index4);
1293    triggerOnChange('dataRemoved');
1294  }
1295
1296  function maskForDimensions(dimensions) {
1297    var n,
1298        d,
1299        len,
1300        id,
1301        mask = Array(filters.subarrays);
1302    for (n = 0; n < filters.subarrays; n++) { mask[n] = ~0; }
1303    for (d = 0, len = dimensions.length; d < len; d++) {
1304      // The top bits of the ID are the subarray offset and the lower bits are the bit
1305      // offset of the "one" mask.
1306      id = dimensions[d].id();
1307      mask[id >> 7] &= ~(0x1 << (id & 0x3f));
1308    }
1309    return mask;
1310  }
1311
1312  // Return true if the data element at index i is filtered IN.
1313  // Optionally, ignore the filters of any dimensions in the ignore_dimensions list.
1314  function isElementFiltered(i, ignore_dimensions) {
1315    var mask = maskForDimensions(ignore_dimensions || []);
1316    return filters.zeroExceptMask(i,mask);
1317  }
1318
1319  // Adds a new dimension with the specified value accessor function.
1320  function dimension(value, iterable) {
1321
1322    if (typeof value === 'string') {
1323      var accessorPath = value;
1324      value = function(d) { return result(d, accessorPath); };
1325    }
1326
1327    var dimension = {
1328      filter: filter,
1329      filterExact: filterExact,
1330      filterRange: filterRange,
1331      filterFunction: filterFunction,
1332      filterAll: filterAll,
1333      currentFilter: currentFilter,
1334      hasCurrentFilter: hasCurrentFilter,
1335      top: top,
1336      bottom: bottom,
1337      group: group,
1338      groupAll: groupAll,
1339      dispose: dispose,
1340      remove: dispose, // for backwards-compatibility
1341      accessor: value,
1342      id: function() { return id; }
1343    };
1344
1345    var one, // lowest unset bit as mask, e.g., 00001000
1346        zero, // inverted one, e.g., 11110111
1347        offset, // offset into the filters arrays
1348        id, // unique ID for this dimension (reused when dimensions are disposed)
1349        values, // sorted, cached array
1350        index, // maps sorted value index -> record index (in data)
1351        newValues, // temporary array storing newly-added values
1352        newIndex, // temporary array storing newly-added index
1353        iterablesIndexCount,
1354        iterablesIndexFilterStatus,
1355        iterablesEmptyRows = [],
1356        sort = quicksort.by(function(i) { return newValues[i]; }),
1357        refilter = xfilterFilter.filterAll, // for recomputing filter
1358        refilterFunction, // the custom filter function in use
1359        filterValue, // the value used for filtering (value, array, function or undefined)
1360        filterValuePresent, // true if filterValue contains something
1361        indexListeners = [], // when data is added
1362        dimensionGroups = [],
1363        lo0 = 0,
1364        hi0 = 0,
1365        t = 0,
1366        k;
1367
1368    // Updating a dimension is a two-stage process. First, we must update the
1369    // associated filters for the newly-added records. Once all dimensions have
1370    // updated their filters, the groups are notified to update.
1371    dataListeners.unshift(preAdd);
1372    dataListeners.push(postAdd);
1373
1374    removeDataListeners.push(removeData);
1375
1376    // Add a new dimension in the filter bitmap and store the offset and bitmask.
1377    var tmp = filters.add();
1378    offset = tmp.offset;
1379    one = tmp.one;
1380    zero = ~one;
1381
1382    // Create a unique ID for the dimension
1383    // IDs will be re-used if dimensions are disposed.
1384    // For internal use the ID is the subarray offset shifted left 7 bits or'd with the
1385    // bit offset of the set bit in the dimension's "one" mask.
1386    id = (offset << 7) | (Math.log(one) / Math.log(2));
1387
1388    preAdd(data, 0, n);
1389    postAdd(data, 0, n);
1390
1391    // Incorporates the specified new records into this dimension.
1392    // This function is responsible for updating filters, values, and index.
1393    function preAdd(newData, n0, n1) {
1394      var newIterablesIndexCount,
1395          newIterablesIndexFilterStatus;
1396
1397      if (iterable){
1398        // Count all the values
1399        t = 0;
1400        j = 0;
1401        k = [];
1402
1403        for (var i0 = 0; i0 < newData.length; i0++) {
1404          for(j = 0, k = value(newData[i0]); j < k.length; j++) {
1405            t++;
1406          }
1407        }
1408
1409        newValues = [];
1410        newIterablesIndexCount = crossfilter_range(newData.length);
1411        newIterablesIndexFilterStatus = crossfilter_index(t,1);
1412        var unsortedIndex = crossfilter_range(t);
1413
1414        for (var l = 0, index1 = 0; index1 < newData.length; index1++) {
1415          k = value(newData[index1])
1416          //
1417          if(!k.length){
1418            newIterablesIndexCount[index1] = 0;
1419            iterablesEmptyRows.push(index1 + n0);
1420            continue;
1421          }
1422          newIterablesIndexCount[index1] = k.length
1423          for (j = 0; j < k.length; j++) {
1424            newValues.push(k[j]);
1425            unsortedIndex[l] = index1;
1426            l++;
1427          }
1428        }
1429
1430        // Create the Sort map used to sort both the values and the valueToData indices
1431        var sortMap = sort(crossfilter_range(t), 0, t);
1432
1433        // Use the sortMap to sort the newValues
1434        newValues = permute(newValues, sortMap);
1435
1436
1437        // Use the sortMap to sort the unsortedIndex map
1438        // newIndex should be a map of sortedValue -> crossfilterData
1439        newIndex = permute(unsortedIndex, sortMap)
1440
1441      } else{
1442        // Permute new values into natural order using a standard sorted index.
1443        newValues = newData.map(value);
1444        newIndex = sort(crossfilter_range(n1), 0, n1);
1445        newValues = permute(newValues, newIndex);
1446      }
1447
1448      // Bisect newValues to determine which new records are selected.
1449      var bounds = refilter(newValues), lo1 = bounds[0], hi1 = bounds[1];
1450
1451      var index2, index3, index4;
1452      if(iterable) {
1453        n1 = t;
1454        if (refilterFunction) {
1455          for (index2 = 0; index2 < n1; ++index2) {
1456            if (!refilterFunction(newValues[index2], index2)) {
1457              if(--newIterablesIndexCount[newIndex[index2]] === 0) {
1458                filters[offset][newIndex[index2] + n0] |= one;
1459              }
1460              newIterablesIndexFilterStatus[index2] = 1;
1461            }
1462          }
1463        } else {
1464          for (index3 = 0; index3 < lo1; ++index3) {
1465            if(--newIterablesIndexCount[newIndex[index3]] === 0) {
1466              filters[offset][newIndex[index3] + n0] |= one;
1467            }
1468            newIterablesIndexFilterStatus[index3] = 1;
1469          }
1470          for (index4 = hi1; index4 < n1; ++index4) {
1471            if(--newIterablesIndexCount[newIndex[index4]] === 0) {
1472              filters[offset][newIndex[index4] + n0] |= one;
1473            }
1474            newIterablesIndexFilterStatus[index4] = 1;
1475          }
1476        }
1477      } else {
1478        if (refilterFunction) {
1479          for (index2 = 0; index2 < n1; ++index2) {
1480            if (!refilterFunction(newValues[index2], index2)) {
1481              filters[offset][newIndex[index2] + n0] |= one;
1482            }
1483          }
1484        } else {
1485          for (index3 = 0; index3 < lo1; ++index3) {
1486            filters[offset][newIndex[index3] + n0] |= one;
1487          }
1488          for (index4 = hi1; index4 < n1; ++index4) {
1489            filters[offset][newIndex[index4] + n0] |= one;
1490          }
1491        }
1492      }
1493
1494      // If this dimension previously had no data, then we don't need to do the
1495      // more expensive merge operation; use the new values and index as-is.
1496      if (!n0) {
1497        values = newValues;
1498        index = newIndex;
1499        iterablesIndexCount = newIterablesIndexCount;
1500        iterablesIndexFilterStatus = newIterablesIndexFilterStatus;
1501        lo0 = lo1;
1502        hi0 = hi1;
1503        return;
1504      }
1505
1506
1507
1508      var oldValues = values,
1509        oldIndex = index,
1510        oldIterablesIndexFilterStatus = iterablesIndexFilterStatus,
1511        old_n0,
1512        i1 = 0;
1513
1514      i0 = 0;
1515
1516      if(iterable){
1517        old_n0 = n0
1518        n0 = oldValues.length;
1519        n1 = t
1520      }
1521
1522      // Otherwise, create new arrays into which to merge new and old.
1523      values = iterable ? new Array(n0 + n1) : new Array(n);
1524      index = iterable ? new Array(n0 + n1) : crossfilter_index(n, n);
1525      if(iterable) iterablesIndexFilterStatus = crossfilter_index(n0 + n1, 1);
1526
1527      // Concatenate the newIterablesIndexCount onto the old one.
1528      if(iterable) {
1529        var oldiiclength = iterablesIndexCount.length;
1530        iterablesIndexCount = xfilterArray.arrayLengthen(iterablesIndexCount, n);
1531        for(var j=0; j+oldiiclength < n; j++) {
1532          iterablesIndexCount[j+oldiiclength] = newIterablesIndexCount[j];
1533        }
1534      }
1535
1536      // Merge the old and new sorted values, and old and new index.
1537      var index5 = 0;
1538      for (; i0 < n0 && i1 < n1; ++index5) {
1539        if (oldValues[i0] < newValues[i1]) {
1540          values[index5] = oldValues[i0];
1541          if(iterable) iterablesIndexFilterStatus[index5] = oldIterablesIndexFilterStatus[i0];
1542          index[index5] = oldIndex[i0++];
1543        } else {
1544          values[index5] = newValues[i1];
1545          if(iterable) iterablesIndexFilterStatus[index5] = newIterablesIndexFilterStatus[i1];
1546          index[index5] = newIndex[i1++] + (iterable ? old_n0 : n0);
1547        }
1548      }
1549
1550      // Add any remaining old values.
1551      for (; i0 < n0; ++i0, ++index5) {
1552        values[index5] = oldValues[i0];
1553        if(iterable) iterablesIndexFilterStatus[index5] = oldIterablesIndexFilterStatus[i0];
1554        index[index5] = oldIndex[i0];
1555      }
1556
1557      // Add any remaining new values.
1558      for (; i1 < n1; ++i1, ++index5) {
1559        values[index5] = newValues[i1];
1560        if(iterable) iterablesIndexFilterStatus[index5] = newIterablesIndexFilterStatus[i1];
1561        index[index5] = newIndex[i1] + (iterable ? old_n0 : n0);
1562      }
1563
1564      // Bisect again to recompute lo0 and hi0.
1565      bounds = refilter(values), lo0 = bounds[0], hi0 = bounds[1];
1566    }
1567
1568    // When all filters have updated, notify index listeners of the new values.
1569    function postAdd(newData, n0, n1) {
1570      indexListeners.forEach(function(l) { l(newValues, newIndex, n0, n1); });
1571      newValues = newIndex = null;
1572    }
1573
1574    function removeData(reIndex) {
1575      if (iterable) {
1576        for (var i0 = 0, i1 = 0; i0 < iterablesEmptyRows.length; i0++) {
1577          if (reIndex[iterablesEmptyRows[i0]] !== REMOVED_INDEX) {
1578            iterablesEmptyRows[i1] = reIndex[iterablesEmptyRows[i0]];
1579            i1++;
1580          }
1581        }
1582        iterablesEmptyRows.length = i1;
1583        for (i0 = 0, i1 = 0; i0 < n; i0++) {
1584          if (reIndex[i0] !== REMOVED_INDEX) {
1585            if (i1 !== i0) iterablesIndexCount[i1] = iterablesIndexCount[i0];
1586            i1++;
1587          }
1588        }
1589        iterablesIndexCount = iterablesIndexCount.slice(0, i1);
1590      }
1591      // Rewrite our index, overwriting removed values
1592      var n0 = values.length;
1593      for (var i = 0, j = 0, oldDataIndex; i < n0; ++i) {
1594        oldDataIndex = index[i];
1595        if (reIndex[oldDataIndex] !== REMOVED_INDEX) {
1596          if (i !== j) values[j] = values[i];
1597          index[j] = reIndex[oldDataIndex];
1598          if (iterable) {
1599            iterablesIndexFilterStatus[j] = iterablesIndexFilterStatus[i];
1600          }
1601          ++j;
1602        }
1603      }
1604      values.length = j;
1605      if (iterable) iterablesIndexFilterStatus = iterablesIndexFilterStatus.slice(0, j);
1606      while (j < n0) index[j++] = 0;
1607
1608      // Bisect again to recompute lo0 and hi0.
1609      var bounds = refilter(values);
1610      lo0 = bounds[0], hi0 = bounds[1];
1611    }
1612
1613    // Updates the selected values based on the specified bounds [lo, hi].
1614    // This implementation is used by all the public filter methods.
1615    function filterIndexBounds(bounds) {
1616
1617      var lo1 = bounds[0],
1618          hi1 = bounds[1];
1619
1620      if (refilterFunction) {
1621        refilterFunction = null;
1622        filterIndexFunction(function(d, i) { return lo1 <= i && i < hi1; }, bounds[0] === 0 && bounds[1] === values.length);
1623        lo0 = lo1;
1624        hi0 = hi1;
1625        return dimension;
1626      }
1627
1628      var i,
1629          j,
1630          k,
1631          added = [],
1632          removed = [],
1633          valueIndexAdded = [],
1634          valueIndexRemoved = [];
1635
1636
1637      // Fast incremental update based on previous lo index.
1638      if (lo1 < lo0) {
1639        for (i = lo1, j = Math.min(lo0, hi1); i < j; ++i) {
1640          added.push(index[i]);
1641          valueIndexAdded.push(i);
1642        }
1643      } else if (lo1 > lo0) {
1644        for (i = lo0, j = Math.min(lo1, hi0); i < j; ++i) {
1645          removed.push(index[i]);
1646          valueIndexRemoved.push(i);
1647        }
1648      }
1649
1650      // Fast incremental update based on previous hi index.
1651      if (hi1 > hi0) {
1652        for (i = Math.max(lo1, hi0), j = hi1; i < j; ++i) {
1653          added.push(index[i]);
1654          valueIndexAdded.push(i);
1655        }
1656      } else if (hi1 < hi0) {
1657        for (i = Math.max(lo0, hi1), j = hi0; i < j; ++i) {
1658          removed.push(index[i]);
1659          valueIndexRemoved.push(i);
1660        }
1661      }
1662
1663      if(!iterable) {
1664        // Flip filters normally.
1665
1666        for(i=0; i<added.length; i++) {
1667          filters[offset][added[i]] ^= one;
1668        }
1669
1670        for(i=0; i<removed.length; i++) {
1671          filters[offset][removed[i]] ^= one;
1672        }
1673
1674      } else {
1675        // For iterables, we need to figure out if the row has been completely removed vs partially included
1676        // Only count a row as added if it is not already being aggregated. Only count a row
1677        // as removed if the last element being aggregated is removed.
1678
1679        var newAdded = [];
1680        var newRemoved = [];
1681        for (i = 0; i < added.length; i++) {
1682          iterablesIndexCount[added[i]]++
1683          iterablesIndexFilterStatus[valueIndexAdded[i]] = 0;
1684          if(iterablesIndexCount[added[i]] === 1) {
1685            filters[offset][added[i]] ^= one;
1686            newAdded.push(added[i]);
1687          }
1688        }
1689        for (i = 0; i < removed.length; i++) {
1690          iterablesIndexCount[removed[i]]--
1691          iterablesIndexFilterStatus[valueIndexRemoved[i]] = 1;
1692          if(iterablesIndexCount[removed[i]] === 0) {
1693            filters[offset][removed[i]] ^= one;
1694            newRemoved.push(removed[i]);
1695          }
1696        }
1697
1698        added = newAdded;
1699        removed = newRemoved;
1700
1701        // Now handle empty rows.
1702        if(refilter === xfilterFilter.filterAll) {
1703          for(i = 0; i < iterablesEmptyRows.length; i++) {
1704            if((filters[offset][k = iterablesEmptyRows[i]] & one)) {
1705              // Was not in the filter, so set the filter and add
1706              filters[offset][k] ^= one;
1707              added.push(k);
1708            }
1709          }
1710        } else {
1711          // filter in place - remove empty rows if necessary
1712          for(i = 0; i < iterablesEmptyRows.length; i++) {
1713            if(!(filters[offset][k = iterablesEmptyRows[i]] & one)) {
1714              // Was in the filter, so set the filter and remove
1715              filters[offset][k] ^= one;
1716              removed.push(k);
1717            }
1718          }
1719        }
1720      }
1721
1722      lo0 = lo1;
1723      hi0 = hi1;
1724      filterListeners.forEach(function(l) { l(one, offset, added, removed); });
1725      triggerOnChange('filtered');
1726      return dimension;
1727    }
1728
1729    // Filters this dimension using the specified range, value, or null.
1730    // If the range is null, this is equivalent to filterAll.
1731    // If the range is an array, this is equivalent to filterRange.
1732    // Otherwise, this is equivalent to filterExact.
1733    function filter(range) {
1734      return range == null
1735          ? filterAll() : Array.isArray(range)
1736          ? filterRange(range) : typeof range === "function"
1737          ? filterFunction(range)
1738          : filterExact(range);
1739    }
1740
1741    // Filters this dimension to select the exact value.
1742    function filterExact(value) {
1743      filterValue = value;
1744      filterValuePresent = true;
1745      return filterIndexBounds((refilter = xfilterFilter.filterExact(bisect, value))(values));
1746    }
1747
1748    // Filters this dimension to select the specified range [lo, hi].
1749    // The lower bound is inclusive, and the upper bound is exclusive.
1750    function filterRange(range) {
1751      filterValue = range;
1752      filterValuePresent = true;
1753      return filterIndexBounds((refilter = xfilterFilter.filterRange(bisect, range))(values));
1754    }
1755
1756    // Clears any filters on this dimension.
1757    function filterAll() {
1758      filterValue = undefined;
1759      filterValuePresent = false;
1760      return filterIndexBounds((refilter = xfilterFilter.filterAll)(values));
1761    }
1762
1763    // Filters this dimension using an arbitrary function.
1764    function filterFunction(f) {
1765      filterValue = f;
1766      filterValuePresent = true;
1767      
1768      refilterFunction = f;
1769      refilter = xfilterFilter.filterAll;
1770
1771      filterIndexFunction(f, false);
1772
1773      var bounds = refilter(values);
1774      lo0 = bounds[0], hi0 = bounds[1];
1775
1776      return dimension;
1777    }
1778
1779    function filterIndexFunction(f, filterAll) {
1780      var i,
1781          k,
1782          x,
1783          added = [],
1784          removed = [],
1785          valueIndexAdded = [],
1786          valueIndexRemoved = [],
1787          indexLength = values.length;
1788
1789      if(!iterable) {
1790        for (i = 0; i < indexLength; ++i) {
1791          if (!(filters[offset][k = index[i]] & one) ^ !!(x = f(values[i], i))) {
1792            if (x) added.push(k);
1793            else removed.push(k);
1794          }
1795        }
1796      }
1797
1798      if(iterable) {
1799        for(i=0; i < indexLength; ++i) {
1800          if(f(values[i], i)) {
1801            added.push(index[i]);
1802            valueIndexAdded.push(i);
1803          } else {
1804            removed.push(index[i]);
1805            valueIndexRemoved.push(i);
1806          }
1807        }
1808      }
1809
1810      if(!iterable) {
1811        for(i=0; i<added.length; i++) {
1812          if(filters[offset][added[i]] & one) filters[offset][added[i]] &= zero;
1813        }
1814
1815        for(i=0; i<removed.length; i++) {
1816          if(!(filters[offset][removed[i]] & one)) filters[offset][removed[i]] |= one;
1817        }
1818      } else {
1819
1820        var newAdded = [];
1821        var newRemoved = [];
1822        for (i = 0; i < added.length; i++) {
1823          // First check this particular value needs to be added
1824          if(iterablesIndexFilterStatus[valueIndexAdded[i]] === 1) {
1825            iterablesIndexCount[added[i]]++
1826            iterablesIndexFilterStatus[valueIndexAdded[i]] = 0;
1827            if(iterablesIndexCount[added[i]] === 1) {
1828              filters[offset][added[i]] ^= one;
1829              newAdded.push(added[i]);
1830            }
1831          }
1832        }
1833        for (i = 0; i < removed.length; i++) {
1834          // First check this particular value needs to be removed
1835          if(iterablesIndexFilterStatus[valueIndexRemoved[i]] === 0) {
1836            iterablesIndexCount[removed[i]]--
1837            iterablesIndexFilterStatus[valueIndexRemoved[i]] = 1;
1838            if(iterablesIndexCount[removed[i]] === 0) {
1839              filters[offset][removed[i]] ^= one;
1840              newRemoved.push(removed[i]);
1841            }
1842          }
1843        }
1844
1845        added = newAdded;
1846        removed = newRemoved;
1847
1848        // Now handle empty rows.
1849        if(filterAll) {
1850          for(i = 0; i < iterablesEmptyRows.length; i++) {
1851            if((filters[offset][k = iterablesEmptyRows[i]] & one)) {
1852              // Was not in the filter, so set the filter and add
1853              filters[offset][k] ^= one;
1854              added.push(k);
1855            }
1856          }
1857        } else {
1858          // filter in place - remove empty rows if necessary
1859          for(i = 0; i < iterablesEmptyRows.length; i++) {
1860            if(!(filters[offset][k = iterablesEmptyRows[i]] & one)) {
1861              // Was in the filter, so set the filter and remove
1862              filters[offset][k] ^= one;
1863              removed.push(k);
1864            }
1865          }
1866        }
1867      }
1868
1869      filterListeners.forEach(function(l) { l(one, offset, added, removed); });
1870      triggerOnChange('filtered');
1871    }
1872    
1873    function currentFilter() {
1874      return filterValue;
1875    }
1876    
1877    function hasCurrentFilter() {
1878      return filterValuePresent;
1879    }
1880
1881    // Returns the top K selected records based on this dimension's order.
1882    // Note: observes this dimension's filter, unlike group and groupAll.
1883    function top(k, top_offset) {
1884      var array = [],
1885          i = hi0,
1886          j,
1887          toSkip = 0;
1888
1889      if(top_offset && top_offset > 0) toSkip = top_offset;
1890
1891      while (--i >= lo0 && k > 0) {
1892        if (filters.zero(j = index[i])) {
1893          if(toSkip > 0) {
1894            //skip matching row
1895            --toSkip;
1896          } else {
1897            array.push(data[j]);
1898            --k;
1899          }
1900        }
1901      }
1902
1903      if(iterable){
1904        for(i = 0; i < iterablesEmptyRows.length && k > 0; i++) {
1905          // Add row with empty iterable column at the end
1906          if(filters.zero(j = iterablesEmptyRows[i])) {
1907            if(toSkip > 0) {
1908              //skip matching row
1909              --toSkip;
1910            } else {
1911              array.push(data[j]);
1912              --k;
1913            }
1914          }
1915        }
1916      }
1917
1918      return array;
1919    }
1920
1921    // Returns the bottom K selected records based on this dimension's order.
1922    // Note: observes this dimension's filter, unlike group and groupAll.
1923    function bottom(k, bottom_offset) {
1924      var array = [],
1925          i,
1926          j,
1927          toSkip = 0;
1928
1929      if(bottom_offset && bottom_offset > 0) toSkip = bottom_offset;
1930
1931      if(iterable) {
1932        // Add row with empty iterable column at the top
1933        for(i = 0; i < iterablesEmptyRows.length && k > 0; i++) {
1934          if(filters.zero(j = iterablesEmptyRows[i])) {
1935            if(toSkip > 0) {
1936              //skip matching row
1937              --toSkip;
1938            } else {
1939              array.push(data[j]);
1940              --k;
1941            }
1942          }
1943        }
1944      }
1945
1946      i = lo0;
1947
1948      while (i < hi0 && k > 0) {
1949        if (filters.zero(j = index[i])) {
1950          if(toSkip > 0) {
1951            //skip matching row
1952            --toSkip;
1953          } else {
1954            array.push(data[j]);
1955            --k;
1956          }
1957        }
1958        i++;
1959      }
1960
1961      return array;
1962    }
1963
1964    // Adds a new group to this dimension, using the specified key function.
1965    function group(key) {
1966      var group = {
1967        top: top,
1968        all: all,
1969        reduce: reduce,
1970        reduceCount: reduceCount,
1971        reduceSum: reduceSum,
1972        order: order,
1973        orderNatural: orderNatural,
1974        size: size,
1975        dispose: dispose,
1976        remove: dispose // for backwards-compatibility
1977      };
1978
1979      // Ensure that this group will be removed when the dimension is removed.
1980      dimensionGroups.push(group);
1981
1982      var groups, // array of {key, value}
1983          groupIndex, // object id ↦ group id
1984          groupWidth = 8,
1985          groupCapacity = crossfilter_capacity(groupWidth),
1986          k = 0, // cardinality
1987          select,
1988          heap,
1989          reduceAdd,
1990          reduceRemove,
1991          reduceInitial,
1992          update = crossfilter_null,
1993          reset = crossfilter_null,
1994          resetNeeded = true,
1995          groupAll = key === crossfilter_null,
1996          n0old;
1997
1998      if (arguments.length < 1) key = crossfilter_identity;
1999
2000      // The group listens to the crossfilter for when any dimension changes, so
2001      // that it can update the associated reduce values. It must also listen to
2002      // the parent dimension for when data is added, and compute new keys.
2003      filterListeners.push(update);
2004      indexListeners.push(add);
2005      removeDataListeners.push(removeData);
2006
2007      // Incorporate any existing data into the grouping.
2008      add(values, index, 0, n);
2009
2010      // Incorporates the specified new values into this group.
2011      // This function is responsible for updating groups and groupIndex.
2012      function add(newValues, newIndex, n0, n1) {
2013
2014        if(iterable) {
2015          n0old = n0
2016          n0 = values.length - newValues.length
2017          n1 = newValues.length;
2018        }
2019
2020        var oldGroups = groups,
2021            reIndex = iterable ? [] : crossfilter_index(k, groupCapacity),
2022            add = reduceAdd,
2023            remove = reduceRemove,
2024            initial = reduceInitial,
2025            k0 = k, // old cardinality
2026            i0 = 0, // index of old group
2027            i1 = 0, // index of new record
2028            j, // object id
2029            g0, // old group
2030            x0, // old key
2031            x1, // new key
2032            g, // group to add
2033            x; // key of group to add
2034
2035        // If a reset is needed, we don't need to update the reduce values.
2036        if (resetNeeded) add = initial = crossfilter_null;
2037        if (resetNeeded) remove = initial = crossfilter_null;
2038
2039        // Reset the new groups (k is a lower bound).
2040        // Also, make sure that groupIndex exists and is long enough.
2041        groups = new Array(k), k = 0;
2042        if(iterable){
2043          groupIndex = k0 ? groupIndex : [];
2044        }
2045        else{
2046          groupIndex = k0 > 1 ? xfilterArray.arrayLengthen(groupIndex, n) : crossfilter_index(n, groupCapacity);
2047        }
2048
2049
2050        // Get the first old key (x0 of g0), if it exists.
2051        if (k0) x0 = (g0 = oldGroups[0]).key;
2052
2053        // Find the first new key (x1), skipping NaN keys.
2054        while (i1 < n1 && !((x1 = key(newValues[i1])) >= x1)) ++i1;
2055
2056        // While new keys remain…
2057        while (i1 < n1) {
2058
2059          // Determine the lesser of the two current keys; new and old.
2060          // If there are no old keys remaining, then always add the new key.
2061          if (g0 && x0 <= x1) {
2062            g = g0, x = x0;
2063
2064            // Record the new index of the old group.
2065            reIndex[i0] = k;
2066
2067            // Retrieve the next old key.
2068            g0 = oldGroups[++i0];
2069            if (g0) x0 = g0.key;
2070          } else {
2071            g = {key: x1, value: initial()}, x = x1;
2072          }
2073
2074          // Add the lesser group.
2075          groups[k] = g;
2076
2077          // Add any selected records belonging to the added group, while
2078          // advancing the new key and populating the associated group index.
2079
2080          while (x1 <= x) {
2081            j = newIndex[i1] + (iterable ? n0old : n0)
2082
2083
2084            if(iterable){
2085              if(groupIndex[j]){
2086                groupIndex[j].push(k)
2087              }
2088              else{
2089                groupIndex[j] = [k]
2090              }
2091            }
2092            else{
2093              groupIndex[j] = k;
2094            }
2095
2096            // Always add new values to groups. Only remove when not in filter.
2097            // This gives groups full information on data life-cycle.
2098            g.value = add(g.value, data[j], true);
2099            if (!filters.zeroExcept(j, offset, zero)) g.value = remove(g.value, data[j], false);
2100            if (++i1 >= n1) break;
2101            x1 = key(newValues[i1]);
2102          }
2103
2104          groupIncrement();
2105        }
2106
2107        // Add any remaining old groups that were greater th1an all new keys.
2108        // No incremental reduce is needed; these groups have no new records.
2109        // Also record the new index of the old group.
2110        while (i0 < k0) {
2111          groups[reIndex[i0] = k] = oldGroups[i0++];
2112          groupIncrement();
2113        }
2114
2115
2116        // Fill in gaps with empty arrays where there may have been rows with empty iterables
2117        if(iterable){
2118          for (var index1 = 0; index1 < n; index1++) {
2119            if(!groupIndex[index1]){
2120              groupIndex[index1] = [];
2121            }
2122          }
2123        }
2124
2125        // If we added any new groups before any old groups,
2126        // update the group index of all the old records.
2127        if(k > i0){
2128          if(iterable){
2129            for (i0 = 0; i0 < n0old; ++i0) {
2130              for (index1 = 0; index1 < groupIndex[i0].length; index1++) {
2131                groupIndex[i0][index1] = reIndex[groupIndex[i0][index1]];
2132              }
2133            }
2134          }
2135          else{
2136            for (i0 = 0; i0 < n0; ++i0) {
2137              groupIndex[i0] = reIndex[groupIndex[i0]];
2138            }
2139          }
2140        }
2141
2142        // Modify the update and reset behavior based on the cardinality.
2143        // If the cardinality is less than or equal to one, then the groupIndex
2144        // is not needed. If the cardinality is zero, then there are no records
2145        // and therefore no groups to update or reset. Note that we also must
2146        // change the registered listener to point to the new method.
2147        j = filterListeners.indexOf(update);
2148        if (k > 1 || iterable) {
2149          update = updateMany;
2150          reset = resetMany;
2151        } else {
2152          if (!k && groupAll) {
2153            k = 1;
2154            groups = [{key: null, value: initial()}];
2155          }
2156          if (k === 1) {
2157            update = updateOne;
2158            reset = resetOne;
2159          } else {
2160            update = crossfilter_null;
2161            reset = crossfilter_null;
2162          }
2163          groupIndex = null;
2164        }
2165        filterListeners[j] = update;
2166
2167        // Count the number of added groups,
2168        // and widen the group index as needed.
2169        function groupIncrement() {
2170          if(iterable){
2171            k++
2172            return
2173          }
2174          if (++k === groupCapacity) {
2175            reIndex = xfilterArray.arrayWiden(reIndex, groupWidth <<= 1);
2176            groupIndex = xfilterArray.arrayWiden(groupIndex, groupWidth);
2177            groupCapacity = crossfilter_capacity(groupWidth);
2178          }
2179        }
2180      }
2181
2182      function removeData(reIndex) {
2183        if (k > 1 || iterable) {
2184          var oldK = k,
2185              oldGroups = groups,
2186              seenGroups = crossfilter_index(oldK, oldK),
2187              i,
2188              i0,
2189              j;
2190
2191          // Filter out non-matches by copying matching group index entries to
2192          // the beginning of the array.
2193          if (!iterable) {
2194            for (i = 0, j = 0; i < n; ++i) {
2195              if (reIndex[i] !== REMOVED_INDEX) {
2196                seenGroups[groupIndex[j] = groupIndex[i]] = 1;
2197                ++j;
2198              }
2199            }
2200          } else {
2201            for (i = 0, j = 0; i < n; ++i) {
2202              if (reIndex[i] !== REMOVED_INDEX) {
2203                groupIndex[j] = groupIndex[i];
2204                for (i0 = 0; i0 < groupIndex[j].length; i0++) {
2205                  seenGroups[groupIndex[j][i0]] = 1;
2206                }
2207                ++j;
2208              }
2209            }
2210          }
2211
2212          // Reassemble groups including only those groups that were referred
2213          // to by matching group index entries.  Note the new group index in
2214          // seenGroups.
2215          groups = [], k = 0;
2216          for (i = 0; i < oldK; ++i) {
2217            if (seenGroups[i]) {
2218              seenGroups[i] = k++;
2219              groups.push(oldGroups[i]);
2220            }
2221          }
2222
2223          if (k > 1 || iterable) {
2224            // Reindex the group index using seenGroups to find the new index.
2225            if (!iterable) {
2226              for (i = 0; i < j; ++i) groupIndex[i] = seenGroups[groupIndex[i]];
2227            } else {
2228              for (i = 0; i < j; ++i) {
2229                for (i0 = 0; i0 < groupIndex[i].length; ++i0) {
2230                  groupIndex[i][i0] = seenGroups[groupIndex[i][i0]];
2231                }
2232              }
2233            }
2234          } else {
2235            groupIndex = null;
2236          }
2237          filterListeners[filterListeners.indexOf(update)] = k > 1 || iterable
2238              ? (reset = resetMany, update = updateMany)
2239              : k === 1 ? (reset = resetOne, update = updateOne)
2240              : reset = update = crossfilter_null;
2241        } else if (k === 1) {
2242          if (groupAll) return;
2243          for (var index3 = 0; index3 < n; ++index3) if (reIndex[index3] !== REMOVED_INDEX) return;
2244          groups = [], k = 0;
2245          filterListeners[filterListeners.indexOf(update)] =
2246          update = reset = crossfilter_null;
2247        }
2248      }
2249
2250      // Reduces the specified selected or deselected records.
2251      // This function is only used when the cardinality is greater than 1.
2252      // notFilter indicates a crossfilter.add/remove operation.
2253      function updateMany(filterOne, filterOffset, added, removed, notFilter) {
2254
2255        if ((filterOne === one && filterOffset === offset) || resetNeeded) return;
2256
2257        var i,
2258            j,
2259            k,
2260            n,
2261            g;
2262
2263        if(iterable){
2264          // Add the added values.
2265          for (i = 0, n = added.length; i < n; ++i) {
2266            if (filters.zeroExcept(k = added[i], offset, zero)) {
2267              for (j = 0; j < groupIndex[k].length; j++) {
2268                g = groups[groupIndex[k][j]];
2269                g.value = reduceAdd(g.value, data[k], false, j);
2270              }
2271            }
2272          }
2273
2274          // Remove the removed values.
2275          for (i = 0, n = removed.length; i < n; ++i) {
2276            if (filters.onlyExcept(k = removed[i], offset, zero, filterOffset, filterOne)) {
2277              for (j = 0; j < groupIndex[k].length; j++) {
2278                g = groups[groupIndex[k][j]];
2279                g.value = reduceRemove(g.value, data[k], notFilter, j);
2280              }
2281            }
2282          }
2283          return;
2284        }
2285
2286        // Add the added values.
2287        for (i = 0, n = added.length; i < n; ++i) {
2288          if (filters.zeroExcept(k = added[i], offset, zero)) {
2289            g = groups[groupIndex[k]];
2290            g.value = reduceAdd(g.value, data[k], false);
2291          }
2292        }
2293
2294        // Remove the removed values.
2295        for (i = 0, n = removed.length; i < n; ++i) {
2296          if (filters.onlyExcept(k = removed[i], offset, zero, filterOffset, filterOne)) {
2297            g = groups[groupIndex[k]];
2298            g.value = reduceRemove(g.value, data[k], notFilter);
2299          }
2300        }
2301      }
2302
2303      // Reduces the specified selected or deselected records.
2304      // This function is only used when the cardinality is 1.
2305      // notFilter indicates a crossfilter.add/remove operation.
2306      function updateOne(filterOne, filterOffset, added, removed, notFilter) {
2307        if ((filterOne === one && filterOffset === offset) || resetNeeded) return;
2308
2309        var i,
2310            k,
2311            n,
2312            g = groups[0];
2313
2314        // Add the added values.
2315        for (i = 0, n = added.length; i < n; ++i) {
2316          if (filters.zeroExcept(k = added[i], offset, zero)) {
2317            g.value = reduceAdd(g.value, data[k], false);
2318          }
2319        }
2320
2321        // Remove the removed values.
2322        for (i = 0, n = removed.length; i < n; ++i) {
2323          if (filters.onlyExcept(k = removed[i], offset, zero, filterOffset, filterOne)) {
2324            g.value = reduceRemove(g.value, data[k], notFilter);
2325          }
2326        }
2327      }
2328
2329      // Recomputes the group reduce values from scratch.
2330      // This function is only used when the cardinality is greater than 1.
2331      function resetMany() {
2332        var i,
2333            j,
2334            g;
2335
2336        // Reset all group values.
2337        for (i = 0; i < k; ++i) {
2338          groups[i].value = reduceInitial();
2339        }
2340
2341        // We add all records and then remove filtered records so that reducers
2342        // can build an 'unfiltered' view even if there are already filters in
2343        // place on other dimensions.
2344        if(iterable){
2345          for (i = 0; i < n; ++i) {
2346            for (j = 0; j < groupIndex[i].length; j++) {
2347              g = groups[groupIndex[i][j]];
2348              g.value = reduceAdd(g.value, data[i], true, j);
2349            }
2350          }
2351          for (i = 0; i < n; ++i) {
2352            if (!filters.zeroExcept(i, offset, zero)) {
2353              for (j = 0; j < groupIndex[i].length; j++) {
2354                g = groups[groupIndex[i][j]];
2355                g.value = reduceRemove(g.value, data[i], false, j);
2356              }
2357            }
2358          }
2359          return;
2360        }
2361
2362        for (i = 0; i < n; ++i) {
2363          g = groups[groupIndex[i]];
2364          g.value = reduceAdd(g.value, data[i], true);
2365        }
2366        for (i = 0; i < n; ++i) {
2367          if (!filters.zeroExcept(i, offset, zero)) {
2368            g = groups[groupIndex[i]];
2369            g.value = reduceRemove(g.value, data[i], false);
2370          }
2371        }
2372      }
2373
2374      // Recomputes the group reduce values from scratch.
2375      // This function is only used when the cardinality is 1.
2376      function resetOne() {
2377        var i,
2378            g = groups[0];
2379
2380        // Reset the singleton group values.
2381        g.value = reduceInitial();
2382
2383        // We add all records and then remove filtered records so that reducers
2384        // can build an 'unfiltered' view even if there are already filters in
2385        // place on other dimensions.
2386        for (i = 0; i < n; ++i) {
2387          g.value = reduceAdd(g.value, data[i], true);
2388        }
2389
2390        for (i = 0; i < n; ++i) {
2391          if (!filters.zeroExcept(i, offset, zero)) {
2392            g.value = reduceRemove(g.value, data[i], false);
2393          }
2394        }
2395      }
2396
2397      // Returns the array of group values, in the dimension's natural order.
2398      function all() {
2399        if (resetNeeded) reset(), resetNeeded = false;
2400        return groups;
2401      }
2402
2403      // Returns a new array containing the top K group values, in reduce order.
2404      function top(k) {
2405        var top = select(all(), 0, groups.length, k);
2406        return heap.sort(top, 0, top.length);
2407      }
2408
2409      // Sets the reduce behavior for this group to use the specified functions.
2410      // This method lazily recomputes the reduce values, waiting until needed.
2411      function reduce(add, remove, initial) {
2412        reduceAdd = add;
2413        reduceRemove = remove;
2414        reduceInitial = initial;
2415        resetNeeded = true;
2416        return group;
2417      }
2418
2419      // A convenience method for reducing by count.
2420      function reduceCount() {
2421        return reduce(xfilterReduce.reduceIncrement, xfilterReduce.reduceDecrement, crossfilter_zero);
2422      }
2423
2424      // A convenience method for reducing by sum(value).
2425      function reduceSum(value) {
2426        return reduce(xfilterReduce.reduceAdd(value), xfilterReduce.reduceSubtract(value), crossfilter_zero);
2427      }
2428
2429      // Sets the reduce order, using the specified accessor.
2430      function order(value) {
2431        select = xfilterHeapselect.by(valueOf);
2432        heap = xfilterHeap.by(valueOf);
2433        function valueOf(d) { return value(d.value); }
2434        return group;
2435      }
2436
2437      // A convenience method for natural ordering by reduce value.
2438      function orderNatural() {
2439        return order(crossfilter_identity);
2440      }
2441
2442      // Returns the cardinality of this group, irrespective of any filters.
2443      function size() {
2444        return k;
2445      }
2446
2447      // Removes this group and associated event listeners.
2448      function dispose() {
2449        var i = filterListeners.indexOf(update);
2450        if (i >= 0) filterListeners.splice(i, 1);
2451        i = indexListeners.indexOf(add);
2452        if (i >= 0) indexListeners.splice(i, 1);
2453        i = removeDataListeners.indexOf(removeData);
2454        if (i >= 0) removeDataListeners.splice(i, 1);
2455        i = dimensionGroups.indexOf(group);
2456        if (i >= 0) dimensionGroups.splice(i, 1);
2457        return group;
2458      }
2459
2460      return reduceCount().orderNatural();
2461    }
2462
2463    // A convenience function for generating a singleton group.
2464    function groupAll() {
2465      var g = group(crossfilter_null), all = g.all;
2466      delete g.all;
2467      delete g.top;
2468      delete g.order;
2469      delete g.orderNatural;
2470      delete g.size;
2471      g.value = function() { return all()[0].value; };
2472      return g;
2473    }
2474
2475    // Removes this dimension and associated groups and event listeners.
2476    function dispose() {
2477      dimensionGroups.forEach(function(group) { group.dispose(); });
2478      var i = dataListeners.indexOf(preAdd);
2479      if (i >= 0) dataListeners.splice(i, 1);
2480      i = dataListeners.indexOf(postAdd);
2481      if (i >= 0) dataListeners.splice(i, 1);
2482      i = removeDataListeners.indexOf(removeData);
2483      if (i >= 0) removeDataListeners.splice(i, 1);
2484      filters.masks[offset] &= zero;
2485      return filterAll();
2486    }
2487
2488    return dimension;
2489  }
2490
2491  // A convenience method for groupAll on a dummy dimension.
2492  // This implementation can be optimized since it always has cardinality 1.
2493  function groupAll() {
2494    var group = {
2495      reduce: reduce,
2496      reduceCount: reduceCount,
2497      reduceSum: reduceSum,
2498      value: value,
2499      dispose: dispose,
2500      remove: dispose // for backwards-compatibility
2501    };
2502
2503    var reduceValue,
2504        reduceAdd,
2505        reduceRemove,
2506        reduceInitial,
2507        resetNeeded = true;
2508
2509    // The group listens to the crossfilter for when any dimension changes, so
2510    // that it can update the reduce value. It must also listen to the parent
2511    // dimension for when data is added.
2512    filterListeners.push(update);
2513    dataListeners.push(add);
2514
2515    // For consistency; actually a no-op since resetNeeded is true.
2516    add(data, 0, n);
2517
2518    // Incorporates the specified new values into this group.
2519    function add(newData, n0) {
2520      var i;
2521
2522      if (resetNeeded) return;
2523
2524      // Cycle through all the values.
2525      for (i = n0; i < n; ++i) {
2526
2527        // Add all values all the time.
2528        reduceValue = reduceAdd(reduceValue, data[i], true);
2529
2530        // Remove the value if filtered.
2531        if (!filters.zero(i)) {
2532          reduceValue = reduceRemove(reduceValue, data[i], false);
2533        }
2534      }
2535    }
2536
2537    // Reduces the specified selected or deselected records.
2538    function update(filterOne, filterOffset, added, removed, notFilter) {
2539      var i,
2540          k,
2541          n;
2542
2543      if (resetNeeded) return;
2544
2545      // Add the added values.
2546      for (i = 0, n = added.length; i < n; ++i) {
2547        if (filters.zero(k = added[i])) {
2548          reduceValue = reduceAdd(reduceValue, data[k], notFilter);
2549        }
2550      }
2551
2552      // Remove the removed values.
2553      for (i = 0, n = removed.length; i < n; ++i) {
2554        if (filters.only(k = removed[i], filterOffset, filterOne)) {
2555          reduceValue = reduceRemove(reduceValue, data[k], notFilter);
2556        }
2557      }
2558    }
2559
2560    // Recomputes the group reduce value from scratch.
2561    function reset() {
2562      var i;
2563
2564      reduceValue = reduceInitial();
2565
2566      // Cycle through all the values.
2567      for (i = 0; i < n; ++i) {
2568
2569        // Add all values all the time.
2570        reduceValue = reduceAdd(reduceValue, data[i], true);
2571
2572        // Remove the value if it is filtered.
2573        if (!filters.zero(i)) {
2574          reduceValue = reduceRemove(reduceValue, data[i], false);
2575        }
2576      }
2577    }
2578
2579    // Sets the reduce behavior for this group to use the specified functions.
2580    // This method lazily recomputes the reduce value, waiting until needed.
2581    function reduce(add, remove, initial) {
2582      reduceAdd = add;
2583      reduceRemove = remove;
2584      reduceInitial = initial;
2585      resetNeeded = true;
2586      return group;
2587    }
2588
2589    // A convenience method for reducing by count.
2590    function reduceCount() {
2591      return reduce(xfilterReduce.reduceIncrement, xfilterReduce.reduceDecrement, crossfilter_zero);
2592    }
2593
2594    // A convenience method for reducing by sum(value).
2595    function reduceSum(value) {
2596      return reduce(xfilterReduce.reduceAdd(value), xfilterReduce.reduceSubtract(value), crossfilter_zero);
2597    }
2598
2599    // Returns the computed reduce value.
2600    function value() {
2601      if (resetNeeded) reset(), resetNeeded = false;
2602      return reduceValue;
2603    }
2604
2605    // Removes this group and associated event listeners.
2606    function dispose() {
2607      var i = filterListeners.indexOf(update);
2608      if (i >= 0) filterListeners.splice(i, 1);
2609      i = dataListeners.indexOf(add);
2610      if (i >= 0) dataListeners.splice(i, 1);
2611      return group;
2612    }
2613
2614    return reduceCount();
2615  }
2616
2617  // Returns the number of records in this crossfilter, irrespective of any filters.
2618  function size() {
2619    return n;
2620  }
2621
2622  // Returns the raw row data contained in this crossfilter
2623  function all(){
2624    return data;
2625  }
2626
2627  // Returns row data with all dimension filters applied, except for filters in ignore_dimensions
2628  function allFiltered(ignore_dimensions) {
2629    var array = [],
2630        i = 0,
2631        mask = maskForDimensions(ignore_dimensions || []);
2632
2633      for (i = 0; i < n; i++) {
2634        if (filters.zeroExceptMask(i, mask)) {
2635          array.push(data[i]);
2636        }
2637      }
2638
2639      return array;
2640  }
2641
2642  function onChange(cb){
2643    if(typeof cb !== 'function'){
2644      /* eslint no-console: 0 */
2645      console.warn('onChange callback parameter must be a function!');
2646      return;
2647    }
2648    callbacks.push(cb);
2649    return function(){
2650      callbacks.splice(callbacks.indexOf(cb), 1);
2651    };
2652  }
2653
2654  function triggerOnChange(eventName){
2655    for (var i = 0; i < callbacks.length; i++) {
2656      callbacks[i](eventName);
2657    }
2658  }
2659
2660  return arguments.length
2661      ? add(arguments[0])
2662      : crossfilter;
2663}
2664
2665// Returns an array of size n, big enough to store ids up to m.
2666function crossfilter_index(n, m) {
2667  return (m < 0x101
2668      ? xfilterArray.array8 : m < 0x10001
2669      ? xfilterArray.array16
2670      : xfilterArray.array32)(n);
2671}
2672
2673// Constructs a new array of size n, with sequential values from 0 to n - 1.
2674function crossfilter_range(n) {
2675  var range = crossfilter_index(n, n);
2676  for (var i = -1; ++i < n;) range[i] = i;
2677  return range;
2678}
2679
2680function crossfilter_capacity(w) {
2681  return w === 8
2682      ? 0x100 : w === 16
2683      ? 0x10000
2684      : 0x100000000;
2685}
2686
2687},{"./../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){
2688'use strict';
2689
2690function crossfilter_filterExact(bisect, value) {
2691  return function(values) {
2692    var n = values.length;
2693    return [bisect.left(values, value, 0, n), bisect.right(values, value, 0, n)];
2694  };
2695}
2696
2697function crossfilter_filterRange(bisect, range) {
2698  var min = range[0],
2699      max = range[1];
2700  return function(values) {
2701    var n = values.length;
2702    return [bisect.left(values, min, 0, n), bisect.left(values, max, 0, n)];
2703  };
2704}
2705
2706function crossfilter_filterAll(values) {
2707  return [0, values.length];
2708}
2709
2710module.exports = {
2711  filterExact: crossfilter_filterExact,
2712  filterRange: crossfilter_filterRange,
2713  filterAll: crossfilter_filterAll
2714};
2715
2716},{}],8:[function(require,module,exports){
2717'use strict';
2718
2719var crossfilter_identity = require('./identity');
2720
2721function heap_by(f) {
2722
2723  // Builds a binary heap within the specified array a[lo:hi]. The heap has the
2724  // property such that the parent a[lo+i] is always less than or equal to its
2725  // two children: a[lo+2*i+1] and a[lo+2*i+2].
2726  function heap(a, lo, hi) {
2727    var n = hi - lo,
2728        i = (n >>> 1) + 1;
2729    while (--i > 0) sift(a, i, n, lo);
2730    return a;
2731  }
2732
2733  // Sorts the specified array a[lo:hi] in descending order, assuming it is
2734  // already a heap.
2735  function sort(a, lo, hi) {
2736    var n = hi - lo,
2737        t;
2738    while (--n > 0) t = a[lo], a[lo] = a[lo + n], a[lo + n] = t, sift(a, 1, n, lo);
2739    return a;
2740  }
2741
2742  // Sifts the element a[lo+i-1] down the heap, where the heap is the contiguous
2743  // slice of array a[lo:lo+n]. This method can also be used to update the heap
2744  // incrementally, without incurring the full cost of reconstructing the heap.
2745  function sift(a, i, n, lo) {
2746    var d = a[--lo + i],
2747        x = f(d),
2748        child;
2749    while ((child = i << 1) <= n) {
2750      if (child < n && f(a[lo + child]) > f(a[lo + child + 1])) child++;
2751      if (x <= f(a[lo + child])) break;
2752      a[lo + i] = a[lo + child];
2753      i = child;
2754    }
2755    a[lo + i] = d;
2756  }
2757
2758  heap.sort = sort;
2759  return heap;
2760}
2761
2762module.exports = heap_by(crossfilter_identity);
2763module.exports.by = heap_by;
2764
2765},{"./identity":10}],9:[function(require,module,exports){
2766'use strict';
2767
2768var crossfilter_identity = require('./identity');
2769var xFilterHeap = require('./heap');
2770
2771function heapselect_by(f) {
2772  var heap = xFilterHeap.by(f);
2773
2774  // Returns a new array containing the top k elements in the array a[lo:hi].
2775  // The returned array is not sorted, but maintains the heap property. If k is
2776  // greater than hi - lo, then fewer than k elements will be returned. The
2777  // order of elements in a is unchanged by this operation.
2778  function heapselect(a, lo, hi, k) {
2779    var queue = new Array(k = Math.min(hi - lo, k)),
2780        min,
2781        i,
2782        d;
2783
2784    for (i = 0; i < k; ++i) queue[i] = a[lo++];
2785    heap(queue, 0, k);
2786
2787    if (lo < hi) {
2788      min = f(queue[0]);
2789      do {
2790        if (f(d = a[lo]) > min) {
2791          queue[0] = d;
2792          min = f(heap(queue, 0, k)[0]);
2793        }
2794      } while (++lo < hi);
2795    }
2796
2797    return queue;
2798  }
2799
2800  return heapselect;
2801}
2802
2803module.exports = heapselect_by(crossfilter_identity);
2804module.exports.by = heapselect_by; // assign the raw function to the export as well
2805
2806},{"./heap":8,"./identity":10}],10:[function(require,module,exports){
2807'use strict';
2808
2809function crossfilter_identity(d) {
2810  return d;
2811}
2812
2813module.exports = crossfilter_identity;
2814
2815},{}],11:[function(require,module,exports){
2816'use strict';
2817
2818var crossfilter_identity = require('./identity');
2819
2820function insertionsort_by(f) {
2821
2822  function insertionsort(a, lo, hi) {
2823    for (var i = lo + 1; i < hi; ++i) {
2824      for (var j = i, t = a[i], x = f(t); j > lo && f(a[j - 1]) > x; --j) {
2825        a[j] = a[j - 1];
2826      }
2827      a[j] = t;
2828    }
2829    return a;
2830  }
2831
2832  return insertionsort;
2833}
2834
2835module.exports = insertionsort_by(crossfilter_identity);
2836module.exports.by = insertionsort_by;
2837
2838},{"./identity":10}],12:[function(require,module,exports){
2839'use strict';
2840
2841function crossfilter_null() {
2842  return null;
2843}
2844
2845module.exports = crossfilter_null;
2846
2847},{}],13:[function(require,module,exports){
2848'use strict';
2849
2850function permute(array, index, deep) {
2851  for (var i = 0, n = index.length, copy = deep ? JSON.parse(JSON.stringify(array)) : new Array(n); i < n; ++i) {
2852    copy[i] = array[index[i]];
2853  }
2854  return copy;
2855}
2856
2857module.exports = permute;
2858
2859},{}],14:[function(require,module,exports){
2860var crossfilter_identity = require('./identity');
2861var xFilterInsertionsort = require('./insertionsort');
2862
2863// Algorithm designed by Vladimir Yaroslavskiy.
2864// Implementation based on the Dart project; see NOTICE and AUTHORS for details.
2865
2866function quicksort_by(f) {
2867  var insertionsort = xFilterInsertionsort.by(f);
2868
2869  function sort(a, lo, hi) {
2870    return (hi - lo < quicksort_sizeThreshold
2871        ? insertionsort
2872        : quicksort)(a, lo, hi);
2873  }
2874
2875  function quicksort(a, lo, hi) {
2876    // Compute the two pivots by looking at 5 elements.
2877    var sixth = (hi - lo) / 6 | 0,
2878        i1 = lo + sixth,
2879        i5 = hi - 1 - sixth,
2880        i3 = lo + hi - 1 >> 1,  // The midpoint.
2881        i2 = i3 - sixth,
2882        i4 = i3 + sixth;
2883
2884    var e1 = a[i1], x1 = f(e1),
2885        e2 = a[i2], x2 = f(e2),
2886        e3 = a[i3], x3 = f(e3),
2887        e4 = a[i4], x4 = f(e4),
2888        e5 = a[i5], x5 = f(e5);
2889
2890    var t;
2891
2892    // Sort the selected 5 elements using a sorting network.
2893    if (x1 > x2) t = e1, e1 = e2, e2 = t, t = x1, x1 = x2, x2 = t;
2894    if (x4 > x5) t = e4, e4 = e5, e5 = t, t = x4, x4 = x5, x5 = t;
2895    if (x1 > x3) t = e1, e1 = e3, e3 = t, t = x1, x1 = x3, x3 = t;
2896    if (x2 > x3) t = e2, e2 = e3, e3 = t, t = x2, x2 = x3, x3 = t;
2897    if (x1 > x4) t = e1, e1 = e4, e4 = t, t = x1, x1 = x4, x4 = t;
2898    if (x3 > x4) t = e3, e3 = e4, e4 = t, t = x3, x3 = x4, x4 = t;
2899    if (x2 > x5) t = e2, e2 = e5, e5 = t, t = x2, x2 = x5, x5 = t;
2900    if (x2 > x3) t = e2, e2 = e3, e3 = t, t = x2, x2 = x3, x3 = t;
2901    if (x4 > x5) t = e4, e4 = e5, e5 = t, t = x4, x4 = x5, x5 = t;
2902
2903    var pivot1 = e2, pivotValue1 = x2,
2904        pivot2 = e4, pivotValue2 = x4;
2905
2906    // e2 and e4 have been saved in the pivot variables. They will be written
2907    // back, once the partitioning is finished.
2908    a[i1] = e1;
2909    a[i2] = a[lo];
2910    a[i3] = e3;
2911    a[i4] = a[hi - 1];
2912    a[i5] = e5;
2913
2914    var less = lo + 1,   // First element in the middle partition.
2915        great = hi - 2;  // Last element in the middle partition.
2916
2917    // Note that for value comparison, <, <=, >= and > coerce to a primitive via
2918    // Object.prototype.valueOf; == and === do not, so in order to be consistent
2919    // with natural order (such as for Date objects), we must do two compares.
2920    var pivotsEqual = pivotValue1 <= pivotValue2 && pivotValue1 >= pivotValue2;
2921    if (pivotsEqual) {
2922
2923      // Degenerated case where the partitioning becomes a dutch national flag
2924      // problem.
2925      //
2926      // [ |  < pivot  | == pivot | unpartitioned | > pivot  | ]
2927      //  ^             ^          ^             ^            ^
2928      // left         less         k           great         right
2929      //
2930      // a[left] and a[right] are undefined and are filled after the
2931      // partitioning.
2932      //
2933      // Invariants:
2934      //   1) for x in ]left, less[ : x < pivot.
2935      //   2) for x in [less, k[ : x == pivot.
2936      //   3) for x in ]great, right[ : x > pivot.
2937      for (var k = less; k <= great; ++k) {
2938        var ek = a[k], xk = f(ek);
2939        if (xk < pivotValue1) {
2940          if (k !== less) {
2941            a[k] = a[less];
2942            a[less] = ek;
2943          }
2944          ++less;
2945        } else if (xk > pivotValue1) {
2946
2947          // Find the first element <= pivot in the range [k - 1, great] and
2948          // put [:ek:] there. We know that such an element must exist:
2949          // When k == less, then el3 (which is equal to pivot) lies in the
2950          // interval. Otherwise a[k - 1] == pivot and the search stops at k-1.
2951          // Note that in the latter case invariant 2 will be violated for a
2952          // short amount of time. The invariant will be restored when the
2953          // pivots are put into their final positions.
2954          /* eslint no-constant-condition: 0 */
2955          while (true) {
2956            var greatValue = f(a[great]);
2957            if (greatValue > pivotValue1) {
2958              great--;
2959              // This is the only location in the while-loop where a new
2960              // iteration is started.
2961              continue;
2962            } else if (greatValue < pivotValue1) {
2963              // Triple exchange.
2964              a[k] = a[less];
2965              a[less++] = a[great];
2966              a[great--] = ek;
2967              break;
2968            } else {
2969              a[k] = a[great];
2970              a[great--] = ek;
2971              // Note: if great < k then we will exit the outer loop and fix
2972              // invariant 2 (which we just violated).
2973              break;
2974            }
2975          }
2976        }
2977      }
2978    } else {
2979
2980      // We partition the list into three parts:
2981      //  1. < pivot1
2982      //  2. >= pivot1 && <= pivot2
2983      //  3. > pivot2
2984      //
2985      // During the loop we have:
2986      // [ | < pivot1 | >= pivot1 && <= pivot2 | unpartitioned  | > pivot2  | ]
2987      //  ^            ^                        ^              ^             ^
2988      // left         less                     k              great        right
2989      //
2990      // a[left] and a[right] are undefined and are filled after the
2991      // partitioning.
2992      //
2993      // Invariants:
2994      //   1. for x in ]left, less[ : x < pivot1
2995      //   2. for x in [less, k[ : pivot1 <= x && x <= pivot2
2996      //   3. for x in ]great, right[ : x > pivot2
2997      (function () { // isolate scope
2998      for (var k = less; k <= great; k++) {
2999        var ek = a[k], xk = f(ek);
3000        if (xk < pivotValue1) {
3001          if (k !== less) {
3002            a[k] = a[less];
3003            a[less] = ek;
3004          }
3005          ++less;
3006        } else {
3007          if (xk > pivotValue2) {
3008            while (true) {
3009              var greatValue = f(a[great]);
3010              if (greatValue > pivotValue2) {
3011                great--;
3012                if (great < k) break;
3013                // This is the only location inside the loop where a new
3014                // iteration is started.
3015                continue;
3016              } else {
3017                // a[great] <= pivot2.
3018                if (greatValue < pivotValue1) {
3019                  // Triple exchange.
3020                  a[k] = a[less];
3021                  a[less++] = a[great];
3022                  a[great--] = ek;
3023                } else {
3024                  // a[great] >= pivot1.
3025                  a[k] = a[great];
3026                  a[great--] = ek;
3027                }
3028                break;
3029              }
3030            }
3031          }
3032        }
3033      }
3034      })(); // isolate scope
3035    }
3036
3037    // Move pivots into their final positions.
3038    // We shrunk the list from both sides (a[left] and a[right] have
3039    // meaningless values in them) and now we move elements from the first
3040    // and third partition into these locations so that we can store the
3041    // pivots.
3042    a[lo] = a[less - 1];
3043    a[less - 1] = pivot1;
3044    a[hi - 1] = a[great + 1];
3045    a[great + 1] = pivot2;
3046
3047    // The list is now partitioned into three partitions:
3048    // [ < pivot1   | >= pivot1 && <= pivot2   |  > pivot2   ]
3049    //  ^            ^                        ^             ^
3050    // left         less                     great        right
3051
3052    // Recursive descent. (Don't include the pivot values.)
3053    sort(a, lo, less - 1);
3054    sort(a, great + 2, hi);
3055
3056    if (pivotsEqual) {
3057      // All elements in the second partition are equal to the pivot. No
3058      // need to sort them.
3059      return a;
3060    }
3061
3062    // In theory it should be enough to call _doSort recursively on the second
3063    // partition.
3064    // The Android source however removes the pivot elements from the recursive
3065    // call if the second partition is too large (more than 2/3 of the list).
3066    if (less < i1 && great > i5) {
3067
3068      (function () { // isolate scope
3069      var lessValue, greatValue;
3070      while ((lessValue = f(a[less])) <= pivotValue1 && lessValue >= pivotValue1) ++less;
3071      while ((greatValue = f(a[great])) <= pivotValue2 && greatValue >= pivotValue2) --great;
3072
3073      // Copy paste of the previous 3-way partitioning with adaptions.
3074      //
3075      // We partition the list into three parts:
3076      //  1. == pivot1
3077      //  2. > pivot1 && < pivot2
3078      //  3. == pivot2
3079      //
3080      // During the loop we have:
3081      // [ == pivot1 | > pivot1 && < pivot2 | unpartitioned  | == pivot2 ]
3082      //              ^                      ^              ^
3083      //            less                     k              great
3084      //
3085      // Invariants:
3086      //   1. for x in [ *, less[ : x == pivot1
3087      //   2. for x in [less, k[ : pivot1 < x && x < pivot2
3088      //   3. for x in ]great, * ] : x == pivot2
3089      for (var k = less; k <= great; k++) {
3090        var ek = a[k], xk = f(ek);
3091        if (xk <= pivotValue1 && xk >= pivotValue1) {
3092          if (k !== less) {
3093            a[k] = a[less];
3094            a[less] = ek;
3095          }
3096          less++;
3097        } else {
3098          if (xk <= pivotValue2 && xk >= pivotValue2) {
3099            /* eslint no-constant-condition: 0 */
3100            while (true) {
3101              greatValue = f(a[great]);
3102              if (greatValue <= pivotValue2 && greatValue >= pivotValue2) {
3103                great--;
3104                if (great < k) break;
3105                // This is the only location inside the loop where a new
3106                // iteration is started.
3107                continue;
3108              } else {
3109                // a[great] < pivot2.
3110                if (greatValue < pivotValue1) {
3111                  // Triple exchange.
3112                  a[k] = a[less];
3113                  a[less++] = a[great];
3114                  a[great--] = ek;
3115                } else {
3116                  // a[great] == pivot1.
3117                  a[k] = a[great];
3118                  a[great--] = ek;
3119                }
3120                break;
3121              }
3122            }
3123          }
3124        }
3125      }
3126      })(); // isolate scope
3127
3128    }
3129
3130    // The second partition has now been cleared of pivot elements and looks
3131    // as follows:
3132    // [  *  |  > pivot1 && < pivot2  | * ]
3133    //        ^                      ^
3134    //       less                  great
3135    // Sort the second partition using recursive descent.
3136
3137    // The second partition looks as follows:
3138    // [  *  |  >= pivot1 && <= pivot2  | * ]
3139    //        ^                        ^
3140    //       less                    great
3141    // Simply sort it by recursive descent.
3142
3143    return sort(a, less, great + 1);
3144  }
3145
3146  return sort;
3147}
3148
3149var quicksort_sizeThreshold = 32;
3150
3151module.exports = quicksort_by(crossfilter_identity);
3152module.exports.by = quicksort_by;
3153
3154},{"./identity":10,"./insertionsort":11}],15:[function(require,module,exports){
3155'use strict';
3156
3157function crossfilter_reduceIncrement(p) {
3158  return p + 1;
3159}
3160
3161function crossfilter_reduceDecrement(p) {
3162  return p - 1;
3163}
3164
3165function crossfilter_reduceAdd(f) {
3166  return function(p, v) {
3167    return p + +f(v);
3168  };
3169}
3170
3171function crossfilter_reduceSubtract(f) {
3172  return function(p, v) {
3173    return p - f(v);
3174  };
3175}
3176
3177module.exports = {
3178  reduceIncrement: crossfilter_reduceIncrement,
3179  reduceDecrement: crossfilter_reduceDecrement,
3180  reduceAdd: crossfilter_reduceAdd,
3181  reduceSubtract: crossfilter_reduceSubtract
3182};
3183
3184},{}],16:[function(require,module,exports){
3185'use strict';
3186
3187function crossfilter_zero() {
3188  return 0;
3189}
3190
3191module.exports = crossfilter_zero;
3192
3193},{}]},{},[1])(1)
3194});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.