PageSourceSearch

https://clg.qc.ca/wp-content/themes/clg.qc.ca/dist/scripts/main.js

js clg.qc.ca collected 2026-09-24 21:48:43 UTC 514,609 bytes, 14,771 lines download raw bytes

1// Console-polyfill. MIT license.
2// https://github.com/paulmillr/console-polyfill
3// Make it safe to do console.log() always.
4(function (con) {
5  'use strict';
6
7  var prop, method;
8  var empty = {};
9  var dummy = function dummy() {};
10  var properties = 'memory'.split(',');
11  var methods = ('assert,clear,count,debug,dir,dirxml,error,exception,group,' + 'groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,' + 'show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn').split(',');
12  while (prop = properties.pop()) con[prop] = con[prop] || empty;
13  while (method = methods.pop()) con[method] = con[method] || dummy;
14})(this.console = this.console || {}); // Using `this` for web workers.
15function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
16/**
17 * @license
18 * Lo-Dash 2.1.0 (Custom Build) <http://lodash.com/>
19 * Build: `lodash -o ./dist/lodash.compat.js`
20 * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
21 * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
22 * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
23 * Available under MIT license <http://lodash.com/license>
24 */
25;
26(function () {
27  /** Used as a safe reference for `undefined` in pre ES5 environments */
28  var undefined;
29
30  /** Used to pool arrays and objects used internally */
31  var arrayPool = [],
32    objectPool = [];
33
34  /** Used to generate unique IDs */
35  var idCounter = 0;
36
37  /** Used internally to indicate various things */
38  var indicatorObject = {};
39
40  /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
41  var keyPrefix = +new Date() + '';
42
43  /** Used as the size when optimizations are enabled for large arrays */
44  var largeArraySize = 75;
45
46  /** Used as the max size of the `arrayPool` and `objectPool` */
47  var maxPoolSize = 40;
48
49  /** Used to detect and test whitespace */
50  var whitespace =
51  // whitespace
52  " \t\x0B\f\xA0\uFEFF" +
53  // line terminators
54  "\n\r\u2028\u2029" +
55  // unicode category "Zs" space separators
56  "\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000";
57
58  /** Used to match empty string literals in compiled template source */
59  var reEmptyStringLeading = /\b__p \+= '';/g,
60    reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
61    reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
62
63  /**
64   * Used to match ES6 template delimiters
65   * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6
66   */
67  var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
68
69  /** Used to match regexp flags from their coerced string values */
70  var reFlags = /\w*$/;
71
72  /** Used to detected named functions */
73  var reFuncName = /^function[ \n\r\t]+\w/;
74
75  /** Used to match "interpolate" template delimiters */
76  var reInterpolate = /<%=([\s\S]+?)%>/g;
77
78  /** Used to match leading whitespace and zeros to be removed */
79  var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
80
81  /** Used to ensure capturing order of template delimiters */
82  var reNoMatch = /($^)/;
83
84  /** Used to detect functions containing a `this` reference */
85  var reThis = /\bthis\b/;
86
87  /** Used to match unescaped characters in compiled string literals */
88  var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
89
90  /** Used to assign default `context` object properties */
91  var contextProps = ['Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object', 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN', 'parseInt', 'setImmediate', 'setTimeout'];
92
93  /** Used to fix the JScript [[DontEnum]] bug */
94  var shadowedProps = ['constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'valueOf'];
95
96  /** Used to make template sourceURLs easier to identify */
97  var templateCounter = 0;
98
99  /** `Object#toString` result shortcuts */
100  var argsClass = '[object Arguments]',
101    arrayClass = '[object Array]',
102    boolClass = '[object Boolean]',
103    dateClass = '[object Date]',
104    errorClass = '[object Error]',
105    funcClass = '[object Function]',
106    numberClass = '[object Number]',
107    objectClass = '[object Object]',
108    regexpClass = '[object RegExp]',
109    stringClass = '[object String]';
110
111  /** Used to identify object classifications that `_.clone` supports */
112  var cloneableClasses = {};
113  cloneableClasses[funcClass] = false;
114  cloneableClasses[argsClass] = cloneableClasses[arrayClass] = cloneableClasses[boolClass] = cloneableClasses[dateClass] = cloneableClasses[numberClass] = cloneableClasses[objectClass] = cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
115
116  /** Used to determine if values are of the language type Object */
117  var objectTypes = {
118    'boolean': false,
119    'function': true,
120    'object': true,
121    'number': false,
122    'string': false,
123    'undefined': false
124  };
125
126  /** Used to escape characters for inclusion in compiled string literals */
127  var stringEscapes = {
128    '\\': '\\',
129    "'": "'",
130    '\n': 'n',
131    '\r': 'r',
132    '\t': 't',
133    "\u2028": 'u2028',
134    "\u2029": 'u2029'
135  };
136
137  /** Used as a reference to the global object */
138  var root = objectTypes[typeof window === "undefined" ? "undefined" : _typeof(window)] && window || this;
139
140  /** Detect free variable `exports` */
141  var freeExports = objectTypes[typeof exports === "undefined" ? "undefined" : _typeof(exports)] && exports && !exports.nodeType && exports;
142
143  /** Detect free variable `module` */
144  var freeModule = objectTypes[typeof module === "undefined" ? "undefined" : _typeof(module)] && module && !module.nodeType && module;
145
146  /** Detect the popular CommonJS extension `module.exports` */
147  var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
148
149  /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
150  var freeGlobal = objectTypes[typeof global === "undefined" ? "undefined" : _typeof(global)] && global;
151  if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
152    root = freeGlobal;
153  }
154
155  /*--------------------------------------------------------------------------*/
156
157  /**
158   * The base implementation of `_.indexOf` without support for binary searches
159   * or `fromIndex` constraints.
160   *
161   * @private
162   * @param {Array} array The array to search.
163   * @param {*} value The value to search for.
164   * @param {number} [fromIndex=0] The index to search from.
165   * @returns {number} Returns the index of the matched value or `-1`.
166   */
167  function baseIndexOf(array, value, fromIndex) {
168    var index = (fromIndex || 0) - 1,
169      length = array ? array.length : 0;
170    while (++index < length) {
171      if (array[index] === value) {
172        return index;
173      }
174    }
175    return -1;
176  }
177
178  /**
179   * An implementation of `_.contains` for cache objects that mimics the return
180   * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
181   *
182   * @private
183   * @param {Object} cache The cache object to inspect.
184   * @param {*} value The value to search for.
185   * @returns {number} Returns `0` if `value` is found, else `-1`.
186   */
187  function cacheIndexOf(cache, value) {
188    var type = _typeof(value);
189    cache = cache.cache;
190    if (type == 'boolean' || value == null) {
191      return cache[value] ? 0 : -1;
192    }
193    if (type != 'number' && type != 'string') {
194      type = 'object';
195    }
196    var key = type == 'number' ? value : keyPrefix + value;
197    cache = (cache = cache[type]) && cache[key];
198    return type == 'object' ? cache && baseIndexOf(cache, value) > -1 ? 0 : -1 : cache ? 0 : -1;
199  }
200
201  /**
202   * Adds a given value to the corresponding cache object.
203   *
204   * @private
205   * @param {*} value The value to add to the cache.
206   */
207  function cachePush(value) {
208    var cache = this.cache,
209      type = _typeof(value);
210    if (type == 'boolean' || value == null) {
211      cache[value] = true;
212    } else {
213      if (type != 'number' && type != 'string') {
214        type = 'object';
215      }
216      var key = type == 'number' ? value : keyPrefix + value,
217        typeCache = cache[type] || (cache[type] = {});
218      if (type == 'object') {
219        (typeCache[key] || (typeCache[key] = [])).push(value);
220      } else {
221        typeCache[key] = true;
222      }
223    }
224  }
225
226  /**
227   * Used by `_.max` and `_.min` as the default callback when a given
228   * collection is a string value.
229   *
230   * @private
231   * @param {string} value The character to inspect.
232   * @returns {number} Returns the code unit of given character.
233   */
234  function charAtCallback(value) {
235    return value.charCodeAt(0);
236  }
237
238  /**
239   * Used by `sortBy` to compare transformed `collection` elements, stable sorting
240   * them in ascending order.
241   *
242   * @private
243   * @param {Object} a The object to compare to `b`.
244   * @param {Object} b The object to compare to `a`.
245   * @returns {number} Returns the sort order indicator of `1` or `-1`.
246   */
247  function compareAscending(a, b) {
248    var ac = a.criteria,
249      bc = b.criteria;
250
251    // ensure a stable sort in V8 and other engines
252    // http://code.google.com/p/v8/issues/detail?id=90
253    if (ac !== bc) {
254      if (ac > bc || typeof ac == 'undefined') {
255        return 1;
256      }
257      if (ac < bc || typeof bc == 'undefined') {
258        return -1;
259      }
260    }
261    // The JS engine embedded in Adobe applications like InDesign has a buggy
262    // `Array#sort` implementation that causes it, under certain circumstances,
263    // to return the same value for `a` and `b`.
264    // See https://github.com/jashkenas/underscore/pull/1247
265    return a.index - b.index;
266  }
267
268  /**
269   * Creates a cache object to optimize linear searches of large arrays.
270   *
271   * @private
272   * @param {Array} [array=[]] The array to search.
273   * @returns {null|Object} Returns the cache object or `null` if caching should not be used.
274   */
275  function createCache(array) {
276    var index = -1,
277      length = array.length,
278      first = array[0],
279      mid = array[length / 2 | 0],
280      last = array[length - 1];
281    if (first && _typeof(first) == 'object' && mid && _typeof(mid) == 'object' && last && _typeof(last) == 'object') {
282      return false;
283    }
284    var cache = getObject();
285    cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
286    var result = getObject();
287    result.array = array;
288    result.cache = cache;
289    result.push = cachePush;
290    while (++index < length) {
291      result.push(array[index]);
292    }
293    return result;
294  }
295
296  /**
297   * Used by `template` to escape characters for inclusion in compiled
298   * string literals.
299   *
300   * @private
301   * @param {string} match The matched character to escape.
302   * @returns {string} Returns the escaped character.
303   */
304  function escapeStringChar(match) {
305    return '\\' + stringEscapes[match];
306  }
307
308  /**
309   * Gets an array from the array pool or creates a new one if the pool is empty.
310   *
311   * @private
312   * @returns {Array} The array from the pool.
313   */
314  function getArray() {
315    return arrayPool.pop() || [];
316  }
317
318  /**
319   * Gets an object from the object pool or creates a new one if the pool is empty.
320   *
321   * @private
322   * @returns {Object} The object from the pool.
323   */
324  function getObject() {
325    return objectPool.pop() || {
326      'args': '',
327      'array': null,
328      'bottom': '',
329      'cache': null,
330      'configurable': false,
331      'criteria': null,
332      'enumerable': false,
333      'false': false,
334      'firstArg': '',
335      'index': 0,
336      'init': '',
337      'keys': null,
338      'leading': false,
339      'loop': '',
340      'maxWait': 0,
341      'null': false,
342      'number': null,
343      'object': null,
344      'push': null,
345      'shadowedProps': null,
346      'string': null,
347      'top': '',
348      'trailing': false,
349      'true': false,
350      'undefined': false,
351      'useHas': false,
352      'value': null,
353      'writable': false
354    };
355  }
356
357  /**
358   * Checks if `value` is a DOM node in IE < 9.
359   *
360   * @private
361   * @param {*} value The value to check.
362   * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`.
363   */
364  function isNode(value) {
365    // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
366    // methods that are `typeof` "string" and still can coerce nodes to strings
367    return typeof value.toString != 'function' && typeof (value + '') == 'string';
368  }
369
370  /**
371   * A no-operation function.
372   *
373   * @private
374   */
375  function noop() {
376    // no operation performed
377  }
378
379  /**
380   * Releases the given array back to the array pool.
381   *
382   * @private
383   * @param {Array} [array] The array to release.
384   */
385  function releaseArray(array) {
386    array.length = 0;
387    if (arrayPool.length < maxPoolSize) {
388      arrayPool.push(array);
389    }
390  }
391
392  /**
393   * Releases the given object back to the object pool.
394   *
395   * @private
396   * @param {Object} [object] The object to release.
397   */
398  function releaseObject(object) {
399    var cache = object.cache;
400    if (cache) {
401      releaseObject(cache);
402    }
403    object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
404    if (objectPool.length < maxPoolSize) {
405      objectPool.push(object);
406    }
407  }
408
409  /**
410   * Slices the `collection` from the `start` index up to, but not including,
411   * the `end` index.
412   *
413   * Note: This function is used instead of `Array#slice` to support node lists
414   * in IE < 9 and to ensure dense arrays are returned.
415   *
416   * @private
417   * @param {Array|Object|string} collection The collection to slice.
418   * @param {number} start The start index.
419   * @param {number} end The end index.
420   * @returns {Array} Returns the new array.
421   */
422  function slice(array, start, end) {
423    start || (start = 0);
424    if (typeof end == 'undefined') {
425      end = array ? array.length : 0;
426    }
427    var index = -1,
428      length = end - start || 0,
429      result = Array(length < 0 ? 0 : length);
430    while (++index < length) {
431      result[index] = array[start + index];
432    }
433    return result;
434  }
435
436  /*--------------------------------------------------------------------------*/
437
438  /**
439   * Create a new `lodash` function using the given context object.
440   *
441   * @static
442   * @memberOf _
443   * @category Utilities
444   * @param {Object} [context=root] The context object.
445   * @returns {Function} Returns the `lodash` function.
446   */
447  function runInContext(context) {
448    // Avoid issues with some ES3 environments that attempt to use values, named
449    // after built-in constructors like `Object`, for the creation of literals.
450    // ES5 clears this up by stating that literals must use built-in constructors.
451    // See http://es5.github.io/#x11.1.5.
452    context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
453
454    /** Native constructor references */
455    var Array = context.Array,
456      Boolean = context.Boolean,
457      Date = context.Date,
458      Error = context.Error,
459      Function = context.Function,
460      Math = context.Math,
461      Number = context.Number,
462      Object = context.Object,
463      RegExp = context.RegExp,
464      String = context.String,
465      TypeError = context.TypeError;
466
467    /**
468     * Used for `Array` method references.
469     *
470     * Normally `Array.prototype` would suffice, however, using an array literal
471     * avoids issues in Narwhal.
472     */
473    var arrayRef = [];
474
475    /** Used for native method references */
476    var errorProto = Error.prototype,
477      objectProto = Object.prototype,
478      stringProto = String.prototype;
479
480    /** Used to restore the original `_` reference in `noConflict` */
481    var oldDash = context._;
482
483    /** Used to detect if a method is native */
484    var reNative = RegExp('^' + String(objectProto.valueOf).replace(/[.*+?^${}()|[\]\\]/g, '\\$&').replace(/valueOf|for [^\]]+/g, '.+?') + '$');
485
486    /** Native method shortcuts */
487    var ceil = Math.ceil,
488      clearTimeout = context.clearTimeout,
489      floor = Math.floor,
490      fnToString = Function.prototype.toString,
491      getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
492      hasOwnProperty = objectProto.hasOwnProperty,
493      push = arrayRef.push,
494      propertyIsEnumerable = objectProto.propertyIsEnumerable,
495      setImmediate = context.setImmediate,
496      setTimeout = context.setTimeout,
497      splice = arrayRef.splice,
498      toString = objectProto.toString,
499      unshift = arrayRef.unshift;
500    var defineProperty = function () {
501      try {
502        var o = {},
503          func = reNative.test(func = Object.defineProperty) && func,
504          result = func(o, o, o) && func;
505      } catch (e) {}
506      return result;
507    }();
508
509    /* Native method shortcuts for methods with the same name as other `lodash` methods */
510    var nativeBind = reNative.test(nativeBind = toString.bind) && nativeBind,
511      nativeCreate = reNative.test(nativeCreate = Object.create) && nativeCreate,
512      nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
513      nativeIsFinite = context.isFinite,
514      nativeIsNaN = context.isNaN,
515      nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
516      nativeMax = Math.max,
517      nativeMin = Math.min,
518      nativeParseInt = context.parseInt,
519      nativeRandom = Math.random,
520      nativeSlice = arrayRef.slice;
521
522    /** Detect various environments */
523    var isIeOpera = reNative.test(context.attachEvent),
524      isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera);
525
526    /** Used to lookup a built-in constructor by [[Class]] */
527    var ctorByClass = {};
528    ctorByClass[arrayClass] = Array;
529    ctorByClass[boolClass] = Boolean;
530    ctorByClass[dateClass] = Date;
531    ctorByClass[funcClass] = Function;
532    ctorByClass[objectClass] = Object;
533    ctorByClass[numberClass] = Number;
534    ctorByClass[regexpClass] = RegExp;
535    ctorByClass[stringClass] = String;
536
537    /** Used to avoid iterating non-enumerable properties in IE < 9 */
538    var nonEnumProps = {};
539    nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = {
540      'constructor': true,
541      'toLocaleString': true,
542      'toString': true,
543      'valueOf': true
544    };
545    nonEnumProps[boolClass] = nonEnumProps[stringClass] = {
546      'constructor': true,
547      'toString': true,
548      'valueOf': true
549    };
550    nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = {
551      'constructor': true,
552      'toString': true
553    };
554    nonEnumProps[objectClass] = {
555      'constructor': true
556    };
557    (function () {
558      var length = shadowedProps.length;
559      while (length--) {
560        var prop = shadowedProps[length];
561        for (var className in nonEnumProps) {
562          if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], prop)) {
563            nonEnumProps[className][prop] = false;
564          }
565        }
566      }
567    })();
568
569    /*--------------------------------------------------------------------------*/
570
571    /**
572     * Creates a `lodash` object which wraps the given value to enable method
573     * chaining.
574     *
575     * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
576     * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
577     * and `unshift`
578     *
579     * Chaining is supported in custom builds as long as the `value` method is
580     * implicitly or explicitly included in the build.
581     *
582     * The chainable wrapper functions are:
583     * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
584     * `compose`, `concat`, `countBy`, `createCallback`, `curry`, `debounce`,
585     * `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, `forEach`,
586     * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`,
587     * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`,
588     * `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, `once`, `pairs`,
589     * `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, `range`, `reject`,
590     * `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`,
591     * `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, `unshift`,
592     * `unzip`, `values`, `where`, `without`, `wrap`, and `zip`
593     *
594     * The non-chainable wrapper functions are:
595     * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
596     * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
597     * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
598     * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
599     * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
600     * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
601     * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
602     * `template`, `unescape`, `uniqueId`, and `value`
603     *
604     * The wrapper functions `first` and `last` return wrapped values when `n` is
605     * provided, otherwise they return unwrapped values.
606     *
607     * @name _
608     * @constructor
609     * @category Chaining
610     * @param {*} value The value to wrap in a `lodash` instance.
611     * @returns {Object} Returns a `lodash` instance.
612     * @example
613     *
614     * var wrapped = _([1, 2, 3]);
615     *
616     * // returns an unwrapped value
617     * wrapped.reduce(function(sum, num) {
618     *   return sum + num;
619     * });
620     * // => 6
621     *
622     * // returns a wrapped value
623     * var squares = wrapped.map(function(num) {
624     *   return num * num;
625     * });
626     *
627     * _.isArray(squares);
628     * // => false
629     *
630     * _.isArray(squares.value());
631     * // => true
632     */
633    function lodash(value) {
634      // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
635      return value && _typeof(value) == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__') ? value : new lodashWrapper(value);
636    }
637
638    /**
639     * A fast path for creating `lodash` wrapper objects.
640     *
641     * @private
642     * @param {*} value The value to wrap in a `lodash` instance.
643     * @param {boolean} chainAll A flag to enable chaining for all methods
644     * @returns {Object} Returns a `lodash` instance.
645     */
646    function lodashWrapper(value, chainAll) {
647      this.__chain__ = !!chainAll;
648      this.__wrapped__ = value;
649    }
650    // ensure `new lodashWrapper` is an instance of `lodash`
651    lodashWrapper.prototype = lodash.prototype;
652
653    /**
654     * An object used to flag environments features.
655     *
656     * @static
657     * @memberOf _
658     * @type Object
659     */
660    var support = lodash.support = {};
661    (function () {
662      var ctor = function ctor() {
663          this.x = 1;
664        },
665        object = {
666          '0': 1,
667          'length': 1
668        },
669        props = [];
670      ctor.prototype = {
671        'valueOf': 1,
672        'y': 1
673      };
674      for (var prop in new ctor()) {
675        props.push(prop);
676      }
677      for (prop in arguments) {}
678
679      /**
680       * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9).
681       *
682       * @memberOf _.support
683       * @type boolean
684       */
685      support.argsClass = toString.call(arguments) == argsClass;
686
687      /**
688       * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5).
689       *
690       * @memberOf _.support
691       * @type boolean
692       */
693      support.argsObject = arguments.constructor == Object && !(arguments instanceof Array);
694
695      /**
696       * Detect if `name` or `message` properties of `Error.prototype` are
697       * enumerable by default. (IE < 9, Safari < 5.1)
698       *
699       * @memberOf _.support
700       * @type boolean
701       */
702      support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name');
703
704      /**
705       * Detect if `prototype` properties are enumerable by default.
706       *
707       * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
708       * (if the prototype or a property on the prototype has been set)
709       * incorrectly sets a function's `prototype` property [[Enumerable]]
710       * value to `true`.
711       *
712       * @memberOf _.support
713       * @type boolean
714       */
715      support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype');
716
717      /**
718       * Detect if `Function#bind` exists and is inferred to be fast (all but V8).
719       *
720       * @memberOf _.support
721       * @type boolean
722       */
723      support.fastBind = nativeBind && !isV8;
724
725      /**
726       * Detect if functions can be decompiled by `Function#toString`
727       * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
728       *
729       * @memberOf _.support
730       * @type boolean
731       */
732      support.funcDecomp = !reNative.test(context.WinRTError) && reThis.test(runInContext);
733
734      /**
735       * Detect if `Function#name` is supported (all but IE).
736       *
737       * @memberOf _.support
738       * @type boolean
739       */
740      support.funcNames = typeof Function.name == 'string';
741
742      /**
743       * Detect if `arguments` object indexes are non-enumerable
744       * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1).
745       *
746       * @memberOf _.support
747       * @type boolean
748       */
749      support.nonEnumArgs = prop != 0;
750
751      /**
752       * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
753       *
754       * In IE < 9 an objects own properties, shadowing non-enumerable ones, are
755       * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug).
756       *
757       * @memberOf _.support
758       * @type boolean
759       */
760      support.nonEnumShadows = !/valueOf/.test(props);
761
762      /**
763       * Detect if own properties are iterated after inherited properties (all but IE < 9).
764       *
765       * @memberOf _.support
766       * @type boolean
767       */
768      support.ownLast = props[0] != 'x';
769
770      /**
771       * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
772       *
773       * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
774       * and `splice()` functions that fail to remove the last element, `value[0]`,
775       * of array-like objects even though the `length` property is set to `0`.
776       * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
777       * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
778       *
779       * @memberOf _.support
780       * @type boolean
781       */
782      support.spliceObjects = (arrayRef.splice.call(object, 0, 1), !object[0]);
783
784      /**
785       * Detect lack of support for accessing string characters by index.
786       *
787       * IE < 8 can't access characters by index and IE 8 can only access
788       * characters by index on string literals.
789       *
790       * @memberOf _.support
791       * @type boolean
792       */
793      support.unindexedChars = 'x'[0] + Object('x')[0] != 'xx';
794
795      /**
796       * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9)
797       * and that the JS engine errors when attempting to coerce an object to
798       * a string without a `toString` function.
799       *
800       * @memberOf _.support
801       * @type boolean
802       */
803      try {
804        support.nodeClass = !(toString.call(document) == objectClass && !({
805          'toString': 0
806        } + ''));
807      } catch (e) {
808        support.nodeClass = true;
809      }
810    })(1);
811
812    /**
813     * By default, the template delimiters used by Lo-Dash are similar to those in
814     * embedded Ruby (ERB). Change the following template settings to use alternative
815     * delimiters.
816     *
817     * @static
818     * @memberOf _
819     * @type Object
820     */
821    lodash.templateSettings = {
822      /**
823       * Used to detect `data` property values to be HTML-escaped.
824       *
825       * @memberOf _.templateSettings
826       * @type RegExp
827       */
828      'escape': /<%-([\s\S]+?)%>/g,
829      /**
830       * Used to detect code to be evaluated.
831       *
832       * @memberOf _.templateSettings
833       * @type RegExp
834       */
835      'evaluate': /<%([\s\S]+?)%>/g,
836      /**
837       * Used to detect `data` property values to inject.
838       *
839       * @memberOf _.templateSettings
840       * @type RegExp
841       */
842      'interpolate': reInterpolate,
843      /**
844       * Used to reference the data object in the template text.
845       *
846       * @memberOf _.templateSettings
847       * @type string
848       */
849      'variable': '',
850      /**
851       * Used to import variables into the compiled template.
852       *
853       * @memberOf _.templateSettings
854       * @type Object
855       */
856      'imports': {
857        /**
858         * A reference to the `lodash` function.
859         *
860         * @memberOf _.templateSettings.imports
861         * @type Function
862         */
863        '_': lodash
864      }
865    };
866
867    /*--------------------------------------------------------------------------*/
868
869    /**
870     * The template used to create iterator functions.
871     *
872     * @private
873     * @param {Object} data The data object used to populate the text.
874     * @returns {string} Returns the interpolated text.
875     */
876    var iteratorTemplate = function iteratorTemplate(obj) {
877      var __p = 'var index, iterable = ' + obj.firstArg + ', result = ' + obj.init + ';\nif (!iterable) return result;\n' + obj.top + ';';
878      if (obj.array) {
879        __p += '\nvar length = iterable.length; index = -1;\nif (' + obj.array + ') {  ';
880        if (support.unindexedChars) {
881          __p += '\n  if (isString(iterable)) {\n    iterable = iterable.split(\'\')\n  }  ';
882        }
883        __p += '\n  while (++index < length) {\n    ' + obj.loop + ';\n  }\n}\nelse {  ';
884      } else if (support.nonEnumArgs) {
885        __p += '\n  var length = iterable.length; index = -1;\n  if (length && isArguments(iterable)) {\n    while (++index < length) {\n      index += \'\';\n      ' + obj.loop + ';\n    }\n  } else {  ';
886      }
887      if (support.enumPrototypes) {
888        __p += '\n  var skipProto = typeof iterable == \'function\';\n  ';
889      }
890      if (support.enumErrorProps) {
891        __p += '\n  var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n  ';
892      }
893      var conditions = [];
894      if (support.enumPrototypes) {
895        conditions.push('!(skipProto && index == "prototype")');
896      }
897      if (support.enumErrorProps) {
898        conditions.push('!(skipErrorProps && (index == "message" || index == "name"))');
899      }
900      if (obj.useHas && obj.keys) {
901        __p += '\n  var ownIndex = -1,\n      ownProps = objectTypes[typeof iterable] && keys(iterable),\n      length = ownProps ? ownProps.length : 0;\n\n  while (++ownIndex < length) {\n    index = ownProps[ownIndex];\n';
902        if (conditions.length) {
903          __p += '    if (' + conditions.join(' && ') + ') {\n  ';
904        }
905        __p += obj.loop + ';    ';
906        if (conditions.length) {
907          __p += '\n    }';
908        }
909        __p += '\n  }  ';
910      } else {
911        __p += '\n  for (index in iterable) {\n';
912        if (obj.useHas) {
913          conditions.push("hasOwnProperty.call(iterable, index)");
914        }
915        if (conditions.length) {
916          __p += '    if (' + conditions.join(' && ') + ') {\n  ';
917        }
918        __p += obj.loop + ';    ';
919        if (conditions.length) {
920          __p += '\n    }';
921        }
922        __p += '\n  }    ';
923        if (support.nonEnumShadows) {
924          __p += '\n\n  if (iterable !== objectProto) {\n    var ctor = iterable.constructor,\n        isProto = iterable === (ctor && ctor.prototype),\n        className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n        nonEnum = n
924onEnumProps[className];\n      ';
925          for (k = 0; k < 7; k++) {
926            __p += '\n    index = \'' + obj.shadowedProps[k] + '\';\n    if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))';
927            if (!obj.useHas) {
928              __p += ' || (!nonEnum[index] && iterable[index] !== objectProto[index])';
929            }
930            __p += ') {\n      ' + obj.loop + ';\n    }      ';
931          }
932          __p += '\n  }    ';
933        }
934      }
935      if (obj.array || support.nonEnumArgs) {
936        __p += '\n}';
937      }
938      __p += obj.bottom + ';\nreturn result';
939      return __p;
940    };
941
942    /*--------------------------------------------------------------------------*/
943
944    /**
945     * The base implementation of `_.clone` without argument juggling or support
946     * for `thisArg` binding.
947     *
948     * @private
949     * @param {*} value The value to clone.
950     * @param {boolean} [deep=false] Specify a deep clone.
951     * @param {Function} [callback] The function to customize cloning values.
952     * @param {Array} [stackA=[]] Tracks traversed source objects.
953     * @param {Array} [stackB=[]] Associates clones with source counterparts.
954     * @returns {*} Returns the cloned `value`.
955     */
956    function baseClone(value, deep, callback, stackA, stackB) {
957      var result = value;
958      if (callback) {
959        result = callback(result);
960        if (typeof result != 'undefined') {
961          return result;
962        }
963        result = value;
964      }
965      // inspect [[Class]]
966      var isObj = isObject(result);
967      if (isObj) {
968        var className = toString.call(result);
969        if (!cloneableClasses[className] || !support.nodeClass && isNode(result)) {
970          return result;
971        }
972        var isArr = isArray(result);
973      }
974      // shallow clone
975      if (!isObj || !deep) {
976        return isObj ? isArr ? slice(result) : assign({}, result) : result;
977      }
978      var ctor = ctorByClass[className];
979      switch (className) {
980        case boolClass:
981        case dateClass:
982          return new ctor(+result);
983        case numberClass:
984        case stringClass:
985          return new ctor(result);
986        case regexpClass:
987          return ctor(result.source, reFlags.exec(result));
988      }
989      // check for circular references and return corresponding clone
990      var initedStack = !stackA;
991      stackA || (stackA = getArray());
992      stackB || (stackB = getArray());
993      var length = stackA.length;
994      while (length--) {
995        if (stackA[length] == value) {
996          return stackB[length];
997        }
998      }
999      // init cloned object
1000      result = isArr ? ctor(result.length) : {};
1001
1002      // add array properties assigned by `RegExp#exec`
1003      if (isArr) {
1004        if (hasOwnProperty.call(value, 'index')) {
1005          result.index = value.index;
1006        }
1007        if (hasOwnProperty.call(value, 'input')) {
1008          result.input = value.input;
1009        }
1010      }
1011      // add the source value to the stack of traversed objects
1012      // and associate it with its clone
1013      stackA.push(value);
1014      stackB.push(result);
1015
1016      // recursively populate clone (susceptible to call stack limits)
1017      (isArr ? baseEach : forOwn)(value, function (objValue, key) {
1018        result[key] = baseClone(objValue, deep, callback, stackA, stackB);
1019      });
1020      if (initedStack) {
1021        releaseArray(stackA);
1022        releaseArray(stackB);
1023      }
1024      return result;
1025    }
1026
1027    /**
1028     * The base implementation of `_.createCallback` without support for creating
1029     * "_.pluck" or "_.where" style callbacks.
1030     *
1031     * @private
1032     * @param {*} [func=identity] The value to convert to a callback.
1033     * @param {*} [thisArg] The `this` binding of the created callback.
1034     * @param {number} [argCount] The number of arguments the callback accepts.
1035     * @returns {Function} Returns a callback function.
1036     */
1037    function baseCreateCallback(func, thisArg, argCount) {
1038      if (typeof func != 'function') {
1039        return identity;
1040      }
1041      // exit early if there is no `thisArg`
1042      if (typeof thisArg == 'undefined') {
1043        return func;
1044      }
1045      var bindData = func.__bindData__ || support.funcNames && !func.name;
1046      if (typeof bindData == 'undefined') {
1047        var source = reThis && fnToString.call(func);
1048        if (!support.funcNames && source && !reFuncName.test(source)) {
1049          bindData = true;
1050        }
1051        if (support.funcNames || !bindData) {
1052          // checks if `func` references the `this` keyword and stores the result
1053          bindData = !support.funcDecomp || reThis.test(source);
1054          setBindData(func, bindData);
1055        }
1056      }
1057      // exit early if there are no `this` references or `func` is bound
1058      if (bindData !== true && bindData && bindData[1] & 1) {
1059        return func;
1060      }
1061      switch (argCount) {
1062        case 1:
1063          return function (value) {
1064            return func.call(thisArg, value);
1065          };
1066        case 2:
1067          return function (a, b) {
1068            return func.call(thisArg, a, b);
1069          };
1070        case 3:
1071          return function (value, index, collection) {
1072            return func.call(thisArg, value, index, collection);
1073          };
1074        case 4:
1075          return function (accumulator, value, index, collection) {
1076            return func.call(thisArg, accumulator, value, index, collection);
1077          };
1078      }
1079      return bind(func, thisArg);
1080    }
1081
1082    /**
1083     * The base implementation of `_.flatten` without support for callback
1084     * shorthands or `thisArg` binding.
1085     *
1086     * @private
1087     * @param {Array} array The array to flatten.
1088     * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
1089     * @param {boolean} [isArgArrays=false] A flag to restrict flattening to arrays and `arguments` objects.
1090     * @param {number} [fromIndex=0] The index to start from.
1091     * @returns {Array} Returns a new flattened array.
1092     */
1093    function baseFlatten(array, isShallow, isArgArrays, fromIndex) {
1094      var index = (fromIndex || 0) - 1,
1095        length = array ? array.length : 0,
1096        result = [];
1097      while (++index < length) {
1098        var value = array[index];
1099        if (value && _typeof(value) == 'object' && typeof value.length == 'number' && (isArray(value) || isArguments(value))) {
1100          // recursively flatten arrays (susceptible to call stack limits)
1101          if (!isShallow) {
1102            value = baseFlatten(value, isShallow, isArgArrays);
1103          }
1104          var valIndex = -1,
1105            valLength = value.length,
1106            resIndex = result.length;
1107          result.length += valLength;
1108          while (++valIndex < valLength) {
1109            result[resIndex++] = value[valIndex];
1110          }
1111        } else if (!isArgArrays) {
1112          result.push(value);
1113        }
1114      }
1115      return result;
1116    }
1117
1118    /**
1119     * The base implementation of `_.isEqual`, without support for `thisArg` binding,
1120     * that allows partial "_.where" style comparisons.
1121     *
1122     * @private
1123     * @param {*} a The value to compare.
1124     * @param {*} b The other value to compare.
1125     * @param {Function} [callback] The function to customize comparing values.
1126     * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
1127     * @param {Array} [stackA=[]] Tracks traversed `a` objects.
1128     * @param {Array} [stackB=[]] Tracks traversed `b` objects.
1129     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
1130     */
1131    function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
1132      // used to indicate that when comparing objects, `a` has at least the properties of `b`
1133      if (callback) {
1134        var result = callback(a, b);
1135        if (typeof result != 'undefined') {
1136          return !!result;
1137        }
1138      }
1139      // exit early for identical values
1140      if (a === b) {
1141        // treat `+0` vs. `-0` as not equal
1142        return a !== 0 || 1 / a == 1 / b;
1143      }
1144      var type = _typeof(a),
1145        otherType = _typeof(b);
1146
1147      // exit early for unlike primitive values
1148      if (a === a && !(a && objectTypes[type]) && !(b && objectTypes[otherType])) {
1149        return false;
1150      }
1151      // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
1152      // http://es5.github.io/#x15.3.4.4
1153      if (a == null || b == null) {
1154        return a === b;
1155      }
1156      // compare [[Class]] names
1157      var className = toString.call(a),
1158        otherClass = toString.call(b);
1159      if (className == argsClass) {
1160        className = objectClass;
1161      }
1162      if (otherClass == argsClass) {
1163        otherClass = objectClass;
1164      }
1165      if (className != otherClass) {
1166        return false;
1167      }
1168      switch (className) {
1169        case boolClass:
1170        case dateClass:
1171          // coerce dates and booleans to numbers, dates to milliseconds and booleans
1172          // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
1173          return +a == +b;
1174        case numberClass:
1175          // treat `NaN` vs. `NaN` as equal
1176          return a != +a ? b != +b
1177          // but treat `+0` vs. `-0` as not equal
1178          : a == 0 ? 1 / a == 1 / b : a == +b;
1179        case regexpClass:
1180        case stringClass:
1181          // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
1182          // treat string primitives and their corresponding object instances as equal
1183          return a == String(b);
1184      }
1185      var isArr = className == arrayClass;
1186      if (!isArr) {
1187        // unwrap any `lodash` wrapped values
1188        if (hasOwnProperty.call(a, '__wrapped__ ') || hasOwnProperty.call(b, '__wrapped__')) {
1189          return baseIsEqual(a.__wrapped__ || a, b.__wrapped__ || b, callback, isWhere, stackA, stackB);
1190        }
1191        // exit for functions and DOM nodes
1192        if (className != objectClass || !support.nodeClass && (isNode(a) || isNode(b))) {
1193          return false;
1194        }
1195        // in older versions of Opera, `arguments` objects have `Array` constructors
1196        var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor,
1197          ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor;
1198
1199        // non `Object` object instances with different constructors are not equal
1200        if (ctorA != ctorB && !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB)) {
1201          return false;
1202        }
1203      }
1204      // assume cyclic structures are equal
1205      // the algorithm for detecting cyclic structures is adapted from ES 5.1
1206      // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
1207      var initedStack = !stackA;
1208      stackA || (stackA = getArray());
1209      stackB || (stackB = getArray());
1210      var length = stackA.length;
1211      while (length--) {
1212        if (stackA[length] == a) {
1213          return stackB[length] == b;
1214        }
1215      }
1216      var size = 0;
1217      result = true;
1218
1219      // add `a` and `b` to the stack of traversed objects
1220      stackA.push(a);
1221      stackB.push(b);
1222
1223      // recursively compare objects and arrays (susceptible to call stack limits)
1224      if (isArr) {
1225        length = a.length;
1226        size = b.length;
1227
1228        // compare lengths to determine if a deep comparison is necessary
1229        result = size == a.length;
1230        if (!result && !isWhere) {
1231          return result;
1232        }
1233        // deep compare the contents, ignoring non-numeric properties
1234        while (size--) {
1235          var index = length,
1236            value = b[size];
1237          if (isWhere) {
1238            while (index--) {
1239              if (result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB)) {
1240                break;
1241              }
1242            }
1243          } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
1244            break;
1245          }
1246        }
1247        return result;
1248      }
1249      // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
1250      // which, in this case, is more costly
1251      forIn(b, function (value, key, b) {
1252        if (hasOwnProperty.call(b, key)) {
1253          // count the number of properties.
1254          size++;
1255          // deep compare each property value.
1256          return result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB);
1257        }
1258      });
1259      if (result && !isWhere) {
1260        // ensure both objects have the same number of properties
1261        forIn(a, function (value, key, a) {
1262          if (hasOwnProperty.call(a, key)) {
1263            // `size` will be `-1` if `a` has more properties than `b`
1264            return result = --size > -1;
1265          }
1266        });
1267      }
1268      if (initedStack) {
1269        releaseArray(stackA);
1270        releaseArray(stackB);
1271      }
1272      return result;
1273    }
1274
1275    /**
1276     * The base implementation of `_.merge` without argument juggling or support
1277     * for `thisArg` binding.
1278     *
1279     * @private
1280     * @param {Object} object The destination object.
1281     * @param {Object} source The source object.
1282     * @param {Function} [callback] The function to customize merging properties.
1283     * @param {Array} [stackA=[]] Tracks traversed source objects.
1284     * @param {Array} [stackB=[]] Associates values with source counterparts.
1285     */
1286    function baseMerge(object, source, callback, stackA, stackB) {
1287      (isArray(source) ? forEach : forOwn)(source, function (source, key) {
1288        var found,
1289          isArr,
1290          result = source,
1291          value = object[key];
1292        if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
1293          // avoid merging previously merged cyclic sources
1294          var stackLength = stackA.length;
1295          while (stackLength--) {
1296            if (found = stackA[stackLength] == source) {
1297              value = stackB[stackLength];
1298              break;
1299            }
1300          }
1301          if (!found) {
1302            var isShallow;
1303            if (callback) {
1304              result = callback(value, source);
1305              if (isShallow = typeof result != 'undefined') {
1306                value = result;
1307              }
1308            }
1309            if (!isShallow) {
1310              value = isArr ? isArray(value) ? value : [] : isPlainObject(value) ? value : {};
1311            }
1312            // add `source` and associated `value` to the stack of traversed objects
1313            stackA.push(source);
1314            stackB.push(value);
1315
1316            // recursively merge objects and arrays (susceptible to call stack limits)
1317            if (!isShallow) {
1318              baseMerge(value, source, callback, stackA, stackB);
1319            }
1320          }
1321        } else {
1322          if (callback) {
1323            result = callback(value, source);
1324            if (typeof result == 'undefined') {
1325              result = source;
1326            }
1327          }
1328          if (typeof result != 'undefined') {
1329            value = result;
1330          }
1331        }
1332        object[key] = value;
1333      });
1334    }
1335
1336    /**
1337     * The base implementation of `_.uniq` without support for callback shorthands
1338     * or `thisArg` binding.
1339     *
1340     * @private
1341     * @param {Array} array The array to process.
1342     * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
1343     * @param {Function} [callback] The function called per iteration.
1344     * @returns {Array} Returns a duplicate-value-free array.
1345     */
1346    function baseUniq(array, isSorted, callback) {
1347      var index = -1,
1348        indexOf = getIndexOf(),
1349        length = array ? array.length : 0,
1350        result = [];
1351      var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf,
1352        seen = callback || isLarge ? getArray() : result;
1353      if (isLarge) {
1354        var cache = createCache(seen);
1355        if (cache) {
1356          indexOf = cacheIndexOf;
1357          seen = cache;
1358        } else {
1359          isLarge = false;
1360          seen = callback ? seen : (releaseArray(seen), result);
1361        }
1362      }
1363      while (++index < length) {
1364        var value = array[index],
1365          computed = callback ? callback(value, index, array) : value;
1366        if (isSorted ? !index || seen[seen.length - 1] !== computed : indexOf(seen, computed) < 0) {
1367          if (callback || isLarge) {
1368            seen.push(computed);
1369          }
1370          result.push(value);
1371        }
1372      }
1373      if (isLarge) {
1374        releaseArray(seen.array);
1375        releaseObject(seen);
1376      } else if (callback) {
1377        releaseArray(seen);
1378      }
1379      return result;
1380    }
1381
1382    /**
1383     * Creates a function that aggregates a collection, creating an object composed
1384     * of keys generated from the results of running each element of the collection
1385     * through a callback. The given `setter` function sets the keys and values
1386     * of the composed object.
1387     *
1388     * @private
1389     * @param {Function} setter The setter function.
1390     * @returns {Function} Returns the new aggregator function.
1391     */
1392    function createAggregator(setter) {
1393      return function (collection, callback, thisArg) {
1394        var result = {};
1395        callback = lodash.createCallback(callback, thisArg, 3);
1396        if (isArray(collection)) {
1397          var index = -1,
1398            length = collection.length;
1399          while (++index < length) {
1400            var value = collection[index];
1401            setter(result, value, callback(value, index, collection), collection);
1402          }
1403        } else {
1404          baseEach(collection, function (value, key, collection) {
1405            setter(result, value, callback(value, key, collection), collection);
1406          });
1407        }
1408        return result;
1409      };
1410    }
1411
1412    /**
1413     * Creates a function that, when called, either curries or invokes `func`
1414     * with an optional `this` binding and partially applied arguments.
1415     *
1416     * @private
1417     * @param {Function|string} func The function or method name to reference.
1418     * @param {number} bitmask The bitmask of method flags to compose.
1419     *  The bitmask may be composed of the following flags:
1420     *  1 - `_.bind`
1421     *  2 - `_.bindKey`
1422     *  4 - `_.curry`
1423     *  8 - `_.curry` (bound)
1424     *  16 - `_.partial`
1425     *  32 - `_.partialRight`
1426     * @param {Array} [partialArgs] An array of arguments to prepend to those
1427     *  provided to the new function.
1428     * @param {Array} [partialRightArgs] An array of arguments to append to those
1429     *  provided to the new function.
1430     * @param {*} [thisArg] The `this` binding of `func`.
1431     * @param {number} [arity] The arity of `func`.
1432     * @returns {Function} Returns the new bound function.
1433     */
1434    function createBound(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
1435      var isBind = bitmask & 1,
1436        isBindKey = bitmask & 2,
1437        isCurry = bitmask & 4,
1438        isCurryBound = bitmask & 8,
1439        isPartial = bitmask & 16,
1440        isPartialRight = bitmask & 32,
1441        key = func;
1442      if (!isBindKey && !isFunction(func)) {
1443        throw new TypeError();
1444      }
1445      if (isPartial && !partialArgs.length) {
1446        bitmask &= ~16;
1447        isPartial = partialArgs = false;
1448      }
1449      if (isPartialRight && !partialRightArgs.length) {
1450        bitmask &= ~32;
1451        isPartialRight = partialRightArgs = false;
1452      }
1453      var bindData = func && func.__bindData__;
1454      if (bindData) {
1455        if (isBind && !(bindData[1] & 1)) {
1456          bindData[4] = thisArg;
1457        }
1458        if (!isBind && bindData[1] & 1) {
1459          bitmask |= 8;
1460        }
1461        if (isCurry && !(bindData[1] & 4)) {
1462          bindData[5] = arity;
1463        }
1464        if (isPartial) {
1465          push.apply(bindData[2] || (bindData[2] = []), partialArgs);
1466        }
1467        if (isPartialRight) {
1468          push.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
1469        }
1470        bindData[1] |= bitmask;
1471        return createBound.apply(null, bindData);
1472      }
1473      // use `Function#bind` if it exists and is fast
1474      // (in V8 `Function#bind` is slower except when partially applied)
1475      if (isBind && !(isBindKey || isCurry || isPartialRight) && (support.fastBind || nativeBind && isPartial)) {
1476        if (isPartial) {
1477          var args = [thisArg];
1478          push.apply(args, partialArgs);
1479        }
1480        var _bound = isPartial ? nativeBind.apply(func, args) : nativeBind.call(func, thisArg);
1481      } else {
1482        _bound = function bound() {
1483          // `Function#bind` spec
1484          // http://es5.github.io/#x15.3.4.5
1485          var args = arguments,
1486            thisBinding = isBind ? thisArg : this;
1487          if (isCurry || isPartial || isPartialRight) {
1488            args = nativeSlice.call(args);
1489            if (isPartial) {
1490              unshift.apply(args, partialArgs);
1491            }
1492            if (isPartialRight) {
1493              push.apply(args, partialRightArgs);
1494            }
1495            if (isCurry && args.length < arity) {
1496              bitmask |= 16 & ~32;
1497              return createBound(func, isCurryBound ? bitmask : bitmask & ~3, args, null, thisArg, arity);
1498            }
1499          }
1500          if (isBindKey) {
1501            func = thisBinding[key];
1502          }
1503          if (this instanceof _bound) {
1504            // ensure `new bound` is an instance of `func`
1505            thisBinding = createObject(func.prototype);
1506
1507            // mimic the constructor's `return` behavior
1508            // http://es5.github.io/#x13.2.2
1509            var result = func.apply(thisBinding, args);
1510            return isObject(result) ? result : thisBinding;
1511          }
1512          return func.apply(thisBinding, args);
1513        };
1514      }
1515      setBindData(_bound, nativeSlice.call(arguments));
1516      return _bound;
1517    }
1518
1519    /**
1520     * Creates compiled iteration functions.
1521     *
1522     * @private
1523     * @param {...Object} [options] The compile options object(s).
1524     * @param {string} [options.array] Code to determine if the iterable is an array or array-like.
1525     * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop.
1526     * @param {Function} [options.keys] A reference to `_.keys` for use in own property iteration.
1527     * @param {string} [options.args] A comma separated string of iteration function arguments.
1528     * @param {string} [options.top] Code to execute before the iteration branches.
1529     * @param {string} [options.loop] Code to execute in the object loop.
1530     * @param {string} [options.bottom] Code to execute after the iteration branches.
1531     * @returns {Function} Returns the compiled function.
1532     */
1533    function createIterator() {
1534      var data = getObject();
1535
1536      // data properties
1537      data.shadowedProps = shadowedProps;
1538
1539      // iterator options
1540      data.array = data.bottom = data.loop = data.top = '';
1541      data.init = 'iterable';
1542      data.useHas = true;
1543
1544      // merge options into a template data object
1545      for (var object, index = 0; object = arguments[index]; index++) {
1546        for (var key in object) {
1547          data[key] = object[key];
1548        }
1549      }
1550      var args = data.args;
1551      data.firstArg = /^[^,]+/.exec(args)[0];
1552
1553      // create the function factory
1554      var factory = Function('baseCreateCallback, errorClass, errorProto, hasOwnProperty, ' + 'indicatorObject, isArguments, isArray, isString, keys, objectProto, ' + 'objectTypes, nonEnumProps, stringClass, stringProto, toString', 'return function(' + args + ') {\n' + iteratorTemplate(data) + '\n}');
1555      releaseObject(data);
1556
1557      // return the compiled function
1558      return factory(baseCreateCallback, errorClass, errorProto, hasOwnProperty, indicatorObject, isArguments, isArray, isString, data.keys, objectProto, objectTypes, nonEnumProps, stringClass, stringProto, toString);
1559    }
1560
1561    /**
1562     * Creates a new object with the specified `prototype`.
1563     *
1564     * @private
1565     * @param {Object} prototype The prototype object.
1566     * @returns {Object} Returns the new object.
1567     */
1568    function createObject(prototype) {
1569      return isObject(prototype) ? nativeCreate(prototype) : {};
1570    }
1571    // fallback for browsers without `Object.create`
1572    if (!nativeCreate) {
1573      createObject = function createObject(prototype) {
1574        if (isObject(prototype)) {
1575          noop.prototype = prototype;
1576          var result = new noop();
1577          noop.prototype = null;
1578        }
1579        return result || {};
1580      };
1581    }
1582
1583    /**
1584     * Used by `escape` to convert characters to HTML entities.
1585     *
1586     * @private
1587     * @param {string} match The matched character to escape.
1588     * @returns {string} Returns the escaped character.
1589     */
1590    function escapeHtmlChar(match) {
1591      return htmlEscapes[match];
1592    }
1593
1594    /**
1595     * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
1596     * customized, this method returns the custom method, otherwise it returns
1597     * the `baseIndexOf` function.
1598     *
1599     * @private
1600     * @returns {Function} Returns the "indexOf" function.
1601     */
1602    function getIndexOf() {
1603      var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
1604      return result;
1605    }
1606
1607    /**
1608     * Sets `this` binding data on a given function.
1609     *
1610     * @private
1611     * @param {Function} func The function to set data on.
1612     * @param {*} value The value to set.
1613     */
1614    var setBindData = !defineProperty ? noop : function (func, value) {
1615      var descriptor = getObject();
1616      descriptor.value = value;
1617      defineProperty(func, '__bindData__', descriptor);
1618      releaseObject(descriptor);
1619    };
1620
1621    /**
1622     * A fallback implementation of `isPlainObject` which checks if a given value
1623     * is an object created by the `Object` constructor, assuming objects created
1624     * by the `Object` constructor have no inherited enumerable properties and that
1625     * there are no `Object.prototype` extensions.
1626     *
1627     * @private
1628     * @param {*} value The value to check.
1629     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
1630     */
1631    function shimIsPlainObject(value) {
1632      var ctor, result;
1633
1634      // avoid non Object objects, `arguments` objects, and DOM elements
1635      if (!(value && toString.call(value) == objectClass) || (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor)) || !support.argsClass && isArguments(value) || !support.nodeClass && isNode(value)) {
1636        return false;
1637      }
1638      // IE < 9 iterates inherited properties before own properties. If the first
1639      // iterated property is an object's own property then there are no inherited
1640      // enumerable properties.
1641      if (support.ownLast) {
1642        forIn(value, function (value, key, object) {
1643          result = hasOwnProperty.call(object, key);
1644          return false;
1645        });
1646        return result !== false;
1647      }
1648      // In most environments an object's own properties are iterated before
1649      // its inherited properties. If the last iterated property is an object's
1650      // own property then there are no inherited enumerable properties.
1651      forIn(value, function (value, key) {
1652        result = key;
1653      });
1654      return typeof result == 'undefined' || hasOwnProperty.call(value, result);
1655    }
1656
1657    /**
1658     * Used by `unescape` to convert HTML entities to characters.
1659     *
1660     * @private
1661     * @param {string} match The matched character to unescape.
1662     * @returns {string} Returns the unescaped character.
1663     */
1664    function unescapeHtmlChar(match) {
1665      return htmlUnescapes[match];
1666    }
1667
1668    /*--------------------------------------------------------------------------*/
1669
1670    /**
1671     * Checks if `value` is an `arguments` object.
1672     *
1673     * @static
1674     * @memberOf _
1675     * @category Objects
1676     * @param {*} value The value to check.
1677     * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
1678     * @example
1679     *
1680     * (function() { return _.isArguments(arguments); })(1, 2, 3);
1681     * // => true
1682     *
1683     * _.isArguments([1, 2, 3]);
1684     * // => false
1685     */
1686    function isArguments(value) {
1687      return value && _typeof(value) == 'object' && typeof value.length == 'number' && toString.call(value) == argsClass || false;
1688    }
1689    // fallback for browsers that can't detect `arguments` objects by [[Class]]
1690    if (!support.argsClass) {
1691      isArguments = function isArguments(value) {
1692        return value && _typeof(value) == 'object' && typeof value.length == 'number' && hasOwnProperty.call(value, 'callee') || false;
1693      };
1694    }
1695
1696    /**
1697     * Checks if `value` is an array.
1698     *
1699     * @static
1700     * @memberOf _
1701     * @type Function
1702     * @category Objects
1703     * @param {*} value The value to check.
1704     * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
1705     * @example
1706     *
1707     * (function() { return _.isArray(arguments); })();
1708     * // => false
1709     *
1710     * _.isArray([1, 2, 3]);
1711     * // => true
1712     */
1713    var isArray = nativeIsArray || function (value) {
1714      return value && _typeof(value) == 'object' && typeof value.length == 'number' && toString.call(value) == arrayClass || false;
1715    };
1716
1717    /**
1718     * A fallback implementation of `Object.keys` which produces an array of the
1719     * given object's own enumerable property names.
1720     *
1721     * @private
1722     * @type Function
1723     * @param {Object} object The object to inspect.
1724     * @returns {Array} Returns an array of property names.
1725     */
1726    var shimKeys = createIterator({
1727      'args': 'object',
1728      'init': '[]',
1729      'top': 'if (!(objectTypes[typeof object])) return result',
1730      'loop': 'result.push(index)'
1731    });
1732
1733    /**
1734     * Creates an array composed of the own enumerable property names of an object.
1735     *
1736     * @static
1737     * @memberOf _
1738     * @category Objects
1739     * @param {Object} object The object to inspect.
1740     * @returns {Array} Returns an array of property names.
1741     * @example
1742     *
1743     * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
1744     * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
1745     */
1746    var keys = !nativeKeys ? shimKeys : function (object) {
1747      if (!isObject(object)) {
1748        return [];
1749      }
1750      if (support.enumPrototypes && typeof object == 'function' || support.nonEnumArgs && object.length && isArguments(object)) {
1751        return shimKeys(object);
1752      }
1753      return nativeKeys(object);
1754    };
1755
1756    /** Reusable iterator options shared by `each`, `forIn`, and `forOwn` */
1757    var eachIteratorOptions = {
1758      'args': 'collection, callback, thisArg',
1759      'top': "callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)",
1760      'array': "typeof length == 'number'",
1761      'keys': keys,
1762      'loop': 'if (callback(iterable[index], index, collection) === false) return result'
1763    };
1764
1765    /** Reusable iterator options for `assign` and `defaults` */
1766    var defaultsIteratorOptions = {
1767      'args': 'object, source, guard',
1768      'top': 'var args = arguments,\n' + '    argsIndex = 0,\n' + "    argsLength = typeof guard == 'number' ? 2 : args.length;\n" + 'while (++argsIndex < argsLength) {\n' + '  iterable = args[argsIndex];\n' + '  if (iterable && objectTypes[typeof iterable]) {',
1769      'keys': keys,
1770      'loop': "if (typeof result[index] == 'undefined') result[index] = iterable[index]",
1771      'bottom': '  }\n}'
1772    };
1773
1774    /** Reusable iterator options for `forIn` and `forOwn` */
1775    var forOwnIteratorOptions = {
1776      'top': 'if (!objectTypes[typeof iterable]) return result;\n' + eachIteratorOptions.top,
1777      'array': false
1778    };
1779
1780    /**
1781     * Used to convert characters to HTML entities:
1782     *
1783     * Though the `>` character is escaped for symmetry, characters like `>` and `/`
1784     * don't require escaping in HTML and have no special meaning unless they're part
1785     * of a tag or an unquoted attribute value.
1786     * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
1787     */
1788    var htmlEscapes = {
1789      '&': '&amp;',
1790      '<': '&lt;',
1791      '>': '&gt;',
1792      '"': '&quot;',
1793      "'": '&#39;'
1794    };
1795
1796    /** Used to convert HTML entities to characters */
1797    var htmlUnescapes = invert(htmlEscapes);
1798
1799    /** Used to match HTML entities and HTML characters */
1800    var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
1801      reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
1802
1803    /**
1804     * A function compiled to iterate `arguments` objects, arrays, objects, and
1805     * strings consistenly across environments, executing the callback for each
1806     * element in the collection. The callback is bound to `thisArg` and invoked
1807     * with three arguments; (value, index|key, collection). Callbacks may exit
1808     * iteration early by explicitly returning `false`.
1809     *
1810     * @private
1811     * @type Function
1812     * @param {Array|Object|string} collection The collection to iterate over.
1813     * @param {Function} [callback=identity] The function called per iteration.
1814     * @param {*} [thisArg] The `this` binding of `callback`.
1815     * @returns {Array|Object|string} Returns `collection`.
1816     */
1817    var baseEach = createIterator(eachIteratorOptions);
1818
1819    /*--------------------------------------------------------------------------*/
1820
1821    /**
1822     * Assigns own enumerable properties of source object(s) to the destination
1823     * object. Subsequent sources will overwrite property assignments of previous
1824     * sources. If a callback is provided it will be executed to produce the
1825     * assigned values. The callback is bound to `thisArg` and invoked with two
1826     * arguments; (objectValue, sourceValue).
1827     *
1828     * @static
1829     * @memberOf _
1830     * @type Function
1831     * @alias extend
1832     * @category Objects
1833     * @param {Object} object The destination object.
1834     * @param {...Object} [source] The source objects.
1835     * @param {Function} [callback] The function to customize assigning values.
1836     * @param {*} [thisArg] The `this` binding of `callback`.
1837     * @returns {Object} Returns the destination object.
1838     * @example
1839     *
1840     * _.assign({ 'name': 'moe' }, { 'age': 40 });
1841     * // => { 'name': 'moe', 'age': 40 }
1842     *
1843     * var defaults = _.partialRight(_.assign, function(a, b) {
1844     *   return typeof a == 'undefined' ? b : a;
1845     * });
1846     *
1847     * var food = { 'name': 'apple' };
1848     * defaults(food, { 'name': 'banana', 'type': 'fruit' });
1849     * // => { 'name': 'apple', 'type': 'fruit' }
1850     */
1851    var assign = createIterator(defaultsIteratorOptions, {
1852      'top': defaultsIteratorOptions.top.replace(';', ';\n' + "if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n" + '  var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n' + "} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n" + '  callback = args[--argsLength];\n' + '}'),
1853      'loop': 'result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]'
1854    });
1855
1856    /**
1857     * Creates a clone of `value`. If `deep` is `true` nested objects will also
1858     * be cloned, otherwise they will be assigned by reference. If a callback
1859     * is provided it will be executed to produce the cloned values. If the
1860     * callback returns `undefined` cloning will be handled by the method instead.
1861     * The callback is bound to `thisArg` and invoked with one argument; (value).
1862     *
1863     * @static
1864     * @memberOf _
1865     * @category Objects
1866     * @param {*} value The value to clone.
1867     * @param {boolean} [deep=false] Specify a deep clone.
1868     * @param {Function} [callback] The function to customize cloning values.
1869     * @param {*} [thisArg] The `this` binding of `callback`.
1870     * @returns {*} Returns the cloned `value`.
1871     * @example
1872     *
1873     * var stooges = [
1874     *   { 'name': 'moe', 'age': 40 },
1875     *   { 'name': 'larry', 'age': 50 }
1876     * ];
1877     *
1878     * var shallow = _.clone(stooges);
1879     * shallow[0] === stooges[0];
1880     * // => true
1881     *
1882     * var deep = _.clone(stooges, true);
1883     * deep[0] === stooges[0];
1884     * // => false
1885     *
1886     * _.mixin({
1887     *   'clone': _.partialRight(_.clone, function(value) {
1888     *     return _.isElement(value) ? value.cloneNode(false) : undefined;
1889     *   })
1890     * });
1891     *
1892     * var clone = _.clone(document.body);
1893     * clone.childNodes.length;
1894     * // => 0
1895     */
1896    function clone(value, deep, callback, thisArg) {
1897      // allows working with "Collections" methods without using their `index`
1898      // and `collection` arguments for `deep` and `callback`
1899      if (typeof deep != 'boolean' && deep != null) {
1900        thisArg = callback;
1901        callback = deep;
1902        deep = false;
1903      }
1904      return baseClone(value, deep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
1905    }
1906
1907    /**
1908     * Creates a deep clone of `value`. If a callback is provided it will be
1909     * executed to produce the cloned values. If the callback returns `undefined`
1910     * cloning will be handled by the method instead. The callback is bound to
1911     * `thisArg` and invoked with one argument; (value).
1912     *
1913     * Note: This method is loosely based on the structured clone algorithm. Functions
1914     * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
1915     * objects created by constructors other than `Object` are cloned to plain `Object` objects.
1916     * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
1917     *
1918     * @static
1919     * @memberOf _
1920     * @category Objects
1921     * @param {*} value The value to deep clone.
1922     * @param {Function} [callback] The function to customize cloning values.
1923     * @param {*} [thisArg] The `this` binding of `callback`.
1924     * @returns {*} Returns the deep cloned `value`.
1925     * @example
1926     *
1927     * var stooges = [
1928     *   { 'name': 'moe', 'age': 40 },
1929     *   { 'name': 'larry', 'age': 50 }
1930     * ];
1931     *
1932     * var deep = _.cloneDeep(stooges);
1933     * deep[0] === stooges[0];
1934     * // => false
1935     *
1936     * var view = {
1937     *   'label': 'docs',
1938     *   'node': element
1939     * };
1940     *
1941     * var clone = _.cloneDeep(view, function(value) {
1942     *   return _.isElement(value) ? value.cloneNode(true) : undefined;
1943     * });
1944     *
1945     * clone.node == view.node;
1946     * // => false
1947     */
1948    function cloneDeep(value, callback, thisArg) {
1949      return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
1950    }
1951
1952    /**
1953     * Assigns own enumerable properties of source object(s) to the destination
1954     * object for all destination properties that resolve to `undefined`. Once a
1955     * property is set, additional defaults of the same property will be ignored.
1956     *
1957     * @static
1958     * @memberOf _
1959     * @type Function
1960     * @category Objects
1961     * @param {Object} object The destination object.
1962     * @param {...Object} [source] The source objects.
1963     * @param- {Object} [guard] Allows working with `_.reduce` without using its
1964     *  `key` and `object` arguments as sources.
1965     * @returns {Object} Returns the destination object.
1966     * @example
1967     *
1968     * var food = { 'name': 'apple' };
1969     * _.defaults(food, { 'name': 'banana', 'type': 'fruit' });
1970     * // => { 'name': 'apple', 'type': 'fruit' }
1971     */
1972    var defaults = createIterator(defaultsIteratorOptions);
1973
1974    /**
1975     * This method is like `_.findIndex` except that it returns the key of the
1976     * first element that passes the callback check, instead of the element itself.
1977     *
1978     * @static
1979     * @memberOf _
1980     * @category Objects
1981     * @param {Object} object The object to search.
1982     * @param {Function|Object|string} [callback=identity] The function called per
1983     *  iteration. If a property name or object is provided it will be used to
1984     *  create a "_.pluck" or "_.where" style callback, respectively.
1985     * @param {*} [thisArg] The `this` binding of `callback`.
1986     * @returns {string|undefined} Returns the key of the found element, else `undefined`.
1987     * @example
1988     *
1989     * _.findKey({ 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, function(num) {
1990     *   return num % 2 == 0;
1991     * });
1992     * // => 'b' (property order is not guaranteed across environments)
1993     */
1994    function findKey(object, callback, thisArg) {
1995      var result;
1996      callback = lodash.createCallback(callback, thisArg, 3);
1997      forOwn(object, function (value, key, object) {
1998        if (callback(value, key, object)) {
1999          result = key;
2000          return false;
2001        }
2002      });
2003      return result;
2004    }
2005
2006    /**
2007     * This method is like `_.findKey` except that it iterates over elements
2008     * of a `collection` in the opposite order.
2009     *
2010     * @static
2011     * @memberOf _
2012     * @category Objects
2013     * @param {Object} object The object to search.
2014     * @param {Function|Object|string} [callback=identity] The function called per
2015     *  iteration. If a property name or object is provided it will be used to
2016     *  create a "_.pluck" or "_.where" style callback, respectively.
2017     * @param {*} [thisArg] The `this` binding of `callback`.
2018     * @returns {string|undefined} Returns the key of the found element, else `undefined`.
2019     * @example
2020     *
2021     * _.findLastKey({ 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, function(num) {
2022     *   return num % 2 == 1;
2023     * });
2024     * // => returns `c`, assuming `_.findKey` returns `a`
2025     */
2026    function findLastKey(object, callback, thisArg) {
2027      var result;
2028      callback = lodash.createCallback(callback, thisArg, 3);
2029      forOwnRight(object, function (value, key, object) {
2030        if (callback(value, key, object)) {
2031          result = key;
2032          return false;
2033        }
2034      });
2035      return result;
2036    }
2037
2038    /**
2039     * Iterates over own and inherited enumerable properties of an object,
2040     * executing the callback for each property. The callback is bound to `thisArg`
2041     * and invoked with three arguments; (value, key, object). Callbacks may exit
2042     * iteration early by explicitly returning `false`.
2043     *
2044     * @static
2045     * @memberOf _
2046     * @type Function
2047     * @category Objects
2048     * @param {Object} object The object to iterate over.
2049     * @param {Function} [callback=identity] The function called per iteration.
2050     * @param {*} [thisArg] The `this` binding of `callback`.
2051     * @returns {Object} Returns `object`.
2052     * @example
2053     *
2054     * function Dog(name) {
2055     *   this.name = name;
2056     * }
2057     *
2058     * Dog.prototype.bark = function() {
2059     *   console.log('Woof, woof!');
2060     * };
2061     *
2062     * _.forIn(new Dog('Dagny'), function(value, key) {
2063     *   console.log(key);
2064     * });
2065     * // => logs 'bark' and 'name' (property order is not guaranteed across environments)
2066     */
2067    var forIn = createIterator(eachIteratorOptions, forOwnIteratorOptions, {
2068      'useHas': false
2069    });
2070
2071    /**
2072     * This method is like `_.forIn` except that it iterates over elements
2073     * of a `collection` in the opposite order.
2074     *
2075     * @static
2076     * @memberOf _
2077     * @category Objects
2078     * @param {Object} object The object to iterate over.
2079     * @param {Function} [callback=identity] The function called per iteration.
2080     * @param {*} [thisArg] The `this` binding of `callback`.
2081     * @returns {Object} Returns `object`.
2082     * @example
2083     *
2084     * function Dog(name) {
2085     *   this.name = name;
2086     * }
2087     *
2088     * Dog.prototype.bark = function() {
2089     *   console.log('Woof, woof!');
2090     * };
2091     *
2092     * _.forInRight(new Dog('Dagny'), function(value, key) {
2093     *   console.log(key);
2094     * });
2095     * // => logs 'name' and 'bark' assuming `_.forIn ` logs 'bark' and 'name'
2096     */
2097    function forInRight(object, callback, thisArg) {
2098      var pairs = [];
2099      forIn(object, function (value, key) {
2100        pairs.push(key, value);
2101      });
2102      var length = pairs.length;
2103      callback = baseCreateCallback(callback, thisArg, 3);
2104      while (length--) {
2105        if (callback(pairs[length--], pairs[length], object) === false) {
2106          break;
2107        }
2108      }
2109      return object;
2110    }
2111
2112    /**
2113     * Iterates over own enumerable properties of an object, executing the callback
2114     * for each property. The callback is bound to `thisArg` and invoked with three
2115     * arguments; (value, key, object). Callbacks may exit iteration early by
2116     * explicitly returning `false`.
2117     *
2118     * @static
2119     * @memberOf _
2120     * @type Function
2121     * @category Objects
2122     * @param {Object} object The object to iterate over.
2123     * @param {Function} [callback=identity] The function called per iteration.
2124     * @param {*} [thisArg] The `this` binding of `callback`.
2125     * @returns {Object} Returns `object`.
2126     * @example
2127     *
2128     * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
2129     *   console.log(key);
2130     * });
2131     * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
2132     */
2133    var forOwn = createIterator(eachIteratorOptions, forOwnIteratorOptions);
2134
2135    /**
2136     * This method is like `_.forOwn` except that it iterates over elements
2137     * of a `collection` in the opposite order.
2138     *
2139     * @static
2140     * @memberOf _
2141     * @category Objects
2142     * @param {Object} object The object to iterate over.
2143     * @param {Function} [callback=identity] The function called per iteration.
2144     * @param {*} [thisArg] The `this` binding of `callback`.
2145     * @returns {Object} Returns `object`.
2146     * @example
2147     *
2148     * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
2149     *   console.log(key);
2150     * });
2151     * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
2152     */
2153    function forOwnRight(object, callback, thisArg) {
2154      var props = keys(object),
2155        length = props.length;
2156      callback = baseCreateCallback(callback, thisArg, 3);
2157      while (length--) {
2158        var key = props[length];
2159        if (callback(object[key], key, object) === false) {
2160          break;
2161        }
2162      }
2163      return object;
2164    }
2165
2166    /**
2167     * Creates a sorted array of property names of all enumerable properties,
2168     * own and inherited, of `object` that have function values.
2169     *
2170     * @static
2171     * @memberOf _
2172     * @alias methods
2173     * @category Objects
2174     * @param {Object} object The object to inspect.
2175     * @returns {Array} Returns an array of property names that have function values.
2176     * @example
2177     *
2178     * _.functions(_);
2179     * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
2180     */
2181    function functions(object) {
2182      var result = [];
2183      forIn(object, function (value, key) {
2184        if (isFunction(value)) {
2185          result.push(key);
2186        }
2187      });
2188      return result.sort();
2189    }
2190
2191    /**
2192     * Checks if the specified object `property` exists and is a direct property,
2193     * instead of an inherited property.
2194     *
2195     * @static
2196     * @memberOf _
2197     * @category Objects
2198     * @param {Object} object The object to check.
2199     * @param {string} property The property to check for.
2200     * @returns {boolean} Returns `true` if key is a direct property, else `false`.
2201     * @example
2202     *
2203     * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
2204     * // => true
2205     */
2206    function has(object, property) {
2207      return object ? hasOwnProperty.call(object, property) : false;
2208    }
2209
2210    /**
2211     * Creates an object composed of the inverted keys and values of the given object.
2212     *
2213     * @static
2214     * @memberOf _
2215     * @category Objects
2216     * @param {Object} object The object to invert.
2217     * @returns {Object} Returns the created inverted object.
2218     * @example
2219     *
2220     *  _.invert({ 'first': 'moe', 'second': 'larry' });
2221     * // => { 'moe': 'first', 'larry': 'second' }
2222     */
2223    function invert(object) {
2224      var index = -1,
2225        props = keys(object),
2226        length = props.length,
2227        result = {};
2228      while (++index < length) {
2229        var key = props[index];
2230        result[object[key]] = key;
2231      }
2232      return result;
2233    }
2234
2235    /**
2236     * Checks if `value` is a boolean value.
2237     *
2238     * @static
2239     * @memberOf _
2240     * @category Objects
2241     * @param {*} value The value to check.
2242     * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
2243     * @example
2244     *
2245     * _.isBoolean(null);
2246     * // => false
2247     */
2248    function isBoolean(value) {
2249      return value === true || value === false || toString.call(value) == boolClass;
2250    }
2251
2252    /**
2253     * Checks if `value` is a date.
2254     *
2255     * @static
2256     * @memberOf _
2257     * @category Objects
2258     * @param {*} value The value to check.
2259     * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
2260     * @example
2261     *
2262     * _.isDate(new Date);
2263     * // => true
2264     */
2265    function isDate(value) {
2266      return value ? _typeof(value) == 'object' && toString.call(value) == dateClass : false;
2267    }
2268
2269    /**
2270     * Checks if `value` is a DOM element.
2271     *
2272     * @static
2273     * @memberOf _
2274     * @category Objects
2275     * @param {*} value The value to check.
2276     * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
2277     * @example
2278     *
2279     * _.isElement(document.body);
2280     * // => true
2281     */
2282    function isElement(value) {
2283      return value ? value.nodeType === 1 : false;
2284    }
2285
2286    /**
2287     * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
2288     * length of `0` and objects with no own enumerable properties are considered
2289     * "empty".
2290     *
2291     * @static
2292     * @memberOf _
2293     * @category Objects
2294     * @param {Array|Object|string} value The value to inspect.
2295     * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
2296     * @example
2297     *
2298     * _.isEmpty([1, 2, 3]);
2299     * // => false
2300     *
2301     * _.isEmpty({});
2302     * // => true
2303     *
2304     * _.isEmpty('');
2305     * // => true
2306     */
2307    function isEmpty(value) {
2308      var result = true;
2309      if (!value) {
2310        return result;
2311      }
2312      var className = toString.call(value),
2313        length = value.length;
2314      if (className == arrayClass || className == stringClass || (support.argsClass ? className == argsClass : isArguments(value)) || className == objectClass && typeof length == 'number' && isFunction(value.splice)) {
2315        return !length;
2316      }
2317      forOwn(value, function () {
2318        return result = false;
2319      });
2320      return result;
2321    }
2322
2323    /**
2324     * Performs a deep comparison between two values to determine if they are
2325     * equivalent to each other. If a callback is provided it will be executed
2326     * to compare values. If the callback returns `undefined` comparisons will
2327     * be handled by the method instead. The callback is bound to `thisArg` and
2328     * invoked with two arguments; (a, b).
2329     *
2330     * @static
2331     * @memberOf _
2332     * @category Objects
2333     * @param {*} a The value to compare.
2334     * @param {*} b The other value to compare.
2335     * @param {Function} [callback] The function to customize comparing values.
2336     * @param {*} [thisArg] The `this` binding of `callback`.
2337     * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
2338     * @example
2339     *
2340     * var moe = { 'name': 'moe', 'age': 40 };
2341     * var copy = { 'name': 'moe', 'age': 40 };
2342     *
2343     * moe == copy;
2344     * // => false
2345     *
2346     * _.isEqual(moe, copy);
2347     * // => true
2348     *
2349     * var words = ['hello', 'goodbye'];
2350     * var otherWords = ['hi', 'goodbye'];
2351     *
2352     * _.isEqual(words, otherWords, function(a, b) {
2353     *   var reGreet = /^(?:hello|hi)$/i,
2354     *       aGreet = _.isString(a) && reGreet.test(a),
2355     *       bGreet = _.isString(b) && reGreet.test(b);
2356     *
2357     *   return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
2358     * });
2359     * // => true
2360     */
2361    function isEqual(a, b, callback, thisArg) {
2362      return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
2363    }
2364
2365    /**
2366     * Checks if `value` is, or can be coerced to, a finite number.
2367     *
2368     * Note: This is not the same as native `isFinite` which will return true for
2369     * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
2370     *
2371     * @static
2372     * @memberOf _
2373     * @category Objects
2374     * @param {*} value The value to check.
2375     * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
2376     * @example
2377     *
2378     * _.isFinite(-101);
2379     * // => true
2380     *
2381     * _.isFinite('10');
2382     * // => true
2383     *
2384     * _.isFinite(true);
2385     * // => false
2386     *
2387     * _.isFinite('');
2388     * // => false
2389     *
2390     * _.isFinite(Infinity);
2391     * // => false
2392     */
2393    function isFinite(value) {
2394      return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
2395    }
2396
2397    /**
2398     * Checks if `value` is a function.
2399     *
2400     * @static
2401     * @memberOf _
2402     * @category Objects
2403     * @param {*} value The value to check.
2404     * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
2405     * @example
2406     *
2407     * _.isFunction(_);
2408     * // => true
2409     */
2410    function isFunction(value) {
2411      return typeof value == 'function';
2412    }
2413    // fallback for older versions of Chrome and Safari
2414    if (isFunction(/x/)) {
2415      isFunction = function isFunction(value) {
2416        return typeof value == 'function' && toString.call(value) == funcClass;
2417      };
2418    }
2419
2420    /**
2421     * Checks if `value` is the language type of Object.
2422     * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
2423     *
2424     * @static
2425     * @memberOf _
2426     * @category Objects
2427     * @param {*} value The value to check.
2428     * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
2429     * @example
2430     *
2431     * _.isObject({});
2432     * // => true
2433     *
2434     * _.isObject([1, 2, 3]);
2435     * // => true
2436     *
2437     * _.isObject(1);
2438     * // => false
2439     */
2440    function isObject(value) {
2441      // check if the value is the ECMAScript language type of Object
2442      // http://es5.github.io/#x8
2443      // and avoid a V8 bug
2444      // http://code.google.com/p/v8/issues/detail?id=2291
2445      return !!(value && objectTypes[_typeof(value)]);
2446    }
2447
2448    /**
2449     * Checks if `value` is `NaN`.
2450     *
2451     * Note: This is not the same as native `isNaN` which will return `true` for
2452     * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
2453     *
2454     * @static
2455     * @memberOf _
2456     * @category Objects
2457     * @param {*} value The value to check.
2458     * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
2459     * @example
2460     *
2461     * _.isNaN(NaN);
2462     * // => true
2463     *
2464     * _.isNaN(new Number(NaN));
2465     * // => true
2466     *
2467     * isNaN(undefined);
2468     * // => true
2469     *
2470     * _.isNaN(undefined);
2471     * // => false
2472     */
2473    function isNaN(value) {
2474      // `NaN` as a primitive is the only value that is not equal to itself
2475      // (perform the [[Class]] check first to avoid errors with some host objects in IE)
2476      return isNumber(value) && value != +value;
2477    }
2478
2479    /**
2480     * Checks if `value` is `null`.
2481     *
2482     * @static
2483     * @memberOf _
2484     * @category Objects
2485     * @param {*} value The value to check.
2486     * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
2487     * @example
2488     *
2489     * _.isNull(null);
2490     * // => true
2491     *
2492     * _.isNull(undefined);
2493     * // => false
2494     */
2495    function isNull(value) {
2496      return value === null;
2497    }
2498
2499    /**
2500     * Checks if `value` is a number.
2501     *
2502     * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
2503     *
2504     * @static
2505     * @memberOf _
2506     * @category Objects
2507     * @param {*} value The value to check.
2508     * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
2509     * @example
2510     *
2511     * _.isNumber(8.4 * 5);
2512     * // => true
2513     */
2514    function isNumber(value) {
2515      return typeof value == 'number' || toString.call(value) == numberClass;
2516    }
2517
2518    /**
2519     * Checks if `value` is an object created by the `Object` constructor.
2520     *
2521     * @static
2522     * @memberOf _
2523     * @category Objects
2524     * @param {*} value The value to check.
2525     * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
2526     * @example
2527     *
2528     * function Stooge(name, age) {
2529     *   this.name = name;
2530     *   this.age = age;
2531     * }
2532     *
2533     * _.isPlainObject(new Stooge('moe', 40));
2534     * // => false
2535     *
2536     * _.isPlainObject([1, 2, 3]);
2537     * // => false
2538     *
2539     * _.isPlainObject({ 'name': 'moe', 'age': 40 });
2540     * // => true
2541     */
2542    var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function (value) {
2543      if (!(value && toString.call(value) == objectClass) || !support.argsClass && isArguments(value)) {
2544        return false;
2545      }
2546      var valueOf = value.valueOf,
2547        objProto = typeof valueOf == 'function' && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
2548      return objProto ? value == objProto || getPrototypeOf(value) == objProto : shimIsPlainObject(value);
2549    };
2550
2551    /**
2552     * Checks if `value` is a regular expression.
2553     *
2554     * @static
2555     * @memberOf _
2556     * @category Objects
2557     * @param {*} value The value to check.
2558     * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
2559     * @example
2560     *
2561     * _.isRegExp(/moe/);
2562     * // => true
2563     */
2564    function isRegExp(value) {
2565      return value && objectTypes[_typeof(value)] ? toString.call(value) == regexpClass : false;
2566    }
2567
2568    /**
2569     * Checks if `value` is a string.
2570     *
2571     * @static
2572     * @memberOf _
2573     * @category Objects
2574     * @param {*} value The value to check.
2575     * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
2576     * @example
2577     *
2578     * _.isString('moe');
2579     * // => true
2580     */
2581    function isString(value) {
2582      return typeof value == 'string' || toString.call(value) == stringClass;
2583    }
2584
2585    /**
2586     * Checks if `value` is `undefined`.
2587     *
2588     * @static
2589     * @memberOf _
2590     * @category Objects
2591     * @param {*} value The value to check.
2592     * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
2593     * @example
2594     *
2595     * _.isUndefined(void 0);
2596     * // => true
2597     */
2598    function isUndefined(value) {
2599      return typeof value == 'undefined';
2600    }
2601
2602    /**
2603     * Recursively merges own enumerable properties of the source object(s), that
2604     * don't resolve to `undefined` into the destination object. Subsequent sources
2605     * will overwrite property assignments of previous sources. If a callback is
2606     * provided it will be executed to produce the merged values of the destination
2607     * and source properties. If the callback returns `undefined` merging will
2608     * be handled by the method instead. The callback is bound to `thisArg` and
2609     * invoked with two arguments; (objectValue, sourceValue).
2610     *
2611     * @static
2612     * @memberOf _
2613     * @category Objects
2614     * @param {Object} object The destination object.
2615     * @param {...Object} [source] The source objects.
2616     * @param {Function} [callback] The function to customize merging properties.
2617     * @param {*} [thisArg] The `this` binding of `callback`.
2618     * @returns {Object} Returns the destination object.
2619     * @example
2620     *
2621     * var names = {
2622     *   'stooges': [
2623     *     { 'name': 'moe' },
2624     *     { 'name': 'larry' }
2625     *   ]
2626     * };
2627     *
2628     * var ages = {
2629     *   'stooges': [
2630     *     { 'age': 40 },
2631     *     { 'age': 50 }
2632     *   ]
2633     * };
2634     *
2635     * _.merge(names, ages);
2636     * // => { 'stooges': [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] }
2637     *
2638     * var food = {
2639     *   'fruits': ['apple'],
2640     *   'vegetables': ['beet']
2641     * };
2642     *
2643     * var otherFood = {
2644     *   'fruits': ['banana'],
2645     *   'vegetables': ['carrot']
2646     * };
2647     *
2648     * _.merge(food, otherFood, function(a, b) {
2649     *   return _.isArray(a) ? a.concat(b) : undefined;
2650     * });
2651     * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
2652     */
2653    function merge(object) {
2654      var args = arguments,
2655        length = 2;
2656      if (!isObject(object)) {
2657        return object;
2658      }
2659      // allows working with `_.reduce` and `_.reduceRight` without using
2660      // their `index` and `collection` arguments
2661      if (typeof args[2] != 'number') {
2662        length = args.length;
2663      }
2664      if (length > 3 && typeof args[length - 2] == 'function') {
2665        var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
2666      } else if (length > 2 && typeof args[length - 1] == 'function') {
2667        callback = args[--length];
2668      }
2669      var sources = nativeSlice.call(arguments, 1, length),
2670        index = -1,
2671        stackA = getArray(),
2672        stackB = getArray();
2673      while (++index < length) {
2674        baseMerge(object, sources[index], callback, stackA, stackB);
2675      }
2676      releaseArray(stackA);
2677      releaseArray(stackB);
2678      return object;
2679    }
2680
2681    /**
2682     * Creates a shallow clone of `object` excluding the specified properties.
2683     * Property names may be specified as individual arguments or as arrays of
2684     * property names. If a callback is provided it will be executed for each
2685     * property of `object` omitting the properties the callback returns truey
2686     * for. The callback is bound to `thisArg` and invoked with three arguments;
2687     * (value, key, object).
2688     *
2689     * @static
2690     * @memberOf _
2691     * @category Objects
2692     * @param {Object} object The source object.
2693     * @param {Function|...string|string[]}
2693 [callback] The properties to omit or the
2694     *  function called per iteration.
2695     * @param {*} [thisArg] The `this` binding of `callback`.
2696     * @returns {Object} Returns an object without the omitted properties.
2697     * @example
2698     *
2699     * _.omit({ 'name': 'moe', 'age': 40 }, 'age');
2700     * // => { 'name': 'moe' }
2701     *
2702     * _.omit({ 'name': 'moe', 'age': 40 }, function(value) {
2703     *   return typeof value == 'number';
2704     * });
2705     * // => { 'name': 'moe' }
2706     */
2707    function omit(object, callback, thisArg) {
2708      var indexOf = getIndexOf(),
2709        isFunc = typeof callback == 'function',
2710        result = {};
2711      if (isFunc) {
2712        callback = lodash.createCallback(callback, thisArg, 3);
2713      } else {
2714        var props = baseFlatten(arguments, true, false, 1);
2715      }
2716      forIn(object, function (value, key, object) {
2717        if (isFunc ? !callback(value, key, object) : indexOf(props, key) < 0) {
2718          result[key] = value;
2719        }
2720      });
2721      return result;
2722    }
2723
2724    /**
2725     * Creates a two dimensional array of an object's key-value pairs,
2726     * i.e. `[[key1, value1], [key2, value2]]`.
2727     *
2728     * @static
2729     * @memberOf _
2730     * @category Objects
2731     * @param {Object} object The object to inspect.
2732     * @returns {Array} Returns new array of key-value pairs.
2733     * @example
2734     *
2735     * _.pairs({ 'moe': 30, 'larry': 40 });
2736     * // => [['moe', 30], ['larry', 40]] (property order is not guaranteed across environments)
2737     */
2738    function pairs(object) {
2739      var index = -1,
2740        props = keys(object),
2741        length = props.length,
2742        result = Array(length);
2743      while (++index < length) {
2744        var key = props[index];
2745        result[index] = [key, object[key]];
2746      }
2747      return result;
2748    }
2749
2750    /**
2751     * Creates a shallow clone of `object` composed of the specified properties.
2752     * Property names may be specified as individual arguments or as arrays of
2753     * property names. If a callback is provided it will be executed for each
2754     * property of `object` picking the properties the callback returns truey
2755     * for. The callback is bound to `thisArg` and invoked with three arguments;
2756     * (value, key, object).
2757     *
2758     * @static
2759     * @memberOf _
2760     * @category Objects
2761     * @param {Object} object The source object.
2762     * @param {Function|...string|string[]} [callback] The function called per
2763     *  iteration or property names to pick, specified as individual property
2764     *  names or arrays of property names.
2765     * @param {*} [thisArg] The `this` binding of `callback`.
2766     * @returns {Object}
2766 Returns an object composed of the picked properties.
2767     * @example
2768     *
2769     * _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name');
2770     * // => { 'name': 'moe' }
2771     *
2772     * _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) {
2773     *   return key.charAt(0) != '_';
2774     * });
2775     * // => { 'name': 'moe' }
2776     */
2777    function pick(object, callback, thisArg) {
2778      var result = {};
2779      if (typeof callback != 'function') {
2780        var index = -1,
2781          props = baseFlatten(arguments, true, false, 1),
2782          length = isObject(object) ? props.length : 0;
2783        while (++index < length) {
2784          var key = props[index];
2785          if (key in object) {
2786            result[key] = object[key];
2787          }
2788        }
2789      } else {
2790        callback = lodash.createCallback(callback, thisArg, 3);
2791        forIn(object, function (value, key, object) {
2792          if (callback(value, key, object)) {
2793            result[key] = value;
2794          }
2795        });
2796      }
2797      return result;
2798    }
2799
2800    /**
2801     * An alternative to `_.reduce` this method transforms `object` to a new
2802     * `accumulator` object which is the result of running each of its elements
2803     * through a callback, with each callback execution potentially mutating
2804     * the `accumulator` object. The callback is bound to `thisArg` and invoked
2805     * with four arguments; (accumulator, value, key, object). Callbacks may exit
2806     * iteration early by explicitly returning `false`.
2807     *
2808     * @static
2809     * @memberOf _
2810     * @category Objects
2811     * @param {Array|Object} collection The collection to iterate over.
2812     * @param {Function} [callback=identity] The function called per iteration.
2813     * @param {*} [accumulator] The custom accumulator value.
2814     * @param {*} [thisArg] The `this` binding of `callback`.
2815     * @returns {*} Returns the accumulated value.
2816     * @example
2817     *
2818     * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
2819     *   num *= num;
2820     *   if (num % 2) {
2821     *     return result.push(num) < 3;
2822     *   }
2823     * });
2824     * // => [1, 9, 25]
2825     *
2826     * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
2827     *   result[key] = num * 3;
2828     * });
2829     * // => { 'a': 3, 'b': 6, 'c': 9 }
2830     */
2831    function transform(object, callback, accumulator, thisArg) {
2832      var isArr = isArray(object);
2833      callback = baseCreateCallback(callback, thisArg, 4);
2834      if (accumulator == null) {
2835        if (isArr) {
2836          accumulator = [];
2837        } else {
2838          var ctor = object && object.constructor,
2839            proto = ctor && ctor.prototype;
2840          accumulator = createObject(proto);
2841        }
2842      }
2843      (isArr ? baseEach : forOwn)(object, function (value, index, object) {
2844        return callback(accumulator, value, index, object);
2845      });
2846      return accumulator;
2847    }
2848
2849    /**
2850     * Creates an array composed of the own enumerable property values of `object`.
2851     *
2852     * @static
2853     * @memberOf _
2854     * @category Objects
2855     * @param {Object} object The object to inspect.
2856     * @returns {Array} Returns an array of property values.
2857     * @example
2858     *
2859     * _.values({ 'one': 1, 'two': 2, 'three': 3 });
2860     * // => [1, 2, 3] (property order is not guaranteed across environments)
2861     */
2862    function values(object) {
2863      var index = -1,
2864        props = keys(object),
2865        length = props.length,
2866        result = Array(length);
2867      while (++index < length) {
2868        result[index] = object[props[index]];
2869      }
2870      return result;
2871    }
2872
2873    /*--------------------------------------------------------------------------*/
2874
2875    /**
2876     * Creates an array of elements from the specified indexes, or keys, of the
2877     * `collection`. Indexes may be specified as individual arguments or as arrays
2878     * of indexes.
2879     *
2880     * @static
2881     * @memberOf _
2882     * @category Collections
2883     * @param {Array|Object|string} collection The collection to iterate over.
2884     * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
2885     *   to retrieve, specified as individual indexes or arrays of indexes.
2886     * @returns {Array} Returns a new array of elements corresponding to the
2887     *  provided indexes.
2888     * @example
2889     *
2890     * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
2891     * // => ['a', 'c', 'e']
2892     *
2893     * _.at(['moe', 'larry', 'curly'], 0, 2);
2894     * // => ['moe', 'curly']
2895     */
2896    function at(collection) {
2897      var args = arguments,
2898        index = -1,
2899        props = baseFlatten(args, true, false, 1),
2900        length = args[2] && args[2][args[1]] === collection ? 1 : props.length,
2901        result = Array(length);
2902      if (support.unindexedChars && isString(collection)) {
2903        collection = collection.split('');
2904      }
2905      while (++index < length) {
2906        result[index] = collection[props[index]];
2907      }
2908      return result;
2909    }
2910
2911    /**
2912     * Checks if a given value is present in a collection using strict equality
2913     * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
2914     * offset from the end of the collection.
2915     *
2916     * @static
2917     * @memberOf _
2918     * @alias include
2919     * @category Collections
2920     * @param {Array|Object|string} collection The collection to iterate over.
2921     * @param {*} target The value to check for.
2922     * @param {number} [fromIndex=0] The index to search from.
2923     * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
2924     * @example
2925     *
2926     * _.contains([1, 2, 3], 1);
2927     * // => true
2928     *
2929     * _.contains([1, 2, 3], 1, 2);
2930     * // => false
2931     *
2932     * _.contains({ 'name': 'moe', 'age': 40 }, 'moe');
2933     * // => true
2934     *
2935     * _.contains('curly', 'ur');
2936     * // => true
2937     */
2938    function contains(collection, target, fromIndex) {
2939      var index = -1,
2940        indexOf = getIndexOf(),
2941        length = collection ? collection.length : 0,
2942        result = false;
2943      fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
2944      if (isArray(collection)) {
2945        result = indexOf(collection, target, fromIndex) > -1;
2946      } else if (typeof length == 'number') {
2947        result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1;
2948      } else {
2949        baseEach(collection, function (value) {
2950          if (++index >= fromIndex) {
2951            return !(result = value === target);
2952          }
2953        });
2954      }
2955      return result;
2956    }
2957
2958    /**
2959     * Creates an object composed of keys generated from the results of running
2960     * each element of `collection` through the callback. The corresponding value
2961     * of each key is the number of times the key was returned by the callback.
2962     * The callback is bound to `thisArg` and invoked with three arguments;
2963     * (value, index|key, collection).
2964     *
2965     * If a property name is provided for `callback` the created "_.pluck" style
2966     * callback will return the property value of the given element.
2967     *
2968     * If an object is provided for `callback` the created "_.where" style callback
2969     * will return `true` for elements that have the properties of the given object,
2970     * else `false`.
2971     *
2972     * @static
2973     * @memberOf _
2974     * @category Collections
2975     * @param {Array|Object|string} collection The collection to iterate over.
2976     * @param {Function|Object|string} [callback=identity] The function called
2977     *  per iteration. If a property name or object is provided it will be used
2978     *  to create a "_.pluck" or "_.where" style callback, respectively.
2979     * @param {*} [thisArg] The `this` binding of `callback`.
2980     * @returns {Object} Returns the composed aggregate object.
2981     * @example
2982     *
2983     * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
2984     * // => { '4': 1, '6': 2 }
2985     *
2986     * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
2987     * // => { '4': 1, '6': 2 }
2988     *
2989     * _.countBy(['one', 'two', 'three'], 'length');
2990     * // => { '3': 2, '5': 1 }
2991     */
2992    var countBy = createAggregator(function (result, value, key) {
2993      hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1;
2994    });
2995
2996    /**
2997     * Checks if the given callback returns truey value for **all** elements of
2998     * a collection. The callback is bound to `thisArg` and invoked with three
2999     * arguments; (value, index|key, collection).
3000     *
3001     * If a property name is provided for `callback` the created "_.pluck" style
3002     * callback will return the property value of the given element.
3003     *
3004     * If an object is provided for `callback` the created "_.where" style callback
3005     * will return `true` for elements that have the properties of the given object,
3006     * else `false`.
3007     *
3008     * @static
3009     * @memberOf _
3010     * @alias all
3011     * @category Collections
3012     * @param {Array|Object|string} collection The collection to iterate over.
3013     * @param {Function|Object|string} [callback=identity] The function called
3014     *  per iteration. If a property name or object is provided it will be used
3015     *  to create a "_.pluck" or "_.where" style callback, respectively.
3016     * @param {*} [thisArg] The `this` binding of `callback`.
3017     * @returns {boolean} Returns `true` if all elements passed the callback check,
3018     *  else `false`.
3019     * @example
3020     *
3021     * _.every([true, 1, null, 'yes'], Boolean);
3022     * // => false
3023     *
3024     * var stooges = [
3025     *   { 'name': 'moe', 'age': 40 },
3026     *   { 'name': 'larry', 'age': 50 }
3027     * ];
3028     *
3029     * // using "_.pluck" callback shorthand
3030     * _.every(stooges, 'age');
3031     * // => true
3032     *
3033     * // using "_.where" callback shorthand
3034     * _.every(stooges, { 'age': 50 });
3035     * // => false
3036     */
3037    function every(collection, callback, thisArg) {
3038      var result = true;
3039      callback = lodash.createCallback(callback, thisArg, 3);
3040      if (isArray(collection)) {
3041        var index = -1,
3042          length = collection.length;
3043        while (++index < length) {
3044          if (!(result = !!callback(collection[index], index, collection))) {
3045            break;
3046          }
3047        }
3048      } else {
3049        baseEach(collection, function (value, index, collection) {
3050          return result = !!callback(value, index, collection);
3051        });
3052      }
3053      return result;
3054    }
3055
3056    /**
3057     * Iterates over elements of a collection, returning an array of all elements
3058     * the callback returns truey for. The callback is bound to `thisArg` and
3059     * invoked with three arguments; (value, index|key, collection).
3060     *
3061     * If a property name is provided for `callback` the created "_.pluck" style
3062     * callback will return the property value of the given element.
3063     *
3064     * If an object is provided for `callback` the created "_.where" style callback
3065     * will return `true` for elements that have the properties of the given object,
3066     * else `false`.
3067     *
3068     * @static
3069     * @memberOf _
3070     * @alias select
3071     * @category Collections
3072     * @param {Array|Object|string} collection The collection to iterate over.
3073     * @param {Function|Object|string} [callback=identity] The function called
3074     *  per iteration. If a property name or object is provided it will be used
3075     *  to create a "_.pluck" or "_.where" style callback, respectively.
3076     * @param {*} [thisArg] The `this` binding of `callback`.
3077     * @returns {Array} Returns a new array of elements that passed the callback check.
3078     * @example
3079     *
3080     * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
3081     * // => [2, 4, 6]
3082     *
3083     * var food = [
3084     *   { 'name': 'apple',  'organic': false, 'type': 'fruit' },
3085     *   { 'name': 'carrot', 'organic': true,  'type': 'vegetable' }
3086     * ];
3087     *
3088     * // using "_.pluck" callback shorthand
3089     * _.filter(food, 'organic');
3090     * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
3091     *
3092     * // using "_.where" callback shorthand
3093     * _.filter(food, { 'type': 'fruit' });
3094     * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
3095     */
3096    function filter(collection, callback, thisArg) {
3097      var result = [];
3098      callback = lodash.createCallback(callback, thisArg, 3);
3099      if (isArray(collection)) {
3100        var index = -1,
3101          length = collection.length;
3102        while (++index < length) {
3103          var value = collection[index];
3104          if (callback(value, index, collection)) {
3105            result.push(value);
3106          }
3107        }
3108      } else {
3109        baseEach(collection, function (value, index, collection) {
3110          if (callback(value, index, collection)) {
3111            result.push(value);
3112          }
3113        });
3114      }
3115      return result;
3116    }
3117
3118    /**
3119     * Iterates over elements of a collection, returning the first element that
3120     * the callback returns truey for. The callback is bound to `thisArg` and
3121     * invoked with three arguments; (value, index|key, collection).
3122     *
3123     * If a property name is provided for `callback` the created "_.pluck" style
3124     * callback will return the property value of the given element.
3125     *
3126     * If an object is provided for `callback` the created "_.where" style callback
3127     * will return `true` for elements that have the properties of the given object,
3128     * else `false`.
3129     *
3130     * @static
3131     * @memberOf _
3132     * @alias detect, findWhere
3133     * @category Collections
3134     * @param {Array|Object|string} collection The collection to iterate over.
3135     * @param {Function|Object|string} [callback=identity] The function called
3136     *  per iteration. If a property name or object is provided it will be used
3137     *  to create a "_.pluck" or "_.where" style callback, respectively.
3138     * @param {*} [thisArg] The `this` binding of `callback`.
3139     * @returns {*} Returns the found element, else `undefined`.
3140     * @example
3141     *
3142     * _.find([1, 2, 3, 4], function(num) {
3143     *   return num % 2 == 0;
3144     * });
3145     * // => 2
3146     *
3147     * var food = [
3148     *   { 'name': 'apple',  'organic': false, 'type': 'fruit' },
3149     *   { 'name': 'banana', 'organic': true,  'type': 'fruit' },
3150     *   { 'name': 'beet',   'organic': false, 'type': 'vegetable' }
3151     * ];
3152     *
3153     * // using "_.where" callback shorthand
3154     * _.find(food, { 'type': 'vegetable' });
3155     * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
3156     *
3157     * // using "_.pluck" callback shorthand
3158     * _.find(food, 'organic');
3159     * // => { 'name': 'banana', 'organic': true, 'type': 'fruit' }
3160     */
3161    function find(collection, callback, thisArg) {
3162      callback = lodash.createCallback(callback, thisArg, 3);
3163      if (isArray(collection)) {
3164        var index = -1,
3165          length = collection.length;
3166        while (++index < length) {
3167          var value = collection[index];
3168          if (callback(value, index, collection)) {
3169            return value;
3170          }
3171        }
3172      } else {
3173        var result;
3174        baseEach(collection, function (value, index, collection) {
3175          if (callback(value, index, collection)) {
3176            result = value;
3177            return false;
3178          }
3179        });
3180        return result;
3181      }
3182    }
3183
3184    /**
3185     * This method is like `_.find` except that it iterates over elements
3186     * of a `collection` from right to left.
3187     *
3188     * @static
3189     * @memberOf _
3190     * @category Collections
3191     * @param {Array|Object|string} collection The collection to iterate over.
3192     * @param {Function|Object|string} [callback=identity] The function called
3193     *  per iteration. If a property name or object is provided it will be used
3194     *  to create a "_.pluck" or "_.where" style callback, respectively.
3195     * @param {*} [thisArg] The `this` binding of `callback`.
3196     * @returns {*} Returns the found element, else `undefined`.
3197     * @example
3198     *
3199     * _.findLast([1, 2, 3, 4], function(num) {
3200     *   return num % 2 == 1;
3201     * });
3202     * // => 3
3203     */
3204    function findLast(collection, callback, thisArg) {
3205      var result;
3206      callback = lodash.createCallback(callback, thisArg, 3);
3207      forEachRight(collection, function (value, index, collection) {
3208        if (callback(value, index, collection)) {
3209          result = value;
3210          return false;
3211        }
3212      });
3213      return result;
3214    }
3215
3216    /**
3217     * Iterates over elements of a collection, executing the callback for each
3218     * element. The callback is bound to `thisArg` and invoked with three arguments;
3219     * (value, index|key, collection). Callbacks may exit iteration early by
3220     * explicitly returning `false`.
3221     *
3222     * @static
3223     * @memberOf _
3224     * @alias each
3225     * @category Collections
3226     * @param {Array|Object|string} collection The collection to iterate over.
3227     * @param {Function} [callback=identity] The function called per iteration.
3228     * @param {*} [thisArg] The `this` binding of `callback`.
3229     * @returns {Array|Object|string} Returns `collection`.
3230     * @example
3231     *
3232     * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
3233     * // => logs each number and returns '1,2,3'
3234     *
3235     * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
3236     * // => logs each number and returns the object (property order is not guaranteed across environments)
3237     */
3238    function forEach(collection, callback, thisArg) {
3239      if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
3240        var index = -1,
3241          length = collection.length;
3242        while (++index < length) {
3243          if (callback(collection[index], index, collection) === false) {
3244            break;
3245          }
3246        }
3247      } else {
3248        baseEach(collection, callback, thisArg);
3249      }
3250      return collection;
3251    }
3252
3253    /**
3254     * This method is like `_.forEach` except that it iterates over elements
3255     * of a `collection` from right to left.
3256     *
3257     * @static
3258     * @memberOf _
3259     * @alias eachRight
3260     * @category Collections
3261     * @param {Array|Object|string} collection The collection to iterate over.
3262     * @param {Function} [callback=identity] The function called per iteration.
3263     * @param {*} [thisArg] The `this` binding of `callback`.
3264     * @returns {Array|Object|string} Returns `collection`.
3265     * @example
3266     *
3267     * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
3268     * // => logs each number from right to left and returns '3,2,1'
3269     */
3270    function forEachRight(collection, callback, thisArg) {
3271      var iterable = collection,
3272        length = collection ? collection.length : 0;
3273      callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
3274      if (isArray(collection)) {
3275        while (length--) {
3276          if (callback(collection[length], length, collection) === false) {
3277            break;
3278          }
3279        }
3280      } else {
3281        if (typeof length != 'number') {
3282          var props = keys(collection);
3283          length = props.length;
3284        } else if (support.unindexedChars && isString(collection)) {
3285          iterable = collection.split('');
3286        }
3287        baseEach(collection, function (value, key, collection) {
3288          key = props ? props[--length] : --length;
3289          return callback(iterable[key], key, collection);
3290        });
3291      }
3292      return collection;
3293    }
3294
3295    /**
3296     * Creates an object composed of keys generated from the results of running
3297     * each element of a collection through the callback. The corresponding value
3298     * of each key is an array of the elements responsible for generating the key.
3299     * The callback is bound to `thisArg` and invoked with three arguments;
3300     * (value, index|key, collection).
3301     *
3302     * If a property name is provided for `callback` the created "_.pluck" style
3303     * callback will return the property value of the given element.
3304     *
3305     * If an object is provided for `callback` the created "_.where" style callback
3306     * will return `true` for elements that have the properties of the given object,
3307     * else `false`
3308     *
3309     * @static
3310     * @memberOf _
3311     * @category Collections
3312     * @param {Array|Object|string} collection The collection to iterate over.
3313     * @param {Function|Object|string} [callback=identity] The function called
3314     *  per iteration. If a property name or object is provided it will be used
3315     *  to create a "_.pluck" or "_.where" style callback, respectively.
3316     * @param {*} [thisArg] The `this` binding of `callback`.
3317     * @returns {Object} Returns the composed aggregate object.
3318     * @example
3319     *
3320     * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
3321     * // => { '4': [4.2], '6': [6.1, 6.4] }
3322     *
3323     * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
3324     * // => { '4': [4.2], '6': [6.1, 6.4] }
3325     *
3326     * // using "_.pluck" callback shorthand
3327     * _.groupBy(['one', 'two', 'three'], 'length');
3328     * // => { '3': ['one', 'two'], '5': ['three'] }
3329     */
3330    var groupBy = createAggregator(function (result, value, key) {
3331      (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
3332    });
3333
3334    /**
3335     * Creates an object composed of keys generated from the results of running
3336     * each element of the collection through the given callback. The corresponding
3337     * value of each key is the last element responsible for generating the key.
3338     * The callback is bound to `thisArg` and invoked with three arguments;
3339     * (value, index|key, collection).
3340     *
3341     * If a property name is provided for `callback` the created "_.pluck" style
3342     * callback will return the property value of the given element.
3343     *
3344     * If an object is provided for `callback` the created "_.where" style callback
3345     * will return `true` for elements that have the properties of the given object,
3346     * else `false`.
3347     *
3348     * @static
3349     * @memberOf _
3350     * @category Collections
3351     * @param {Array|Object|string} collection The collection to iterate over.
3352     * @param {Function|Object|string} [callback=identity] The function called
3353     *  per iteration. If a property name or object is provided it will be used
3354     *  to create a "_.pluck" or "_.where" style callback, respectively.
3355     * @param {*} [thisArg] The `this` binding of `callback`.
3356     * @returns {Object} Returns the composed aggregate object.
3357     * @example
3358     *
3359     * var keys = [
3360     *   { 'dir': 'left', 'code': 97 },
3361     *   { 'dir': 'right', 'code': 100 }
3362     * ];
3363     *
3364     * _.indexBy(keys, 'dir');
3365     * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
3366     *
3367     * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
3368     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
3369     *
3370     * _.indexBy(stooges, function(key) { this.fromCharCode(key.code); }, String);
3371     * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
3372     */
3373    var indexBy = createAggregator(function (result, value, key) {
3374      result[key] = value;
3375    });
3376
3377    /**
3378     * Invokes the method named by `methodName` on each element in the `collection`
3379     * returning an array of the results of each invoked method. Additional arguments
3380     * will be provided to each invoked method. If `methodName` is a function it
3381     * will be invoked for, and `this` bound to, each element in the `collection`.
3382     *
3383     * @static
3384     * @memberOf _
3385     * @category Collections
3386     * @param {Array|Object|string} collection The collection to iterate over.
3387     * @param {Function|string} methodName The name of the method to invoke or
3388     *  the function invoked per iteration.
3389     * @param {...*} [arg] Arguments to invoke the method with.
3390     * @returns {Array} Returns a new array of the results of each invoked method.
3391     * @example
3392     *
3393     * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
3394     * // => [[1, 5, 7], [1, 2, 3]]
3395     *
3396     * _.invoke([123, 456], String.prototype.split, '');
3397     * // => [['1', '2', '3'], ['4', '5', '6']]
3398     */
3399    function invoke(collection, methodName) {
3400      var args = nativeSlice.call(arguments, 2),
3401        index = -1,
3402        isFunc = typeof methodName == 'function',
3403        length = collection ? collection.length : 0,
3404        result = Array(typeof length == 'number' ? length : 0);
3405      forEach(collection, function (value) {
3406        result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
3407      });
3408      return result;
3409    }
3410
3411    /**
3412     * Creates an array of values by running each element in the collection
3413     * through the callback. The callback is bound to `thisArg` and invoked with
3414     * three arguments; (value, index|key, collection).
3415     *
3416     * If a property name is provided for `callback` the created "_.pluck" style
3417     * callback will return the property value of the given element.
3418     *
3419     * If an object is provided for `callback` the created "_.where" style callback
3420     * will return `true` for elements that have the properties of the given object,
3421     * else `false`.
3422     *
3423     * @static
3424     * @memberOf _
3425     * @alias collect
3426     * @category Collections
3427     * @param {Array|Object|string} collection The collection to iterate over.
3428     * @param {Function|Object|string} [callback=identity] The function called
3429     *  per iteration. If a property name or object is provided it will be used
3430     *  to create a "_.pluck" or "_.where" style callback, respectively.
3431     * @param {*} [thisArg] The `this` binding of `callback`.
3432     * @returns {Array} Returns a new array of the results of each `callback` execution.
3433     * @example
3434     *
3435     * _.map([1, 2, 3], function(num) { return num * 3; });
3436     * // => [3, 6, 9]
3437     *
3438     * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
3439     * // => [3, 6, 9] (property order is not guaranteed across environments)
3440     *
3441     * var stooges = [
3442     *   { 'name': 'moe', 'age': 40 },
3443     *   { 'name': 'larry', 'age': 50 }
3444     * ];
3445     *
3446     * // using "_.pluck" callback shorthand
3447     * _.map(stooges, 'name');
3448     * // => ['moe', 'larry']
3449     */
3450    function map(collection, callback, thisArg) {
3451      var index = -1,
3452        length = collection ? collection.length : 0,
3453        result = Array(typeof length == 'number' ? length : 0);
3454      callback = lodash.createCallback(callback, thisArg, 3);
3455      if (isArray(collection)) {
3456        while (++index < length) {
3457          result[index] = callback(collection[index], index, collection);
3458        }
3459      } else {
3460        baseEach(collection, function (value, key, collection) {
3461          result[++index] = callback(value, key, collection);
3462        });
3463      }
3464      return result;
3465    }
3466
3467    /**
3468     * Retrieves the maximum value of a collection. If the collection is empty or
3469     * falsey `-Infinity` is returned. If a callback is provided it will be executed
3470     * for each value in the collection to generate the criterion by which the value
3471     * is ranked. The callback is bound to `thisArg` and invoked with three
3472     * arguments; (value, index, collection).
3473     *
3474     * If a property name is provided for `callback` the created "_.pluck" style
3475     * callback will return the property value of the given element.
3476     *
3477     * If an object is provided for `callback` the created "_.where" style callback
3478     * will return `true` for elements that have the properties of the given object,
3479     * else `false`.
3480     *
3481     * @static
3482     * @memberOf _
3483     * @category Collections
3484     * @param {Array|Object|string} collection The collection to iterate over.
3485     * @param {Function|Object|string} [callback=identity] The function called
3486     *  per iteration. If a property name or object is provided it will be used
3487     *  to create a "_.pluck" or "_.where" style callback, respectively.
3488     * @param {*} [thisArg] The `this` binding of `callback`.
3489     * @returns {*} Returns the maximum value.
3490     * @example
3491     *
3492     * _.max([4, 2, 8, 6]);
3493     * // => 8
3494     *
3495     * var stooges = [
3496     *   { 'name': 'moe', 'age': 40 },
3497     *   { 'name': 'larry', 'age': 50 }
3498     * ];
3499     *
3500     * _.max(stooges, function(stooge) { return stooge.age; });
3501     * // => { 'name': 'larry', 'age': 50 };
3502     *
3503     * // using "_.pluck" callback shorthand
3504     * _.max(stooges, 'age');
3505     * // => { 'name': 'larry', 'age': 50 };
3506     */
3507    function max(collection, callback, thisArg) {
3508      var computed = -Infinity,
3509        result = computed;
3510      if (!callback && isArray(collection)) {
3511        var index = -1,
3512          length = collection.length;
3513        while (++index < length) {
3514          var value = collection[index];
3515          if (value > result) {
3516            result = value;
3517          }
3518        }
3519      } else {
3520        callback = !callback && isString(collection) ? charAtCallback : lodash.createCallback(callback, thisArg, 3);
3521        baseEach(collection, function (value, index, collection) {
3522          var current = callback(value, index, collection);
3523          if (current > computed) {
3524            computed = current;
3525            result = value;
3526          }
3527        });
3528      }
3529      return result;
3530    }
3531
3532    /**
3533     * Retrieves the minimum value of a collection. If the collection is empty or
3534     * falsey `Infinity` is returned. If a callback is provided it will be executed
3535     * for each value in the collection to generate the criterion by which the value
3536     * is ranked. The callback is bound to `thisArg` and invoked with three
3537     * arguments; (value, index, collection).
3538     *
3539     * If a property name is provided for `callback` the created "_.pluck" style
3540     * callback will return the property value of the given element.
3541     *
3542     * If an object is provided for `callback` the created "_.where" style callback
3543     * will return `true` for elements that have the properties of the given object,
3544     * else `false`.
3545     *
3546     * @static
3547     * @memberOf _
3548     * @category Collections
3549     * @param {Array|Object|string} collection The collection to iterate over.
3550     * @param {Function|Object|string} [callback=identity] The function called
3551     *  per iteration. If a property name or object is provided it will be used
3552     *  to create a "_.pluck" or "_.where" style callback, respectively.
3553     * @param {*} [thisArg] The `this` binding of `callback`.
3554     * @returns {*} Returns the minimum value.
3555     * @example
3556     *
3557     * _.min([4, 2, 8, 6]);
3558     * // => 2
3559     *
3560     * var stooges = [
3561     *   { 'name': 'moe', 'age': 40 },
3562     *   { 'name': 'larry', 'age': 50 }
3563     * ];
3564     *
3565     * _.min(stooges, function(stooge) { return stooge.age; });
3566     * // => { 'name': 'moe', 'age': 40 };
3567     *
3568     * // using "_.pluck" callback shorthand
3569     * _.min(stooges, 'age');
3570     * // => { 'name': 'moe', 'age': 40 };
3571     */
3572    function min(collection, callback, thisArg) {
3573      var computed = Infinity,
3574        result = computed;
3575      if (!callback && isArray(collection)) {
3576        var index = -1,
3577          length = collection.length;
3578        while (++index < length) {
3579          var value = collection[index];
3580          if (value < result) {
3581            result = value;
3582          }
3583        }
3584      } else {
3585        callback = !callback && isString(collection) ? charAtCallback : lodash.createCallback(callback, thisArg, 3);
3586        baseEach(collection, function (value, index, collection) {
3587          var current = callback(value, index, collection);
3588          if (current < computed) {
3589            computed = current;
3590            result = value;
3591          }
3592        });
3593      }
3594      return result;
3595    }
3596
3597    /**
3598     * Retrieves the value of a specified property from all elements in the `collection`.
3599     *
3600     * @static
3601     * @memberOf _
3602     * @type Function
3603     * @category Collections
3604     * @param {Array|Object|string} collection The collection to iterate over.
3605     * @param {string} property The property to pluck.
3606     * @returns {Array} Returns a new array of property values.
3607     * @example
3608     *
3609     * var stooges = [
3610     *   { 'name': 'moe', 'age': 40 },
3611     *   { 'name': 'larry', 'age': 50 }
3612     * ];
3613     *
3614     * _.pluck(stooges, 'name');
3615     * // => ['moe', 'larry']
3616     */
3617    var pluck = map;
3618
3619    /**
3620     * Reduces a collection to a value which is the accumulated result of running
3621     * each element in the collection through the callback, where each successive
3622     * callback execution consumes the return value of the previous execution. If
3623     * `accumulator` is not provided the first element of the collection will be
3624     * used as the initial `accumulator` value. The callback is bound to `thisArg`
3625     * and invoked with four arguments; (accumulator, value, index|key, collection).
3626     *
3627     * @static
3628     * @memberOf _
3629     * @alias foldl, inject
3630     * @category Collections
3631     * @param {Array|Object|string} collection The collection to iterate over.
3632     * @param {Function} [callback=identity] The function called per iteration.
3633     * @param {*} [accumulator] Initial value of the accumulator.
3634     * @param {*} [thisArg] The `this` binding of `callback`.
3635     * @returns {*} Returns the accumulated value.
3636     * @example
3637     *
3638     * var sum = _.reduce([1, 2, 3], function(sum, num) {
3639     *   return sum + num;
3640     * });
3641     * // => 6
3642     *
3643     * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
3644     *   result[key] = num * 3;
3645     *   return result;
3646     * }, {});
3647     * // => { 'a': 3, 'b': 6, 'c': 9 }
3648     */
3649    function reduce(collection, callback, accumulator, thisArg) {
3650      var noaccum = arguments.length < 3;
3651      callback = baseCreateCallback(callback, thisArg, 4);
3652      if (isArray(collection)) {
3653        var index = -1,
3654          length = collection.length;
3655        if (noaccum) {
3656          accumulator = collection[++index];
3657        }
3658        while (++index < length) {
3659          accumulator = callback(accumulator, collection[index], index, collection);
3660        }
3661      } else {
3662        baseEach(collection, function (value, index, collection) {
3663          accumulator = noaccum ? (noaccum = false, value) : callback(accumulator, value, index, collection);
3664        });
3665      }
3666      return accumulator;
3667    }
3668
3669    /**
3670     * This method is like `_.reduce` except that it iterates over elements
3671     * of a `collection` from right to left.
3672     *
3673     * @static
3674     * @memberOf _
3675     * @alias foldr
3676     * @category Collections
3677     * @param {Array|Object|string} collection The collection to iterate over.
3678     * @param {Function} [callback=identity] The function called per iteration.
3679     * @param {*} [accumulator] Initial value of the accumulator.
3680     * @param {*} [thisArg] The `this` binding of `callback`.
3681     * @returns {*} Returns the accumulated value.
3682     * @example
3683     *
3684     * var list = [[0, 1], [2, 3], [4, 5]];
3685     * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
3686     * // => [4, 5, 2, 3, 0, 1]
3687     */
3688    function reduceRight(collection, callback, accumulator, thisArg) {
3689      var noaccum = arguments.length < 3;
3690      callback = baseCreateCallback(callback, thisArg, 4);
3691      forEachRight(collection, function (value, index, collection) {
3692        accumulator = noaccum ? (noaccum = false, value) : callback(accumulator, value, index, collection);
3693      });
3694      return accumulator;
3695    }
3696
3697    /**
3698     * The opposite of `_.filter` this method returns the elements of a
3699     * collection that the callback does **not** return truey for.
3700     *
3701     * If a property name is provided for `callback` the created "_.pluck" style
3702     * callback will return the property value of the given element.
3703     *
3704     * If an object is provided for `callback` the created "_.where" style callback
3705     * will return `true` for elements that have the properties of the given object,
3706     * else `false`.
3707     *
3708     * @static
3709     * @memberOf _
3710     * @category Collections
3711     * @param {Array|Object|string} collection The collection to iterate over.
3712     * @param {Function|Object|string} [callback=identity] The function called
3713     *  per iteration. If a property name or object is provided it will be used
3714     *  to create a "_.pluck" or "_.where" style callback, respectively.
3715     * @param {*} [thisArg] The `this` binding of `callback`.
3716     * @returns {Array} Returns a new array of elements that failed the callback check.
3717     * @example
3718     *
3719     * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
3720     * // => [1, 3, 5]
3721     *
3722     * var food = [
3723     *   { 'name': 'apple',  'organic': false, 'type': 'fruit' },
3724     *   { 'name': 'carrot', 'organic': true,  'type': 'vegetable' }
3725     * ];
3726     *
3727     * // using "_.pluck" callback shorthand
3728     * _.reject(food, 'organic');
3729     * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
3730     *
3731     * // using "_.where" callback shorthand
3732     * _.reject(food, { 'type': 'fruit' });
3733     * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
3734     */
3735    function reject(collection, callback, thisArg) {
3736      callback = lodash.createCallback(callback, thisArg, 3);
3737      return filter(collection, function (value, index, collection) {
3738        return !callback(value, index, collection);
3739      });
3740    }
3741
3742    /**
3743     * Retrieves a random element or `n` random elements from a collection.
3744     *
3745     * @static
3746     * @memberOf _
3747     * @category Collections
3748     * @param {Array|Object|string} collection The collection to sample.
3749     * @param {number} [n] The number of elements to sample.
3750     * @param- {Object} [guard] Allows working with functions, like `_.map`,
3751     *  without using their `key` and `object` arguments as sources.
3752     * @returns {Array} Returns the random sample(s) of `collection`.
3753     * @example
3754     *
3755     * _.sample([1, 2, 3, 4]);
3756     * // => 2
3757     *
3758     * _.sample([1, 2, 3, 4], 2);
3759     * // => [3, 1]
3760     */
3761    function sample(collection, n, guard) {
3762      var length = collection ? collection.length : 0;
3763      if (typeof length != 'number') {
3764        collection = values(collection);
3765      } else if (support.unindexedChars && isString(collection)) {
3766        collection = collection.split('');
3767      }
3768      if (n == null || guard) {
3769        return collection ? collection[random(length - 1)] : undefined;
3770      }
3771      var result = shuffle(collection);
3772      result.length = nativeMin(nativeMax(0, n), result.length);
3773      return result;
3774    }
3775
3776    /**
3777     * Creates an array of shuffled values, using a version of the Fisher-Yates
3778     * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
3779     *
3780     * @static
3781     * @memberOf _
3782     * @category Collections
3783     * @param {Array|Object|string} collection The collection to shuffle.
3784     * @returns {Array} Returns a new shuffled collection.
3785     * @example
3786     *
3787     * _.shuffle([1, 2, 3, 4, 5, 6]);
3788     * // => [4, 1, 6, 3, 5, 2]
3789     */
3790    function shuffle(collection) {
3791      var index = -1,
3792        length = collection ? c
3792ollection.length : 0,
3793        result = Array(typeof length == 'number' ? length : 0);
3794      forEach(collection, function (value) {
3795        var rand = random(++index);
3796        result[index] = result[rand];
3797        result[rand] = value;
3798      });
3799      return result;
3800    }
3801
3802    /**
3803     * Gets the size of the `collection` by returning `collection.length` for arrays
3804     * and array-like objects or the number of own enumerable properties for objects.
3805     *
3806     * @static
3807     * @memberOf _
3808     * @category Collections
3809     * @param {Array|Object|string} collection The collection to inspect.
3810     * @returns {number} Returns `collection.length` or number of own enumerable properties.
3811     * @example
3812     *
3813     * _.size([1, 2]);
3814     * // => 2
3815     *
3816     * _.size({ 'one': 1, 'two': 2, 'three': 3 });
3817     * // => 3
3818     *
3819     * _.size('curly');
3820     * // => 5
3821     */
3822    function size(collection) {
3823      var length = collection ? collection.length : 0;
3824      return typeof length == 'number' ? length : keys(collection).length;
3825    }
3826
3827    /**
3828     * Checks if the callback returns a truey value for **any** element of a
3829     * collection. The function returns as soon as it finds a passing value and
3830     * does not iterate over the entire collection. The callback is bound to
3831     * `thisArg` and invoked with three arguments; (value, index|key, collection).
3832     *
3833     * If a property name is provided for `callback` the created "_.pluck" style
3834     * callback will return the property value of the given element.
3835     *
3836     * If an object is provided for `callback` the created "_.where" style callback
3837     * will return `true` for elements that have the properties of the given object,
3838     * else `false`.
3839     *
3840     * @static
3841     * @memberOf _
3842     * @alias any
3843     * @category Collections
3844     * @param {Array|Object|string} collection The collection to iterate over.
3845     * @param {Function|Object|string} [callback=identity] The function called
3846     *  per iteration. If a property name or object is provided it will be used
3847     *  to create a "_.pluck" or "_.where" style callback, respectively.
3848     * @param {*} [thisArg] The `this` binding of `callback`.
3849     * @returns {boolean} Returns `true` if any element passed the callback check,
3850     *  else `false`.
3851     * @example
3852     *
3853     * _.some([null, 0, 'yes', false], Boolean);
3854     * // => true
3855     *
3856     * var food = [
3857     *   { 'name': 'apple',  'organic': false, 'type': 'fruit' },
3858     *   { 'name': 'carrot', 'organic': true,  'type': 'vegetable' }
3859     * ];
3860     *
3861     * // using "_.pluck" callback shorthand
3862     * _.some(food, 'organic');
3863     * // => true
3864     *
3865     * // using "_.where" callback shorthand
3866     * _.some(food, { 'type': 'meat' });
3867     * // => false
3868     */
3869    function some(collection, callback, thisArg) {
3870      var result;
3871      callback = lodash.createCallback(callback, thisArg, 3);
3872      if (isArray(collection)) {
3873        var index = -1,
3874          length = collection.length;
3875        while (++index < length) {
3876          if (result = callback(collection[index], index, collection)) {
3877            break;
3878          }
3879        }
3880      } else {
3881        baseEach(collection, function (value, index, collection) {
3882          return !(result = callback(value, index, collection));
3883        });
3884      }
3885      return !!result;
3886    }
3887
3888    /**
3889     * Creates an array of elements, sorted in ascending order by the results of
3890     * running each element in a collection through the callback. This method
3891     * performs a stable sort, that is, it will preserve the original sort order
3892     * of equal elements. The callback is bound to `thisArg` and invoked with
3893     * three arguments; (value, index|key, collection).
3894     *
3895     * If a property name is provided for `callback` the created "_.pluck" style
3896     * callback will return the property value of the given element.
3897     *
3898     * If an object is provided for `callback` the created "_.where" style callback
3899     * will return `true` for elements that have the properties of the given object,
3900     * else `false`.
3901     *
3902     * @static
3903     * @memberOf _
3904     * @category Collections
3905     * @param {Array|Object|string} collection The collection to iterate over.
3906     * @param {Function|Object|string} [callback=identity] The function called
3907     *  per iteration. If a property name or object is provided it will be used
3908     *  to create a "_.pluck" or "_.where" style callback, respectively.
3909     * @param {*} [thisArg] The `this` binding of `callback`.
3910     * @returns {Array} Returns a new array of sorted elements.
3911     * @example
3912     *
3913     * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
3914     * // => [3, 1, 2]
3915     *
3916     * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
3917     * // => [3, 1, 2]
3918     *
3919     * // using "_.pluck" callback shorthand
3920     * _.sortBy(['banana', 'strawberry', 'apple'], 'length');
3921     * // => ['apple', 'banana', 'strawberry']
3922     */
3923    function sortBy(collection, callback, thisArg) {
3924      var index = -1,
3925        length = collection ? collection.length : 0,
3926        result = Array(typeof length == 'number' ? length : 0);
3927      callback = lodash.createCallback(callback, thisArg, 3);
3928      forEach(collection, function (value, key, collection) {
3929        var object = result[++index] = getObject();
3930        object.criteria = callback(value, key, collection);
3931        object.index = index;
3932        object.value = value;
3933      });
3934      length = result.length;
3935      result.sort(compareAscending);
3936      while (length--) {
3937        var object = result[length];
3938        result[length] = object.value;
3939        releaseObject(object);
3940      }
3941      return result;
3942    }
3943
3944    /**
3945     * Converts the `collection` to an array.
3946     *
3947     * @static
3948     * @memberOf _
3949     * @category Collections
3950     * @param {Array|Object|string} collection The collection to convert.
3951     * @returns {Array} Returns the new converted array.
3952     * @example
3953     *
3954     * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
3955     * // => [2, 3, 4]
3956     */
3957    function toArray(collection) {
3958      if (collection && typeof collection.length == 'number') {
3959        return support.unindexedChars && isString(collection) ? collection.split('') : slice(collection);
3960      }
3961      return values(collection);
3962    }
3963
3964    /**
3965     * Performs a deep comparison of each element in a `collection` to the given
3966     * `properties` object, returning an array of all elements that have equivalent
3967     * property values.
3968     *
3969     * @static
3970     * @memberOf _
3971     * @type Function
3972     * @category Collections
3973     * @param {Array|Object|string} collection The collection to iterate over.
3974     * @param {Object} properties The object of property values to filter by.
3975     * @returns {Array} Returns a new array of elements that have the given properties.
3976     * @example
3977     *
3978     * var stooges = [
3979     *   { 'name': 'curly', 'age': 30, 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] },
3980     *   { 'name': 'moe', 'age': 40, 'quotes': ['Spread out!', 'You knucklehead!'] }
3981     * ];
3982     *
3983     * _.where(stooges, { 'age': 40 });
3984     * // => [{ 'name': 'moe', 'age': 40, 'quotes': ['Spread out!', 'You knucklehead!'] }]
3985     *
3986     * _.where(stooges, { 'quotes': ['Poifect!'] });
3987     * // => [{ 'name': 'curly', 'age': 30, 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] }]
3988     */
3989    var where = filter;
3990
3991    /*--------------------------------------------------------------------------*/
3992
3993    /**
3994     * Creates an array with all falsey values removed. The values `false`, `null`,
3995     * `0`, `""`, `undefined`, and `NaN` are all falsey.
3996     *
3997     * @static
3998     * @memberOf _
3999     * @category Arrays
4000     * @param {Array} array The array to compact.
4001     * @returns {Array} Returns a new array of filtered values.
4002     * @example
4003     *
4004     * _.compact([0, 1, false, 2, '', 3]);
4005     * // => [1, 2, 3]
4006     */
4007    function compact(array) {
4008      var index = -1,
4009        length = array ? array.length : 0,
4010        result = [];
4011      while (++index < length) {
4012        var value = array[index];
4013        if (value) {
4014          result.push(value);
4015        }
4016      }
4017      return result;
4018    }
4019
4020    /**
4021     * Creates an array excluding all values of the provided arrays using strict
4022     * equality for comparisons, i.e. `===`.
4023     *
4024     * @static
4025     * @memberOf _
4026     * @category Arrays
4027     * @param {Array} array The array to process.
4028     * @param {...Array} [array] The arrays of values to exclude.
4029     * @returns {Array} Returns a new array of filtered values.
4030     * @example
4031     *
4032     * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
4033     * // => [1, 3, 4]
4034     */
4035    function difference(array) {
4036      var index = -1,
4037        indexOf = getIndexOf(),
4038        length = array ? array.length : 0,
4039        seen = baseFlatten(arguments, true, true, 1),
4040        result = [];
4041      var isLarge = length >= largeArraySize && indexOf === baseIndexOf;
4042      if (isLarge) {
4043        var cache = createCache(seen);
4044        if (cache) {
4045          indexOf = cacheIndexOf;
4046          seen = cache;
4047        } else {
4048          isLarge = false;
4049        }
4050      }
4051      while (++index < length) {
4052        var value = array[index];
4053        if (indexOf(seen, value) < 0) {
4054          result.push(value);
4055        }
4056      }
4057      if (isLarge) {
4058        releaseObject(seen);
4059      }
4060      return result;
4061    }
4062
4063    /**
4064     * This method is like `_.find` except that it returns the index of the first
4065     * element that passes the callback check, instead of the element itself.
4066     *
4067     * @static
4068     * @memberOf _
4069     * @category Arrays
4070     * @param {Array} array The array to search.
4071     * @param {Function|Object|string} [callback=identity] The function called
4072     *  per iteration. If a property name or object is provided it will be used
4073     *  to create a "_.pluck" or "_.where" style callback, respectively.
4074     * @param {*} [thisArg] The `this` binding of `callback`.
4075     * @returns {number} Returns the index of the found element, else `-1`.
4076     * @example
4077     *
4078     * _.findIndex(['apple', 'banana', 'beet'], function(food) {
4079     *   return /^b/.test(food);
4080     * });
4081     * // => 1
4082     */
4083    function findIndex(array, callback, thisArg) {
4084      var index = -1,
4085        length = array ? array.length : 0;
4086      callback = lodash.createCallback(callback, thisArg, 3);
4087      while (++index < length) {
4088        if (callback(array[index], index, array)) {
4089          return index;
4090        }
4091      }
4092      return -1;
4093    }
4094
4095    /**
4096     * This method is like `_.findIndex` except that it iterates over elements
4097     * of a `collection` from right to left.
4098     *
4099     * @static
4100     * @memberOf _
4101     * @category Arrays
4102     * @param {Array} array The array to search.
4103     * @param {Function|Object|string} [callback=identity] The function called
4104     *  per iteration. If a property name or object is provided it will be used
4105     *  to create a "_.pluck" or "_.where" style callback, respectively.
4106     * @param {*} [thisArg] The `this` binding of `callback`.
4107     * @returns {number} Returns the index of the found element, else `-1`.
4108     * @example
4109     *
4110     * _.findLastIndex(['apple', 'banana', 'beet'], function(food) {
4111     *   return /^b/.test(food);
4112     * });
4113     * // => 2
4114     */
4115    function findLastIndex(array, callback, thisArg) {
4116      var length = array ? array.length : 0;
4117      callback = lodash.createCallback(callback, thisArg, 3);
4118      while (length--) {
4119        if (callback(array[length], length, array)) {
4120          return length;
4121        }
4122      }
4123      return -1;
4124    }
4125
4126    /**
4127     * Gets the first element or first `n` elements of an array. If a callback
4128     * is provided elements at the beginning of the array are returned as long
4129     * as the callback returns truey. The callback is bound to `thisArg` and
4130     * invoked with three arguments; (value, index, array).
4131     *
4132     * If a property name is provided for `callback` the created "_.pluck" style
4133     * callback will return the property value of the given element.
4134     *
4135     * If an object is provided for `callback` the created "_.where" style callback
4136     * will return `true` for elements that have the properties of the given object,
4137     * else `false`.
4138     *
4139     * @static
4140     * @memberOf _
4141     * @alias head, take
4142     * @category Arrays
4143     * @param {Array} array The array to query.
4144     * @param {Function|Object|number|string} [callback] The function called
4145     *  per element or the number of elements to return. If a property name or
4146     *  object is provided it will be used to create a "_.pluck" or "_.where"
4147     *  style callback, respectively.
4148     * @param {*} [thisArg] The `this` binding of `callback`.
4149     * @returns {*} Returns the first element(s) of `array`.
4150     * @example
4151     *
4152     * _.first([1, 2, 3]);
4153     * // => 1
4154     *
4155     * _.first([1, 2, 3], 2);
4156     * // => [1, 2]
4157     *
4158     * _.first([1, 2, 3], function(num) {
4159     *   return num < 3;
4160     * });
4161     * // => [1, 2]
4162     *
4163     * var food = [
4164     *   { 'name': 'banana', 'organic': true },
4165     *   { 'name': 'beet',   'organic': false },
4166     * ];
4167     *
4168     * // using "_.pluck" callback shorthand
4169     * _.first(food, 'organic');
4170     * // => [{ 'name': 'banana', 'organic': true }]
4171     *
4172     * var food = [
4173     *   { 'name': 'apple',  'type': 'fruit' },
4174     *   { 'name': 'banana', 'type': 'fruit' },
4175     *   { 'name': 'beet',   'type': 'vegetable' }
4176     * ];
4177     *
4178     * // using "_.where" callback shorthand
4179     * _.first(food, { 'type': 'fruit' });
4180     * // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }]
4181     */
4182    function first(array, callback, thisArg) {
4183      var n = 0,
4184        length = array ? array.length : 0;
4185      if (typeof callback != 'number' && callback != null) {
4186        var index = -1;
4187        callback = lodash.createCallback(callback, thisArg, 3);
4188        while (++index < length && callback(array[index], index, array)) {
4189          n++;
4190        }
4191      } else {
4192        n = callback;
4193        if (n == null || thisArg) {
4194          return array ? array[0] : undefined;
4195        }
4196      }
4197      return slice(array, 0, nativeMin(nativeMax(0, n), length));
4198    }
4199
4200    /**
4201     * Flattens a nested array (the nesting can be to any depth). If `isShallow`
4202     * is truey, the array will only be flattened a single level. If a callback
4203     * is provided each element of the array is passed through the callback before
4204     * flattening. The callback is bound to `thisArg` and invoked with three
4205     * arguments; (value, index, array).
4206     *
4207     * If a property name is provided for `callback` the created "_.pluck" style
4208     * callback will return the property value of the given element.
4209     *
4210     * If an object is provided for `callback` the created "_.where" style callback
4211     * will return `true` for elements that have the properties of the given object,
4212     * else `false`.
4213     *
4214     * @static
4215     * @memberOf _
4216     * @category Arrays
4217     * @param {Array} array The array to flatten.
4218     * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
4219     * @param {Function|Object|string} [callback=identity] The function called
4220     *  per iteration. If a property name or object is provided it will be used
4221     *  to create a "_.pluck" or "_.where" style callback, respectively.
4222     * @param {*} [thisArg] The `this` binding of `callback`.
4223     * @returns {Array} Returns a new flattened array.
4224     * @example
4225     *
4226     * _.flatten([1, [2], [3, [[4]]]]);
4227     * // => [1, 2, 3, 4];
4228     *
4229     * _.flatten([1, [2], [3, [[4]]]], true);
4230     * // => [1, 2, 3, [[4]]];
4231     *
4232     * var stooges = [
4233     *   { 'name': 'curly', 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] },
4234     *   { 'name': 'moe', 'quotes': ['Spread out!', 'You knucklehead!'] }
4235     * ];
4236     *
4237     * // using "_.pluck" callback shorthand
4238     * _.flatten(stooges, 'quotes');
4239     * // => ['Oh, a wise guy, eh?', 'Poifect!', 'Spread out!', 'You knucklehead!']
4240     */
4241    function flatten(array, isShallow, callback, thisArg) {
4242      // juggle arguments
4243      if (typeof isShallow != 'boolean' && isShallow != null) {
4244        thisArg = callback;
4245        callback = !(thisArg && thisArg[isShallow] === array) ? isShallow : null;
4246        isShallow = false;
4247      }
4248      if (callback != null) {
4249        array = map(array, callback, thisArg);
4250      }
4251      return baseFlatten(array, isShallow);
4252    }
4253
4254    /**
4255     * Gets the index at which the first occurrence of `value` is found using
4256     * strict equality for comparisons, i.e. `===`. If the array is already sorted
4257     * providing `true` for `fromIndex` will run a faster binary search.
4258     *
4259     * @static
4260     * @memberOf _
4261     * @category Arrays
4262     * @param {Array} array The array to search.
4263     * @param {*} value The value to search for.
4264     * @param {boolean|number} [fromIndex=0] The index to search from or `true`
4265     *  to perform a binary search on a sorted array.
4266     * @returns {number} Returns the index of the matched value or `-1`.
4267     * @example
4268     *
4269     * _.indexOf([1, 2, 3, 1, 2, 3], 2);
4270     * // => 1
4271     *
4272     * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
4273     * // => 4
4274     *
4275     * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
4276     * // => 2
4277     */
4278    function indexOf(array, value, fromIndex) {
4279      if (typeof fromIndex == 'number') {
4280        var length = array ? array.length : 0;
4281        fromIndex = fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0;
4282      } else if (fromIndex) {
4283        var index = sortedIndex(array, value);
4284        return array[index] === value ? index : -1;
4285      }
4286      return baseIndexOf(array, value, fromIndex);
4287    }
4288
4289    /**
4290     * Gets all but the last element or last `n` elements of an array. If a
4291     * callback is provided elements at the end of the array are excluded from
4292     * the result as long as the callback returns truey. The callback is bound
4293     * to `thisArg` and invoked with three arguments; (value, index, array).
4294     *
4295     * If a property name is provided for `callback` the created "_.pluck" style
4296     * callback will return the property value of the given element.
4297     *
4298     * If an object is provided for `callback` the created "_.where" style callback
4299     * will return `true` for elements that have the properties of the given object,
4300     * else `false`.
4301     *
4302     * @static
4303     * @memberOf _
4304     * @category Arrays
4305     * @param {Array} array The array to query.
4306     * @param {Function|Object|number|string} [callback=1] The function called
4307     *  per element or the number of elements to exclude. If a property name or
4308     *  object is provided it will be used to create a "_.pluck" or "_.where"
4309     *  style callback, respectively.
4310     * @param {*} [thisArg] The `this` binding of `callback`.
4311     * @returns {Array} Returns a slice of `array`.
4312     * @example
4313     *
4314     * _.initial([1, 2, 3]);
4315     * // => [1, 2]
4316     *
4317     * _.initial([1, 2, 3], 2);
4318     * // => [1]
4319     *
4320     * _.initial([1, 2, 3], function(num) {
4321     *   return num > 1;
4322     * });
4323     * // => [1]
4324     *
4325     * var food = [
4326     *   { 'name': 'beet',   'organic': false },
4327     *   { 'name': 'carrot', 'organic': true }
4328     * ];
4329     *
4330     * // using "_.pluck" callback shorthand
4331     * _.initial(food, 'organic');
4332     * // => [{ 'name': 'beet',   'organic': false }]
4333     *
4334     * var food = [
4335     *   { 'name': 'banana', 'type': 'fruit' },
4336     *   { 'name': 'beet',   'type': 'vegetable' },
4337     *   { 'name': 'carrot', 'type': 'vegetable' }
4338     * ];
4339     *
4340     * // using "_.where" callback shorthand
4341     * _.initial(food, { 'type': 'vegetable' });
4342     * // => [{ 'name': 'banana', 'type': 'fruit' }]
4343     */
4344    function initial(array, callback, thisArg) {
4345      var n = 0,
4346        length = array ? array.length : 0;
4347      if (typeof callback != 'number' && callback != null) {
4348        var index = length;
4349        callback = lodash.createCallback(callback, thisArg, 3);
4350        while (index-- && callback(array[index], index, array)) {
4351          n++;
4352        }
4353      } else {
4354        n = callback == null || thisArg ? 1 : callback || n;
4355      }
4356      return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
4357    }
4358
4359    /**
4360     * Creates an array of unique values present in all provided arrays using
4361     * strict equality for comparisons, i.e. `===`.
4362     *
4363     * @static
4364     * @memberOf _
4365     * @category Arrays
4366     * @param {...Array} [array] The arrays to inspect.
4367     * @returns {Array} Returns an array of composite values.
4368     * @example
4369     *
4370     * _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
4371     * // => [1, 2]
4372     */
4373    function intersection(array) {
4374      var args = arguments,
4375        argsLength = args.length,
4376        argsIndex = -1,
4377        caches = getArray(),
4378        index = -1,
4379        indexOf = getIndexOf(),
4380        length = array ? array.length : 0,
4381        result = [],
4382        seen = getArray();
4383      while (++argsIndex < argsLength) {
4384        var value = args[argsIndex];
4385        caches[argsIndex] = indexOf === baseIndexOf && (value ? value.length : 0) >= largeArraySize && createCache(argsIndex ? args[argsIndex] : seen);
4386      }
4387      outer: while (++index < length) {
4388        var cache = caches[0];
4389        value = array[index];
4390        if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
4391          argsIndex = argsLength;
4392          (cache || seen).push(value);
4393          while (--argsIndex) {
4394            cache = caches[argsIndex];
4395            if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
4396              continue outer;
4397            }
4398          }
4399          result.push(value);
4400        }
4401      }
4402      while (argsLength--) {
4403        cache = caches[argsLength];
4404        if (cache) {
4405          releaseObject(cache);
4406        }
4407      }
4408      releaseArray(caches);
4409      releaseArray(seen);
4410      return result;
4411    }
4412
4413    /**
4414     * Gets the last element or last `n` elements of an array. If a callback is
4415     * provided elements at the end of the array are returned as long as the
4416     * callback returns truey. The callback is bound to `thisArg` and invoked
4417     * with three arguments; (value, index, array).
4418     *
4419     * If a property name is provided for `callback` the created "_.pluck" style
4420     * callback will return the property value of the given element.
4421     *
4422     * If an object is provided for `callback` the created "_.where" style callback
4423     * will return `true` for elements that have the properties of the given object,
4424     * else `false`.
4425     *
4426     * @static
4427     * @memberOf _
4428     * @category Arrays
4429     * @param {Array} array The array to query.
4430     * @param {Function|Object|number|string} [callback] The function called
4431     *  per element or the number of elements to return. If a property name or
4432     *  object is provided it will be used to create a "_.pluck" or "_.where"
4433     *  style callback, respectively.
4434     * @param {*} [thisArg] The `this` binding of `callback`.
4435     * @returns {*} Returns the last element(s) of `array`.
4436     * @example
4437     *
4438     * _.last([1, 2, 3]);
4439     * // => 3
4440     *
4441     * _.last([1, 2, 3], 2);
4442     * // => [2, 3]
4443     *
4444     * _.last([1, 2, 3], function(num) {
4445     *   return num > 1;
4446     * });
4447     * // => [2, 3]
4448     *
4449     * var food = [
4450     *   { 'name': 'beet',   'organic': false },
4451     *   { 'name': 'carrot', 'organic': true }
4452     * ];
4453     *
4454     * // using "_.pluck" callback shorthand
4455     * _.last(food, 'organic');
4456     * // => [{ 'name': 'carrot', 'organic': true }]
4457     *
4458     * var food = [
4459     *   { 'name': 'banana', 'type': 'fruit' },
4460     *   { 'name': 'beet',   'type': 'vegetable' },
4461     *   { 'name': 'carrot', 'type': 'vegetable' }
4462     * ];
4463     *
4464     * // using "_.where" callback shorthand
4465     * _.last(food, { 'type': 'vegetable' });
4466     * // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }]
4467     */
4468    function last(array, callback, thisArg) {
4469      var n = 0,
4470        length = array ? array.length : 0;
4471      if (typeof callback != 'number' && callback != null) {
4472        var index = length;
4473        callback = lodash.createCallback(callback, thisArg, 3);
4474        while (index-- && callback(array[index], index, array)) {
4475          n++;
4476        }
4477      } else {
4478        n = callback;
4479        if (n == null || thisArg) {
4480          return array ? array[length - 1] : undefined;
4481        }
4482      }
4483      return slice(array, nativeMax(0, length - n));
4484    }
4485
4486    /**
4487     * Gets the index at which the last occurrence of `value` is found using strict
4488     * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
4489     * as the offset from the end of the collection.
4490     *
4491     * @static
4492     * @memberOf _
4493     * @category Arrays
4494     * @param {Array} array The array to search.
4495     * @param {*} value The value to search for.
4496     * @param {number} [fromIndex=array.length-1] The index to search from.
4497     * @returns {number} Returns the index of the matched value or `-1`.
4498     * @example
4499     *
4500     * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
4501     * // => 4
4502     *
4503     * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
4504     * // => 1
4505     */
4506    function lastIndexOf(array, value, fromIndex) {
4507      var index = array ? array.length : 0;
4508      if (typeof fromIndex == 'number') {
4509        index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
4510      }
4511      while (index--) {
4512        if (array[index] === value) {
4513          return index;
4514        }
4515      }
4516      return -1;
4517    }
4518
4519    /**
4520     * Removes all provided values from the given array using strict equality for
4521     * comparisons, i.e. `===`.
4522     *
4523     * @static
4524     * @memberOf _
4525     * @category Arrays
4526     * @param {Array} array The array to modify.
4527     * @param {...*} [value] The values to remove.
4528     * @returns {Array} Returns `array`.
4529     * @example
4530     *
4531     * var array = [1, 2, 3, 1, 2, 3];
4532     * _.pull(array, 2, 3);
4533     * console.log(array);
4534     * // => [1, 1]
4535     */
4536    function pull(array) {
4537      var args = arguments,
4538        argsIndex = 0,
4539        argsLength = args.length,
4540        length = array ? array.length : 0;
4541      while (++argsIndex < argsLength) {
4542        var index = -1,
4543          value = args[argsIndex];
4544        while (++index < length) {
4545          if (array[index] === value) {
4546            splice.call(array, index--, 1);
4547            length--;
4548          }
4549        }
4550      }
4551      return array;
4552    }
4553
4554    /**
4555     * Creates an array of numbers (positive and/or negative) progressing from
4556     * `start` up to but not including `end`. If `start` is less than `stop` a
4557     * zero-length range is created unless a negative `step` is specified.
4558     *
4559     * @static
4560     * @memberOf _
4561     * @category Arrays
4562     * @param {number} [start=0] The start of the range.
4563     * @param {number} end The end of the range.
4564     * @param {number} [step=1] The value to increment or decrement by.
4565     * @returns {Array} Returns a new range array.
4566     * @example
4567     *
4568     * _.range(10);
4569     * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4570     *
4571     * _.range(1, 11);
4572     * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
4573     *
4574     * _.range(0, 30, 5);
4575     * // => [0, 5, 10, 15, 20, 25]
4576     *
4577     * _.range(0, -10, -1);
4578     * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
4579     *
4580     * _.range(1, 4, 0);
4581     * // => [1, 1, 1]
4582     *
4583     * _.range(0);
4584     * // => []
4585     */
4586    function range(start, end, step) {
4587      start = +start || 0;
4588      step = typeof step == 'number' ? step : +step || 1;
4589      if (end == null) {
4590        end = start;
4591        start = 0;
4592      }
4593      // use `Array(length)` so engines, like Chakra and V8, avoid slower modes
4594      // http://youtu.be/XAqIpGU8ZZk#t=17m25s
4595      var index = -1,
4596        length = nativeMax(0, ceil((end - start) / (step || 1))),
4597        result = Array(length);
4598      while (++index < length) {
4599        result[index] = start;
4600        start += step;
4601      }
4602      return result;
4603    }
4604
4605    /**
4606     * Removes all elements from an array that the callback returns truey for
4607     * and returns an array of removed elements. The callback is bound to `thisArg`
4608     * and invoked with three arguments; (value, index, array).
4609     *
4610     * If a property name is provided for `callback` the created "_.pluck" style
4611     * callback will return the property value of the given element.
4612     *
4613     * If an object is provided for `callback` the created "_.where" style callback
4614     * will return `true` for elements that have the properties of the given object,
4615     * else `false`.
4616     *
4617     * @static
4618     * @memberOf _
4619     * @category Arrays
4620     * @param {Array} array The array to modify.
4621     * @param {Function|Object|string} [callback=identity] The function called
4622     *  per iteration. If a property name or object is provided it will be used
4623     *  to create a "_.pluck" or "_.where" style callback, respectively.
4624     * @param {*} [thisArg] The `this` binding of `callback`.
4625     * @returns {Array} Returns a new array of removed elements.
4626     * @example
4627     *
4628     * var array = [1, 2, 3, 4, 5, 6];
4629     * var evens = _.remove(array, function(num) { return num % 2 == 0; });
4630     *
4631     * console.log(array);
4632     * // => [1, 3, 5]
4633     *
4634     * console.log(evens);
4635     * // => [2, 4, 6]
4636     */
4637    function remove(array, callback, thisArg) {
4638      var index = -1,
4639        length = array ? array.length : 0,
4640        result = [];
4641      callback = lodash.createCallback(callback, thisArg, 3);
4642      while (++index < length) {
4643        var value = array[index];
4644        if (callback(value, index, array)) {
4645          result.push(value);
4646          splice.call(array, index--, 1);
4647          length--;
4648        }
4649      }
4650      return result;
4651    }
4652
4653    /**
4654     * The opposite of `_.initial` this method gets all but the first element or
4655     * first `n` elements of an array. If a callback function is provided elements
4656     * at the beginning of the array are excluded from the result as long as the
4657     * callback returns truey. The callback is bound to `thisArg` and invoked
4658     * with three arguments; (value, index, array).
4659     *
4660     * If a property name is provided for `callback` the created "_.pluck" style
4661     * callback will return the property value of the given element.
4662     *
4663     * If an object is provided for `callback` the created "_.where" style callback
4664     * will return `true` for elements that have the properties of the given object,
4665     * else `false`.
4666     *
4667     * @static
4668     * @memberOf _
4669     * @alias drop, tail
4670     * @category Arrays
4671     * @param {Array} array The array to query.
4672     * @param {Function|Object|number|string} [callback=1] The function called
4673     *  per element or the number of elements to exclude. If a property name or
4674     *  object is provided it will be used to create a "_.pluck" or "_.where"
4675     *  style callback, respectively.
4676     * @param {*} [thisArg] The `this` binding of `callback`.
4677     * @returns {Array} Returns a slice of `array`.
4678     * @example
4679     *
4680     * _.rest([1, 2, 3]);
4681     * // => [2, 3]
4682     *
4683     * _.rest([1, 2, 3], 2);
4684     * // => [3]
4685     *
4686     * _.rest([1, 2, 3], function(num) {
4687     *   return num < 3;
4688     * });
4689     * // => [3]
4690     *
4691     * var food = [
4692     *   { 'name': 'banana', 'organic': true },
4693     *   { 'name': 'beet',   'organic': false },
4694     * ];
4695     *
4696     * // using "_.pluck" callback shorthand
4697     * _.rest(food, 'organic');
4698     * // => [{ 'name': 'beet', 'organic': false }]
4699     *
4700     * var food = [
4701     *   { 'name': 'apple',  'type': 'fruit' },
4702     *   { 'name': 'banana', 'type': 'fruit' },
4703     *   { 'name': 'beet',   'type': 'vegetable' }
4704     * ];
4705     *
4706     * // using "_.where" callback shorthand
4707     * _.rest(food, { 'type': 'fruit' });
4708     * // => [{ 'name': 'beet', 'type': 'vegetable' }]
4709     */
4710    function rest(array, callback, thisArg) {
4711      if (typeof callback != 'number' && callback != null) {
4712        var n = 0,
4713          index = -1,
4714          length = array ? array.length : 0;
4715        callback = lodash.createCallback(callback, thisArg, 3);
4716        while (++index < length && callback(array[index], index, array)) {
4717          n++;
4718        }
4719      } else {
4720        n = callback == null || thisArg ? 1 : nativeMax(0, callback);
4721      }
4722      return slice(array, n);
4723    }
4724
4725    /**
4726     * Uses a binary search to determine the smallest index at which a value
4727     * should be inserted into a given sorted array in order to maintain the sort
4728     * order of the array. If a callback is provided it will be executed for
4729     * `value` and each element of `array` to compute their sort ranking. The
4730     * callback is bound to `thisArg` and invoked with one argument; (value).
4731     *
4732     * If a property name is provided for `callback` the created "_.pluck" style
4733     * callback will return the property value of the given element.
4734     *
4735     * If an object is provided for `callback` the created "_.where" style callback
4736     * will return `true` for elements that have the properties of the given object,
4737     * else `false`.
4738     *
4739     * @static
4740     * @memberOf _
4741     * @category Arrays
4742     * @param {Array} array The array to inspect.
4743     * @param {*} value The value to evaluate.
4744     * @param {Function|Object|string} [callback=identity] The function called
4745     *  per iteration. If a property name or object is provided it will be used
4746     *  to create a "_.pluck" or "_.where" style callback, respectively.
4747     * @param {*} [thisArg] The `this` binding of `callback`.
4748     * @returns {number} Returns the index at which `value` should be inserted
4749     *  into `array`.
4750     * @example
4751     *
4752     * _.sortedIndex([20, 30, 50], 40);
4753     * // => 2
4754     *
4755     * // using "_.pluck" callback shorthand
4756     * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
4757     * // => 2
4758     *
4759     * var dict = {
4760     *   'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
4761     * };
4762     *
4763     * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
4764     *   return dict.wordToNumber[word];
4765     * });
4766     * // => 2
4767     *
4768     * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
4769     *   return this.wordToNumber[word];
4770     * }, dict);
4771     * // => 2
4772     */
4773    function sortedIndex(array, value, callback, thisArg) {
4774      var low = 0,
4775        high = array ? array.length : low;
4776
4777      // explicitly reference `identity` for better inlining in Firefox
4778      callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
4779      value = callback(value);
4780      while (low < high) {
4781        var mid = low + high >>> 1;
4782        callback(array[mid]) < value ? low = mid + 1 : high = mid;
4783      }
4784      return low;
4785    }
4786
4787    /**
4788     * Creates an array of unique values, in order, of the provided arrays using
4789     * strict equality for comparisons, i.e. `===`.
4790     *
4791     * @static
4792     * @memberOf _
4793     * @category Arrays
4794     * @param {...Array} [array] The arrays to inspect.
4795     * @returns {Array} Returns an array of composite values.
4796     * @example
4797     *
4798     * _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
4799     * // => [1, 2, 3, 101, 10]
4800     */
4801    function union(array) {
4802      return baseUniq(baseFlatten(arguments, true, true));
4803    }
4804
4805    /**
4806     * Creates a duplicate-value-free version of an array using strict equality
4807     * for comparisons, i.e. `===`. If the array is sorted, providing
4808     * `true` for `isSorted` will use a faster algorithm. If a callback is provided
4809     * each element of `array` is passed through the callback before uniqueness
4810     * is computed. The callback is bound to `thisArg` and invoked with three
4811     * arguments; (value, index, array).
4812     *
4813     * If a property name is provided for `callback` the created "_.pluck" style
4814     * callback will return the property value of the given element.
4815     *
4816     * If an object is provided for `callback` the created "_.where" style callback
4817     * will return `true` for elements that have the properties of the given object,
4818     * else `false`.
4819     *
4820     * @static
4821     * @memberOf _
4822     * @alias unique
4823     * @category Arrays
4824     * @param {Array} array The array to process.
4825     * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
4826     * @param {Function|Object|string} [callback=identity] The function called
4827     *  per iteration. If a property name or object is provided it will be used
4828     *  to create a "_.pluck" or "_.where" style callback, respectively.
4829     * @param {*} [thisArg] The `this` binding of `callback`.
4830     * @returns {Array} Returns a duplicate-value-free array.
4831     * @example
4832     *
4833     * _.uniq([1, 2, 1, 3, 1]);
4834     * // => [1, 2, 3]
4835     *
4836     * _.uniq([1, 1, 2, 2, 3], true);
4837     * // => [1, 2, 3]
4838     *
4839     * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
4840     * // => ['A', 'b', 'C']
4841     *
4842     * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
4843     * // => [1, 2.5, 3]
4844     *
4845     * // using "_.pluck" callback shorthand
4846     * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
4847     * // => [{ 'x': 1 }, { 'x': 2 }]
4848     */
4849    function uniq(array, isSorted, callback, thisArg) {
4850      // juggle arguments
4851      if (typeof isSorted != 'boolean' && isSorted != null) {
4852        thisArg = callback;
4853        callback = !(thisArg && thisArg[isSorted] === array) ? isSorted : null;
4854        isSorted = false;
4855      }
4856      if (callback != null) {
4857        callback = lodash.createCallback(callback, thisArg, 3);
4858      }
4859      return baseUniq(array, isSorted, callback);
4860    }
4861
4862    /**
4863     * Creates an array excluding all provided values using strict equality for
4864     * comparisons, i.e. `===`.
4865     *
4866     * @static
4867     * @memberOf _
4868     * @category Arrays
4869     * @param {Array} array The array to filter.
4870     * @param {...*} [value] The values to exclude.
4871     * @returns {Array} Returns a new array of filtered values.
4872     * @example
4873     *
4874     * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
4875     * // => [2, 3, 4]
4876     */
4877    function without(array) {
4878      return difference(array, nativeSlice.call(arguments, 1));
4879    }
4880
4881    /**
4882     * Creates an array of grouped elements, the first of which contains the first
4883     * elements of the given arrays, the second of which contains the second
4884     * elements of the given arrays, and so on.
4885     *
4886     * @static
4887     * @memberOf _
4888     * @alias unzip
4889     * @category Arrays
4890     * @param {...Array} [array] Arrays to process.
4891     * @returns {Array} Returns a new array of grouped elements.
4892     * @example
4893     *
4894     * _.zip(['moe', 'larry'], [30, 40], [true, false]);
4895     * // => [['moe', 30, true], ['larry', 40, false]]
4896     */
4897    function zip() {
4898      var array = arguments.length > 1 ? arguments : arguments[0],
4899        index = -1,
4900        length = array ? max(pluck(array, 'length')) : 0,
4901        result = Array(length < 0 ? 0 : length);
4902      while (++index < length) {
4903        result[index] = pluck(array, index);
4904      }
4905      return result;
4906    }
4907
4908    /**
4909     * Creates an object composed from arrays of `keys` and `values`. Provide
4910     * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
4911     * or two arrays, one of `keys` and one of corresponding `values`.
4912     *
4913     * @static
4914     * @memberOf _
4915     * @alias object
4916     * @category Arrays
4917     * @param {Array} keys The array of keys.
4918     * @param {Array} [values=[]] The array of values.
4919     * @returns {Object} Returns an object composed of the given keys and
4920     *  corresponding values.
4921     * @example
4922     *
4923     * _.zipObject(['moe', 'larry'], [30, 40]);
4924     * // => { 'moe': 30, 'larry': 40 }
4925     */
4926    function zipObject(keys, values) {
4927      var index = -1,
4928        length = keys ? keys.length : 0,
4929        result = {};
4930      while (++index < length) {
4931        var key = keys[index];
4932        if (values) {
4933          result[key] = values[index];
4934        } else if (key) {
4935          result[key[0]] = key[1];
4936        }
4937      }
4938      return result;
4939    }
4940
4941    /*--------------------------------------------------------------------------*/
4942
4943    /**
4944     * Creates a function that executes `func`, with  the `this` binding and
4945     * arguments of the created function, only after being called `n` times.
4946     *
4947     * @static
4948     * @memberOf _
4949     * @category Functions
4950     * @param {number} n The number of times the function must be called before
4951     *  `func` is executed.
4952     * @param {Function} func The function to restrict.
4953     * @returns {Function} Returns the new restricted function.
4954     * @example
4955     *
4956     * var saves = ['profile', 'settings'];
4957     *
4958     * var done = _.after(saves.length, function() {
4959     *   console.log('Done saving!');
4960     * });
4961     *
4962     * _.forEach(saves, function(type) {
4963     *   asyncSave({ 'type': type, 'complete': done });
4964     * });
4965     * // => logs 'Done saving!', after all saves have completed
4966     */
4967    function after(n, func) {
4968      if (!isFunction(func)) {
4969        throw new TypeError();
4970      }
4971      return function () {
4972        if (--n < 1) {
4973          return func.apply(this, arguments);
4974        }
4975      };
4976    }
4977
4978    /**
4979     * Creates a function that, when called, invokes `func` with the `this`
4980     * binding of `thisArg` and prepends any additional `bind` arguments to those
4981     * provided to the bound function.
4982     *
4983     * @static
4984     * @memberOf _
4985     * @category Functions
4986     * @param {Function} func The function to bind.
4987     * @param {*} [thisArg] The `this` binding of `func`.
4988     * @param {...*} [arg] Arguments to be partially applied.
4989     * @returns {Function} Returns the new bound function.
4990     * @example
4991     *
4992     * var func = function(greeting) {
4993     *   return greeting + ' ' + this.name;
4994     * };
4995     *
4996     * func = _.bind(func, { 'name': 'moe' }, 'hi');
4997     * func();
4998     * // => 'hi moe'
4999     */
5000    function bind(func, thisArg) {
5001      return arguments.length > 2 ? createBound(func, 17, nativeSlice.call(arguments, 2), null, thisArg) : createBound(func, 1, null, null, thisArg);
5002    }
5003
5004    /**
5005     * Binds methods of an object to the object itself, overwriting the existing
5006     * method. Method names may be specified as individual arguments or as arrays
5007     * of method names. If no method names are provided all the function properties
5008     * of `object` will be bound.
5009     *
5010     * @static
5011     * @memberOf _
5012     * @category Functions
5013     * @param {Object} object The object to bind and assign the bound methods to.
5014     * @param {...string} [methodName] The object method names to
5015     *  bind, specified as individual method names or arrays of method names.
5016     * @returns {Object} Returns `object`.
5017     * @example
5018     *
5019     * var view = {
5020     *  'label': 'docs',
5021     *  'onClick': function() { console.log('clicked ' + this.label); }
5022     * };
5023     *
5024     * _.bindAll(view);
5025     * jQuery('#docs').on('click', view.onClick);
5026     * // => logs 'clicked docs', when the button is clicked
5027     */
5028    function bindAll(object) {
5029      var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
5030        index = -1,
5031        length = funcs.length;
5032      while (++index < length) {
5033        var key = funcs[index];
5034        object[key] = createBound(object[key], 1, null, null, object);
5035      }
5036      return object;
5037    }
5038
5039    /**
5040     * Creates a function that, when called, invokes the method at `object[key]`
5041     * and prepends any additional `bindKey` arguments to those provided to the bound
5042     * function. This method differs from `_.bind` by allowing bound functions to
5043     * reference methods that will be redefined or don't yet exist.
5044     * See http://michaux.ca/articles/lazy-function-definition-pattern.
5045     *
5046     * @static
5047     * @memberOf _
5048     * @category Functions
5049     * @param {Object} object The object the method belongs to.
5050     * @param {string} key The key of the method.
5051     * @param {...*} [arg] Arguments to be partially applied.
5052     * @returns {Function} Returns the new bound function.
5053     * @example
5054     *
5055     * var object = {
5056     *   'name': 'moe',
5057     *   'greet': function(greeting) {
5058     *     return greeting + ' ' + this.name;
5059     *   }
5060     * };
5061     *
5062     * var func = _.bindKey(object, 'greet', 'hi');
5063     * func();
5064     * // => 'hi moe'
5065     *
5066     * object.greet = function(greeting) {
5067     *   return greeting + ', ' + this.name + '!';
5068     * };
5069     *
5070     * func();
5071     * // => 'hi, moe!'
5072     */
5073    function bindKey(object, key) {
5074      return arguments.length > 2 ? createBound(key, 19, nativeSlice.call(arguments, 2), null, object) : createBound(key, 3, null, null, object);
5075    }
5076
5077    /**
5078     * Creates a function that is the composition of the provided functions,
5079     * where each function consumes the return value of the function that follows.
5080     * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
5081     * Each function is executed with the `this` binding of the composed function.
5082     *
5083     * @static
5084     * @memberOf _
5085     * @category Functions
5086     * @param {...Function} [func] Functions to compose.
5087     * @returns {Function} Returns the new composed function.
5088     * @example
5089     *
5090     * var realNameMap = {
5091     *   'curly': 'jerome'
5092     * };
5093     *
5094     * var format = function(name) {
5095     *   name = realNameMap[name.toLowerCase()] || name;
5096     *   return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
5097     * };
5098     *
5099     * var greet = function(formatted) {
5100     *   return 'Hiya ' + formatted + '!';
5101     * };
5102     *
5103     * var welcome = _.compose(greet, format);
5104     * welcome('curly');
5105     * // => 'Hiya Jerome!'
5106     */
5107    function compose() {
5108      var funcs = arguments,
5109        length = funcs.length;
5110      while (length--) {
5111        if (!isFunction(funcs[length])) {
5112          throw new TypeError();
5113        }
5114      }
5115      return function () {
5116        var args = arguments,
5117          length = funcs.length;
5118        while (length--) {
5119          args = [funcs[length].apply(this, args)];
5120        }
5121        return args[0];
5122      };
5123    }
5124
5125    /**
5126     * Produces a callback bound to an optional `thisArg`. If `func` is a property
5127     * name the created callback will return the property value for a given element.
5128     * If `func` is an object the created callback will return `true` for elements
5129     * that contain the equivalent object properties, otherwise it will return `false`.
5130     *
5131     * @static
5132     * @memberOf _
5133     * @category Functions
5134     * @param {*} [func=identity] The value to convert to a callback.
5135     * @param {*} [thisArg] The `this` binding of the created callback.
5136     * @param {number} [argCount] The number of arguments the callback accepts.
5137     * @returns {Function} Returns a callback function.
5138     * @example
5139     *
5140     * var stooges = [
5141     *   { 'name': 'moe', 'age': 40 },
5142     *   { 'name': 'larry', 'age': 50 }
5143     * ];
5144     *
5145     * // wrap to create custom callback shorthands
5146     * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
5147     *   var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
5148     *   return !match ? func(callback, thisArg) : function(object) {
5149     *     return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
5150     *   };
5151     * });
5152     *
5153     * _.filter(stooges, 'age__gt45');
5154     * // => [{ 'name': 'larry', 'age': 50 }]
5155     */
5156    function createCallback(func, thisArg, argCount) {
5157      var type = _typeof(func);
5158      if (func == null || type == 'function') {
5159        return baseCreateCallback(func, thisArg, argCount);
5160      }
5161      // handle "_.pluck" style callback shorthands
5162      if (type != 'object') {
5163        return function (object) {
5164          return object[func];
5165        };
5166      }
5167      var props = keys(func),
5168        key = props[0],
5169        a = func[key];
5170
5171      // handle "_.where" style callback shorthands
5172      if (props.length == 1 && a === a && !isObject(a)) {
5173        // fast path the common case of providing an object with a single
5174        // property containing a primitive value
5175        return function (object) {
5176          var b = object[key];
5177          return a === b && (a !== 0 || 1 / a == 1 / b);
5178        };
5179      }
5180      return function (object) {
5181        var length = props.length,
5182          result = false;
5183        while (length--) {
5184          if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) {
5185            break;
5186          }
5187        }
5188        return result;
5189      };
5190    }
5191
5192    /**
5193     * Creates a function which accepts one or more arguments of `func` that when
5194     * invoked either executes `func` returning its result, if all `func` arguments
5195     * have been provided, or returns a function that accepts one or more of the
5196     * remaining `func` arguments, and so on. The arity of `func` can be specified
5197     * if `func.length` is not sufficient.
5198     *
5199     * @static
5200     * @memberOf _
5201     * @category Functions
5202     * @param {Function} func The function to curry.
5203     * @param {number} [arity=func.length] The arity of `func`.
5204     * @returns {Function} Returns the new curried function.
5205     * @example
5206     *
5207     * var curried = _.curry(function(a, b, c) {
5208     *   console.log(a + b + c);
5209     * });
5210     *
5211     * curried(1)(2)(3);
5212     * // => 6
5213     *
5214     * curried(1, 2)(3);
5215     * // => 6
5216     *
5217     * curried(1, 2, 3);
5218     * // => 6
5219     */
5220    function curry(func, arity) {
5221      arity = typeof arity == 'number' ? arity : +arity || func.length;
5222      return createBound(func, 4, null, null, null, arity);
5223    }
5224
5225    /**
5226     * Creates a function that will delay the execution of `func` until after
5227     * `wait` milliseconds have elapsed since the last time it was invoked.
5228     * Provide an options object to indicate that `func` should be invoked on
5229     * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
5230     * to the debounced function will return the result of the last `func` call.
5231     *
5232     * Note: If `leading` and `trailing` options are `true` `func` will be called
5233     * on the trailing edge of the timeout only if the the debounced function is
5234     * invoked more than once during the `wait` timeout.
5235     *
5236     * @static
5237     * @memberOf _
5238     * @category Functions
5239     * @param {Function} func The function to debounce.
5240     * @param {number} wait The number of milliseconds to delay.
5241     * @param {Object} [options] The options object.
5242     * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
5243     * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
5244     * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
5245     * @returns {Function} Returns the new debounced function.
5246     * @example
5247     *
5248     * // avoid costly calculations while the window size is in flux
5249     * var lazyLayout = _.debounce(calculateLayout, 150);
5250     * jQuery(window).on('resize', lazyLayout);
5251     *
5252     * // execute `sendMail` when the click event is fired, debouncing subsequent calls
5253     * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
5254     *   'leading': true,
5255     *   'trailing': false
5256     * });
5257     *
5258     * // ensure `batchLog` is executed once after 1 second of debounced calls
5259     * var source = new EventSource('/stream');
5260     * source.addEventListener('message', _.debounce(batchLog, 250, {
5261     *   'maxWait': 1000
5262     * }, false);
5263     */
5264    function debounce(func, wait, options) {
5265      var args,
5266        maxTimeoutId,
5267        result,
5268        stamp,
5269        thisArg,
5270        timeoutId,
5271        trailingCall,
5272        lastCalled = 0,
5273        maxWait = false,
5274        trailing = true;
5275      if (!isFunction(func)) {
5276        throw new TypeError();
5277      }
5278      wait = nativeMax(0, wait) || 0;
5279      if (options === true) {
5280        var leading = true;
5281        trailing = false;
5282      } else if (isObject(options)) {
5283        leading = options.leading;
5284        maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
5285        trailing = 'trailing' in options ? options.trailing : trailing;
5286      }
5287      var delayed = function delayed() {
5288        var remaining = wait - (new Date() - stamp);
5289        if (remaining <= 0) {
5290          if (maxTimeoutId) {
5291            clearTimeout(maxTimeoutId);
5292          }
5293          var isCalled = trailingCall;
5294          maxTimeoutId = timeoutId = trailingCall = undefined;
5295          if (isCalled) {
5296            lastCalled = +new Date();
5297            result = func.apply(thisArg, args);
5298          }
5299        } else {
5300          timeoutId = setTimeout(delayed, remaining);
5301        }
5302      };
5303      var maxDelayed = function maxDelayed() {
5304        if (timeoutId) {
5305          clearTimeout(timeoutId);
5306        }
5307        maxTimeoutId = timeoutId = trailingCall = undefined;
5308        if (trailing || maxWait !== wait) {
5309          lastCalled = +new Date();
5310          result = func.apply(thisArg, args);
5311        }
5312      };
5313      return function () {
5314        args = arguments;
5315        stamp = +new Date();
5316        thisArg = this;
5317        trailingCall = trailing && (timeoutId || !leading);
5318        if (maxWait === false) {
5319          var leadingCall = leading && !timeoutId;
5320        } else {
5321          if (!maxTimeoutId && !leading) {
5322            lastCalled = stamp;
5323          }
5324          var remaining = maxWait - (stamp - lastCalled);
5325          if (remaining <= 0) {
5326            if (maxTimeoutId) {
5327              maxTimeoutId = clearTimeout(maxTimeoutId);
5328            }
5329            lastCalled = stamp;
5330            result = func.apply(thisArg, args);
5331          } else if (!maxTimeoutId) {
5332            maxTimeoutId = setTimeout(maxDelayed, remaining);
5333          }
5334        }
5335        if (!timeoutId && wait !== maxWait) {
5336          timeoutId = setTimeout(delayed, wait);
5337        }
5338        if (leadingCall) {
5339          result = func.apply(thisArg, args);
5340        }
5341        return result;
5342      };
5343    }
5344
5345    /**
5346     * Defers executing the `func` function until the current call stack has cleared.
5347     * Additional arguments will be provided to `func` when it is invoked.
5348     *
5349     * @static
5350     * @memberOf _
5351     * @category Functions
5352     * @param {Function} func The function to defer.
5353     * @param {...*} [arg] Arguments to invoke the function with.
5354     * @returns {number} Returns the timer id.
5355     * @example
5356     *
5357     * _.defer(function() { console.log('deferred'); });
5358     * // returns from the function before 'deferred' is logged
5359     */
5360    function defer(func) {
5361      if (!isFunction(func)) {
5362        throw new TypeError();
5363      }
5364      var args = nativeSlice.call(arguments, 1);
5365      return setTimeout(function () {
5366        func.apply(undefined, args);
5367      }, 1);
5368    }
5369    // use `setImmediate` if available in Node.js
5370    if (isV8 && moduleExports && typeof setImmediate == 'function') {
5371      defer = function defer(func) {
5372        if (!isFunction(func)) {
5373          throw new TypeError();
5374        }
5375        return setImmediate.apply(context, arguments);
5376      };
5377    }
5378
5379    /**
5380     * Executes the `func` function after `wait` milliseconds. Additional arguments
5381     * will be provided to `func` when it is invoked.
5382     *
5383     * @static
5384     * @memberOf _
5385     * @category Functions
5386     * @param {Function} func The function to delay.
5387     * @param {number} wait The number of milliseconds to delay execution.
5388     * @param {...*} [arg] Arguments to invoke the function with.
5389     * @returns {number} Returns the timer id.
5390     * @example
5391     *
5392     * var log = _.bind(console.log, console);
5393     * _.delay(log, 1000, 'logged later');
5394     * // => 'logged later' (Appears after one second.)
5395     */
5396    function delay(func, wait) {
5397      if (!isFunction(func)) {
5398        throw new TypeError();
5399      }
5400      var args = nativeSlice.call(arguments, 2);
5401      return setTimeout(function () {
5402        func.apply(undefined, args);
5403      }, wait);
5404    }
5405
5406    /**
5407     * Creates a function that memoizes the result of `func`. If `resolver` is
5408     * provided it will be used to determine the cache key for storing the result
5409     * based on the arguments provided to the memoized function. By default, the
5410     * first argument provided to the memoized function is used as the cache key.
5411     * The `func` is executed with the `this` binding of the memoized function.
5412     * The result cache is exposed as the `cache` property on the memoized function.
5413     *
5414     * @static
5415     * @memberOf _
5416     * @category Functions
5417     * @param {Function} func The function to have its output memoized.
5418     * @param {Function} [resolver] A function used to resolve the cache key.
5419     * @returns {Function} Returns the new memoizing function.
5420     * @example
5421     *
5422     * var fibonacci = _.memoize(function(n) {
5423     *   return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
5424     * });
5425     *
5426     * var data = {
5427     *   'moe': { 'name': 'moe', 'age': 40 },
5428     *   'curly': { 'name': 'curly', 'age': 60 }
5429     * };
5430     *
5431     * // modifying the result cache
5432     * var stooge = _.memoize(function(name) { return data[name]; }, _.identity);
5433     * stooge('curly');
5434     * // => { 'name': 'curly', 'age': 60 }
5435     *
5436     * stooge.cache.curly.name = 'jerome';
5437     * stooge('curly');
5438     * // => { 'name': 'jerome', 'age': 60 }
5439     */
5440    function memoize(func, resolver) {
5441      if (!isFunction(func)) {
5442        throw new TypeError();
5443      }
5444      var memoized = function memoized() {
5445        var cache = memoized.cache,
5446          key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
5447        return hasOwnProperty.call(cache, key) ? cache[key] : cache[key] = func.apply(this, arguments);
5448      };
5449      memoized.cache = {};
5450      return memoized;
5451    }
5452
5453    /**
5454     * Creates a function that is restricted to execute `func` once. Repeat calls to
5455     * the function will return the value of the first call. The `func` is executed
5456     * with the `this` binding of the created function.
5457     *
5458     * @static
5459     * @memberOf _
5460     * @category Functions
5461     * @param {Function} func The function to restrict.
5462     * @returns {Function} Returns the new restricted function.
5463     * @example
5464     *
5465     * var initialize = _.once(createApplication);
5466     * initialize();
5467     * initialize();
5468     * // `initialize` executes `createApplication` once
5469     */
5470    function once(func) {
5471      var ran, result;
5472      if (!isFunction(func)) {
5473        throw new TypeError();
5474      }
5475      return function () {
5476        if (ran) {
5477          return result;
5478        }
5479        ran = true;
5480        result = func.apply(this, arguments);
5481
5482        // clear the `func` variable so the function may be garbage collected
5483        func = null;
5484        return result;
5485      };
5486    }
5487
5488    /**
5489     * Creates a function that, when called, invokes `func` with any additional
5490     * `partial` arguments prepended to those provided to the new function. This
5491     * method is similar to `_.bind` except it does **not** alter the `this` binding.
5492     *
5493     * @static
5494     * @memberOf _
5495     * @category Functions
5496     * @param {Function} func The function to partially apply arguments to.
5497     * @param {...*} [arg] Arguments to be partially applied.
5498     * @returns {Function} Returns the new partially applied function.
5499     * @example
5500     *
5501     * var greet = function(greeting, name) { return greeting + ' ' + name; };
5502     * var hi = _.partial(greet, 'hi');
5503     * hi('moe');
5504     * // => 'hi moe'
5505     */
5506    function partial(func) {
5507      return createBound(func, 16, nativeSlice.call(arguments, 1));
5508    }
5509
5510    /**
5511     * This method is like `_.partial` except that `partial` arguments are
5512     * appended to those provided to the new function.
5513     *
5514     * @static
5515     * @memberOf _
5516     * @category Functions
5517     * @param {Function} func The function to partially apply arguments to.
5518     * @param {...*} [arg] Arguments to be partially applied.
5519     * @returns {Function} Returns the new partially applied function.
5520     * @example
5521     *
5522     * var defaultsDeep = _.partialRight(_.merge, _.defaults);
5523     *
5524     * var options = {
5525     *   'variable': 'data',
5526     *   'imports': { 'jq': $ }
5527     * };
5528     *
5529     * defaultsDeep(options, _.templateSettings);
5530     *
5531     * options.variable
5532     * // => 'data'
5533     *
5534     * options.imports
5535     * // => { '_': _, 'jq': $ }
5536     */
5537    function partialRight(func) {
5538      return createBound(func, 32, null, nativeSlice.call(arguments, 1));
5539    }
5540
5541    /**
5542     * Creates a function that, when executed, will only call the `func` function
5543     * at most once per every `wait` milliseconds. Provide an options object to
5544     * indicate that `func` should be invoked on the leading and/or trailing edge
5545     * of the `wait` timeout. Subsequent calls to the throttled function will
5546     * return the result of the last `func` call.
5547     *
5548     * Note: If `leading` and `trailing` options are `true` `func` will be called
5549     * on the trailing edge of the timeout only if the the throttled function is
5550     * invoked more than once during the `wait` timeout.
5551     *
5552     * @static
5553     * @memberOf _
5554     * @category Functions
5555     * @param {Function} func The function to throttle.
5556     * @param {number} wait The number of milliseconds to throttle executions to.
5557     * @param {Object} [options] The options object.
5558     * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
5559     * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
5560     * @returns {Function} Returns the new throttled function.
5561     * @example
5562     *
5563     * // avoid excessively updating the position while scrolling
5564     * var throttled = _.throttle(updatePosition, 100);
5565     * jQuery(window).on('scroll', throttled);
5566     *
5567     * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
5568     * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
5569     *   'trailing': false
5570     * }));
5571     */
5572    function throttle(func, wait, options) {
5573      var leading = true,
5574        trailing = true;
5575      if (!isFunction(func)) {
5576        throw new TypeError();
5577      }
5578      if (options === false) {
5579        leading = false;
5580      } else if (isObject(options)) {
5581        leading = 'leading' in options ? options.leading : leading;
5582        trailing = 'trailing' in options ? options.trailing : trailing;
5583      }
5584      options = getObject();
5585      options.leading = leading;
5586      options.maxWait = wait;
5587      options.trailing = trailing;
5588      var result = debounce(func, wait, options);
5589      releaseObject(options);
5590      return result;
5591    }
5592
5593    /**
5594     * Creates a function that provides `value` to the wrapper function as its
5595     * first argument. Additional arguments provided to the function are appended
5596     * to those provided to the wrapper function. The wrapper is executed with
5597     * the `this` binding of the created function.
5598     *
5599     * @static
5600     * @memberOf _
5601     * @category Functions
5602     * @param {*} value The value to wrap.
5603     * @param {Function} wrapper The wrapper function.
5604     * @returns {Function} Returns the new function.
5605     * @example
5606     *
5607     * var hello = function(name) { return 'hello ' + name; };
5608     * hello = _.wrap(hello, function(func) {
5609     *   return 'before, ' + func('moe') + ', after';
5610     * });
5611     * hello();
5612     * // => 'before, hello moe, after'
5613     */
5614    function wrap(value, wrapper) {
5615      if (!isFunction(wrapper)) {
5616        throw new TypeError();
5617      }
5618      return function () {
5619        var args = [value];
5620        push.apply(args, arguments);
5621        return wrapper.apply(this, args);
5622      };
5623    }
5624
5625    /*--------------------------------------------------------------------------*/
5626
5627    /**
5628     * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
5629     * corresponding HTML entities.
5630     *
5631     * @static
5632     * @memberOf _
5633     * @category Utilities
5634     * @param {string} string The string to escape.
5635     * @returns {string} Returns the escaped string.
5636     * @example
5637     *
5638     * _.escape('Moe, Larry & Curly');
5639     * // => 'Moe, Larry &amp; Curly'
5640     */
5641    function escape(string) {
5642      return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
5643    }
5644
5645    /**
5646     * This method returns the first argument provided to it.
5647     *
5648     * @static
5649     * @memberOf _
5650     * @category Utilities
5651     * @param {*} value Any value.
5652     * @returns {*} Returns `value`.
5653     * @example
5654     *
5655     * var moe = { 'name': 'moe' };
5656     * moe === _.identity(moe);
5657     * // => true
5658     */
5659    function identity(value) {
5660      return value;
5661    }
5662
5663    /**
5664     * Adds function properties of a source object to the `lodash` function and
5665     * chainable wrapper.
5666     *
5667     * @static
5668     * @memberOf _
5669     * @category Utilities
5670     * @param {Object} object The object of function properties to add to `lodash`.
5671     * @param {Object} object The object of function properties to add to `lodash`.
5672     * @example
5673     *
5674     * _.mixin({
5675     *   'capitalize': function(string) {
5676     *     return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
5677     *   }
5678     * });
5679     *
5680     * _.capitalize('moe');
5681     * // => 'Moe'
5682     *
5683     * _('moe').capitalize();
5684     * // => 'Moe'
5685     */
5686    function mixin(object, source) {
5687      var ctor = object,
5688        isFunc = !source || isFunction(ctor);
5689      if (!source) {
5690        ctor = lodashWrapper;
5691        source = object;
5692        object = lodash;
5693      }
5694      forEach(functions(source), function (methodName) {
5695        var func = object[methodName] = source[methodName];
5696        if (isFunc) {
5697          ctor.prototype[methodName] = function () {
5698            var value = this.__wrapped__,
5699              args = [value];
5700            push.apply(args, arguments);
5701            var result = func.apply(object, args);
5702            return value && _typeof(value) == 'object' && value === result ? this : new ctor(result);
5703          };
5704        }
5705      });
5706    }
5707
5708    /**
5709     * Reverts the '_' variable to its previous value and returns a reference to
5710     * the `lodash` function.
5711     *
5712     * @static
5713     * @memberOf _
5714     * @category Utilities
5715     * @returns {Function} Returns the `lodash` function.
5716     * @example
5717     *
5718     * var lodash = _.noConflict();
5719     */
5720    function noConflict() {
5721      context._ = oldDash;
5722      return this;
5723    }
5724
5725    /**
5726     * Converts the given value into an integer of the specified radix.
5727     * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
5728     * `value` is a hexadecimal, in which case a `radix` of `16` is used.
5729     *
5730     * Note: This method avoids differences in native ES3 and ES5 `parseInt`
5731     * implementations. See http://es5.github.io/#E.
5732     *
5733     * @static
5734     * @memberOf _
5735     * @category Utilities
5736     * @param {string} value The value to parse.
5737     * @param {number} [radix] The radix used to interpret the value to parse.
5738     * @returns {number} Returns the new integer value.
5739     * @example
5740     *
5741     * _.parseInt('08');
5742     * // => 8
5743     */
5744    var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function (value, radix) {
5745      // Firefox and Opera still follow the ES3 specified implementation of `parseInt`
5746      return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
5747    };
5748
5749    /**
5750     * Produces a random number between `min` and `max` (inclusive). If only one
5751     * argument is provided a number between `0` and the given number will be
5752     * returned. If `floating` is truey or either `min` or `max` are floats a
5753     * floating-point number will be returned instead of an integer.
5754     *
5755     * @static
5756     * @memberOf _
5757     * @category Utilities
5758     * @param {number} [min=0] The minimum possible value.
5759     * @param {number} [max=1] The maximum possible value.
5760     * @param {boolean} [floating=false] Specify returning a floating-point number.
5761     * @returns {number} Returns a random number.
5762     * @example
5763     *
5764     * _.random(0, 5);
5765     * // => an integer between 0 and 5
5766     *
5767     * _.random(5);
5768     * // => also an integer between 0 and 5
5769     *
5770     * _.random(5, true);
5771     * // => a floating-point number between 0 and 5
5772     *
5773     * _.random(1.2, 5.2);
5774     * // => a floating-point number between 1.2 and 5.2
5775     */
5776    function random(min, max, floating) {
5777      var noMin = min == null,
5778        noMax = max == null;
5779      if (floating == null) {
5780        if (typeof min == 'boolean' && noMax) {
5781          floating = min;
5782          min = 1;
5783        } else if (!noMax && typeof max == 'boolean') {
5784          floating = max;
5785          noMax = true;
5786        }
5787      }
5788      if (noMin && noMax) {
5789        max = 1;
5790      }
5791      min = +min || 0;
5792      if (noMax) {
5793        max = min;
5794        min = 0;
5795      } else {
5796        max = +max || 0;
5797      }
5798      var rand = nativeRandom();
5799      return floating || min % 1 || max % 1 ? min + nativeMin(rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1))), max) : min + floor(rand * (max - min + 1));
5800    }
5801
5802    /**
5803     * Resolves the value of `property` on `object`. If `property` is a function
5804     * it will be invoked with the `this` binding of `object` and its result returned,
5805     * else the property value is returned. If `object` is falsey then `undefined`
5806     * is returned.
5807     *
5808     * @static
5809     * @memberOf _
5810     * @category Utilities
5811     * @param {Object} object The object to inspect.
5812     * @param {string} property The property to get the value of.
5813     * @returns {*} Returns the resolved value.
5814     * @example
5815     *
5816     * var object = {
5817     *   'cheese': 'crumpets',
5818     *   'stuff': function() {
5819     *     return 'nonsense';
5820     *   }
5821     * };
5822     *
5823     * _.result(object, 'cheese');
5824     * // => 'crumpets'
5825     *
5826     * _.result(object, 'stuff');
5827     * // => 'nonsense'
5828     */
5829    function result(object, property) {
5830      if (object) {
5831        var value = object[property];
5832        return isFunction(value) ? object[property]() : value;
5833      }
5834    }
5835
5836    /**
5837     * A micro-templating method that handles arbitrary delimiters, preserves
5838     * whitespace, and correctly escapes quotes within interpolated code.
5839     *
5840     * Note: In the development build, `_.template` utilizes sourceURLs for easier
5841     * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
5842     *
5843     * For more information on precompiling templates see:
5844     * http://lodash.com/#custom-builds
5845     *
5846     * For more information on Chrome extension sandboxes see:
5847     * http://developer.chrome.com/stable/extensions/sandboxingEval.html
5848     *
5849     * @static
5850     * @memberOf _
5851     * @category Utilities
5852     * @param {string} text The template text.
5853     * @param {Object} data The data object used to populate the text.
5854     * @param {Object} [options] The options object.
5855     * @param {RegExp} [options.escape] The "escape" delimiter.
5856     * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
5857     * @param {Object} [options.imports] An object to import into the template as local variables.
5858     * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
5859     * @param {string} [sourceURL] The sourceURL of the template's compiled source.
5860     * @param {string} [variable] The data object variable name.
5861     * @returns {Function|string} Returns a compiled function when no `data` object
5862     *  is given, else it returns the interpolated text.
5863     * @example
5864     *
5865     * // using the "interpolate" delimiter to create a compiled template
5866     * var compiled = _.template('hello <%= name %>');
5867     * compiled({ 'name': 'moe' });
5868     * // => 'hello moe'
5869     *
5870     * // using the "escape" delimiter to escape HTML in data property values
5871     * _.template('<b><%- value %></b>', { 'value': '<script>' });
5872     * // => '<b>&lt;script&gt;</b>'
5873     *
5874     * // using the "evaluate" delimiter to generate HTML
5875     * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
5876     * _.template(list, { 'people': ['moe', 'larry'] });
5877     * // => '<li>moe</li><li>larry</li>'
5878     *
5879     * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
5880     * _.template('hello ${ name }', { 'name': 'curly' });
5881     * // => 'hello curly'
5882     *
5883     * // using the internal `print` function in "evaluate" delimiters
5884     * _.template('<% print("hello " + name); %>!', { 'name': 'larry' });
5885     * // => 'hello larry!'
5886     *
5887     * // using a custom template delimiters
5888     * _.templateSettings = {
5889     *   'interpolate': /{{([\s\S]+?)}}/g
5890     * };
5891     *
5892     * _.template('hello {{ name }}!', { 'name': 'mustache' });
5893     * // => 'hello mustache!'
5894     *
5895     * // using the `imports` option to import jQuery
5896     * var list = '<% $.each(people, function(name) { %><li><%- name %></li><% }); %>';
5897     * _.template(list, { 'people': ['moe', 'larry'] }, { 'imports': { '$': jQuery } });
5898     * // => '<li>moe</li><li>larry</li>'
5899     *
5900     * // using the `sourceURL` option to specify a custom sourceURL for the template
5901     * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
5902     * compiled(data);
5903     * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
5904     *
5905     * // using the `variable` option to ensure a with-statement isn't used in the compiled template
5906     * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
5907     * compiled.source;
5908     * // => function(data) {
5909     *   var __t, __p = '', __e = _.escape;
5910     *   __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
5911     *   return __p;
5912     * }
5913     *
5914     * // using the `source` property to inline compiled templates for meaningful
5915     * // line numbers in error messages and a stack trace
5916     * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
5917     *   var JST = {\
5918     *     "main": ' + _.template(mainText).source + '\
5919     *   };\
5920     * ');
5921     */
5922    function template(text, data, options) {
5923      // based on John Resig's `tmpl` implementation
5924      // http://ejohn.org/blog/javascript-micro-templating/
5925      // and Laura Doktorova's doT.js
5926      // https://github.com/olado/doT
5927      var settings = lodash.templateSettings;
5928      text || (text = '');
5929
5930      // avoid missing dependencies when `iteratorTemplate` is not defined
5931      options = defaults({}, options, settings);
5932      var imports = defaults({}, options.imports, settings.imports),
5933        importsKeys = keys(imports),
5934        importsValues = values(imports);
5935      var isEvaluating,
5936        index = 0,
5937        interpolate = options.interpolate || reNoMatch,
5938        source = "__p += '";
5939
5940      // compile the regexp to match each delimiter
5941      var reDelimiters = RegExp((options.escape || reNoMatch).source + '|' + interpolate.source + '|' + (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' + (options.evaluate || reNoMatch).source + '|$', 'g');
5942      text.replace(reDelimiters, function (match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
5943        interpolateValue || (interpolateValue = esTemplateValue);
5944
5945        // escape characters that cannot be included in string literals
5946        source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
5947
5948        // replace delimiters with snippets
5949        if (escapeValue) {
5950          source += "' +\n__e(" + escapeValue + ") +\n'";
5951        }
5952        if (evaluateValue) {
5953          isEvaluating = true;
5954          source += "';\n" + evaluateValue + ";\n__p += '";
5955        }
5956        if (interpolateValue) {
5957          source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
5958        }
5959        index = offset + match.length;
5960
5961        // the JS engine embedded in Adobe products requires returning the `match`
5962        // string in order to produce the correct `offset` value
5963        return match;
5964      });
5965      source += "';\n";
5966
5967      // if `variable` is not specified, wrap a with-statement around the generated
5968      // code to add the data object to the top of the scope chain
5969      var variable = options.variable,
5970        hasVariable = variable;
5971      if (!hasVariable) {
5972        variable = 'obj';
5973        source = 'with (' + variable + ') {\n' + source + '\n}\n';
5974      }
5975      // cleanup code by stripping empty strings
5976      source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source).replace(reEmptyStringMiddle, '$1').replace(reEmptyStringTrailing, '$1;');
5977
5978      // frame code as the function body
5979      source = 'function(' + variable + ') {\n' + (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') + "var __t, __p = '', __e = _.escape" + (isEvaluating ? ', __j = Array.prototype.join;\n' + "function print() { __p += __j.call(arguments, '') }\n" : ';\n') + source + 'return __p\n}';
5980
5981      // Use a sourceURL for easier debugging.
5982      // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
5983      var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + templateCounter++ + ']') + '\n*/';
5984      try {
5985        var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
5986      } catch (e) {
5987        e.source = source;
5988        throw e;
5989      }
5990      if (data) {
5991        return result(data);
5992      }
5993      // provide the compiled function's source by its `toString` method, in
5994      // supported environments, or the `source` property as a convenience for
5995      // inlining compiled templates during the build process
5996      result.source = source;
5997      return result;
5998    }
5999
6000    /**
6001     * Executes the callback `n` times, returning an array of the results
6002     * of each callback execution. The callback is bound to `thisArg` and invoked
6003     * with one argument; (index).
6004     *
6005     * @static
6006     * @memberOf _
6007     * @category Utilities
6008     * @param {number} n The number of times to execute the callback.
6009     * @param {Function} callback The function called per iteration.
6010     * @param {*} [thisArg] The `this` binding of `callback`.
6011     * @returns {Array} Returns an array of the results of each `callback` execution.
6012     * @example
6013     *
6014     * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
6015     * // => [3, 6, 4]
6016     *
6017     * _.times(3, function(n) { mage.castSpell(n); });
6018     * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
6019     *
6020     * _.times(3, function(n) { this.cast(n); }, mage);
6021     * // => also calls `mage.castSpell(n)` three times
6022     */
6023    function times(n, callback, thisArg) {
6024      n = (n = +n) > -1 ? n : 0;
6025      var index = -1,
6026        result = Array(n);
6027      callback = baseCreateCallback(callback, thisArg, 1);
6028      while (++index < n) {
6029        result[index] = callback(index);
6030      }
6031      return result;
6032    }
6033
6034    /**
6035     * The inverse of `_.escape` this method converts the HTML entities
6036     * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to their
6037     * corresponding characters.
6038     *
6039     * @static
6040     * @memberOf _
6041     * @category Utilities
6042     * @param {string} string The string to unescape.
6043     * @returns {string} Returns the unescaped string.
6044     * @example
6045     *
6046     * _.unescape('Moe, Larry &amp; Curly');
6047     * // => 'Moe, Larry & Curly'
6048     */
6049    function unescape(string) {
6050      return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar);
6051    }
6052
6053    /**
6054     * Generates a unique ID. If `prefix` is provided the ID will be appended to it.
6055     *
6056     * @static
6057     * @memberOf _
6058     * @category Utilities
6059     * @param {string} [prefix] The value to prefix the ID with.
6060     * @returns {string} Returns the unique ID.
6061     * @example
6062     *
6063     * _.uniqueId('contact_');
6064     * // => 'contact_104'
6065     *
6066     * _.uniqueId();
6067     * // => '105'
6068     */
6069    function uniqueId(prefix) {
6070      var id = ++idCounter;
6071      return String(prefix == null ? '' : prefix) + id;
6072    }
6073
6074    /*--------------------------------------------------------------------------*/
6075
6076    /**
6077     * Creates a `lodash` object that wraps the given value.
6078     *
6079     * @static
6080     * @memberOf _
6081     * @category Chaining
6082     * @param {*} value The value to wrap.
6083     * @returns {Object} Returns the wrapper object.
6084     * @example
6085     *
6086     * var stooges = [
6087     *   { 'name': 'moe', 'age': 40 },
6088     *   { 'name': 'larry', 'age': 50 },
6089     *   { 'name': 'curly', 'age': 60 }
6090     * ];
6091     *
6092     * var youngest = _.chain(stooges)
6093     *     .sortBy(function(stooge) { return stooge.age; })
6094     *     .map(function(stooge) { return stooge.name + ' is ' + stooge.age; })
6095     *     .first();
6096     * // => 'moe is 40'
6097     */
6098    function chain(value) {
6099      value = new lodashWrapper(value);
6100      value.__chain__ = true;
6101      return value;
6102    }
6103
6104    /**
6105     * Invokes `interceptor` with the `value` as the first argument and then
6106     * returns `value`. The purpose of this method is to "tap into" a method
6107     * chain in order to perform operations on intermediate results within
6108     * the chain.
6109     *
6110     * @static
6111     * @memberOf _
6112     * @category Chaining
6113     * @param {*} value The value to provide to `interceptor`.
6114     * @param {Function} interceptor The function to invoke.
6115     * @returns {*} Returns `value`.
6116     * @example
6117     *
6118     * _([1, 2, 3, 4])
6119     *  .filter(function(num) { return num % 2 == 0; })
6120     *  .tap(function(array) { console.log(array); })
6121     *  .map(function(num) { return num * num; })
6122     *  .value();
6123     * // => // [2, 4] (logged)
6124     * // => [4, 16]
6125     */
6126    function tap(value, interceptor) {
6127      interceptor(value);
6128      return value;
6129    }
6130
6131    /**
6132     * Enables method chaining on the wrapper object.
6133     *
6134     * @name chain
6135     * @memberOf _
6136     * @category Chaining
6137     * @returns {*} Returns the wrapper object.
6138     * @example
6139     *
6140     * var sum = _([1, 2, 3])
6141     *     .chain()
6142     *     .reduce(function(sum, num) { return sum + num; })
6143     *     .value()
6144     * // => 6`
6145     */
6146    function wrapperChain() {
6147      this.__chain__ = true;
6148      return this;
6149    }
6150
6151    /**
6152     * Produces the `toString` result of the wrapped value.
6153     *
6154     * @name toString
6155     * @memberOf _
6156     * @category Chaining
6157     * @returns {string} Returns the string result.
6158     * @example
6159     *
6160     * _([1, 2, 3]).toString();
6161     * // => '1,2,3'
6162     */
6163    function wrapperToString() {
6164      return String(this.__wrapped__);
6165    }
6166
6167    /**
6168     * Extracts the wrapped value.
6169     *
6170     * @name valueOf
6171     * @memberOf _
6172     * @alias value
6173     * @category Chaining
6174     * @returns {*} Returns the wrapped value.
6175     * @example
6176     *
6177     * _([1, 2, 3]).valueOf();
6178     * // => [1, 2, 3]
6179     */
6180    function wrapperValueOf() {
6181      return this.__wrapped__;
6182    }
6183
6184    /*--------------------------------------------------------------------------*/
6185
6186    // add functions that return wrapped values when chaining
6187    lodash.after = after;
6188    lodash.assign = assign;
6189    lodash.at = at;
6190    lodash.bind = bind;
6191    lodash.bindAll = bindAll;
6192    lodash.bindKey = bindKey;
6193    lodash.chain = chain;
6194    lodash.compact = compact;
6195    lodash.compose = compose;
6196    lodash.countBy = countBy;
6197    lodash.createCallback = createCallback;
6198    lodash.curry = curry;
6199    lodash.debounce = debounce;
6200    lodash.defaults = defaults;
6201    lodash.defer = defer;
6202    lodash.delay = delay;
6203    lodash.difference = difference;
6204    lodash.filter = filter;
6205    lodash.flatten = flatten;
6206    lodash.forEach = forEach;
6207    lodash.forEachRight = forEachRight;
6208    lodash.forIn = forIn;
6209    lodash.forInRight = forInRight;
6210    lodash.forOwn = forOwn;
6211    lodash.forOwnRight = forOwnRight;
6212    lodash.functions = functions;
6213    lodash.groupBy = groupBy;
6214    lodash.indexBy = indexBy;
6215    lodash.initial = initial;
6216    lodash.intersection = intersection;
6217    lodash.invert = invert;
6218    lodash.invoke = invoke;
6219    lodash.keys = keys;
6220    lodash.map = map;
6221    lodash.max = max;
6222    lodash.memoize = memoize;
6223    lodash.merge = merge;
6224    lodash.min = min;
6225    lodash.omit = omit;
6226    lodash.once = once;
6227    lodash.pairs = pairs;
6228    lodash.partial = partial;
6229    lodash.partialRight = partialRight;
6230    lodash.pick = pick;
6231    lodash.pluck = pluck;
6232    lodash.pull = pull;
6233    lodash.range = range;
6234    lodash.reject = reject;
6235    lodash.remove = remove;
6236    lodash.rest = rest;
6237    lodash.shuffle = shuffle;
6238    lodash.sortBy = sortBy;
6239    lodash.tap = tap;
6240    lodash.throttle = throttle;
6241    lodash.times = times;
6242    lodash.toArray = toArray;
6243    lodash.transform = transform;
6244    lodash.union = union;
6245    lodash.uniq = uniq;
6246    lodash.values = values;
6247    lodash.where = where;
6248    lodash.without = without;
6249    lodash.wrap = wrap;
6250    lodash.zip = zip;
6251    lodash.zipObject = zipObject;
6252
6253    // add aliases
6254    lodash.collect = map;
6255    lodash.drop = rest;
6256    lodash.each = forEach;
6257    lodash.eachRight = forEachRight;
6258    lodash.extend = assign;
6259    lodash.methods = functions;
6260    lodash.object = zipObject;
6261    lodash.select = filter;
6262    lodash.tail = rest;
6263    lodash.unique = uniq;
6264    lodash.unzip = zip;
6265
6266    // add functions to `lodash.prototype`
6267    mixin(lodash);
6268
6269    /*--------------------------------------------------------------------------*/
6270
6271    // add functions that return unwrapped values when chaining
6272    lodash.clone = clone;
6273    lodash.cloneDeep = cloneDeep;
6274    lodash.contains = contains;
6275    lodash.escape = escape;
6276    lodash.every = every;
6277    lodash.find = find;
6278    lodash.findIndex = findIndex;
6279    lodash.findKey = findKey;
6280    lodash.findLast = findLast;
6281    lodash.findLastIndex = findLastIndex;
6282    lodash.findLastKey = findLastKey;
6283    lodash.has = has;
6284    lodash.identity = identity;
6285    lodash.indexOf = indexOf;
6286    lodash.isArguments = isArguments;
6287    lodash.isArray = isArray;
6288    lodash.isBoolean = isBoolean;
6289    lodash.isDate = isDate;
6290    lodash.isElement = isElement;
6291    lodash.isEmpty = isEmpty;
6292    lodash.isEqual = isEqual;
6293    lodash.isFinite = isFinite;
6294    lodash.isFunction = isFunction;
6295    lodash.isNaN = isNaN;
6296    lodash.isNull = isNull;
6297    lodash.isNumber = isNumber;
6298    lodash.isObject = isObject;
6299    lodash.isPlainObject = isPlainObject;
6300    lodash.isRegExp = isRegExp;
6301    lodash.isString = isString;
6302    lodash.isUndefined = isUndefined;
6303    lodash.lastIndexOf = lastIndexOf;
6304    lodash.mixin = mixin;
6305    lodash.noConflict = noConflict;
6306    lodash.parseInt = parseInt;
6307    lodash.random = random;
6308    lodash.reduce = reduce;
6309    lodash.reduceRight = reduceRight;
6310    lodash.result = result;
6311    lodash.runInContext = runInContext;
6312    lodash.size = size;
6313    lodash.some = some;
6314    lodash.sortedIndex = sortedIndex;
6315    lodash.template = template;
6316    lodash.unescape = unescape;
6317    lodash.uniqueId = uniqueId;
6318
6319    // add aliases
6320    lodash.all = every;
6321    lodash.any = some;
6322    lodash.detect = find;
6323    lodash.findWhere = find;
6324    lodash.foldl = reduce;
6325    lodash.foldr = reduceRight;
6326    lodash.include = contains;
6327    lodash.inject = reduce;
6328    forOwn(lodash, function (func, methodName) {
6329      if (!lodash.prototype[methodName]) {
6330        lodash.prototype[methodName] = function () {
6331          var args = [this.__wrapped__],
6332            chainAll = this.__chain__;
6333          push.apply(args, arguments);
6334          var result = func.apply(lodash, args);
6335          return chainAll ? new lodashWrapper(result, chainAll) : result;
6336        };
6337      }
6338    });
6339
6340    /*--------------------------------------------------------------------------*/
6341
6342    // add functions capable of returning wrapped and unwrapped values when chaining
6343    lodash.first = first;
6344    lodash.last = last;
6345    lodash.sample = sample;
6346
6347    // add aliases
6348    lodash.take = first;
6349    lodash.head = first;
6350    forOwn(lodash, function (func, methodName) {
6351      var callbackable = methodName !== 'sample';
6352      if (!lodash.prototype[methodName]) {
6353        lodash.prototype[methodName] = function (n, guard) {
6354          var chainAll = this.__chain__,
6355            result = func(this.__wrapped__, n, guard);
6356          return !chainAll && (n == null || guard && !(callbackable && typeof n == 'function')) ? result : new lodashWrapper(result, chainAll);
6357        };
6358      }
6359    });
6360
6361    /*--------------------------------------------------------------------------*/
6362
6363    /**
6364     * The semantic version number.
6365     *
6366     * @static
6367     * @memberOf _
6368     * @type string
6369     */
6370    lodash.VERSION = '2.1.0';
6371
6372    // add "Chaining" functions to the wrapper
6373    lodash.prototype.chain = wrapperChain;
6374    lodash.prototype.toString = wrapperToString;
6375    lodash.prototype.value = wrapperValueOf;
6376    lodash.prototype.valueOf = wrapperValueOf;
6377
6378    // add `Array` functions that return unwrapped values
6379    baseEach(['join', 'pop', 'shift'], function (methodName) {
6380      var func = arrayRef[methodName];
6381      lodash.prototype[methodName] = function () {
6382        var chainAll = this.__chain__,
6383          result = func.apply(this.__wrapped__, arguments);
6384        return chainAll ? new lodashWrapper(result, chainAll) : result;
6385      };
6386    });
6387
6388    // add `Array` functions that return the wrapped value
6389    baseEach(['push', 'reverse', 'sort', 'unshift'], function (methodName) {
6390      var func = arrayRef[methodName];
6391      lodash.prototype[methodName] = function () {
6392        func.apply(this.__wrapped__, arguments);
6393        return this;
6394      };
6395    });
6396
6397    // add `Array` functions that return new wrapped values
6398    baseEach(['concat', 'slice', 'splice'], function (methodName) {
6399      var func = arrayRef[methodName];
6400      lodash.prototype[methodName] = function () {
6401        return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__);
6402      };
6403    });
6404
6405    // avoid array-like object bugs with `Array#shift` and `Array#splice`
6406    // in Firefox < 10 and IE < 9
6407    if (!support.spliceObjects) {
6408      baseEach(['pop', 'shift', 'splice'], function (methodName) {
6409        var func = arrayRef[methodName],
6410          isSplice = methodName == 'splice';
6411        lodash.prototype[methodName] = function () {
6412          var chainAll = this.__chain__,
6413            value = this.__wrapped__,
6414            result = func.apply(value, arguments);
6415          if (value.length === 0) {
6416            delete value[0];
6417          }
6418          return chainAll || isSplice ? new lodashWrapper(result, chainAll) : result;
6419        };
6420      });
6421    }
6422    return lodash;
6423  }
6424
6425  /*--------------------------------------------------------------------------*/
6426
6427  // expose Lo-Dash
6428  var _ = runInContext();
6429
6430  // some AMD build optimizers, like r.js, check for condition patterns like the following:
6431  if (typeof define == 'function' && _typeof(define.amd) == 'object' && define.amd) {
6432    // Expose Lo-Dash to the global object even when an AMD loader is present in
6433    // case Lo-Dash was injected by a third-party script and not intended to be
6434    // loaded as a module. The global assignment can be reverted in the Lo-Dash
6435    // module by its `noConflict()` method.
6436    root._ = _;
6437
6438    // define as an anonymous module so, through path mapping, it can be
6439    // referenced as the "underscore" module
6440    define(function () {
6441      return _;
6442    });
6443  }
6444  // check for `exports` after `define` in case a build optimizer adds an `exports` object
6445  else if (freeExports && freeModule) {
6446    // in Node.js or RingoJS
6447    if (moduleExports) {
6448      (freeModule.exports = _)._ = _;
6449    }
6450    // in Narwhal or Rhino -require
6451    else {
6452      freeExports._ = _;
6453    }
6454  } else {
6455    // in a browser or Rhino
6456    root._ = _;
6457  }
6458}).call(this);
6459/*!
6460 * jQuery JavaScript Library v2.0.3
6461 * http://jquery.com/
6462 *
6463 * Includes Sizzle.js
6464 * http://sizzlejs.com/
6465 *
6466 * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors
6467 * Released under the MIT license
6468 * http://jquery.org/license
6469 *
6470 * Date: 2013-07-03T13:30Z
6471 */
6472(function (window, undefined) {
6473  // Can't do this because several apps including ASP.NET trace
6474  // the stack via arguments.caller.callee and Firefox dies if
6475  // you try to trace through "use strict" call chains. (#13335)
6476  // Support: Firefox 18+
6477  //"use strict";
6478  var
6479    // A central reference to the root jQuery(document)
6480    rootjQuery,
6481    // The deferred used on DOM ready
6482    readyList,
6483    // Support: IE9
6484    // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
6485    core_strundefined = typeof undefined,
6486    // Use the correct document accordingly with window argument (sandbox)
6487    location = window.location,
6488    document = window.document,
6489    docElem = document.documentElement,
6490    // Map over jQuery in case of overwrite
6491    _jQuery = window.jQuery,
6492    // Map over the $ in case of overwrite
6493    _$ = window.$,
6494    // [[Class]] -> type pairs
6495    class2type = {},
6496    // List of deleted data cache ids, so we can reuse them
6497    core_deletedIds = [],
6498    core_version = "2.0.3",
6499    // Save a reference to some core methods
6500    core_concat = core_deletedIds.concat,
6501    core_push = core_deletedIds.push,
6502    core_slice = core_deletedIds.slice,
6503    core_indexOf = core_deletedIds.indexOf,
6504    core_toString = class2type.toString,
6505    core_hasOwn = class2type.hasOwnProperty,
6506    core_trim = core_version.trim,
6507    // Define a local copy of jQuery
6508    jQuery = function (selector, context) {
6509      // The jQuery object is actually just the init constructor 'enhanced'
6510      return new jQuery.fn.init(selector, context, rootjQuery);
6511    },
6512    // Used for matching numbers
6513    core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
6514    // Used for splitting on whitespace
6515    core_rnotwhite = /\S+/g,
6516    // A simple way to check for HTML strings
6517    // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
6518    // Strict HTML recognition (#11290: must start with <)
6519    rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
6520    // Match a standalone tag
6521    rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
6522    // Matches dashed string for camelizing
6523    rmsPrefix = /^-ms-/,
6524    rdashAlpha = /-([\da-z])/gi,
6525    // Used by jQuery.camelCase as callback to replace()
6526    fcamelCase = function (all, letter) {
6527      return letter.toUpperCase();
6528    },
6529    // The ready event handler and self cleanup method
6530    completed = function () {
6531      document.removeEventListener("DOMContentLoaded", completed, false);
6532      window.removeEventListener("load", completed, false);
6533      jQuery.ready();
6534    };
6535  jQuery.fn = jQuery.prototype = {
6536    // The current version of jQuery being used
6537    jquery: core_version,
6538    constructor: jQuery,
6539    init: function (selector, context, rootjQuery) {
6540      var match, elem;
6541
6542      // HANDLE: $(""), $(null), $(undefined), $(false)
6543      if (!selector) {
6544        return this;
6545      }
6546
6547      // Handle HTML strings
6548      if (typeof selector === "string") {
6549        if (selector.charAt(0) === "<" && selector.charAt(selector.length - 1) === ">" && selector.length >= 3) {
6550          // Assume that strings that start and end with <> are HTML and skip the regex check
6551          match = [null, selector, null];
6552        } else {
6553          match = rquickExpr.exec(selector);
6554        }
6555
6556        // Match html or make sure no context is specified for #id
6557        if (match && (match[1] || !context)) {
6558          // HANDLE: $(html) -> $(array)
6559          if (match[1]) {
6560            context = context instanceof jQuery ? context[0] : context;
6561
6562            // scripts is true for back-compat
6563            jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true));
6564
6565            // HANDLE: $(html, props)
6566            if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
6567              for (match in context) {
6568                // Properties of context are called as methods if possible
6569                if (jQuery.isFunction(this[match])) {
6570                  this[match](context[match]);
6571
6572                  // ...and otherwise set as attributes
6573                } else {
6574                  this.attr(match, context[match]);
6575                }
6576              }
6577            }
6578            return this;
6579
6580            // HANDLE: $(#id)
6581          } else {
6582            elem = document.getElementById(match[2]);
6583
6584            // Check parentNode to catch when Blackberry 4.6 returns
6585            // nodes that are no longer in the document #6963
6586            if (elem && elem.parentNode) {
6587              // Inject the element directly into the jQuery object
6588              this.length = 1;
6589              this[0] = elem;
6590            }
6591            this.context = document;
6592            this.selector = selector;
6593            return this;
6594          }
6595
6596          // HANDLE: $(expr, $(...))
6597        } else if (!context || context.jquery) {
6598          return (context || rootjQuery).find(selector);
6599
6600          // HANDLE: $(expr, context)
6601          // (which is just equivalent to: $(context).find(expr)
6602        } else {
6603          return this.constructor(context).find(selector);
6604        }
6605
6606        // HANDLE: $(DOMElement)
6607      } else if (selector.nodeType) {
6608        this.context = this[0] = selector;
6609        this.length = 1;
6610        return this;
6611
6612        // HANDLE: $(function)
6613        // Shortcut for document ready
6614      } else if (jQuery.isFunction(selector)) {
6615        return rootjQuery.ready(selector);
6616      }
6617      if (selector.selector !== undefined) {
6618        this.selector = selector.selector;
6619        this.context = selector.context;
6620      }
6621      return jQuery.makeArray(selector, this);
6622    },
6623    // Start with an empty selector
6624    selector: "",
6625    // The default length of a jQuery object is 0
6626    length: 0,
6627    toArray: function () {
6628      return core_slice.call(this);
6629    },
6630    // Get the Nth element in the matched element set OR
6631    // Get the whole matched element set as a clean array
6632    get: function (num) {
6633      return num == null ?
6634      // Return a 'clean' array
6635      this.toArray() :
6636      // Return just the object
6637      num < 0 ? this[this.length + num] : this[num];
6638    },
6639    // Take an array of elements and push it onto the stack
6640    // (returning the new matched element set)
6641    pushStack: function (elems) {
6642      // Build a new jQuery matched element set
6643      var ret = jQuery.merge(this.constructor(), elems);
6644
6645      // Add the old object onto the stack (as a reference)
6646      ret.prevObject = this;
6647      ret.context = this.context;
6648
6649      // Return the newly-formed element set
6650      return ret;
6651    },
6652    // Execute a callback for every element in the matched set.
6653    // (You can seed the arguments with an array of args, but this is
6654    // only used internally.)
6655    each: function (callback, args) {
6656      return jQuery.each(this, callback, args);
6657    },
6658    ready: function (fn) {
6659      // Add the callback
6660      jQuery.ready.promise().done(fn);
6661      return this;
6662    },
6663    slice: function () {
6664      return this.pushStack(core_slice.apply(this, arguments));
6665    },
6666    first: function () {
6667      return this.eq(0);
6668    },
6669    last: function () {
6670      return this.eq(-1);
6671    },
6672    eq: function (i) {
6673      var len = this.length,
6674        j = +i + (i < 0 ? len : 0);
6675      return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
6676    },
6677    map: function (callback) {
6678      return this.pushStack(jQuery.map(this, function (elem, i) {
6679        return callback.call(elem, i, elem);
6680      }));
6681    },
6682    end: function () {
6683      return this.prevObject || this.constructor(null);
6684    },
6685    // For internal use only.
6686    // Behaves like an Array's method, not like a jQuery method.
6687    push: core_push,
6688    sort: [].sort,
6689    splice: [].splice
6690  };
6691
6692  // Give the init function the jQuery prototype for later instantiation
6693  jQuery.fn.init.prototype = jQuery.fn;
6694  jQuery.extend = jQuery.fn.extend = function () {
6695    var options,
6696      name,
6697      src,
6698      copy,
6699      copyIsArray,
6700      clone,
6701      target = arguments[0] || {},
6702      i = 1,
6703      length = arguments.length,
6704      deep = false;
6705
6706    // Handle a deep copy situation
6707    if (typeof target === "boolean") {
6708      deep = target;
6709      target = arguments[1] || {};
6710      // skip the boolean and the target
6711      i = 2;
6712    }
6713
6714    // Handle case when target is a string or something (possible in deep copy)
6715    if (typeof target !== "object" && !jQuery.isFunction(target)) {
6716      target = {};
6717    }
6718
6719    // extend jQuery itself if only one argument is passed
6720    if (length === i) {
6721      target = this;
6722      --i;
6723    }
6724    for (; i < length; i++) {
6725      // Only deal with non-null/undefined values
6726      if ((options = arguments[i]) != null) {
6727        // Extend the base object
6728        for (name in options) {
6729          src = target[name];
6730          copy = options[name];
6731
6732          // Prevent never-ending loop
6733          if (target === copy) {
6734            continue;
6735          }
6736
6737          // Recurse if we're merging plain objects or arrays
6738          if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {
6739            if (copyIsArray) {
6740              copyIsArray = false;
6741              clone = src && jQuery.isArray(src) ? src : [];
6742            } else {
6743              clone = src && jQuery.isPlainObject(src) ? src : {};
6744            }
6745
6746            // Never move original objects, clone them
6747            target[name] = jQuery.extend(deep, clone, copy);
6748
6749            // Don't bring in undefined values
6750          } else if (copy !== undefined) {
6751            target[name] = copy;
6752          }
6753        }
6754      }
6755    }
6756
6757    // Return the modified object
6758    return target;
6759  };
6760  jQuery.extend({
6761    // Unique for each copy of jQuery on the page
6762    expando: "jQuery" + (core_version + Math.random()).replace(/\D/g, ""),
6763    noConflict: function (deep) {
6764      if (window.$ === jQuery) {
6765        window.$ = _$;
6766      }
6767      if (deep && window.jQuery === jQuery) {
6768        window.jQuery = _jQuery;
6769      }
6770      return jQuery;
6771    },
6772    // Is the DOM ready to be used? Set to true once it occurs.
6773    isReady: false,
6774    // A counter to track how many items to wait for before
6775    // the ready event fires. See #6781
6776    readyWait: 1,
6777    // Hold (or release) the ready event
6778    holdReady: function (hold) {
6779      if (hold) {
6780        jQuery.readyWait++;
6781      } else {
6782        jQuery.ready(true);
6783      }
6784    },
6785    // Handle when the DOM is ready
6786    ready: function (wait) {
6787      // Abort if there are pending holds or we're already ready
6788      if (wait === true ? --jQuery.readyWait : jQuery.isReady) {
6789        return;
6790      }
6791
6792      // Remember that the DOM is ready
6793      jQuery.isReady = true;
6794
6795      // If a normal DOM Ready event fired, decrement, and wait if need be
6796      if (wait !== true && --jQuery.readyWait > 0) {
6797        return;
6798      }
6799
6800      // If there are functions bound, to execute
6801      readyList.resolveWith(document, [jQuery]);
6802
6803      // Trigger any bound ready events
6804      if (jQuery.fn.trigger) {
6805        jQuery(document).trigger("ready").off("ready");
6806      }
6807    },
6808    // See test/unit/core.js for details concerning isFunction.
6809    // Since version 1.3, DOM methods and functions like alert
6810    // aren't supported. They return false on IE (#2968).
6811    isFunction: function (obj) {
6812      return jQuery.type(obj) === "function";
6813    },
6814    isArray: Array.isArray,
6815    isWindow: function (obj) {
6816      return obj != null && obj === obj.window;
6817    },
6818    isNumeric: function (obj) {
6819      return !isNaN(parseFloat(obj)) && isFinite(obj);
6820    },
6821    type: function (obj) {
6822      if (obj == null) {
6823        return String(obj);
6824      }
6825      // Support: Safari <= 5.1 (functionish RegExp)
6826      return typeof obj === "object" || typeof obj === "function" ? class2type[core_toString.call(obj)] || "object" : typeof obj;
6827    },
6828    isPlainObject: function (obj) {
6829      // Not plain objects:
6830      // - Any object or value whose internal [[Class]] property is not "[object Object]"
6831      // - DOM nodes
6832      // - window
6833      if (jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow(obj)) {
6834        return false;
6835      }
6836
6837      // Support: Firefox <20
6838      // The try/catch suppresses exceptions thrown when attempting to access
6839      // the "constructor" property of certain host objects, ie. |window.location|
6840      // https://bugzilla.mozilla.org/show_bug.cgi?id=814622
6841      try {
6842        if (obj.constructor && !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf")) {
6843          return false;
6844        }
6845      } catch (e) {
6846        return false;
6847      }
6848
6849      // If the function hasn't returned already, we're confident that
6850      // |obj| is a plain object, created by {} or constructed with new Object
6851      return true;
6852    },
6853    isEmptyObject: function (obj) {
6854      var name;
6855      for (name in obj) {
6856        return false;
6857      }
6858      return true;
6859    },
6860    error: function (msg) {
6861      throw new Error(msg);
6862    },
6863    // data: string of html
6864    // context (optional): If specified, the fragment will be created in this context, defaults to document
6865    // keepScripts (optional): If true, will include scripts passed in the html string
6866    parseHTML: function (data, context, keepScripts) {
6867      if (!data || typeof data !== "string") {
6868        return null;
6869      }
6870      if (typeof context === "boolean") {
6871        keepScripts = context;
6872        context = false;
6873      }
6874      context = context || document;
6875      var parsed = rsingleTag.exec(data),
6876        scripts = !keepScripts && [];
6877
6878      // Single tag
6879      if (parsed) {
6880        return [context.createElement(parsed[1])];
6881      }
6882      parsed = jQuery.buildFragment([data], context, scripts);
6883      if (scripts) {
6884        jQuery(scripts).remove();
6885      }
6886      return jQuery.merge([], parsed.childNodes);
6887    },
6888    parseJSON: JSON.parse,
6889    // Cross-browser xml parsing
6890    parseXML: function (data) {
6891      var xml, tmp;
6892      if (!data || typeof data !== "string") {
6893        return null;
6894      }
6895
6896      // Support: IE9
6897      try {
6898        tmp = new DOMParser();
6899        xml = tmp.parseFromString(data, "text/xml");
6900      } catch (e) {
6901        xml = undefined;
6902      }
6903      if (!xml || xml.getElementsByTagName("parsererror").length) {
6904        jQuery.error("Invalid XML: " + data);
6905      }
6906      return xml;
6907    },
6908    noop: function () {},
6909    // Evaluates a script in a global context
6910    globalEval: function (code) {
6911      var script,
6912        indirect = eval;
6913      code = jQuery.trim(code);
6914      if (code) {
6915        // If the code includes a valid, prologue position
6916        // strict mode pragma, execute code by injecting a
6917        // script tag into the document.
6918        if (code.indexOf("use strict") === 1) {
6919          script = document.createElement("script");
6920          script.text = code;
6921          document.head.appendChild(script).parentNode.removeChild(script);
6922        } else {
6923          // Otherwise, avoid the DOM node creation, insertion
6924          // and removal by using an indirect global eval
6925          indirect(code);
6926        }
6927      }
6928    },
6929    // Convert dashed to camelCase; used by the css and data modules
6930    // Microsoft forgot to hump their vendor prefix (#9572)
6931    camelCase: function (string) {
6932      return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);
6933    },
6934    nodeName: function (elem, name) {
6935      return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
6936    },
6937    // args is for internal usage only
6938    each: function (obj, callback, args) {
6939      var value,
6940        i = 0,
6941        length = obj.length,
6942        isArray = isArraylike(obj);
6943      if (args) {
6944        if (isArray) {
6945          for (; i < length; i++) {
6946            value = callback.apply(obj[i], args);
6947            if (value === false) {
6948              break;
6949            }
6950          }
6951        } else {
6952          for (i in obj) {
6953            value = callback.apply(obj[i], args);
6954            if (value === false) {
6955              break;
6956            }
6957          }
6958        }
6959
6960        // A special, fast, case for the most common use of each
6961      } else {
6962        if (isArray) {
6963          for (; i < length; i++) {
6964            value = callback.call(obj[i], i, obj[i]);
6965            if (value === false) {
6966              break;
6967            }
6968          }
6969        } else {
6970          for (i in obj) {
6971            value = callback.call(obj[i], i, obj[i]);
6972            if (value === false) {
6973              break;
6974            }
6975          }
6976        }
6977      }
6978      return obj;
6979    },
6980    trim: function (text) {
6981      return text == null ? "" : core_trim.call(text);
6982    },
6983    // results is for internal usage only
6984    makeArray: function (arr, results) {
6985      var ret = results || [];
6986      if (arr != null) {
6987        if (isArraylike(Object(arr))) {
6988          jQuery.merge(ret, typeof arr === "string" ? [arr] : arr);
6989        } else {
6990          core_push.call(ret, arr);
6991        }
6992      }
6993      return ret;
6994    },
6995    inArray: function (elem, arr, i) {
6996      return arr == null ? -1 : core_indexOf.call(arr, elem, i);
6997    },
6998    merge: function (first, second) {
6999      var l = second.length,
7000        i = first.length,
7001        j = 0;
7002      if (typeof l === "number") {
7003        for (; j < l; j++) {
7004          first[i++] = second[j];
7005        }
7006      } else {
7007        while (second[j] !== undefined) {
7008          first[i++] = second[j++];
7009        }
7010      }
7011      first.length = i;
7012      return first;
7013    },
7014    grep: function (elems, callback, inv) {
7015      var retVal,
7016        ret = [],
7017        i = 0,
7018        length = elems.length;
7019      inv = !!inv;
7020
7021      // Go through the array, only saving the items
7022      // that pass the validator function
7023      for (; i < length; i++) {
7024        retVal = !!callback(elems[i], i);
7025        if (inv !== retVal) {
7026          ret.push(elems[i]);
7027        }
7028      }
7029      return ret;
7030    },
7031    // arg is for internal usage only
7032    map: function (elems, callback, arg) {
7033      var value,
7034        i = 0,
7035        length = elems.length,
7036        isArray = isArraylike(elems),
7037        ret = [];
7038
7039      // Go through the array, translating each of the items to their
7040      if (isArray) {
7041        for (; i < length; i++) {
7042          value = callback(elems[i], i, arg);
7043          if (value != null) {
7044            ret[ret.length] = value;
7045          }
7046        }
7047
7048        // Go through every key on the object,
7049      } else {
7050        for (i in elems) {
7051          value = callback(elems[i], i, arg);
7052          if (value != null) {
7053            ret[ret.length] = value;
7054          }
7055        }
7056      }
7057
7058      // Flatten any nested arrays
7059      return core_concat.apply([], ret);
7060    },
7061    // A global GUID counter for objects
7062    guid: 1,
7063    // Bind a function to a context, optionally partially applying any
7064    // arguments.
7065    proxy: function (fn, context) {
7066      var tmp, args, proxy;
7067      if (typeof context === "string") {
7068        tmp = fn[context];
7069        context = fn;
7070        fn = tmp;
7071      }
7072
7073      // Quick check to determine if target is callable, in the spec
7074      // this throws a TypeError, but we will just return undefined.
7075      if (!jQuery.isFunction(fn)) {
7076        return undefined;
7077      }
7078
7079      // Simulated bind
7080      args = core_slice.call(arguments, 2);
7081      proxy = function () {
7082        return fn.apply(context || this, args.concat(core_slice.call(arguments)));
7083      };
7084
7085      // Set the guid of unique handler to the same of original handler, so it can be removed
7086      proxy.guid = fn.guid = fn.guid || jQuery.guid++;
7087      return proxy;
7088    },
7089    // Multifunctional method to get and set values of a collection
7090    // The value/s can optionally be executed if it's a function
7091    access: function (elems, fn, key, value, chainable, emptyGet, raw) {
7092      var i = 0,
7093        length = elems.length,
7094        bulk = key == null;
7095
7096      // Sets many values
7097      if (jQuery.type(key) === "object") {
7098        chainable = true;
7099        for (i in key) {
7100          jQuery.access(elems, fn, i, key[i], true, emptyGet, raw);
7101        }
7102
7103        // Sets one value
7104      } else if (value !== undefined) {
7105        chainable = true;
7106        if (!jQuery.isFunction(value)) {
7107          raw = true;
7108        }
7109        if (bulk) {
7110          // Bulk operations run against the entire set
7111          if (raw) {
7112            fn.call(elems, value);
7113            fn = null;
7114
7115            // ...except when executing function values
7116          } else {
7117            bulk = fn;
7118            fn = function (elem, key, value) {
7119              return bulk.call(jQuery(elem), value);
7120            };
7121          }
7122        }
7123        if (fn) {
7124          for (; i < length; i++) {
7125            fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key)));
7126          }
7127        }
7128      }
7129      return chainable ? elems :
7130      // Gets
7131      bulk ? fn.call(elems) : length ? fn(elems[0], key) : emptyGet;
7132    },
7133    now: Date.now,
7134    // A method for quickly swapping in/out CSS properties to get correct calculations.
7135    // Note: this method belongs to the css module but it's needed here for the support module.
7136    // If support gets modularized, this method should be moved back to the css module.
7137    swap: function (elem, options, callback, args) {
7138      var ret,
7139        name,
7140        old = {};
7141
7142      // Remember the old values, and insert the new ones
7143      for (name in options) {
7144        old[name] = elem.style[name];
7145        elem.style[name] = options[name];
7146      }
7147      ret = callback.apply(elem, args || []);
7148
7149      // Revert the old values
7150      for (name in options) {
7151        elem.style[name] = old[name];
7152      }
7153      return ret;
7154    }
7155  });
7156  jQuery.ready.promise = function (obj) {
7157    if (!readyList) {
7158      readyList = jQuery.Deferred();
7159
7160      // Catch cases where $(document).ready() is called after the browser event has already occurred.
7161      // we once tried to use readyState "interactive" here, but it caused issues like the one
7162      // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
7163      if (document.readyState === "complete") {
7164        // Handle it asynchronously to allow scripts the opportunity to delay ready
7165        setTimeout(jQuery.ready);
7166      } else {
7167        // Use the handy event callback
7168        document.addEventListener("DOMContentLoaded", completed, false);
7169
7170        // A fallback to window.onload, that will always work
7171        window.addEventListener("load", completed, false);
7172      }
7173    }
7174    return readyList.promise(obj);
7175  };
7176
7177  // Populate the class2type map
7178  jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function (i, name) {
7179    class2type["[object " + name + "]"] = name.toLowerCase();
7180  });
7181  function isArraylike(obj) {
7182    var length = obj.length,
7183      type = jQuery.type(obj);
7184    if (jQuery.isWindow(obj)) {
7185      return false;
7186    }
7187    if (obj.nodeType === 1 && length) {
7188      return true;
7189    }
7190    return type === "array" || type !== "function" && (length === 0 || typeof length === "number" && length > 0 && length - 1 in obj);
7191  }
7192
7193  // All jQuery objects should point back to these
7194  rootjQuery = jQuery(document);
7195  /*!
7196   * Sizzle CSS Selector Engine v1.9.4-pre
7197   * http://sizzlejs.com/
7198   *
7199   * Copyright 2013 jQuery Foundation, Inc. and other contributors
7200   * Released under the MIT license
7201   * http://jquery.org/license
7202   *
7203   * Date: 2013-06-03
7204   */
7205  (function (window, undefined) {
7206    var i,
7207      support,
7208      cachedruns,
7209      Expr,
7210      getText,
7211      isXML,
7212      compile,
7213      outermostContext,
7214      sortInput,
7215      // Local document vars
7216      setDocument,
7217      document,
7218      docElem,
7219      documentIsHTML,
7220      rbuggyQSA,
7221      rbuggyMatches,
7222      matches,
7223      contains,
7224      // Instance-specific data
7225      expando = "sizzle" + -new Date(),
7226      preferredDoc = window.document,
7227      dirruns = 0,
7228      done = 0,
7229      classCache = createCache(),
7230      tokenCache = createCache(),
7231      compilerCache = createCache(),
7232      hasDuplicate = false,
7233      sortOrder = function (a, b) {
7234        if (a === b) {
7235          hasDuplicate = true;
7236          return 0;
7237        }
7238        return 0;
7239      },
7240      // General-purpose constants
7241      strundefined = typeof undefined,
7242      MAX_NEGATIVE = 1 << 31,
7243      // Instance methods
7244      hasOwn = {}.hasOwnProperty,
7245      arr = [],
7246      pop = arr.pop,
7247      push_native = arr.push,
7248      push = arr.push,
7249      slice = arr.slice,
7250      // Use a stripped-down indexOf if we can't use a native one
7251      indexOf = arr.indexOf || function (elem) {
7252        var i = 0,
7253          len = this.length;
7254        for (; i < len; i++) {
7255          if (this[i] === elem) {
7256            return i;
7257          }
7258        }
7259        return -1;
7260      },
7261      booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
7262      // Regular expressions
7263
7264      // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
7265      whitespace = "[\\x20\\t\\r\\n\\f]",
7266      // http://www.w3.org/TR/css3-syntax/#characters
7267      characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
7268      // Loosely modeled on CSS identifier characters
7269      // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
7270      // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
7271      identifier = characterEncoding.replace("w", "w#"),
7272      // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
7273      attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
7274      // Prefer arguments quoted,
7275      //   then not containing pseudos/brackets,
7276      //   then attribute selectors/non-parenthetical expressions,
7277      //   then anything else
7278      // These preferences are here to reduce the number of selectors
7279      //   needing tokenize in the PSEUDO preFilter
7280      pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace(3, 8) + ")*)|.*)\\)|)",
7281      // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
7282      rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"),
7283      rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"),
7284      rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"),
7285      rsibling = new RegExp(whitespace + "*[+~]"),
7286      rattributeQuotes = new RegExp("=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g"),
7287      rpseudo = new RegExp(pseudos),
7288      ridentifier = new RegExp("^" + identifier + "$"),
7289      matchExpr = {
7290        "ID": new RegExp("^#(" + characterEncoding + ")"),
7291        "CLASS": new RegExp("^\\.(" + characterEncoding + ")"),
7292        "TAG": new RegExp("^(" + characterEncoding.replace("w", "w*") + ")"),
7293        "ATTR": new RegExp("^" + attributes),
7294        "PSEUDO": new RegExp("^" + pseudos),
7295        "CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i"),
7296        "bool": new RegExp("^(?:" + booleans + ")$", "i"),
7297        // For use in libraries implementing .is()
7298        // We use this for POS matching in `select`
7299        "needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i")
7300      },
7301      rnative = /^[^{]+\{\s*\[native \w/,
7302      // Easily-parseable/retrievable ID or TAG or CLASS selectors
7303      rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
7304      rinputs = /^(?:input|select|textarea|button)$/i,
7305      rheader = /^h\d$/i,
7306      rescape = /'|\\/g,
7307      // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
7308      runescape = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"),
7309      funescape = function (_, escaped, escapedWhitespace) {
7310        var high = "0x" + escaped - 0x10000;
7311        // NaN means non-codepoint
7312        // Support: Firefox
7313        // Workaround erroneous numeric interpretation of +"0x"
7314        return high !== high || escapedWhitespace ? escaped :
7315        // BMP codepoint
7316        high < 0 ? String.fromCharCode(high + 0x10000) :
7317        // Supplemental Plane codepoint (surrogate pair)
7318        String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);
7319      };
7320
7321    // Optimize for push.apply( _, NodeList )
7322    try {
7323      push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes);
7324      // Support: Android<4.0
7325      // Detect silently failing push.apply
7326      arr[preferredDoc.childNodes.length].nodeType;
7327    } catch (e) {
7328      push = {
7329        apply: arr.length ?
7330        // Leverage slice if possible
7331        function (target, els) {
7332          push_native.apply(target, slice.call(els));
7333        } :
7334        // Support: IE<9
7335        // Otherwise append directly
7336        function (target, els) {
7337          var j = target.length,
7338            i = 0;
7339          // Can't trust NodeList.length
7340          while (target[j++] = els[i++]) {}
7341          target.length = j - 1;
7342        }
7343      };
7344    }
7345    function Sizzle(selector, context, results, seed) {
7346      var match, elem, m, nodeType,
7347        // QSA vars
7348        i, groups, old, nid, newContext, newSelector;
7349      if ((context ? context.ownerDocument || context : preferredDoc) !== document) {
7350        setDocument(context);
7351      }
7352      context = context || document;
7353      results = results || [];
7354      if (!selector || typeof selector !== "string") {
7355        return results;
7356      }
7357      if ((nodeType = context.nodeType) !== 1 && nodeType !== 9) {
7358        return [];
7359      }
7360      if (documentIsHTML && !seed) {
7361        // Shortcuts
7362        if (match = rquickExpr.exec(selector)) {
7363          // Speed-up: Sizzle("#ID")
7364          if (m = match[1]) {
7365            if (nodeType === 9) {
7366              elem = context.getElementById(m);
7367              // Check parentNode to catch when Blackberry 4.6 returns
7368              // nodes that are no longer in the document #6963
7369              if (elem && elem.parentNode) {
7370                // Handle the case where IE, Opera, and Webkit return items
7371                // by name instead of ID
7372                if (elem.id === m) {
7373                  results.push(elem);
7374                  return results;
7375                }
7376              } else {
7377                return results;
7378              }
7379            } else {
7380              // Context is not a document
7381              if (context.ownerDocument && (elem = context.ownerDocument.getElementById(m)) && contains(context, elem) && elem.id === m) {
7382                results.push(elem);
7383                return results;
7384              }
7385            }
7386
7387            // Speed-up: Sizzle("TAG")
7388          } else if (match[2]) {
7389            push.apply(results, context.getElementsByTagName(selector));
7390            return results;
7391
7392            // Speed-up: Sizzle(".CLASS")
7393          } else if ((m = match[3]) && support.getElementsByClassName && context.getElementsByClassName) {
7394            push.apply(results, context.getElementsByClassName(m));
7395            return results;
7396          }
7397        }
7398
7399        // QSA path
7400        if (support.qsa && (!rbuggyQSA || !rbuggyQSA.test(selector))) {
7401          nid = old = expando;
7402          newContext = context;
7403          newSelector = nodeType === 9 && selector;
7404
7405          // qSA works strangely on Element-rooted queries
7406          // We can work around this by specifying an extra ID on the root
7407          // and working up from there (Thanks to Andrew Dupont for the technique)
7408          // IE 8 doesn't work on object elements
7409          if (nodeType === 1 && context.nodeName.toLowerCase() !== "object") {
7410            groups = tokenize(selector);
7411            if (old = context.getAttribute("id")) {
7412              nid = old.replace(rescape, "\\$&");
7413            } else {
7414              context.setAttribute("id", nid);
7415            }
7416            nid = "[id='" + nid + "'] ";
7417            i = groups.length;
7418            while (i--) {
7419              groups[i] = nid + toSelector(groups[i]);
7420            }
7421            newContext = rsibling.test(selector) && context.parentNode || context;
7422            newSelector = groups.join(",");
7423          }
7424          if (newSelector) {
7425            try {
7426              push.apply(results, newContext.querySelectorAll(newSelector));
7427              return results;
7428            } catch (qsaError) {} finally {
7429              if (!old) {
7430                context.removeAttribute("id");
7431              }
7432            }
7433          }
7434        }
7435      }
7436
7437      // All others
7438      return select(selector.replace(rtrim, "$1"), context, results, seed);
7439    }
7440
7441    /**
7442     * Create key-value caches of limited size
7443     * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
7444     *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
7445     *	deleting the oldest entry
7446     */
7447    function createCache() {
7448      var keys = [];
7449      function cache(key, value) {
7450        // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
7451        if (keys.push(key += " ") > Expr.cacheLength) {
7452          // Only keep the most recent entries
7453          delete cache[keys.shift()];
7454        }
7455        return cache[key] = value;
7456      }
7457      return cache;
7458    }
7459
7460    /**
7461     * Mark a function for special use by Sizzle
7462     * @param {Function} fn The function to mark
7463     */
7464    function markFunction(fn) {
7465      fn[expando] = true;
7466      return fn;
7467    }
7468
7469    /**
7470     * Support testing using an element
7471     * @param {Function} fn Passed the created div and expects a boolean result
7472     */
7473    function assert(fn) {
7474      var div = document.createElement("div");
7475      try {
7476        return !!fn(div);
7477      } catch (e) {
7478        return false;
7479      } finally {
7480        // Remove from its parent by default
7481        if (div.parentNode) {
7482          div.parentNode.removeChild(div);
7483        }
7484        // release memory in IE
7485        div = null;
7486      }
7487    }
7488
7489    /**
7490     * Adds the same handler for all of the specified attrs
7491     * @param {String} attrs Pipe-separated list of attributes
7492     * @param {Function} handler The method that will be applied
7493     */
7494    function addHandle(attrs, handler) {
7495      var arr = attrs.split("|"),
7496        i = attrs.length;
7497      while (i--) {
7498        Expr.attrHandle[arr[i]] = handler;
7499      }
7500    }
7501
7502    /**
7503     * Checks document order of two siblings
7504     * @param {Element} a
7505     * @param {Element} b
7506     * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
7507     */
7508    function siblingCheck(a, b) {
7509      var cur = b && a,
7510        diff = cur && a.nodeType === 1 && b.nodeType === 1 && (~b.sourceIndex || MAX_NEGATIVE) - (~a.sourceIndex || MAX_NEGATIVE);
7511
7512      // Use IE sourceIndex if available on both nodes
7513      if (diff) {
7514        return diff;
7515      }
7516
7517      // Check if b follows a
7518      if (cur) {
7519        while (cur = cur.nextSibling) {
7520          if (cur === b) {
7521            return -1;
7522          }
7523        }
7524      }
7525      return a ? 1 : -1;
7526    }
7527
7528    /**
7529     * Returns a function to use in pseudos for input types
7530     * @param {String} type
7531     */
7532    function createInputPseudo(type) {
7533      return function (elem) {
7534        var name = elem.nodeName.toLowerCase();
7535        return name === "input" && elem.type === type;
7536      };
7537    }
7538
7539    /**
7540     * Returns a function to use in pseudos for buttons
7541     * @param {String} type
7542     */
7543    function createButtonPseudo(type) {
7544      return function (elem) {
7545        var name = elem.nodeName.toLowerCase();
7546        return (name === "input" || name === "button") && elem.type === type;
7547      };
7548    }
7549
7550    /**
7551     * Returns a function to use in pseudos for positionals
7552     * @param {Function} fn
7553     */
7554    function createPositionalPseudo(fn) {
7555      return markFunction(function (argument) {
7556        argument = +argument;
7557        return markFunction(function (seed, matches) {
7558          var j,
7559            matchIndexes = fn([], seed.length, argument),
7560            i = matchIndexes.length;
7561
7562          // Match elements found at the specified indexes
7563          while (i--) {
7564            if (seed[j = matchIndexes[i]]) {
7565              seed[j] = !(matches[j] = seed[j]);
7566            }
7567          }
7568        });
7569      });
7570    }
7571
7572    /**
7573     * Detect xml
7574     * @param {Element|Object} elem An element or a document
7575     */
7576    isXML = Sizzle.isXML = function (elem) {
7577      // documentElement is verified for cases where it doesn't yet exist
7578      // (such as loading iframes in IE - #4833)
7579      var documentElement = elem && (elem.ownerDocument || elem).documentElement;
7580      return documentElement ? documentElement.nodeName !== "HTML" : false;
7581    };
7582
7583    // Expose support vars for convenience
7584    support = Sizzle.support = {};
7585
7586    /**
7587     * Sets document-related variables once based on the current document
7588     * @param {Element|Object} [doc] An element or document object to use to set the document
7589     * @returns {Object} Returns the current document
7590     */
7591    setDocument = Sizzle.setDocument = function (node) {
7592      var doc = node ? node.ownerDocument || node : preferredDoc,
7593        parent = doc.defaultView;
7594
7595      // If no document and documentElement is available, return
7596      if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {
7597        return document;
7598      }
7599
7600      // Set our document
7601      document = doc;
7602      docElem = doc.documentElement;
7603
7604      // Support tests
7605      documentIsHTML = !isXML(doc);
7606
7607      // Support: IE>8
7608      // If iframe document is assigned to "document" variable and if iframe has been reloaded,
7609      // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
7610      // IE6-8 do not support the defaultView property so parent will be undefined
7611      if (parent && parent.attachEvent && parent !== parent.top) {
7612        parent.attachEvent("onbeforeunload", function () {
7613          setDocument();
7614        });
7615      }
7616
7617      /* Attributes
7618      ---------------------------------------------------------------------- */
7619
7620      // Support: IE<8
7621      // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
7622      support.attributes = assert(function (div) {
7623        div.className = "i";
7624        return !div.getAttribute("className");
7625      });
7626
7627      /* getElement(s)By*
7628      ---------------------------------------------------------------------- */
7629
7630      // Check if getElementsByTagName("*") returns only elements
7631      support.getElementsByTagName = assert(function (div) {
7632        div.appendChild(doc.createComment(""));
7633        return !div.getElementsByTagName("*").length;
7634      });
7635
7636      // Check if getElementsByClassName can be trusted
7637      support.getElementsByClassName = assert(function (div) {
7638        div.innerHTML = "<div class='a'></div><div class='a i'></div>";
7639
7640        // Support: Safari<4
7641        // Catch class over-caching
7642        div.firstChild.className = "i";
7643        // Support: Opera<10
7644        // Catch gEBCN failure to find non-leading classes
7645        return div.getElementsByClassName("i").length === 2;
7646      });
7647
7648      // Support: IE<10
7649      // Check if getElementById returns elements by name
7650      // The broken getElementById methods don't pick up programatically-set names,
7651      // so use a roundabout getElementsByName test
7652      support.getById = assert(function (div) {
7653        docElem.appendChild(div).id = expando;
7654        return !doc.getElementsByName || !doc.getElementsByName(expando).length;
7655      });
7656
7657      // ID find and filter
7658      if (support.getById) {
7659        Expr.find["ID"] = function (id, context) {
7660          if (typeof context.getElementById !== strundefined && documentIsHTML) {
7661            var m = context.getElementById(id);
7662            // Check parentNode to catch when Blackberry 4.6 returns
7663            // nodes that are no longer in the document #6963
7664            return m && m.parentNode ? [m] : [];
7665          }
7666        };
7667        Expr.filter["ID"] = function (id) {
7668          var attrId = id.replace(runescape, funescape);
7669          return function (elem) {
7670            return elem.getAttribute("id") === attrId;
7671          };
7672        };
7673      } else {
7674        // Support: IE6/7
7675        // getElementById is not reliable as a find shortcut
7676        delete Expr.find["ID"];
7677        Expr.filter["ID"] = function (id) {
7678          var attrId = id.replace(runescape, funescape);
7679          return function (elem) {
7680            var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
7681            return node && node.value === attrId;
7682          };
7683        };
7684      }
7685
7686      // Tag
7687      Expr.find["TAG"] = support.getElementsByTagName ? function (tag, context) {
7688        if (typeof context.getElementsByTagName !== strundefined) {
7689          return context.getElementsByTagName(tag);
7690        }
7691      } : function (tag, context) {
7692        var elem,
7693          tmp = [],
7694          i = 0,
7695          results = context.getElementsByTagName(tag);
7696
7697        // Filter out possible comments
7698        if (tag === "*") {
7699          while (elem = results[i++]) {
7700            if (elem.nodeType === 1) {
7701              tmp.push(elem);
7702            }
7703          }
7704          return tmp;
7705        }
7706        return results;
7707      };
7708
7709      // Class
7710      Expr.find["CLASS"] = support.getElementsByClassName && function (className, context) {
7711        if (typeof context.getElementsByClassName !== strundefined && documentIsHTML) {
7712          return context.getElementsByClassName(className);
7713        }
7714      };
7715
7716      /* QSA/matchesSelector
7717      ---------------------------------------------------------------------- */
7718
7719      // QSA and matchesSelector support
7720
7721      // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
7722      rbuggyMatches = [];
7723
7724      // qSa(:focus) reports false when true (Chrome 21)
7725      // We allow this because of a bug in IE8/9 that throws an error
7726      // whenever `document.activeElement` is accessed on an iframe
7727      // So, we allow :focus to pass through QSA all the time to avoid the IE error
7728      // See http://bugs.jquery.com/ticket/13378
7729      rbuggyQSA = [];
7730      if (support.qsa = rnative.test(doc.querySelectorAll)) {
7731        // Build QSA regex
7732        // Regex strategy adopted from Diego Perini
7733        assert(function (div) {
7734          // Select is set to empty string on purpose
7735          // This is to test IE's treatment of not explicitly
7736          // setting a boolean content attribute,
7737          // since its presence should be enough
7738          // http://bugs.jquery.com/ticket/12359
7739          div.innerHTML = "<select><option selected=''></option></select>";
7740
7741          // Support: IE8
7742          // Boolean attributes and "value" are not treated correctly
7743          if (!div.querySelectorAll("[selected]").length) {
7744            rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")");
7745          }
7746
7747          // Webkit/Opera - :checked should return selected option elements
7748          // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
7749          // IE8 throws error here and will not see later tests
7750          if (!div.querySelectorAll(":checked").length) {
7751            rbuggyQSA.push(":checked");
7752          }
7753        });
7754        assert(function (div) {
7755          // Support: Opera 10-12/IE8
7756          // ^= $= *= and empty values
7757          // Should not select anything
7758          // Support: Windows 8 Native Apps
7759          // The type attribute is restricted during .innerHTML assignment
7760          var input = doc.createElement("input");
7761          input.setAttribute("type", "hidden");
7762          div.appendChild(input).setAttribute("t", "");
7763          if (div.querySelectorAll("[t^='']").length) {
7764            rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")");
7765          }
7766
7767          // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
7768          // IE8 throws error here and will not see later tests
7769          if (!div.querySelectorAll(":enabled").length) {
7770            rbuggyQSA.push(":enabled", ":disabled");
7771          }
7772
7773          // Opera 10-11 does not throw on post-comma invalid pseudos
7774          div.querySelectorAll("*,:x");
7775          rbuggyQSA.push(",.*:");
7776        });
7777      }
7778      if (support.matchesSelector = rnative.test(matches = docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector)) {
7779        assert(function (div) {
7780          // Check to see if it's possible to do matchesSelector
7781          // on a disconnected node (IE 9)
7782          support.disconnectedMatch = matches.call(div, "div");
7783
7784          // This should fail with an exception
7785          // Gecko does not error, returns false instead
7786          matches.call(div, "[s!='']:x");
7787          rbuggyMatches.push("!=", pseudos);
7788        });
7789      }
7790      rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));
7791      rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|"));
7792
7793      /* Contains
7794      ---------------------------------------------------------------------- */
7795
7796      // Element contains another
7797      // Purposefully does not implement inclusive descendent
7798      // As in, an element does not contain itself
7799      contains = rnative.test(docElem.contains) || docElem.compareDocumentPosition ? function (a, b) {
7800        var adown = a.nodeType === 9 ? a.documentElement : a,
7801          bup = b && b.parentNode;
7802        return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));
7803      } : function (a, b) {
7804        if (b) {
7805          while (b = b.parentNode) {
7806            if (b === a) {
7807              return true;
7808            }
7809          }
7810        }
7811        return false;
7812      };
7813
7814      /* Sorting
7815      ---------------------------------------------------------------------- */
7816
7817      // Document order sorting
7818      sortOrder = docElem.compareDocumentPosition ? function (a, b) {
7819        // Flag for duplicate removal
7820        if (a === b) {
7821          hasDuplicate = true;
7822          return 0;
7823        }
7824        var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition(b);
7825        if (compare) {
7826          // Disconnected nodes
7827          if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) {
7828            // Choose the first element that is related to our preferred document
7829            if (a === doc || contains(preferredDoc, a)) {
7830              return -1;
7831            }
7832            if (b === doc || contains(preferredDoc, b)) {
7833              return 1;
7834            }
7835
7836            // Maintain original order
7837            return sortInput ? indexOf.call(sortInput, a) - indexOf.call(sortInput, b) : 0;
7838          }
7839          return compare & 4 ? -1 : 1;
7840        }
7841
7842        // Not directly comparable, sort on existence of method
7843        return a.compareDocumentPosition ? -1 : 1;
7844      } : function (a, b) {
7845        var cur,
7846          i = 0,
7847          aup = a.parentNode,
7848          bup = b.parentNode,
7849          ap = [a],
7850          bp = [b];
7851
7852        // Exit early if the nodes are identical
7853        if (a === b) {
7854          hasDuplicate = true;
7855          return 0;
7856
7857          // Parentless nodes are either documents or disconnected
7858        } else if (!aup || !bup) {
7859          return a === doc ? -1 : b === doc ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf.call(sortInput, a) - indexOf.call(sortInput, b) : 0;
7860
7861          // If the nodes are siblings, we can do a quick check
7862        } else if (aup === bup) {
7863          return siblingCheck(a, b);
7864        }
7865
7866        // Otherwise we need full lists of their ancestors for comparison
7867        cur = a;
7868        while (cur = cur.parentNode) {
7869          ap.unshift(cur);
7870        }
7871        cur = b;
7872        while (cur = cur.parentNode) {
7873          bp.unshift(cur);
7874        }
7875
7876        // Walk down the tree looking for a discrepancy
7877        while (ap[i] === bp[i]) {
7878          i++;
7879        }
7880        return i ?
7881        // Do a sibling check if the nodes have a common ancestor
7882        siblingCheck(ap[i], bp[i]) :
7883        // Otherwise nodes in our document sort first
7884        ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0;
7885      };
7886      return doc;
7887    };
7888    Sizzle.matches = function (expr, elements) {
7889      return Sizzle(expr, null, null, elements);
7890    };
7891    Sizzle.matchesSelector = function (elem, expr) {
7892      // Set document vars if needed
7893      if ((elem.ownerDocument || elem) !== document) {
7894        setDocument(elem);
7895      }
7896
7897      // Make sure that attribute selectors are quoted
7898      expr = expr.replace(rattributeQuotes, "='$1']");
7899      if (support.matchesSelector && documentIsHTML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) {
7900        try {
7901          var ret = matches.call(elem, expr);
7902
7903          // IE 9's matchesSelector returns false on disconnected nodes
7904          if (ret || support.disconnectedMatch ||
7905          // As well, disconnected nodes are said to be in a document
7906          // fragment in IE 9
7907          elem.document && elem.document.nodeType !== 11) {
7908            return ret;
7909          }
7910        } catch (e) {}
7911      }
7912      return Sizzle(expr, document, null, [elem]).length > 0;
7913    };
7914    Sizzle.contains = function (context, elem) {
7915      // Set document vars if needed
7916      if ((context.ownerDocument || context) !== document) {
7917        setDocument(context);
7918      }
7919      return contains(context, elem);
7920    };
7921    Sizzle.attr = function (elem, name) {
7922      // Set document vars if needed
7923      if ((elem.ownerDocument || elem) !== document) {
7924        setDocument(elem);
7925      }
7926      var fn = Expr.attrHandle[name.toLowerCase()],
7927        // Don't get fooled by Object.prototype properties (jQuery #13807)
7928        val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined;
7929      return val === undefined ? support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null : val;
7930    };
7931    Sizzle.error = function (msg) {
7932      throw new Error("Syntax error, unrecognized expression: " + msg);
7933    };
7934
7935    /**
7936     * Document sorting and removing duplicates
7937     * @param {ArrayLike} results
7938     */
7939    Sizzle.uniqueSort = function (results) {
7940      var elem,
7941        duplicates = [],
7942        j = 0,
7943        i = 0;
7944
7945      // Unless we *know* we can detect duplicates, assume their presence
7946      hasDuplicate = !support.detectDuplicates;
7947      sortInput = !support.sortStable && results.slice(0);
7948      results.sort(sortOrder);
vendor: 5,928 bytes, lines 7949-8109
7949      if (hasDuplicate) {
7950        while (elem = results[i++]) {
7951          if (elem === results[i]) {
7952            j = duplicates.push(i);
7953          }
7954        }
7955        while (j--) {
7956          results.splice(duplicates[j], 1);
7957        }
7958      }
7959      return results;
7960    };
7961
7962    /**
7963     * Utility function for retrieving the text value of an array of DOM nodes
7964     * @param {Array|Element} elem
7965     */
7966    getText = Sizzle.getText = function (elem) {
7967      var node,
7968        ret = "",
7969        i = 0,
7970        nodeType = elem.nodeType;
7971      if (!nodeType) {
7972        // If no nodeType, this is expected to be an array
7973        for (; node = elem[i]; i++) {
7974          // Do not traverse comment nodes
7975          ret += getText(node);
7976        }
7977      } else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
7978        // Use textContent for elements
7979        // innerText usage removed for consistency of new lines (see #11153)
7980        if (typeof elem.textContent === "string") {
7981          return elem.textContent;
7982        } else {
7983          // Traverse its children
7984          for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
7985            ret += getText(elem);
7986          }
7987        }
7988      } else if (nodeType === 3 || nodeType === 4) {
7989        return elem.nodeValue;
7990      }
7991      // Do not include comment or processing instruction nodes
7992
7993      return ret;
7994    };
7995    Expr = Sizzle.selectors = {
7996      // Can be adjusted by the user
7997      cacheLength: 50,
7998      createPseudo: markFunction,
7999      match: matchExpr,
8000      attrHandle: {},
8001      find: {},
8002      relative: {
8003        ">": {
8004          dir: "parentNode",
8005          first: true
8006        },
8007        " ": {
8008          dir: "parentNode"
8009        },
8010        "+": {
8011          dir: "previousSibling",
8012          first: true
8013        },
8014        "~": {
8015          dir: "previousSibling"
8016        }
8017      },
8018      preFilter: {
8019        "ATTR": function (match) {
8020          match[1] = match[1].replace(runescape, funescape);
8021
8022          // Move the given value to match[3] whether quoted or unquoted
8023          match[3] = (match[4] || match[5] || "").replace(runescape, funescape);
8024          if (match[2] === "~=") {
8025            match[3] = " " + match[3] + " ";
8026          }
8027          return match.slice(0, 4);
8028        },
8029        "CHILD": function (match) {
8030          /* matches from matchExpr["CHILD"]
8031          	1 type (only|nth|...)
8032          	2 what (child|of-type)
8033          	3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
8034          	4 xn-component of xn+y argument ([+-]?\d*n|)
8035          	5 sign of xn-component
8036          	6 x of xn-component
8037          	7 sign of y-component
8038          	8 y of y-component
8039          */
8040          match[1] = match[1].toLowerCase();
8041          if (match[1].slice(0, 3) === "nth") {
8042            // nth-* requires argument
8043            if (!match[3]) {
8044              Sizzle.error(match[0]);
8045            }
8046
8047            // numeric x and y parameters for Expr.filter.CHILD
8048            // remember that false/true cast respectively to 0/1
8049            match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd"));
8050            match[5] = +(match[7] + match[8] || match[3] === "odd");
8051
8052            // other types prohibit arguments
8053          } else if (match[3]) {
8054            Sizzle.error(match[0]);
8055          }
8056          return match;
8057        },
8058        "PSEUDO": function (match) {
8059          var excess,
8060            unquoted = !match[5] && match[2];
8061          if (matchExpr["CHILD"].test(match[0])) {
8062            return null;
8063          }
8064
8065          // Accept quoted arguments as-is
8066          if (match[3] && match[4] !== undefined) {
8067            match[2] = match[4];
8068
8069            // Strip excess characters from unquoted arguments
8070          } else if (unquoted && rpseudo.test(unquoted) && (
8071          // Get excess from tokenize (recursively)
8072          excess = tokenize(unquoted, true)) && (
8073          // advance to the next closing parenthesis
8074          excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {
8075            // excess is a negative index
8076            match[0] = match[0].slice(0, excess);
8077            match[2] = unquoted.slice(0, excess);
8078          }
8079
8080          // Return only captures needed by the pseudo filter method (type and argument)
8081          return match.slice(0, 3);
8082        }
8083      },
8084      filter: {
8085        "TAG": function (nodeNameSelector) {
8086          var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
8087          return nodeNameSelector === "*" ? function () {
8088            return true;
8089          } : function (elem) {
8090            return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
8091          };
8092        },
8093        "CLASS": function (className) {
8094          var pattern = classCache[className + " "];
8095          return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && classCache(className, function (elem) {
8096            return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "");
8097          });
8098        },
8099        "ATTR": function (name, operator, check) {
8100          return function (elem) {
8101            var result = Sizzle.attr(elem, name);
8102            if (result == null) {
8103              return operator === "!=";
8104            }
8105            if (!operator) {
8106              return true;
8107            }
8108            result += "";
8109            return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf(check) === 0 : operator === "*=" ? check && result.indexOf(check) > -1 : operator === "$=" ? check && result.slice(-check.length) === check : operator === "~=" ? (" " + result + " ").indexOf(check) > -1 : operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-" : false;
8110          };
8111        },
8112        "CHILD": function (type, what, argument, first, last) {
8113          var simple = type.slice(0, 3) !== "nth",
8114            forward = type.slice(-4) !== "last",
8115            ofType = what === "of-type";
8116          return first === 1 && last === 0 ?
8117          // Shortcut for :nth-*(n)
8118          function (elem) {
8119            return !!elem.parentNode;
8120          } : function (elem, context, xml) {
8121            var cache,
8122              outerCache,
8123              node,
8124              diff,
8125              nodeIndex,
8126              start,
8127              dir = simple !== forward ? "nextSibling" : "previousSibling",
8128              parent = elem.parentNode,
8129              name = ofType && elem.nodeName.toLowerCase(),
8130              useCache = !xml && !ofType;
8131            if (parent) {
8132              // :(first|last|only)-(child|of-type)
8133              if (simple) {
8134                while (dir) {
8135                  node = elem;
8136                  while (node = node[dir]) {
8137                    if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) {
8138                      return false;
8139                    }
8140                  }
8141                  // Reverse direction for :only-* (if we haven't yet done so)
8142                  start = dir = type === "only" && !start && "nextSibling";
8143                }
8144                return true;
8145              }
8146              start = [forward ? parent.firstChild : parent.lastChild];
8147
8148              // non-xml :nth-child(...) stores cache data on `parent`
8149              if (forward && useCache) {
8150                // Seek `elem` from a previously-cached index
8151                outerCache = parent[expando] || (parent[expando] = {});
8152                cache = outerCache[type] || [];
8153                nodeIndex = cache[0] === dirruns && cache[1];
8154                diff = cache[0] === dirruns && cache[2];
8155                node = nodeIndex && parent.childNodes[nodeIndex];
8156                while (node = ++nodeIndex && node && node[dir] || (
8157                // Fallback to seeking `elem` from the start
8158                diff = nodeIndex = 0) || start.pop()) {
8159                  // When found, cache indexes on `parent` and break
8160                  if (node.nodeType === 1 && ++diff && node === elem) {
8161                    outerCache[type] = [dirruns, nodeIndex, diff];
8162                    break;
8163                  }
8164                }
8165
8166                // Use previously-cached element index if available
8167              } else if (useCache && (cache = (elem[expando] || (elem[expando] = {}))[type]) && cache[0] === dirruns) {
8168                diff = cache[1];
8169
8170                // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
8171              } else {
8172                // Use the same loop as above to seek `elem` from the start
8173                while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
8174                  if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) {
8175                    // Cache the index of each encountered element
8176                    if (useCache) {
8177                      (node[expando] || (node[expando] = {}))[type] = [dirruns, diff];
8178                    }
8179                    if (node === elem) {
8180                      break;
8181                    }
8182                  }
8183                }
8184              }
8185
8186              // Incorporate the offset, then check against cycle size
8187              diff -= last;
8188              return diff === first || diff % first === 0 && diff / first >= 0;
8189            }
8190          };
8191        },
8192        "PSEUDO": function (pseudo, argument) {
8193          // pseudo-class names are case-insensitive
8194          // http://www.w3.org/TR/selectors/#pseudo-classes
8195          // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
8196          // Remember that setFilters inherits from pseudos
8197          var args,
8198            fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error("unsupported pseudo: " + pseudo);
8199
8200          // The user may use createPseudo to indicate that
8201          // arguments are needed to create the filter function
8202          // just as Sizzle does
8203          if (fn[expando]) {
8204            return fn(argument);
8205          }
8206
8207          // But maintain support for old signatures
8208          if (fn.length > 1) {
8209            args = [pseudo, pseudo, "", argument];
8210            return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) {
8211              var idx,
8212                matched = fn(seed, argument),
8213                i = matched.length;
8214              while (i--) {
8215                idx = indexOf.call(seed, matched[i]);
8216                seed[idx] = !(matches[idx] = matched[i]);
8217              }
8218            }) : function (elem) {
8219              return fn(elem, 0, args);
8220            };
8221          }
8222          return fn;
8223        }
8224      },
8225      pseudos: {
8226        // Potentially complex pseudos
8227        "not": markFunction(function (selector) {
8228          // Trim the selector passed to compile
8229          // to avoid treating leading and trailing
8230          // spaces as combinators
8231          var input = [],
8232            results = [],
8233            matcher = compile(selector.replace(rtrim, "$1"));
8234          return matcher[expando] ? markFunction(function (seed, matches, context, xml) {
8235            var elem,
8236              unmatched = matcher(seed, null, xml, []),
8237              i = seed.length;
8238
8239            // Match elements unmatched by `matcher`
8240            while (i--) {
8241              if (elem = unmatched[i]) {
8242                seed[i] = !(matches[i] = elem);
8243              }
8244            }
8245          }) : function (elem, context, xml) {
8246            input[0] = elem;
8247            matcher(input, null, xml, results);
8248            return !results.pop();
8249          };
8250        }),
8251        "has": markFunction(function (selector) {
8252          return function (elem) {
8253            return Sizzle(selector, elem).length > 0;
8254          };
8255        }),
8256        "contains": markFunction(function (text) {
8257          return function (elem) {
8258            return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;
8259          };
8260        }),
8261        // "Whether an element is represented by a :lang() selector
8262        // is based solely on the element's language value
8263        // being equal to the identifier C,
8264        // or beginning with the identifier C immediately followed by "-".
8265        // The matching of C against the element's language value is performed case-insensitively.
8266        // The identifier C does not have to be a valid language name."
8267        // http://www.w3.org/TR/selectors/#lang-pseudo
8268        "lang": markFunction(function (lang) {
8269          // lang value must be a valid identifier
8270          if (!ridentifier.test(lang || "")) {
8271            Sizzle.error("unsupported lang: " + lang);
8272          }
8273          lang = lang.replace(runescape, funescape).toLowerCase();
8274          return function (elem) {
8275            var elemLang;
8276            do {
8277              if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) {
8278                elemLang = elemLang.toLowerCase();
8279                return elemLang === lang || elemLang.indexOf(lang + "-") === 0;
8280              }
8281            } while ((elem = elem.parentNode) && elem.nodeType === 1);
8282            return false;
8283          };
8284        }),
8285        // Miscellaneous
8286        "target": function (elem) {
8287          var hash = window.location && window.location.hash;
8288          return hash && hash.slice(1) === elem.id;
8289        },
8290        "root": function (elem) {
8291          return elem === docElem;
8292        },
8293        "focus": function (elem) {
8294          return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
8295        },
8296        // Boolean properties
8297        "enabled": function (elem) {
8298          return elem.disabled === false;
8299        },
8300        "disabled": function (elem) {
8301          return elem.disabled === true;
8302        },
8303        "checked": function (elem) {
8304          // In CSS3, :checked should return both checked and selected elements
8305          // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
8306          var nodeName = elem.nodeName.toLowerCase();
8307          return nodeName === "input" && !!elem.checked || nodeName === "option" && !!elem.selected;
8308        },
8309        "selected": function (elem) {
8310          // Accessing this property makes selected-by-default
8311          // options in Safari work properly
8312          if (elem.parentNode) {
8313            elem.parentNode.selectedIndex;
8314          }
8315          return elem.selected === true;
8316        },
8317        // Contents
8318        "empty": function (elem) {
8319          // http://www.w3.org/TR/selectors/#empty-pseudo
8320          // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
8321          //   not comment, processing instructions, or others
8322          // Thanks to Diego Perini for the nodeName shortcut
8323          //   Greater than "@" means alpha characters (specifically not starting with "#" or "?")
8324          for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
8325            if (elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4) {
8326              return false;
8327            }
8328          }
8329          return true;
8330        },
8331        "parent": function (elem) {
8332          return !Expr.pseudos["empty"](elem);
8333        },
8334        // Element/input types
8335        "header": function (elem) {
8336          return rheader.test(elem.nodeName);
8337        },
8338        "input": function (elem) {
8339          return rinputs.test(elem.nodeName);
8340        },
8341        "button": function (elem) {
8342          var name = elem.nodeName.toLowerCase();
8343          return name === "input" && elem.type === "button" || name === "button";
8344        },
8345        "text": function (elem) {
8346          var attr;
8347          // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
8348          // use getAttribute instead to test this case
8349          return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && ((attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type);
8350        },
8351        // Position-in-collection
8352        "first": createPositionalPseudo(function () {
8353          return [0];
8354        }),
8355        "last": createPositionalPseudo(function (matchIndexes, length) {
8356          return [length - 1];
8357        }),
8358        "eq": createPositionalPseudo(function (matchIndexes, length, argument) {
8359          return [argument < 0 ? argument + length : argument];
8360        }),
8361        "even": createPositionalPseudo(function (matchIndexes, length) {
8362          var i = 0;
8363          for (; i < length; i += 2) {
8364            matchIndexes.push(i);
8365          }
8366          return matchIndexes;
8367        }),
8368        "odd": createPositionalPseudo(function (matchIndexes, length) {
8369          var i = 1;
8370          for (; i < length; i += 2) {
8371            matchIndexes.push(i);
8372          }
8373          return matchIndexes;
8374        }),
8375        "lt": createPositionalPseudo(function (matchIndexes, length, argument) {
8376          var i = argument < 0 ? argument + length : argument;
8377          for (; --i >= 0;) {
8378            matchIndexes.push(i);
8379          }
8380          return matchIndexes;
8381        }),
8382        "gt": createPositionalPseudo(function (matchIndexes, length, argument) {
8383          var i = argument < 0 ? argument + length : argument;
8384          for (; ++i < length;) {
8385            matchIndexes.push(i);
8386          }
8387          return matchIndexes;
8388        })
8389      }
8390    };
8391    Expr.pseudos["nth"] = Expr.pseudos["eq"];
8392
8393    // Add button/input type pseudos
8394    for (i in {
8395      radio: true,
8396      checkbox: true,
8397      file: true,
8398      password: true,
8399      image: true
8400    }) {
8401      Expr.pseudos[i] = createInputPseudo(i);
8402    }
8403    for (i in {
8404      submit: true,
8405      reset: true
8406    }) {
8407      Expr.pseudos[i] = createButtonPseudo(i);
8408    }
8409
8410    // Easy API for creating new setFilters
8411    function setFilters() {}
8412    setFilters.prototype = Expr.filters = Expr.pseudos;
8413    Expr.setFilters = new setFilters();
8414    function tokenize(selector, parseOnly) {
8415      var matched,
8416        match,
8417        tokens,
8418        type,
8419        soFar,
8420        groups,
8421        preFilters,
8422        cached = tokenCache[selector + " "];
8423      if (cached) {
8424        return parseOnly ? 0 : cached.slice(0);
8425      }
8426      soFar = selector;
8427      groups = [];
8428      preFilters = Expr.preFilter;
8429      while (soFar) {
8430        // Comma and first run
8431        if (!matched || (match = rcomma.exec(soFar))) {
8432          if (match) {
8433            // Don't consume trailing commas as valid
8434            soFar = soFar.slice(match[0].length) || soFar;
8435          }
8436          groups.push(tokens = []);
8437        }
8438        matched = false;
8439
8440        // Combinators
8441        if (match = rcombinators.exec(soFar)) {
8442          matched = match.shift();
8443          tokens.push({
8444            value: matched,
8445            // Cast descendant combinators to space
8446            type: match[0].replace(rtrim, " ")
8447          });
8448          soFar = soFar.slice(matched.length);
8449        }
8450
8451        // Filters
8452        for (type in Expr.filter) {
8453          if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {
8454            matched = match.shift();
8455            tokens.push({
8456              value: matched,
8457              type: type,
8458              matches: match
8459            });
8460            soFar = soFar.slice(matched.length);
8461          }
8462        }
8463        if (!matched) {
8464          break;
8465        }
8466      }
8467
8468      // Return the length of the invalid excess
8469      // if we're just parsing
8470      // Otherwise, throw an error or return tokens
8471      return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) :
8472      // Cache the tokens
8473      tokenCache(selector, groups).slice(0);
8474    }
8475    function toSelector(tokens) {
8476      var i = 0,
8477        len = tokens.length,
8478        selector = "";
8479      for (; i < len; i++) {
8480        selector += tokens[i].value;
8481      }
8482      return selector;
8483    }
8484    function addCombinator(matcher, combinator, base) {
8485      var dir = combinator.dir,
8486        checkNonElements = base && dir === "parentNode",
8487        doneName = done++;
8488      return combinator.first ?
8489      // Check against closest ancestor/preceding element
8490      function (elem, context, xml) {
8491        while (elem = elem[dir]) {
8492          if (elem.nodeType === 1 || checkNonElements) {
8493            return matcher(elem, context, xml);
8494          }
8495        }
8496      } :
8497      // Check against all ancestor/preceding elements
8498      function (elem, context, xml) {
8499        var data,
8500          cache,
8501          outerCache,
8502          dirkey = dirruns + " " + doneName;
8503
8504        // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
8505        if (xml) {
8506          while (elem = elem[dir]) {
8507            if (elem.nodeType === 1 || checkNonElements) {
8508              if (matcher(elem, context, xml)) {
8509                return true;
8510              }
8511            }
8512          }
8513        } else {
8514          while (elem = elem[dir]) {
8515            if (elem.nodeType === 1 || checkNonElements) {
8516              outerCache = elem[expando] || (elem[expando] = {});
8517              if ((cache = outerCache[dir]) && cache[0] === dirkey) {
8518                if ((data = cache[1]) === true || data === cachedruns) {
8519                  return data === true;
8520                }
8521              } else {
8522                cache = outerCache[dir] = [dirkey];
8523                cache[1] = matcher(elem, context, xml) || cachedruns;
8524                if (cache[1] === true) {
8525                  return true;
8526                }
8527              }
8528            }
8529          }
8530        }
8531      };
8532    }
8533    function elementMatcher(matchers) {
8534      return matchers.length > 1 ? function (elem, context, xml) {
8535        var i = matchers.length;
8536        while (i--) {
8537          if (!matchers[i](elem, context, xml)) {
8538            return false;
8539          }
8540        }
8541        return true;
8542      } : matchers[0];
8543    }
8544    function condense(unmatched, map, filter, context, xml) {
8545      var elem,
8546        newUnmatched = [],
8547        i = 0,
8548        len = unmatched.length,
8549        mapped = map != null;
8550      for (; i < len; i++) {
8551        if (elem = unmatched[i]) {
8552          if (!filter || filter(elem, context, xml)) {
8553            newUnmatched.push(elem);
8554            if (mapped) {
8555              map.push(i);
8556            }
8557          }
8558        }
8559      }
8560      return newUnmatched;
8561    }
8562    function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
8563      if (postFilter && !postFilter[expando]) {
8564        postFilter = setMatcher(postFilter);
8565      }
8566      if (postFinder && !postFinder[expando]) {
8567        postFinder = setMatcher(postFinder, postSelector);
8568      }
8569      return markFunction(function (seed, results, context, xml) {
8570        var temp,
8571          i,
8572          elem,
8573          preMap = [],
8574          postMap = [],
8575          preexisting = results.length,
8576          // Get initial elements from seed or context
8577          elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []),
8578          // Prefilter to get matcher input, preserving a map for seed-results synchronization
8579          matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems,
8580          matcherOut = matcher ?
8581          // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
8582          postFinder || (seed ? preFilter : preexisting || postFilter) ?
8583          // ...intermediate processing is necessary
8584          [] :
8585          // ...otherwise use results directly
8586          results : matcherIn;
8587
8588        // Find primary matches
8589        if (matcher) {
8590          matcher(matcherIn, matcherOut, context, xml);
8591        }
8592
8593        // Apply postFilter
8594        if (postFilter) {
8595          temp = condense(matcherOut, postMap);
8596          postFilter(temp, [], context, xml);
8597
8598          // Un-match failing elements by moving them back to matcherIn
8599          i = temp.length;
8600          while (i--) {
8601            if (elem = temp[i]) {
8602              matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
8603            }
8604          }
8605        }
8606        if (seed) {
8607          if (postFinder || preFilter) {
8608            if (postFinder) {
8609              // Get the final matcherOut by condensing this intermediate into postFinder contexts
8610              temp = [];
8611              i = matcherOut.length;
8612              while (i--) {
8613                if (elem = matcherOut[i]) {
8614                  // Restore matcherIn since elem is not yet a final match
8615                  temp.push(matcherIn[i] = elem);
8616                }
8617              }
8618              postFinder(null, matcherOut = [], temp, xml);
8619            }
8620
8621            // Move matched elements from seed to results to keep them synchronized
8622            i = matcherOut.length;
8623            while (i--) {
8624              if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf.call(seed, elem) : preMap[i]) > -1) {
8625                seed[temp] = !(results[temp] = elem);
8626              }
8627            }
8628          }
8629
8630          // Add elements to results, through postFinder if defined
8631        } else {
8632          matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut);
8633          if (postFinder) {
8634            postFinder(null, results, matcherOut, xml);
8635          } else {
8636            push.apply(results, matcherOut);
8637          }
8638        }
8639      });
8640    }
8641    function matcherFromTokens(tokens) {
8642      var checkContext,
8643        matcher,
8644        j,
8645        len = tokens.length,
8646        leadingRelative = Expr.relative[tokens[0].type],
8647        implicitRelative = leadingRelative || Expr.relative[" "],
8648        i = leadingRelative ? 1 : 0,
8649        // The foundational matcher ensures that elements are reachable from top-level context(s)
8650        matchContext = addCombinator(function (elem) {
8651          return elem === checkContext;
8652        }, implicitRelative, true),
8653        matchAnyContext = addCombinator(function (elem) {
8654          return indexOf.call(checkContext, elem) > -1;
8655        }, implicitRelative, true),
8656        matchers = [function (elem, context, xml) {
8657          return !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml));
8658        }];
8659      for (; i < len; i++) {
8660        if (matcher = Expr.relative[tokens[i].type]) {
8661          matchers = [addCombinator(elementMatcher(matchers), matcher)];
8662        } else {
8663          matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);
8664
8665          // Return special upon seeing a positional matcher
8666          if (matcher[expando]) {
8667            // Find the next relative operator (if any) for proper handling
8668            j = ++i;
8669            for (; j < len; j++) {
8670              if (Expr.relative[tokens[j].type]) {
8671                break;
8672              }
8673            }
8674            return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector(
8675            // If the preceding token was a descendant combinator, insert an implicit any-element `*`
8676            tokens.slice(0, i - 1).concat({
8677              value: tokens[i - 2].type === " " ? "*" : ""
8678            })).replace(rtrim, "$1"), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens));
8679          }
8680          matchers.push(matcher);
8681        }
8682      }
8683      return elementMatcher(matchers);
8684    }
8685    function matcherFromGroupMatchers(elementMatchers, setMatchers) {
8686      // A counter to specify which element is currently being matched
8687      var matcherCachedRuns = 0,
8688        bySet = setMatchers.length > 0,
8689        byElement = elementMatchers.length > 0,
8690        superMatcher = function (seed, context, xml, results, expandContext) {
8691          var elem,
8692            j,
8693            matcher,
8694            setMatched = [],
8695            matchedCount = 0,
8696            i = "0",
8697            unmatched = seed && [],
8698            outermost = expandContext != null,
8699            contextBackup = outermostContext,
8700            // We must always have either seed elements or context
8701            elems = seed || byElement && Expr.find["TAG"]("*", expandContext && context.parentNode || context),
8702            // Use integer dirruns iff this is the outermost matcher
8703            dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1;
8704          if (outermost) {
8705            outermostContext = context !== document && context;
8706            cachedruns = matcherCachedRuns;
8707          }
8708
8709          // Add elements passing elementMatchers directly to results
8710          // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
8711          for (; (elem = elems[i]) != null; i++) {
8712            if (byElement && elem) {
8713              j = 0;
8714              while (matcher = elementMatchers[j++]) {
8715                if (matcher(elem, context, xml)) {
8716                  results.push(elem);
8717                  break;
8718                }
8719              }
8720              if (outermost) {
8721                dirruns = dirrunsUnique;
8722                cachedruns = ++matcherCachedRuns;
8723              }
8724            }
8725
8726            // Track unmatched elements for set filters
8727            if (bySet) {
8728              // They will have gone through all possible matchers
8729              if (elem = !matcher && elem) {
8730                matchedCount--;
8731              }
8732
8733              // Lengthen the array for every element, matched or not
8734              if (seed) {
8735                unmatched.push(elem);
8736              }
8737            }
8738          }
8739
8740          // Apply set filters to unmatched elements
8741          matchedCount += i;
8742          if (bySet && i !== matchedCount) {
8743            j = 0;
8744            while (matcher = setMatchers[j++]) {
8745              matcher(unmatched, setMatched, context, xml);
8746            }
8747            if (seed) {
8748              // Reintegrate element matches to eliminate the need for sorting
8749              if (matchedCount > 0) {
8750                while (i--) {
8751                  if (!(unmatched[i] || setMatched[i])) {
8752                    setMatched[i] = pop.call(results);
8753                  }
8754                }
8755              }
8756
8757              // Discard index placeholder values to get only actual matches
8758              setMatched = condense(setMatched);
8759            }
8760
8761            // Add matches to results
8762            push.apply(results, setMatched);
8763
8764            // Seedless set matches succeeding multiple successful matchers stipulate sorting
8765            if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {
8766              Sizzle.uniqueSort(results);
8767            }
8768          }
8769
8770          // Override manipulation of globals by nested matchers
8771          if (outermost) {
8772            dirruns = dirrunsUnique;
8773            outermostContext = contextBackup;
8774          }
8775          return unmatched;
8776        };
8777      return bySet ? markFunction(superMatcher) : superMatcher;
8778    }
8779    compile = Sizzle.compile = function (selector, group /* Internal Use Only */) {
8780      var i,
8781        setMatchers = [],
8782        elementMatchers = [],
8783        cached = compilerCache[selector + " "];
8784      if (!cached) {
8785        // Generate a function of recursive functions that can be used to check each element
8786        if (!group) {
8787          group = tokenize(selector);
8788        }
8789        i = group.length;
8790        while (i--) {
8791          cached = matcherFromTokens(group[i]);
8792          if (cached[expando]) {
8793            setMatchers.push(cached);
8794          } else {
8795            elementMatchers.push(cached);
8796          }
8797        }
8798
8799        // Cache the compiled function
8800        cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers));
8801      }
8802      return cached;
8803    };
8804    function multipleContexts(selector, contexts, results) {
8805      var i = 0,
8806        len = contexts.length;
8807      for (; i < len; i++) {
8808        Sizzle(selector, contexts[i], results);
8809      }
8810      return results;
8811    }
8812    function select(selector, context, results, seed) {
8813      var i,
8814        tokens,
8815        token,
8816        type,
8817        find,
8818        match = tokenize(selector);
8819      if (!seed) {
8820        // Try to minimize operations if there is only one group
8821        if (match.length === 1) {
8822          // Take a shortcut and set the context if the root selector is an ID
8823          tokens = match[0] = match[0].slice(0);
8824          if (tokens.length > 2 && (token = tokens[0]).type === "ID" && support.getById && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {
8825            context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0];
8826            if (!context) {
8827              return results;
8828            }
8829            selector = selector.slice(tokens.shift().value.length);
8830          }
8831
8832          // Fetch a seed set for right-to-left matching
8833          i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length;
8834          while (i--) {
8835            token = tokens[i];
8836
8837            // Abort if we hit a combinator
8838            if (Expr.relative[type = token.type]) {
8839              break;
8840            }
8841            if (find = Expr.find[type]) {
8842              // Search, expanding context for leading sibling combinators
8843              if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && context.parentNode || context)) {
8844                // If seed is empty or no tokens remain, we can return early
8845                tokens.splice(i, 1);
8846                selector = seed.length && toSelector(tokens);
8847                if (!selector) {
8848                  push.apply(results, seed);
8849                  return results;
8850                }
8851                break;
8852              }
8853            }
8854          }
8855        }
8856      }
8857
8858      // Compile and execute a filtering function
8859      // Provide `match` to avoid retokenization if we modified the selector above
8860      compile(selector, match)(seed, context, !documentIsHTML, results, rsibling.test(selector));
8861      return results;
8862    }
8863
8864    // One-time assignments
8865
8866    // Sort stability
8867    support.sortStable = expando.split("").sort(sortOrder).join("") === expando;
8868
8869    // Support: Chrome<14
8870    // Always assume duplicates if they aren't passed to the comparison function
8871    support.detectDuplicates = hasDuplicate;
8872
8873    // Initialize against the default document
8874    setDocument();
8875
8876    // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
8877    // Detached nodes confoundingly follow *each other*
8878    support.sortDetached = assert(function (div1) {
8879      // Should return 1, but returns 4 (following)
8880      return div1.compareDocumentPosition(document.createElement("div")) & 1;
8881    });
8882
8883    // Support: IE<8
8884    // Prevent attribute/property "interpolation"
8885    // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
8886    if (!assert(function (div) {
8887      div.innerHTML = "<a href='#'></a>";
8888      return div.firstChild.getAttribute("href") === "#";
8889    })) {
8890      addHandle("type|href|height|width", function (elem, name, isXML) {
8891        if (!isXML) {
8892          return elem.getAttribute(name, name.toLowerCase() === "type" ? 1 : 2);
8893        }
8894      });
8895    }
8896
8897    // Support: IE<9
8898    // Use defaultValue in place of getAttribute("value")
8899    if (!support.attributes || !assert(function (div) {
8900      div.innerHTML = "<input/>";
8901      div.firstChild.setAttribute("value", "");
8902      return div.firstChild.getAttribute("value") === "";
8903    })) {
8904      addHandle("value", function (elem, name, isXML) {
8905        if (!isXML && elem.nodeName.toLowerCase() === "input") {
8906          return elem.defaultValue;
8907        }
8908      });
8909    }
8910
8911    // Support: IE<9
8912    // Use getAttributeNode to fetch booleans when getAttribute lies
8913    if (!assert(function (div) {
8914      return div.getAttribute("disabled") == null;
8915    })) {
8916      addHandle(booleans, function (elem, name, isXML) {
8917        var val;
8918        if (!isXML) {
8919          return (val = elem.getAttributeNode(name)) && val.specified ? val.value : elem[name] === true ? name.toLowerCase() : null;
8920        }
8921      });
8922    }
8923    jQuery.find = Sizzle;
8924    jQuery.expr = Sizzle.selectors;
8925    jQuery.expr[":"] = jQuery.expr.pseudos;
8926    jQuery.unique = Sizzle.uniqueSort;
8927    jQuery.text = Sizzle.getText;
8928    jQuery.isXMLDoc = Sizzle.isXML;
8929    jQuery.contains = Sizzle.contains;
8930  })(window);
8931  // String to Object options format cache
8932  var optionsCache = {};
8933
8934  // Convert String-formatted options into Object-formatted ones and store in cache
8935  function createOptions(options) {
8936    var object = optionsCache[options] = {};
8937    jQuery.each(options.match(core_rnotwhite) || [], function (_, flag) {
8938      object[flag] = true;
8939    });
8940    return object;
8941  }
8942
8943  /*
8944   * Create a callback list using the following parameters:
8945   *
8946   *	options: an optional list of space-separated options that will change how
8947   *			the callback list behaves or a more traditional option object
8948   *
8949   * By default a callback list will act like an event callback list and can be
8950   * "fired" multiple times.
8951   *
8952   * Possible options:
8953   *
8954   *	once:			will ensure the callback list can only be fired once (like a Deferred)
8955   *
8956   *	memory:			will keep track of previous values and will call any callback added
8957   *					after the list has been fired right away with the latest "memorized"
8958   *					values (like a Deferred)
8959   *
8960   *	unique:			will ensure a callback can only be added once (no duplicate in the list)
8961   *
8962   *	stopOnFalse:	interrupt callings when a callback returns false
8963   *
8964   */
8965  jQuery.Callbacks = function (options) {
8966    // Convert options from String-formatted to Object-formatted if needed
8967    // (we check in cache first)
8968    options = typeof options === "string" ? optionsCache[options] || createOptions(options) : jQuery.extend({}, options);
8969    var
8970      // Last fire value (for non-forgettable lists)
8971      memory,
8972      // Flag to know if list was already fired
8973      fired,
8974      // Flag to know if list is currently firing
8975      firing,
8976      // First callback to fire (used internally by add and fireWith)
8977      firingStart,
8978      // End of the loop when firing
8979      firingLength,
8980      // Index of currently firing callback (modified by remove if needed)
8981      firingIndex,
8982      // Actual callback list
8983      list = [],
vendor: 1,773 bytes, lines 8984-9036
8984      // Stack of fire calls for repeatable lists
8985      stack = !options.once && [],
8986      // Fire callbacks
8987      fire = function (data) {
8988        memory = options.memory && data;
8989        fired = true;
8990        firingIndex = firingStart || 0;
8991        firingStart = 0;
8992        firingLength = list.length;
8993        firing = true;
8994        for (; list && firingIndex < firingLength; firingIndex++) {
8995          if (list[firingIndex].apply(data[0], data[1]) === false && options.stopOnFalse) {
8996            memory = false; // To prevent further calls using add
8997            break;
8998          }
8999        }
9000        firing = false;
9001        if (list) {
9002          if (stack) {
9003            if (stack.length) {
9004              fire(stack.shift());
9005            }
9006          } else if (memory) {
9007            list = [];
9008          } else {
9009            self.disable();
9010          }
9011        }
9012      },
9013      // Actual Callbacks object
9014      self = {
9015        // Add a callback or a collection of callbacks to the list
9016        add: function () {
9017          if (list) {
9018            // First, we save the current length
9019            var start = list.length;
9020            (function add(args) {
9021              jQuery.each(args, function (_, arg) {
9022                var type = jQuery.type(arg);
9023                if (type === "function") {
9024                  if (!options.unique || !self.has(arg)) {
9025                    list.push(arg);
9026                  }
9027                } else if (arg && arg.length && type !== "string") {
9028                  // Inspect recursively
9029                  add(arg);
9030                }
9031              });
9032            })(arguments);
9033            // Do we need to add the callbacks to the
9034            // current firing batch?
9035            if (firing) {
9036              firingLength = list.length;
9037              // With memory, if we're not firing then
9038              // we should call right away
9039            } else if (memory) {
9040              firingStart = start;
9041              fire(memory);
9042            }
9043          }
9044          return this;
9045        },
9046        // Remove a callback from the list
9047        remove: function () {
9048          if (list) {
9049            jQuery.each(arguments, function (_, arg) {
9050              var index;
9051              while ((index = jQuery.inArray(arg, list, index)) > -1) {
9052                list.splice(index, 1);
9053                // Handle firing indexes
9054                if (firing) {
9055                  if (index <= firingLength) {
9056                    firingLength--;
9057                  }
9058                  if (index <= firingIndex) {
9059                    firingIndex--;
9060                  }
9061                }
9062              }
9063            });
9064          }
9065          return this;
9066        },
9067        // Check if a given callback is in the list.
9068        // If no argument is given, return whether or not list has callbacks attached.
9069        has: function (fn) {
9070          return fn ? jQuery.inArray(fn, list) > -1 : !!(list && list.length);
9071        },
9072        // Remove all callbacks from the list
9073        empty: function () {
9074          list = [];
9075          firingLength = 0;
9076          return this;
9077        },
9078        // Have the list do nothing anymore
9079        disable: function () {
9080          list = stack = memory = undefined;
9081          return this;
9082        },
9083        // Is it disabled?
9084        disabled: function () {
9085          return !list;
9086        },
9087        // Lock the list in its current state
9088        lock: function () {
9089          stack = undefined;
9090          if (!memory) {
9091            self.disable();
9092          }
9093          return this;
9094        },
9095        // Is it locked?
9096        locked: function () {
9097          return !stack;
9098        },
9099        // Call all callbacks with the given context and arguments
9100        fireWith: function (context, args) {
9101          if (list && (!fired || stack)) {
9102            args = args || [];
9103            args = [context, args.slice ? args.slice() : args];
9104            if (firing) {
9105              stack.push(args);
9106            } else {
9107              fire(args);
9108            }
9109          }
9110          return this;
9111        },
9112        // Call all the callbacks with the given arguments
9113        fire: function () {
9114          self.fireWith(this, arguments);
9115          return this;
9116        },
9117        // To know if the callbacks have already been called at least once
9118        fired: function () {
9119          return !!fired;
9120        }
9121      };
9122    return self;
9123  };
9124  jQuery.extend({
9125    Deferred: function (func) {
9126      var tuples = [
9127        // action, add listener, listener list, final state
9128        ["resolve", "done", jQuery.Callbacks("once memory"), "resolved"], ["reject", "fail", jQuery.Callbacks("once memory"), "rejected"], ["notify", "progress", jQuery.Callbacks("memory")]],
9129        state = "pending",
9130        promise = {
9131          state: function () {
9132            return state;
9133          },
9134          always: function () {
9135            deferred.done(arguments).fail(arguments);
9136            return this;
9137          },
9138          then: function /* fnDone, fnFail, fnProgress */
9139          () {
9140            var fns = arguments;
9141            return jQuery.Deferred(function (newDefer) {
9142              jQuery.each(tuples, function (i, tuple) {
9143                var action = tuple[0],
9144                  fn = jQuery.isFunction(fns[i]) && fns[i];
9145                // deferred[ done | fail | progress ] for forwarding actions to newDefer
9146                deferred[tuple[1]](function () {
9147                  var returned = fn && fn.apply(this, arguments);
9148                  if (returned && jQuery.isFunction(returned.promise)) {
9149                    returned.promise().done(newDefer.resolve).fail(newDefer.reject).progress(newDefer.notify);
9150                  } else {
9151                    newDefer[action + "With"](this === promise ? newDefer.promise() : this, fn ? [returned] : arguments);
9152                  }
9153                });
9154              });
9155              fns = null;
9156            }).promise();
9157          },
9158          // Get a promise for this deferred
9159          // If obj is provided, the promise aspect is added to the object
9160          promise: function (obj) {
9161            return obj != null ? jQuery.extend(obj, promise) : promise;
9162          }
9163        },
9164        deferred = {};
9165
9166      // Keep pipe for back-compat
9167      promise.pipe = promise.then;
9168
9169      // Add list-specific methods
9170      jQuery.each(tuples, function (i, tuple) {
9171        var list = tuple[2],
9172          stateString = tuple[3];
9173
9174        // promise[ done | fail | progress ] = list.add
9175        promise[tuple[1]] = list.add;
9176
9177        // Handle state
9178        if (stateString) {
9179          list.add(function () {
9180            // state = [ resolved | rejected ]
9181            state = stateString;
9182
9183            // [ reject_list | resolve_list ].disable; progress_list.lock
9184          }, tuples[i ^ 1][2].disable, tuples[2][2].lock);
9185        }
9186
9187        // deferred[ resolve | reject | notify ]
9188        deferred[tuple[0]] = function () {
9189          deferred[tuple[0] + "With"](this === deferred ? promise : this, arguments);
9190          return this;
9191        };
9192        deferred[tuple[0] + "With"] = list.fireWith;
9193      });
9194
9195      // Make the deferred a promise
9196      promise.promise(deferred);
9197
9198      // Call given func if any
9199      if (func) {
9200        func.call(deferred, deferred);
9201      }
9202
9203      // All done!
9204      return deferred;
9205    },
9206    // Deferred helper
9207    when: function (subordinate /* , ..., subordinateN */) {
9208      var i = 0,
9209        resolveValues = core_slice.call(arguments),
9210        length = resolveValues.length,
9211        // the count of uncompleted subordinates
9212        remaining = length !== 1 || subordinate && jQuery.isFunction(subordinate.promise) ? length : 0,
9213        // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
9214        deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
9215        // Update function for both resolve and progress values
9216        updateFunc = function (i, contexts, values) {
9217          return function (value) {
9218            contexts[i] = this;
9219            values[i] = arguments.length > 1 ? core_slice.call(arguments) : value;
9220            if (values === progressValues) {
9221              deferred.notifyWith(contexts, values);
9222            } else if (! --remaining) {
9223              deferred.resolveWith(contexts, values);
9224            }
9225          };
9226        },
9227        progressValues,
9228        progressContexts,
9229        resolveContexts;
9230
9231      // add listeners to Deferred subordinates; treat others as resolved
9232      if (length > 1) {
9233        progressValues = new Array(length);
9234        progressContexts = new Array(length);
9235        resolveContexts = new Array(length);
9236        for (; i < length; i++) {
9237          if (resolveValues[i] && jQuery.isFunction(resolveValues[i].promise)) {
9238            resolveValues[i].promise().done(updateFunc(i, resolveContexts, resolveValues)).fail(deferred.reject).progress(updateFunc(i, progressContexts, progressValues));
9239          } else {
9240            --remaining;
9241          }
9242        }
9243      }
9244
9245      // if we're not waiting on anything, resolve the master
9246      if (!remaining) {
9247        deferred.resolveWith(resolveContexts, resolveValues);
9248      }
9249      return deferred.promise();
9250    }
9251  });
9252  jQuery.support = function (support) {
9253    var input = document.createElement("input"),
9254      fragment = document.createDocumentFragment(),
9255      div = document.createElement("div"),
9256      select = document.createElement("select"),
9257      opt = select.appendChild(document.createElement("option"));
9258
9259    // Finish early in limited environments
9260    if (!input.type) {
9261      return support;
9262    }
9263    input.type = "checkbox";
9264
9265    // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
9266    // Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere)
9267    support.checkOn = input.value !== "";
9268
9269    // Must access the parent to make an option select properly
9270    // Support: IE9, IE10
9271    support.optSelected = opt.selected;
9272
9273    // Will be defined later
9274    support.reliableMarginRight = true;
9275    support.boxSizingReliable = true;
9276    support.pixelPosition = false;
9277
9278    // Make sure checked status is properly cloned
9279    // Support: IE9, IE10
9280    input.checked = true;
9281    support.noCloneChecked = input.cloneNode(true).checked;
9282
9283    // Make sure that the options inside disabled selects aren't marked as disabled
9284    // (WebKit marks them as disabled)
9285    select.disabled = true;
9286    support.optDisabled = !opt.disabled;
9287
9288    // Check if an input maintains its value after becoming a radio
9289    // Support: IE9, IE10
9290    input = document.createElement("input");
9291    input.value = "t";
9292    input.type = "radio";
9293    support.radioValue = input.value === "t";
9294
9295    // #11217 - WebKit loses check when the name is after the checked attribute
9296    input.setAttribute("checked", "t");
9297    input.setAttribute("name", "t");
9298    fragment.appendChild(input);
9299
9300    // Support: Safari 5.1, Android 4.x, Android 2.3
9301    // old WebKit doesn't clone checked state correctly in fragments
9302    support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
9303
9304    // Support: Firefox, Chrome, Safari
9305    // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
9306    support.focusinBubbles = "onfocusin" in window;
9307    div.style.backgroundClip = "content-box";
9308    div.cloneNode(true).style.backgroundClip = "";
9309    support.clearCloneStyle = div.style.backgroundClip === "content-box";
9310
9311    // Run tests that need a body at doc ready
9312    jQuery(function () {
9313      var container,
9314        marginDiv,
9315        // Support: Firefox, Android 2.3 (Prefixed box-sizing versions).
9316        divReset = "padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",
9317        body = document.getElementsByTagName("body")[0];
9318      if (!body) {
9319        // Return for frameset docs that don't have a body
9320        return;
9321      }
9322      container = document.createElement("div");
9323      container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
9324
9325      // Check box-sizing and margin behavior.
9326      body.appendChild(container).appendChild(div);
9327      div.innerHTML = "";
9328      // Support: Firefox, Android 2.3 (Prefixed box-sizing versions).
9329      div.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%";
9330
9331      // Workaround failing boxSizing test due to offsetWidth returning wrong value
9332      // with some non-1 values of body zoom, ticket #13543
9333      jQuery.swap(body, body.style.zoom != null ? {
9334        zoom: 1
9335      } : {}, function () {
9336        support.boxSizing = div.offsetWidth === 4;
9337      });
9338
9339      // Use window.getComputedStyle because jsdom on node.js will break without it.
9340      if (window.getComputedStyle) {
9341        support.pixelPosition = (window.getComputedStyle(div, null) || {}).top !== "1%";
9342        support.boxSizingReliable = (window.getComputedStyle(div, null) || {
9343          width: "4px"
9344        }).width === "4px";
9345
9346        // Support: Android 2.3
9347        // Check if div with explicit width and no margin-right incorrectly
9348        // gets computed margin-right based on width of container. (#3333)
9349        // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
9350        marginDiv = div.appendChild(document.createElement("div"));
9351        marginDiv.style.cssText = div.style.cssText = divReset;
9352        marginDiv.style.marginRight = marginDiv.style.width = "0";
9353        div.style.width = "1px";
9354        support.reliableMarginRight = !parseFloat((window.getComputedStyle(marginDiv, null) || {}).marginRight);
9355      }
9356      body.removeChild(container);
9357    });
9358    return support;
9359  }({});
9360
9361  /*
9362  	Implementation Summary
9363  
9364  	1. Enforce API surface and semantic compatibility with 1.9.x branch
9365  	2. Improve the module's maintainability by reducing the storage
9366  		paths to a single mechanism.
9367  	3. Use the same single mechanism to support "private" and "user" data.
9368  	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
9369  	5. Avoid exposing implementation details on user objects (eg. expando properties)
9370  	6. Provide a clear path for implementation upgrade to WeakMap in 2014
9371  */
9372  var data_user,
9373    data_priv,
9374    rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
9375    rmultiDash = /([A-Z])/g;
9376  function Data() {
9377    // Support: Android < 4,
9378    // Old WebKit does not have Object.preventExtensions/freeze method,
9379    // return new empty object instead with no [[set]] accessor
9380    Object.defineProperty(this.cache = {}, 0, {
9381      get: function () {
9382        return {};
9383      }
9384    });
9385    this.expando = jQuery.expando + Math.random();
9386  }
9387  Data.uid = 1;
9388  Data.accepts = function (owner) {
9389    // Accepts only:
9390    //  - Node
9391    //    - Node.ELEMENT_NODE
9392    //    - Node.DOCUMENT_NODE
9393    //  - Object
9394    //    - Any
9395    return owner.nodeType ? owner.nodeType === 1 || owner.nodeType === 9 : true;
9396  };
9397  Data.prototype = {
9398    key: function (owner) {
9399      // We can accept data for non-element nodes in modern browsers,
9400      // but we should not, see #8335.
9401      // Always return the key for a frozen object.
9402      if (!Data.accepts(owner)) {
9403        return 0;
9404      }
9405      var descriptor = {},
9406        // Check if the owner object already has a cache key
9407        unlock = owner[this.expando];
9408
9409      // If not, create one
9410      if (!unlock) {
9411        unlock = Data.uid++;
9412
9413        // Secure it in a non-enumerable, non-writable property
9414        try {
9415          descriptor[this.expando] = {
9416            value: unlock
9417          };
9418          Object.defineProperties(owner, descriptor);
9419
9420          // Support: Android < 4
9421          // Fallback to a less secure definition
9422        } catch (e) {
9423          descriptor[this.expando] = unlock;
9424          jQuery.extend(owner, descriptor);
9425        }
9426      }
9427
9428      // Ensure the cache object
9429      if (!this.cache[unlock]) {
9430        this.cache[unlock] = {};
9431      }
9432      return unlock;
9433    },
9434    set: function (owner, data, value) {
9435      var prop,
9436        // There may be an unlock assigned to this node,
9437        // if there is no entry for this "owner", create one inline
9438        // and set the unlock as though an owner entry had always existed
9439        unlock = this.key(owner),
9440        cache = this.cache[unlock];
9441
9442      // Handle: [ owner, key, value ] args
9443      if (typeof data === "string") {
9444        cache[data] = value;
9445
9446        // Handle: [ owner, { properties } ] args
9447      } else {
9448        // Fresh assignments by object are shallow copied
9449        if (jQuery.isEmptyObject(cache)) {
9450          jQuery.extend(this.cache[unlock], data);
9451          // Otherwise, copy the properties one-by-one to the cache object
9452        } else {
9453          for (prop in data) {
9454            cache[prop] = data[prop];
9455          }
9456        }
9457      }
9458      return cache;
9459    },
9460    get: function (owner, key) {
9461      // Either a valid cache is found, or will be created.
9462      // New caches will be created and the unlock returned,
9463      // allowing direct access to the newly created
9464      // empty data object. A valid owner object must be provided.
9465      var cache = this.cache[this.key(owner)];
9466      return key === undefined ? cache : cache[key];
9467    },
9468    access: function (owner, key, value) {
9469      var stored;
9470      // In cases where either:
9471      //
9472      //   1. No key was specified
9473      //   2. A string key was specified, but no value provided
9474      //
9475      // Take the "read" path and allow the get method to determine
9476      // which value to return, respectively either:
9477      //
9478      //   1. The entire cache object
9479      //   2. The data stored at the key
9480      //
9481      if (key === undefined || key && typeof key === "string" && value === undefined) {
9482        stored = this.get(owner, key);
9483        return stored !== undefined ? stored : this.get(owner, jQuery.camelCase(key));
9484      }
9485
9486      // [*]When the key is not a string, or both a key and value
9487      // are specified, set or extend (existing objects) with either:
9488      //
9489      //   1. An object of properties
9490      //   2. A key and value
9491      //
9492      this.set(owner, key, value);
9493
9494      // Since the "set" path can have two possible entry points
9495      // return the expected data based on which path was taken[*]
9496      return value !== undefined ? value : key;
9497    },
9498    remove: function (owner, key) {
9499      var i,
9500        name,
9501        camel,
9502        unlock = this.key(owner),
9503        cache = this.cache[unlock];
9504      if (key === undefined) {
9505        this.cache[unlock] = {};
9506      } else {
9507        // Support array or space separated string of keys
9508        if (jQuery.isArray(key)) {
9509          // If "name" is an array of keys...
9510          // When data is initially created, via ("key", "val") signature,
9511          // keys will be converted to camelCase.
9512          // Since there is no way to tell _how_ a key was added, remove
9513          // both plain key and camelCase key. #12786
9514          // This will only penalize the array argument path.
9515          name = key.concat(key.map(jQuery.camelCase));
9516        } else {
9517          camel = jQuery.camelCase(key);
9518          // Try the string as a key before any manipulation
9519          if (key in cache) {
9520            name = [key, camel];
9521          } else {
9522            // If a key with the spaces exists, use it.
9523            // Otherwise, create an array by matching non-whitespace
9524            name = camel;
9525            name = name in cache ? [name] : name.match(core_rnotwhite) || [];
9526          }
9527        }
9528        i = name.length;
9529        while (i--) {
9530          delete cache[name[i]];
9531        }
9532      }
9533    },
9534    hasData: function (owner) {
9535      return !jQuery.isEmptyObject(this.cache[owner[this.expando]] || {});
9536    },
9537    discard: function (owner) {
9538      if (owner[this.expando]) {
9539        delete this.cache[owner[this.expando]];
9540      }
9541    }
9542  };
9543
9544  // These may be used throughout the jQuery core codebase
9545  data_user = new Data();
9546  data_priv = new Data();
9547  jQuery.extend({
9548    acceptData: Data.accepts,
9549    hasData: function (elem) {
9550      return data_user.hasData(elem) || data_priv.hasData(elem);
9551    },
9552    data: function (elem, name, data) {
9553      return data_user.access(elem, name, data);
9554    },
9555    removeData: function (elem, name) {
9556      data_user.remove(elem, name);
9557    },
9558    // TODO: Now that all calls to _data and _removeData have been replaced
9559    // with direct calls to data_priv methods, these can be deprecated.
9560    _data: function (elem, name, data) {
9561      return data_priv.access(elem, name, data);
9562    },
9563    _removeData: function (elem, name) {
9564      data_priv.remove(elem, name);
9565    }
9566  });
9567  jQuery.fn.extend({
9568    data: function (key, value) {
9569      var attrs,
9570        name,
9571        elem = this[0],
9572        i = 0,
9573        data = null;
9574
9575      // Gets all values
9576      if (key === undefined) {
9577        if (this.length) {
9578          data = data_user.get(elem);
9579          if (elem.nodeType === 1 && !data_priv.get(elem, "hasDataAttrs")) {
9580            attrs = elem.attributes;
9581            for (; i < attrs.length; i++) {
9582              name = attrs[i].name;
9583              if (name.indexOf("data-") === 0) {
9584                name = jQuery.camelCase(name.slice(5));
9585                dataAttr(elem, name, data[name]);
9586              }
9587            }
9588            data_priv.set(elem, "hasDataAttrs", true);
9589          }
9590        }
9591        return data;
9592      }
9593
9594      // Sets multiple values
9595      if (typeof key === "object") {
9596        return this.each(function () {
9597          data_user.set(this, key);
9598        });
9599      }
9600      return jQuery.access(this, function (value) {
9601        var data,
9602          camelKey = jQuery.camelCase(key);
9603
9604        // The calling jQuery object (element matches) is not empty
9605        // (and therefore has an element appears at this[ 0 ]) and the
9606        // `value` parameter was not undefined. An empty jQuery object
9607        // will result in `undefined` for elem = this[ 0 ] which will
9608        // throw an exception if an attempt to read a data cache is made.
9609        if (elem && value === undefined) {
9610          // Attempt to get data from the cache
9611          // with the key as-is
9612          data = data_user.get(elem, key);
9613          if (data !== undefined) {
9614            return data;
9615          }
9616
9617          // Attempt to get data from the cache
9618          // with the key camelized
9619          data = data_user.get(elem, camelKey);
9620          if (data !== undefined) {
9621            return data;
9622          }
9623
9624          // Attempt to "discover" the data in
9625          // HTML5 custom data-* attrs
9626          data = dataAttr(elem, camelKey, undefined);
9627          if (data !== undefined) {
9628            return data;
9629          }
9630
9631          // We tried really hard, but the data doesn't exist.
9632          return;
9633        }
9634
9635        // Set the data...
9636        this.each(function () {
9637          // First, attempt to store a copy or reference of any
9638          // data that might've been store with a camelCased key.
9639          var data = data_user.get(this, camelKey);
9640
9641          // For HTML5 data-* attribute interop, we have to
9642          // store property names with dashes in a camelCase form.
9643          // This might not apply to all properties...*
9644          data_user.set(this, camelKey, value);
9645
9646          // *... In the case of properties that might _actually_
9647          // have dashes, we need to also store a copy of that
9648          // unchanged property.
9649          if (key.indexOf("-") !== -1 && data !== undefined) {
9650            data_user.set(this, key, value);
9651          }
9652        });
9653      }, null, value, arguments.length > 1, null, true);
9654    },
9655    removeData: function (key) {
9656      return this.each(function () {
9657        data_user.remove(this, key);
9658      });
9659    }
9660  });
9661  function dataAttr(elem, key, data) {
9662    var name;
9663
9664    // If nothing was found internally, try to fetch any
9665    // data from the HTML5 data-* attribute
9666    if (data === undefined && elem.nodeType === 1) {
9667      name = "data-" + key.replace(rmultiDash, "-$1").toLowerCase();
9668      data = elem.getAttribute(name);
9669      if (typeof data === "string") {
9670        try {
9671          data = data === "true" ? true : data === "false" ? false : data === "null" ? null :
9672          // Only convert to a number if it doesn't change the string
9673          +data + "" === data ? +data : rbrace.test(data) ? JSON.parse(data) : data;
9674        } catch (e) {}
9675
9676        // Make sure we set the data so it isn't changed later
9677        data_user.set(elem, key, data);
9678      } else {
9679        data = undefined;
9680      }
9681    }
9682    return data;
9683  }
9684  jQuery.extend({
9685    queue: function (elem, type, data) {
9686      var queue;
9687      if (elem) {
9688        type = (type || "fx") + "queue";
9689        queue = data_priv.get(elem, type);
9690
9691        // Speed up dequeue by getting out quickly if this is just a lookup
9692        if (data) {
9693          if (!queue || jQuery.isArray(data)) {
9694            queue = data_priv.access(elem, type, jQuery.makeArray(data));
9695          } else {
9696            queue.push(data);
9697          }
9698        }
9699        return queue || [];
9700      }
9701    },
9702    dequeue: function (elem, type) {
9703      type = type || "fx";
9704      var queue = jQuery.queue(elem, type),
9705        startLength = queue.length,
9706        fn = queue.shift(),
9707        hooks = jQuery._queueHooks(elem, type),
9708        next = function () {
9709          jQuery.dequeue(elem, type);
9710        };
9711
9712      // If the fx queue is dequeued, always remove the progress sentinel
9713      if (fn === "inprogress") {
9714        fn = queue.shift();
9715        startLength--;
9716      }
9717      if (fn) {
9718        // Add a progress sentinel to prevent the fx queue from being
9719        // automatically dequeued
9720        if (type === "fx") {
9721          queue.unshift("inprogress");
9722        }
9723
9724        // clear up the last queue stop function
9725        delete hooks.stop;
9726        fn.call(elem, next, hooks);
9727      }
9728      if (!startLength && hooks) {
9729        hooks.empty.fire();
9730      }
9731    },
9732    // not intended for public consumption - generates a queueHooks object, or returns the current one
9733    _queueHooks: function (elem, type) {
9734      var key = type + "queueHooks";
9735      return data_priv.get(elem, key) || data_priv.access(elem, key, {
9736        empty: jQuery.Callbacks("once memory").add(function () {
9737          data_priv.remove(elem, [type + "queue", key]);
9738        })
9739      });
9740    }
9741  });
9742  jQuery.fn.extend({
9743    queue: function (type, data) {
9744      var setter = 2;
9745      if (typeof type !== "string") {
9746        data = type;
9747        type = "fx";
9748        setter--;
9749      }
9750      if (arguments.length < setter) {
9751        return jQuery.queue(this[0], type);
9752      }
9753      return data === undefined ? this : this.each(function () {
9754        var queue = jQuery.queue(this, type, data);
9755
9756        // ensure a hooks for this queue
9757        jQuery._queueHooks(this, type);
9758        if (type === "fx" && queue[0] !== "inprogress") {
9759          jQuery.dequeue(this, type);
9760        }
9761      });
9762    },
9763    dequeue: function (type) {
9764      return this.each(function () {
9765        jQuery.dequeue(this, type);
9766      });
9767    },
9768    // Based off of the plugin by Clint Helfers, with permission.
9769    // http://blindsignals.com/index.php/2009/07/jquery-delay/
9770    delay: function (time, type) {
9771      time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
9772      type = type || "fx";
9773      return this.queue(type, function (next, hooks) {
9774        var timeout = setTimeout(next, time);
9775        hooks.stop = function () {
9776          clearTimeout(timeout);
9777        };
9778      });
9779    },
9780    clearQueue: function (type) {
9781      return this.queue(type || "fx", []);
9782    },
9783    // Get a promise resolved when queues of a certain type
9784    // are emptied (fx is the type by default)
9785    promise: function (type, obj) {
9786      var tmp,
9787        count = 1,
9788        defer = jQuery.Deferred(),
9789        elements = this,
9790        i = this.length,
9791        resolve = function () {
9792          if (! --count) {
9793            defer.resolveWith(elements, [elements]);
9794          }
9795        };
9796      if (typeof type !== "string") {
9797        obj = type;
9798        type = undefined;
9799      }
9800      type = type || "fx";
9801      while (i--) {
9802        tmp = data_priv.get(elements[i], type + "queueHooks");
9803        if (tmp && tmp.empty) {
9804          count++;
9805          tmp.empty.add(resolve);
9806        }
9807      }
9808      resolve();
9809      return defer.promise(obj);
9810    }
9811  });
9812  var nodeHook,
9813    boolHook,
9814    rclass = /[\t\r\n\f]/g,
9815    rreturn = /\r/g,
9816    rfocusable = /^(?:input|select|textarea|button)$/i;
9817  jQuery.fn.extend({
9818    attr: function (name, value) {
9819      return jQuery.access(this, jQuery.attr, name, value, arguments.length > 1);
9820    },
9821    removeAttr: function (name) {
9822      return this.each(function () {
9823        jQuery.removeAttr(this, name);
9824      });
9825    },
9826    prop: function (name, value) {
9827      return jQuery.access(this, jQuery.prop, name, value, arguments.length > 1);
9828    },
9829    removeProp: function (name) {
9830      return this.each(function () {
9831        delete this[jQuery.propFix[name] || name];
9832      });
9833    },
9834    addClass: function (value) {
9835      var classes,
9836        elem,
9837        cur,
9838        clazz,
9839        j,
9840        i = 0,
9841        len = this.length,
9842        proceed = typeof value === "string" && value;
9843      if (jQuery.isFunction(value)) {
9844        return this.each(function (j) {
9845          jQuery(this).addClass(value.call(this, j, this.className));
9846        });
9847      }
9848      if (proceed) {
9849        // The disjunction here is for better compressibility (see removeClass)
9850        classes = (value || "").match(core_rnotwhite) || [];
9851        for (; i < len; i++) {
9852          elem = this[i];
9853          cur = elem.nodeType === 1 && (elem.className ? (" " + elem.className + " ").replace(rclass, " ") : " ");
9854          if (cur) {
9855            j = 0;
9856            while (clazz = classes[j++]) {
9857              if (cur.indexOf(" " + clazz + " ") < 0) {
9858                cur += clazz + " ";
9859              }
9860            }
9861            elem.className = jQuery.trim(cur);
9862          }
9863        }
9864      }
9865      return this;
9866    },
9867    removeClass: function (value) {
9868      var classes,
9869        elem,
9870        cur,
9871        clazz,
9872        j,
9873        i = 0,
9874        len = this.length,
9875        proceed = arguments.length === 0 || typeof value === "string" && value;
9876      if (jQuery.isFunction(value)) {
9877        return this.each(function (j) {
9878          jQuery(this).removeClass(value.call(this, j, this.className));
9879        });
9880      }
9881      if (proceed) {
9882        classes = (value || "").match(core_rnotwhite) || [];
9883        for (; i < len; i++) {
9884          elem = this[i];
9885          // This expression is here for better compressibility (see addClass)
9886          cur = elem.nodeType === 1 && (elem.className ? (" " + elem.className + " ").replace(rclass, " ") : "");
9887          if (cur) {
9888            j = 0;
9889            while (clazz = classes[j++]) {
9890              // Remove *all* instances
9891              while (cur.indexOf(" " + clazz + " ") >= 0) {
9892                cur = cur.replace(" " + clazz + " ", " ");
9893              }
9894            }
9895            elem.className = value ? jQuery.trim(cur) : "";
9896          }
9897        }
9898      }
9899      return this;
9900    },
9901    toggleClass: function (value, stateVal) {
9902      var type = typeof value;
9903      if (typeof stateVal === "boolean" && type === "string") {
9904        return stateVal ? this.addClass(value) : this.removeClass(value);
9905      }
9906      if (jQuery.isFunction(value)) {
9907        return this.each(function (i) {
9908          jQuery(this).toggleClass(value.call(this, i, this.className, stateVal), stateVal);
9909        });
9910      }
9911      return this.each(function () {
9912        if (type === "string") {
9913          // toggle individual class names
9914          var className,
9915            i = 0,
9916            self = jQuery(this),
9917            classNames = value.match(core_rnotwhite) || [];
9918          while (className = classNames[i++]) {
9919            // check each className given, space separated list
9920            if (self.hasClass(className)) {
9921              self.removeClass(className);
9922            } else {
9923              self.addClass(className);
9924            }
9925          }
9926
9927          // Toggle whole class name
9928        } else if (type === core_strundefined || type === "boolean") {
9929          if (this.className) {
9930            // store className if set
9931            data_priv.set(this, "__className__", this.className);
9932          }
9933
9934          // If the element has a class name or if we're passed "false",
9935          // then remove the whole classname (if there was one, the above saved it).
9936          // Otherwise bring back whatever was previously saved (if anything),
9937          // falling back to the empty string if nothing was stored.
9938          this.className = this.className || value === false ? "" : data_priv.get(this, "__className__") || "";
9939        }
9940      });
9941    },
9942    hasClass: function (selector) {
9943      var className = " " + selector + " ",
9944        i = 0,
9945        l = this.length;
9946      for (; i < l; i++) {
9947        if (this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf(className) >= 0) {
9948          return true;
9949        }
9950      }
9951      return false;
9952    },
9953    val: function (value) {
9954      var hooks,
9955        ret,
9956        isFunction,
9957        elem = this[0];
9958      if (!arguments.length) {
9959        if (elem) {
9960          hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()];
9961          if (hooks && "get" in hooks && (ret = hooks.get(elem, "value")) !== undefined) {
9962            return ret;
9963          }
9964          ret = elem.value;
9965          return typeof ret === "string" ?
9966          // handle most common string cases
9967          ret.replace(rreturn, "") :
9968          // handle cases where value is null/undef or number
9969          ret == null ? "" : ret;
9970        }
9971        return;
9972      }
9973      isFunction = jQuery.isFunction(value);
9974      return this.each(function (i) {
9975        var val;
9976        if (this.nodeType !== 1) {
9977          return;
9978        }
9979        if (isFunction) {
9980          val = value.call(this, i, jQuery(this).val());
9981        } else {
9982          val = value;
9983        }
9984
9985        // Treat null/undefined as ""; convert numbers to string
9986        if (val == null) {
9987          val = "";
9988        } else if (typeof val === "number") {
9989          val += "";
9990        } else if (jQuery.isArray(val)) {
9991          val = jQuery.map(val, function (value) {
9992            return value == null ? "" : value + "";
9993          });
9994        }
9995        hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()];
9996
9997        // If set returns undefined, fall back to normal setting
9998        if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) {
9999          this.value = val;
10000        }
10001      });
10002    }
10003  });
10004  jQuery.extend({
10005    valHooks: {
10006      option: {
10007        get: function (elem) {
10008          // attributes.value is undefined in Blackberry 4.7 but
10009          // uses .value. See #6932
10010          var val = elem.attributes.value;
10011          return !val || val.specified ? elem.value : elem.text;
10012        }
10013      },
10014      select: {
10015        get: function (elem) {
10016          var value,
10017            option,
10018            options = elem.options,
10019            index = elem.selectedIndex,
10020            one = elem.type === "select-one" || index < 0,
10021            values = one ? null : [],
10022            max = one ? index + 1 : options.length,
10023            i = index < 0 ? max : one ? index : 0;
10024
10025          // Loop through all the selected options
10026          for (; i < max; i++) {
10027            option = options[i];
10028
10029            // IE6-9 doesn't update selected after form reset (#2551)
10030            if ((option.selected || i === index) && (
10031            // Don't return options that are disabled or in a disabled optgroup
10032            jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && (!option.parentNode.disabled || !jQuery.nodeName(option.parentNode, "optgroup"))) {
10033              // Get the specific value for the option
10034              value = jQuery(option).val();
10035
10036              // We don't need an array for one selects
10037              if (one) {
10038                return value;
10039              }
10040
10041              // Multi-Selects return an array
10042              values.push(value);
10043            }
10044          }
10045          return values;
10046        },
10047        set: function (elem, value) {
10048          var optionSet,
10049            option,
10050            options = elem.options,
10051            values = jQuery.makeArray(value),
10052            i = options.length;
10053          while (i--) {
10054            option = options[i];
10055            if (option.selected = jQuery.inArray(jQuery(option).val(), values) >= 0) {
10056              optionSet = true;
10057            }
10058          }
10059
10060          // force browsers to behave consistently when non-matching value is set
10061          if (!optionSet) {
10062            elem.selectedIndex = -1;
10063          }
10064          return values;
10065        }
10066      }
10067    },
10068    attr: function (elem, name, value) {
10069      var hooks,
10070        ret,
10071        nType = elem.nodeType;
10072
10073      // don't get/set attributes on text, comment and attribute nodes
10074      if (!elem || nType === 3 || nType === 8 || nType === 2) {
10075        return;
10076      }
10077
10078      // Fallback to prop when attributes are not supported
10079      if (typeof elem.getAttribute === core_strundefined) {
10080        return jQuery.prop(elem, name, value);
10081      }
10082
10083      // All attributes are lowercase
10084      // Grab necessary hook if one is defined
10085      if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
10086        name = name.toLowerCase();
10087        hooks = jQuery.attrHooks[name] || (jQuery.expr.match.bool.test(name) ? boolHook : nodeHook);
10088      }
10089      if (value !== undefined) {
10090        if (value === null) {
10091          jQuery.removeAttr(elem, name);
10092        } else if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {
10093          return ret;
10094        } else {
10095          elem.setAttribute(name, value + "");
10096          return value;
10097        }
10098      } else if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
10099        return ret;
10100      } else {
10101        ret = jQuery.find.attr(elem, name);
10102
10103        // Non-existent attributes return null, we normalize to undefined
10104        return ret == null ? undefined : ret;
10105      }
10106    },
10107    removeAttr: function (elem, value) {
10108      var name,
10109        propName,
10110        i = 0,
10111        attrNames = value && value.match(core_rnotwhite);
10112      if (attrNames && elem.nodeType === 1) {
10113        while (name = attrNames[i++]) {
10114          propName = jQuery.propFix[name] || name;
10115
10116          // Boolean attributes get special treatment (#10870)
10117          if (jQuery.expr.match.bool.test(name)) {
10118            // Set corresponding property to false
10119            elem[propName] = false;
10120          }
10121          elem.removeAttribute(name);
10122        }
10123      }
10124    },
10125    attrHooks: {
10126      type: {
10127        set: function (elem, value) {
10128          if (!jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input")) {
10129            // Setting the type on a radio button after the value resets the value in IE6-9
10130            // Reset value to default in case type is set after value during creation
10131            var val = elem.value;
10132            elem.setAttribute("type", value);
10133            if (val) {
10134              elem.value = val;
10135            }
10136            return value;
10137          }
10138        }
10139      }
10140    },
10141    propFix: {
10142      "for": "htmlFor",
10143      "class": "className"
10144    },
10145    prop: function (elem, name, value) {
10146      var ret,
10147        hooks,
10148        notxml,
10149        nType = elem.nodeType;
10150
10151      // don't get/set properties on text, comment and attribute nodes
10152      if (!elem || nType === 3 || nType === 8 || nType === 2) {
10153        return;
10154      }
10155      notxml = nType !== 1 || !jQuery.isXMLDoc(elem);
10156      if (notxml) {
10157        // Fix name and attach hooks
10158        name = jQuery.propFix[name] || name;
10159        hooks = jQuery.propHooks[name];
10160      }
10161      if (value !== undefined) {
10162        return hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined ? ret : elem[name] = value;
10163      } else {
10164        return hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null ? ret : elem[name];
10165      }
10166    },
10167    propHooks: {
10168      tabIndex: {
10169        get: function (elem) {
10170          return elem.hasAttribute("tabindex") || rfocusable.test(elem.nodeName) || elem.href ? elem.tabIndex : -1;
10171        }
10172      }
10173    }
10174  });
10175
10176  // Hooks for boolean attributes
10177  boolHook = {
10178    set: function (elem, value, name) {
10179      if (value === false) {
10180        // Remove boolean attributes when set to false
10181        jQuery.removeAttr(elem, name);
10182      } else {
10183        elem.setAttribute(name, name);
10184      }
10185      return name;
10186    }
10187  };
10188  jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (i, name) {
10189    var getter = jQuery.expr.attrHandle[name] || jQuery.find.attr;
10190    jQuery.expr.attrHandle[name] = function (elem, name, isXML) {
10191      var fn = jQuery.expr.attrHandle[name],
10192        ret = isXML ? undefined : /* jshint eqeqeq: false */
10193        // Temporarily disable this handler to check existence
10194        (jQuery.expr.attrHandle[name] = undefined) != getter(elem, name, isXML) ? name.toLowerCase() : null;
10195
10196      // Restore handler
10197      jQuery.expr.attrHandle[name] = fn;
10198      return ret;
10199    };
10200  });
10201
10202  // Support: IE9+
10203  // Selectedness for an option in an optgroup can be inaccurate
10204  if (!jQuery.support.optSelected) {
10205    jQuery.propHooks.selected = {
10206      get: function (elem) {
10207        var parent = elem.parentNode;
10208        if (parent && parent.parentNode) {
10209          parent.parentNode.selectedIndex;
10210        }
10211        return null;
10212      }
10213    };
10214  }
10215  jQuery.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () {
10216    jQuery.propFix[this.toLowerCase()] = this;
10217  });
10218
10219  // Radios and checkboxes getter/setter
10220  jQuery.each(["radio", "checkbox"], function () {
10221    jQuery.valHooks[this] = {
10222      set: function (elem, value) {
10223        if (jQuery.isArray(value)) {
10224          return elem.checked = jQuery.inArray(jQuery(elem).val(), value) >= 0;
10225        }
10226      }
10227    };
10228    if (!jQuery.support.checkOn) {
10229      jQuery.valHooks[this].get = function (elem) {
10230        // Support: Webkit
10231        // "" is returned instead of "on" if a value isn't specified
10232        return elem.getAttribute("value") === null ? "on" : elem.value;
10233      };
10234    }
10235  });
10236  var rkeyEvent = /^key/,
10237    rmouseEvent = /^(?:mouse|contextmenu)|click/,
10238    rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
10239    rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
10240  function returnTrue() {
10241    return true;
10242  }
10243  function returnFalse() {
10244    return false;
10245  }
10246  function safeActiveElement() {
10247    try {
10248      return document.activeElement;
10249    } catch (err) {}
10250  }
10251
10252  /*
10253   * Helper functions for managing events -- not part of the public interface.
10254   * Props to Dean Edwards' addEvent library for many of the ideas.
10255   */
10256  jQuery.event = {
10257    global: {},
10258    add: function (elem, types, handler, data, selector) {
10259      var handleObjIn,
10260        eventHandle,
10261        tmp,
10262        events,
10263        t,
10264        handleObj,
10265        special,
10266        handlers,
10267        type,
10268        namespaces,
10269        origType,
10270        elemData = data_priv.get(elem);
10271
10272      // Don't attach events to noData or text/comment nodes (but allow plain objects)
10273      if (!elemData) {
10274        return;
10275      }
10276
10277      // Caller can pass in an object of custom data in lieu of the handler
10278      if (handler.handler) {
10279        handleObjIn = handler;
10280        handler = handleObjIn.handler;
10281        selector = handleObjIn.selector;
10282      }
10283
10284      // Make sure that the handler has a unique ID, used to find/remove it later
10285      if (!handler.guid) {
10286        handler.guid = jQuery.guid++;
10287      }
10288
10289      // Init the element's event structure and main handler, if this is the first
10290      if (!(events = elemData.events)) {
10291        events = elemData.events = {};
10292      }
10293      if (!(eventHandle = elemData.handle)) {
10294        eventHandle = elemData.handle = function (e) {
10295          // Discard the second event of a jQuery.event.trigger() and
10296          // when an event is called after a page has unloaded
10297          return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.dispatch.apply(eventHandle.elem, arguments) : undefined;
10298        };
10299        // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
10300        eventHandle.elem = elem;
10301      }
10302
10303      // Handle multiple events separated by a space
10304      types = (types || "").match(core_rnotwhite) || [""];
10305      t = types.length;
10306      while (t--) {
10307        tmp = rtypenamespace.exec(types[t]) || [];
10308        type = origType = tmp[1];
10309        namespaces = (tmp[2] || "").split(".").sort();
10310
10311        // There *must* be a type, no attaching namespace-only handlers
10312        if (!type) {
10313          continue;
10314        }
10315
10316        // If event changes its type, use the special event handlers for the changed type
10317        special = jQuery.event.special[type] || {};
10318
10319        // If selector defined, determine special event api type, otherwise given type
10320        type = (selector ? special.delegateType : special.bindType) || type;
10321
10322        // Update special based on newly reset type
10323        special = jQuery.event.special[type] || {};
10324
10325        // handleObj is passed to all event handlers
10326        handleObj = jQuery.extend({
10327          type: type,
10328          origType: origType,
10329          data: data,
10330          handler: handler,
10331          guid: handler.guid,
10332          selector: selector,
10333          needsContext: selector && jQuery.expr.match.needsContext.test(selector),
10334          namespace: namespaces.join(".")
10335        }, handleObjIn);
10336
10337        // Init the event handler queue if we're the first
10338        if (!(handlers = events[type])) {
10339          handlers = events[type] = [];
10340          handlers.delegateCount = 0;
10341
10342          // Only use addEventListener if the special events handler returns false
10343          if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {
10344            if (elem.addEventListener) {
10345              elem.addEventListener(type, eventHandle, false);
10346            }
10347          }
10348        }
10349        if (special.add) {
10350          special.add.call(elem, handleObj);
10351          if (!handleObj.handler.guid) {
10352            handleObj.handler.guid = handler.guid;
10353          }
10354        }
10355
10356        // Add to the element's handler list, delegates in front
10357        if (selector) {
10358          handlers.splice(handlers.delegateCount++, 0, handleObj);
10359        } else {
10360          handlers.push(handleObj);
10361        }
10362
10363        // Keep track of which events have ever been used, for event optimization
10364        jQuery.event.global[type] = true;
10365      }
10366
10367      // Nullify elem to prevent memory leaks in IE
10368      elem = null;
10369    },
10370    // Detach an event or set of events from an element
10371    remove: function (elem, types, handler, selector, mappedTypes) {
10372      var j,
10373        origCount,
10374        tmp,
10375        events,
10376        t,
10377        handleObj,
10378        special,
10379        handlers,
10380        type,
10381        namespaces,
10382        origType,
10383        elemData = data_priv.hasData(elem) && data_priv.get(elem);
10384      if (!elemData || !(events = elemData.events)) {
10385        return;
10386      }
10387
vendor: 6,790 bytes, lines 10388-10562
10388      // Once for each type.namespace in types; type may be omitted
10389      types = (types || "").match(core_rnotwhite) || [""];
10390      t = types.length;
10391      while (t--) {
10392        tmp = rtypenamespace.exec(types[t]) || [];
10393        type = origType = tmp[1];
10394        namespaces = (tmp[2] || "").split(".").sort();
10395
10396        // Unbind all events (on this namespace, if provided) for the element
10397        if (!type) {
10398          for (type in events) {
10399            jQuery.event.remove(elem, type + types[t], handler, selector, true);
10400          }
10401          continue;
10402        }
10403        special = jQuery.event.special[type] || {};
10404        type = (selector ? special.delegateType : special.bindType) || type;
10405        handlers = events[type] || [];
10406        tmp = tmp[2] && new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)");
10407
10408        // Remove matching events
10409        origCount = j = handlers.length;
10410        while (j--) {
10411          handleObj = handlers[j];
10412          if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) {
10413            handlers.splice(j, 1);
10414            if (handleObj.selector) {
10415              handlers.delegateCount--;
10416            }
10417            if (special.remove) {
10418              special.remove.call(elem, handleObj);
10419            }
10420          }
10421        }
10422
10423        // Remove generic event handler if we removed something and no more handlers exist
10424        // (avoids potential for endless recursion during removal of special event handlers)
10425        if (origCount && !handlers.length) {
10426          if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) {
10427            jQuery.removeEvent(elem, type, elemData.handle);
10428          }
10429          delete events[type];
10430        }
10431      }
10432
10433      // Remove the expando if it's no longer used
10434      if (jQuery.isEmptyObject(events)) {
10435        delete elemData.handle;
10436        data_priv.remove(elem, "events");
10437      }
10438    },
10439    trigger: function (event, data, elem, onlyHandlers) {
10440      var i,
10441        cur,
10442        tmp,
10443        bubbleType,
10444        ontype,
10445        handle,
10446        special,
10447        eventPath = [elem || document],
10448        type = core_hasOwn.call(event, "type") ? event.type : event,
10449        namespaces = core_hasOwn.call(event, "namespace") ? event.namespace.split(".") : [];
10450      cur = tmp = elem = elem || document;
10451
10452      // Don't do events on text and comment nodes
10453      if (elem.nodeType === 3 || elem.nodeType === 8) {
10454        return;
10455      }
10456
10457      // focus/blur morphs to focusin/out; ensure we're not firing them right now
10458      if (rfocusMorph.test(type + jQuery.event.triggered)) {
10459        return;
10460      }
10461      if (type.indexOf(".") >= 0) {
10462        // Namespaced trigger; create a regexp to match event type in handle()
10463        namespaces = type.split(".");
10464        type = namespaces.shift();
10465        namespaces.sort();
10466      }
10467      ontype = type.indexOf(":") < 0 && "on" + type;
10468
10469      // Caller can pass in a jQuery.Event object, Object, or just an event type string
10470      event = event[jQuery.expando] ? event : new jQuery.Event(type, typeof event === "object" && event);
10471
10472      // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
10473      event.isTrigger = onlyHandlers ? 2 : 3;
10474      event.namespace = namespaces.join(".");
10475      event.namespace_re = event.namespace ? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null;
10476
10477      // Clean up the event in case it is being reused
10478      event.result = undefined;
10479      if (!event.target) {
10480        event.target = elem;
10481      }
10482
10483      // Clone any incoming data and prepend the event, creating the handler arg list
10484      data = data == null ? [event] : jQuery.makeArray(data, [event]);
10485
10486      // Allow special events to draw outside the lines
10487      special = jQuery.event.special[type] || {};
10488      if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
10489        return;
10490      }
10491
10492      // Determine event propagation path in advance, per W3C events spec (#9951)
10493      // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
10494      if (!onlyHandlers && !special.noBubble && !jQuery.isWindow(elem)) {
10495        bubbleType = special.delegateType || type;
10496        if (!rfocusMorph.test(bubbleType + type)) {
10497          cur = cur.parentNode;
10498        }
10499        for (; cur; cur = cur.parentNode) {
10500          eventPath.push(cur);
10501          tmp = cur;
10502        }
10503
10504        // Only add window if we got to document (e.g., not plain obj or detached DOM)
10505        if (tmp === (elem.ownerDocument || document)) {
10506          eventPath.push(tmp.defaultView || tmp.parentWindow || window);
10507        }
10508      }
10509
10510      // Fire handlers on the event path
10511      i = 0;
10512      while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {
10513        event.type = i > 1 ? bubbleType : special.bindType || type;
10514
10515        // jQuery handler
10516        handle = (data_priv.get(cur, "events") || {})[event.type] && data_priv.get(cur, "handle");
10517        if (handle) {
10518          handle.apply(cur, data);
10519        }
10520
10521        // Native handler
10522        handle = ontype && cur[ontype];
10523        if (handle && jQuery.acceptData(cur) && handle.apply && handle.apply(cur, data) === false) {
10524          event.preventDefault();
10525        }
10526      }
10527      event.type = type;
10528
10529      // If nobody prevented the default action, do it now
10530      if (!onlyHandlers && !event.isDefaultPrevented()) {
10531        if ((!special._default || special._default.apply(eventPath.pop(), data) === false) && jQuery.acceptData(elem)) {
10532          // Call a native DOM method on the target with the same name name as the event.
10533          // Don't do default actions on window, that's where global variables be (#6170)
10534          if (ontype && jQuery.isFunction(elem[type]) && !jQuery.isWindow(elem)) {
10535            // Don't re-trigger an onFOO event when we call its FOO() method
10536            tmp = elem[ontype];
10537            if (tmp) {
10538              elem[ontype] = null;
10539            }
10540
10541            // Prevent re-triggering of the same event, since we already bubbled it above
10542            jQuery.event.triggered = type;
10543            elem[type]();
10544            jQuery.event.triggered = undefined;
10545            if (tmp) {
10546              elem[ontype] = tmp;
10547            }
10548          }
10549        }
10550      }
10551      return event.result;
10552    },
10553    dispatch: function (event) {
10554      // Make a writable jQuery.Event from the native event object
10555      event = jQuery.event.fix(event);
10556      var i,
10557        j,
10558        ret,
10559        matched,
10560        handleObj,
10561        handlerQueue = [],
10562        args = core_slice.call(arguments),
10563        handlers = (data_priv.get(this, "events") || {})[event.type] || [],
10564        special = jQuery.event.special[event.type] || {};
10565
10566      // Use the fix-ed jQuery.Event rather than the (read-only) native event
10567      args[0] = event;
10568      event.delegateTarget = this;
10569
10570      // Call the preDispatch hook for the mapped type, and let it bail if desired
10571      if (special.preDispatch && special.preDispatch.call(this, event) === false) {
10572        return;
10573      }
10574
10575      // Determine handlers
10576      handlerQueue = jQuery.event.handlers.call(this, event, handlers);
10577
10578      // Run delegates first; they may want to stop propagation beneath us
10579      i = 0;
10580      while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {
10581        event.currentTarget = matched.elem;
10582        j = 0;
10583        while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) {
10584          // Triggered event must either 1) have no namespace, or
10585          // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
10586          if (!event.namespace_re || event.namespace_re.test(handleObj.namespace)) {
10587            event.handleObj = handleObj;
10588            event.data = handleObj.data;
10589            ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args);
10590            if (ret !== undefined) {
10591              if ((event.result = ret) === false) {
10592                event.preventDefault();
10593                event.stopPropagation();
10594              }
10595            }
10596          }
10597        }
10598      }
10599
10600      // Call the postDispatch hook for the mapped type
10601      if (special.postDispatch) {
10602        special.postDispatch.call(this, event);
10603      }
10604      return event.result;
10605    },
10606    handlers: function (event, handlers) {
10607      var i,
10608        matches,
10609        sel,
10610        handleObj,
10611        handlerQueue = [],
10612        delegateCount = handlers.delegateCount,
10613        cur = event.target;
10614
10615      // Find delegate handlers
10616      // Black-hole SVG <use> instance trees (#13180)
10617      // Avoid non-left-click bubbling in Firefox (#3861)
10618      if (delegateCount && cur.nodeType && (!event.button || event.type !== "click")) {
10619        for (; cur !== this; cur = cur.parentNode || this) {
10620          // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
10621          if (cur.disabled !== true || event.type !== "click") {
10622            matches = [];
10623            for (i = 0; i < delegateCount; i++) {
10624              handleObj = handlers[i];
10625
10626              // Don't conflict with Object.prototype properties (#13203)
10627              sel = handleObj.selector + " ";
10628              if (matches[sel] === undefined) {
10629                matches[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) >= 0 : jQuery.find(sel, this, null, [cur]).length;
10630              }
10631              if (matches[sel]) {
10632                matches.push(handleObj);
10633              }
10634            }
10635            if (matches.length) {
10636              handlerQueue.push({
10637                elem: cur,
10638                handlers: matches
10639              });
10640            }
10641          }
10642        }
10643      }
10644
10645      // Add the remaining (directly-bound) handlers
10646      if (delegateCount < handlers.length) {
10647        handlerQueue.push({
10648          elem: this,
10649          handlers: handlers.slice(delegateCount)
10650        });
10651      }
10652      return handlerQueue;
10653    },
10654    // Includes some event props shared by KeyEvent and MouseEvent
10655    props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
10656    fixHooks: {},
10657    keyHooks: {
10658      props: "char charCode key keyCode".split(" "),
10659      filter: function (event, original) {
10660        // Add which for key events
10661        if (event.which == null) {
10662          event.which = original.charCode != null ? original.charCode : original.keyCode;
10663        }
10664        return event;
10665      }
10666    },
10667    mouseHooks: {
10668      props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
10669      filter: function (event, original) {
10670        var eventDoc,
10671          doc,
10672          body,
10673          button = original.button;
10674
10675        // Calculate pageX/Y if missing and clientX/Y available
10676        if (event.pageX == null && original.clientX != null) {
10677          eventDoc = event.target.ownerDocument || document;
10678          doc = eventDoc.documentElement;
10679          body = eventDoc.body;
10680          event.pageX = original.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
10681          event.pageY = original.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
10682        }
10683
10684        // Add which for click: 1 === left; 2 === middle; 3 === right
10685        // Note: button is not normalized, so don't use it
10686        if (!event.which && button !== undefined) {
10687          event.which = button & 1 ? 1 : button & 2 ? 3 : button & 4 ? 2 : 0;
10688        }
10689        return event;
10690      }
10691    },
10692    fix: function (event) {
10693      if (event[jQuery.expando]) {
10694        return event;
10695      }
10696
10697      // Create a writable copy of the event object and normalize some properties
10698      var i,
10699        prop,
10700        copy,
10701        type = event.type,
10702        originalEvent = event,
10703        fixHook = this.fixHooks[type];
10704      if (!fixHook) {
10705        this.fixHooks[type] = fixHook = rmouseEvent.test(type) ? this.mouseHooks : rkeyEvent.test(type) ? this.keyHooks 
10705: {};
10706      }
10707      copy = fixHook.props ? this.props.concat(fixHook.props) : this.props;
10708      event = new jQuery.Event(originalEvent);
10709      i = copy.length;
10710      while (i--) {
10711        prop = copy[i];
10712        event[prop] = originalEvent[prop];
10713      }
10714
10715      // Support: Cordova 2.5 (WebKit) (#13255)
10716      // All events should have a target; Cordova deviceready doesn't
10717      if (!event.target) {
10718        event.target = document;
10719      }
10720
10721      // Support: Safari 6.0+, Chrome < 28
10722      // Target should not be a text node (#504, #13143)
10723      if (event.target.nodeType === 3) {
10724        event.target = event.target.parentNode;
10725      }
10726      return fixHook.filter ? fixHook.filter(event, originalEvent) : event;
10727    },
10728    special: {
10729      load: {
10730        // Prevent triggered image.load events from bubbling to window.load
10731        noBubble: true
10732      },
10733      focus: {
10734        // Fire native event if possible so blur/focus sequence is correct
10735        trigger: function () {
10736          if (this !== safeActiveElement() && this.focus) {
10737            this.focus();
10738            return false;
10739          }
10740        },
10741        delegateType: "focusin"
10742      },
10743      blur: {
10744        trigger: function () {
10745          if (this === safeActiveElement() && this.blur) {
10746            this.blur();
10747            return false;
10748          }
10749        },
10750        delegateType: "focusout"
10751      },
10752      click: {
10753        // For checkbox, fire native event so checked state will be right
10754        trigger: function () {
10755          if (this.type === "checkbox" && this.click && jQuery.nodeName(this, "input")) {
10756            this.click();
10757            return false;
10758          }
10759        },
10760        // For cross-browser consistency, don't fire native .click() on links
10761        _default: function (event) {
10762          return jQuery.nodeName(event.target, "a");
10763        }
10764      },
10765      beforeunload: {
10766        postDispatch: function (event) {
10767          // Support: Firefox 20+
10768          // Firefox doesn't alert if the returnValue field is not set.
10769          if (event.result !== undefined) {
10770            event.originalEvent.returnValue = event.result;
10771          }
10772        }
10773      }
10774    },
10775    simulate: function (type, elem, event, bubble) {
10776      // Piggyback on a donor event to simulate a different one.
10777      // Fake originalEvent to avoid donor's stopPropagation, but if the
10778      // simulated event prevents default then we do the same on the donor.
10779      var e = jQuery.extend(new jQuery.Event(), event, {
10780        type: type,
10781        isSimulated: true,
10782        originalEvent: {}
10783      });
10784      if (bubble) {
10785        jQuery.event.trigger(e, null, elem);
10786      } else {
10787        jQuery.event.dispatch.call(elem, e);
10788      }
10789      if (e.isDefaultPrevented()) {
10790        event.preventDefault();
10791      }
10792    }
10793  };
10794  jQuery.removeEvent = function (elem, type, handle) {
10795    if (elem.removeEventListener) {
10796      elem.removeEventListener(type, handle, false);
10797    }
10798  };
10799  jQuery.Event = function (src, props) {
10800    // Allow instantiation without the 'new' keyword
10801    if (!(this instanceof jQuery.Event)) {
10802      return new jQuery.Event(src, props);
10803    }
10804
10805    // Event object
10806    if (src && src.type) {
10807      this.originalEvent = src;
10808      this.type = src.type;
10809
10810      // Events bubbling up the document may have been marked as prevented
10811      // by a handler lower down the tree; reflect the correct value.
10812      this.isDefaultPrevented = src.defaultPrevented || src.getPreventDefault && src.getPreventDefault() ? returnTrue : returnFalse;
10813
10814      // Event type
10815    } else {
10816      this.type = src;
10817    }
10818
10819    // Put explicitly provided properties onto the event object
10820    if (props) {
10821      jQuery.extend(this, props);
10822    }
10823
10824    // Create a timestamp if incoming event doesn't have one
10825    this.timeStamp = src && src.timeStamp || jQuery.now();
10826
10827    // Mark it as fixed
10828    this[jQuery.expando] = true;
10829  };
10830
10831  // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
10832  // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
10833  jQuery.Event.prototype = {
10834    isDefaultPrevented: returnFalse,
10835    isPropagationStopped: returnFalse,
10836    isImmediatePropagationStopped: returnFalse,
10837    preventDefault: function () {
10838      var e = this.originalEvent;
10839      this.isDefaultPrevented = returnTrue;
10840      if (e && e.preventDefault) {
10841        e.preventDefault();
10842      }
10843    },
10844    stopPropagation: function () {
10845      var e = this.originalEvent;
10846      this.isPropagationStopped = returnTrue;
10847      if (e && e.stopPropagation) {
10848        e.stopPropagation();
10849      }
10850    },
10851    stopImmediatePropagation: function () {
10852      this.isImmediatePropagationStopped = returnTrue;
10853      this.stopPropagation();
10854    }
10855  };
10856
10857  // Create mouseenter/leave events using mouseover/out and event-time checks
10858  // Support: Chrome 15+
10859  jQuery.each({
10860    mouseenter: "mouseover",
10861    mouseleave: "mouseout"
10862  }, function (orig, fix) {
10863    jQuery.event.special[orig] = {
10864      delegateType: fix,
10865      bindType: fix,
10866      handle: function (event) {
10867        var ret,
10868          target = this,
10869          related = event.relatedTarget,
10870          handleObj = event.handleObj;
10871
10872        // For mousenter/leave call the handler if related is outside the target.
10873        // NB: No relatedTarget if the mouse left/entered the browser window
10874        if (!related || related !== target && !jQuery.contains(target, related)) {
10875          event.type = handleObj.origType;
10876          ret = handleObj.handler.apply(this, arguments);
10877          event.type = fix;
10878        }
10879        return ret;
10880      }
10881    };
10882  });
10883
10884  // Create "bubbling" focus and blur events
10885  // Support: Firefox, Chrome, Safari
10886  if (!jQuery.support.focusinBubbles) {
10887    jQuery.each({
10888      focus: "focusin",
10889      blur: "focusout"
10890    }, function (orig, fix) {
10891      // Attach a single capturing handler while someone wants focusin/focusout
10892      var attaches = 0,
10893        handler = function (event) {
10894          jQuery.event.simulate(fix, event.target, jQuery.event.fix(event), true);
10895        };
10896      jQuery.event.special[fix] = {
10897        setup: function () {
10898          if (attaches++ === 0) {
10899            document.addEventListener(orig, handler, true);
10900          }
10901        },
10902        teardown: function () {
10903          if (--attaches === 0) {
10904            document.removeEventListener(orig, handler, true);
10905          }
10906        }
10907      };
10908    });
10909  }
10910  jQuery.fn.extend({
10911    on: function (types, selector, data, fn, /*INTERNAL*/one) {
10912      var origFn, type;
10913
10914      // Types can be a map of types/handlers
10915      if (typeof types === "object") {
10916        // ( types-Object, selector, data )
10917        if (typeof selector !== "string") {
10918          // ( types-Object, data )
10919          data = data || selector;
10920          selector = undefined;
10921        }
10922        for (type in types) {
10923          this.on(type, selector, data, types[type], one);
10924        }
10925        return this;
10926      }
10927      if (data == null && fn == null) {
10928        // ( types, fn )
10929        fn = selector;
10930        data = selector = undefined;
10931      } else if (fn == null) {
10932        if (typeof selector === "string") {
10933          // ( types, selector, fn )
10934          fn = data;
10935          data = undefined;
10936        } else {
10937          // ( types, data, fn )
10938          fn = data;
10939          data = selector;
10940          selector = undefined;
10941        }
10942      }
10943      if (fn === false) {
10944        fn = returnFalse;
10945      } else if (!fn) {
10946        return this;
10947      }
10948      if (one === 1) {
10949        origFn = fn;
10950        fn = function (event) {
10951          // Can use an empty set, since event contains the info
10952          jQuery().off(event);
10953          return origFn.apply(this, arguments);
10954        };
10955        // Use same guid so caller can remove using origFn
10956        fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
10957      }
10958      return this.each(function () {
10959        jQuery.event.add(this, types, fn, data, selector);
10960      });
10961    },
10962    one: function (types, selector, data, fn) {
10963      return this.on(types, selector, data, fn, 1);
10964    },
10965    off: function (types, selector, fn) {
10966      var handleObj, type;
10967      if (types && types.preventDefault && types.handleObj) {
10968        // ( event )  dispatched jQuery.Event
10969        handleObj = types.handleObj;
10970        jQuery(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler);
10971        return this;
10972      }
10973      if (typeof types === "object") {
10974        // ( types-object [, selector] )
10975        for (type in types) {
10976          this.off(type, selector, types[type]);
10977        }
10978        return this;
10979      }
10980      if (selector === false || typeof selector === "function") {
10981        // ( types [, fn] )
10982        fn = selector;
10983        selector = undefined;
10984      }
10985      if (fn === false) {
10986        fn = returnFalse;
10987      }
10988      return this.each(function () {
10989        jQuery.event.remove(this, types, fn, selector);
10990      });
10991    },
10992    trigger: function (type, data) {
10993      return this.each(function () {
10994        jQuery.event.trigger(type, data, this);
10995      });
10996    },
10997    triggerHandler: function (type, data) {
10998      var elem = this[0];
10999      if (elem) {
11000        return jQuery.event.trigger(type, data, elem, true);
11001      }
11002    }
11003  });
11004  var isSimple = /^.[^:#\[\.,]*$/,
11005    rparentsprev = /^(?:parents|prev(?:Until|All))/,
11006    rneedsContext = jQuery.expr.match.needsContext,
11007    // methods guaranteed to produce a unique set when starting from a unique set
11008    guaranteedUnique = {
11009      children: true,
11010      contents: true,
11011      next: true,
11012      prev: true
11013    };
11014  jQuery.fn.extend({
11015    find: function (selector) {
11016      var i,
11017        ret = [],
11018        self = this,
11019        len = self.length;
11020      if (typeof selector !== "string") {
11021        return this.pushStack(jQuery(selector).filter(function () {
11022          for (i = 0; i < len; i++) {
11023            if (jQuery.contains(self[i], this)) {
11024              return true;
11025            }
11026          }
11027        }));
11028      }
11029      for (i = 0; i < len; i++) {
11030        jQuery.find(selector, self[i], ret);
11031      }
11032
11033      // Needed because $( selector, context ) becomes $( context ).find( selector )
11034      ret = this.pushStack(len > 1 ? jQuery.unique(ret) : ret);
11035      ret.selector = this.selector ? this.selector + " " + selector : selector;
11036      return ret;
11037    },
11038    has: function (target) {
11039      var targets = jQuery(target, this),
11040        l = targets.length;
11041      return this.filter(function () {
11042        var i = 0;
11043        for (; i < l; i++) {
11044          if (jQuery.contains(this, targets[i])) {
11045            return true;
11046          }
11047        }
11048      });
11049    },
11050    not: function (selector) {
11051      return this.pushStack(winnow(this, selector || [], true));
11052    },
11053    filter: function (selector) {
11054      return this.pushStack(winnow(this, selector || [], false));
11055    },
11056    is: function (selector) {
11057      return !!winnow(this,
11058      // If this is a positional/relative selector, check membership in the returned set
11059      // so $("p:first").is("p:last") won't return true for a doc with two "p".
11060      typeof selector === "string" && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false).length;
11061    },
11062    closest: function (selectors, context) {
11063      var cur,
11064        i = 0,
11065        l = this.length,
11066        matched = [],
11067        pos = rneedsContext.test(selectors) || typeof selectors !== "string" ? jQuery(selectors, context || this.context) : 0;
11068      for (; i < l; i++) {
11069        for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {
11070          // Always skip document fragments
11071          if (cur.nodeType < 11 && (pos ? pos.index(cur) > -1 :
11072          // Don't pass non-elements to Sizzle
11073          cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) {
11074            cur = matched.push(cur);
11075            break;
11076          }
11077        }
11078      }
11079      return this.pushStack(matched.length > 1 ? jQuery.unique(matched) : matched);
11080    },
11081    // Determine the position of an element within
11082    // the matched set of elements
11083    index: function (elem) {
11084      // No argument, return index in parent
11085      if (!elem) {
11086        return this[0] && this[0].parentNode ? this.first().prevAll().length : -1;
11087      }
11088
11089      // index in selector
11090      if (typeof elem === "string") {
11091        return core_indexOf.call(jQuery(elem), this[0]);
11092      }
11093
11094      // Locate the position of the desired element
11095      return core_indexOf.call(this,
11096      // If it receives a jQuery object, the first element is used
11097      elem.jquery ? elem[0] : elem);
11098    },
11099    add: function (selector, context) {
11100      var set = typeof selector === "string" ? jQuery(selector, context) : jQuery.makeArray(selector && selector.nodeType ? [selector] : selector),
11101        all = jQuery.merge(this.get(), set);
11102      return this.pushStack(jQuery.unique(all));
11103    },
11104    addBack: function (selector) {
11105      return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector));
11106    }
11107  });
11108  function sibling(cur, dir) {
11109    while ((cur = cur[dir]) && cur.nodeType !== 1) {}
11110    return cur;
11111  }
11112  jQuery.each({
11113    parent: function (elem) {
11114      var parent = elem.parentNode;
11115      return parent && parent.nodeType !== 11 ? parent : null;
11116    },
11117    parents: function (elem) {
11118      return jQuery.dir(elem, "parentNode");
11119    },
11120    parentsUntil: function (elem, i, until) {
11121      return jQuery.dir(elem, "parentNode", until);
11122    },
11123    next: function (elem) {
11124      return sibling(elem, "nextSibling");
11125    },
11126    prev: function (elem) {
11127      return sibling(elem, "previousSibling");
11128    },
11129    nextAll: function (elem) {
11130      return jQuery.dir(elem, "nextSibling");
11131    },
11132    prevAll: function (elem) {
11133      return jQuery.dir(elem, "previousSibling");
11134    },
11135    nextUntil: function (elem, i, until) {
11136      return jQuery.dir(elem, "nextSibling", until);
11137    },
11138    prevUntil: function (elem, i, until) {
11139      return jQuery.dir(elem, "previousSibling", until);
11140    },
11141    siblings: function (elem) {
11142      return jQuery.sibling((elem.parentNode || {}).firstChild, elem);
11143    },
11144    children: function (elem) {
11145      return jQuery.sibling(elem.firstChild);
11146    },
11147    contents: function (elem) {
11148      return elem.contentDocument || jQuery.merge([], elem.childNodes);
11149    }
11150  }, function (name, fn) {
11151    jQuery.fn[name] = function (until, selector) {
11152      var matched = jQuery.map(this, fn, until);
11153      if (name.slice(-5) !== "Until") {
11154        selector = until;
11155      }
11156      if (selector && typeof selector === "string") {
11157        matched = jQuery.filter(selector, matched);
11158      }
11159      if (this.length > 1) {
11160        // Remove duplicates
11161        if (!guaranteedUnique[name]) {
11162          jQuery.unique(matched);
11163        }
11164
11165        // Reverse order for parents* and prev-derivatives
11166        if (rparentsprev.test(name)) {
11167          matched.reverse();
11168        }
11169      }
11170      return this.pushStack(matched);
11171    };
11172  });
11173  jQuery.extend({
11174    filter: function (expr, elems, not) {
11175      var elem = elems[0];
11176      if (not) {
11177        expr = ":not(" + expr + ")";
11178      }
11179      return elems.length === 1 && elem.nodeType === 1 ? jQuery.find.matchesSelector(elem, expr) ? [elem] : [] : jQuery.find.matches(expr, jQuery.grep(elems, function (elem) {
11180        return elem.nodeType === 1;
11181      }));
11182    },
11183    dir: function (elem, dir, until) {
11184      var matched = [],
11185        truncate = until !== undefined;
11186      while ((elem = elem[dir]) && elem.nodeType !== 9) {
11187        if (elem.nodeType === 1) {
11188          if (truncate && jQuery(elem).is(until)) {
11189            break;
11190          }
11191          matched.push(elem);
11192        }
11193      }
11194      return matched;
11195    },
11196    sibling: function (n, elem) {
11197      var matched = [];
11198      for (; n; n = n.nextSibling) {
11199        if (n.nodeType === 1 && n !== elem) {
11200          matched.push(n);
11201        }
11202      }
11203      return matched;
11204    }
11205  });
11206
11207  // Implement the identical functionality for filter and not
11208  function winnow(elements, qualifier, not) {
11209    if (jQuery.isFunction(qualifier)) {
11210      return jQuery.grep(elements, function (elem, i) {
11211        /* jshint -W018 */
11212        return !!qualifier.call(elem, i, elem) !== not;
11213      });
11214    }
11215    if (qualifier.nodeType) {
11216      return jQuery.grep(elements, function (elem) {
11217        return elem === qualifier !== not;
11218      });
11219    }
11220    if (typeof qualifier === "string") {
11221      if (isSimple.test(qualifier)) {
11222        return jQuery.filter(qualifier, elements, not);
11223      }
11224      qualifier = jQuery.filter(qualifier, elements);
11225    }
11226    return jQuery.grep(elements, function (elem) {
11227      return core_indexOf.call(qualifier, elem) >= 0 !== not;
11228    });
11229  }
11230  var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
11231    rtagName = /<([\w:]+)/,
11232    rhtml = /<|&#?\w+;/,
11233    rnoInnerhtml = /<(?:script|style|link)/i,
11234    manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
11235    // checked="checked" or checked
11236    rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
11237    rscriptType = /^$|\/(?:java|ecma)script/i,
11238    rscriptTypeMasked = /^true\/(.*)/,
11239    rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
11240    // We have to close these tags to support XHTML (#13200)
11241    wrapMap = {
11242      // Support: IE 9
11243      option: [1, "<select multiple='multiple'>", "</select>"],
11244      thead: [1, "<table>", "</table>"],
11245      col: [2, "<table><colgroup>", "</colgroup></table>"],
11246      tr: [2, "<table><tbody>", "</tbody></table>"],
11247      td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],
11248      _default: [0, "", ""]
11249    };
11250
11251  // Support: IE 9
11252  wrapMap.optgroup = wrapMap.option;
11253  wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
11254  wrapMap.th = wrapMap.td;
11255  jQuery.fn.extend({
11256    text: function (value) {
11257      return jQuery.access(this, function (value) {
11258        return value === undefined ? jQuery.text(this) : this.empty().append((this[0] && this[0].ownerDocument || document).createTextNode(value));
11259      }, null, value, arguments.length);
11260    },
11261    append: function () {
11262      return this.domManip(arguments, function (elem) {
11263        if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
11264          var target = manipulationTarget(this, elem);
11265          target.appendChild(elem);
11266        }
11267      });
11268    },
11269    prepend: function () {
11270      return this.domManip(arguments, function (elem) {
11271        if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
11272          var target = manipulationTarget(this, elem);
11273          target.insertBefore(elem, target.firstChild);
11274        }
11275      });
11276    },
11277    before: function () {
11278      return this.domManip(arguments, function (elem) {
11279        if (this.parentNode) {
11280          this.parentNode.insertBefore(elem, this);
11281        }
11282      });
11283    },
11284    after: function () {
11285      return this.domManip(arguments, function (elem) {
11286        if (this.parentNode) {
11287          this.parentNode.insertBefore(elem, this.nextSibling);
11288        }
11289      });
11290    },
11291    // keepData is for internal use only--do not document
11292    remove: function (selector, keepData) {
11293      var elem,
11294        elems = selector ? jQuery.filter(selector, this) : this,
11295        i = 0;
11296      for (; (elem = elems[i]) != null; i++) {
11297        if (!keepData && elem.nodeType === 1) {
11298          jQuery.cleanData(getAll(elem));
11299        }
11300        if (elem.parentNode) {
11301          if (keepData && jQuery.contains(elem.ownerDocument, elem)) {
11302            setGlobalEval(getAll(elem, "script"));
11303          }
11304          elem.parentNode.removeChild(elem);
11305        }
11306      }
11307      return this;
11308    },
11309    empty: function () {
11310      var elem,
11311        i = 0;
11312      for (; (elem = this[i]) != null; i++) {
11313        if (elem.nodeType === 1) {
11314          // Prevent memory leaks
11315          jQuery.cleanData(getAll(elem, false));
11316
11317          // Remove any remaining nodes
11318          elem.textContent = "";
11319        }
11320      }
11321      return this;
11322    },
11323    clone: function (dataAndEvents, deepDataAndEvents) {
11324      dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
11325      deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
11326      return this.map(function () {
11327        return jQuery.clone(this, dataAndEvents, deepDataAndEvents);
11328      });
11329    },
11330    html: function (value) {
11331      return jQuery.access(this, function (value) {
11332        var elem = this[0] || {},
11333          i = 0,
11334          l = this.length;
11335        if (value === undefined && elem.nodeType === 1) {
11336          return elem.innerHTML;
11337        }
11338
11339        // See if we can take a shortcut and just use innerHTML
11340        if (typeof value === "string" && !rnoInnerhtml.test(value) && !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) {
11341          value = value.replace(rxhtmlTag, "<$1></$2>");
11342          try {
11343            for (; i < l; i++) {
11344              elem = this[i] || {};
11345
11346              // Remove element nodes and prevent memory leaks
11347              if (elem.nodeType === 1) {
11348                jQuery.cleanData(getAll(elem, false));
11349                elem.innerHTML = value;
11350              }
11351            }
11352            elem = 0;
11353
11354            // If using innerHTML throws an exception, use the fallback method
11355          } catch (e) {}
11356        }
11357        if (elem) {
11358          this.empty().append(value);
11359        }
11360      }, null, value, arguments.length);
11361    },
11362    replaceWith: function () {
11363      var
11364        // Snapshot the DOM in case .domManip sweeps something relevant into its fragment
11365        args = jQuery.map(this, function (elem) {
11366          return [elem.nextSibling, elem.parentNode];
11367        }),
11368        i = 0;
11369
11370      // Make the changes, replacing each context element with the new content
11371      this.domManip(arguments, function (elem) {
11372        var next = args[i++],
11373          parent = args[i++];
11374        if (parent) {
11375          // Don't use the snapshot next if it has moved (#13810)
11376          if (next && next.parentNode !== parent) {
11377            next = this.nextSibling;
11378          }
11379          jQuery(this).remove();
11380          parent.insertBefore(elem, next);
11381        }
11382        // Allow new content to include elements from the context set
11383      }, true);
11384
11385      // Force removal if there was no new content (e.g., from empty arguments)
11386      return i ? this : this.remove();
11387    },
11388    detach: function (selector) {
11389      return this.remove(selector, true);
11390    },
11391    domManip: function (args, callback, allowIntersection) {
11392      // Flatten any nested arrays
11393      args = core_concat.apply([], args);
11394      var fragment,
11395        first,
11396        scripts,
11397        hasScripts,
11398        node,
11399        doc,
11400        i = 0,
11401        l = this.length,
11402        set = this,
11403        iNoClone = l - 1,
11404        value = args[0],
11405        isFunction = jQuery.isFunction(value);
11406
11407      // We can't cloneNode fragments that contain checked, in WebKit
11408      if (isFunction || !(l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test(value))) {
11409        return this.each(function (index) {
11410          var self = set.eq(index);
11411          if (isFunction) {
11412            args[0] = value.call(this, index, self.html());
11413          }
11414          self.domManip(args, callback, allowIntersection);
11415        });
11416      }
11417      if (l) {
11418        fragment = jQuery.buildFragment(args, this[0].ownerDocument, false, !allowIntersection && this);
11419        first = fragment.firstChild;
11420        if (fragment.childNodes.length === 1) {
11421          fragment = first;
11422        }
11423        if (first) {
11424          scripts = jQuery.map(getAll(fragment, "script"), disableScript);
11425          hasScripts = scripts.length;
11426
11427          // Use the original fragment for the last item instead of the first because it can end up
11428          // being emptied incorrectly in certain situations (#8070).
11429          for (; i < l; i++) {
11430            node = fragment;
11431            if (i !== iNoClone) {
11432              node = jQuery.clone(node, true, true);
11433
11434              // Keep references to cloned scripts for later restoration
11435              if (hasScripts) {
11436                // Support: QtWebKit
11437                // jQuery.merge because core_push.apply(_, arraylike) throws
11438                jQuery.merge(scripts, getAll(node, "script"));
11439              }
11440            }
11441            callback.call(this[i], node, i);
11442          }
11443          if (hasScripts) {
11444            doc = scripts[scripts.length - 1].ownerDocument;
11445
11446            // Reenable scripts
11447            jQuery.map(scripts, restoreScript);
11448
11449            // Evaluate executable scripts on first document insertion
11450            for (i = 0; i < hasScripts; i++) {
11451              node = scripts[i];
11452              if (rscriptType.test(node.type || "") && !data_priv.access(node, "globalEval") && jQuery.contains(doc, node)) {
11453                if (node.src) {
11454                  // Hope ajax is available...
11455                  jQuery._evalUrl(node.src);
11456                } else {
11457                  jQuery.globalEval(node.textContent.replace(rcleanScript, ""));
11458                }
11459              }
11460            }
11461          }
11462        }
11463      }
11464      return this;
11465    }
11466  });
11467  jQuery.each({
11468    appendTo: "append",
11469    prependTo: "prepend",
11470    insertBefore: "before",
11471    insertAfter: "after",
11472    replaceAll: "replaceWith"
11473  }, function (name, original) {
11474    jQuery.fn[name] = function (selector) {
11475      var elems,
11476        ret = [],
11477        insert = jQuery(selector),
11478        last = insert.length - 1,
11479        i = 0;
11480      for (; i <= last; i++) {
11481        elems = i === last ? this : this.clone(true);
11482        jQuery(insert[i])[original](elems);
11483
11484        // Support: QtWebKit
11485        // .get() because core_push.apply(_, arraylike) throws
11486        core_push.apply(ret, elems.get());
11487      }
11488      return this.pushStack(ret);
11489    };
11490  });
11491  jQuery.extend({
11492    clone: function (elem, dataAndEvents, deepDataAndEvents) {
11493      var i,
11494        l,
11495        srcElements,
11496        destElements,
11497        clone = elem.cloneNode(true),
11498        inPage = jQuery.contains(elem.ownerDocument, elem);
11499
11500      // Support: IE >= 9
11501      // Fix Cloning issues
11502      if (!jQuery.support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem)) {
11503        // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
11504        destElements = getAll(clone);
11505        srcElements = getAll(elem);
11506        for (i = 0, l = srcElements.length; i < l; i++) {
11507          fixInput(srcElements[i], destElements[i]);
11508        }
11509      }
11510
11511      // Copy the events from the original to the clone
11512      if (dataAndEvents) {
11513        if (deepDataAndEvents) {
11514          srcElements = srcElements || getAll(elem);
11515          destElements = destElements || getAll(clone);
11516          for (i = 0, l = srcElements.length; i < l; i++) {
11517            cloneCopyEvent(srcElements[i], destElements[i]);
11518          }
11519        } else {
11520          cloneCopyEvent(elem, clone);
11521        }
11522      }
11523
11524      // Preserve script evaluation history
11525      destElements = getAll(clone, "script");
11526      if (destElements.length > 0) {
11527        setGlobalEval(destElements, !inPage && getAll(elem, "script"));
11528      }
11529
11530      // Return the cloned set
11531      return clone;
11532    },
11533    buildFragment: function (elems, context, scripts, selection) {
11534      var elem,
11535        tmp,
11536        tag,
11537        wrap,
11538        contains,
11539        j,
11540        i = 0,
11541        l = elems.length,
11542        fragment = context.createDocumentFragment(),
11543        nodes = [];
11544      for (; i < l; i++) {
11545        elem = elems[i];
11546        if (elem || elem === 0) {
11547          // Add nodes directly
11548          if (jQuery.type(elem) === "object") {
11549            // Support: QtWebKit
11550            // jQuery.merge because core_push.apply(_, arraylike) throws
11551            jQuery.merge(nodes, elem.nodeType ? [elem] : elem);
11552
11553            // Convert non-html into a text node
11554          } else if (!rhtml.test(elem)) {
11555            nodes.push(context.createTextNode(elem));
11556
11557            // Convert html into DOM nodes
11558          } else {
11559            tmp = tmp || fragment.appendChild(context.createElement("div"));
11560
11561            // Deserialize a standard representation
11562            tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase();
11563            wrap = wrapMap[tag] || wrapMap._default;
11564            tmp.innerHTML = wrap[1] + elem.replace(rxhtmlTag, "<$1></$2>") + wrap[2];
11565
11566            // Descend through wrappers to the right content
11567            j = wrap[0];
11568            while (j--) {
11569              tmp = tmp.lastChild;
11570            }
11571
11572            // Support: QtWebKit
11573            // jQuery.merge because core_push.apply(_, arraylike) throws
11574            jQuery.merge(nodes, tmp.childNodes);
11575
11576            // Remember the top-level container
11577            tmp = fragment.firstChild;
11578
11579            // Fixes #12346
11580            // Support: Webkit, IE
11581            tmp.textContent = "";
11582          }
11583        }
11584      }
11585
11586      // Remove wrapper from fragment
11587      fragment.textContent = "";
11588      i = 0;
11589      while (elem = nodes[i++]) {
11590        // #4087 - If origin and destination elements are the same, and this is
11591        // that element, do not do anything
11592        if (selection && jQuery.inArray(elem, selection) !== -1) {
11593          continue;
11594        }
11595        contains = jQuery.contains(elem.ownerDocument, elem);
11596
11597        // Append to fragment
11598        tmp = getAll(fragment.appendChild(elem), "script");
11599
11600        // Preserve script evaluation history
11601        if (contains) {
11602          setGlobalEval(tmp);
11603        }
11604
11605        // Capture executables
11606        if (scripts) {
11607          j = 0;
11608          while (elem = tmp[j++]) {
11609            if (rscriptType.test(elem.type || "")) {
11610              scripts.push(elem);
11611            }
11612          }
11613        }
11614      }
11615      return fragment;
11616    },
11617    cleanData: function (elems) {
11618      var data,
11619        elem,
11620        events,
11621        type,
11622        key,
11623        j,
11624        special = jQuery.event.special,
11625        i = 0;
11626      for (; (elem = elems[i]) !== undefined; i++) {
11627        if (Data.accepts(elem)) {
11628          key = elem[data_priv.expando];
11629          if (key && (data = data_priv.cache[key])) {
11630            events = Object.keys(data.events || {});
11631            if (events.length) {
11632              for (j = 0; (type = events[j]) !== undefined; j++) {
11633                if (special[type]) {
11634                  jQuery.event.remove(elem, type);
11635
11636                  // This is a shortcut to avoid jQuery.event.remove's overhead
11637                } else {
11638                  jQuery.removeEvent(elem, type, data.handle);
11639                }
11640              }
11641            }
11642            if (data_priv.cache[key]) {
11643              // Discard any remaining `private` data
11644              delete data_priv.cache[key];
11645            }
11646          }
11647        }
11648        // Discard any remaining `user` data
11649        delete data_user.cache[elem[data_user.expando]];
11650      }
11651    },
11652    _evalUrl: function (url) {
11653      return jQuery.ajax({
11654        url: url,
11655        type: "GET",
11656        dataType: "script",
11657        async: false,
11658        global: false,
11659        "throws": true
11660      });
11661    }
11662  });
11663
11664  // Support: 1.x compatibility
11665  // Manipulating tables requires a tbody
11666  function manipulationTarget(elem, content) {
11667    return jQuery.nodeName(elem, "table") && jQuery.nodeName(content.nodeType === 1 ? content : content.firstChild, "tr") ? elem.getElementsByTagName("tbody")[0] || elem.appendChild(elem.ownerDocument.createElement("tbody")) : elem;
11668  }
11669
11670  // Replace/restore the type attribute of script elements for safe DOM manipulation
11671  function disableScript(elem) {
11672    elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
11673    return elem;
11674  }
11675  function restoreScript(elem) {
11676    var match = rscriptTypeMasked.exec(elem.type);
11677    if (match) {
11678      elem.type = match[1];
11679    } else {
11680      elem.removeAttribute("type");
11681    }
11682    return elem;
11683  }
11684
11685  // Mark scripts as having already been evaluated
11686  function setGlobalEval(elems, refElements) {
11687    var l = elems.length,
11688      i = 0;
11689    for (; i < l; i++) {
11690      data_priv.set(elems[i], "globalEval", !refElements || data_priv.get(refElements[i], "globalEval"));
11691    }
11692  }
11693  function cloneCopyEvent(src, dest) {
11694    var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
11695    if (dest.nodeType !== 1) {
11696      return;
11697    }
11698
11699    // 1. Copy private data: events, handlers, etc.
11700    if (data_priv.hasData(src)) {
11701      pdataOld = data_priv.access(src);
11702      pdataCur = data_priv.set(dest, pdataOld);
11703      events = pdataOld.events;
11704      if (events) {
11705        delete pdataCur.handle;
11706        pdataCur.events = {};
11707        for (type in events) {
11708          for (i = 0, l = events[type].length; i < l; i++) {
11709            jQuery.event.add(dest, type, events[type][i]);
11710          }
11711        }
11712      }
11713    }
11714
11715    // 2. Copy user data
11716    if (data_user.hasData(src)) {
11717      udataOld = data_user.access(src);
11718      udataCur = jQuery.extend({}, udataOld);
11719      data_user.set(dest, udataCur);
11720    }
11721  }
11722  function getAll(context, tag) {
11723    var ret = context.getElementsByTagName ? context.getElementsByTagName(tag || "*") : context.querySelectorAll ? context.querySelectorAll(tag || "*") : [];
11724    return tag === undefined || tag && jQuery.nodeName(context, tag) ? jQuery.merge([context], ret) : ret;
11725  }
11726
11727  // Support: IE >= 9
11728  function fixInput(src, dest) {
11729    var nodeName = dest.nodeName.toLowerCase();
11730
11731    // Fails to persist the checked state of a cloned checkbox or radio button.
11732    if (nodeName === "input" && manipulation_rcheckableType.test(src.type)) {
11733      dest.checked = src.checked;
11734
11735      // Fails to return the selected option to the default selected state when cloning options
11736    } else if (nodeName === "input" || nodeName === "textarea") {
11737      dest.defaultValue = src.defaultValue;
11738    }
11739  }
11740  jQuery.fn.extend({
11741    wrapAll: function (html) {
11742      var wrap;
11743      if (jQuery.isFunction(html)) {
11744        return this.each(function (i) {
11745          jQuery(this).wrapAll(html.call(this, i));
11746        });
11747      }
11748      if (this[0]) {
11749        // The elements to wrap the target around
11750        wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true);
11751        if (this[0].parentNode) {
11752          wrap.insertBefore(this[0]);
11753        }
11754        wrap.map(function () {
11755          var elem = this;
11756          while (elem.firstElementChild) {
11757            elem = elem.firstElementChild;
11758          }
11759          return elem;
11760        }).append(this);
11761      }
11762      return this;
11763    },
11764    wrapInner: function (html) {
11765      if (jQuery.isFunction(html)) {
11766        return this.each(function (i) {
11767          jQuery(this).wrapInner(html.call(this, i));
11768        });
11769      }
11770      return this.each(function () {
11771        var self = jQuery(this),
11772          contents = self.contents();
11773        if (contents.length) {
11774          contents.wrapAll(html);
11775        } else {
11776          self.append(html);
11777        }
11778      });
11779    },
11780    wrap: function (html) {
11781      var isFunction = jQuery.isFunction(html);
11782      return this.each(function (i) {
11783        jQuery(this).wrapAll(isFunction ? html.call(this, i) : html);
11784      });
11785    },
11786    unwrap: function () {
11787      return this.parent().each(function () {
11788        if (!jQuery.nodeName(this, "body")) {
11789          jQuery(this).replaceWith(this.childNodes);
11790        }
11791      }).end();
11792    }
11793  });
11794  var curCSS,
11795    iframe,
11796    // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
11797    // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
11798    rdisplayswap = /^(none|table(?!-c[ea]).+)/,
11799    rmargin = /^margin/,
11800    rnumsplit = new RegExp("^(" + core_pnum + ")(.*)$", "i"),
11801    rnumnonpx = new RegExp("^(" + core_pnum + ")(?!px)[a-z%]+$", "i"),
11802    rrelNum = new RegExp("^([+-])=(" + core_pnum + ")", "i"),
11803    elemdisplay = {
11804      BODY: "block"
11805    },
11806    cssShow = {
11807      position: "absolute",
11808      visibility: "hidden",
11809      display: "block"
11810    },
11811    cssNormalTransform = {
11812      letterSpacing: 0,
11813      fontWeight: 400
11814    },
11815    cssExpand = ["Top", "Right", "Bottom", "Left"],
11816    cssPrefixes = ["Webkit", "O", "Moz", "ms"];
11817
11818  // return a css property mapped to a potentially vendor prefixed property
11819  function vendorPropName(style, name) {
11820    // shortcut for names that are not vendor prefixed
11821    if (name in style) {
11822      return name;
11823    }
11824
11825    // check for vendor prefixed names
11826    var capName = name.charAt(0).toUpperCase() + name.slice(1),
11827      origName = name,
11828      i = cssPrefixes.length;
11829    while (i--) {
11830      name = cssPrefixes[i] + capName;
11831      if (name in style) {
11832        return name;
11833      }
11834    }
11835    return origName;
11836  }
11837  function isHidden(elem, el) {
11838    // isHidden might be called from jQuery#filter function;
11839    // in that case, element will be second argument
11840    elem = el || elem;
11841    return jQuery.css(elem, "display") === "none" || !jQuery.contains(elem.ownerDocument, elem);
11842  }
11843
11844  // NOTE: we've included the "window" in window.getComputedStyle
11845  // because jsdom on node.js will break without it.
11846  function getStyles(elem) {
11847    return window.getComputedStyle(elem, null);
11848  }
11849  function showHide(elements, show) {
11850    var display,
11851      elem,
11852      hidden,
11853      values = [],
11854      index = 0,
11855      length = elements.length;
11856    for (; index < length; index++) {
11857      elem = elements[index];
11858      if (!elem.style) {
11859        continue;
11860      }
11861      values[index] = data_priv.get(elem, "olddisplay");
11862      display = elem.style.display;
11863      if (show) {
11864        // Reset the inline display of this element to learn if it is
11865        // being hidden by cascaded rules or not
11866        if (!values[index] && display === "none") {
11867          elem.style.display = "";
11868        }
11869
11870        // Set elements which have been overridden with display: none
11871        // in a stylesheet to whatever the default browser style is
11872        // for such an element
11873        if (elem.style.display === "" && isHidden(elem)) {
11874          values[index] = data_priv.access(elem, "olddisplay", css_defaultDisplay(elem.nodeName));
11875        }
11876      } else {
11877        if (!values[index]) {
11878          hidden = isHidden(elem);
11879          if (display && display !== "none" || !hidden) {
11880            data_priv.set(elem, "olddisplay", hidden ? display : jQuery.css(elem, "display"));
11881          }
11882        }
11883      }
11884    }
11885
11886    // Set the display of most of the elements in a second loop
11887    // to avoid the constant reflow
11888    for (index = 0; index < length; index++) {
11889      elem = elements[index];
11890      if (!elem.style) {
11891        continue;
11892      }
11893      if (!show || elem.style.display === "none" || elem.style.display === "") {
11894        elem.style.display = show ? values[index] || "" : "none";
11895      }
11896    }
11897    return elements;
11898  }
11899  jQuery.fn.extend({
11900    css: function (name, value) {
11901      return jQuery.access(this, function (elem, name, value) {
11902        var styles,
11903          len,
11904          map = {},
11905          i = 0;
11906        if (jQuery.isArray(name)) {
11907          styles = getStyles(elem);
11908          len = name.length;
11909          for (; i < len; i++) {
11910            map[name[i]] = jQuery.css(elem, name[i], false, styles);
11911          }
11912          return map;
11913        }
11914        return value !== undefined ? jQuery.style(elem, name, value) : jQuery.css(elem, name);
11915      }, name, value, arguments.length > 1);
11916    },
11917    show: function () {
11918      return showHide(this, true);
11919    },
11920    hide: function () {
11921      return showHide(this);
11922    },
11923    toggle: function (state) {
11924      if (typeof state === "boolean") {
11925        return state ? this.show() : this.hide();
11926      }
11927      return this.each(function () {
11928        if (isHidden(this)) {
11929          jQuery(this).show();
11930        } else {
11931          jQuery(this).hide();
11932        }
11933      });
11934    }
11935  });
11936  jQuery.extend({
11937    // Add in style property hooks for overriding the default
11938    // behavior of getting and setting a style property
11939    cssHooks: {
11940      opacity: {
11941        get: function (elem, computed) {
11942          if (computed) {
11943            // We should always get a number back from opacity
11944            var ret = curCSS(elem, "opacity");
11945            return ret === "" ? "1" : ret;
11946          }
11947        }
11948      }
11949    },
11950    // Don't automatically add "px" to these possibly-unitless properties
11951    cssNumber: {
11952      "columnCount": true,
11953      "fillOpacity": true,
11954      "fontWeight": true,
11955      "lineHeight": true,
11956      "opacity": true,
11957      "order": true,
11958      "orphans": true,
11959      "widows": true,
11960      "zIndex": true,
11961      "zoom": true
11962    },
11963    // Add in properties whose names you wish to fix before
11964    // setting or getting the value
11965    cssProps: {
11966      // normalize float css property
11967      "float": "cssFloat"
11968    },
11969    // Get and set the style property on a DOM Node
11970    style: function (elem, name, value, extra) {
11971      // Don't set styles on text and comment nodes
11972      if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {
11973        return;
11974      }
11975
11976      // Make sure that we're working with the right name
11977      var ret,
11978        type,
11979        hooks,
11980        origName = jQuery.camelCase(name),
11981        style = elem.style;
11982      name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(style, origName));
11983
11984      // gets hook for the prefixed version
11985      // followed by the unprefixed version
11986      hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
11987
11988      // Check if we're setting a value
11989      if (value !== undefined) {
11990        type = typeof value;
11991
11992        // convert relative number strings (+= or -=) to relative numbers. #7345
11993        if (type === "string" && (ret = rrelNum.exec(value))) {
11994          value = (ret[1] + 1) * ret[2] + parseFloat(jQuery.css(elem, name));
11995          // Fixes bug #9237
11996          type = "number";
11997        }
11998
11999        // Make sure that NaN and null values aren't set. See: #7116
12000        if (value == null || type === "number" && isNaN(value)) {
12001          return;
12002        }
12003
12004        // If a number was passed in, add 'px' to the (except for certain CSS properties)
12005        if (type === "number" && !jQuery.cssNumber[origName]) {
12006          value += "px";
12007        }
12008
12009        // Fixes #8908, it can be done more correctly by specifying setters in cssHooks,
12010        // but it would mean to define eight (for every problematic property) identical functions
12011        if (!jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0) {
12012          style[name] = "inherit";
12013        }
12014
12015        // If a hook was provided, use that value, otherwise just set the specified value
12016        if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) {
12017          style[name] = value;
12018        }
12019      } else {
12020        // If a hook was provided get the non-computed value from there
12021        if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) {
12022          return ret;
12023        }
12024
12025        // Otherwise just get the value from the style object
12026        return style[name];
12027      }
12028    },
12029    css: function (elem, name, extra, styles) {
12030      var val,
12031        num,
12032        hooks,
12033        origName = jQuery.camelCase(name);
12034
12035      // Make sure that we're working with the right name
12036      name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(elem.style, origName));
12037
12038      // gets hook for the prefixed version
12039      // followed by the unprefixed version
12040      hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];
12041
12042      // If a hook was provided get the computed value from there
12043      if (hooks && "get" in hooks) {
12044        val = hooks.get(elem, true, extra);
12045      }
12046
12047      // Otherwise, if a way to get the computed value exists, use that
12048      if (val === undefined) {
12049        val = curCSS(elem, name, styles);
12050      }
12051
12052      //convert "normal" to computed value
12053      if (val === "normal" && name in cssNormalTransform) {
12054        val = cssNormalTransform[name];
12055      }
12056
12057      // Return, converting to number if forced or a qualifier was provided and val looks numeric
12058      if (extra === "" || extra) {
12059        num = parseFloat(val);
12060        return extra === true || jQuery.isNumeric(num) ? num || 0 : val;
12061      }
12062      return val;
12063    }
12064  });
12065  curCSS = function (elem, name, _computed) {
12066    var width,
12067      minWidth,
12068      maxWidth,
12069      computed = _computed || getStyles(elem),
12070      // Support: IE9
12071      // getPropertyValue is only needed for .css('filter') in IE9, see #12537
12072      ret = computed ? computed.getPropertyValue(name) || computed[name] : undefined,
12073      style = elem.style;
12074    if (computed) {
12075      if (ret === "" && !jQuery.contains(elem.ownerDocument, elem)) {
12076        ret = jQuery.style(elem, name);
12077      }
12078
12079      // Support: Safari 5.1
12080      // A tribute to the "awesome hack by Dean Edwards"
12081      // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
12082      // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
12083      if (rnumnonpx.test(ret) && rmargin.test(name)) {
12084        // Remember the original values
12085        width = style.width;
12086        minWidth = style.minWidth;
12087        maxWidth = style.maxWidth;
12088
12089        // Put in the new values to get a computed value out
12090        style.minWidth = style.maxWidth = style.width = ret;
12091        ret = computed.width;
12092
12093        // Revert the changed values
12094        style.width = width;
12095        style.minWidth = minWidth;
12096        style.maxWidth = maxWidth;
12097      }
12098    }
12099    return ret;
12100  };
12101  function setPositiveNumber(elem, value, subtract) {
12102    var matches = rnumsplit.exec(value);
12103    return matches ?
12104    // Guard against undefined "subtract", e.g., when used as in cssHooks
12105    Math.max(0, matches[1] - (subtract || 0)) + (matches[2] || "px") : value;
12106  }
12107  function augmentWidthOrHeight(elem, name, extra, isBorderBox, styles) {
12108    var i = extra === (isBorderBox ? "border" : "content") ?
12109      // If we already have the right measurement, avoid augmentation
12110      4 :
12111      // Otherwise initialize for horizontal or vertical properties
12112      name === "width" ? 1 : 0,
12113      val = 0;
12114    for (; i < 4; i += 2) {
12115      // both box models exclude margin, so add it if we want it
12116      if (extra === "margin") {
12117        val += jQuery.css(elem, extra + cssExpand[i], true, styles);
12118      }
12119      if (isBorderBox) {
12120        // border-box includes padding, so remove it if we want content
12121        if (extra === "content") {
12122          val -= jQuery.css(elem, "padding" + cssExpand[i], true, styles);
12123        }
12124
12125        // at this point, extra isn't border nor margin, so remove border
12126        if (extra !== "margin") {
12127          val -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
12128        }
12129      } else {
12130        // at this point, extra isn't content, so add padding
12131        val += jQuery.css(elem, "padding" + cssExpand[i], true, styles);
12132
12133        // at this point, extra isn't content nor padding, so add border
12134        if (extra !== "padding") {
12135          val += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
12136        }
12137      }
12138    }
12139    return val;
12140  }
12141  function getWidthOrHeight(elem, name, extra) {
12142    // Start with offset property, which is equivalent to the border-box value
12143    var valueIsBorderBox = true,
12144      val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
12145      styles = getStyles(elem),
12146      isBorderBox = jQuery.support.boxSizing && jQuery.css(elem, "boxSizing", false, styles) === "border-box";
12147
12148    // some non-html elements return undefined for offsetWidth, so check for null/undefined
12149    // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
12150    // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
12151    if (val <= 0 || val == null) {
12152      // Fall back to computed then uncomputed css if necessary
12153      val = curCSS(elem, name, styles);
12154      if (val < 0 || val == null) {
12155        val = elem.style[name];
12156      }
12157
12158      // Computed unit is not pixels. Stop here and return.
12159      if (rnumnonpx.test(val)) {
12160        return val;
12161      }
12162
12163      // we need the check for style in case a browser which returns unreliable values
12164      // for getComputedStyle silently falls back to the reliable elem.style
12165      valueIsBorderBox = isBorderBox && (jQuery.support.boxSizingReliable || val === elem.style[name]);
12166
12167      // Normalize "", auto, and prepare for extra
12168      val = parseFloat(val) || 0;
12169    }
12170
12171    // use the active box-sizing model to add/subtract irrelevant styles
12172    return val + augmentWidthOrHeight(elem, name, extra || (isBorderBox ? "border" : "content"), valueIsBorderBox, styles) + "px";
12173  }
12174
12175  // Try to determine the default display value of an element
12176  function css_defaultDisplay(nodeName) {
12177    var doc = document,
12178      display = elemdisplay[nodeName];
12179    if (!display) {
12180      display = actualDisplay(nodeName, doc);
12181
12182      // If the simple way fails, read from inside an iframe
12183      if (display === "none" || !display) {
12184        // Use the already-created iframe if possible
12185        iframe = (iframe || jQuery("<iframe frameborder='0' width='0' height='0'/>").css("cssText", "display:block !important")).appendTo(doc.documentElement);
12186
12187        // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
12188        doc = (iframe[0].contentWindow || iframe[0].contentDocument).document;
12189        doc.write("<!doctype html><html><body>");
12190        doc.close();
12191        display = actualDisplay(nodeName, doc);
12192        iframe.detach();
12193      }
12194
12195      // Store the correct default display
12196      elemdisplay[nodeName] = display;
12197    }
12198    return display;
12199  }
12200
12201  // Called ONLY from within css_defaultDisplay
12202  function actualDisplay(name, doc) {
12203    var elem = jQuery(doc.createElement(name)).appendTo(doc.body),
12204      display = jQuery.css(elem[0], "display");
12205    elem.remove();
12206    return display;
12207  }
12208  jQuery.each(["height", "width"], function (i, name) {
12209    jQuery.cssHooks[name] = {
12210      get: function (elem, computed, extra) {
12211        if (computed) {
12212          // certain elements can have dimension info if we invisibly show them
12213          // however, it must have a current display style that would benefit from this
12214          return elem.offsetWidth === 0 && rdisplayswap.test(jQuery.css(elem, "display")) ? jQuery.swap(elem, cssShow, function () {
12215            return getWidthOrHeight(elem, name, extra);
12216          }) : getWidthOrHeight(elem, name, extra);
12217        }
12218      },
12219      set: function (elem, value, extra) {
12220        var styles = extra && getStyles(elem);
12221        return setPositiveNumber(elem, value, extra ? augmentWidthOrHeight(elem, name, extra, jQuery.support.boxSizing && jQuery.css(elem, "boxSizing", false, styles) === "border-box", styles) : 0);
12222      }
12223    };
12224  });
12225
12226  // These hooks cannot be added until DOM ready because the support test
12227  // for it is not run until after DOM ready
12228  jQuery(function () {
12229    // Support: Android 2.3
12230    if (!jQuery.support.reliableMarginRight) {
12231      jQuery.cssHooks.marginRight = {
12232        get: function (elem, computed) {
12233          if (computed) {
12234            // Support: Android 2.3
12235            // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
12236            // Work around by temporarily setting element display to inline-block
12237            return jQuery.swap(elem, {
12238              "display": "inline-block"
12239            }, curCSS, [elem, "marginRight"]);
12240          }
12241        }
12242      };
12243    }
12244
12245    // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
12246    // getComputedStyle returns percent when specified for top/left/bottom/right
12247    // rather than make the css module depend on the offset module, we just check for it here
12248    if (!jQuery.support.pixelPosition && jQuery.fn.position) {
12249      jQuery.each(["top", "left"], function (i, prop) {
12250        jQuery.cssHooks[prop] = {
12251          get: function (elem, computed) {
12252            if (computed) {
12253              computed = curCSS(elem, prop);
12254              // if curCSS returns percentage, fallback to offset
12255              return rnumnonpx.test(computed) ? jQuery(elem).position()[prop] + "px" : computed;
12256            }
12257          }
12258        };
12259      });
12260    }
12261  });
12262  if (jQuery.expr && jQuery.expr.filters) {
12263    jQuery.expr.filters.hidden = function (elem) {
12264      // Support: Opera <= 12.12
12265      // Opera reports offsetWidths and offsetHeights less than zero on some elements
12266      return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
12267    };
12268    jQuery.expr.filters.visible = function (elem) {
12269      return !jQuery.expr.filters.hidden(elem);
12270    };
12271  }
12272
12273  // These hooks are used by animate to expand properties
12274  jQuery.each({
12275    margin: "",
12276    padding: "",
12277    border: "Width"
12278  }, function (prefix, suffix) {
12279    jQuery.cssHooks[prefix + suffix] = {
12280      expand: function (value) {
12281        var i = 0,
12282          expanded = {},
12283          // assumes a single number if not a string
12284          parts = typeof value === "string" ? value.split(" ") : [value];
12285        for (; i < 4; i++) {
12286          expanded[prefix + cssExpand[i] + suffix] = parts[i] || parts[i - 2] || parts[0];
12287        }
12288        return expanded;
12289      }
12290    };
12291    if (!rmargin.test(prefix)) {
12292      jQuery.cssHooks[prefix + suffix].set = setPositiveNumber;
12293    }
12294  });
12295  var r20 = /%20/g,
12296    rbracket = /\[\]$/,
12297    rCRLF = /\r?\n/g,
12298    rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
12299    rsubmittable = /^(?:input|select|textarea|keygen)/i;
12300  jQuery.fn.extend({
12301    serialize: function () {
12302      return jQuery.param(this.serializeArray());
12303    },
12304    serializeArray: function () {
12305      return this.map(function () {
12306        // Can add propHook for "elements" to filter or add form elements
12307        var elements = jQuery.prop(this, "elements");
12308        return elements ? jQuery.makeArray(elements) : this;
12309      }).filter(function () {
12310        var type = this.type;
12311        // Use .is(":disabled") so that fieldset[disabled] works
12312        return this.name && !jQuery(this).is(":disabled") && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (this.checked || !manipulation_rcheckableType.test(type));
12313      }).map(function (i, elem) {
12314        var val = jQuery(this).val();
12315        return val == null ? null : jQuery.isArray(val) ? jQuery.map(val, function (val) {
12316          return {
12317            name: elem.name,
12318            value: val.replace(rCRLF, "\r\n")
12319          };
12320        }) : {
12321          name: elem.name,
12322          value: val.replace(rCRLF, "\r\n")
12323        };
12324      }).get();
12325    }
12326  });
12327
12328  //Serialize an array of form elements or a set of
12329  //key/values into a query string
12330  jQuery.param = function (a, traditional) {
12331    var prefix,
12332      s = [],
12333      add = function (key, value) {
12334        // If value is a function, invoke it and return its value
12335        value = jQuery.isFunction(value) ? value() : value == null ? "" : value;
12336        s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
12337      };
12338
12339    // Set traditional to true for jQuery <= 1.3.2 behavior.
12340    if (traditional === undefined) {
12341      traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
12342    }
12343
12344    // If an array was passed in, assume that it is an array of form elements.
12345    if (jQuery.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) {
12346      // Serialize the form elements
12347      jQuery.each(a, function () {
12348        add(this.name, this.value);
12349      });
12350    } else {
12351      // If traditional, encode the "old" way (the way 1.3.2 or older
12352      // did it), otherwise encode params recursively.
12353      for (prefix in a) {
12354        buildParams(prefix, a[prefix], traditional, add);
12355      }
12356    }
12357
12358    // Return the resulting serialization
12359    return s.join("&").replace(r20, "+");
12360  };
12361  function buildParams(prefix, obj, traditional, add) {
12362    var name;
12363    if (jQuery.isArray(obj)) {
12364      // Serialize array item.
12365      jQuery.each(obj, function (i, v) {
12366        if (traditional || rbracket.test(prefix)) {
12367          // Treat each array item as a scalar.
12368          add(prefix, v);
12369        } else {
12370          // Item is non-scalar (array or object), encode its numeric index.
12371          buildParams(prefix + "[" + (typeof v === "object" ? i : "") + "]", v, traditional, add);
12372        }
12373      });
12374    } else if (!traditional && jQuery.type(obj) === "object") {
12375      // Serialize object item.
12376      for (name in obj) {
12377        buildParams(prefix + "[" + name + "]", obj[name], traditional, add);
12378      }
12379    } else {
12380      // Serialize scalar item.
12381      add(prefix, obj);
12382    }
12383  }
12384  jQuery.each(("blur focus focusin focusout load resize scroll unload click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "change select submit keydown keypress keyup error contextmenu").split(" "), function (i, name) {
12385    // Handle event binding
12386    jQuery.fn[name] = function (data, fn) {
12387      return arguments.length > 0 ? this.on(name, null, data, fn) : this.trigger(name);
12388    };
12389  });
12390  jQuery.fn.extend({
12391    hover: function (fnOver, fnOut) {
12392      return this.mouseenter(fnOver).mouseleave(fnOut || fnOver);
12393    },
12394    bind: function (types, data, fn) {
12395      return this.on(types, null, data, fn);
12396    },
12397    unbind: function (types, fn) {
12398      return this.off(types, null, fn);
12399    },
12400    delegate: function (selector, types, data, fn) {
12401      return this.on(types, selector, data, fn);
12402    },
12403    undelegate: function (selector, types, fn) {
12404      // ( namespace ) or ( selector, types [, fn] )
12405      return arguments.length === 1 ? this.off(selector, "**") : this.off(types, selector || "**", fn);
12406    }
12407  });
12408  var
12409    // Document location
12410    ajaxLocParts,
12411    ajaxLocation,
12412    ajax_nonce = jQuery.now(),
12413    ajax_rquery = /\?/,
12414    rhash = /#.*$/,
12415    rts = /([?&])_=[^&]*/,
12416    rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
12417    // #7653, #8125, #8152: local protocol detection
12418    rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
12419    rnoContent = /^(?:GET|HEAD)$/,
12420    rprotocol = /^\/\//,
12421    rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
12422    // Keep a copy of the old load method
12423    _load = jQuery.fn.load,
12424    /* Prefilters
12425     * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
12426     * 2) These are called:
12427     *    - BEFORE asking for a transport
12428     *    - AFTER param serialization (s.data is a string if s.processData is true)
12429     * 3) key is the dataType
12430     * 4) the catchall symbol "*" can be used
12431     * 5) execution will start with transport dataType and THEN continue down to "*" if needed
12432     */
12433    prefilters = {},
12434    /* Transports bindings
12435     * 1) key is the dataType
12436     * 2) the catchall symbol "*" can be used
12437     * 3) selection will start with transport dataType and THEN go to "*" if needed
12438     */
12439    transports = {},
12440    // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
12441    allTypes = "*/".concat("*");
12442
12443  // #8138, IE may throw an exception when accessing
12444  // a field from window.location if document.domain has been set
12445  try {
12446    ajaxLocation = location.href;
12447  } catch (e) {
12448    // Use the href attribute of an A element
12449    // since IE will modify it given document.location
12450    ajaxLocation = document.createElement("a");
12451    ajaxLocation.href = "";
12452    ajaxLocation = ajaxLocation.href;
12453  }
12454
12455  // Segment location into parts
12456  ajaxLocParts = rurl.exec(ajaxLocation.toLowerCase()) || [];
12457
12458  // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
12459  function addToPrefiltersOrTransports(structure) {
12460    // dataTypeExpression is optional and defaults to "*"
12461    return function (dataTypeExpression, func) {
12462      if (typeof dataTypeExpression !== "string") {
12463        func = dataTypeExpression;
12464        dataTypeExpression = "*";
12465      }
12466      var dataType,
12467        i = 0,
12468        dataTypes = dataTypeExpression.toLowerCase().match(core_rnotwhite) || [];
12469      if (jQuery.isFunction(func)) {
12470        // For each dataType in the dataTypeExpression
12471        while (dataType = dataTypes[i++]) {
12472          // Prepend if requested
12473          if (dataType[0] === "+") {
12474            dataType = dataType.slice(1) || "*";
12475            (structure[dataType] = structure[dataType] || []).unshift(func);
12476
12477            // Otherwise append
12478          } else {
12479            (structure[dataType] = structure[dataType] || []).push(func);
12480          }
12481        }
12482      }
12483    };
12484  }
12485
12486  // Base inspection function for prefilters and transports
12487  function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) {
12488    var inspected = {},
12489      seekingTransport = structure === transports;
12490    function inspect(dataType) {
12491      var selected;
12492      inspected[dataType] = true;
12493      jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) {
12494        var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);
12495        if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) {
12496          options.dataTypes.unshift(dataTypeOrTransport);
12497          inspect(dataTypeOrTransport);
12498          return false;
12499        } else if (seekingTransport) {
12500          return !(selected = dataTypeOrTransport);
12501        }
12502      });
12503      return selected;
12504    }
12505    return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*");
12506  }
12507
12508  // A special extend for ajax options
12509  // that takes "flat" options (not to be deep extended)
12510  // Fixes #9887
12511  function ajaxExtend(target, src) {
12512    var key,
12513      deep,
12514      flatOptions = jQuery.ajaxSettings.flatOptions || {};
12515    for (key in src) {
12516      if (src[key] !== undefined) {
12517        (flatOptions[key] ? target : deep || (deep = {}))[key] = src[key];
12518      }
12519    }
12520    if (deep) {
12521      jQuery.extend(true, target, deep);
12522    }
12523    return target;
12524  }
12525  jQuery.fn.load = function (url, params, callback) {
12526    if (typeof url !== "string" && _load) {
12527      return _load.apply(this, arguments);
12528    }
12529    var selector,
12530      type,
12531      response,
12532      self = this,
12533      off = url.indexOf(" ");
12534    if (off >= 0) {
12535      selector = url.slice(off);
12536      url = url.slice(0, off);
12537    }
12538
12539    // If it's a function
12540    if (jQuery.isFunction(params)) {
12541      // We assume that it's the callback
12542      callback = params;
12543      params = undefined;
12544
12545      // Otherwise, build a param string
12546    } else if (params && typeof params === "object") {
12547      type = "POST";
12548    }
12549
12550    // If we have elements to modify, make the request
12551    if (self.length > 0) {
12552      jQuery.ajax({
12553        url: url,
12554        // if "type" variable is undefined, then "GET" method will be used
12555        type: type,
12556        dataType: "html",
12557        data: params
12558      }).done(function (responseText) {
12559        // Save response for use in complete callback
12560        response = arguments;
12561        self.html(selector ?
12562        // If a selector was specified, locate the right elements in a dummy div
12563        // Exclude scripts to avoid IE 'Permission Denied' errors
12564        jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) :
12565        // Otherwise use the full result
12566        responseText);
12567      }).complete(callback && function (jqXHR, status) {
12568        self.each(callback, response || [jqXHR.responseText, status, jqXHR]);
12569      });
12570    }
12571    return this;
12572  };
12573
12574  // Attach a bunch of functions for handling common AJAX events
12575  jQuery.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function (i, type) {
12576    jQuery.fn[type] = function (fn) {
12577      return this.on(type, fn);
12578    };
12579  });
12580  jQuery.extend({
12581    // Counter for holding the number of active queries
12582    active: 0,
12583    // Last-Modified header cache for next request
12584    lastModified: {},
12585    etag: {},
12586    ajaxSettings: {
12587      url: ajaxLocation,
12588      type: "GET",
12589      isLocal: rlocalProtocol.test(ajaxLocParts[1]),
12590      global: true,
12591      processData: true,
12592      async: true,
12593      contentType: "application/x-www-form-urlencoded; charset=UTF-8",
12594      /*
12595      timeout: 0,
12596      data: null,
12597      dataType: null,
12598      username: null,
12599      password: null,
12600      cache: null,
12601      throws: false,
12602      traditional: false,
12603      headers: {},
12604      */
12605
12606      accepts: {
12607        "*": allTypes,
12608        text: "text/plain",
12609        html: "text/html",
12610        xml: "application/xml, text/xml",
12611        json: "application/json, text/javascript"
12612      },
12613      contents: {
12614        xml: /xml/,
12615        html: /html/,
12616        json: /json/
12617      },
12618      responseFields: {
12619        xml: "responseXML",
12620        text: "responseText",
12621        json: "responseJSON"
12622      },
12623      // Data converters
12624      // Keys separate source (or catchall "*") and destination types with a single space
12625      converters: {
12626        // Convert anything to text
12627        "* text": String,
12628        // Text to html (true = no transformation)
12629        "text html": true,
12630        // Evaluate text as a json expression
12631        "text json": jQuery.parseJSON,
12632        // Parse text as xml
12633        "text xml": jQuery.parseXML
12634      },
12635      // For options that shouldn't be deep extended:
12636      // you can add your own custom options here if
12637      // and when you create one that shouldn't be
12638      // deep extended (see ajaxExtend)
12639      flatOptions: {
12640        url: true,
12641        context: true
12642      }
12643    },
12644    // Creates a full fledged settings object into target
12645    // with both ajaxSettings and settings fields.
12646    // If target is omitted, writes into ajaxSettings.
12647    ajaxSetup: function (target, settings) {
12648      return settings ?
12649      // Building a settings object
12650      ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) :
12651      // Extending ajaxSettings
12652      ajaxExtend(jQuery.ajaxSettings, target);
12653    },
12654    ajaxPrefilter: addToPrefiltersOrTransports(prefilters),
12655    ajaxTransport: addToPrefiltersOrTransports(transports),
12656    // Main method
12657    ajax: function (url, options) {
12658      // If url is an object, simulate pre-1.5 signature
12659      if (typeof url === "object") {
12660        options = url;
12661        url = undefined;
12662      }
12663
12664      // Force options to be an object
12665      options = options || {};
12666      var transport,
12667        // URL without anti-cache param
12668        cacheURL,
12669        // Response headers
12670        responseHeadersString,
12671        responseHeaders,
12672        // timeout handle
12673        timeoutTimer,
12674        // Cross-domain detection vars
12675        parts,
12676        // To know if global events are to be dispatched
12677        fireGlobals,
12678        // Loop variable
12679        i,
12680        // Create the final options object
12681        s = jQuery.ajaxSetup({}, options),
12682        // Callbacks context
12683        callbackContext = s.context || s,
12684        // Context for global events is callbackContext if it is a DOM node or jQuery collection
12685        globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ? jQuery(callbackContext) : jQuery.event,
12686        // Deferreds
12687        deferred = jQuery.Deferred(),
12688        completeDeferred = jQuery.Callbacks("once memory"),
12689        // Status-dependent callbacks
12690        statusCode = s.statusCode || {},
12691        // Headers (they are sent all at once)
12692        requestHeaders = {},
12693        requestHeadersNames = {},
12694        // The jqXHR state
12695        state = 0,
12696        // Default abort message
12697        strAbort = "canceled",
12698        // Fake xhr
12699        jqXHR = {
12700          readyState: 0,
12701          // Builds headers hashtable if needed
12702          getResponseHeader: function (key) {
12703            var match;
12704            if (state === 2) {
12705              if (!responseHeaders) {
12706                responseHeaders = {};
12707                while (match = rheaders.exec(responseHeadersString)) {
12708                  responseHeaders[match[1].toLowerCase()] = match[2];
12709                }
12710              }
12711              match = responseHeaders[key.toLowerCase()];
12712            }
12713            return match == null ? null : match;
12714          },
12715          // Raw string
12716          getAllResponseHeaders: function () {
12717            return state === 2 ? responseHeadersString : null;
12718          },
12719          // Caches the header
12720          setRequestHeader: function (name, value) {
12721            var lname = name.toLowerCase();
12722            if (!state) {
12723              name = requestHeadersNames[lname] = requestHeadersNames[lname] || name;
12724              requestHeaders[name] = value;
12725            }
12726            return this;
12727          },
12728          // Overrides response content-type header
12729          overrideMimeType: function (type) {
12730            if (!state) {
12731              s.mimeType = type;
12732            }
12733            return this;
12734          },
12735          // Status-dependent callbacks
12736          statusCode: function (map) {
12737            var code;
12738            if (map) {
12739              if (state < 2) {
12740                for (code in map) {
12741                  // Lazy-add the new callback in a way that preserves old ones
12742                  statusCode[code] = [statusCode[code], map[code]];
12743                }
12744              } else {
12745                // Execute the appropriate callbacks
12746                jqXHR.always(map[jqXHR.status]);
12747              }
12748            }
12749            return this;
12750          },
12751          // Cancel the request
12752          abort: function (statusText) {
12753            var finalText = statusText || strAbort;
12754            if (transport) {
12755              transport.abort(finalText);
12756            }
12757            done(0, finalText);
12758            return this;
12759          }
12760        };
12761
12762      // Attach deferreds
12763      deferred.promise(jqXHR).complete = completeDeferred.add;
12764      jqXHR.success = jqXHR.done;
12765      jqXHR.error = jqXHR.fail;
12766
12767      // Remove hash character (#7531: and string promotion)
12768      // Add protocol if not provided (prefilters might expect it)
12769      // Handle falsy url in the settings object (#10093: consistency with old signature)
12770      // We also use the url parameter if available
12771      s.url = ((url || s.url || ajaxLocation) + "").replace(rhash, "").replace(rprotocol, ajaxLocParts[1] + "//");
12772
12773      // Alias method option to type as per ticket #12004
12774      s.type = options.method || options.type || s.method || s.type;
12775
12776      // Extract dataTypes list
12777      s.dataTypes = jQuery.trim(s.dataType || "*").toLowerCase().match(core_rnotwhite) || [""];
12778
12779      // A cross-domain request is in order when we have a protocol:host:port mismatch
12780      if (s.crossDomain == null) {
12781        parts = rurl.exec(s.url.toLowerCase());
12782        s.crossDomain = !!(parts && (parts[1] !== ajaxLocParts[1] || parts[2] !== ajaxLocParts[2] || (parts[3] || (parts[1] === "http:" ? "80" : "443")) !== (ajaxLocParts[3] || (ajaxLocParts[1] === "http:" ? "80" : "443")))
12782);
12783      }
12784
12785      // Convert data if not already a string
12786      if (s.data && s.processData && typeof s.data !== "string") {
12787        s.data = jQuery.param(s.data, s.traditional);
12788      }
12789
12790      // Apply prefilters
12791      inspectPrefiltersOrTransports(prefilters, s, options, jqXHR);
12792
12793      // If request was aborted inside a prefilter, stop there
12794      if (state === 2) {
12795        return jqXHR;
12796      }
12797
12798      // We can fire global events as of now if asked to
12799      fireGlobals = s.global;
12800
12801      // Watch for a new set of requests
12802      if (fireGlobals && jQuery.active++ === 0) {
12803        jQuery.event.trigger("ajaxStart");
12804      }
12805
12806      // Uppercase the type
12807      s.type = s.type.toUpperCase();
12808
12809      // Determine if request has content
12810      s.hasContent = !rnoContent.test(s.type);
12811
12812      // Save the URL in case we're toying with the If-Modified-Since
12813      // and/or If-None-Match header later on
12814      cacheURL = s.url;
12815
12816      // More options handling for requests with no content
12817      if (!s.hasContent) {
12818        // If data is available, append data to url
12819        if (s.data) {
12820          cacheURL = s.url += (ajax_rquery.test(cacheURL) ? "&" : "?") + s.data;
12821          // #9682: remove data so that it's not used in an eventual retry
12822          delete s.data;
12823        }
12824
12825        // Add anti-cache in url if needed
12826        if (s.cache === false) {
12827          s.url = rts.test(cacheURL) ?
12828          // If there is already a '_' parameter, set its value
12829          cacheURL.replace(rts, "$1_=" + ajax_nonce++) :
12830          // Otherwise add one to the end
12831          cacheURL + (ajax_rquery.test(cacheURL) ? "&" : "?") + "_=" + ajax_nonce++;
12832        }
12833      }
12834
12835      // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
12836      if (s.ifModified) {
12837        if (jQuery.lastModified[cacheURL]) {
12838          jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]);
12839        }
12840        if (jQuery.etag[cacheURL]) {
12841          jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]);
12842        }
12843      }
12844
12845      // Set the correct header, if data is being sent
12846      if (s.data && s.hasContent && s.contentType !== false || options.contentType) {
12847        jqXHR.setRequestHeader("Content-Type", s.contentType);
12848      }
12849
12850      // Set the Accepts header for the server, depending on the dataType
12851      jqXHR.setRequestHeader("Accept", s.dataTypes[0] && s.accepts[s.dataTypes[0]] ? s.accepts[s.dataTypes[0]] + (s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "") : s.accepts["*"]);
12852
12853      // Check for headers option
12854      for (i in s.headers) {
12855        jqXHR.setRequestHeader(i, s.headers[i]);
12856      }
12857
12858      // Allow custom headers/mimetypes and early abort
12859      if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || state === 2)) {
12860        // Abort if not done already and return
12861        return jqXHR.abort();
12862      }
12863
12864      // aborting is no longer a cancellation
12865      strAbort = "abort";
12866
12867      // Install callbacks on deferreds
12868      for (i in {
12869        success: 1,
12870        error: 1,
12871        complete: 1
12872      }) {
12873        jqXHR[i](s[i]);
12874      }
12875
12876      // Get transport
12877      transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);
12878
12879      // If no transport, we auto-abort
12880      if (!transport) {
12881        done(-1, "No Transport");
12882      } else {
12883        jqXHR.readyState = 1;
12884
12885        // Send global event
12886        if (fireGlobals) {
12887          globalEventContext.trigger("ajaxSend", [jqXHR, s]);
12888        }
12889        // Timeout
12890        if (s.async && s.timeout > 0) {
12891          timeoutTimer = setTimeout(function () {
12892            jqXHR.abort("timeout");
12893          }, s.timeout);
12894        }
12895        try {
12896          state = 1;
12897          transport.send(requestHeaders, done);
12898        } catch (e) {
12899          // Propagate exception as error if not done
12900          if (state < 2) {
12901            done(-1, e);
12902            // Simply rethrow otherwise
12903          } else {
12904            throw e;
12905          }
12906        }
12907      }
12908
12909      // Callback for when everything is done
12910      function done(status, nativeStatusText, responses, headers) {
12911        var isSuccess,
12912          success,
12913          error,
12914          response,
12915          modified,
12916          statusText = nativeStatusText;
12917
12918        // Called once
12919        if (state === 2) {
12920          return;
12921        }
12922
12923        // State is "done" now
12924        state = 2;
12925
12926        // Clear timeout if it exists
12927        if (timeoutTimer) {
12928          clearTimeout(timeoutTimer);
12929        }
12930
12931        // Dereference transport for early garbage collection
12932        // (no matter how long the jqXHR object will be used)
12933        transport = undefined;
12934
12935        // Cache response headers
12936        responseHeadersString = headers || "";
12937
12938        // Set readyState
12939        jqXHR.readyState = status > 0 ? 4 : 0;
12940
12941        // Determine if successful
12942        isSuccess = status >= 200 && status < 300 || status === 304;
12943
12944        // Get response data
12945        if (responses) {
12946          response = ajaxHandleResponses(s, jqXHR, responses);
12947        }
12948
12949        // Convert no matter what (that way responseXXX fields are always set)
12950        response = ajaxConvert(s, response, jqXHR, isSuccess);
12951
12952        // If successful, handle type chaining
12953        if (isSuccess) {
12954          // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
12955          if (s.ifModified) {
12956            modified = jqXHR.getResponseHeader("Last-Modified");
12957            if (modified) {
12958              jQuery.lastModified[cacheURL] = modified;
12959            }
12960            modified = jqXHR.getResponseHeader("etag");
12961            if (modified) {
12962              jQuery.etag[cacheURL] = modified;
12963            }
12964          }
12965
12966          // if no content
12967          if (status === 204 || s.type === "HEAD") {
12968            statusText = "nocontent";
12969
12970            // if not modified
12971          } else if (status === 304) {
12972            statusText = "notmodified";
12973
12974            // If we have data, let's convert it
12975          } else {
12976            statusText = response.state;
12977            success = response.data;
12978            error = response.error;
12979            isSuccess = !error;
12980          }
12981        } else {
12982          // We extract error from statusText
12983          // then normalize statusText and status for non-aborts
12984          error = statusText;
12985          if (status || !statusText) {
12986            statusText = "error";
12987            if (status < 0) {
12988              status = 0;
12989            }
12990          }
12991        }
12992
12993        // Set data for the fake xhr object
12994        jqXHR.status = status;
12995        jqXHR.statusText = (nativeStatusText || statusText) + "";
12996
12997        // Success/Error
12998        if (isSuccess) {
12999          deferred.resolveWith(callbackContext, [success, statusText, jqXHR]);
13000        } else {
13001          deferred.rejectWith(callbackContext, [jqXHR, statusText, error]);
13002        }
13003
13004        // Status-dependent callbacks
13005        jqXHR.statusCode(statusCode);
13006        statusCode = undefined;
13007        if (fireGlobals) {
13008          globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError", [jqXHR, s, isSuccess ? success : error]);
13009        }
13010
13011        // Complete
13012        completeDeferred.fireWith(callbackContext, [jqXHR, statusText]);
13013        if (fireGlobals) {
13014          globalEventContext.trigger("ajaxComplete", [jqXHR, s]);
13015          // Handle the global AJAX counter
13016          if (! --jQuery.active) {
13017            jQuery.event.trigger("ajaxStop");
13018          }
13019        }
13020      }
13021      return jqXHR;
13022    },
13023    getJSON: function (url, data, callback) {
13024      return jQuery.get(url, data, callback, "json");
13025    },
13026    getScript: function (url, callback) {
13027      return jQuery.get(url, undefined, callback, "script");
13028    }
13029  });
13030  jQuery.each(["get", "post"], function (i, method) {
13031    jQuery[method] = function (url, data, callback, type) {
13032      // shift arguments if data argument was omitted
13033      if (jQuery.isFunction(data)) {
13034        type = type || callback;
13035        callback = data;
13036        data = undefined;
13037      }
13038      return jQuery.ajax({
13039        url: url,
13040        type: method,
13041        dataType: type,
13042        data: data,
13043        success: callback
13044      });
13045    };
13046  });
13047
13048  /* Handles responses to an ajax request:
13049   * - finds the right dataType (mediates between content-type and expected dataType)
13050   * - returns the corresponding response
13051   */
13052  function ajaxHandleResponses(s, jqXHR, responses) {
13053    var ct,
13054      type,
13055      finalDataType,
13056      firstDataType,
13057      contents = s.contents,
13058      dataTypes = s.dataTypes;
13059
13060    // Remove auto dataType and get content-type in the process
13061    while (dataTypes[0] === "*") {
13062      dataTypes.shift();
13063      if (ct === undefined) {
13064        ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
13065      }
13066    }
13067
13068    // Check if we're dealing with a known content-type
13069    if (ct) {
13070      for (type in contents) {
13071        if (contents[type] && contents[type].test(ct)) {
13072          dataTypes.unshift(type);
13073          break;
13074        }
13075      }
13076    }
13077
13078    // Check to see if we have a response for the expected dataType
13079    if (dataTypes[0] in responses) {
13080      finalDataType = dataTypes[0];
13081    } else {
vendor: 5,763 bytes, lines 13082-13272
13082      // Try convertible dataTypes
13083      for (type in responses) {
13084        if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) {
13085          finalDataType = type;
13086          break;
13087        }
13088        if (!firstDataType) {
13089          firstDataType = type;
13090        }
13091      }
13092      // Or just use first one
13093      finalDataType = finalDataType || firstDataType;
13094    }
13095
13096    // If we found a dataType
13097    // We add the dataType to the list if needed
13098    // and return the corresponding response
13099    if (finalDataType) {
13100      if (finalDataType !== dataTypes[0]) {
13101        dataTypes.unshift(finalDataType);
13102      }
13103      return responses[finalDataType];
13104    }
13105  }
13106
13107  /* Chain conversions given the request and the original response
13108   * Also sets the responseXXX fields on the jqXHR instance
13109   */
13110  function ajaxConvert(s, response, jqXHR, isSuccess) {
13111    var conv2,
13112      current,
13113      conv,
13114      tmp,
13115      prev,
13116      converters = {},
13117      // Work with a copy of dataTypes in case we need to modify it for conversion
13118      dataTypes = s.dataTypes.slice();
13119
13120    // Create converters map with lowercased keys
13121    if (dataTypes[1]) {
13122      for (conv in s.converters) {
13123        converters[conv.toLowerCase()] = s.converters[conv];
13124      }
13125    }
13126    current = dataTypes.shift();
13127
13128    // Convert to each sequential dataType
13129    while (current) {
13130      if (s.responseFields[current]) {
13131        jqXHR[s.responseFields[current]] = response;
13132      }
13133
13134      // Apply the dataFilter if provided
13135      if (!prev && isSuccess && s.dataFilter) {
13136        response = s.dataFilter(response, s.dataType);
13137      }
13138      prev = current;
13139      current = dataTypes.shift();
13140      if (current) {
13141        // There's only work to do if current dataType is non-auto
13142        if (current === "*") {
13143          current = prev;
13144
13145          // Convert response if prev dataType is non-auto and differs from current
13146        } else if (prev !== "*" && prev !== current) {
13147          // Seek a direct converter
13148          conv = converters[prev + " " + current] || converters["* " + current];
13149
13150          // If none found, seek a pair
13151          if (!conv) {
13152            for (conv2 in converters) {
13153              // If conv2 outputs current
13154              tmp = conv2.split(" ");
13155              if (tmp[1] === current) {
13156                // If prev can be converted to accepted input
13157                conv = converters[prev + " " + tmp[0]] || converters["* " + tmp[0]];
13158                if (conv) {
13159                  // Condense equivalence converters
13160                  if (conv === true) {
13161                    conv = converters[conv2];
13162
13163                    // Otherwise, insert the intermediate dataType
13164                  } else if (converters[conv2] !== true) {
13165                    current = tmp[0];
13166                    dataTypes.unshift(tmp[1]);
13167                  }
13168                  break;
13169                }
13170              }
13171            }
13172          }
13173
13174          // Apply converter (if not an equivalence)
13175          if (conv !== true) {
13176            // Unless errors are allowed to bubble, catch and return them
13177            if (conv && s["throws"]) {
13178              response = conv(response);
13179            } else {
13180              try {
13181                response = conv(response);
13182              } catch (e) {
13183                return {
13184                  state: "parsererror",
13185                  error: conv ? e : "No conversion from " + prev + " to " + current
13186                };
13187              }
13188            }
13189          }
13190        }
13191      }
13192    }
13193    return {
13194      state: "success",
13195      data: response
13196    };
13197  }
13198  // Install script dataType
13199  jQuery.ajaxSetup({
13200    accepts: {
13201      script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
13202    },
13203    contents: {
13204      script: /(?:java|ecma)script/
13205    },
13206    converters: {
13207      "text script": function (text) {
13208        jQuery.globalEval(text);
13209        return text;
13210      }
13211    }
13212  });
13213
13214  // Handle cache's special case and crossDomain
13215  jQuery.ajaxPrefilter("script", function (s) {
13216    if (s.cache === undefined) {
13217      s.cache = false;
13218    }
13219    if (s.crossDomain) {
13220      s.type = "GET";
13221    }
13222  });
13223
13224  // Bind script tag hack transport
13225  jQuery.ajaxTransport("script", function (s) {
13226    // This transport only deals with cross domain requests
13227    if (s.crossDomain) {
13228      var script, callback;
13229      return {
13230        send: function (_, complete) {
13231          script = jQuery("<script>").prop({
13232            async: true,
13233            charset: s.scriptCharset,
13234            src: s.url
13235          }).on("load error", callback = function (evt) {
13236            script.remove();
13237            callback = null;
13238            if (evt) {
13239              complete(evt.type === "error" ? 404 : 200, evt.type);
13240            }
13241          });
13242          document.head.appendChild(script[0]);
13243        },
13244        abort: function () {
13245          if (callback) {
13246            callback();
13247          }
13248        }
13249      };
13250    }
13251  });
13252  var oldCallbacks = [],
13253    rjsonp = /(=)\?(?=&|$)|\?\?/;
13254
13255  // Default jsonp settings
13256  jQuery.ajaxSetup({
13257    jsonp: "callback",
13258    jsonpCallback: function () {
13259      var callback = oldCallbacks.pop() || jQuery.expando + "_" + ajax_nonce++;
13260      this[callback] = true;
13261      return callback;
13262    }
13263  });
13264
13265  // Detect, normalize options and install callbacks for jsonp requests
13266  jQuery.ajaxPrefilter("json jsonp", function (s, originalSettings, jqXHR) {
13267    var callbackName,
13268      overwritten,
13269      responseContainer,
13270      jsonProp = s.jsonp !== false && (rjsonp.test(s.url) ? "url" : typeof s.data === "string" && !(s.contentType || "").indexOf("application/x-www-form-urlencoded") && rjsonp.test(s.data) && "data");
13271
13272    // Handle iff the expected data type is "jsonp" or we have a parameter to set
13273    if (jsonProp || s.dataTypes[0] === "jsonp") {
13274      // Get callback name, remembering preexisting value associated with it
13275      callbackName = s.jsonpCallback = jQuery.isFunction(s.jsonpCallback) ? s.jsonpCallback() : s.jsonpCallback;
13276
13277      // Insert callback into url or form data
13278      if (jsonProp) {
13279        s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName);
13280      } else if (s.jsonp !== false) {
13281        s.url += (ajax_rquery.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName;
13282      }
13283
13284      // Use data converter to retrieve json after script execution
13285      s.converters["script json"] = function () {
13286        if (!responseContainer) {
13287          jQuery.error(callbackName + " was not called");
13288        }
13289        return responseContainer[0];
13290      };
13291
13292      // force json dataType
13293      s.dataTypes[0] = "json";
13294
13295      // Install callback
13296      overwritten = window[callbackName];
13297      window[callbackName] = function () {
13298        responseContainer = arguments;
13299      };
13300
13301      // Clean-up function (fires after converters)
13302      jqXHR.always(function () {
13303        // Restore preexisting value
13304        window[callbackName] = overwritten;
13305
13306        // Save back as free
13307        if (s[callbackName]) {
13308          // make sure that re-using the options doesn't screw things around
13309          s.jsonpCallback = originalSettings.jsonpCallback;
13310
13311          // save the callback name for future use
13312          oldCallbacks.push(callbackName);
13313        }
13314
13315        // Call if it was a function and we have a response
13316        if (responseContainer && jQuery.isFunction(overwritten)) {
13317          overwritten(responseContainer[0]);
13318        }
13319        responseContainer = overwritten = undefined;
13320      });
13321
13322      // Delegate to script
13323      return "script";
13324    }
13325  });
13326  jQuery.ajaxSettings.xhr = function () {
13327    try {
13328      return new XMLHttpRequest();
13329    } catch (e) {}
13330  };
13331  var xhrSupported = jQuery.ajaxSettings.xhr(),
13332    xhrSuccessStatus = {
13333      // file protocol always yields status code 0, assume 200
13334      0: 200,
13335      // Support: IE9
13336      // #1450: sometimes IE returns 1223 when it should be 204
13337      1223: 204
13338    },
13339    // Support: IE9
13340    // We need to keep track of outbound xhr and abort them manually
13341    // because IE is not smart enough to do it all by itself
13342    xhrId = 0,
13343    xhrCallbacks = {};
13344  if (window.ActiveXObject) {
13345    jQuery(window).on("unload", function () {
13346      for (var key in xhrCallbacks) {
13347        xhrCallbacks[key]();
13348      }
13349      xhrCallbacks = undefined;
13350    });
13351  }
13352  jQuery.support.cors = !!xhrSupported && "withCredentials" in xhrSupported;
13353  jQuery.support.ajax = xhrSupported = !!xhrSupported;
13354  jQuery.ajaxTransport(function (options) {
13355    var callback;
13356    // Cross domain only allowed if supported through XMLHttpRequest
13357    if (jQuery.support.cors || xhrSupported && !options.crossDomain) {
13358      return {
13359        send: function (headers, complete) {
13360          var i,
13361            id,
13362            xhr = options.xhr();
13363          xhr.open(options.type, options.url, options.async, options.username, options.password);
13364          // Apply custom fields if provided
13365          if (options.xhrFields) {
13366            for (i in options.xhrFields) {
13367              xhr[i] = options.xhrFields[i];
13368            }
13369          }
13370          // Override mime type if needed
13371          if (options.mimeType && xhr.overrideMimeType) {
13372            xhr.overrideMimeType(options.mimeType);
13373          }
13374          // X-Requested-With header
13375          // For cross-domain requests, seeing as conditions for a preflight are
13376          // akin to a jigsaw puzzle, we simply never set it to be sure.
13377          // (it can always be set on a per-request basis or even using ajaxSetup)
13378          // For same-domain requests, won't change header if already provided.
13379          if (!options.crossDomain && !headers["X-Requested-With"]) {
13380            headers["X-Requested-With"] = "XMLHttpRequest";
13381          }
13382          // Set headers
13383          for (i in headers) {
13384            xhr.setRequestHeader(i, headers[i]);
13385          }
13386          // Callback
13387          callback = function (type) {
13388            return function () {
13389              if (callback) {
13390                delete xhrCallbacks[id];
13391                callback = xhr.onload = xhr.onerror = null;
13392                if (type === "abort") {
13393                  xhr.abort();
13394                } else if (type === "error") {
13395                  complete(
13396                  // file protocol always yields status 0, assume 404
13397                  xhr.status || 404, xhr.statusText);
13398                } else {
13399                  complete(xhrSuccessStatus[xhr.status] || xhr.status, xhr.statusText,
13400                  // Support: IE9
13401                  // #11426: When requesting binary data, IE9 will throw an exception
13402                  // on any attempt to access responseText
13403                  typeof xhr.responseText === "string" ? {
13404                    text: xhr.responseText
13405                  } : undefined, xhr.getAllResponseHeaders());
13406                }
13407              }
13408            };
13409          };
13410          // Listen to events
13411          xhr.onload = callback();
13412          xhr.onerror = callback("error");
13413          // Create the abort callback
13414          callback = xhrCallbacks[id = xhrId++] = callback("abort");
13415          // Do send the request
13416          // This may raise an exception which is actually
13417          // handled in jQuery.ajax (so no try/catch here)
13418          xhr.send(options.hasContent && options.data || null);
13419        },
13420        abort: function () {
13421          if (callback) {
13422            callback();
13423          }
13424        }
13425      };
13426    }
13427  });
13428  var fxNow,
13429    timerId,
13430    rfxtypes = /^(?:toggle|show|hide)$/,
13431    rfxnum = new RegExp("^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i"),
13432    rrun = /queueHooks$/,
13433    animationPrefilters = [defaultPrefilter],
13434    tweeners = {
13435      "*": [function (prop, value) {
13436        var tween = this.createTween(prop, value),
13437          target = tween.cur(),
13438          parts = rfxnum.exec(value),
13439          unit = parts && parts[3] || (jQuery.cssNumber[prop] ? "" : "px"),
13440          // Starting value computation is required for potential unit mismatches
13441          start = (jQuery.cssNumber[prop] || unit !== "px" && +target) && rfxnum.exec(jQuery.css(tween.elem, prop)),
13442          scale = 1,
13443          maxIterations = 20;
13444        if (start && start[3] !== unit) {
13445          // Trust units reported by jQuery.css
13446          unit = unit || start[3];
13447
13448          // Make sure we update the tween properties later on
13449          parts = parts || [];
13450
13451          // Iteratively approximate from a nonzero starting point
13452          start = +target || 1;
13453          do {
13454            // If previous iteration zeroed out, double until we get *something*
13455            // Use a string for doubling factor so we don't accidentally see scale as unchanged below
13456            scale = scale || ".5";
13457
13458            // Adjust and apply
13459            start = start / scale;
13460            jQuery.style(tween.elem, prop, start + unit);
13461
13462            // Update scale, tolerating zero or NaN from tween.cur()
13463            // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
13464          } while (scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations);
13465        }
13466
13467        // Update tween properties
13468        if (parts) {
13469          start = tween.start = +start || +target || 0;
13470          tween.unit = unit;
13471          // If a +=/-= token was provided, we're doing a relative animation
13472          tween.end = parts[1] ? start + (parts[1] + 1) * parts[2] : +parts[2];
13473        }
13474        return tween;
13475      }]
13476    };
13477
13478  // Animations created synchronously will run synchronously
13479  function createFxNow() {
13480    setTimeout(function () {
13481      fxNow = undefined;
13482    });
13483    return fxNow = jQuery.now();
13484  }
13485  function createTween(value, prop, animation) {
13486    var tween,
13487      collection = (tweeners[prop] || []).concat(tweeners["*"]),
13488      index = 0,
13489      length = collection.length;
13490    for (; index < length; index++) {
13491      if (tween = collection[index].call(animation, prop, value)) {
13492        // we're done with this property
13493        return tween;
13494      }
13495    }
13496  }
13497  function Animation(elem, properties, options) {
13498    var result,
13499      stopped,
13500      index = 0,
13501      length = animationPrefilters.length,
13502      deferred = jQuery.Deferred().always(function () {
13503        // don't match elem in the :animated selector
13504        delete tick.elem;
13505      }),
13506      tick = function () {
13507        if (stopped) {
13508          return false;
vendor: 3,025 bytes, lines 13509-13593
13509        }
13510        var currentTime = fxNow || createFxNow(),
13511          remaining = Math.max(0, animation.startTime + animation.duration - currentTime),
13512          // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
13513          temp = remaining / animation.duration || 0,
13514          percent = 1 - temp,
13515          index = 0,
13516          length = animation.tweens.length;
13517        for (; index < length; index++) {
13518          animation.tweens[index].run(percent);
13519        }
13520        deferred.notifyWith(elem, [animation, percent, remaining]);
13521        if (percent < 1 && length) {
13522          return remaining;
13523        } else {
13524          deferred.resolveWith(elem, [animation]);
13525          return false;
13526        }
13527      },
13528      animation = deferred.promise({
13529        elem: elem,
13530        props: jQuery.extend({}, properties),
13531        opts: jQuery.extend(true, {
13532          specialEasing: {}
13533        }, options),
13534        originalProperties: properties,
13535        originalOptions: options,
13536        startTime: fxNow || createFxNow(),
13537        duration: options.duration,
13538        tweens: [],
13539        createTween: function (prop, end) {
13540          var tween = jQuery.Tween(elem, animation.opts, prop, end, animation.opts.specialEasing[prop] || animation.opts.easing);
13541          animation.tweens.push(tween);
13542          return tween;
13543        },
13544        stop: function (gotoEnd) {
13545          var index = 0,
13546            // if we are going to the end, we want to run all the tweens
13547            // otherwise we skip this part
13548            length = gotoEnd ? animation.tweens.length : 0;
13549          if (stopped) {
13550            return this;
13551          }
13552          stopped = true;
13553          for (; index < length; index++) {
13554            animation.tweens[index].run(1);
13555          }
13556
13557          // resolve when we played the last frame
13558          // otherwise, reject
13559          if (gotoEnd) {
13560            deferred.resolveWith(elem, [animation, gotoEnd]);
13561          } else {
13562            deferred.rejectWith(elem, [animation, gotoEnd]);
13563          }
13564          return this;
13565        }
13566      }),
13567      props = animation.props;
13568    propFilter(props, animation.opts.specialEasing);
13569    for (; index < length; index++) {
13570      result = animationPrefilters[index].call(animation, elem, props, animation.opts);
13571      if (result) {
13572        return result;
13573      }
13574    }
13575    jQuery.map(props, createTween, animation);
13576    if (jQuery.isFunction(animation.opts.start)) {
13577      animation.opts.start.call(elem, animation);
13578    }
13579    jQuery.fx.timer(jQuery.extend(tick, {
13580      elem: elem,
13581      anim: animation,
13582      queue: animation.opts.queue
13583    }));
13584
13585    // attach callbacks from options
13586    return animation.progress(animation.opts.progress).done(animation.opts.done, animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always);
13587  }
13588  function propFilter(props, specialEasing) {
13589    var index, name, easing, value, hooks;
13590
13591    // camelCase, specialEasing and expand cssHook pass
13592    for (index in props) {
13593      name = jQuery.camelCase(index);
13594      easing = specialEasing[name];
13595      value = props[index];
13596      if (jQuery.isArray(value)) {
13597        easing = value[1];
13598        value = props[index] = value[0];
13599      }
13600      if (index !== name) {
13601        props[name] = value;
13602        delete props[index];
13603      }
13604      hooks = jQuery.cssHooks[name];
13605      if (hooks && "expand" in hooks) {
13606        value = hooks.expand(value);
13607        delete props[name];
13608
13609        // not quite $.extend, this wont overwrite keys already present.
13610        // also - reusing 'index' from above because we have the correct "name"
13611        for (index in value) {
13612          if (!(index in props)) {
13613            props[index] = value[index];
13614            specialEasing[index] = easing;
13615          }
13616        }
13617      } else {
13618        specialEasing[name] = easing;
13619      }
13620    }
13621  }
13622  jQuery.Animation = jQuery.extend(Animation, {
13623    tweener: function (props, callback) {
13624      if (jQuery.isFunction(props)) {
13625        callback = props;
13626        props = ["*"];
13627      } else {
13628        props = props.split(" ");
13629      }
13630      var prop,
13631        index = 0,
13632        length = props.length;
13633      for (; index < length; index++) {
13634        prop = props[index];
13635        tweeners[prop] = tweeners[prop] || [];
13636        tweeners[prop].unshift(callback);
13637      }
13638    },
13639    prefilter: function (callback, prepend) {
13640      if (prepend) {
13641        animationPrefilters.unshift(callback);
13642      } else {
13643        animationPrefilters.push(callback);
13644      }
13645    }
13646  });
13647  function defaultPrefilter(elem, props, opts) {
13648    /* jshint validthis: true */
13649    var prop,
13650      value,
13651      toggle,
13652      tween,
13653      hooks,
13654      oldfire,
13655      anim = this,
13656      orig = {},
13657      style = elem.style,
13658      hidden = elem.nodeType && isHidden(elem),
13659      dataShow = data_priv.get(elem, "fxshow");
13660
13661    // handle queue: false promises
13662    if (!opts.queue) {
13663      hooks = jQuery._queueHooks(elem, "fx");
13664      if (hooks.unqueued == null) {
13665        hooks.unqueued = 0;
13666        oldfire = hooks.empty.fire;
13667        hooks.empty.fire = function () {
13668          if (!hooks.unqueued) {
13669            oldfire();
13670          }
13671        };
13672      }
13673      hooks.unqueued++;
13674      anim.always(function () {
13675        // doing this makes sure that the complete handler will be called
13676        // before this completes
13677        anim.always(function () {
13678          hooks.unqueued--;
13679          if (!jQuery.queue(elem, "fx").length) {
13680            hooks.empty.fire();
13681          }
13682        });
13683      });
13684    }
13685
13686    // height/width overflow pass
13687    if (elem.nodeType === 1 && ("height" in props || "width" in props)) {
13688      // Make sure that nothing sneaks out
13689      // Record all 3 overflow attributes because IE9-10 do not
13690      // change the overflow attribute when overflowX and
13691      // overflowY are set to the same value
13692      opts.overflow = [style.overflow, style.overflowX, style.overflowY];
13693
13694      // Set display property to inline-block for height/width
13695      // animations on inline elements that are having width/height animated
13696      if (jQuery.css(elem, "display") === "inline" && jQuery.css(elem, "float") === "none") {
13697        style.display = "inline-block";
13698      }
13699    }
13700    if (opts.overflow) {
13701      style.overflow = "hidden";
13702      anim.always(function () {
13703        style.overflow = opts.overflow[0];
13704        style.overflowX = opts.overflow[1];
13705        style.overflowY = opts.overflow[2];
13706      });
13707    }
13708
13709    // show/hide pass
13710    for (prop in props) {
13711      value = props[prop];
13712      if (rfxtypes.exec(value)) {
13713        delete props[prop];
13714        toggle = toggle || value === "toggle";
13715        if (value === (hidden ? "hide" : "show")) {
13716          // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
13717          if (value === "show" && dataShow && dataShow[prop] !== undefined) {
13718            hidden = true;
13719          } else {
13720            continue;
13721          }
13722        }
13723        orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop);
13724      }
13725    }
13726    if (!jQuery.isEmptyObject(orig)) {
13727      if (dataShow) {
13728        if ("hidden" in dataShow) {
13729          hidden = dataShow.hidden;
13730        }
13731      } else {
13732        dataShow = data_priv.access(elem, "fxshow", {});
13733      }
13734
13735      // store state if its toggle - enables .stop().toggle() to "reverse"
13736      if (toggle) {
13737        dataShow.hidden = !hidden;
13738      }
13739      if (hidden) {
13740        jQuery(elem).show();
13741      } else {
13742        anim.done(function () {
13743          jQuery(elem).hide();
13744        });
13745      }
13746      anim.done(function () {
13747        var prop;
13748        data_priv.remove(elem, "fxshow");
13749        for (prop in orig) {
13750          jQuery.style(elem, prop, orig[prop]);
13751        }
13752      });
13753      for (prop in orig) {
13754        tween = createTween(hidden ? dataShow[prop] : 0, prop, anim);
13755        if (!(prop in dataShow)) {
13756          dataShow[prop] = tween.start;
13757          if (hidden) {
13758            tween.end = tween.start;
13759            tween.start = prop === "width" || prop === "height" ? 1 : 0;
13760          }
13761        }
13762      }
13763    }
13764  }
13765  function Tween(elem, options, prop, end, easing) {
13766    return new Tween.prototype.init(elem, options, prop, end, easing);
13767  }
13768  jQuery.Tween = Tween;
13769  Tween.prototype = {
13770    constructor: Tween,
13771    init: function (elem, options, prop, end, easing, unit) {
13772      this.elem = elem;
13773      this.prop = prop;
13774      this.easing = easing || "swing";
13775      this.options = options;
13776      this.start = this.now = this.cur();
13777      this.end = end;
13778      this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px");
13779    },
13780    cur: function () {
13781      var hooks = Tween.propHooks[this.prop];
13782      return hooks && hooks.get ? hooks.get(this) : Tween.propHooks._default.get(this);
13783    },
13784    run: function (percent) {
13785      var eased,
13786        hooks = Tween.propHooks[this.prop];
13787      if (this.options.duration) {
13788        this.pos = eased = jQuery.easing[this.easing](percent, this.options.duration * percent, 0, 1, this.options.duration);
13789      } else {
13790        this.pos = eased = percent;
13791      }
vendor: 4,389 bytes, lines 13792-13909
13792      this.now = (this.end - this.start) * eased + this.start;
13793      if (this.options.step) {
13794        this.options.step.call(this.elem, this.now, this);
13795      }
13796      if (hooks && hooks.set) {
13797        hooks.set(this);
13798      } else {
13799        Tween.propHooks._default.set(this);
13800      }
13801      return this;
13802    }
13803  };
13804  Tween.prototype.init.prototype = Tween.prototype;
13805  Tween.propHooks = {
13806    _default: {
13807      get: function (tween) {
13808        var result;
13809        if (tween.elem[tween.prop] != null && (!tween.elem.style || tween.elem.style[tween.prop] == null)) {
13810          return tween.elem[tween.prop];
13811        }
13812
13813        // passing an empty string as a 3rd parameter to .css will automatically
13814        // attempt a parseFloat and fallback to a string if the parse fails
13815        // so, simple values such as "10px" are parsed to Float.
13816        // complex values such as "rotate(1rad)" are returned as is.
13817        result = jQuery.css(tween.elem, tween.prop, "");
13818        // Empty strings, null, undefined and "auto" are converted to 0.
13819        return !result || result === "auto" ? 0 : result;
13820      },
13821      set: function (tween) {
13822        // use step hook for back compat - use cssHook if its there - use .style if its
13823        // available and use plain properties where available
13824        if (jQuery.fx.step[tween.prop]) {
13825          jQuery.fx.step[tween.prop](tween);
13826        } else if (tween.elem.style && (tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop])) {
13827          jQuery.style(tween.elem, tween.prop, tween.now + tween.unit);
13828        } else {
13829          tween.elem[tween.prop] = tween.now;
13830        }
13831      }
13832    }
13833  };
13834
13835  // Support: IE9
13836  // Panic based approach to setting things on disconnected nodes
13837
13838  Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
13839    set: function (tween) {
13840      if (tween.elem.nodeType && tween.elem.parentNode) {
13841        tween.elem[tween.prop] = tween.now;
13842      }
13843    }
13844  };
13845  jQuery.each(["toggle", "show", "hide"], function (i, name) {
13846    var cssFn = jQuery.fn[name];
13847    jQuery.fn[name] = function (speed, easing, callback) {
13848      return speed == null || typeof speed === "boolean" ? cssFn.apply(this, arguments) : this.animate(genFx(name, true), speed, easing, callback);
13849    };
13850  });
13851  jQuery.fn.extend({
13852    fadeTo: function (speed, to, easing, callback) {
13853      // show any hidden elements after setting opacity to 0
13854      return this.filter(isHidden).css("opacity", 0).show()
13855
13856      // animate to the value specified
13857      .end().animate({
13858        opacity: to
13859      }, speed, easing, callback);
13860    },
13861    animate: function (prop, speed, easing, callback) {
13862      var empty = jQuery.isEmptyObject(prop),
13863        optall = jQuery.speed(speed, easing, callback),
13864        doAnimation = function () {
13865          // Operate on a copy of prop so per-property easing won't be lost
13866          var anim = Animation(this, jQuery.extend({}, prop), optall);
13867
13868          // Empty animations, or finishing resolves immediately
13869          if (empty || data_priv.get(this, "finish")) {
13870            anim.stop(true);
13871          }
13872        };
13873      doAnimation.finish = doAnimation;
13874      return empty || optall.queue === false ? this.each(doAnimation) : this.queue(optall.queue, doAnimation);
13875    },
13876    stop: function (type, clearQueue, gotoEnd) {
13877      var stopQueue = function (hooks) {
13878        var stop = hooks.stop;
13879        delete hooks.stop;
13880        stop(gotoEnd);
13881      };
13882      if (typeof type !== "string") {
13883        gotoEnd = clearQueue;
13884        clearQueue = type;
13885        type = undefined;
13886      }
13887      if (clearQueue && type !== false) {
13888        this.queue(type || "fx", []);
13889      }
13890      return this.each(function () {
13891        var dequeue = true,
13892          index = type != null && type + "queueHooks",
13893          timers = jQuery.timers,
13894          data = data_priv.get(this);
13895        if (index) {
13896          if (data[index] && data[index].stop) {
13897            stopQueue(data[index]);
13898          }
13899        } else {
13900          for (index in data) {
13901            if (data[index] && data[index].stop && rrun.test(index)) {
13902              stopQueue(data[index]);
13903            }
13904          }
13905        }
13906        for (index = timers.length; index--;) {
13907          if (timers[index].elem === this && (type == null || timers[index].queue === type)) {
13908            timers[index].anim.stop(gotoEnd);
13909            dequeue = false;
13910            timers.splice(index, 1);
13911          }
13912        }
13913
13914        // start the next in the queue if the last step wasn't forced
13915        // timers currently will call their complete callbacks, which will dequeue
13916        // but only if they were gotoEnd
13917        if (dequeue || !gotoEnd) {
13918          jQuery.dequeue(this, type);
13919        }
13920      });
13921    },
13922    finish: function (type) {
13923      if (type !== false) {
13924        type = type || "fx";
13925      }
13926      return this.each(function () {
13927        var index,
13928          data = data_priv.get(this),
13929          queue = data[type + "queue"],
13930          hooks = data[type + "queueHooks"],
13931          timers = jQuery.timers,
13932          length = queue ? queue.length : 0;
13933
13934        // enable finishing flag on private data
13935        data.finish = true;
13936
13937        // empty the queue first
13938        jQuery.queue(this, type, []);
13939        if (hooks && hooks.stop) {
13940          hooks.stop.call(this, true);
13941        }
13942
13943        // look for any active animations, and finish them
13944        for (index = timers.length; index--;) {
13945          if (timers[index].elem === this && timers[index].queue === type) {
13946            timers[index].anim.stop(true);
13947            timers.splice(index, 1);
13948          }
13949        }
13950
13951        // look for any animations in the old queue and finish them
13952        for (index = 0; index < length; index++) {
13953          if (queue[index] && queue[index].finish) {
13954            queue[index].finish.call(this);
13955          }
13956        }
13957
13958        // turn off finishing flag
13959        delete data.finish;
13960      });
13961    }
13962  });
13963
13964  // Generate parameters to create a standard animation
13965  function genFx(type, includeWidth) {
13966    var which,
13967      attrs = {
13968        height: type
13969      },
13970      i = 0;
13971
13972    // if we include width, step value is 1 to do all cssExpand values,
13973    // if we don't include width, step value is 2 to skip over Left and Right
13974    includeWidth = includeWidth ? 1 : 0;
13975    for (; i < 4; i += 2 - includeWidth) {
13976      which = cssExpand[i];
13977      attrs["margin" + which] = attrs["padding" + which] = type;
13978    }
13979    if (includeWidth) {
13980      attrs.opacity = attrs.width = type;
13981    }
13982    return attrs;
13983  }
13984
13985  // Generate shortcuts for custom animations
13986  jQuery.each({
13987    slideDown: genFx("show"),
13988    slideUp: genFx("hide"),
13989    slideToggle: genFx("toggle"),
13990    fadeIn: {
13991      opacity: "show"
13992    },
13993    fadeOut: {
13994      opacity: "hide"
13995    },
13996    fadeToggle: {
13997      opacity: "toggle"
13998    }
13999  }, function (name, props) {
14000    jQuery.fn[name] = function (speed, easing, callback) {
14001      return this.animate(props, speed, easing, callback);
14002    };
14003  });
14004  jQuery.speed = function (speed, easing, fn) {
14005    var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : {
14006      complete: fn || !fn && easing || jQuery.isFunction(speed) && speed,
14007      duration: speed,
14008      easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
14009    };
14010    opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;
14011
14012    // normalize opt.queue - true/undefined/null -> "fx"
14013    if (opt.queue == null || opt.queue === true) {
14014      opt.queue = "fx";
14015    }
14016
14017    // Queueing
14018    opt.old = opt.complete;
14019    opt.complete = function () {
14020      if (jQuery.isFunction(opt.old)) {
14021        opt.old.call(this);
14022      }
14023      if (opt.queue) {
14024        jQuery.dequeue(this, opt.queue);
14025      }
14026    };
14027    return opt;
14028  };
14029  jQuery.easing = {
14030    linear: function (p) {
14031      return p;
14032    },
14033    swing: function (p) {
14034      return 0.5 - Math.cos(p * Math.PI) / 2;
14035    }
14036  };
14037  jQuery.timers = [];
14038  jQuery.fx = Tween.prototype.init;
14039  jQuery.fx.tick = function () {
14040    var timer,
14041      timers = jQuery.timers,
14042      i = 0;
14043    fxNow = jQuery.now();
14044    for (; i < timers.length; i++) {
14045      timer = timers[i];
14046      // Checks the timer has not already been removed
14047      if (!timer() && timers[i] === timer) {
14048        timers.splice(i--, 1);
14049      }
14050    }
14051    if (!timers.length) {
14052      jQuery.fx.stop();
14053    }
14054    fxNow = undefined;
14055  };
14056  jQuery.fx.timer = function (timer) {
14057    if (timer() && jQuery.timers.push(timer)) {
14058      jQuery.fx.start();
14059    }
14060  };
14061  jQuery.fx.interval = 13;
14062  jQuery.fx.start = function () {
14063    if (!timerId) {
14064      timerId = setInterval(jQuery.fx.tick, jQuery.fx.interval);
14065    }
14066  };
14067  jQuery.fx.stop = function () {
14068    clearInterval(timerId);
14069    timerId = null;
14070  };
14071  jQuery.fx.speeds = {
14072    slow: 600,
14073    fast: 200,
14074    // Default speed
14075    _default: 400
14076  };
14077
14078  // Back Compat <1.8 extension point
14079  jQuery.fx.step = {};
14080  if (jQuery.expr && jQuery.expr.filters) {
14081    jQuery.expr.filters.animated = function (elem) {
14082      return jQuery.grep(jQuery.timers, function (fn) {
14083        return elem === fn.elem;
14084      }).length;
14085    };
14086  }
14087  jQuery.fn.offset = function (options) {
14088    if (arguments.length) {
14089      return options === undefined ? this : this.each(function (i) {
14090        jQuery.offset.setOffset(this, options, i);
14091      });
14092    }
14093    var docElem,
14094      win,
14095      elem = this[0],
14096      box = {
14097        top: 0,
14098        left: 0
14099      },
14100      doc = elem && elem.ownerDocument;
14101    if (!doc) {
14102      return;
14103    }
14104    docElem = doc.documentElement;
14105
14106    // Make sure it's not a disconnected DOM node
14107    if (!jQuery.contains(docElem, elem)) {
14108      return box;
14109    }
14110
14111    // If we don't have gBCR, just use 0,0 rather than error
14112    // BlackBerry 5, iOS 3 (original iPhone)
14113    if (typeof elem.getBoundingClientRect !== core_strundefined) {
14114      box = elem.getBoundingClientRect();
14115    }
14116    win = getWindow(doc);
14117    return {
14118      top: box.top + win.pageYOffset - docElem.clientTop,
14119      left: box.left + win.pageXOffset - docElem.clientLeft
14120    };
14121  };
14122  jQuery.offset = {
14123    setOffset: function (elem, options, i) {
14124      var curPosition,
14125        curLeft,
14126        curCSSTop,
14127        curTop,
14128        curOffset,
14129        curCSSLeft,
14130        calculatePosition,
14131        position = jQuery.css(elem, "position"),
14132        curElem = jQuery(elem),
14133        props = {};
14134
14135      // Set position first, in-case top/left are set even on static elem
14136      if (position === "static") {
14137        elem.style.position = "relative";
14138      }
14139      curOffset = curElem.offset();
14140      curCSSTop = jQuery.css(elem, "top");
14141      curCSSLeft = jQuery.css(elem, "left");
14142      calculatePosition = (position === "absolute" || position === "fixed") && (curCSSTop + curCSSLeft).indexOf("auto") > -1;
14143
14144      // Need to be able to calculate position if either top or left is auto and position is either absolute or fixed
14145      if (calculatePosition) {
14146        curPosition = curElem.position();
14147        curTop = curPosition.top;
14148        curLeft = curPosition.left;
14149      } else {
14150        curTop = parseFloat(curCSSTop) || 0;
14151        curLeft = parseFloat(curCSSLeft) || 0;
14152      }
14153      if (jQuery.isFunction(options)) {
14154        options = options.call(elem, i, curOffset);
14155      }
14156      if (options.top != null) {
14157        props.top = options.top - curOffset.top + curTop;
14158      }
14159      if (options.left != null) {
14160        props.left = options.left - curOffset.left + curLeft;
14161      }
14162      if ("using" in options) {
14163        options.using.call(elem, props);
14164      } else {
14165        curElem.css(props);
14166      }
14167    }
14168  };
14169  jQuery.fn.extend({
14170    position: function () {
14171      if (!this[0]) {
14172        return;
14173      }
14174      var offsetParent,
14175        offset,
14176        elem = this[0],
14177        parentOffset = {
14178          top: 0,
14179          left: 0
14180        };
14181
14182      // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
14183      if (jQuery.css(elem, "position") === "fixed") {
14184        // We assume that getBoundingClientRect is available when computed position is fixed
14185        offset = elem.getBoundingClientRect();
14186      } else {
14187        // Get *real* offsetParent
14188        offsetParent = this.offsetParent();
14189
14190        // Get correct offsets
14191        offset = this.offset();
14192        if (!jQuery.nodeName(offsetParent[0], "html")) {
14193          parentOffset = offsetParent.offset();
14194        }
14195
14196        // Add offsetParent borders
14197        parentOffset.top += jQuery.css(offsetParent[0], "borderTopWidth", true);
14198        parentOffset.left += jQuery.css(offsetParent[0], "borderLeftWidth", true);
14199      }
14200
14201      // Subtract parent offsets and element margins
14202      return {
14203        top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true),
14204        left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true)
14205      };
14206    },
14207    offsetParent: function () {
14208      return this.map(function () {
14209        var offsetParent = this.offsetParent || docElem;
14210        while (offsetParent && !jQuery.nodeName(offsetParent, "html") && jQuery.css(offsetParent, "position") === "static") {
14211          offsetParent = offsetParent.offsetParent;
14212        }
14213        return offsetParent || docElem;
14214      });
14215    }
14216  });
14217
14218  // Create scrollLeft and scrollTop methods
14219  jQuery.each({
14220    scrollLeft: "pageXOffset",
14221    scrollTop: "pageYOffset"
14222  }, function (method, prop) {
14223    var top = "pageYOffset" === prop;
14224    jQuery.fn[method] = function (val) {
14225      return jQuery.access(this, function (elem, method, val) {
14226        var win = getWindow(elem);
14227        if (val === undefined) {
14228          return win ? win[prop] : elem[method];
14229        }
14230        if (win) {
14231          win.scrollTo(!top ? val : window.pageXOffset, top ? val : window.pageYOffset);
14232        } else {
14233          elem[method] = val;
14234        }
14235      }, method, val, arguments.length, null);
14236    };
14237  });
14238  function getWindow(elem) {
14239    return jQuery.isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView;
14240  }
14241  // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
14242  jQuery.each({
14243    Height: "height",
14244    Width: "width"
14245  }, function (name, type) {
14246    jQuery.each({
14247      padding: "inner" + name,
14248      content: type,
14249      "": "outer" + name
14250    }, function (defaultExtra, funcName) {
14251      // margin is only for outerHeight, outerWidth
14252      jQuery.fn[funcName] = function (margin, value) {
14253        var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"),
14254          extra = defaultExtra || (margin === true || value === true ? "margin" : "border");
14255        return jQuery.access(this, function (elem, type, value) {
14256          var doc;
14257          if (jQuery.isWindow(elem)) {
14258            // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
14259            // isn't a whole lot we can do. See pull request at this URL for discussion:
14260            // https://github.com/jquery/jquery/pull/764
14261            return elem.document.documentElement["client" + name];
14262          }
14263
14264          // Get document width or height
14265          if (elem.nodeType === 9) {
14266            doc = elem.documentElement;
14267
14268            // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
14269            // whichever is greatest
14270            return Math.max(elem.body["scroll" + name], doc["scroll" + name], elem.body["offset" + name], doc["offset" + name], doc["client" + name]);
14271          }
14272          return value === undefined ?
14273          // Get width or height on the element, requesting but not forcing parseFloat
14274          jQuery.css(elem, type, extra) :
14275          // Set width or height on the element
14276          jQuery.style(elem, type, value, extra);
14277        }, type, chainable ? margin : undefined, chainable, null);
14278      };
14279    });
14280  });
14281  // Limit scope pollution from any deprecated API
14282  // (function() {
14283
14284  // The number of elements contained in the matched element set
14285  jQuery.fn.size = function () {
14286    return this.length;
14287  };
14288  jQuery.fn.andSelf = jQuery.fn.addBack;
14289
14290  // })();
14291  if (typeof module === "object" && module && typeof module.exports === "object") {
14292    // Expose jQuery as module.exports in loaders that implement the Node
14293    // module pattern (including browserify). Do not create the global, since
14294    // the user will be storing it themselves locally, and globals are frowned
14295    // upon in the Node module world.
14296    module.exports = jQuery;
14297  } else {
14298    // Register as a named AMD module, since jQuery can be concatenated with other
14299    // files that may use define, but not via a proper concatenation script that
14300    // understands anonymous AMD modules. A named AMD is safest and most robust
14301    // way to register. Lowercase jquery is used because AMD module names are
14302    // derived from file names, and jQuery is normally delivered in a lowercase
14303    // file name. Do this after creating the global so that if an AMD module wants
14304    // to call noConflict to hide this version of jQuery, it will work.
14305    if (typeof define === "function" && define.amd) {
14306      define("jquery", [], function () {
14307        return jQuery;
14308      });
14309    }
14310  }
14311
14312  // If there is a window object, that at least has a document property,
14313  // define jQuery and $ identifiers
14314  if (typeof window === "object" && typeof window.document === "object") {
14315    window.jQuery = window.$ = jQuery;
14316  }
14317})(window);
14318/* ========================================================================
14319 * DOM-based Routing
14320 * Based on http://goo.gl/EUTi53 by Paul Irish
14321 *
14322 * Only fires on body classes that match. If a body class contains a dash,
14323 * replace the dash with an underscore when adding it to the object below.
14324 *
14325 * .noConflict()
14326 * The routing is enclosed within an anonymous function so that you can
14327 * always reference jQuery with $, even when in .noConflict() mode.
14328 * ======================================================================== */
14329
14330(function () {
14331  var RETRY_KEY = 'vtx-admin-bar-retry-v3';
14332  var MARKER_COOKIE = 'vtx_logged_in=1';
14333  function queryHasCacheBypass() {
14334    return /(?:^|[?&])(?:vtx_)?nocache=/.test(window.location.search);
14335  }
14336  function hasLoggedInMarker() {
14337    return document.cookie.split(';').some(function (cookie) {
14338      return cookie.trim() === MARKER_COOKIE;
14339    });
14340  }
14341  function setLoggedInMarker() {
14342    document.cookie = MARKER_COOKIE + '; path=/; SameSite=Lax';
14343  }
14344  function buildCacheBypassUrl() {
14345    var url = new URL(window.location.href);
14346    url.searchParams.set('vtx_nocache', String(Date.now()));
14347    return url.toString();
14348  }
14349  function cleanCacheBypassFromUrl() {
14350    if (!queryHasCacheBypass()) {
14351      return;
14352    }
14353    var url = new URL(window.location.href);
14354    url.searchParams.delete('vtx_nocache');
14355    url.searchParams.delete('nocache');
14356    window.history.replaceState({}, '', url.pathname + url.search + url.hash);
14357  }
14358  function reloadWithoutCache() {
14359    if (window.sessionStorage.getItem(RETRY_KEY)) {
14360      return;
14361    }
14362    window.sessionStorage.setItem(RETRY_KEY, '1');
14363    window.location.replace(buildCacheBypassUrl());
14364  }
14365  function recoverAdminBar() {
14366    if (document.getElementById('wpadminbar')) {
14367      window.sessionStorage.removeItem(RETRY_KEY);
14368      setLoggedInMarker();
14369      cleanCacheBypassFromUrl();
14370      return;
14371    }
14372    if (queryHasCacheBypass() || !hasLoggedInMarker()) {
14373      return;
14374    }
14375    reloadWithoutCache();
14376  }
14377  if (document.readyState === 'loading') {
14378    document.addEventListener('DOMContentLoaded', recoverAdminBar);
14379  } else {
14380    recoverAdminBar();
14381  }
14382})();
14383var __ = wp.i18n.__;
14384var _x = wp.i18n._x;
14385var _n = wp.i18n._n;
14386var _nx = wp.i18n._nx;
14387var sprintf = wp.i18n.sprintf;
14388(function ($) {
14389  // Use this variable to set up the common and page specific functions. If you
14390  // rename this variable, you will also need to rename the namespace below.
14391  var Sage = {
14392    // All pages
14393    'common': {
14394      init: function init() {
14395        // detects if user is using the keyboard to navigate and if so, adds a class to body
14396        function handleFirstTab(e) {
14397          if (e.keyCode === 9 || e.keyCode === 32 || e.keyCode === 37 || e.keyCode === 39) {
14398            // the "I am a keyboard user" key
14399            document.body.classList.add('user-is-tabbing');
14400            window.removeEventListener('keydown', handleFirstTab);
14401          }
14402        }
14403        window.addEventListener('keydown', handleFirstTab);
14404        var header = document.getElementById("header");
14405        var searchBtn = document.getElementById('search-toggle');
14406        var searchForm = document.getElementById('search-popup');
14407        searchBtn.onclick = function () {
14408          this.classList.toggle("open");
14409          searchForm.classList.toggle("open");
14410          if (this.classList.contains('open')) {
14411            header.classList.add('search-open');
14412            this.setAttribute('aria-expanded', true);
14413          } else {
14414            header.classList.remove('search-open');
14415            this.setAttribute('aria-expanded', false);
14416          }
14417        };
14418
14419        //credits..
14420        // console.log(
14421        //   '%c  \n' +
14422        //   '%cVortex Solution \n' +
14423        //   'https://www.vortexsolution.com',
14424        //   'font-size:30px; background: #fff url(https://www.vortexsolution.com/wp-content/themes/vortex-solution/assets/favicon/favicon-32x32.png) no-repeat; color:#fff;',
14425        //   'background: #fff; color:#00a6e9;font-weight:bold;'
14426        // );
14427      },
14428
14429      finalize: function finalize() {
14430        // JavaScript to be fired on all pages, after page specific JS is fired
14431      }
14432    },
14433    // Home page
14434    'home': {
14435      init: function init() {
14436        // JavaScript to be fired on the home page
14437      },
14438      finalize: function finalize() {
14439        // JavaScript to be fired on the home page, after the init JS
14440      }
14441    },
14442    // About us page, note the change from about-us to about_us.
14443    'about_us': {
14444      init: function init() {
14445        // JavaScript to be fired on the about us page
14446      }
14447    }
14448  };
14449
14450  // The routing fires all common scripts, followed by the page specific scripts.
14451  // Add additional events for more control over timing e.g. a finalize event
14452  var UTIL = {
14453    fire: function fire(func, funcname, args) {
14454      var fire;
14455      var namespace = Sage;
14456      funcname = funcname === undefined ? 'init' : funcname;
14457      fire = func !== '';
14458      fire = fire && namespace[func];
14459      fire = fire && typeof namespace[func][funcname] === 'function';
14460      if (fire) {
14461        namespace[func][funcname](args);
14462      }
14463    },
14464    loadEvents: function loadEvents() {
14465      // Fire common init JS
14466      UTIL.fire('common');
14467
14468      // Fire page-specific init JS, and then finalize JS
14469      $.each(document.body.className.replace(/-/g, '_').split(/\s+/), function (i, classnm) {
14470        UTIL.fire(classnm);
14471        UTIL.fire(classnm, 'finalize');
14472      });
14473
14474      // Fire common finalize JS
14475      UTIL.fire('common', 'finalize');
14476    }
14477  };
14478
14479  // Load Events
14480  $(document).ready(UTIL.loadEvents);
14481})(jQuery); // Fully reference jQuery after this point.
14482/**
14483 * Reference accessible navigation: https://adrianroselli.com/2019/06/link-disclosure-widget-navigation.html
14484 * 
14485 * @todo Rendre plus comme Vie des Arts
14486 */
14487(function ($) {
14488  // (!) These classes and selector also need to be changed in the _dropdown-menu.scss (!)
14489
14490  var $nav_with_dropdown = $('.nav-primary, .top-navigation');
14491  var dropdown_container_selector = '.dropdown';
14492  var link_wrapper_selector = '.nav-item__link-wrapper';
14493  var dropdown_toggle_class = 'dropdown__toggle';
14494  var active_class = 'opened';
14495  var opened_subnav = {};
14496  var unique_name_count = 0;
14497  var is_temporary_cancel = false;
14498  function create_unique_subnav_name() {
14499    unique_name_count++;
14500    return 'subnav_' + unique_name_count;
14501  }
14502  function try_closing_subnav(event) {
14503    for (var subnav_name in opened_subnav) {
14504      if ('undefined' === typeof subnav_name) {
14505        continue;
14506      }
14507      var $target = opened_subnav[subnav_name].find(event.target);
14508      if (!$target.length) {
14509        /* jshint ignore:start */
14510        close_subnav(subnav_name);
14511        /* jshint ignore:end */
14512
14513        continue;
14514      }
14515    }
14516  }
14517  function get_opened_subnav_by_name(subnav_name) {
14518    if (!opened_subnav[subnav_name]) {
14519      console.warn(subnav_name + ' n\'existe pas encore. (get_opened_subnav_by_name())');
14520      return $();
14521    }
14522    return opened_subnav[subnav_name];
14523  }
14524  function get_subnav_name($subnav) {
14525    var subnav_name = $subnav.data('subnav');
14526    if (!subnav_name) {
14527      subnav_name = create_unique_subnav_name();
14528      $subnav.data('subnav', subnav_name);
14529    }
14530    return subnav_name;
14531  }
14532  function set_opened_subnav($subnav) {
14533    var subnav_name = get_subnav_name($subnav);
14534    opened_subnav[subnav_name] = $subnav;
14535  }
14536  function open_subnav(subnav_name) {
14537    var $subnav = get_opened_subnav_by_name(subnav_name);
14538    $subnav.addClass(active_class);
14539    // Items are not visible for the moment and also not targetable by that fact.
14540    // This delay will permit a focus.
14541    setTimeout(function () {
14542      this.find('li a').first().focus();
14543      var $toggle = this.find('.' + dropdown_toggle_class).first();
14544      $toggle.attr('aria-expanded', true).attr('aria-label', $toggle.data('label-close'));
14545      if (1 === Object.keys(opened_subnav).length) {
14546        $(document).on('focusin.closing_subnav', try_closing_subnav).on('click.closing_subnav', try_closing_subnav);
14547      }
14548    }.bind($subnav), 10);
14549  }
14550  function close_subnav(subnav_name) {
14551    var $subnav = get_opened_subnav_by_name(subnav_name);
14552    $subnav.removeClass(active_class);
14553    var $toggle = $subnav.find('.' + dropdown_toggle_class).first();
14554    $toggle.attr('aria-expanded', false).attr('aria-label', $toggle.data('label-open'));
14555    delete opened_subnav[subnav_name];
14556
14557    // Supprimer les événements si il n'y a plus de menu ouvert.
14558    if (!Object.keys(opened_subnav).length) {
14559      $(document).off('click.closing_subnav').off('focusin.closing_subnav');
14560    }
14561  }
14562
14563  /////////////// ON READY /////////////////
14564  $(function () {
14565    $nav_with_dropdown.find('.' + dropdown_toggle_class).on('click', function (event) {
14566      event.stopPropagation();
14567      var $dropdown_container = $(this).closest(dropdown_container_selector);
14568      if (!$dropdown_container.hasClass(active_class)) {
14569        // On pourrait le faire tout le temps, mais en théorie on a déjà set un sub menu au close.
14570        // C'est donc plus performant de le faire juste ici.
14571        set_opened_subnav($dropdown_container);
14572        open_subnav(get_subnav_name($dropdown_container));
14573      } else {
14574        close_subnav(get_subnav_name($dropdown_container));
14575      }
14576    }).on('focusin', function () {
14577      var $dropdown_container = $(this).closest(dropdown_container_selector);
14578      if ($dropdown_container.hasClass(active_class)) {
14579        close_subnav(get_subnav_name($dropdown_container));
14580      }
14581    });
14582  });
14583})(jQuery);
14584(function ($) {
14585  var $slidebar_toggle = null;
14586  var $nav_item = $('#mobile-menu .nav-item__link');
14587  function toggle_dropdown(event) {
14588    event.preventDefault();
14589    event.stopPropagation();
14590    var $toggle = $(this);
14591    var $li = $toggle.closest('.dropdown');
14592    var $subnav = $li.children('.dropdown__subnav-wrapper');
14593    if ($li.hasClass('opened')) {
14594      $li.removeClass('opened');
14595      $subnav.slideUp('fast');
14596    } else {
14597      $li.addClass('opened');
14598      $subnav.slideDown('fast');
14599    }
14600  }
14601  function prepare_dropdown_for_nav($nav) {
14602    ///// INIT SLIDER POSITION /////
14603    $nav.find(".active").addClass("opened");
14604    $nav.find(".dropdown").filter(":not(.opened)").each(function () {
14605      $(this).children('.dropdown__subnav-wrapper').slideUp(0);
14606    });
14607
14608    ///// INIT EVENTS /////
14609    $nav.find(".dropdown__toggle").on('click', toggle_dropdown);
14610  }
14611  function close_slidebar_menu() {
14612    $slidebar_toggle.attr('aria-expanded', false);
14613    $('body').removeClass('mobile-menu-open');
14614    $(document).off('click.close_slidebar').off('keyup.close_slidebar');
14615  }
14616  function try_closing_slidebar_menu(event) {
14617    // Keyboard
14618    if ('undefined' !== typeof event.keyCode) {
14619      // ESCAPE
14620      if (27 === event.keyCode) {
14621        $('.vtx-burger-container').focus();
14622        close_slidebar_menu();
14623      }
14624    }
14625    // Click
14626    else if (!$(event.target).closest('#mobile-menu-wrapper').length) {
14627      close_slidebar_menu();
14628    }
14629  }
14630  function open_slidebar_menu() {
14631    $slidebar_toggle.attr('aria-expanded', true);
14632    $('body').addClass('mobile-menu-open');
14633    $('.header__search-popup').removeClass('open');
14634    $('.search-btn').removeClass('open');
14635    $(document).on('click.close_slidebar', try_closing_slidebar_menu).on('keyup.close_slidebar', try_closing_slidebar_menu);
14636  }
14637  function init_menu_mobile() {
14638    $slidebar_toggle = $('.vtx-burger-container');
14639    $secondary_slidebar_toggle = $('.secondary-burger');
14640    var $mobile_menu = $('#mobile-menu');
14641    $slidebar_toggle.on('click', function (event) {
14642      event.stopPropagation();
14643      if ($('body').hasClass('mobile-menu-open')) {
14644        close_slidebar_menu();
14645      } else {
14646        open_slidebar_menu();
14647      }
14648    });
14649    $secondary_slidebar_toggle.on('click', function (event) {
14650      event.stopPropagation();
14651      if ($('body').hasClass('mobile-menu-open')) {
14652        close_slidebar_menu();
14653      } else {
14654        open_slidebar_menu();
14655      }
14656    });
14657    $nav_item.on('click', function () {
14658      close_slidebar_menu();
14659    });
14660    prepare_dropdown_for_nav($mobile_menu.find('.nav-mobile'));
14661  }
14662  $(document).ready(function () {
14663    init_menu_mobile();
14664  });
14665})(jQuery);
14666fields_are_initialized = false;
14667function change_form_label(label, input) {
14668  if ('' !== input.val()) {
14669    $(label).addClass('active');
14670  }
14671  $(label).on('click', function () {
14672    $(input).focus();
14673  });
14674  $(input).on('focus', function () {
14675    $(label).addClass('active');
14676  }).on('focusout change', function () {
14677    var value = $.trim($(this).val());
14678    if (value.length === 0 || $(this).val() === '(___) ___-____') {
14679      $(label).removeClass('active');
14680    } else {
14681      $(label).addClass('active');
14682    }
14683  });
14684}
14685function init_floating_select(label, select) {
14686  var $label = $(label);
14687  var $select = $(select);
14688  function update_select_label_state() {
14689    var value = $.trim($select.val());
14690    var isEmpty = value.length === 0;
14691    $select.toggleClass('is-empty', isEmpty);
14692    if (isEmpty && !$select.is(':focus')) {
14693      $label.removeClass('active');
14694    } else {
14695      $label.addClass('active');
14696    }
14697  }
14698  update_select_label_state();
14699  $select.on('focus', function () {
14700    $label.addClass('active');
14701  }).on('focusout change', function () {
14702    update_select_label_state();
14703  });
14704}
14705function add_form_events() {
14706  $('.woocommerce-billing-fields__field-wrapper .form-row, .form_field_wrapper').each(function () {
14707    var $woofield = $(this);
14708    if ($woofield.hasClass('initialized')) {
14709      return;
14710    }
14711    var wooClassesExcluded = ['update_totals_on_change', 'audition-fileupload'];
14712    for (var i = 0; i < wooClassesExcluded.length; i++) {
14713      if ($woofield.hasClass(wooClassesExcluded[i])) {
14714        return;
14715      }
14716    }
14717    var $woolabel;
14718    var $wooinput;
14719    $woofield.addClass('initialized');
14720    $woolabel = $woofield.find('label');
14721    $wooinput = $woofield.find('input');
14722    change_form_label($woolabel, $wooinput);
14723  });
14724  $('.gfield:not(.gfield--radio)').each(function () {
14725    var $field = $(this);
14726    if ($field.hasClass('initialized')) {
14727      return;
14728    }
14729    var classesExcluded = ['ginput-wrapper--radio', 'ginput-wrapper--checkbox', 'ginput-wrapper--consent'];
14730    for (var i = 0; i < classesExcluded.length; i++) {
14731      if ($field.hasClass(classesExcluded[i])) {
14732        return;
14733      }
14734    }
14735    var $label;
14736    var $input;
14737    $field.addClass('initialized');
14738    $label = $field.find('.gfield_label');
14739    $field.find('.ginput_container select').each(function () {
14740      init_floating_select($label, this);
14741    });
14742    $field.find('.ginput_container input, .ginput_container textarea').each(function () {
14743      change_form_label($label, $(this));
14744    });
14745    if ($field.hasClass('gfield--has-multiple-inputs')) {
14746      $field.find('.ginput_complex > span').each(function () {
14747        var $deeper_field = $(this);
14748        if ($deeper_field.hasClass('initialized')) {
14749          return;
14750        }
14751        $deeper_field.addClass('initialized');
14752        $label = $deeper_field.find('label');
14753        $input = $deeper_field.find('input, textarea');
14754        change_form_label($label, $input);
14755      });
14756    }
14757  });
14758}
14759$(document).on('gform_post_render', function (event, form_id, current_page) {
14760  fields_are_initialized = true;
14761  add_form_events();
14762});
14763
14764// ON READY
14765$(function () {
14766  if (!fields_are_initialized) {
14767    // Initialize fields events only if they were not already.
14768    add_form_events();
14769  }
14770});
14771//# sourceMappingURL=main.js.map

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.