File indexing completed on 2024-05-19 04:00:11
0001 /* 0002 Underscore.js 1.9.1 <http://underscorejs.org> 0003 0004 SPDX-FileCopyrightText: 2009-2018 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 0005 0006 SPDX-License-Identifier: MIT 0007 */ 0008 0009 (function() { 0010 0011 // Baseline setup 0012 // -------------- 0013 0014 // Establish the root object, `window` (`self`) in the browser, `global` 0015 // on the server, or `this` in some virtual machines. We use `self` 0016 // instead of `window` for `WebWorker` support. 0017 var root = typeof self == 'object' && self.self === self && self || 0018 typeof global == 'object' && global.global === global && global || 0019 this || 0020 {}; 0021 0022 // Save the previous value of the `_` variable. 0023 var previousUnderscore = root._; 0024 0025 // Save bytes in the minified (but not gzipped) version: 0026 var ArrayProto = Array.prototype, ObjProto = Object.prototype; 0027 var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null; 0028 0029 // Create quick reference variables for speed access to core prototypes. 0030 var push = ArrayProto.push, 0031 slice = ArrayProto.slice, 0032 toString = ObjProto.toString, 0033 hasOwnProperty = ObjProto.hasOwnProperty; 0034 0035 // All **ECMAScript 5** native function implementations that we hope to use 0036 // are declared here. 0037 var nativeIsArray = Array.isArray, 0038 nativeKeys = Object.keys, 0039 nativeCreate = Object.create; 0040 0041 // Naked function reference for surrogate-prototype-swapping. 0042 var Ctor = function(){}; 0043 0044 // Create a safe reference to the Underscore object for use below. 0045 var _ = function(obj) { 0046 if (obj instanceof _) return obj; 0047 if (!(this instanceof _)) return new _(obj); 0048 this._wrapped = obj; 0049 }; 0050 0051 // Export the Underscore object for **Node.js**, with 0052 // backwards-compatibility for their old module API. If we're in 0053 // the browser, add `_` as a global object. 0054 // (`nodeType` is checked to ensure that `module` 0055 // and `exports` are not HTML elements.) 0056 if (typeof exports != 'undefined' && !exports.nodeType) { 0057 if (typeof module != 'undefined' && !module.nodeType && module.exports) { 0058 exports = module.exports = _; 0059 } 0060 exports._ = _; 0061 } else { 0062 root._ = _; 0063 } 0064 0065 // Current version. 0066 _.VERSION = '1.9.1'; 0067 0068 // Internal function that returns an efficient (for current engines) version 0069 // of the passed-in callback, to be repeatedly applied in other Underscore 0070 // functions. 0071 var optimizeCb = function(func, context, argCount) { 0072 if (context === void 0) return func; 0073 switch (argCount == null ? 3 : argCount) { 0074 case 1: return function(value) { 0075 return func.call(context, value); 0076 }; 0077 // The 2-argument case is omitted because we’re not using it. 0078 case 3: return function(value, index, collection) { 0079 return func.call(context, value, index, collection); 0080 }; 0081 case 4: return function(accumulator, value, index, collection) { 0082 return func.call(context, accumulator, value, index, collection); 0083 }; 0084 } 0085 return function() { 0086 return func.apply(context, arguments); 0087 }; 0088 }; 0089 0090 var builtinIteratee; 0091 0092 // An internal function to generate callbacks that can be applied to each 0093 // element in a collection, returning the desired result — either `identity`, 0094 // an arbitrary callback, a property matcher, or a property accessor. 0095 var cb = function(value, context, argCount) { 0096 if (_.iteratee !== builtinIteratee) return _.iteratee(value, context); 0097 if (value == null) return _.identity; 0098 if (_.isFunction(value)) return optimizeCb(value, context, argCount); 0099 if (_.isObject(value) && !_.isArray(value)) return _.matcher(value); 0100 return _.property(value); 0101 }; 0102 0103 // External wrapper for our callback generator. Users may customize 0104 // `_.iteratee` if they want additional predicate/iteratee shorthand styles. 0105 // This abstraction hides the internal-only argCount argument. 0106 _.iteratee = builtinIteratee = function(value, context) { 0107 return cb(value, context, Infinity); 0108 }; 0109 0110 // Some functions take a variable number of arguments, or a few expected 0111 // arguments at the beginning and then a variable number of values to operate 0112 // on. This helper accumulates all remaining arguments past the function’s 0113 // argument length (or an explicit `startIndex`), into an array that becomes 0114 // the last argument. Similar to ES6’s "rest parameter". 0115 var restArguments = function(func, startIndex) { 0116 startIndex = startIndex == null ? func.length - 1 : +startIndex; 0117 return function() { 0118 var length = Math.max(arguments.length - startIndex, 0), 0119 rest = Array(length), 0120 index = 0; 0121 for (; index < length; index++) { 0122 rest[index] = arguments[index + startIndex]; 0123 } 0124 switch (startIndex) { 0125 case 0: return func.call(this, rest); 0126 case 1: return func.call(this, arguments[0], rest); 0127 case 2: return func.call(this, arguments[0], arguments[1], rest); 0128 } 0129 var args = Array(startIndex + 1); 0130 for (index = 0; index < startIndex; index++) { 0131 args[index] = arguments[index]; 0132 } 0133 args[startIndex] = rest; 0134 return func.apply(this, args); 0135 }; 0136 }; 0137 0138 // An internal function for creating a new object that inherits from another. 0139 var baseCreate = function(prototype) { 0140 if (!_.isObject(prototype)) return {}; 0141 if (nativeCreate) return nativeCreate(prototype); 0142 Ctor.prototype = prototype; 0143 var result = new Ctor; 0144 Ctor.prototype = null; 0145 return result; 0146 }; 0147 0148 var shallowProperty = function(key) { 0149 return function(obj) { 0150 return obj == null ? void 0 : obj[key]; 0151 }; 0152 }; 0153 0154 var has = function(obj, path) { 0155 return obj != null && hasOwnProperty.call(obj, path); 0156 } 0157 0158 var deepGet = function(obj, path) { 0159 var length = path.length; 0160 for (var i = 0; i < length; i++) { 0161 if (obj == null) return void 0; 0162 obj = obj[path[i]]; 0163 } 0164 return length ? obj : void 0; 0165 }; 0166 0167 // Helper for collection methods to determine whether a collection 0168 // should be iterated as an array or as an object. 0169 // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength 0170 // Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094 0171 var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; 0172 var getLength = shallowProperty('length'); 0173 var isArrayLike = function(collection) { 0174 var length = getLength(collection); 0175 return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; 0176 }; 0177 0178 // Collection Functions 0179 // -------------------- 0180 0181 // The cornerstone, an `each` implementation, aka `forEach`. 0182 // Handles raw objects in addition to array-likes. Treats all 0183 // sparse array-likes as if they were dense. 0184 _.each = _.forEach = function(obj, iteratee, context) { 0185 iteratee = optimizeCb(iteratee, context); 0186 var i, length; 0187 if (isArrayLike(obj)) { 0188 for (i = 0, length = obj.length; i < length; i++) { 0189 iteratee(obj[i], i, obj); 0190 } 0191 } else { 0192 var keys = _.keys(obj); 0193 for (i = 0, length = keys.length; i < length; i++) { 0194 iteratee(obj[keys[i]], keys[i], obj); 0195 } 0196 } 0197 return obj; 0198 }; 0199 0200 // Return the results of applying the iteratee to each element. 0201 _.map = _.collect = function(obj, iteratee, context) { 0202 iteratee = cb(iteratee, context); 0203 var keys = !isArrayLike(obj) && _.keys(obj), 0204 length = (keys || obj).length, 0205 results = Array(length); 0206 for (var index = 0; index < length; index++) { 0207 var currentKey = keys ? keys[index] : index; 0208 results[index] = iteratee(obj[currentKey], currentKey, obj); 0209 } 0210 return results; 0211 }; 0212 0213 // Create a reducing function iterating left or right. 0214 var createReduce = function(dir) { 0215 // Wrap code that reassigns argument variables in a separate function than 0216 // the one that accesses `arguments.length` to avoid a perf hit. (#1991) 0217 var reducer = function(obj, iteratee, memo, initial) { 0218 var keys = !isArrayLike(obj) && _.keys(obj), 0219 length = (keys || obj).length, 0220 index = dir > 0 ? 0 : length - 1; 0221 if (!initial) { 0222 memo = obj[keys ? keys[index] : index]; 0223 index += dir; 0224 } 0225 for (; index >= 0 && index < length; index += dir) { 0226 var currentKey = keys ? keys[index] : index; 0227 memo = iteratee(memo, obj[currentKey], currentKey, obj); 0228 } 0229 return memo; 0230 }; 0231 0232 return function(obj, iteratee, memo, context) { 0233 var initial = arguments.length >= 3; 0234 return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial); 0235 }; 0236 }; 0237 0238 // **Reduce** builds up a single result from a list of values, aka `inject`, 0239 // or `foldl`. 0240 _.reduce = _.foldl = _.inject = createReduce(1); 0241 0242 // The right-associative version of reduce, also known as `foldr`. 0243 _.reduceRight = _.foldr = createReduce(-1); 0244 0245 // Return the first value which passes a truth test. Aliased as `detect`. 0246 _.find = _.detect = function(obj, predicate, context) { 0247 var keyFinder = isArrayLike(obj) ? _.findIndex : _.findKey; 0248 var key = keyFinder(obj, predicate, context); 0249 if (key !== void 0 && key !== -1) return obj[key]; 0250 }; 0251 0252 // Return all the elements that pass a truth test. 0253 // Aliased as `select`. 0254 _.filter = _.select = function(obj, predicate, context) { 0255 var results = []; 0256 predicate = cb(predicate, context); 0257 _.each(obj, function(value, index, list) { 0258 if (predicate(value, index, list)) results.push(value); 0259 }); 0260 return results; 0261 }; 0262 0263 // Return all the elements for which a truth test fails. 0264 _.reject = function(obj, predicate, context) { 0265 return _.filter(obj, _.negate(cb(predicate)), context); 0266 }; 0267 0268 // Determine whether all of the elements match a truth test. 0269 // Aliased as `all`. 0270 _.every = _.all = function(obj, predicate, context) { 0271 predicate = cb(predicate, context); 0272 var keys = !isArrayLike(obj) && _.keys(obj), 0273 length = (keys || obj).length; 0274 for (var index = 0; index < length; index++) { 0275 var currentKey = keys ? keys[index] : index; 0276 if (!predicate(obj[currentKey], currentKey, obj)) return false; 0277 } 0278 return true; 0279 }; 0280 0281 // Determine if at least one element in the object matches a truth test. 0282 // Aliased as `any`. 0283 _.some = _.any = function(obj, predicate, context) { 0284 predicate = cb(predicate, context); 0285 var keys = !isArrayLike(obj) && _.keys(obj), 0286 length = (keys || obj).length; 0287 for (var index = 0; index < length; index++) { 0288 var currentKey = keys ? keys[index] : index; 0289 if (predicate(obj[currentKey], currentKey, obj)) return true; 0290 } 0291 return false; 0292 }; 0293 0294 // Determine if the array or object contains a given item (using `===`). 0295 // Aliased as `includes` and `include`. 0296 _.contains = _.includes = _.include = function(obj, item, fromIndex, guard) { 0297 if (!isArrayLike(obj)) obj = _.values(obj); 0298 if (typeof fromIndex != 'number' || guard) fromIndex = 0; 0299 return _.indexOf(obj, item, fromIndex) >= 0; 0300 }; 0301 0302 // Invoke a method (with arguments) on every item in a collection. 0303 _.invoke = restArguments(function(obj, path, args) { 0304 var contextPath, func; 0305 if (_.isFunction(path)) { 0306 func = path; 0307 } else if (_.isArray(path)) { 0308 contextPath = path.slice(0, -1); 0309 path = path[path.length - 1]; 0310 } 0311 return _.map(obj, function(context) { 0312 var method = func; 0313 if (!method) { 0314 if (contextPath && contextPath.length) { 0315 context = deepGet(context, contextPath); 0316 } 0317 if (context == null) return void 0; 0318 method = context[path]; 0319 } 0320 return method == null ? method : method.apply(context, args); 0321 }); 0322 }); 0323 0324 // Convenience version of a common use case of `map`: fetching a property. 0325 _.pluck = function(obj, key) { 0326 return _.map(obj, _.property(key)); 0327 }; 0328 0329 // Convenience version of a common use case of `filter`: selecting only objects 0330 // containing specific `key:value` pairs. 0331 _.where = function(obj, attrs) { 0332 return _.filter(obj, _.matcher(attrs)); 0333 }; 0334 0335 // Convenience version of a common use case of `find`: getting the first object 0336 // containing specific `key:value` pairs. 0337 _.findWhere = function(obj, attrs) { 0338 return _.find(obj, _.matcher(attrs)); 0339 }; 0340 0341 // Return the maximum element (or element-based computation). 0342 _.max = function(obj, iteratee, context) { 0343 var result = -Infinity, lastComputed = -Infinity, 0344 value, computed; 0345 if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) { 0346 obj = isArrayLike(obj) ? obj : _.values(obj); 0347 for (var i = 0, length = obj.length; i < length; i++) { 0348 value = obj[i]; 0349 if (value != null && value > result) { 0350 result = value; 0351 } 0352 } 0353 } else { 0354 iteratee = cb(iteratee, context); 0355 _.each(obj, function(v, index, list) { 0356 computed = iteratee(v, index, list); 0357 if (computed > lastComputed || computed === -Infinity && result === -Infinity) { 0358 result = v; 0359 lastComputed = computed; 0360 } 0361 }); 0362 } 0363 return result; 0364 }; 0365 0366 // Return the minimum element (or element-based computation). 0367 _.min = function(obj, iteratee, context) { 0368 var result = Infinity, lastComputed = Infinity, 0369 value, computed; 0370 if (iteratee == null || typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null) { 0371 obj = isArrayLike(obj) ? obj : _.values(obj); 0372 for (var i = 0, length = obj.length; i < length; i++) { 0373 value = obj[i]; 0374 if (value != null && value < result) { 0375 result = value; 0376 } 0377 } 0378 } else { 0379 iteratee = cb(iteratee, context); 0380 _.each(obj, function(v, index, list) { 0381 computed = iteratee(v, index, list); 0382 if (computed < lastComputed || computed === Infinity && result === Infinity) { 0383 result = v; 0384 lastComputed = computed; 0385 } 0386 }); 0387 } 0388 return result; 0389 }; 0390 0391 // Shuffle a collection. 0392 _.shuffle = function(obj) { 0393 return _.sample(obj, Infinity); 0394 }; 0395 0396 // Sample **n** random values from a collection using the modern version of the 0397 // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). 0398 // If **n** is not specified, returns a single random element. 0399 // The internal `guard` argument allows it to work with `map`. 0400 _.sample = function(obj, n, guard) { 0401 if (n == null || guard) { 0402 if (!isArrayLike(obj)) obj = _.values(obj); 0403 return obj[_.random(obj.length - 1)]; 0404 } 0405 var sample = isArrayLike(obj) ? _.clone(obj) : _.values(obj); 0406 var length = getLength(sample); 0407 n = Math.max(Math.min(n, length), 0); 0408 var last = length - 1; 0409 for (var index = 0; index < n; index++) { 0410 var rand = _.random(index, last); 0411 var temp = sample[index]; 0412 sample[index] = sample[rand]; 0413 sample[rand] = temp; 0414 } 0415 return sample.slice(0, n); 0416 }; 0417 0418 // Sort the object's values by a criterion produced by an iteratee. 0419 _.sortBy = function(obj, iteratee, context) { 0420 var index = 0; 0421 iteratee = cb(iteratee, context); 0422 return _.pluck(_.map(obj, function(value, key, list) { 0423 return { 0424 value: value, 0425 index: index++, 0426 criteria: iteratee(value, key, list) 0427 }; 0428 }).sort(function(left, right) { 0429 var a = left.criteria; 0430 var b = right.criteria; 0431 if (a !== b) { 0432 if (a > b || a === void 0) return 1; 0433 if (a < b || b === void 0) return -1; 0434 } 0435 return left.index - right.index; 0436 }), 'value'); 0437 }; 0438 0439 // An internal function used for aggregate "group by" operations. 0440 var group = function(behavior, partition) { 0441 return function(obj, iteratee, context) { 0442 var result = partition ? [[], []] : {}; 0443 iteratee = cb(iteratee, context); 0444 _.each(obj, function(value, index) { 0445 var key = iteratee(value, index, obj); 0446 behavior(result, value, key); 0447 }); 0448 return result; 0449 }; 0450 }; 0451 0452 // Groups the object's values by a criterion. Pass either a string attribute 0453 // to group by, or a function that returns the criterion. 0454 _.groupBy = group(function(result, value, key) { 0455 if (has(result, key)) result[key].push(value); else result[key] = [value]; 0456 }); 0457 0458 // Indexes the object's values by a criterion, similar to `groupBy`, but for 0459 // when you know that your index values will be unique. 0460 _.indexBy = group(function(result, value, key) { 0461 result[key] = value; 0462 }); 0463 0464 // Counts instances of an object that group by a certain criterion. Pass 0465 // either a string attribute to count by, or a function that returns the 0466 // criterion. 0467 _.countBy = group(function(result, value, key) { 0468 if (has(result, key)) result[key]++; else result[key] = 1; 0469 }); 0470 0471 var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g; 0472 // Safely create a real, live array from anything iterable. 0473 _.toArray = function(obj) { 0474 if (!obj) return []; 0475 if (_.isArray(obj)) return slice.call(obj); 0476 if (_.isString(obj)) { 0477 // Keep surrogate pair characters together 0478 return obj.match(reStrSymbol); 0479 } 0480 if (isArrayLike(obj)) return _.map(obj, _.identity); 0481 return _.values(obj); 0482 }; 0483 0484 // Return the number of elements in an object. 0485 _.size = function(obj) { 0486 if (obj == null) return 0; 0487 return isArrayLike(obj) ? obj.length : _.keys(obj).length; 0488 }; 0489 0490 // Split a collection into two arrays: one whose elements all satisfy the given 0491 // predicate, and one whose elements all do not satisfy the predicate. 0492 _.partition = group(function(result, value, pass) { 0493 result[pass ? 0 : 1].push(value); 0494 }, true); 0495 0496 // Array Functions 0497 // --------------- 0498 0499 // Get the first element of an array. Passing **n** will return the first N 0500 // values in the array. Aliased as `head` and `take`. The **guard** check 0501 // allows it to work with `_.map`. 0502 _.first = _.head = _.take = function(array, n, guard) { 0503 if (array == null || array.length < 1) return n == null ? void 0 : []; 0504 if (n == null || guard) return array[0]; 0505 return _.initial(array, array.length - n); 0506 }; 0507 0508 // Returns everything but the last entry of the array. Especially useful on 0509 // the arguments object. Passing **n** will return all the values in 0510 // the array, excluding the last N. 0511 _.initial = function(array, n, guard) { 0512 return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); 0513 }; 0514 0515 // Get the last element of an array. Passing **n** will return the last N 0516 // values in the array. 0517 _.last = function(array, n, guard) { 0518 if (array == null || array.length < 1) return n == null ? void 0 : []; 0519 if (n == null || guard) return array[array.length - 1]; 0520 return _.rest(array, Math.max(0, array.length - n)); 0521 }; 0522 0523 // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. 0524 // Especially useful on the arguments object. Passing an **n** will return 0525 // the rest N values in the array. 0526 _.rest = _.tail = _.drop = function(array, n, guard) { 0527 return slice.call(array, n == null || guard ? 1 : n); 0528 }; 0529 0530 // Trim out all falsy values from an array. 0531 _.compact = function(array) { 0532 return _.filter(array, Boolean); 0533 }; 0534 0535 // Internal implementation of a recursive `flatten` function. 0536 var flatten = function(input, shallow, strict, output) { 0537 output = output || []; 0538 var idx = output.length; 0539 for (var i = 0, length = getLength(input); i < length; i++) { 0540 var value = input[i]; 0541 if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { 0542 // Flatten current level of array or arguments object. 0543 if (shallow) { 0544 var j = 0, len = value.length; 0545 while (j < len) output[idx++] = value[j++]; 0546 } else { 0547 flatten(value, shallow, strict, output); 0548 idx = output.length; 0549 } 0550 } else if (!strict) { 0551 output[idx++] = value; 0552 } 0553 } 0554 return output; 0555 }; 0556 0557 // Flatten out an array, either recursively (by default), or just one level. 0558 _.flatten = function(array, shallow) { 0559 return flatten(array, shallow, false); 0560 }; 0561 0562 // Return a version of the array that does not contain the specified value(s). 0563 _.without = restArguments(function(array, otherArrays) { 0564 return _.difference(array, otherArrays); 0565 }); 0566 0567 // Produce a duplicate-free version of the array. If the array has already 0568 // been sorted, you have the option of using a faster algorithm. 0569 // The faster algorithm will not work with an iteratee if the iteratee 0570 // is not a one-to-one function, so providing an iteratee will disable 0571 // the faster algorithm. 0572 // Aliased as `unique`. 0573 _.uniq = _.unique = function(array, isSorted, iteratee, context) { 0574 if (!_.isBoolean(isSorted)) { 0575 context = iteratee; 0576 iteratee = isSorted; 0577 isSorted = false; 0578 } 0579 if (iteratee != null) iteratee = cb(iteratee, context); 0580 var result = []; 0581 var seen = []; 0582 for (var i = 0, length = getLength(array); i < length; i++) { 0583 var value = array[i], 0584 computed = iteratee ? iteratee(value, i, array) : value; 0585 if (isSorted && !iteratee) { 0586 if (!i || seen !== computed) result.push(value); 0587 seen = computed; 0588 } else if (iteratee) { 0589 if (!_.contains(seen, computed)) { 0590 seen.push(computed); 0591 result.push(value); 0592 } 0593 } else if (!_.contains(result, value)) { 0594 result.push(value); 0595 } 0596 } 0597 return result; 0598 }; 0599 0600 // Produce an array that contains the union: each distinct element from all of 0601 // the passed-in arrays. 0602 _.union = restArguments(function(arrays) { 0603 return _.uniq(flatten(arrays, true, true)); 0604 }); 0605 0606 // Produce an array that contains every item shared between all the 0607 // passed-in arrays. 0608 _.intersection = function(array) { 0609 var result = []; 0610 var argsLength = arguments.length; 0611 for (var i = 0, length = getLength(array); i < length; i++) { 0612 var item = array[i]; 0613 if (_.contains(result, item)) continue; 0614 var j; 0615 for (j = 1; j < argsLength; j++) { 0616 if (!_.contains(arguments[j], item)) break; 0617 } 0618 if (j === argsLength) result.push(item); 0619 } 0620 return result; 0621 }; 0622 0623 // Take the difference between one array and a number of other arrays. 0624 // Only the elements present in just the first array will remain. 0625 _.difference = restArguments(function(array, rest) { 0626 rest = flatten(rest, true, true); 0627 return _.filter(array, function(value){ 0628 return !_.contains(rest, value); 0629 }); 0630 }); 0631 0632 // Complement of _.zip. Unzip accepts an array of arrays and groups 0633 // each array's elements on shared indices. 0634 _.unzip = function(array) { 0635 var length = array && _.max(array, getLength).length || 0; 0636 var result = Array(length); 0637 0638 for (var index = 0; index < length; index++) { 0639 result[index] = _.pluck(array, index); 0640 } 0641 return result; 0642 }; 0643 0644 // Zip together multiple lists into a single array -- elements that share 0645 // an index go together. 0646 _.zip = restArguments(_.unzip); 0647 0648 // Converts lists into objects. Pass either a single array of `[key, value]` 0649 // pairs, or two parallel arrays of the same length -- one of keys, and one of 0650 // the corresponding values. Passing by pairs is the reverse of _.pairs. 0651 _.object = function(list, values) { 0652 var result = {}; 0653 for (var i = 0, length = getLength(list); i < length; i++) { 0654 if (values) { 0655 result[list[i]] = values[i]; 0656 } else { 0657 result[list[i][0]] = list[i][1]; 0658 } 0659 } 0660 return result; 0661 }; 0662 0663 // Generator function to create the findIndex and findLastIndex functions. 0664 var createPredicateIndexFinder = function(dir) { 0665 return function(array, predicate, context) { 0666 predicate = cb(predicate, context); 0667 var length = getLength(array); 0668 var index = dir > 0 ? 0 : length - 1; 0669 for (; index >= 0 && index < length; index += dir) { 0670 if (predicate(array[index], index, array)) return index; 0671 } 0672 return -1; 0673 }; 0674 }; 0675 0676 // Returns the first index on an array-like that passes a predicate test. 0677 _.findIndex = createPredicateIndexFinder(1); 0678 _.findLastIndex = createPredicateIndexFinder(-1); 0679 0680 // Use a comparator function to figure out the smallest index at which 0681 // an object should be inserted so as to maintain order. Uses binary search. 0682 _.sortedIndex = function(array, obj, iteratee, context) { 0683 iteratee = cb(iteratee, context, 1); 0684 var value = iteratee(obj); 0685 var low = 0, high = getLength(array); 0686 while (low < high) { 0687 var mid = Math.floor((low + high) / 2); 0688 if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; 0689 } 0690 return low; 0691 }; 0692 0693 // Generator function to create the indexOf and lastIndexOf functions. 0694 var createIndexFinder = function(dir, predicateFind, sortedIndex) { 0695 return function(array, item, idx) { 0696 var i = 0, length = getLength(array); 0697 if (typeof idx == 'number') { 0698 if (dir > 0) { 0699 i = idx >= 0 ? idx : Math.max(idx + length, i); 0700 } else { 0701 length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1; 0702 } 0703 } else if (sortedIndex && idx && length) { 0704 idx = sortedIndex(array, item); 0705 return array[idx] === item ? idx : -1; 0706 } 0707 if (item !== item) { 0708 idx = predicateFind(slice.call(array, i, length), _.isNaN); 0709 return idx >= 0 ? idx + i : -1; 0710 } 0711 for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) { 0712 if (array[idx] === item) return idx; 0713 } 0714 return -1; 0715 }; 0716 }; 0717 0718 // Return the position of the first occurrence of an item in an array, 0719 // or -1 if the item is not included in the array. 0720 // If the array is large and already in sort order, pass `true` 0721 // for **isSorted** to use binary search. 0722 _.indexOf = createIndexFinder(1, _.findIndex, _.sortedIndex); 0723 _.lastIndexOf = createIndexFinder(-1, _.findLastIndex); 0724 0725 // Generate an integer Array containing an arithmetic progression. A port of 0726 // the native Python `range()` function. See 0727 // [the Python documentation](http://docs.python.org/library/functions.html#range). 0728 _.range = function(start, stop, step) { 0729 if (stop == null) { 0730 stop = start || 0; 0731 start = 0; 0732 } 0733 if (!step) { 0734 step = stop < start ? -1 : 1; 0735 } 0736 0737 var length = Math.max(Math.ceil((stop - start) / step), 0); 0738 var range = Array(length); 0739 0740 for (var idx = 0; idx < length; idx++, start += step) { 0741 range[idx] = start; 0742 } 0743 0744 return range; 0745 }; 0746 0747 // Chunk a single array into multiple arrays, each containing `count` or fewer 0748 // items. 0749 _.chunk = function(array, count) { 0750 if (count == null || count < 1) return []; 0751 var result = []; 0752 var i = 0, length = array.length; 0753 while (i < length) { 0754 result.push(slice.call(array, i, i += count)); 0755 } 0756 return result; 0757 }; 0758 0759 // Function (ahem) Functions 0760 // ------------------ 0761 0762 // Determines whether to execute a function as a constructor 0763 // or a normal function with the provided arguments. 0764 var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { 0765 if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); 0766 var self = baseCreate(sourceFunc.prototype); 0767 var result = sourceFunc.apply(self, args); 0768 if (_.isObject(result)) return result; 0769 return self; 0770 }; 0771 0772 // Create a function bound to a given object (assigning `this`, and arguments, 0773 // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if 0774 // available. 0775 _.bind = restArguments(function(func, context, args) { 0776 if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); 0777 var bound = restArguments(function(callArgs) { 0778 return executeBound(func, bound, context, this, args.concat(callArgs)); 0779 }); 0780 return bound; 0781 }); 0782 0783 // Partially apply a function by creating a version that has had some of its 0784 // arguments pre-filled, without changing its dynamic `this` context. _ acts 0785 // as a placeholder by default, allowing any combination of arguments to be 0786 // pre-filled. Set `_.partial.placeholder` for a custom placeholder argument. 0787 _.partial = restArguments(function(func, boundArgs) { 0788 var placeholder = _.partial.placeholder; 0789 var bound = function() { 0790 var position = 0, length = boundArgs.length; 0791 var args = Array(length); 0792 for (var i = 0; i < length; i++) { 0793 args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i]; 0794 } 0795 while (position < arguments.length) args.push(arguments[position++]); 0796 return executeBound(func, bound, this, this, args); 0797 }; 0798 return bound; 0799 }); 0800 0801 _.partial.placeholder = _; 0802 0803 // Bind a number of an object's methods to that object. Remaining arguments 0804 // are the method names to be bound. Useful for ensuring that all callbacks 0805 // defined on an object belong to it. 0806 _.bindAll = restArguments(function(obj, keys) { 0807 keys = flatten(keys, false, false); 0808 var index = keys.length; 0809 if (index < 1) throw new Error('bindAll must be passed function names'); 0810 while (index--) { 0811 var key = keys[index]; 0812 obj[key] = _.bind(obj[key], obj); 0813 } 0814 }); 0815 0816 // Memoize an expensive function by storing its results. 0817 _.memoize = function(func, hasher) { 0818 var memoize = function(key) { 0819 var cache = memoize.cache; 0820 var address = '' + (hasher ? hasher.apply(this, arguments) : key); 0821 if (!has(cache, address)) cache[address] = func.apply(this, arguments); 0822 return cache[address]; 0823 }; 0824 memoize.cache = {}; 0825 return memoize; 0826 }; 0827 0828 // Delays a function for the given number of milliseconds, and then calls 0829 // it with the arguments supplied. 0830 _.delay = restArguments(function(func, wait, args) { 0831 return setTimeout(function() { 0832 return func.apply(null, args); 0833 }, wait); 0834 }); 0835 0836 // Defers a function, scheduling it to run after the current call stack has 0837 // cleared. 0838 _.defer = _.partial(_.delay, _, 1); 0839 0840 // Returns a function, that, when invoked, will only be triggered at most once 0841 // during a given window of time. Normally, the throttled function will run 0842 // as much as it can, without ever going more than once per `wait` duration; 0843 // but if you'd like to disable the execution on the leading edge, pass 0844 // `{leading: false}`. To disable execution on the trailing edge, ditto. 0845 _.throttle = function(func, wait, options) { 0846 var timeout, context, args, result; 0847 var previous = 0; 0848 if (!options) options = {}; 0849 0850 var later = function() { 0851 previous = options.leading === false ? 0 : _.now(); 0852 timeout = null; 0853 result = func.apply(context, args); 0854 if (!timeout) context = args = null; 0855 }; 0856 0857 var throttled = function() { 0858 var now = _.now(); 0859 if (!previous && options.leading === false) previous = now; 0860 var remaining = wait - (now - previous); 0861 context = this; 0862 args = arguments; 0863 if (remaining <= 0 || remaining > wait) { 0864 if (timeout) { 0865 clearTimeout(timeout); 0866 timeout = null; 0867 } 0868 previous = now; 0869 result = func.apply(context, args); 0870 if (!timeout) context = args = null; 0871 } else if (!timeout && options.trailing !== false) { 0872 timeout = setTimeout(later, remaining); 0873 } 0874 return result; 0875 }; 0876 0877 throttled.cancel = function() { 0878 clearTimeout(timeout); 0879 previous = 0; 0880 timeout = context = args = null; 0881 }; 0882 0883 return throttled; 0884 }; 0885 0886 // Returns a function, that, as long as it continues to be invoked, will not 0887 // be triggered. The function will be called after it stops being called for 0888 // N milliseconds. If `immediate` is passed, trigger the function on the 0889 // leading edge, instead of the trailing. 0890 _.debounce = function(func, wait, immediate) { 0891 var timeout, result; 0892 0893 var later = function(context, args) { 0894 timeout = null; 0895 if (args) result = func.apply(context, args); 0896 }; 0897 0898 var debounced = restArguments(function(args) { 0899 if (timeout) clearTimeout(timeout); 0900 if (immediate) { 0901 var callNow = !timeout; 0902 timeout = setTimeout(later, wait); 0903 if (callNow) result = func.apply(this, args); 0904 } else { 0905 timeout = _.delay(later, wait, this, args); 0906 } 0907 0908 return result; 0909 }); 0910 0911 debounced.cancel = function() { 0912 clearTimeout(timeout); 0913 timeout = null; 0914 }; 0915 0916 return debounced; 0917 }; 0918 0919 // Returns the first function passed as an argument to the second, 0920 // allowing you to adjust arguments, run code before and after, and 0921 // conditionally execute the original function. 0922 _.wrap = function(func, wrapper) { 0923 return _.partial(wrapper, func); 0924 }; 0925 0926 // Returns a negated version of the passed-in predicate. 0927 _.negate = function(predicate) { 0928 return function() { 0929 return !predicate.apply(this, arguments); 0930 }; 0931 }; 0932 0933 // Returns a function that is the composition of a list of functions, each 0934 // consuming the return value of the function that follows. 0935 _.compose = function() { 0936 var args = arguments; 0937 var start = args.length - 1; 0938 return function() { 0939 var i = start; 0940 var result = args[start].apply(this, arguments); 0941 while (i--) result = args[i].call(this, result); 0942 return result; 0943 }; 0944 }; 0945 0946 // Returns a function that will only be executed on and after the Nth call. 0947 _.after = function(times, func) { 0948 return function() { 0949 if (--times < 1) { 0950 return func.apply(this, arguments); 0951 } 0952 }; 0953 }; 0954 0955 // Returns a function that will only be executed up to (but not including) the Nth call. 0956 _.before = function(times, func) { 0957 var memo; 0958 return function() { 0959 if (--times > 0) { 0960 memo = func.apply(this, arguments); 0961 } 0962 if (times <= 1) func = null; 0963 return memo; 0964 }; 0965 }; 0966 0967 // Returns a function that will be executed at most one time, no matter how 0968 // often you call it. Useful for lazy initialization. 0969 _.once = _.partial(_.before, 2); 0970 0971 _.restArguments = restArguments; 0972 0973 // Object Functions 0974 // ---------------- 0975 0976 // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. 0977 var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); 0978 var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', 0979 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; 0980 0981 var collectNonEnumProps = function(obj, keys) { 0982 var nonEnumIdx = nonEnumerableProps.length; 0983 var constructor = obj.constructor; 0984 var proto = _.isFunction(constructor) && constructor.prototype || ObjProto; 0985 0986 // Constructor is a special case. 0987 var prop = 'constructor'; 0988 if (has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); 0989 0990 while (nonEnumIdx--) { 0991 prop = nonEnumerableProps[nonEnumIdx]; 0992 if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { 0993 keys.push(prop); 0994 } 0995 } 0996 }; 0997 0998 // Retrieve the names of an object's own properties. 0999 // Delegates to **ECMAScript 5**'s native `Object.keys`. 1000 _.keys = function(obj) { 1001 if (!_.isObject(obj)) return []; 1002 if (nativeKeys) return nativeKeys(obj); 1003 var keys = []; 1004 for (var key in obj) if (has(obj, key)) keys.push(key); 1005 // Ahem, IE < 9. 1006 if (hasEnumBug) collectNonEnumProps(obj, keys); 1007 return keys; 1008 }; 1009 1010 // Retrieve all the property names of an object. 1011 _.allKeys = function(obj) { 1012 if (!_.isObject(obj)) return []; 1013 var keys = []; 1014 for (var key in obj) keys.push(key); 1015 // Ahem, IE < 9. 1016 if (hasEnumBug) collectNonEnumProps(obj, keys); 1017 return keys; 1018 }; 1019 1020 // Retrieve the values of an object's properties. 1021 _.values = function(obj) { 1022 var keys = _.keys(obj); 1023 var length = keys.length; 1024 var values = Array(length); 1025 for (var i = 0; i < length; i++) { 1026 values[i] = obj[keys[i]]; 1027 } 1028 return values; 1029 }; 1030 1031 // Returns the results of applying the iteratee to each element of the object. 1032 // In contrast to _.map it returns an object. 1033 _.mapObject = function(obj, iteratee, context) { 1034 iteratee = cb(iteratee, context); 1035 var keys = _.keys(obj), 1036 length = keys.length, 1037 results = {}; 1038 for (var index = 0; index < length; index++) { 1039 var currentKey = keys[index]; 1040 results[currentKey] = iteratee(obj[currentKey], currentKey, obj); 1041 } 1042 return results; 1043 }; 1044 1045 // Convert an object into a list of `[key, value]` pairs. 1046 // The opposite of _.object. 1047 _.pairs = function(obj) { 1048 var keys = _.keys(obj); 1049 var length = keys.length; 1050 var pairs = Array(length); 1051 for (var i = 0; i < length; i++) { 1052 pairs[i] = [keys[i], obj[keys[i]]]; 1053 } 1054 return pairs; 1055 }; 1056 1057 // Invert the keys and values of an object. The values must be serializable. 1058 _.invert = function(obj) { 1059 var result = {}; 1060 var keys = _.keys(obj); 1061 for (var i = 0, length = keys.length; i < length; i++) { 1062 result[obj[keys[i]]] = keys[i]; 1063 } 1064 return result; 1065 }; 1066 1067 // Return a sorted list of the function names available on the object. 1068 // Aliased as `methods`. 1069 _.functions = _.methods = function(obj) { 1070 var names = []; 1071 for (var key in obj) { 1072 if (_.isFunction(obj[key])) names.push(key); 1073 } 1074 return names.sort(); 1075 }; 1076 1077 // An internal function for creating assigner functions. 1078 var createAssigner = function(keysFunc, defaults) { 1079 return function(obj) { 1080 var length = arguments.length; 1081 if (defaults) obj = Object(obj); 1082 if (length < 2 || obj == null) return obj; 1083 for (var index = 1; index < length; index++) { 1084 var source = arguments[index], 1085 keys = keysFunc(source), 1086 l = keys.length; 1087 for (var i = 0; i < l; i++) { 1088 var key = keys[i]; 1089 if (!defaults || obj[key] === void 0) obj[key] = source[key]; 1090 } 1091 } 1092 return obj; 1093 }; 1094 }; 1095 1096 // Extend a given object with all the properties in passed-in object(s). 1097 _.extend = createAssigner(_.allKeys); 1098 1099 // Assigns a given object with all the own properties in the passed-in object(s). 1100 // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) 1101 _.extendOwn = _.assign = createAssigner(_.keys); 1102 1103 // Returns the first key on an object that passes a predicate test. 1104 _.findKey = function(obj, predicate, context) { 1105 predicate = cb(predicate, context); 1106 var keys = _.keys(obj), key; 1107 for (var i = 0, length = keys.length; i < length; i++) { 1108 key = keys[i]; 1109 if (predicate(obj[key], key, obj)) return key; 1110 } 1111 }; 1112 1113 // Internal pick helper function to determine if `obj` has key `key`. 1114 var keyInObj = function(value, key, obj) { 1115 return key in obj; 1116 }; 1117 1118 // Return a copy of the object only containing the whitelisted properties. 1119 _.pick = restArguments(function(obj, keys) { 1120 var result = {}, iteratee = keys[0]; 1121 if (obj == null) return result; 1122 if (_.isFunction(iteratee)) { 1123 if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]); 1124 keys = _.allKeys(obj); 1125 } else { 1126 iteratee = keyInObj; 1127 keys = flatten(keys, false, false); 1128 obj = Object(obj); 1129 } 1130 for (var i = 0, length = keys.length; i < length; i++) { 1131 var key = keys[i]; 1132 var value = obj[key]; 1133 if (iteratee(value, key, obj)) result[key] = value; 1134 } 1135 return result; 1136 }); 1137 1138 // Return a copy of the object without the blacklisted properties. 1139 _.omit = restArguments(function(obj, keys) { 1140 var iteratee = keys[0], context; 1141 if (_.isFunction(iteratee)) { 1142 iteratee = _.negate(iteratee); 1143 if (keys.length > 1) context = keys[1]; 1144 } else { 1145 keys = _.map(flatten(keys, false, false), String); 1146 iteratee = function(value, key) { 1147 return !_.contains(keys, key); 1148 }; 1149 } 1150 return _.pick(obj, iteratee, context); 1151 }); 1152 1153 // Fill in a given object with default properties. 1154 _.defaults = createAssigner(_.allKeys, true); 1155 1156 // Creates an object that inherits from the given prototype object. 1157 // If additional properties are provided then they will be added to the 1158 // created object. 1159 _.create = function(prototype, props) { 1160 var result = baseCreate(prototype); 1161 if (props) _.extendOwn(result, props); 1162 return result; 1163 }; 1164 1165 // Create a (shallow-cloned) duplicate of an object. 1166 _.clone = function(obj) { 1167 if (!_.isObject(obj)) return obj; 1168 return _.isArray(obj) ? obj.slice() : _.extend({}, obj); 1169 }; 1170 1171 // Invokes interceptor with the obj, and then returns obj. 1172 // The primary purpose of this method is to "tap into" a method chain, in 1173 // order to perform operations on intermediate results within the chain. 1174 _.tap = function(obj, interceptor) { 1175 interceptor(obj); 1176 return obj; 1177 }; 1178 1179 // Returns whether an object has a given set of `key:value` pairs. 1180 _.isMatch = function(object, attrs) { 1181 var keys = _.keys(attrs), length = keys.length; 1182 if (object == null) return !length; 1183 var obj = Object(object); 1184 for (var i = 0; i < length; i++) { 1185 var key = keys[i]; 1186 if (attrs[key] !== obj[key] || !(key in obj)) return false; 1187 } 1188 return true; 1189 }; 1190 1191 1192 // Internal recursive comparison function for `isEqual`. 1193 var eq, deepEq; 1194 eq = function(a, b, aStack, bStack) { 1195 // Identical objects are equal. `0 === -0`, but they aren't identical. 1196 // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). 1197 if (a === b) return a !== 0 || 1 / a === 1 / b; 1198 // `null` or `undefined` only equal to itself (strict comparison). 1199 if (a == null || b == null) return false; 1200 // `NaN`s are equivalent, but non-reflexive. 1201 if (a !== a) return b !== b; 1202 // Exhaust primitive checks 1203 var type = typeof a; 1204 if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; 1205 return deepEq(a, b, aStack, bStack); 1206 }; 1207 1208 // Internal recursive comparison function for `isEqual`. 1209 deepEq = function(a, b, aStack, bStack) { 1210 // Unwrap any wrapped objects. 1211 if (a instanceof _) a = a._wrapped; 1212 if (b instanceof _) b = b._wrapped; 1213 // Compare `[[Class]]` names. 1214 var className = toString.call(a); 1215 if (className !== toString.call(b)) return false; 1216 switch (className) { 1217 // Strings, numbers, regular expressions, dates, and booleans are compared by value. 1218 case '[object RegExp]': 1219 // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') 1220 case '[object String]': 1221 // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is 1222 // equivalent to `new String("5")`. 1223 return '' + a === '' + b; 1224 case '[object Number]': 1225 // `NaN`s are equivalent, but non-reflexive. 1226 // Object(NaN) is equivalent to NaN. 1227 if (+a !== +a) return +b !== +b; 1228 // An `egal` comparison is performed for other numeric values. 1229 return +a === 0 ? 1 / +a === 1 / b : +a === +b; 1230 case '[object Date]': 1231 case '[object Boolean]': 1232 // Coerce dates and booleans to numeric primitive values. Dates are compared by their 1233 // millisecond representations. Note that invalid dates with millisecond representations 1234 // of `NaN` are not equivalent. 1235 return +a === +b; 1236 case '[object Symbol]': 1237 return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); 1238 } 1239 1240 var areArrays = className === '[object Array]'; 1241 if (!areArrays) { 1242 if (typeof a != 'object' || typeof b != 'object') return false; 1243 1244 // Objects with different constructors are not equivalent, but `Object`s or `Array`s 1245 // from different frames are. 1246 var aCtor = a.constructor, bCtor = b.constructor; 1247 if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && 1248 _.isFunction(bCtor) && bCtor instanceof bCtor) 1249 && ('constructor' in a && 'constructor' in b)) { 1250 return false; 1251 } 1252 } 1253 // Assume equality for cyclic structures. The algorithm for detecting cyclic 1254 // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. 1255 1256 // Initializing stack of traversed objects. 1257 // It's done here since we only need them for objects and arrays comparison. 1258 aStack = aStack || []; 1259 bStack = bStack || []; 1260 var length = aStack.length; 1261 while (length--) { 1262 // Linear search. Performance is inversely proportional to the number of 1263 // unique nested structures. 1264 if (aStack[length] === a) return bStack[length] === b; 1265 } 1266 1267 // Add the first object to the stack of traversed objects. 1268 aStack.push(a); 1269 bStack.push(b); 1270 1271 // Recursively compare objects and arrays. 1272 if (areArrays) { 1273 // Compare array lengths to determine if a deep comparison is necessary. 1274 length = a.length; 1275 if (length !== b.length) return false; 1276 // Deep compare the contents, ignoring non-numeric properties. 1277 while (length--) { 1278 if (!eq(a[length], b[length], aStack, bStack)) return false; 1279 } 1280 } else { 1281 // Deep compare objects. 1282 var keys = _.keys(a), key; 1283 length = keys.length; 1284 // Ensure that both objects contain the same number of properties before comparing deep equality. 1285 if (_.keys(b).length !== length) return false; 1286 while (length--) { 1287 // Deep compare each member 1288 key = keys[length]; 1289 if (!(has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; 1290 } 1291 } 1292 // Remove the first object from the stack of traversed objects. 1293 aStack.pop(); 1294 bStack.pop(); 1295 return true; 1296 }; 1297 1298 // Perform a deep comparison to check if two objects are equal. 1299 _.isEqual = function(a, b) { 1300 return eq(a, b); 1301 }; 1302 1303 // Is a given array, string, or object empty? 1304 // An "empty" object has no enumerable own-properties. 1305 _.isEmpty = function(obj) { 1306 if (obj == null) return true; 1307 if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; 1308 return _.keys(obj).length === 0; 1309 }; 1310 1311 // Is a given value a DOM element? 1312 _.isElement = function(obj) { 1313 return !!(obj && obj.nodeType === 1); 1314 }; 1315 1316 // Is a given value an array? 1317 // Delegates to ECMA5's native Array.isArray 1318 _.isArray = nativeIsArray || function(obj) { 1319 return toString.call(obj) === '[object Array]'; 1320 }; 1321 1322 // Is a given variable an object? 1323 _.isObject = function(obj) { 1324 var type = typeof obj; 1325 return type === 'function' || type === 'object' && !!obj; 1326 }; 1327 1328 // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError, isMap, isWeakMap, isSet, isWeakSet. 1329 _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error', 'Symbol', 'Map', 'WeakMap', 'Set', 'WeakSet'], function(name) { 1330 _['is' + name] = function(obj) { 1331 return toString.call(obj) === '[object ' + name + ']'; 1332 }; 1333 }); 1334 1335 // Define a fallback version of the method in browsers (ahem, IE < 9), where 1336 // there isn't any inspectable "Arguments" type. 1337 if (!_.isArguments(arguments)) { 1338 _.isArguments = function(obj) { 1339 return has(obj, 'callee'); 1340 }; 1341 } 1342 1343 // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, 1344 // IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236). 1345 var nodelist = root.document && root.document.childNodes; 1346 if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') { 1347 _.isFunction = function(obj) { 1348 return typeof obj == 'function' || false; 1349 }; 1350 } 1351 1352 // Is a given object a finite number? 1353 _.isFinite = function(obj) { 1354 return !_.isSymbol(obj) && isFinite(obj) && !isNaN(parseFloat(obj)); 1355 }; 1356 1357 // Is the given value `NaN`? 1358 _.isNaN = function(obj) { 1359 return _.isNumber(obj) && isNaN(obj); 1360 }; 1361 1362 // Is a given value a boolean? 1363 _.isBoolean = function(obj) { 1364 return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; 1365 }; 1366 1367 // Is a given value equal to null? 1368 _.isNull = function(obj) { 1369 return obj === null; 1370 }; 1371 1372 // Is a given variable undefined? 1373 _.isUndefined = function(obj) { 1374 return obj === void 0; 1375 }; 1376 1377 // Shortcut function for checking if an object has a given property directly 1378 // on itself (in other words, not on a prototype). 1379 _.has = function(obj, path) { 1380 if (!_.isArray(path)) { 1381 return has(obj, path); 1382 } 1383 var length = path.length; 1384 for (var i = 0; i < length; i++) { 1385 var key = path[i]; 1386 if (obj == null || !hasOwnProperty.call(obj, key)) { 1387 return false; 1388 } 1389 obj = obj[key]; 1390 } 1391 return !!length; 1392 }; 1393 1394 // Utility Functions 1395 // ----------------- 1396 1397 // Run Underscore.js in *noConflict* mode, returning the `_` variable to its 1398 // previous owner. Returns a reference to the Underscore object. 1399 _.noConflict = function() { 1400 root._ = previousUnderscore; 1401 return this; 1402 }; 1403 1404 // Keep the identity function around for default iteratees. 1405 _.identity = function(value) { 1406 return value; 1407 }; 1408 1409 // Predicate-generating functions. Often useful outside of Underscore. 1410 _.constant = function(value) { 1411 return function() { 1412 return value; 1413 }; 1414 }; 1415 1416 _.noop = function(){}; 1417 1418 // Creates a function that, when passed an object, will traverse that object’s 1419 // properties down the given `path`, specified as an array of keys or indexes. 1420 _.property = function(path) { 1421 if (!_.isArray(path)) { 1422 return shallowProperty(path); 1423 } 1424 return function(obj) { 1425 return deepGet(obj, path); 1426 }; 1427 }; 1428 1429 // Generates a function for a given object that returns a given property. 1430 _.propertyOf = function(obj) { 1431 if (obj == null) { 1432 return function(){}; 1433 } 1434 return function(path) { 1435 return !_.isArray(path) ? obj[path] : deepGet(obj, path); 1436 }; 1437 }; 1438 1439 // Returns a predicate for checking whether an object has a given set of 1440 // `key:value` pairs. 1441 _.matcher = _.matches = function(attrs) { 1442 attrs = _.extendOwn({}, attrs); 1443 return function(obj) { 1444 return _.isMatch(obj, attrs); 1445 }; 1446 }; 1447 1448 // Run a function **n** times. 1449 _.times = function(n, iteratee, context) { 1450 var accum = Array(Math.max(0, n)); 1451 iteratee = optimizeCb(iteratee, context, 1); 1452 for (var i = 0; i < n; i++) accum[i] = iteratee(i); 1453 return accum; 1454 }; 1455 1456 // Return a random integer between min and max (inclusive). 1457 _.random = function(min, max) { 1458 if (max == null) { 1459 max = min; 1460 min = 0; 1461 } 1462 return min + Math.floor(Math.random() * (max - min + 1)); 1463 }; 1464 1465 // A (possibly faster) way to get the current timestamp as an integer. 1466 _.now = Date.now || function() { 1467 return new Date().getTime(); 1468 }; 1469 1470 // List of HTML entities for escaping. 1471 var escapeMap = { 1472 '&': '&', 1473 '<': '<', 1474 '>': '>', 1475 '"': '"', 1476 "'": ''', 1477 '`': '`' 1478 }; 1479 var unescapeMap = _.invert(escapeMap); 1480 1481 // Functions for escaping and unescaping strings to/from HTML interpolation. 1482 var createEscaper = function(map) { 1483 var escaper = function(match) { 1484 return map[match]; 1485 }; 1486 // Regexes for identifying a key that needs to be escaped. 1487 var source = '(?:' + _.keys(map).join('|') + ')'; 1488 var testRegexp = RegExp(source); 1489 var replaceRegexp = RegExp(source, 'g'); 1490 return function(string) { 1491 string = string == null ? '' : '' + string; 1492 return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; 1493 }; 1494 }; 1495 _.escape = createEscaper(escapeMap); 1496 _.unescape = createEscaper(unescapeMap); 1497 1498 // Traverses the children of `obj` along `path`. If a child is a function, it 1499 // is invoked with its parent as context. Returns the value of the final 1500 // child, or `fallback` if any child is undefined. 1501 _.result = function(obj, path, fallback) { 1502 if (!_.isArray(path)) path = [path]; 1503 var length = path.length; 1504 if (!length) { 1505 return _.isFunction(fallback) ? fallback.call(obj) : fallback; 1506 } 1507 for (var i = 0; i < length; i++) { 1508 var prop = obj == null ? void 0 : obj[path[i]]; 1509 if (prop === void 0) { 1510 prop = fallback; 1511 i = length; // Ensure we don't continue iterating. 1512 } 1513 obj = _.isFunction(prop) ? prop.call(obj) : prop; 1514 } 1515 return obj; 1516 }; 1517 1518 // Generate a unique integer id (unique within the entire client session). 1519 // Useful for temporary DOM ids. 1520 var idCounter = 0; 1521 _.uniqueId = function(prefix) { 1522 var id = ++idCounter + ''; 1523 return prefix ? prefix + id : id; 1524 }; 1525 1526 // By default, Underscore uses ERB-style template delimiters, change the 1527 // following template settings to use alternative delimiters. 1528 _.templateSettings = { 1529 evaluate: /<%([\s\S]+?)%>/g, 1530 interpolate: /<%=([\s\S]+?)%>/g, 1531 escape: /<%-([\s\S]+?)%>/g 1532 }; 1533 1534 // When customizing `templateSettings`, if you don't want to define an 1535 // interpolation, evaluation or escaping regex, we need one that is 1536 // guaranteed not to match. 1537 var noMatch = /(.)^/; 1538 1539 // Certain characters need to be escaped so that they can be put into a 1540 // string literal. 1541 var escapes = { 1542 "'": "'", 1543 '\\': '\\', 1544 '\r': 'r', 1545 '\n': 'n', 1546 '\u2028': 'u2028', 1547 '\u2029': 'u2029' 1548 }; 1549 1550 var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g; 1551 1552 var escapeChar = function(match) { 1553 return '\\' + escapes[match]; 1554 }; 1555 1556 // JavaScript micro-templating, similar to John Resig's implementation. 1557 // Underscore templating handles arbitrary delimiters, preserves whitespace, 1558 // and correctly escapes quotes within interpolated code. 1559 // NB: `oldSettings` only exists for backwards compatibility. 1560 _.template = function(text, settings, oldSettings) { 1561 if (!settings && oldSettings) settings = oldSettings; 1562 settings = _.defaults({}, settings, _.templateSettings); 1563 1564 // Combine delimiters into one regular expression via alternation. 1565 var matcher = RegExp([ 1566 (settings.escape || noMatch).source, 1567 (settings.interpolate || noMatch).source, 1568 (settings.evaluate || noMatch).source 1569 ].join('|') + '|$', 'g'); 1570 1571 // Compile the template source, escaping string literals appropriately. 1572 var index = 0; 1573 var source = "__p+='"; 1574 text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { 1575 source += text.slice(index, offset).replace(escapeRegExp, escapeChar); 1576 index = offset + match.length; 1577 1578 if (escape) { 1579 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; 1580 } else if (interpolate) { 1581 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; 1582 } else if (evaluate) { 1583 source += "';\n" + evaluate + "\n__p+='"; 1584 } 1585 1586 // Adobe VMs need the match returned to produce the correct offset. 1587 return match; 1588 }); 1589 source += "';\n"; 1590 1591 // If a variable is not specified, place data values in local scope. 1592 if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; 1593 1594 source = "var __t,__p='',__j=Array.prototype.join," + 1595 "print=function(){__p+=__j.call(arguments,'');};\n" + 1596 source + 'return __p;\n'; 1597 1598 var render; 1599 try { 1600 render = new Function(settings.variable || 'obj', '_', source); 1601 } catch (e) { 1602 e.source = source; 1603 throw e; 1604 } 1605 1606 var template = function(data) { 1607 return render.call(this, data, _); 1608 }; 1609 1610 // Provide the compiled source as a convenience for precompilation. 1611 var argument = settings.variable || 'obj'; 1612 template.source = 'function(' + argument + '){\n' + source + '}'; 1613 1614 return template; 1615 }; 1616 1617 // Add a "chain" function. Start chaining a wrapped Underscore object. 1618 _.chain = function(obj) { 1619 var instance = _(obj); 1620 instance._chain = true; 1621 return instance; 1622 }; 1623 1624 // OOP 1625 // --------------- 1626 // If Underscore is called as a function, it returns a wrapped object that 1627 // can be used OO-style. This wrapper holds altered versions of all the 1628 // underscore functions. Wrapped objects may be chained. 1629 1630 // Helper function to continue chaining intermediate results. 1631 var chainResult = function(instance, obj) { 1632 return instance._chain ? _(obj).chain() : obj; 1633 }; 1634 1635 // Add your own custom functions to the Underscore object. 1636 _.mixin = function(obj) { 1637 _.each(_.functions(obj), function(name) { 1638 var func = _[name] = obj[name]; 1639 _.prototype[name] = function() { 1640 var args = [this._wrapped]; 1641 push.apply(args, arguments); 1642 return chainResult(this, func.apply(_, args)); 1643 }; 1644 }); 1645 return _; 1646 }; 1647 1648 // Add all of the Underscore functions to the wrapper object. 1649 _.mixin(_); 1650 1651 // Add all mutator Array functions to the wrapper. 1652 _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { 1653 var method = ArrayProto[name]; 1654 _.prototype[name] = function() { 1655 var obj = this._wrapped; 1656 method.apply(obj, arguments); 1657 if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; 1658 return chainResult(this, obj); 1659 }; 1660 }); 1661 1662 // Add all accessor Array functions to the wrapper. 1663 _.each(['concat', 'join', 'slice'], function(name) { 1664 var method = ArrayProto[name]; 1665 _.prototype[name] = function() { 1666 return chainResult(this, method.apply(this._wrapped, arguments)); 1667 }; 1668 }); 1669 1670 // Extracts the result from a wrapped and chained object. 1671 _.prototype.value = function() { 1672 return this._wrapped; 1673 }; 1674 1675 // Provide unwrapping proxy for some methods used in engine operations 1676 // such as arithmetic and JSON stringification. 1677 _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; 1678 1679 _.prototype.toString = function() { 1680 return String(this._wrapped); 1681 }; 1682 1683 // AMD registration happens at the end for compatibility with AMD loaders 1684 // that may not enforce next-turn semantics on modules. Even though general 1685 // practice for AMD registration is to be anonymous, underscore registers 1686 // as a named module because, like jQuery, it is a base library that is 1687 // popular enough to be bundled in a third party lib, but not be part of 1688 // an AMD load request. Those cases could generate an error when an 1689 // anonymous define() is called outside of a loader request. 1690 if (typeof define == 'function' && define.amd) { 1691 define('underscore', [], function() { 1692 return _; 1693 }); 1694 } 1695 }());