vendor: 16,669 bytes, lines 1-475
1// Underscore.js 1.8.2 2// http://underscorejs.org 3// (c) 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors 4// Underscore may be freely distributed under the MIT license. 5 6(function() { 7 8 // Baseline setup 9 // -------------- 10 11 // Establish the root object, `window` in the browser, or `exports` on the server. 12 var root = this; 13 14 // Save the previous value of the `_` variable. 15 var previousUnderscore = root._; 16 17 // Save bytes in the minified (but not gzipped) version: 18 var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype; 19 20 // Create quick reference variables for speed access to core prototypes. 21 var 22 push = ArrayProto.push, 23 slice = ArrayProto.slice, 24 toString = ObjProto.toString, 25 hasOwnProperty = ObjProto.hasOwnProperty; 26 27 // All **ECMAScript 5** native function implementations that we hope to use 28 // are declared here. 29 var 30 nativeIsArray = Array.isArray, 31 nativeKeys = Object.keys, 32 nativeBind = FuncProto.bind, 33 nativeCreate = Object.create; 34 35 // Naked function reference for surrogate-prototype-swapping. 36 var Ctor = function(){}; 37 38 // Create a safe reference to the Underscore object for use below. 39 var _ = function(obj) { 40 if (obj instanceof _) return obj; 41 if (!(this instanceof _)) return new _(obj); 42 this._wrapped = obj; 43 }; 44 45 // Export the Underscore object for **Node.js**, with 46 // backwards-compatibility for the old `require()` API. If we're in 47 // the browser, add `_` as a global object. 48 if (typeof exports !== 'undefined') { 49 if (typeof module !== 'undefined' && module.exports) { 50 exports = module.exports = _; 51 } 52 exports._ = _; 53 } else { 54 root._ = _; 55 } 56 57 // Current version. 58 _.VERSION = '1.8.2'; 59 60 // Internal function that returns an efficient (for current engines) version 61 // of the passed-in callback, to be repeatedly applied in other Underscore 62 // functions. 63 var optimizeCb = function(func, context, argCount) { 64 if (context === void 0) return func; 65 switch (argCount == null ? 3 : argCount) { 66 case 1: return function(value) { 67 return func.call(context, value); 68 }; 69 case 2: return function(value, other) { 70 return func.call(context, value, other); 71 }; 72 case 3: return function(value, index, collection) { 73 return func.call(context, value, index, collection); 74 }; 75 case 4: return function(accumulator, value, index, collection) { 76 return func.call(context, accumulator, value, index, collection); 77 }; 78 } 79 return function() { 80 return func.apply(context, arguments); 81 }; 82 }; 83 84 // A mostly-internal function to generate callbacks that can be applied 85 // to each element in a collection, returning the desired result â either 86 // identity, an arbitrary callback, a property matcher, or a property accessor. 87 var cb = function(value, context, argCount) { 88 if (value == null) return _.identity; 89 if (_.isFunction(value)) return optimizeCb(value, context, argCount); 90 if (_.isObject(value)) return _.matcher(value); 91 return _.property(value); 92 }; 93 _.iteratee = function(value, context) { 94 return cb(value, context, Infinity); 95 }; 96 97 // An internal function for creating assigner functions. 98 var createAssigner = function(keysFunc, undefinedOnly) { 99 return function(obj) { 100 var length = arguments.length; 101 if (length < 2 || obj == null) return obj; 102 for (var index = 1; index < length; index++) { 103 var source = arguments[index], 104 keys = keysFunc(source), 105 l = keys.length; 106 for (var i = 0; i < l; i++) { 107 var key = keys[i]; 108 if (!undefinedOnly || obj[key] === void 0) obj[key] = source[key]; 109 } 110 } 111 return obj; 112 }; 113 }; 114 115 // An internal function for creating a new object that inherits from another. 116 var baseCreate = function(prototype) { 117 if (!_.isObject(prototype)) return {}; 118 if (nativeCreate) return nativeCreate(prototype); 119 Ctor.prototype = prototype; 120 var result = new Ctor; 121 Ctor.prototype = null; 122 return result; 123 }; 124 125 // Helper for collection methods to determine whether a collection 126 // should be iterated as an array or as an object 127 // Related: http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength 128 var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1; 129 var isArrayLike = function(collection) { 130 var length = collection && collection.length; 131 return typeof length == 'number' && length >= 0 && length <= MAX_ARRAY_INDEX; 132 }; 133 134 // Collection Functions 135 // -------------------- 136 137 // The cornerstone, an `each` implementation, aka `forEach`. 138 // Handles raw objects in addition to array-likes. Treats all 139 // sparse array-likes as if they were dense. 140 _.each = _.forEach = function(obj, iteratee, context) { 141 iteratee = optimizeCb(iteratee, context); 142 var i, length; 143 if (isArrayLike(obj)) { 144 for (i = 0, length = obj.length; i < length; i++) { 145 iteratee(obj[i], i, obj); 146 } 147 } else { 148 var keys = _.keys(obj); 149 for (i = 0, length = keys.length; i < length; i++) { 150 iteratee(obj[keys[i]], keys[i], obj); 151 } 152 } 153 return obj; 154 }; 155 156 // Return the results of applying the iteratee to each element. 157 _.map = _.collect = function(obj, iteratee, context) { 158 iteratee = cb(iteratee, context); 159 var keys = !isArrayLike(obj) && _.keys(obj), 160 length = (keys || obj).length, 161 results = Array(length); 162 for (var index = 0; index < length; index++) { 163 var currentKey = keys ? keys[index] : index; 164 results[index] = iteratee(obj[currentKey], currentKey, obj); 165 } 166 return results; 167 }; 168 169 // Create a reducing function iterating left or right. 170 function createReduce(dir) { 171 // Optimized iterator function as using arguments.length 172 // in the main function will deoptimize the, see #1991. 173 function iterator(obj, iteratee, memo, keys, index, length) { 174 for (; index >= 0 && index < length; index += dir) { 175 var currentKey = keys ? keys[index] : index; 176 memo = iteratee(memo, obj[currentKey], currentKey, obj); 177 } 178 return memo; 179 } 180 181 return function(obj, iteratee, memo, context) { 182 iteratee = optimizeCb(iteratee, context, 4); 183 var keys = !isArrayLike(obj) && _.keys(obj), 184 length = (keys || obj).length, 185 index = dir > 0 ? 0 : length - 1; 186 // Determine the initial value if none is provided. 187 if (arguments.length < 3) { 188 memo = obj[keys ? keys[index] : index]; 189 index += dir; 190 } 191 return iterator(obj, iteratee, memo, keys, index, length); 192 }; 193 } 194 195 // **Reduce** builds up a single result from a list of values, aka `inject`, 196 // or `foldl`. 197 _.reduce = _.foldl = _.inject = createReduce(1); 198 199 // The right-associative version of reduce, also known as `foldr`. 200 _.reduceRight = _.foldr = createReduce(-1); 201 202 // Return the first value which passes a truth test. Aliased as `detect`. 203 _.find = _.detect = function(obj, predicate, context) { 204 var key; 205 if (isArrayLike(obj)) { 206 key = _.findIndex(obj, predicate, context); 207 } else { 208 key = _.findKey(obj, predicate, context); 209 } 210 if (key !== void 0 && key !== -1) return obj[key]; 211 }; 212 213 // Return all the elements that pass a truth test. 214 // Aliased as `select`. 215 _.filter = _.select = function(obj, predicate, context) { 216 var results = []; 217 predicate = cb(predicate, context); 218 _.each(obj, function(value, index, list) { 219 if (predicate(value, index, list)) results.push(value); 220 }); 221 return results; 222 }; 223 224 // Return all the elements for which a truth test fails. 225 _.reject = function(obj, predicate, context) { 226 return _.filter(obj, _.negate(cb(predicate)), context); 227 }; 228 229 // Determine whether all of the elements match a truth test. 230 // Aliased as `all`. 231 _.every = _.all = function(obj, predicate, context) { 232 predicate = cb(predicate, context); 233 var keys = !isArrayLike(obj) && _.keys(obj), 234 length = (keys || obj).length; 235 for (var index = 0; index < length; index++) { 236 var currentKey = keys ? keys[index] : index; 237 if (!predicate(obj[currentKey], currentKey, obj)) return false; 238 } 239 return true; 240 }; 241 242 // Determine if at least one element in the object matches a truth test. 243 // Aliased as `any`. 244 _.some = _.any = function(obj, predicate, context) { 245 predicate = cb(predicate, context); 246 var keys = !isArrayLike(obj) && _.keys(obj), 247 length = (keys || obj).length; 248 for (var index = 0; index < length; index++) { 249 var currentKey = keys ? keys[index] : index; 250 if (predicate(obj[currentKey], currentKey, obj)) return true; 251 } 252 return false; 253 }; 254 255 // Determine if the array or object contains a given value (using `===`). 256 // Aliased as `includes` and `include`. 257 _.contains = _.includes = _.include = function(obj, target, fromIndex) { 258 if (!isArrayLike(obj)) obj = _.values(obj); 259 return _.indexOf(obj, target, typeof fromIndex == 'number' && fromIndex) >= 0; 260 }; 261 262 // Invoke a method (with arguments) on every item in a collection. 263 _.invoke = function(obj, method) { 264 var args = slice.call(arguments, 2); 265 var isFunc = _.isFunction(method); 266 return _.map(obj, function(value) { 267 var func = isFunc ? method : value[method]; 268 return func == null ? func : func.apply(value, args); 269 }); 270 }; 271 272 // Convenience version of a common use case of `map`: fetching a property. 273 _.pluck = function(obj, key) { 274 return _.map(obj, _.property(key)); 275 }; 276 277 // Convenience version of a common use case of `filter`: selecting only objects 278 // containing specific `key:value` pairs. 279 _.where = function(obj, attrs) { 280 return _.filter(obj, _.matcher(attrs)); 281 }; 282 283 // Convenience version of a common use case of `find`: getting the first object 284 // containing specific `key:value` pairs. 285 _.findWhere = function(obj, attrs) { 286 return _.find(obj, _.matcher(attrs)); 287 }; 288 289 // Return the maximum element (or element-based computation). 290 _.max = function(obj, iteratee, context) { 291 var result = -Infinity, lastComputed = -Infinity, 292 value, computed; 293 if (iteratee == null && obj != null) { 294 obj = isArrayLike(obj) ? obj : _.values(obj); 295 for (var i = 0, length = obj.length; i < length; i++) { 296 value = obj[i]; 297 if (value > result) { 298 result = value; 299 } 300 } 301 } else { 302 iteratee = cb(iteratee, context); 303 _.each(obj, function(value, index, list) { 304 computed = iteratee(value, index, list); 305 if (computed > lastComputed || computed === -Infinity && result === -Infinity) { 306 result = value; 307 lastComputed = computed; 308 } 309 }); 310 } 311 return result; 312 }; 313 314 // Return the minimum element (or element-based computation). 315 _.min = function(obj, iteratee, context) { 316 var result = Infinity, lastComputed = Infinity, 317 value, computed; 318 if (iteratee == null && obj != null) { 319 obj = isArrayLike(obj) ? obj : _.values(obj); 320 for (var i = 0, length = obj.length; i < length; i++) { 321 value = obj[i]; 322 if (value < result) { 323 result = value; 324 } 325 } 326 } else { 327 iteratee = cb(iteratee, context); 328 _.each(obj, function(value, index, list) { 329 computed = iteratee(value, index, list); 330 if (computed < lastComputed || computed === Infinity && result === Infinity) { 331 result = value; 332 lastComputed = computed; 333 } 334 }); 335 } 336 return result; 337 }; 338 339 // Shuffle a collection, using the modern version of the 340 // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/FisherâYates_shuffle). 341 _.shuffle = function(obj) { 342 var set = isArrayLike(obj) ? obj : _.values(obj); 343 var length = set.length; 344 var shuffled = Array(length); 345 for (var index = 0, rand; index < length; index++) { 346 rand = _.random(0, index); 347 if (rand !== index) shuffled[index] = shuffled[rand]; 348 shuffled[rand] = set[index]; 349 } 350 return shuffled; 351 }; 352 353 // Sample **n** random values from a collection. 354 // If **n** is not specified, returns a single random element. 355 // The internal `guard` argument allows it to work with `map`. 356 _.sample = function(obj, n, guard) { 357 if (n == null || guard) { 358 if (!isArrayLike(obj)) obj = _.values(obj); 359 return obj[_.random(obj.length - 1)]; 360 } 361 return _.shuffle(obj).slice(0, Math.max(0, n)); 362 }; 363 364 // Sort the object's values by a criterion produced by an iteratee. 365 _.sortBy = function(obj, iteratee, context) { 366 iteratee = cb(iteratee, context); 367 return _.pluck(_.map(obj, function(value, index, list) { 368 return { 369 value: value, 370 index: index, 371 criteria: iteratee(value, index, list) 372 }; 373 }).sort(function(left, right) { 374 var a = left.criteria; 375 var b = right.criteria; 376 if (a !== b) { 377 if (a > b || a === void 0) return 1; 378 if (a < b || b === void 0) return -1; 379 } 380 return left.index - right.index; 381 }), 'value'); 382 }; 383 384 // An internal function used for aggregate "group by" operations. 385 var group = function(behavior) { 386 return function(obj, iteratee, context) { 387 var result = {}; 388 iteratee = cb(iteratee, context); 389 _.each(obj, function(value, index) { 390 var key = iteratee(value, index, obj); 391 behavior(result, value, key); 392 }); 393 return result; 394 }; 395 }; 396 397 // Groups the object's values by a criterion. Pass either a string attribute 398 // to group by, or a function that returns the criterion. 399 _.groupBy = group(function(result, value, key) { 400 if (_.has(result, key)) result[key].push(value); else result[key] = [value]; 401 }); 402 403 // Indexes the object's values by a criterion, similar to `groupBy`, but for 404 // when you know that your index values will be unique. 405 _.indexBy = group(function(result, value, key) { 406 result[key] = value; 407 }); 408 409 // Counts instances of an object that group by a certain criterion. Pass 410 // either a string attribute to count by, or a function that returns the 411 // criterion. 412 _.countBy = group(function(result, value, key) { 413 if (_.has(result, key)) result[key]++; else result[key] = 1; 414 }); 415 416 // Safely create a real, live array from anything iterable. 417 _.toArray = function(obj) { 418 if (!obj) return []; 419 if (_.isArray(obj)) return slice.call(obj); 420 if (isArrayLike(obj)) return _.map(obj, _.identity); 421 return _.values(obj); 422 }; 423 424 // Return the number of elements in an object. 425 _.size = function(obj) { 426 if (obj == null) return 0; 427 return isArrayLike(obj) ? obj.length : _.keys(obj).length; 428 }; 429 430 // Split a collection into two arrays: one whose elements all satisfy the given 431 // predicate, and one whose elements all do not satisfy the predicate. 432 _.partition = function(obj, predicate, context) { 433 predicate = cb(predicate, context); 434 var pass = [], fail = []; 435 _.each(obj, function(value, key, obj) { 436 (predicate(value, key, obj) ? pass : fail).push(value); 437 }); 438 return [pass, fail]; 439 }; 440 441 // Array Functions 442 // --------------- 443 444 // Get the first element of an array. Passing **n** will return the first N 445 // values in the array. Aliased as `head` and `take`. The **guard** check 446 // allows it to work with `_.map`. 447 _.first = _.head = _.take = function(array, n, guard) { 448 if (array == null) return void 0; 449 if (n == null || guard) return array[0]; 450 return _.initial(array, array.length - n); 451 }; 452 453 // Returns everything but the last entry of the array. Especially useful on 454 // the arguments object. Passing **n** will return all the values in 455 // the array, excluding the last N. 456 _.initial = function(array, n, guard) { 457 return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n))); 458 }; 459 460 // Get the last element of an array. Passing **n** will return the last N 461 // values in the array. 462 _.last = function(array, n, guard) { 463 if (array == null) return void 0; 464 if (n == null || guard) return array[array.length - 1]; 465 return _.rest(array, Math.max(0, array.length - n)); 466 }; 467 468 // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. 469 // Especially useful on the arguments object. Passing an **n** will return 470 // the rest N values in the array. 471 _.rest = _.tail = _.drop = function(array, n, guard) { 472 return slice.call(array, n == null || guard ? 1 : n); 473 }; 474 475 // Trim out all falsy values from an array.
476 _.compact = function(array) { 477 return _.filter(array, _.identity); 478 }; 479 480 // Internal implementation of a recursive `flatten` function. 481 var flatten = function(input, shallow, strict, startIndex) { 482 var output = [], idx = 0; 483 for (var i = startIndex || 0, length = input && input.length; i < length; i++) { 484 var value = input[i]; 485 if (isArrayLike(value) && (_.isArray(value) || _.isArguments(value))) { 486 //flatten current level of array or arguments object 487 if (!shallow) value = flatten(value, shallow, strict); 488 var j = 0, len = value.length; 489 output.length += len; 490 while (j < len) { 491 output[idx++] = value[j++]; 492 } 493 } else if (!strict) { 494 output[idx++] = value; 495 } 496 } 497 return output; 498 }; 499 500 // Flatten out an array, either recursively (by default), or just one level. 501 _.flatten = function(array, shallow) { 502 return flatten(array, shallow, false); 503 }; 504 505 // Return a version of the array that does not contain the specified value(s). 506 _.without = function(array) { 507 return _.difference(array, slice.call(arguments, 1)); 508 }; 509 510 // Produce a duplicate-free version of the array. If the array has already 511 // been sorted, you have the option of using a faster algorithm. 512 // Aliased as `unique`. 513 _.uniq = _.unique = function(array, isSorted, iteratee, context) { 514 if (array == null) return []; 515 if (!_.isBoolean(isSorted)) { 516 context = iteratee; 517 iteratee = isSorted; 518 isSorted = false; 519 } 520 if (iteratee != null) iteratee = cb(iteratee, context); 521 var result = []; 522 var seen = []; 523 for (var i = 0, length = array.length; i < length; i++) { 524 var value = array[i], 525 computed = iteratee ? iteratee(value, i, array) : value; 526 if (isSorted) { 527 if (!i || seen !== computed) result.push(value); 528 seen = computed; 529 } else if (iteratee) { 530 if (!_.contains(seen, computed)) { 531 seen.push(computed); 532 result.push(value); 533 } 534 } else if (!_.contains(result, value)) { 535 result.push(value); 536 } 537 } 538 return result; 539 }; 540 541 // Produce an array that contains the union: each distinct element from all of 542 // the passed-in arrays. 543 _.union = function() { 544 return _.uniq(flatten(arguments, true, true)); 545 }; 546 547 // Produce an array that contains every item shared between all the 548 // passed-in arrays. 549 _.intersection = function(array) { 550 if (array == null) return []; 551 var result = []; 552 var argsLength = arguments.length; 553 for (var i = 0, length = array.length; i < length; i++) { 554 var item = array[i]; 555 if (_.contains(result, item)) continue; 556 for (var j = 1; j < argsLength; j++) { 557 if (!_.contains(arguments[j], item)) break; 558 } 559 if (j === argsLength) result.push(item); 560 } 561 return result; 562 }; 563 564 // Take the difference between one array and a number of other arrays. 565 // Only the elements present in just the first array will remain. 566 _.difference = function(array) { 567 var rest = flatten(arguments, true, true, 1); 568 return _.filter(array, function(value){ 569 return !_.contains(rest, value); 570 }); 571 }; 572 573 // Zip together multiple lists into a single array -- elements that share 574 // an index go together. 575 _.zip = function() { 576 return _.unzip(arguments); 577 }; 578 579 // Complement of _.zip. Unzip accepts an array of arrays and groups 580 // each array's elements on shared indices 581 _.unzip = function(array) { 582 var length = array && _.max(array, 'length').length || 0; 583 var result = Array(length); 584 585 for (var index = 0; index < length; index++) { 586 result[index] = _.pluck(array, index); 587 } 588 return result; 589 }; 590 591 // Converts lists into objects. Pass either a single array of `[key, value]` 592 // pairs, or two parallel arrays of the same length -- one of keys, and one of 593 // the corresponding values. 594 _.object = function(list, values) { 595 var result = {}; 596 for (var i = 0, length = list && list.length; i < length; i++) { 597 if (values) { 598 result[list[i]] = values[i]; 599 } else { 600 result[list[i][0]] = list[i][1]; 601 } 602 } 603 return result; 604 }; 605 606 // Return the position of the first occurrence of an item in an array, 607 // or -1 if the item is not included in the array. 608 // If the array is large and already in sort order, pass `true` 609 // for **isSorted** to use binary search. 610 _.indexOf = function(array, item, isSorted) { 611 var i = 0, length = array && array.length; 612 if (typeof isSorted == 'number') { 613 i = isSorted < 0 ? Math.max(0, length + isSorted) : isSorted; 614 } else if (isSorted && length) { 615 i = _.sortedIndex(array, item); 616 return array[i] === item ? i : -1; 617 } 618 if (item !== item) { 619 return _.findIndex(slice.call(array, i), _.isNaN); 620 } 621 for (; i < length; i++) if (array[i] === item) return i; 622 return -1; 623 }; 624 625 _.lastIndexOf = function(array, item, from) { 626 var idx = array ? array.length : 0; 627 if (typeof from == 'number') { 628 idx = from < 0 ? idx + from + 1 : Math.min(idx, from + 1); 629 } 630 if (item !== item) { 631 return _.findLastIndex(slice.call(array, 0, idx), _.isNaN); 632 } 633 while (--idx >= 0) if (array[idx] === item) return idx; 634 return -1; 635 }; 636 637 // Generator function to create the findIndex and findLastIndex functions 638 function createIndexFinder(dir) { 639 return function(array, predicate, context) { 640 predicate = cb(predicate, context); 641 var length = array != null && array.length; 642 var index = dir > 0 ? 0 : length - 1; 643 for (; index >= 0 && index < length; index += dir) { 644 if (predicate(array[index], index, array)) return index; 645 } 646 return -1; 647 }; 648 } 649 650 // Returns the first index on an array-like that passes a predicate test 651 _.findIndex = createIndexFinder(1); 652 653 _.findLastIndex = createIndexFinder(-1); 654 655 // Use a comparator function to figure out the smallest index at which 656 // an object should be inserted so as to maintain order. Uses binary search. 657 _.sortedIndex = function(array, obj, iteratee, context) { 658 iteratee = cb(iteratee, context, 1); 659 var value = iteratee(obj); 660 var low = 0, high = array.length; 661 while (low < high) { 662 var mid = Math.floor((low + high) / 2); 663 if (iteratee(array[mid]) < value) low = mid + 1; else high = mid; 664 } 665 return low; 666 }; 667 668 // Generate an integer Array containing an arithmetic progression. A port of 669 // the native Python `range()` function. See 670 // [the Python documentation](http://docs.python.org/library/functions.html#range). 671 _.range = function(start, stop, step) { 672 if (arguments.length <= 1
vendor: 12,494 bytes, lines 672-1051
672) { 673 stop = start || 0; 674 start = 0; 675 } 676 step = step || 1; 677 678 var length = Math.max(Math.ceil((stop - start) / step), 0); 679 var range = Array(length); 680 681 for (var idx = 0; idx < length; idx++, start += step) { 682 range[idx] = start; 683 } 684 685 return range; 686 }; 687 688 // Function (ahem) Functions 689 // ------------------ 690 691 // Determines whether to execute a function as a constructor 692 // or a normal function with the provided arguments 693 var executeBound = function(sourceFunc, boundFunc, context, callingContext, args) { 694 if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args); 695 var self = baseCreate(sourceFunc.prototype); 696 var result = sourceFunc.apply(self, args); 697 if (_.isObject(result)) return result; 698 return self; 699 }; 700 701 // Create a function bound to a given object (assigning `this`, and arguments, 702 // optionally). Delegates to **ECMAScript 5**'s native `Function.bind` if 703 // available. 704 _.bind = function(func, context) { 705 if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1)); 706 if (!_.isFunction(func)) throw new TypeError('Bind must be called on a function'); 707 var args = slice.call(arguments, 2); 708 var bound = function() { 709 return executeBound(func, bound, context, this, args.concat(slice.call(arguments))); 710 }; 711 return bound; 712 }; 713 714 // Partially apply a function by creating a version that has had some of its 715 // arguments pre-filled, without changing its dynamic `this` context. _ acts 716 // as a placeholder, allowing any combination of arguments to be pre-filled. 717 _.partial = function(func) { 718 var boundArgs = slice.call(arguments, 1); 719 var bound = function() { 720 var position = 0, length = boundArgs.length; 721 var args = Array(length); 722 for (var i = 0; i < length; i++) { 723 args[i] = boundArgs[i] === _ ? arguments[position++] : boundArgs[i]; 724 } 725 while (position < arguments.length) args.push(arguments[position++]); 726 return executeBound(func, bound, this, this, args); 727 }; 728 return bound; 729 }; 730 731 // Bind a number of an object's methods to that object. Remaining arguments 732 // are the method names to be bound. Useful for ensuring that all callbacks 733 // defined on an object belong to it. 734 _.bindAll = function(obj) { 735 var i, length = arguments.length, key; 736 if (length <= 1) throw new Error('bindAll must be passed function names'); 737 for (i = 1; i < length; i++) { 738 key = arguments[i]; 739 obj[key] = _.bind(obj[key], obj); 740 } 741 return obj; 742 }; 743 744 // Memoize an expensive function by storing its results. 745 _.memoize = function(func, hasher) { 746 var memoize = function(key) { 747 var cache = memoize.cache; 748 var address = '' + (hasher ? hasher.apply(this, arguments) : key); 749 if (!_.has(cache, address)) cache[address] = func.apply(this, arguments); 750 return cache[address]; 751 }; 752 memoize.cache = {}; 753 return memoize; 754 }; 755 756 // Delays a function for the given number of milliseconds, and then calls 757 // it with the arguments supplied. 758 _.delay = function(func, wait) { 759 var args = slice.call(arguments, 2); 760 return setTimeout(function(){ 761 return func.apply(null, args); 762 }, wait); 763 }; 764 765 // Defers a function, scheduling it to run after the current call stack has 766 // cleared. 767 _.defer = _.partial(_.delay, _, 1); 768 769 // Returns a function, that, when invoked, will only be triggered at most once 770 // during a given window of time. Normally, the throttled function will run 771 // as much as it can, without ever going more than once per `wait` duration; 772 // but if you'd like to disable the execution on the leading edge, pass 773 // `{leading: false}`. To disable execution on the trailing edge, ditto. 774 _.throttle = function(func, wait, options) { 775 var context, args, result; 776 var timeout = null; 777 var previous = 0; 778 if (!options) options = {}; 779 var later = function() { 780 previous = options.leading === false ? 0 : _.now(); 781 timeout = null; 782 result = func.apply(context, args); 783 if (!timeout) context = args = null; 784 }; 785 return function() { 786 var now = _.now(); 787 if (!previous && options.leading === false) previous = now; 788 var remaining = wait - (now - previous); 789 context = this; 790 args = arguments; 791 if (remaining <= 0 || remaining > wait) { 792 if (timeout) { 793 clearTimeout(timeout); 794 timeout = null; 795 } 796 previous = now; 797 result = func.apply(context, args); 798 if (!timeout) context = args = null; 799 } else if (!timeout && options.trailing !== false) { 800 timeout = setTimeout(later, remaining); 801 } 802 return result; 803 }; 804 }; 805 806 // Returns a function, that, as long as it continues to be invoked, will not 807 // be triggered. The function will be called after it stops being called for 808 // N milliseconds. If `immediate` is passed, trigger the function on the 809 // leading edge, instead of the trailing. 810 _.debounce = function(func, wait, immediate) { 811 var timeout, args, context, timestamp, result; 812 813 var later = function() { 814 var last = _.now() - timestamp; 815 816 if (last < wait && last >= 0) { 817 timeout = setTimeout(later, wait - last); 818 } else { 819 timeout = null; 820 if (!immediate) { 821 result = func.apply(context, args); 822 if (!timeout) context = args = null; 823 } 824 } 825 }; 826 827 return function() { 828 context = this; 829 args = arguments; 830 timestamp = _.now(); 831 var callNow = immediate && !timeout; 832 if (!timeout) timeout = setTimeout(later, wait); 833 if (callNow) { 834 result = func.apply(context, args); 835 context = args = null; 836 } 837 838 return result; 839 }; 840 }; 841 842 // Returns the first function passed as an argument to the second, 843 // allowing you to adjust arguments, run code before and after, and 844 // conditionally execute the original function. 845 _.wrap = function(func, wrapper) { 846 return _.partial(wrapper, func); 847 }; 848 849 // Returns a negated version of the passed-in predicate. 850 _.negate = function(predicate) { 851 return function() { 852 return !predicate.apply(this, arguments); 853 }; 854 }; 855 856 // Returns a function that is the composition of a list of functions, each 857 // consuming the return value of the function that follows. 858 _.compose = function() { 859 var args = arguments; 860 var start = args.length - 1; 861 return function() { 862 var i = start; 863 var result = args[start].apply(this, arguments); 864 while (i--) result = args[i].call(this, result); 865 return result; 866 }; 867 }; 868 869 // Returns a function that will only be executed on and after the Nth call. 870 _.after = function(times, func) { 871 return function() { 872 if (--times < 1) { 873 return func.apply(this, arguments); 874 } 875 }; 876 }; 877 878 // Returns a function that will only be executed up to (but not including) the Nth call. 879 _.before = function(times, func) { 880 var memo; 881 return function() { 882 if (--times > 0) { 883 memo = func.apply(this, arguments); 884 } 885 if (times <= 1) func = null; 886 return memo; 887 }; 888 }; 889 890 // Returns a function that will be executed at most one time, no matter how 891 // often you call it. Useful for lazy initialization. 892 _.once = _.partial(_.before, 2); 893 894 // Object Functions 895 // ---------------- 896 897 // Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed. 898 var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString'); 899 var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString', 900 'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString']; 901 902 function collectNonEnumProps(obj, keys) { 903 var nonEnumIdx = nonEnumerableProps.length; 904 var constructor = obj.constructor; 905 var proto = (_.isFunction(constructor) && constructor.prototype) || ObjProto; 906 907 // Constructor is a special case. 908 var prop = 'constructor'; 909 if (_.has(obj, prop) && !_.contains(keys, prop)) keys.push(prop); 910 911 while (nonEnumIdx--) { 912 prop = nonEnumerableProps[nonEnumIdx]; 913 if (prop in obj && obj[prop] !== proto[prop] && !_.contains(keys, prop)) { 914 keys.push(prop); 915 } 916 } 917 } 918 919 // Retrieve the names of an object's own properties. 920 // Delegates to **ECMAScript 5**'s native `Object.keys` 921 _.keys = function(obj) { 922 if (!_.isObject(obj)) return []; 923 if (nativeKeys) return nativeKeys(obj); 924 var keys = []; 925 for (var key in obj) if (_.has(obj, key)) keys.push(key); 926 // Ahem, IE < 9. 927 if (hasEnumBug) collectNonEnumProps(obj, keys); 928 return keys; 929 }; 930 931 // Retrieve all the property names of an object. 932 _.allKeys = function(obj) { 933 if (!_.isObject(obj)) return []; 934 var keys = []; 935 for (var key in obj) keys.push(key); 936 // Ahem, IE < 9. 937 if (hasEnumBug) collectNonEnumProps(obj, keys); 938 return keys; 939 }; 940 941 // Retrieve the values of an object's properties. 942 _.values = function(obj) { 943 var keys = _.keys(obj); 944 var length = keys.length; 945 var values = Array(length); 946 for (var i = 0; i < length; i++) { 947 values[i] = obj[keys[i]]; 948 } 949 return values; 950 }; 951 952 // Returns the results of applying the iteratee to each element of the object 953 // In contrast to _.map it returns an object 954 _.mapObject = function(obj, iteratee, context) { 955 iteratee = cb(iteratee, context); 956 var keys = _.keys(obj), 957 length = keys.length, 958 results = {}, 959 currentKey; 960 for (var index = 0; index < length; index++) { 961 currentKey = keys[index]; 962 results[currentKey] = iteratee(obj[currentKey], currentKey, obj); 963 } 964 return results; 965 }; 966 967 // Convert an object into a list of `[key, value]` pairs. 968 _.pairs = function(obj) { 969 var keys = _.keys(obj); 970 var length = keys.length; 971 var pairs = Array(length); 972 for (var i = 0; i < length; i++) { 973 pairs[i] = [keys[i], obj[keys[i]]]; 974 } 975 return pairs; 976 }; 977 978 // Invert the keys and values of an object. The values must be serializable. 979 _.invert = function(obj) { 980 var result = {}; 981 var keys = _.keys(obj); 982 for (var i = 0, length = keys.length; i < length; i++) { 983 result[obj[keys[i]]] = keys[i]; 984 } 985 return result; 986 }; 987 988 // Return a sorted list of the function names available on the object. 989 // Aliased as `methods` 990 _.functions = _.methods = function(obj) { 991 var names = []; 992 for (var key in obj) { 993 if (_.isFunction(obj[key])) names.push(key); 994 } 995 return names.sort(); 996 }; 997 998 // Extend a given object with all the properties in passed-in object(s). 999 _.extend = createAssigner(_.allKeys); 1000 1001 // Assigns a given object with all the own properties in the passed-in object(s) 1002 // (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) 1003 _.extendOwn = _.assign = createAssigner(_.keys); 1004 1005 // Returns the first key on an object that passes a predicate test 1006 _.findKey = function(obj, predicate, context) { 1007 predicate = cb(predicate, context); 1008 var keys = _.keys(obj), key; 1009 for (var i = 0, length = keys.length; i < length; i++) { 1010 key = keys[i]; 1011 if (predicate(obj[key], key, obj)) return key; 1012 } 1013 }; 1014 1015 // Return a copy of the object only containing the whitelisted properties. 1016 _.pick = function(object, oiteratee, context) { 1017 var result = {}, obj = object, iteratee, keys; 1018 if (obj == null) return result; 1019 if (_.isFunction(oiteratee)) { 1020 keys = _.allKeys(obj); 1021 iteratee = optimizeCb(oiteratee, context); 1022 } else { 1023 keys = flatten(arguments, false, false, 1); 1024 iteratee = function(value, key, obj) { return key in obj; }; 1025 obj = Object(obj); 1026 } 1027 for (var i = 0, length = keys.length; i < length; i++) { 1028 var key = keys[i]; 1029 var value = obj[key]; 1030 if (iteratee(value, key, obj)) result[key] = value; 1031 } 1032 return result; 1033 }; 1034 1035 // Return a copy of the object without the blacklisted properties. 1036 _.omit = function(obj, iteratee, context) { 1037 if (_.isFunction(iteratee)) { 1038 iteratee = _.negate(iteratee); 1039 } else { 1040 var keys = _.map(flatten(arguments, false, false, 1), String); 1041 iteratee = function(value, key) { 1042 return !_.contains(keys, key); 1043 }; 1044 } 1045 return _.pick(obj, iteratee, context); 1046 }; 1047 1048 // Fill in a given object with default properties. 1049 _.defaults = createAssigner(_.allKeys, true); 1050 1051 // Create
vendor: 16,516 bytes, lines 1051-1536
1051 a (shallow-cloned) duplicate of an object. 1052 _.clone = function(obj) { 1053 if (!_.isObject(obj)) return obj; 1054 return _.isArray(obj) ? obj.slice() : _.extend({}, obj); 1055 }; 1056 1057 // Invokes interceptor with the obj, and then returns obj. 1058 // The primary purpose of this method is to "tap into" a method chain, in 1059 // order to perform operations on intermediate results within the chain. 1060 _.tap = function(obj, interceptor) { 1061 interceptor(obj); 1062 return obj; 1063 }; 1064 1065 // Returns whether an object has a given set of `key:value` pairs. 1066 _.isMatch = function(object, attrs) { 1067 var keys = _.keys(attrs), length = keys.length; 1068 if (object == null) return !length; 1069 var obj = Object(object); 1070 for (var i = 0; i < length; i++) { 1071 var key = keys[i]; 1072 if (attrs[key] !== obj[key] || !(key in obj)) return false; 1073 } 1074 return true; 1075 }; 1076 1077 1078 // Internal recursive comparison function for `isEqual`. 1079 var eq = function(a, b, aStack, bStack) { 1080 // Identical objects are equal. `0 === -0`, but they aren't identical. 1081 // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). 1082 if (a === b) return a !== 0 || 1 / a === 1 / b; 1083 // A strict comparison is necessary because `null == undefined`. 1084 if (a == null || b == null) return a === b; 1085 // Unwrap any wrapped objects. 1086 if (a instanceof _) a = a._wrapped; 1087 if (b instanceof _) b = b._wrapped; 1088 // Compare `[[Class]]` names. 1089 var className = toString.call(a); 1090 if (className !== toString.call(b)) return false; 1091 switch (className) { 1092 // Strings, numbers, regular expressions, dates, and booleans are compared by value. 1093 case '[object RegExp]': 1094 // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') 1095 case '[object String]': 1096 // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is 1097 // equivalent to `new String("5")`. 1098 return '' + a === '' + b; 1099 case '[object Number]': 1100 // `NaN`s are equivalent, but non-reflexive. 1101 // Object(NaN) is equivalent to NaN 1102 if (+a !== +a) return +b !== +b; 1103 // An `egal` comparison is performed for other numeric values. 1104 return +a === 0 ? 1 / +a === 1 / b : +a === +b; 1105 case '[object Date]': 1106 case '[object Boolean]': 1107 // Coerce dates and booleans to numeric primitive values. Dates are compared by their 1108 // millisecond representations. Note that invalid dates with millisecond representations 1109 // of `NaN` are not equivalent. 1110 return +a === +b; 1111 } 1112 1113 var areArrays = className === '[object Array]'; 1114 if (!areArrays) { 1115 if (typeof a != 'object' || typeof b != 'object') return false; 1116 1117 // Objects with different constructors are not equivalent, but `Object`s or `Array`s 1118 // from different frames are. 1119 var aCtor = a.constructor, bCtor = b.constructor; 1120 if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && 1121 _.isFunction(bCtor) && bCtor instanceof bCtor) 1122 && ('constructor' in a && 'constructor' in b)) { 1123 return false; 1124 } 1125 } 1126 // Assume equality for cyclic structures. The algorithm for detecting cyclic 1127 // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. 1128 1129 // Initializing stack of traversed objects. 1130 // It's done here since we only need them for objects and arrays comparison. 1131 aStack = aStack || []; 1132 bStack = bStack || []; 1133 var length = aStack.length; 1134 while (length--) { 1135 // Linear search. Performance is inversely proportional to the number of 1136 // unique nested structures. 1137 if (aStack[length] === a) return bStack[length] === b; 1138 } 1139 1140 // Add the first object to the stack of traversed objects. 1141 aStack.push(a); 1142 bStack.push(b); 1143 1144 // Recursively compare objects and arrays. 1145 if (areArrays) { 1146 // Compare array lengths to determine if a deep comparison is necessary. 1147 length = a.length; 1148 if (length !== b.length) return false; 1149 // Deep compare the contents, ignoring non-numeric properties. 1150 while (length--) { 1151 if (!eq(a[length], b[length], aStack, bStack)) return false; 1152 } 1153 } else { 1154 // Deep compare objects. 1155 var keys = _.keys(a), key; 1156 length = keys.length; 1157 // Ensure that both objects contain the same number of properties before comparing deep equality. 1158 if (_.keys(b).length !== length) return false; 1159 while (length--) { 1160 // Deep compare each member 1161 key = keys[length]; 1162 if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; 1163 } 1164 } 1165 // Remove the first object from the stack of traversed objects. 1166 aStack.pop(); 1167 bStack.pop(); 1168 return true; 1169 }; 1170 1171 // Perform a deep comparison to check if two objects are equal. 1172 _.isEqual = function(a, b) { 1173 return eq(a, b); 1174 }; 1175 1176 // Is a given array, string, or object empty? 1177 // An "empty" object has no enumerable own-properties. 1178 _.isEmpty = function(obj) { 1179 if (obj == null) return true; 1180 if (isArrayLike(obj) && (_.isArray(obj) || _.isString(obj) || _.isArguments(obj))) return obj.length === 0; 1181 return _.keys(obj).length === 0; 1182 }; 1183 1184 // Is a given value a DOM element? 1185 _.isElement = function(obj) { 1186 return !!(obj && obj.nodeType === 1); 1187 }; 1188 1189 // Is a given value an array? 1190 // Delegates to ECMA5's native Array.isArray 1191 _.isArray = nativeIsArray || function(obj) { 1192 return toString.call(obj) === '[object Array]'; 1193 }; 1194 1195 // Is a given variable an object? 1196 _.isObject = function(obj) { 1197 var type = typeof obj; 1198 return type === 'function' || type === 'object' && !!obj; 1199 }; 1200 1201 // Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp, isError. 1202 _.each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp', 'Error'], function(name) { 1203 _['is' + name] = function(obj) { 1204 return toString.call(obj) === '[object ' + name + ']'; 1205 }; 1206 }); 1207 1208 // Define a fallback version of the method in browsers (ahem, IE < 9), where 1209 // there isn't any inspectable "Arguments" type. 1210 if (!_.isArguments(arguments)) { 1211 _.isArguments = function(obj) { 1212 return _.has(obj, 'callee'); 1213 }; 1214 } 1215 1216 // Optimize `isFunction` if appropriate. Work around some typeof bugs in old v8, 1217 // IE 11 (#1621), and in Safari 8 (#1929). 1218 if (typeof /./ != 'function' && typeof Int8Array != 'object') { 1219 _.isFunction = function(obj) { 1220 return typeof obj == 'function' || false; 1221 }; 1222 } 1223 1224 // Is a given object a finite number? 1225 _.isFinite = function(obj) { 1226 return isFinite(obj) && !isNaN(parseFloat(obj)); 1227 }; 1228 1229 // Is the given value `NaN`? (NaN is the only number which does not equal itself). 1230 _.isNaN = function(obj) { 1231 return _.isNumber(obj) && obj !== +obj; 1232 }; 1233 1234 // Is a given value a boolean? 1235 _.isBoolean = function(obj) { 1236 return obj === true || obj === false || toString.call(obj) === '[object Boolean]'; 1237 }; 1238 1239 // Is a given value equal to null? 1240 _.isNull = function(obj) { 1241 return obj === null; 1242 }; 1243 1244 // Is a given variable undefined? 1245 _.isUndefined = function(obj) { 1246 return obj === void 0; 1247 }; 1248 1249 // Shortcut function for checking if an object has a given property directly 1250 // on itself (in other words, not on a prototype). 1251 _.has = function(obj, key) { 1252 return obj != null && hasOwnProperty.call(obj, key); 1253 }; 1254 1255 // Utility Functions 1256 // ----------------- 1257 1258 // Run Underscore.js in *noConflict* mode, returning the `_` variable to its 1259 // previous owner. Returns a reference to the Underscore object. 1260 _.noConflict = function() { 1261 root._ = previousUnderscore; 1262 return this; 1263 }; 1264 1265 // Keep the identity function around for default iteratees. 1266 _.identity = function(value) { 1267 return value; 1268 }; 1269 1270 // Predicate-generating functions. Often useful outside of Underscore. 1271 _.constant = function(value) { 1272 return function() { 1273 return value; 1274 }; 1275 }; 1276 1277 _.noop = function(){}; 1278 1279 _.property = function(key) { 1280 return function(obj) { 1281 return obj == null ? void 0 : obj[key]; 1282 }; 1283 }; 1284 1285 // Generates a function for a given object that returns a given property. 1286 _.propertyOf = function(obj) { 1287 return obj == null ? function(){} : function(key) { 1288 return obj[key]; 1289 }; 1290 }; 1291 1292 // Returns a predicate for checking whether an object has a given set of 1293 // `key:value` pairs. 1294 _.matcher = _.matches = function(attrs) { 1295 attrs = _.extendOwn({}, attrs); 1296 return function(obj) { 1297 return _.isMatch(obj, attrs); 1298 }; 1299 }; 1300 1301 // Run a function **n** times. 1302 _.times = function(n, iteratee, context) { 1303 var accum = Array(Math.max(0, n)); 1304 iteratee = optimizeCb(iteratee, context, 1); 1305 for (var i = 0; i < n; i++) accum[i] = iteratee(i); 1306 return accum; 1307 }; 1308 1309 // Return a random integer between min and max (inclusive). 1310 _.random = function(min, max) { 1311 if (max == null) { 1312 max = min; 1313 min = 0; 1314 } 1315 return min + Math.floor(Math.random() * (max - min + 1)); 1316 }; 1317 1318 // A (possibly faster) way to get the current timestamp as an integer. 1319 _.now = Date.now || function() { 1320 return new Date().getTime(); 1321 }; 1322 1323 // List of HTML entities for escaping. 1324 var escapeMap = { 1325 '&': '&', 1326 '<': '<', 1327 '>': '>', 1328 '"': '"', 1329 "'": ''', 1330 '`': '`' 1331 }; 1332 var unescapeMap = _.invert(escapeMap); 1333 1334 // Functions for escaping and unescaping strings to/from HTML interpolation. 1335 var createEscaper = function(map) { 1336 var escaper = function(match) { 1337 return map[match]; 1338 }; 1339 // Regexes for identifying a key that needs to be escaped 1340 var source = '(?:' + _.keys(map).join('|') + ')'; 1341 var testRegexp = RegExp(source); 1342 var replaceRegexp = RegExp(source, 'g'); 1343 return function(string) { 1344 string = string == null ? '' : '' + string; 1345 return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; 1346 }; 1347 }; 1348 _.escape = createEscaper(escapeMap); 1349 _.unescape = createEscaper(unescapeMap); 1350 1351 // If the value of the named `property` is a function then invoke it with the 1352 // `object` as context; otherwise, return it. 1353 _.result = function(object, property, fallback) { 1354 var value = object == null ? void 0 : object[property]; 1355 if (value === void 0) { 1356 value = fallback; 1357 } 1358 return _.isFunction(value) ? value.call(object) : value; 1359 }; 1360 1361 // Generate a unique integer id (unique within the entire client session). 1362 // Useful for temporary DOM ids. 1363 var idCounter = 0; 1364 _.uniqueId = function(prefix) { 1365 var id = ++idCounter + ''; 1366 return prefix ? prefix + id : id; 1367 }; 1368 1369 // By default, Underscore uses ERB-style template delimiters, change the 1370 // following template settings to use alternative delimiters. 1371 _.templateSettings = { 1372 evaluate : /<%([\s\S]+?)%>/g, 1373 interpolate : /<%=([\s\S]+?)%>/g, 1374 escape : /<%-([\s\S]+?)%>/g 1375 }; 1376 1377 // When customizing `templateSettings`, if you don't want to define an 1378 // interpolation, evaluation or escaping regex, we need one that is 1379 // guaranteed not to match. 1380 var noMatch = /(.)^/; 1381 1382 // Certain characters need to be escaped so that they can be put into a 1383 // string literal. 1384 var escapes = { 1385 "'": "'", 1386 '\\': '\\', 1387 '\r': 'r', 1388 '\n': 'n', 1389 '\u2028': 'u2028', 1390 '\u2029': 'u2029' 1391 }; 1392 1393 var escaper = /\\|'|\r|\n|\u2028|\u2029/g; 1394 1395 var escapeChar = function(match) { 1396 return '\\' + escapes[match]; 1397 }; 1398 1399 // JavaScript micro-templating, similar to John Resig's implementation. 1400 // Underscore templating handles arbitrary delimiters, preserves whitespace, 1401 // and correctly escapes quotes within interpolated code. 1402 // NB: `oldSettings` only exists for backwards compatibility. 1403 _.template = function(text, settings, oldSettings) { 1404 if (!settings && oldSettings) settings = oldSettings; 1405 settings = _.defaults({}, settings, _.templateSettings); 1406 1407 // Combine delimiters into one regular expression via alternation. 1408 var matcher = RegExp([ 1409 (settings.escape || noMatch).source, 1410 (settings.interpolate || noMatch).source, 1411 (settings.evaluate || noMatch).source 1412 ].join('|') + '|$', 'g'); 1413 1414 // Compile the template source, escaping string literals appropriately. 1415 var index = 0; 1416 var source = "__p+='"; 1417 text.replace(matcher, function(match, escape, interpolate, evaluate, offset) { 1418 source += text.slice(index, offset).replace(escaper, escapeChar); 1419 index = offset + match.length; 1420 1421 if (escape) { 1422 source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'"; 1423 } else if (interpolate) { 1424 source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'"; 1425 } else if (evaluate) { 1426 source += "';\n" + evaluate + "\n__p+='"; 1427 } 1428 1429 // Adobe VMs need the match returned to produce the correct offest. 1430 return match; 1431 }); 1432 source += "';\n"; 1433 1434 // If a variable is not specified, place data values in local scope. 1435 if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n'; 1436 1437 source = "var __t,__p='',__j=Array.prototype.join," + 1438 "print=function(){__p+=__j.call(arguments,'');};\n" + 1439 source + 'return __p;\n'; 1440 1441 try { 1442 var render = new Function(settings.variable || 'obj', '_', source); 1443 } catch (e) { 1444 e.source = source; 1445 throw e; 1446 } 1447 1448 var template = function(data) { 1449 return render.call(this, data, _); 1450 }; 1451 1452 // Provide the compiled source as a convenience for precompilation. 1453 var argument = settings.variable || 'obj'; 1454 template.source = 'function(' + argument + '){\n' + source + '}'; 1455 1456 return template; 1457 }; 1458 1459 // Add a "chain" function. Start chaining a wrapped Underscore object. 1460 _.chain = function(obj) { 1461 var instance = _(obj); 1462 instance._chain = true; 1463 return instance; 1464 }; 1465 1466 // OOP 1467 // --------------- 1468 // If Underscore is called as a function, it returns a wrapped object that 1469 // can be used OO-style. This wrapper holds altered versions of all the 1470 // underscore functions. Wrapped objects may be chained. 1471 1472 // Helper function to continue chaining intermediate results. 1473 var result = function(instance, obj) { 1474 return instance._chain ? _(obj).chain() : obj; 1475 }; 1476 1477 // Add your own custom functions to the Underscore object. 1478 _.mixin = function(obj) { 1479 _.each(_.functions(obj), function(name) { 1480 var func = _[name] = obj[name]; 1481 _.prototype[name] = function() { 1482 var args = [this._wrapped]; 1483 push.apply(args, arguments); 1484 return result(this, func.apply(_, args)); 1485 }; 1486 }); 1487 }; 1488 1489 // Add all of the Underscore functions to the wrapper object. 1490 _.mixin(_); 1491 1492 // Add all mutator Array functions to the wrapper. 1493 _.each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) { 1494 var method = ArrayProto[name]; 1495 _.prototype[name] = function() { 1496 var obj = this._wrapped; 1497 method.apply(obj, arguments); 1498 if ((name === 'shift' || name === 'splice') && obj.length === 0) delete obj[0]; 1499 return result(this, obj); 1500 }; 1501 }); 1502 1503 // Add all accessor Array functions to the wrapper. 1504 _.each(['concat', 'join', 'slice'], function(name) { 1505 var method = ArrayProto[name]; 1506 _.prototype[name] = function() { 1507 return result(this, method.apply(this._wrapped, arguments)); 1508 }; 1509 }); 1510 1511 // Extracts the result from a wrapped and chained object. 1512 _.prototype.value = function() { 1513 return this._wrapped; 1514 }; 1515 1516 // Provide unwrapping proxy for some methods used in engine operations 1517 // such as arithmetic and JSON stringification. 1518 _.prototype.valueOf = _.prototype.toJSON = _.prototype.value; 1519 1520 _.prototype.toString = function() { 1521 return '' + this._wrapped; 1522 }; 1523 1524 // AMD registration happens at the end for compatibility with AMD loaders 1525 // that may not enforce next-turn semantics on modules. Even though general 1526 // practice for AMD registration is to be anonymous, underscore registers 1527 // as a named module because, like jQuery, it is a base library that is 1528 // popular enough to be bundled in a third party lib, but not be part of 1529 // an AMD load request. Those cases could generate an error when an 1530 // anonymous define() is called outside of a loader request. 1531 if (typeof define === 'function' && define.amd) { 1532 define('underscore', [], function() { 1533 return _; 1534 }); 1535 } 1536}.call(this));
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.