diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..8e920719d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +root = true + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[**.{js,json,html}] +indent_style = space +indent_size = 2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e133ebea1..8b22557d1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,6 +2,8 @@ * Before you open a ticket or send a pull request, [search](https://github.com/jashkenas/underscore/issues) for previous discussions about the same feature or issue. Add to the earlier ticket if you find one. +* If you're proposing a new feature, make sure it isn't already implemented in [Underscore-Contrib](https://github.com/documentcloud/underscore-contrib). + * Before sending a pull request for a feature, be sure to have [tests](http://underscorejs.org/test/). * Use the same coding style as the rest of the [codebase](https://github.com/jashkenas/underscore/blob/master/underscore.js). diff --git a/LICENSE b/LICENSE index 3acf90838..0d6b8739d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative +Copyright (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors Permission is hereby granted, free of charge, to any person diff --git a/Rakefile b/Rakefile deleted file mode 100644 index 6033c158b..000000000 --- a/Rakefile +++ /dev/null @@ -1,10 +0,0 @@ -desc "Use Uglify JS to compress Underscore.js" -task :build do - sh "uglifyjs underscore.js -c \"evaluate=false\" --comments \"/ .*/\" -m --source-map underscore-min.map -o underscore-min.js" -end - -desc "Build the docco documentation" -task :doc do - sh "docco underscore.js" -end - diff --git a/bower.json b/bower.json new file mode 100644 index 000000000..6c6bbdab2 --- /dev/null +++ b/bower.json @@ -0,0 +1,8 @@ +{ + "name": "underscore", + "version": "1.6.0", + "main": "underscore.js", + "keywords": ["util", "functional", "server", "client", "browser"], + "ignore" : ["underscore-min.js", "docs", "test", "*.yml", "*.map", + "CNAME", "index.html", "favicon.ico", "CONTRIBUTING.md"] +} diff --git a/component.json b/component.json new file mode 100644 index 000000000..bb1775e70 --- /dev/null +++ b/component.json @@ -0,0 +1,10 @@ +{ + "name" : "underscore", + "description" : "JavaScript's functional programming helper library.", + "keywords" : ["util", "functional", "server", "client", "browser"], + "repo" : "jashkenas/underscore", + "main" : "underscore.js", + "scripts" : ["underscore.js"], + "version" : "1.6.0", + "license" : "MIT" +} diff --git a/docs/docco.css b/docs/docco.css index f690a0794..a2899ac87 100644 --- a/docs/docco.css +++ b/docs/docco.css @@ -51,9 +51,17 @@ b, strong { font-family: "aller-bold"; } -p, ul, ol { +p { margin: 15px 0 0px; } + .annotation ul, .annotation ol { + margin: 25px 0; + } + .annotation ul li, .annotation ol li { + font-size: 14px; + line-height: 18px; + margin: 10px 0; + } h1, h2, h3, h4, h5, h6 { color: #112233; @@ -70,7 +78,7 @@ h1 { hr { border: 0; - background: 1px solid #ddd; + background: 1px #ddd; height: 1px; margin: 20px 0; } @@ -205,7 +213,6 @@ ul.sections > li > div { } ul.sections > li > div.content { - background: #f5f5ff; overflow-x:auto; -webkit-box-shadow: inset 0 0 5px #e5e5ee; box-shadow: inset 0 0 5px #e5e5ee; @@ -306,7 +313,6 @@ ul.sections > li > div { ul.sections > li > div.content { padding: 13px; vertical-align: top; - background: #f5f5ff; border: none; -webkit-box-shadow: none; box-shadow: none; @@ -376,125 +382,125 @@ pre code { background: #f8f8ff } -pre .comment, -pre .template_comment, -pre .diff .header, -pre .javadoc { +pre .hljs-comment, +pre .hljs-template_comment, +pre .hljs-diff .hljs-header, +pre .hljs-javadoc { color: #408080; font-style: italic } -pre .keyword, -pre .assignment, -pre .literal, -pre .css .rule .keyword, -pre .winutils, -pre .javascript .title, -pre .lisp .title, -pre .subst { +pre .hljs-keyword, +pre .hljs-assignment, +pre .hljs-literal, +pre .hljs-css .hljs-rule .hljs-keyword, +pre .hljs-winutils, +pre .hljs-javascript .hljs-title, +pre .hljs-lisp .hljs-title, +pre .hljs-subst { color: #954121; /*font-weight: bold*/ } -pre .number, -pre .hexcolor { +pre .hljs-number, +pre .hljs-hexcolor { color: #40a070 } -pre .string, -pre .tag .value, -pre .phpdoc, -pre .tex .formula { +pre .hljs-string, +pre .hljs-tag .hljs-value, +pre .hljs-phpdoc, +pre .hljs-tex .hljs-formula { color: #219161; } -pre .title, -pre .id { +pre .hljs-title, +pre .hljs-id { color: #19469D; } -pre .params { +pre .hljs-params { color: #00F; } -pre .javascript .title, -pre .lisp .title, -pre .subst { +pre .hljs-javascript .hljs-title, +pre .hljs-lisp .hljs-title, +pre .hljs-subst { font-weight: normal } -pre .class .title, -pre .haskell .label, -pre .tex .command { +pre .hljs-class .hljs-title, +pre .hljs-haskell .hljs-label, +pre .hljs-tex .hljs-command { color: #458; font-weight: bold } -pre .tag, -pre .tag .title, -pre .rules .property, -pre .django .tag .keyword { +pre .hljs-tag, +pre .hljs-tag .hljs-title, +pre .hljs-rules .hljs-property, +pre .hljs-django .hljs-tag .hljs-keyword { color: #000080; font-weight: normal } -pre .attribute, -pre .variable, -pre .instancevar, -pre .lisp .body { +pre .hljs-attribute, +pre .hljs-variable, +pre .hljs-instancevar, +pre .hljs-lisp .hljs-body { color: #008080 } -pre .regexp { +pre .hljs-regexp { color: #B68 } -pre .class { +pre .hljs-class { color: #458; font-weight: bold } -pre .symbol, -pre .ruby .symbol .string, -pre .ruby .symbol .keyword, -pre .ruby .symbol .keymethods, -pre .lisp .keyword, -pre .tex .special, -pre .input_number { +pre .hljs-symbol, +pre .hljs-ruby .hljs-symbol .hljs-string, +pre .hljs-ruby .hljs-symbol .hljs-keyword, +pre .hljs-ruby .hljs-symbol .hljs-keymethods, +pre .hljs-lisp .hljs-keyword, +pre .hljs-tex .hljs-special, +pre .hljs-input_number { color: #990073 } -pre .builtin, -pre .constructor, -pre .built_in, -pre .lisp .title { +pre .hljs-builtin, +pre .hljs-constructor, +pre .hljs-built_in, +pre .hljs-lisp .hljs-title { color: #0086b3 } -pre .preprocessor, -pre .pi, -pre .doctype, -pre .shebang, -pre .cdata { +pre .hljs-preprocessor, +pre .hljs-pi, +pre .hljs-doctype, +pre .hljs-shebang, +pre .hljs-cdata { color: #999; font-weight: bold } -pre .deletion { +pre .hljs-deletion { background: #fdd } -pre .addition { +pre .hljs-addition { background: #dfd } -pre .diff .change { +pre .hljs-diff .hljs-change { background: #0086b3 } -pre .chunk { +pre .hljs-chunk { color: #aaa } -pre .tex .formula { +pre .hljs-tex .hljs-formula { opacity: 0.5; } diff --git a/docs/public/fonts/aller-bold.eot b/docs/public/fonts/aller-bold.eot old mode 100755 new mode 100644 diff --git a/docs/public/fonts/aller-bold.ttf b/docs/public/fonts/aller-bold.ttf old mode 100755 new mode 100644 diff --git a/docs/public/fonts/aller-bold.woff b/docs/public/fonts/aller-bold.woff old mode 100755 new mode 100644 diff --git a/docs/public/fonts/aller-light.eot b/docs/public/fonts/aller-light.eot old mode 100755 new mode 100644 diff --git a/docs/public/fonts/aller-light.ttf b/docs/public/fonts/aller-light.ttf old mode 100755 new mode 100644 diff --git a/docs/public/fonts/aller-light.woff b/docs/public/fonts/aller-light.woff old mode 100755 new mode 100644 diff --git a/docs/public/fonts/novecento-bold.eot b/docs/public/fonts/novecento-bold.eot old mode 100755 new mode 100644 diff --git a/docs/public/fonts/novecento-bold.ttf b/docs/public/fonts/novecento-bold.ttf old mode 100755 new mode 100644 diff --git a/docs/public/fonts/novecento-bold.woff b/docs/public/fonts/novecento-bold.woff old mode 100755 new mode 100644 diff --git a/docs/underscore.html b/docs/underscore.html index b96d40874..014d5dece 100644 --- a/docs/underscore.html +++ b/docs/underscore.html @@ -27,14 +27,15 @@

underscore.js

-
Underscore.js 1.5.2
-http://underscorejs.org
-(c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
-Underscore may be freely distributed under the MIT license.
- +
Underscore.js 1.6.0
+http://underscorejs.org
+(c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+Underscore may be freely distributed under the MIT license.
+
-
(function() {
+
+(function() {
@@ -42,10 +43,10 @@

underscore.js

  • -
    +
    -

    Baseline setup

    +

    Baseline setup

    @@ -58,12 +59,9 @@

    Baseline setup

    -

    Establish the root object, window in the browser, or exports on the server.

    - +
    -
      var root = this;
    -
  • @@ -73,11 +71,11 @@

    Baseline setup

    -

    Save the previous value of the _ variable.

    +

    Establish the root object, window in the browser, or exports on the server.

    -
      var previousUnderscore = root._;
    +
      var root = this;
    @@ -88,11 +86,11 @@

    Baseline setup

    -

    Establish the object that gets returned to break out of a loop iteration.

    +

    Save the previous value of the _ variable.

    -
      var breaker = {};
    +
      var previousUnderscore = root._;
    @@ -103,11 +101,11 @@

    Baseline setup

    -

    Save bytes in the minified (but not gzipped) version:

    +

    Establish the object that gets returned to break out of a loop iteration.

    -
      var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
    +
      var breaker = {};
    @@ -118,11 +116,26 @@

    Baseline setup

    +

    Save bytes in the minified (but not gzipped) version:

    + + + +
      var ArrayProto = Array.prototype, ObjProto = Object.prototype, FuncProto = Function.prototype;
    + + + + +
  • +
    + +
    + +

    Create quick reference variables for speed access to core prototypes.

    -
      var
    +            
      var
         push             = ArrayProto.push,
         slice            = ArrayProto.slice,
         concat           = ArrayProto.concat,
    @@ -132,18 +145,18 @@ 

    Baseline setup

  • -
  • +
  • - +

    All ECMAScript 5 native function implementations that we hope to use are declared here.

    -
      var
    +            
      var
         nativeForEach      = ArrayProto.forEach,
         nativeMap          = ArrayProto.map,
         nativeReduce       = ArrayProto.reduce,
    @@ -153,653 +166,667 @@ 

    Baseline setup

    nativeSome = ArrayProto.some, nativeIndexOf = ArrayProto.indexOf, nativeLastIndexOf = ArrayProto.lastIndexOf, - nativeIsArray = Array.isArray, - nativeKeys = Object.keys, + nativeIsArray = Array.isArray, + nativeKeys = Object.keys, nativeBind = FuncProto.bind;
  • -
  • +
  • - +

    Create a safe reference to the Underscore object for use below.

    -
      var _ = function(obj) {
    -    if (obj instanceof _) return obj;
    -    if (!(this instanceof _)) return new _(obj);
    -    this._wrapped = obj;
    +            
      var _ = function(obj) {
    +    if (obj instanceof _) return obj;
    +    if (!(this instanceof _)) return new _(obj);
    +    this._wrapped = obj;
       };
  • -
  • +
  • - +

    Export the Underscore object for Node.js, with -backwards-compatibility for the old require() API. If we're in +backwards-compatibility for the old require() API. If we’re in the browser, add _ as a global object via a string identifier, -for Closure Compiler "advanced" mode.

    +for Closure Compiler “advanced” mode.

    -
      if (typeof exports !== 'undefined') {
    -    if (typeof module !== 'undefined' && module.exports) {
    +            
      if (typeof exports !== 'undefined') {
    +    if (typeof module !== 'undefined' && module.exports) {
           exports = module.exports = _;
         }
         exports._ = _;
    -  } else {
    +  } else {
         root._ = _;
       }
  • -
  • +
  • - +

    Current version.

    -
      _.VERSION = '1.5.2';
    +
      _.VERSION = '1.6.0';
  • -
  • +
  • -
    - +
    +
    -

    Collection Functions

    +

    Collection Functions

  • -
  • +
  • - + +
    + +
    + +
  • + + +
  • +
    + +
    +

    The cornerstone, an each implementation, aka forEach. Handles objects with the built-in forEach, arrays, and raw objects. -Delegates to ECMAScript 5's native forEach if available.

    +Delegates to ECMAScript 5‘s native forEach if available.

    -
      var each = _.each = _.forEach = function(obj, iterator, context) {
    -    if (obj == null) return;
    -    if (nativeForEach && obj.forEach === nativeForEach) {
    +            
      var each = _.each = _.forEach = function(obj, iterator, context) {
    +    if (obj == null) return obj;
    +    if (nativeForEach && obj.forEach === nativeForEach) {
           obj.forEach(iterator, context);
    -    } else if (obj.length === +obj.length) {
    -      for (var i = 0, length = obj.length; i < length; i++) {
    -        if (iterator.call(context, obj[i], i, obj) === breaker) return;
    +    } else if (obj.length === +obj.length) {
    +      for (var i = 0, length = obj.length; i < length; i++) {
    +        if (iterator.call(context, obj[i], i, obj) === breaker) return;
           }
    -    } else {
    -      var keys = _.keys(obj);
    -      for (var i = 0, length = keys.length; i < length; i++) {
    -        if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
    +    } else {
    +      var keys = _.keys(obj);
    +      for (var i = 0, length = keys.length; i < length; i++) {
    +        if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return;
           }
         }
    +    return obj;
       };
  • -
  • +
  • - +

    Return the results of applying the iterator to each element. -Delegates to ECMAScript 5's native map if available.

    +Delegates to ECMAScript 5‘s native map if available.

    -
      _.map = _.collect = function(obj, iterator, context) {
    -    var results = [];
    -    if (obj == null) return results;
    -    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
    -    each(obj, function(value, index, list) {
    +            
      _.map = _.collect = function(obj, iterator, context) {
    +    var results = [];
    +    if (obj == null) return results;
    +    if (nativeMap && obj.map === nativeMap) return obj.map(iterator, context);
    +    each(obj, function(value, index, list) {
           results.push(iterator.call(context, value, index, list));
         });
    -    return results;
    +    return results;
       };
     
    -  var reduceError = 'Reduce of empty array with no initial value';
    + var reduceError = 'Reduce of empty array with no initial value';
  • -
  • +
  • - +

    Reduce builds up a single result from a list of values, aka inject, -or foldl. Delegates to ECMAScript 5's native reduce if available.

    +or foldl. Delegates to ECMAScript 5‘s native reduce if available.

    -
      _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
    -    var initial = arguments.length > 2;
    -    if (obj == null) obj = [];
    -    if (nativeReduce && obj.reduce === nativeReduce) {
    -      if (context) iterator = _.bind(iterator, context);
    -      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
    +            
      _.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
    +    var initial = arguments.length > 2;
    +    if (obj == null) obj = [];
    +    if (nativeReduce && obj.reduce === nativeReduce) {
    +      if (context) iterator = _.bind(iterator, context);
    +      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
         }
    -    each(obj, function(value, index, list) {
    -      if (!initial) {
    +    each(obj, function(value, index, list) {
    +      if (!initial) {
             memo = value;
    -        initial = true;
    -      } else {
    +        initial = true;
    +      } else {
             memo = iterator.call(context, memo, value, index, list);
           }
         });
    -    if (!initial) throw new TypeError(reduceError);
    -    return memo;
    +    if (!initial) throw new TypeError(reduceError);
    +    return memo;
       };
  • -
  • +
  • - +

    The right-associative version of reduce, also known as foldr. -Delegates to ECMAScript 5's native reduceRight if available.

    +Delegates to ECMAScript 5‘s native reduceRight if available.

    -
      _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
    -    var initial = arguments.length > 2;
    -    if (obj == null) obj = [];
    -    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
    -      if (context) iterator = _.bind(iterator, context);
    -      return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
    +            
      _.reduceRight = _.foldr = function(obj, iterator, memo, context) {
    +    var initial = arguments.length > 2;
    +    if (obj == null) obj = [];
    +    if (nativeReduceRight && obj.reduceRight === nativeReduceRight) {
    +      if (context) iterator = _.bind(iterator, context);
    +      return initial ? obj.reduceRight(iterator, memo) : obj.reduceRight(iterator);
         }
    -    var length = obj.length;
    -    if (length !== +length) {
    -      var keys = _.keys(obj);
    +    var length = obj.length;
    +    if (length !== +length) {
    +      var keys = _.keys(obj);
           length = keys.length;
         }
    -    each(obj, function(value, index, list) {
    +    each(obj, function(value, index, list) {
           index = keys ? keys[--length] : --length;
    -      if (!initial) {
    +      if (!initial) {
             memo = obj[index];
    -        initial = true;
    -      } else {
    +        initial = true;
    +      } else {
             memo = iterator.call(context, memo, obj[index], index, list);
           }
         });
    -    if (!initial) throw new TypeError(reduceError);
    -    return memo;
    +    if (!initial) throw new TypeError(reduceError);
    +    return memo;
       };
  • -
  • +
  • - +

    Return the first value which passes a truth test. Aliased as detect.

    -
      _.find = _.detect = function(obj, iterator, context) {
    -    var result;
    -    any(obj, function(value, index, list) {
    -      if (iterator.call(context, value, index, list)) {
    +            
      _.find = _.detect = function(obj, predicate, context) {
    +    var result;
    +    any(obj, function(value, index, list) {
    +      if (predicate.call(context, value, index, list)) {
             result = value;
    -        return true;
    +        return true;
           }
         });
    -    return result;
    +    return result;
       };
  • -
  • +
  • - +

    Return all the elements that pass a truth test. -Delegates to ECMAScript 5's native filter if available. +Delegates to ECMAScript 5‘s native filter if available. Aliased as select.

    -
      _.filter = _.select = function(obj, iterator, context) {
    -    var results = [];
    -    if (obj == null) return results;
    -    if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context);
    -    each(obj, function(value, index, list) {
    -      if (iterator.call(context, value, index, list)) results.push(value);
    +            
      _.filter = _.select = function(obj, predicate, context) {
    +    var results = [];
    +    if (obj == null) return results;
    +    if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context);
    +    each(obj, function(value, index, list) {
    +      if (predicate.call(context, value, index, list)) results.push(value);
         });
    -    return results;
    +    return results;
       };
  • -
  • +
  • - +

    Return all the elements for which a truth test fails.

    -
      _.reject = function(obj, iterator, context) {
    -    return _.filter(obj, function(value, index, list) {
    -      return !iterator.call(context, value, index, list);
    +            
      _.reject = function(obj, predicate, context) {
    +    return _.filter(obj, function(value, index, list) {
    +      return !predicate.call(context, value, index, list);
         }, context);
       };
  • -
  • +
  • - +

    Determine whether all of the elements match a truth test. -Delegates to ECMAScript 5's native every if available. +Delegates to ECMAScript 5‘s native every if available. Aliased as all.

    -
      _.every = _.all = function(obj, iterator, context) {
    -    iterator || (iterator = _.identity);
    -    var result = true;
    -    if (obj == null) return result;
    -    if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context);
    -    each(obj, function(value, index, list) {
    -      if (!(result = result && iterator.call(context, value, index, list))) return breaker;
    +            
      _.every = _.all = function(obj, predicate, context) {
    +    predicate || (predicate = _.identity);
    +    var result = true;
    +    if (obj == null) return result;
    +    if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context);
    +    each(obj, function(value, index, list) {
    +      if (!(result = result && predicate.call(context, value, index, list))) return breaker;
         });
    -    return !!result;
    +    return !!result;
       };
  • -
  • +
  • - +

    Determine if at least one element in the object matches a truth test. -Delegates to ECMAScript 5's native some if available. +Delegates to ECMAScript 5‘s native some if available. Aliased as any.

    -
      var any = _.some = _.any = function(obj, iterator, context) {
    -    iterator || (iterator = _.identity);
    -    var result = false;
    -    if (obj == null) return result;
    -    if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context);
    -    each(obj, function(value, index, list) {
    -      if (result || (result = iterator.call(context, value, index, list))) return breaker;
    +            
      var any = _.some = _.any = function(obj, predicate, context) {
    +    predicate || (predicate = _.identity);
    +    var result = false;
    +    if (obj == null) return result;
    +    if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context);
    +    each(obj, function(value, index, list) {
    +      if (result || (result = predicate.call(context, value, index, list))) return breaker;
         });
    -    return !!result;
    +    return !!result;
       };
  • -
  • +
  • - +

    Determine if the array or object contains a given value (using ===). Aliased as include.

    -
      _.contains = _.include = function(obj, target) {
    -    if (obj == null) return false;
    -    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
    -    return any(obj, function(value) {
    -      return value === target;
    +            
      _.contains = _.include = function(obj, target) {
    +    if (obj == null) return false;
    +    if (nativeIndexOf && obj.indexOf === nativeIndexOf) return obj.indexOf(target) != -1;
    +    return any(obj, function(value) {
    +      return value === target;
         });
       };
  • -
  • +
  • - +

    Invoke a method (with arguments) on every item in a collection.

    -
      _.invoke = function(obj, method) {
    -    var args = slice.call(arguments, 2);
    -    var isFunc = _.isFunction(method);
    -    return _.map(obj, function(value) {
    -      return (isFunc ? method : value[method]).apply(value, args);
    +            
      _.invoke = function(obj, method) {
    +    var args = slice.call(arguments, 2);
    +    var isFunc = _.isFunction(method);
    +    return _.map(obj, function(value) {
    +      return (isFunc ? method : value[method]).apply(value, args);
         });
       };
  • -
  • +
  • - +

    Convenience version of a common use case of map: fetching a property.

    -
      _.pluck = function(obj, key) {
    -    return _.map(obj, function(value){ return value[key]; });
    +            
      _.pluck = function(obj, key) {
    +    return _.map(obj, _.property(key));
       };
  • -
  • +
  • - +

    Convenience version of a common use case of filter: selecting only objects containing specific key:value pairs.

    -
      _.where = function(obj, attrs, first) {
    -    if (_.isEmpty(attrs)) return first ? void 0 : [];
    -    return _[first ? 'find' : 'filter'](obj, function(value) {
    -      for (var key in attrs) {
    -        if (attrs[key] !== value[key]) return false;
    -      }
    -      return true;
    -    });
    +            
      _.where = function(obj, attrs) {
    +    return _.filter(obj, _.matches(attrs));
       };
  • -
  • +
  • - +

    Convenience version of a common use case of find: getting the first object containing specific key:value pairs.

    -
      _.findWhere = function(obj, attrs) {
    -    return _.where(obj, attrs, true);
    +            
      _.findWhere = function(obj, attrs) {
    +    return _.find(obj, _.matches(attrs));
       };
  • -
  • +
  • - +

    Return the maximum element or (element-based computation). -Can't optimize arrays of integers longer than 65,535 elements. +Can’t optimize arrays of integers longer than 65,535 elements. See WebKit Bug 80797

    -
      _.max = function(obj, iterator, context) {
    -    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
    -      return Math.max.apply(Math, obj);
    +            
      _.max = function(obj, iterator, context) {
    +    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
    +      return Math.max.apply(Math, obj);
         }
    -    if (!iterator && _.isEmpty(obj)) return -Infinity;
    -    var result = {computed : -Infinity, value: -Infinity};
    -    each(obj, function(value, index, list) {
    -      var computed = iterator ? iterator.call(context, value, index, list) : value;
    -      computed > result.computed && (result = {value : value, computed : computed});
    +    var result = -Infinity, lastComputed = -Infinity;
    +    each(obj, function(value, index, list) {
    +      var computed = iterator ? iterator.call(context, value, index, list) : value;
    +      if (computed > lastComputed) {
    +        result = value;
    +        lastComputed = computed;
    +      }
         });
    -    return result.value;
    +    return result;
       };
  • -
  • +
  • - +

    Return the minimum element (or element-based computation).

    -
      _.min = function(obj, iterator, context) {
    -    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
    -      return Math.min.apply(Math, obj);
    +            
      _.min = function(obj, iterator, context) {
    +    if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) {
    +      return Math.min.apply(Math, obj);
         }
    -    if (!iterator && _.isEmpty(obj)) return Infinity;
    -    var result = {computed : Infinity, value: Infinity};
    -    each(obj, function(value, index, list) {
    -      var computed = iterator ? iterator.call(context, value, index, list) : value;
    -      computed < result.computed && (result = {value : value, computed : computed});
    +    var result = Infinity, lastComputed = Infinity;
    +    each(obj, function(value, index, list) {
    +      var computed = iterator ? iterator.call(context, value, index, list) : value;
    +      if (computed < lastComputed) {
    +        result = value;
    +        lastComputed = computed;
    +      }
         });
    -    return result.value;
    +    return result;
       };
  • -
  • +
  • - +
    -

    Shuffle an array, using the modern version of the +

    Shuffle an array, using the modern version of the Fisher-Yates shuffle.

    -
      _.shuffle = function(obj) {
    -    var rand;
    -    var index = 0;
    -    var shuffled = [];
    -    each(obj, function(value) {
    +            
      _.shuffle = function(obj) {
    +    var rand;
    +    var index = 0;
    +    var shuffled = [];
    +    each(obj, function(value) {
           rand = _.random(index++);
    -      shuffled[index - 1] = shuffled[rand];
    +      shuffled[index - 1] = shuffled[rand];
           shuffled[rand] = value;
         });
    -    return shuffled;
    +    return shuffled;
       };
  • -
  • +
  • - +
    -

    Sample n random values from an array. -If n is not specified, returns a single random element from the array. +

    Sample n random values from a collection. +If n is not specified, returns a single random element. The internal guard argument allows it to work with map.

    -
      _.sample = function(obj, n, guard) {
    -    if (arguments.length < 2 || guard) {
    -      return obj[_.random(obj.length - 1)];
    +            
      _.sample = function(obj, n, guard) {
    +    if (n == null || guard) {
    +      if (obj.length !== +obj.length) obj = _.values(obj);
    +      return obj[_.random(obj.length - 1)];
         }
    -    return _.shuffle(obj).slice(0, Math.max(0, n));
    +    return _.shuffle(obj).slice(0, Math.max(0, n));
       };
  • -
  • +
  • - +

    An internal function to generate lookup iterators.

    -
      var lookupIterator = function(value) {
    -    return _.isFunction(value) ? value : function(obj){ return obj[value]; };
    +            
      var lookupIterator = function(value) {
    +    if (value == null) return _.identity;
    +    if (_.isFunction(value)) return value;
    +    return _.property(value);
       };
  • -
  • +
  • - +
    -

    Sort the object's values by a criterion produced by an iterator.

    +

    Sort the object’s values by a criterion produced by an iterator.

    -
      _.sortBy = function(obj, value, context) {
    -    var iterator = lookupIterator(value);
    -    return _.pluck(_.map(obj, function(value, index, list) {
    -      return {
    +            
      _.sortBy = function(obj, iterator, context) {
    +    iterator = lookupIterator(iterator);
    +    return _.pluck(_.map(obj, function(value, index, list) {
    +      return {
             value: value,
             index: index,
             criteria: iterator.call(context, value, index, list)
           };
    -    }).sort(function(left, right) {
    -      var a = left.criteria;
    -      var b = right.criteria;
    -      if (a !== b) {
    -        if (a > b || a === void 0) return 1;
    -        if (a < b || b === void 0) return -1;
    +    }).sort(function(left, right) {
    +      var a = left.criteria;
    +      var b = right.criteria;
    +      if (a !== b) {
    +        if (a > b || a === void 0) return 1;
    +        if (a < b || b === void 0) return -1;
           }
    -      return left.index - right.index;
    -    }), 'value');
    +      return left.index - right.index;
    +    }), 'value');
       };
  • -
  • +
  • - +
    -

    An internal function used for aggregate "group by" operations.

    +

    An internal function used for aggregate “group by” operations.

    -
      var group = function(behavior) {
    -    return function(obj, value, context) {
    -      var result = {};
    -      var iterator = value == null ? _.identity : lookupIterator(value);
    -      each(obj, function(value, index) {
    -        var key = iterator.call(context, value, index, obj);
    +            
      var group = function(behavior) {
    +    return function(obj, iterator, context) {
    +      var result = {};
    +      iterator = lookupIterator(iterator);
    +      each(obj, function(value, index) {
    +        var key = iterator.call(context, value, index, obj);
             behavior(result, key, value);
           });
    -      return result;
    +      return result;
         };
       };
  • -
  • +
  • - +
    -

    Groups the object's values by a criterion. Pass either a string attribute +

    Groups the object’s values by a criterion. Pass either a string attribute to group by, or a function that returns the criterion.

    -
      _.groupBy = group(function(result, key, value) {
    -    (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
    +            
      _.groupBy = group(function(result, key, value) {
    +    _.has(result, key) ? result[key].push(value) : result[key] = [value];
       });
  • -
  • +
  • - +
    -

    Indexes the object's values by a criterion, similar to groupBy, but for +

    Indexes the object’s values by a criterion, similar to groupBy, but for when you know that your index values will be unique.

    -
      _.indexBy = group(function(result, key, value) {
    +            
      _.indexBy = group(function(result, key, value) {
         result[key] = value;
       });
  • -
  • +
  • - +

    Counts instances of an object that group by a certain criterion. Pass either a string attribute to count by, or a function that returns the @@ -807,94 +834,106 @@

    Collection Functions

    -
      _.countBy = group(function(result, key) {
    -    _.has(result, key) ? result[key]++ : result[key] = 1;
    +            
      _.countBy = group(function(result, key) {
    +    _.has(result, key) ? result[key]++ : result[key] = 1;
       });
  • -
  • +
  • - +

    Use a comparator function to figure out the smallest index at which an object should be inserted so as to maintain order. Uses binary search.

    -
      _.sortedIndex = function(array, obj, iterator, context) {
    -    iterator = iterator == null ? _.identity : lookupIterator(iterator);
    -    var value = iterator.call(context, obj);
    -    var low = 0, high = array.length;
    -    while (low < high) {
    -      var mid = (low + high) >>> 1;
    -      iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
    +            
      _.sortedIndex = function(array, obj, iterator, context) {
    +    iterator = lookupIterator(iterator);
    +    var value = iterator.call(context, obj);
    +    var low = 0, high = array.length;
    +    while (low < high) {
    +      var mid = (low + high) >>> 1;
    +      iterator.call(context, array[mid]) < value ? low = mid + 1 : high = mid;
         }
    -    return low;
    +    return low;
       };
  • -
  • +
  • - +

    Safely create a real, live array from anything iterable.

    -
      _.toArray = function(obj) {
    -    if (!obj) return [];
    -    if (_.isArray(obj)) return slice.call(obj);
    -    if (obj.length === +obj.length) return _.map(obj, _.identity);
    -    return _.values(obj);
    +            
      _.toArray = function(obj) {
    +    if (!obj) return [];
    +    if (_.isArray(obj)) return slice.call(obj);
    +    if (obj.length === +obj.length) return _.map(obj, _.identity);
    +    return _.values(obj);
       };
  • -
  • +
  • - +

    Return the number of elements in an object.

    -
      _.size = function(obj) {
    -    if (obj == null) return 0;
    -    return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
    +            
      _.size = function(obj) {
    +    if (obj == null) return 0;
    +    return (obj.length === +obj.length) ? obj.length : _.keys(obj).length;
       };
  • -
  • +
  • -
    - +
    +
    -

    Array Functions

    +

    Array Functions

  • -
  • +
  • - + +
    + +
    + +
  • + + +
  • +
    + +
    +

    Get the first element of an array. Passing n will return the first N values in the array. Aliased as head and take. The guard check @@ -902,19 +941,21 @@

    Array Functions

    -
      _.first = _.head = _.take = function(array, n, guard) {
    -    if (array == null) return void 0;
    -    return (n == null) || guard ? array[0] : slice.call(array, 0, n);
    +            
      _.first = _.head = _.take = function(array, n, guard) {
    +    if (array == null) return void 0;
    +    if ((n == null) || guard) return array[0];
    +    if (n < 0) return [];
    +    return slice.call(array, 0, n);
       };
  • -
  • +
  • - +

    Returns everything but the last entry of the array. Especially useful on the arguments object. Passing n will return all the values in @@ -923,41 +964,38 @@

    Array Functions

    -
      _.initial = function(array, n, guard) {
    -    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
    +            
      _.initial = function(array, n, guard) {
    +    return slice.call(array, 0, array.length - ((n == null) || guard ? 1 : n));
       };
  • -
  • +
  • - +

    Get the last element of an array. Passing n will return the last N values in the array. The guard check allows it to work with _.map.

    -
      _.last = function(array, n, guard) {
    -    if (array == null) return void 0;
    -    if ((n == null) || guard) {
    -      return array[array.length - 1];
    -    } else {
    -      return slice.call(array, Math.max(array.length - n, 0));
    -    }
    +            
      _.last = function(array, n, guard) {
    +    if (array == null) return void 0;
    +    if ((n == null) || guard) return array[array.length - 1];
    +    return slice.call(array, Math.max(array.length - n, 0));
       };
  • -
  • +
  • - +

    Returns everything but the first entry of the array. Aliased as tail and drop. Especially useful on the arguments object. Passing an n will return @@ -966,96 +1004,118 @@

    Array Functions

    -
      _.rest = _.tail = _.drop = function(array, n, guard) {
    -    return slice.call(array, (n == null) || guard ? 1 : n);
    +            
      _.rest = _.tail = _.drop = function(array, n, guard) {
    +    return slice.call(array, (n == null) || guard ? 1 : n);
       };
  • -
  • +
  • - +

    Trim out all falsy values from an array.

    -
      _.compact = function(array) {
    -    return _.filter(array, _.identity);
    +            
      _.compact = function(array) {
    +    return _.filter(array, _.identity);
       };
  • -
  • +
  • - +

    Internal implementation of a recursive flatten function.

    -
      var flatten = function(input, shallow, output) {
    -    if (shallow && _.every(input, _.isArray)) {
    -      return concat.apply(output, input);
    +            
      var flatten = function(input, shallow, output) {
    +    if (shallow && _.every(input, _.isArray)) {
    +      return concat.apply(output, input);
         }
    -    each(input, function(value) {
    -      if (_.isArray(value) || _.isArguments(value)) {
    +    each(input, function(value) {
    +      if (_.isArray(value) || _.isArguments(value)) {
             shallow ? push.apply(output, value) : flatten(value, shallow, output);
    -      } else {
    +      } else {
             output.push(value);
           }
         });
    -    return output;
    +    return output;
       };
  • -
  • +
  • - +

    Flatten out an array, either recursively (by default), or just one level.

    -
      _.flatten = function(array, shallow) {
    -    return flatten(array, shallow, []);
    +            
      _.flatten = function(array, shallow) {
    +    return flatten(array, shallow, []);
       };
  • -
  • +
  • - +

    Return a version of the array that does not contain the specified value(s).

    -
      _.without = function(array) {
    -    return _.difference(array, slice.call(arguments, 1));
    +            
      _.without = function(array) {
    +    return _.difference(array, slice.call(arguments, 1));
       };
  • -
  • +
  • - + +
    +

    Split an array into two arrays: one whose elements all satisfy the given +predicate, and one whose elements all do not satisfy the predicate.

    + +
    + +
      _.partition = function(array, predicate) {
    +    var pass = [], fail = [];
    +    each(array, function(elem) {
    +      (predicate(elem) ? pass : fail).push(elem);
    +    });
    +    return [pass, fail];
    +  };
    + +
  • + + +
  • +
    + +
    +

    Produce a duplicate-free version of the array. If the array has already been sorted, you have the option of using a faster algorithm. @@ -1063,61 +1123,61 @@

    Array Functions

    -
      _.uniq = _.unique = function(array, isSorted, iterator, context) {
    -    if (_.isFunction(isSorted)) {
    +            
      _.uniq = _.unique = function(array, isSorted, iterator, context) {
    +    if (_.isFunction(isSorted)) {
           context = iterator;
           iterator = isSorted;
    -      isSorted = false;
    +      isSorted = false;
         }
    -    var initial = iterator ? _.map(array, iterator, context) : array;
    -    var results = [];
    -    var seen = [];
    -    each(initial, function(value, index) {
    -      if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
    +    var initial = iterator ? _.map(array, iterator, context) : array;
    +    var results = [];
    +    var seen = [];
    +    each(initial, function(value, index) {
    +      if (isSorted ? (!index || seen[seen.length - 1] !== value) : !_.contains(seen, value)) {
             seen.push(value);
             results.push(array[index]);
           }
         });
    -    return results;
    +    return results;
       };
  • -
  • +
  • - +

    Produce an array that contains the union: each distinct element from all of the passed-in arrays.

    -
      _.union = function() {
    -    return _.uniq(_.flatten(arguments, true));
    +            
      _.union = function() {
    +    return _.uniq(_.flatten(arguments, true));
       };
  • -
  • +
  • - +

    Produce an array that contains every item shared between all the passed-in arrays.

    -
      _.intersection = function(array) {
    -    var rest = slice.call(arguments, 1);
    -    return _.filter(_.uniq(array), function(item) {
    -      return _.every(rest, function(other) {
    -        return _.indexOf(other, item) >= 0;
    +            
      _.intersection = function(array) {
    +    var rest = slice.call(arguments, 1);
    +    return _.filter(_.uniq(array), function(item) {
    +      return _.every(rest, function(other) {
    +        return _.contains(other, item);
           });
         });
       };
    @@ -1125,139 +1185,139 @@

    Array Functions

  • -
  • +
  • - +

    Take the difference between one array and a number of other arrays. Only the elements present in just the first array will remain.

    -
      _.difference = function(array) {
    -    var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
    -    return _.filter(array, function(value){ return !_.contains(rest, value); });
    +            
      _.difference = function(array) {
    +    var rest = concat.apply(ArrayProto, slice.call(arguments, 1));
    +    return _.filter(array, function(value){ return !_.contains(rest, value); });
       };
  • -
  • +
  • - +
    -

    Zip together multiple lists into a single array -- elements that share +

    Zip together multiple lists into a single array — elements that share an index go together.

    -
      _.zip = function() {
    -    var length = _.max(_.pluck(arguments, "length").concat(0));
    -    var results = new Array(length);
    -    for (var i = 0; i < length; i++) {
    -      results[i] = _.pluck(arguments, '' + i);
    +            
      _.zip = function() {
    +    var length = _.max(_.pluck(arguments, 'length').concat(0));
    +    var results = new Array(length);
    +    for (var i = 0; i < length; i++) {
    +      results[i] = _.pluck(arguments, '' + i);
         }
    -    return results;
    +    return results;
       };
  • -
  • +
  • - +

    Converts lists into objects. Pass either a single array of [key, value] -pairs, or two parallel arrays of the same length -- one of keys, and one of +pairs, or two parallel arrays of the same length — one of keys, and one of the corresponding values.

    -
      _.object = function(list, values) {
    -    if (list == null) return {};
    -    var result = {};
    -    for (var i = 0, length = list.length; i < length; i++) {
    -      if (values) {
    +            
      _.object = function(list, values) {
    +    if (list == null) return {};
    +    var result = {};
    +    for (var i = 0, length = list.length; i < length; i++) {
    +      if (values) {
             result[list[i]] = values[i];
    -      } else {
    -        result[list[i][0]] = list[i][1];
    +      } else {
    +        result[list[i][0]] = list[i][1];
           }
         }
    -    return result;
    +    return result;
       };
  • -
  • +
  • - +
    -

    If the browser doesn't supply us with indexOf (I'm looking at you, MSIE), +

    If the browser doesn’t supply us with indexOf (I’m looking at you, MSIE), we need this function. Return the position of the first occurrence of an item in an array, or -1 if the item is not included in the array. -Delegates to ECMAScript 5's native indexOf if available. +Delegates to ECMAScript 5‘s native indexOf if available. If the array is large and already in sort order, pass true for isSorted to use binary search.

    -
      _.indexOf = function(array, item, isSorted) {
    -    if (array == null) return -1;
    -    var i = 0, length = array.length;
    -    if (isSorted) {
    -      if (typeof isSorted == 'number') {
    -        i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
    -      } else {
    +            
      _.indexOf = function(array, item, isSorted) {
    +    if (array == null) return -1;
    +    var i = 0, length = array.length;
    +    if (isSorted) {
    +      if (typeof isSorted == 'number') {
    +        i = (isSorted < 0 ? Math.max(0, length + isSorted) : isSorted);
    +      } else {
             i = _.sortedIndex(array, item);
    -        return array[i] === item ? i : -1;
    +        return array[i] === item ? i : -1;
           }
         }
    -    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
    -    for (; i < length; i++) if (array[i] === item) return i;
    -    return -1;
    +    if (nativeIndexOf && array.indexOf === nativeIndexOf) return array.indexOf(item, isSorted);
    +    for (; i < length; i++) if (array[i] === item) return i;
    +    return -1;
       };
  • -
  • +
  • - +
    -

    Delegates to ECMAScript 5's native lastIndexOf if available.

    +

    Delegates to ECMAScript 5‘s native lastIndexOf if available.

    -
      _.lastIndexOf = function(array, item, from) {
    -    if (array == null) return -1;
    -    var hasIndex = from != null;
    -    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
    -      return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
    +            
      _.lastIndexOf = function(array, item, from) {
    +    if (array == null) return -1;
    +    var hasIndex = from != null;
    +    if (nativeLastIndexOf && array.lastIndexOf === nativeLastIndexOf) {
    +      return hasIndex ? array.lastIndexOf(item, from) : array.lastIndexOf(item);
         }
    -    var i = (hasIndex ? from : array.length);
    -    while (i--) if (array[i] === item) return i;
    -    return -1;
    +    var i = (hasIndex ? from : array.length);
    +    while (i--) if (array[i] === item) return i;
    +    return -1;
       };
  • -
  • +
  • - +

    Generate an integer Array containing an arithmetic progression. A port of the native Python range() function. See @@ -1265,238 +1325,260 @@

    Array Functions

    -
      _.range = function(start, stop, step) {
    -    if (arguments.length <= 1) {
    -      stop = start || 0;
    -      start = 0;
    +            
      _.range = function(start, stop, step) {
    +    if (arguments.length <= 1) {
    +      stop = start || 0;
    +      start = 0;
         }
    -    step = arguments[2] || 1;
    +    step = arguments[2] || 1;
     
    -    var length = Math.max(Math.ceil((stop - start) / step), 0);
    -    var idx = 0;
    -    var range = new Array(length);
    +    var length = Math.max(Math.ceil((stop - start) / step), 0);
    +    var idx = 0;
    +    var range = new Array(length);
     
    -    while(idx < length) {
    +    while(idx < length) {
           range[idx++] = start;
           start += step;
         }
     
    -    return range;
    +    return range;
       };
  • -
  • +
  • -
    - +
    +
    -

    Function (ahem) Functions

    +

    Function (ahem) Functions

  • -
  • +
  • - + +
    + +
    + +
  • + + +
  • +
    + +
    +

    Reusable constructor function for prototype setting.

    -
      var ctor = function(){};
    +
      var ctor = function(){};
  • -
  • +
  • - +

    Create a function bound to a given object (assigning this, and arguments, -optionally). Delegates to ECMAScript 5's native Function.bind if +optionally). Delegates to ECMAScript 5‘s native Function.bind if available.

    -
      _.bind = function(func, context) {
    -    var args, bound;
    -    if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
    -    if (!_.isFunction(func)) throw new TypeError;
    -    args = slice.call(arguments, 2);
    -    return bound = function() {
    -      if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
    +            
      _.bind = function(func, context) {
    +    var args, bound;
    +    if (nativeBind && func.bind === nativeBind) return nativeBind.apply(func, slice.call(arguments, 1));
    +    if (!_.isFunction(func)) throw new TypeError;
    +    args = slice.call(arguments, 2);
    +    return bound = function() {
    +      if (!(this instanceof bound)) return func.apply(context, args.concat(slice.call(arguments)));
           ctor.prototype = func.prototype;
    -      var self = new ctor;
    -      ctor.prototype = null;
    -      var result = func.apply(self, args.concat(slice.call(arguments)));
    -      if (Object(result) === result) return result;
    -      return self;
    +      var self = new ctor;
    +      ctor.prototype = null;
    +      var result = func.apply(self, args.concat(slice.call(arguments)));
    +      if (Object(result) === result) return result;
    +      return self;
         };
       };
  • -
  • +
  • - +

    Partially apply a function by creating a version that has had some of its -arguments pre-filled, without changing its dynamic this context.

    +arguments pre-filled, without changing its dynamic this context. _ acts +as a placeholder, allowing any combination of arguments to be pre-filled.

    -
      _.partial = function(func) {
    -    var args = slice.call(arguments, 1);
    -    return function() {
    -      return func.apply(this, args.concat(slice.call(arguments)));
    +            
      _.partial = function(func) {
    +    var boundArgs = slice.call(arguments, 1);
    +    return function() {
    +      var position = 0;
    +      var args = boundArgs.slice();
    +      for (var i = 0, length = args.length; i < length; i++) {
    +        if (args[i] === _) args[i] = arguments[position++];
    +      }
    +      while (position < arguments.length) args.push(arguments[position++]);
    +      return func.apply(this, args);
         };
       };
  • -
  • +
  • - +
    -

    Bind all of an object's methods to that object. Useful for ensuring that -all callbacks defined on an object belong to it.

    +

    Bind a number of an object’s methods to that object. Remaining arguments +are the method names to be bound. Useful for ensuring that all callbacks +defined on an object belong to it.

    -
      _.bindAll = function(obj) {
    -    var funcs = slice.call(arguments, 1);
    -    if (funcs.length === 0) throw new Error("bindAll must be passed function names");
    -    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
    -    return obj;
    +            
      _.bindAll = function(obj) {
    +    var funcs = slice.call(arguments, 1);
    +    if (funcs.length === 0) throw new Error('bindAll must be passed function names');
    +    each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); });
    +    return obj;
       };
  • -
  • +
  • - +

    Memoize an expensive function by storing its results.

    -
      _.memoize = function(func, hasher) {
    -    var memo = {};
    +            
      _.memoize = function(func, hasher) {
    +    var memo = {};
         hasher || (hasher = _.identity);
    -    return function() {
    -      var key = hasher.apply(this, arguments);
    -      return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
    +    return function() {
    +      var key = hasher.apply(this, arguments);
    +      return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
         };
       };
  • -
  • +
  • - +

    Delays a function for the given number of milliseconds, and then calls it with the arguments supplied.

    -
      _.delay = function(func, wait) {
    -    var args = slice.call(arguments, 2);
    -    return setTimeout(function(){ return func.apply(null, args); }, wait);
    +            
      _.delay = function(func, wait) {
    +    var args = slice.call(arguments, 2);
    +    return setTimeout(function(){ return func.apply(null, args); }, wait);
       };
  • -
  • +
  • - +

    Defers a function, scheduling it to run after the current call stack has cleared.

    -
      _.defer = function(func) {
    -    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
    +            
      _.defer = function(func) {
    +    return _.delay.apply(_, [func, 1].concat(slice.call(arguments, 1)));
       };
  • -
  • +
  • - +

    Returns a function, that, when invoked, will only be triggered at most once during a given window of time. Normally, the throttled function will run as much as it can, without ever going more than once per wait duration; -but if you'd like to disable the execution on the leading edge, pass +but if you’d like to disable the execution on the leading edge, pass {leading: false}. To disable execution on the trailing edge, ditto.

    -
      _.throttle = function(func, wait, options) {
    -    var context, args, result;
    -    var timeout = null;
    -    var previous = 0;
    +            
      _.throttle = function(func, wait, options) {
    +    var context, args, result;
    +    var timeout = null;
    +    var previous = 0;
         options || (options = {});
    -    var later = function() {
    -      previous = options.leading === false ? 0 : new Date;
    -      timeout = null;
    +    var later = function() {
    +      previous = options.leading === false ? 0 : _.now();
    +      timeout = null;
           result = func.apply(context, args);
    +      context = args = null;
         };
    -    return function() {
    -      var now = new Date;
    -      if (!previous && options.leading === false) previous = now;
    -      var remaining = wait - (now - previous);
    -      context = this;
    -      args = arguments;
    -      if (remaining <= 0) {
    +    return function() {
    +      var now = _.now();
    +      if (!previous && options.leading === false) previous = now;
    +      var remaining = wait - (now - previous);
    +      context = this;
    +      args = arguments;
    +      if (remaining <= 0) {
             clearTimeout(timeout);
    -        timeout = null;
    +        timeout = null;
             previous = now;
             result = func.apply(context, args);
    -      } else if (!timeout && options.trailing !== false) {
    +        context = args = null;
    +      } else if (!timeout && options.trailing !== false) {
             timeout = setTimeout(later, remaining);
           }
    -      return result;
    +      return result;
         };
       };
  • -
  • +
  • - +

    Returns a function, that, as long as it continues to be invoked, will not be triggered. The function will be called after it stops being called for @@ -1505,63 +1587,72 @@

    Function (ahem) Functions

    -
      _.debounce = function(func, wait, immediate) {
    -    var timeout, args, context, timestamp, result;
    -    return function() {
    -      context = this;
    -      args = arguments;
    -      timestamp = new Date();
    -      var later = function() {
    -        var last = (new Date()) - timestamp;
    -        if (last < wait) {
    -          timeout = setTimeout(later, wait - last);
    -        } else {
    -          timeout = null;
    -          if (!immediate) result = func.apply(context, args);
    +            
      _.debounce = function(func, wait, immediate) {
    +    var timeout, args, context, timestamp, result;
    +
    +    var later = function() {
    +      var last = _.now() - timestamp;
    +      if (last < wait) {
    +        timeout = setTimeout(later, wait - last);
    +      } else {
    +        timeout = null;
    +        if (!immediate) {
    +          result = func.apply(context, args);
    +          context = args = null;
             }
    -      };
    -      var callNow = immediate && !timeout;
    -      if (!timeout) {
    +      }
    +    };
    +
    +    return function() {
    +      context = this;
    +      args = arguments;
    +      timestamp = _.now();
    +      var callNow = immediate && !timeout;
    +      if (!timeout) {
             timeout = setTimeout(later, wait);
           }
    -      if (callNow) result = func.apply(context, args);
    -      return result;
    +      if (callNow) {
    +        result = func.apply(context, args);
    +        context = args = null;
    +      }
    +
    +      return result;
         };
       };
  • -
  • +
  • - +

    Returns a function that will be executed at most one time, no matter how often you call it. Useful for lazy initialization.

    -
      _.once = function(func) {
    -    var ran = false, memo;
    -    return function() {
    -      if (ran) return memo;
    -      ran = true;
    -      memo = func.apply(this, arguments);
    -      func = null;
    -      return memo;
    +            
      _.once = function(func) {
    +    var ran = false, memo;
    +    return function() {
    +      if (ran) return memo;
    +      ran = true;
    +      memo = func.apply(this, arguments);
    +      func = null;
    +      return memo;
         };
       };
  • -
  • +
  • - +

    Returns the first function passed as an argument to the second, allowing you to adjust arguments, run code before and after, and @@ -1569,56 +1660,52 @@

    Function (ahem) Functions

    -
      _.wrap = function(func, wrapper) {
    -    return function() {
    -      var args = [func];
    -      push.apply(args, arguments);
    -      return wrapper.apply(this, args);
    -    };
    +            
      _.wrap = function(func, wrapper) {
    +    return _.partial(wrapper, func);
       };
  • -
  • +
  • - +

    Returns a function that is the composition of a list of functions, each consuming the return value of the function that follows.

    -
      _.compose = function() {
    -    var funcs = arguments;
    -    return function() {
    -      var args = arguments;
    -      for (var i = funcs.length - 1; i >= 0; i--) {
    -        args = [funcs[i].apply(this, args)];
    +            
      _.compose = function() {
    +    var funcs = arguments;
    +    return function() {
    +      var args = arguments;
    +      for (var i = funcs.length - 1; i >= 0; i--) {
    +        args = [funcs[i].apply(this, args)];
           }
    -      return args[0];
    +      return args[0];
         };
       };
  • -
  • +
  • - +

    Returns a function that will only be executed after being called N times.

    -
      _.after = function(times, func) {
    -    return function() {
    -      if (--times < 1) {
    -        return func.apply(this, arguments);
    +            
      _.after = function(times, func) {
    +    return function() {
    +      if (--times < 1) {
    +        return func.apply(this, arguments);
           }
         };
       };
    @@ -1626,394 +1713,407 @@

    Function (ahem) Functions

  • -
  • +
  • -
    - +
    +
    -

    Object Functions

    +

    Object Functions

  • -
  • +
  • - + +
    + +
    + +
  • + + +
  • +
    + +
    +
    -

    Retrieve the names of an object's properties. -Delegates to ECMAScript 5's native Object.keys

    +

    Retrieve the names of an object’s properties. +Delegates to ECMAScript 5‘s native Object.keys

    -
      _.keys = nativeKeys || function(obj) {
    -    if (obj !== Object(obj)) throw new TypeError('Invalid object');
    -    var keys = [];
    -    for (var key in obj) if (_.has(obj, key)) keys.push(key);
    -    return keys;
    +            
      _.keys = function(obj) {
    +    if (!_.isObject(obj)) return [];
    +    if (nativeKeys) return nativeKeys(obj);
    +    var keys = [];
    +    for (var key in obj) if (_.has(obj, key)) keys.push(key);
    +    return keys;
       };
  • -
  • +
  • - +
    -

    Retrieve the values of an object's properties.

    +

    Retrieve the values of an object’s properties.

    -
      _.values = function(obj) {
    -    var keys = _.keys(obj);
    -    var length = keys.length;
    -    var values = new Array(length);
    -    for (var i = 0; i < length; i++) {
    +            
      _.values = function(obj) {
    +    var keys = _.keys(obj);
    +    var length = keys.length;
    +    var values = new Array(length);
    +    for (var i = 0; i < length; i++) {
           values[i] = obj[keys[i]];
         }
    -    return values;
    +    return values;
       };
  • -
  • +
  • - +

    Convert an object into a list of [key, value] pairs.

    -
      _.pairs = function(obj) {
    -    var keys = _.keys(obj);
    -    var length = keys.length;
    -    var pairs = new Array(length);
    -    for (var i = 0; i < length; i++) {
    +            
      _.pairs = function(obj) {
    +    var keys = _.keys(obj);
    +    var length = keys.length;
    +    var pairs = new Array(length);
    +    for (var i = 0; i < length; i++) {
           pairs[i] = [keys[i], obj[keys[i]]];
         }
    -    return pairs;
    +    return pairs;
       };
  • -
  • +
  • - +

    Invert the keys and values of an object. The values must be serializable.

    -
      _.invert = function(obj) {
    -    var result = {};
    -    var keys = _.keys(obj);
    -    for (var i = 0, length = keys.length; i < length; i++) {
    +            
      _.invert = function(obj) {
    +    var result = {};
    +    var keys = _.keys(obj);
    +    for (var i = 0, length = keys.length; i < length; i++) {
           result[obj[keys[i]]] = keys[i];
         }
    -    return result;
    +    return result;
       };
  • -
  • +
  • - +

    Return a sorted list of the function names available on the object. Aliased as methods

    -
      _.functions = _.methods = function(obj) {
    -    var names = [];
    -    for (var key in obj) {
    -      if (_.isFunction(obj[key])) names.push(key);
    +            
      _.functions = _.methods = function(obj) {
    +    var names = [];
    +    for (var key in obj) {
    +      if (_.isFunction(obj[key])) names.push(key);
         }
    -    return names.sort();
    +    return names.sort();
       };
  • -
  • +
  • - +

    Extend a given object with all the properties in passed-in object(s).

    -
      _.extend = function(obj) {
    -    each(slice.call(arguments, 1), function(source) {
    -      if (source) {
    -        for (var prop in source) {
    +            
      _.extend = function(obj) {
    +    each(slice.call(arguments, 1), function(source) {
    +      if (source) {
    +        for (var prop in source) {
               obj[prop] = source[prop];
             }
           }
         });
    -    return obj;
    +    return obj;
       };
  • -
  • +
  • - +

    Return a copy of the object only containing the whitelisted properties.

    -
      _.pick = function(obj) {
    -    var copy = {};
    -    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
    -    each(keys, function(key) {
    -      if (key in obj) copy[key] = obj[key];
    +            
      _.pick = function(obj) {
    +    var copy = {};
    +    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
    +    each(keys, function(key) {
    +      if (key in obj) copy[key] = obj[key];
         });
    -    return copy;
    +    return copy;
       };
  • -
  • +
  • - +

    Return a copy of the object without the blacklisted properties.

    -
      _.omit = function(obj) {
    -    var copy = {};
    -    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
    -    for (var key in obj) {
    -      if (!_.contains(keys, key)) copy[key] = obj[key];
    +            
      _.omit = function(obj) {
    +    var copy = {};
    +    var keys = concat.apply(ArrayProto, slice.call(arguments, 1));
    +    for (var key in obj) {
    +      if (!_.contains(keys, key)) copy[key] = obj[key];
         }
    -    return copy;
    +    return copy;
       };
  • -
  • +
  • - +

    Fill in a given object with default properties.

    -
      _.defaults = function(obj) {
    -    each(slice.call(arguments, 1), function(source) {
    -      if (source) {
    -        for (var prop in source) {
    -          if (obj[prop] === void 0) obj[prop] = source[prop];
    +            
      _.defaults = function(obj) {
    +    each(slice.call(arguments, 1), function(source) {
    +      if (source) {
    +        for (var prop in source) {
    +          if (obj[prop] === void 0) obj[prop] = source[prop];
             }
           }
         });
    -    return obj;
    +    return obj;
       };
  • -
  • +
  • - +

    Create a (shallow-cloned) duplicate of an object.

    -
      _.clone = function(obj) {
    -    if (!_.isObject(obj)) return obj;
    -    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
    +            
      _.clone = function(obj) {
    +    if (!_.isObject(obj)) return obj;
    +    return _.isArray(obj) ? obj.slice() : _.extend({}, obj);
       };
  • -
  • +
  • - +

    Invokes interceptor with the obj, and then returns obj. -The primary purpose of this method is to "tap into" a method chain, in +The primary purpose of this method is to “tap into” a method chain, in order to perform operations on intermediate results within the chain.

    -
      _.tap = function(obj, interceptor) {
    +            
      _.tap = function(obj, interceptor) {
         interceptor(obj);
    -    return obj;
    +    return obj;
       };
  • -
  • +
  • - +

    Internal recursive comparison function for isEqual.

    -
      var eq = function(a, b, aStack, bStack) {
    +
      var eq = function(a, b, aStack, bStack) {
  • -
  • +
  • - +
    -

    Identical objects are equal. 0 === -0, but they aren't identical. +

    Identical objects are equal. 0 === -0, but they aren’t identical. See the Harmony egal proposal.

    -
        if (a === b) return a !== 0 || 1 / a == 1 / b;
    +
        if (a === b) return a !== 0 || 1 / a == 1 / b;
  • -
  • +
  • - +

    A strict comparison is necessary because null == undefined.

    -
        if (a == null || b == null) return a === b;
    +
        if (a == null || b == null) return a === b;
  • -
  • +
  • - +

    Unwrap any wrapped objects.

    -
        if (a instanceof _) a = a._wrapped;
    -    if (b instanceof _) b = b._wrapped;
    +
        if (a instanceof _) a = a._wrapped;
    +    if (b instanceof _) b = b._wrapped;
  • -
  • +
  • - +

    Compare [[Class]] names.

    -
        var className = toString.call(a);
    -    if (className != toString.call(b)) return false;
    -    switch (className) {
    +
        var className = toString.call(a);
    +    if (className != toString.call(b)) return false;
    +    switch (className) {
  • -
  • +
  • - +

    Strings, numbers, dates, and booleans are compared by value.

    -
          case '[object String]':
    +
          case '[object String]':
  • -
  • +
  • - +

    Primitives and their corresponding object wrappers are equivalent; thus, "5" is equivalent to new String("5").

    -
            return a == String(b);
    -      case '[object Number]':
    +
            return a == String(b);
    +      case '[object Number]':
  • -
  • +
  • - +

    NaNs are equivalent, but non-reflexive. An egal comparison is performed for other numeric values.

    -
            return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
    -      case '[object Date]':
    -      case '[object Boolean]':
    +
            return a != +a ? b != +b : (a == 0 ? 1 / a == 1 / b : a == +b);
    +      case '[object Date]':
    +      case '[object Boolean]':
  • -
  • +
  • - +

    Coerce dates and booleans to numeric primitive values. Dates are compared by their millisecond representations. Note that invalid dates with millisecond representations @@ -2021,91 +2121,92 @@

    Object Functions

    -
            return +a == +b;
    +
            return +a == +b;
  • -
  • +
  • - +

    RegExps are compared by their source patterns and flags.

    -
          case '[object RegExp]':
    -        return a.source == b.source &&
    +            
          case '[object RegExp]':
    +        return a.source == b.source &&
                    a.global == b.global &&
                    a.multiline == b.multiline &&
                    a.ignoreCase == b.ignoreCase;
         }
    -    if (typeof a != 'object' || typeof b != 'object') return false;
    + if (typeof a != 'object' || typeof b != 'object') return false;
  • -
  • +
  • - +

    Assume equality for cyclic structures. The algorithm for detecting cyclic structures is adapted from ES 5.1 section 15.12.3, abstract operation JO.

    -
        var length = aStack.length;
    -    while (length--) {
    +
        var length = aStack.length;
    +    while (length--) {
  • -
  • +
  • - +

    Linear search. Performance is inversely proportional to the number of unique nested structures.

    -
          if (aStack[length] == a) return bStack[length] == b;
    +            
          if (aStack[length] == a) return bStack[length] == b;
         }
  • -
  • +
  • - +

    Objects with different constructors are not equivalent, but Objects from different frames are.

    -
        var aCtor = a.constructor, bCtor = b.constructor;
    -    if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
    -                             _.isFunction(bCtor) && (bCtor instanceof bCtor))) {
    -      return false;
    +            
        var aCtor = a.constructor, bCtor = b.constructor;
    +    if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) &&
    +                             _.isFunction(bCtor) && (bCtor instanceof bCtor))
    +                        && ('constructor' in a && 'constructor' in b)) {
    +      return false;
         }
  • -
  • +
  • - +

    Add the first object to the stack of traversed objects.

    @@ -2113,31 +2214,31 @@

    Object Functions

        aStack.push(a);
         bStack.push(b);
    -    var size = 0, result = true;
    + var size = 0, result = true;
  • -
  • +
  • - +

    Recursively compare objects and arrays.

    -
        if (className == '[object Array]') {
    +
        if (className == '[object Array]') {
  • -
  • +
  • - +

    Compare array lengths to determine if a deep comparison is necessary.

    @@ -2145,51 +2246,51 @@

    Object Functions

          size = a.length;
           result = size == b.length;
    -      if (result) {
    + if (result) {
  • -
  • +
  • - +

    Deep compare the contents, ignoring non-numeric properties.

    -
            while (size--) {
    -          if (!(result = eq(a[size], b[size], aStack, bStack))) break;
    +            
            while (size--) {
    +          if (!(result = eq(a[size], b[size], aStack, bStack))) break;
             }
           }
    -    } else {
    + } else {
  • -
  • +
  • - +

    Deep compare objects.

    -
          for (var key in a) {
    -        if (_.has(a, key)) {
    +
          for (var key in a) {
    +        if (_.has(a, key)) {
  • -
  • +
  • - +

    Count the expected number of properties.

    @@ -2200,36 +2301,36 @@

    Object Functions

  • -
  • +
  • - +

    Deep compare each member.

    -
              if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
    +            
              if (!(result = _.has(b, key) && eq(a[key], b[key], aStack, bStack))) break;
             }
           }
  • -
  • +
  • - +

    Ensure that both objects contain the same number of properties.

    -
          if (result) {
    -        for (key in b) {
    -          if (_.has(b, key) && !(size--)) break;
    +            
          if (result) {
    +        for (key in b) {
    +          if (_.has(b, key) && !(size--)) break;
             }
             result = !size;
           }
    @@ -2238,11 +2339,11 @@ 

    Object Functions

  • -
  • +
  • - +

    Remove the first object from the stack of traversed objects.

    @@ -2250,369 +2351,432 @@

    Object Functions

        aStack.pop();
         bStack.pop();
    -    return result;
    +    return result;
       };
  • -
  • +
  • - +

    Perform a deep comparison to check if two objects are equal.

    -
      _.isEqual = function(a, b) {
    -    return eq(a, b, [], []);
    +            
      _.isEqual = function(a, b) {
    +    return eq(a, b, [], []);
       };
  • -
  • +
  • - +

    Is a given array, string, or object empty? -An "empty" object has no enumerable own-properties.

    +An “empty” object has no enumerable own-properties.

    -
      _.isEmpty = function(obj) {
    -    if (obj == null) return true;
    -    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
    -    for (var key in obj) if (_.has(obj, key)) return false;
    -    return true;
    +            
      _.isEmpty = function(obj) {
    +    if (obj == null) return true;
    +    if (_.isArray(obj) || _.isString(obj)) return obj.length === 0;
    +    for (var key in obj) if (_.has(obj, key)) return false;
    +    return true;
       };
  • -
  • +
  • - +

    Is a given value a DOM element?

    -
      _.isElement = function(obj) {
    -    return !!(obj && obj.nodeType === 1);
    +            
      _.isElement = function(obj) {
    +    return !!(obj && obj.nodeType === 1);
       };
  • -
  • +
  • - +

    Is a given value an array? -Delegates to ECMA5's native Array.isArray

    +Delegates to ECMA5’s native Array.isArray

    -
      _.isArray = nativeIsArray || function(obj) {
    -    return toString.call(obj) == '[object Array]';
    +            
      _.isArray = nativeIsArray || function(obj) {
    +    return toString.call(obj) == '[object Array]';
       };
  • -
  • +
  • - +

    Is a given variable an object?

    -
      _.isObject = function(obj) {
    -    return obj === Object(obj);
    +            
      _.isObject = function(obj) {
    +    return obj === Object(obj);
       };
  • -
  • +
  • - +

    Add some isType methods: isArguments, isFunction, isString, isNumber, isDate, isRegExp.

    -
      each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
    -    _['is' + name] = function(obj) {
    -      return toString.call(obj) == '[object ' + name + ']';
    +            
      each(['Arguments', 'Function', 'String', 'Number', 'Date', 'RegExp'], function(name) {
    +    _['is' + name] = function(obj) {
    +      return toString.call(obj) == '[object ' + name + ']';
         };
       });
  • -
  • +
  • - +

    Define a fallback version of the method in browsers (ahem, IE), where -there isn't any inspectable "Arguments" type.

    +there isn’t any inspectable “Arguments” type.

    -
      if (!_.isArguments(arguments)) {
    -    _.isArguments = function(obj) {
    -      return !!(obj && _.has(obj, 'callee'));
    +            
      if (!_.isArguments(arguments)) {
    +    _.isArguments = function(obj) {
    +      return !!(obj && _.has(obj, 'callee'));
         };
       }
  • -
  • +
  • - +

    Optimize isFunction if appropriate.

    -
      if (typeof (/./) !== 'function') {
    -    _.isFunction = function(obj) {
    -      return typeof obj === 'function';
    +            
      if (typeof (/./) !== 'function') {
    +    _.isFunction = function(obj) {
    +      return typeof obj === 'function';
         };
       }
  • -
  • +
  • - +

    Is a given object a finite number?

    -
      _.isFinite = function(obj) {
    -    return isFinite(obj) && !isNaN(parseFloat(obj));
    +            
      _.isFinite = function(obj) {
    +    return isFinite(obj) && !isNaN(parseFloat(obj));
       };
  • -
  • +
  • - +

    Is the given value NaN? (NaN is the only number which does not equal itself).

    -
      _.isNaN = function(obj) {
    -    return _.isNumber(obj) && obj != +obj;
    +            
      _.isNaN = function(obj) {
    +    return _.isNumber(obj) && obj != +obj;
       };
  • -
  • +
  • - +

    Is a given value a boolean?

    -
      _.isBoolean = function(obj) {
    -    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
    +            
      _.isBoolean = function(obj) {
    +    return obj === true || obj === false || toString.call(obj) == '[object Boolean]';
       };
  • -
  • +
  • - +

    Is a given value equal to null?

    -
      _.isNull = function(obj) {
    -    return obj === null;
    +            
      _.isNull = function(obj) {
    +    return obj === null;
       };
  • -
  • +
  • - +

    Is a given variable undefined?

    -
      _.isUndefined = function(obj) {
    -    return obj === void 0;
    +            
      _.isUndefined = function(obj) {
    +    return obj === void 0;
       };
  • -
  • +
  • - +

    Shortcut function for checking if an object has a given property directly on itself (in other words, not on a prototype).

    -
      _.has = function(obj, key) {
    -    return hasOwnProperty.call(obj, key);
    +            
      _.has = function(obj, key) {
    +    return hasOwnProperty.call(obj, key);
       };
  • -
  • +
  • -
    - +
    +
    -

    Utility Functions

    +

    Utility Functions

  • -
  • +
  • - + +
    + +
    + +
  • + + +
  • +
    + +
    +

    Run Underscore.js in noConflict mode, returning the _ variable to its previous owner. Returns a reference to the Underscore object.

    -
      _.noConflict = function() {
    +            
      _.noConflict = function() {
         root._ = previousUnderscore;
    -    return this;
    +    return this;
       };
  • -
  • +
  • - +

    Keep the identity function around for default iterators.

    -
      _.identity = function(value) {
    -    return value;
    +            
      _.identity = function(value) {
    +    return value;
    +  };
    +
    +  _.constant = function(value) {
    +    return function () {
    +      return value;
    +    };
    +  };
    +
    +  _.property = function(key) {
    +    return function(obj) {
    +      return obj[key];
    +    };
       };
  • -
  • +
  • - + +
    +

    Returns a predicate for checking whether an object has a given set of key:value pairs.

    + +
    + +
      _.matches = function(attrs) {
    +    return function(obj) {
    +      if (obj === attrs) return true; //avoid comparing an object to itself.
    +      for (var key in attrs) {
    +        if (attrs[key] !== obj[key])
    +          return false;
    +      }
    +      return true;
    +    }
    +  };
    + +
  • + + +
  • +
    + +
    +

    Run a function n times.

    -
      _.times = function(n, iterator, context) {
    -    var accum = Array(Math.max(0, n));
    -    for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
    -    return accum;
    +            
      _.times = function(n, iterator, context) {
    +    var accum = Array(Math.max(0, n));
    +    for (var i = 0; i < n; i++) accum[i] = iterator.call(context, i);
    +    return accum;
       };
  • -
  • +
  • - +

    Return a random integer between min and max (inclusive).

    -
      _.random = function(min, max) {
    -    if (max == null) {
    +            
      _.random = function(min, max) {
    +    if (max == null) {
           max = min;
    -      min = 0;
    +      min = 0;
         }
    -    return min + Math.floor(Math.random() * (max - min + 1));
    +    return min + Math.floor(Math.random() * (max - min + 1));
       };
  • -
  • +
  • - + +
    +

    A (possibly faster) way to get the current timestamp as an integer.

    + +
    + +
      _.now = Date.now || function() { return new Date().getTime(); };
    + +
  • + + +
  • +
    + +
    +

    List of HTML entities for escaping.

    -
      var entityMap = {
    -    escape: {
    -      '&': '&amp;',
    -      '<': '&lt;',
    -      '>': '&gt;',
    -      '"': '&quot;',
    -      "'": '&#x27;'
    +            
      var entityMap = {
    +    escape: {
    +      '&': '&amp;',
    +      '<': '&lt;',
    +      '>': '&gt;',
    +      '"': '&quot;',
    +      "'": '&#x27;'
         }
       };
       entityMap.unescape = _.invert(entityMap.escape);
    @@ -2620,39 +2784,39 @@

    Utility Functions

  • -
  • +
  • - +

    Regexes containing the keys and values listed immediately above.

    -
      var entityRegexes = {
    -    escape:   new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
    -    unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
    +            
      var entityRegexes = {
    +    escape:   new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
    +    unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
       };
  • -
  • +
  • - +

    Functions for escaping and unescaping strings to/from HTML interpolation.

    -
      _.each(['escape', 'unescape'], function(method) {
    -    _[method] = function(string) {
    -      if (string == null) return '';
    -      return ('' + string).replace(entityRegexes[method], function(match) {
    -        return entityMap[method][match];
    +            
      _.each(['escape', 'unescape'], function(method) {
    +    _[method] = function(string) {
    +      if (string == null) return '';
    +      return ('' + string).replace(entityRegexes[method], function(match) {
    +        return entityMap[method][match];
           });
         };
       });
    @@ -2660,43 +2824,43 @@

    Utility Functions

  • -
  • +
  • - +

    If the value of the named property is a function then invoke it with the object as context; otherwise, return it.

    -
      _.result = function(object, property) {
    -    if (object == null) return void 0;
    -    var value = object[property];
    -    return _.isFunction(value) ? value.call(object) : value;
    +            
      _.result = function(object, property) {
    +    if (object == null) return void 0;
    +    var value = object[property];
    +    return _.isFunction(value) ? value.call(object) : value;
       };
  • -
  • +
  • - +

    Add your own custom functions to the Underscore object.

    -
      _.mixin = function(obj) {
    -    each(_.functions(obj), function(name) {
    -      var func = _[name] = obj[name];
    -      _.prototype[name] = function() {
    -        var args = [this._wrapped];
    -        push.apply(args, arguments);
    -        return result.call(this, func.apply(_, args));
    +            
      _.mixin = function(obj) {
    +    each(_.functions(obj), function(name) {
    +      var func = _[name] = obj[name];
    +      _.prototype[name] = function() {
    +        var args = [this._wrapped];
    +        push.apply(args, arguments);
    +        return result.call(this, func.apply(_, args));
           };
         });
       };
    @@ -2704,31 +2868,31 @@

    Utility Functions

  • -
  • +
  • - +

    Generate a unique integer id (unique within the entire client session). Useful for temporary DOM ids.

    -
      var idCounter = 0;
    -  _.uniqueId = function(prefix) {
    -    var id = ++idCounter + '';
    -    return prefix ? prefix + id : id;
    +            
      var idCounter = 0;
    +  _.uniqueId = function(prefix) {
    +    var id = ++idCounter + '';
    +    return prefix ? prefix + id : id;
       };
  • -
  • +
  • - +

    By default, Underscore uses ERB-style template delimiters, change the following template settings to use alternative delimiters.

    @@ -2736,232 +2900,244 @@

    Utility Functions

      _.templateSettings = {
    -    evaluate    : /<%([\s\S]+?)%>/g,
    -    interpolate : /<%=([\s\S]+?)%>/g,
    -    escape      : /<%-([\s\S]+?)%>/g
    +    evaluate    : /<%([\s\S]+?)%>/g,
    +    interpolate : /<%=([\s\S]+?)%>/g,
    +    escape      : /<%-([\s\S]+?)%>/g
       };
  • -
  • +
  • - +
    -

    When customizing templateSettings, if you don't want to define an +

    When customizing templateSettings, if you don’t want to define an interpolation, evaluation or escaping regex, we need one that is guaranteed not to match.

    -
      var noMatch = /(.)^/;
    +
      var noMatch = /(.)^/;
  • -
  • +
  • - +

    Certain characters need to be escaped so that they can be put into a string literal.

    -
      var escapes = {
    -    "'":      "'",
    -    '\\':     '\\',
    -    '\r':     'r',
    -    '\n':     'n',
    -    '\t':     't',
    -    '\u2028': 'u2028',
    -    '\u2029': 'u2029'
    +            
      var escapes = {
    +    "'":      "'",
    +    '\\':     '\\',
    +    '\r':     'r',
    +    '\n':     'n',
    +    '\t':     't',
    +    '\u2028': 'u2028',
    +    '\u2029': 'u2029'
       };
     
    -  var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
    + var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
  • -
  • +
  • - +
    -

    JavaScript micro-templating, similar to John Resig's implementation. +

    JavaScript micro-templating, similar to John Resig’s implementation. Underscore templating handles arbitrary delimiters, preserves whitespace, and correctly escapes quotes within interpolated code.

    -
      _.template = function(text, data, settings) {
    -    var render;
    +            
      _.template = function(text, data, settings) {
    +    var render;
         settings = _.defaults({}, settings, _.templateSettings);
  • -
  • +
  • - +

    Combine delimiters into one regular expression via alternation.

    -
        var matcher = new RegExp([
    +            
        var matcher = new RegExp([
           (settings.escape || noMatch).source,
           (settings.interpolate || noMatch).source,
           (settings.evaluate || noMatch).source
    -    ].join('|') + '|$', 'g');
    + ].join('|') + '|$', 'g');
  • -
  • +
  • - +

    Compile the template source, escaping string literals appropriately.

    -
        var index = 0;
    -    var source = "__p+='";
    -    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
    +            
        var index = 0;
    +    var source = "__p+='";
    +    text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
           source += text.slice(index, offset)
    -        .replace(escaper, function(match) { return '\\' + escapes[match]; });
    +        .replace(escaper, function(match) { return '\\' + escapes[match]; });
     
    -      if (escape) {
    -        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
    +      if (escape) {
    +        source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
           }
    -      if (interpolate) {
    -        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
    +      if (interpolate) {
    +        source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
           }
    -      if (evaluate) {
    -        source += "';\n" + evaluate + "\n__p+='";
    +      if (evaluate) {
    +        source += "';\n" + evaluate + "\n__p+='";
           }
           index = offset + match.length;
    -      return match;
    +      return match;
         });
    -    source += "';\n";
    + source += "';\n";
  • -
  • +
  • - +

    If a variable is not specified, place data values in local scope.

    -
        if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
    +            
        if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
     
    -    source = "var __t,__p='',__j=Array.prototype.join," +
    -      "print=function(){__p+=__j.call(arguments,'');};\n" +
    -      source + "return __p;\n";
    +    source = "var __t,__p='',__j=Array.prototype.join," +
    +      "print=function(){__p+=__j.call(arguments,'');};\n" +
    +      source + "return __p;\n";
     
    -    try {
    -      render = new Function(settings.variable || 'obj', '_', source);
    -    } catch (e) {
    +    try {
    +      render = new Function(settings.variable || 'obj', '_', source);
    +    } catch (e) {
           e.source = source;
    -      throw e;
    +      throw e;
         }
     
    -    if (data) return render(data, _);
    -    var template = function(data) {
    -      return render.call(this, data, _);
    +    if (data) return render(data, _);
    +    var template = function(data) {
    +      return render.call(this, data, _);
         };
  • -
  • +
  • - +

    Provide the compiled function source as a convenience for precompilation.

    -
        template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
    +            
        template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
     
    -    return template;
    +    return template;
       };
  • -
  • +
  • - +
    -

    Add a "chain" function, which will delegate to the wrapper.

    +

    Add a “chain” function, which will delegate to the wrapper.

    -
      _.chain = function(obj) {
    -    return _(obj).chain();
    +            
      _.chain = function(obj) {
    +    return _(obj).chain();
       };
  • -
  • +
  • -
    - +
    +
    -

    OOP

    +

    OOP

  • -
  • +
  • - +

    If Underscore is called as a function, it returns a wrapped object that can be used OO-style. This wrapper holds altered versions of all the underscore functions. Wrapped objects may be chained.

    -

    Helper function to continue chaining intermediate results.

    -
      var result = function(obj) {
    -    return this._chain ? _(obj).chain() : obj;
    +        
  • + + +
  • +
    + +
    + +
    +

    Helper function to continue chaining intermediate results.

    + +
    + +
      var result = function(obj) {
    +    return this._chain ? _(obj).chain() : obj;
       };
  • -
  • +
  • - +

    Add all of the Underscore functions to the wrapper object.

    @@ -2972,43 +3148,43 @@

    OOP

  • -
  • +
  • - +

    Add all mutator Array functions to the wrapper.

    -
      each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
    -    var method = ArrayProto[name];
    -    _.prototype[name] = function() {
    -      var obj = this._wrapped;
    -      method.apply(obj, arguments);
    -      if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
    -      return result.call(this, obj);
    +            
      each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
    +    var method = ArrayProto[name];
    +    _.prototype[name] = function() {
    +      var obj = this._wrapped;
    +      method.apply(obj, arguments);
    +      if ((name == 'shift' || name == 'splice') && obj.length === 0) delete obj[0];
    +      return result.call(this, obj);
         };
       });
  • -
  • +
  • - +

    Add all accessor Array functions to the wrapper.

    -
      each(['concat', 'join', 'slice'], function(name) {
    -    var method = ArrayProto[name];
    -    _.prototype[name] = function() {
    -      return result.call(this, method.apply(this._wrapped, arguments));
    +            
      each(['concat', 'join', 'slice'], function(name) {
    +    var method = ArrayProto[name];
    +    _.prototype[name] = function() {
    +      return result.call(this, method.apply(this._wrapped, arguments));
         };
       });
     
    @@ -3017,41 +3193,65 @@ 

    OOP

  • -
  • +
  • - +

    Start chaining a wrapped Underscore object.

    -
        chain: function() {
    -      this._chain = true;
    -      return this;
    +            
        chain: function() {
    +      this._chain = true;
    +      return this;
         },
  • -
  • +
  • - +

    Extracts the result from a wrapped and chained object.

    -
        value: function() {
    -      return this._wrapped;
    +            
        value: function() {
    +      return this._wrapped;
         }
     
    -  });
    +  });
    + +
  • + + +
  • +
    + +
    + +
    +

    AMD registration happens at the end for compatibility with AMD loaders +that may not enforce next-turn semantics on modules. Even though general +practice for AMD registration is to be anonymous, underscore registers +as a named module because, like jQuery, it is a base library that is +popular enough to be bundled in a third party lib, but not be part of +an AMD load request. Those cases could generate an error when an +anonymous define() is called outside of a loader request.

    -}).call(this);
    + + +
      if (typeof define === 'function' && define.amd) {
    +    define('underscore', [], function() {
    +      return _;
    +    });
    +  }
    +}).call(this);
  • diff --git a/index.html b/index.html index eddf69f38..163cc76f6 100644 --- a/index.html +++ b/index.html @@ -6,7 +6,7 @@ - + Underscore.js '; - - // HTML markup for the UI - var MARKUP = '
    \ - \ - \ -
    \ -
    \ - Normalize results \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ -
    ' + platform + '
    TestOps/sec
    \ -
    \ - \ - Powered by JSLitmus \ -
    '; - - /** - * The public API for creating and running tests - */ - window.JSLitmus = { - /** The list of all tests that have been registered with JSLitmus.test */ - _tests: [], - /** The queue of tests that need to be run */ - _queue: [], - - /** - * The parsed query parameters the current page URL. This is provided as a - * convenience for test functions - it's not used by JSLitmus proper - */ - params: {}, - - /** - * Initialize - */ - _init: function() { - // Parse query params into JSLitmus.params[] hash - var match = (location + '').match(/([^?#]*)(#.*)?$/); - if (match) { - var pairs = match[1].split('&'); - for (var i = 0; i < pairs.length; i++) { - var pair = pairs[i].split('='); - if (pair.length > 1) { - var key = pair.shift(); - var value = pair.length > 1 ? pair.join('=') : pair[0]; - this.params[key] = value; - } - } - } - - // Write out the stylesheet. We have to do this here because IE - // doesn't honor sheets written after the document has loaded. - document.write(STYLESHEET); - - // Setup the rest of the UI once the document is loaded - if (window.addEventListener) { - window.addEventListener('load', this._setup, false); - } else if (document.addEventListener) { - document.addEventListener('load', this._setup, false); - } else if (window.attachEvent) { - window.attachEvent('onload', this._setup); - } - - return this; - }, - - /** - * Set up the UI - */ - _setup: function() { - var el = jsl.$('jslitmus_container'); - if (!el) document.body.appendChild(el = document.createElement('div')); - - el.innerHTML = MARKUP; - - // Render the UI for all our tests - for (var i=0; i < JSLitmus._tests.length; i++) - JSLitmus.renderTest(JSLitmus._tests[i]); - }, - - /** - * (Re)render all the test results - */ - renderAll: function() { - for (var i = 0; i < JSLitmus._tests.length; i++) - JSLitmus.renderTest(JSLitmus._tests[i]); - JSLitmus.renderChart(); - }, - - /** - * (Re)render the chart graphics - */ - renderChart: function() { - var url = JSLitmus.chartUrl(); - jsl.$('chart_link').href = url; - jsl.$('chart_image').src = url; - jsl.$('chart').style.display = ''; - - // Update the tiny URL - jsl.$('tiny_url').src = 'http://tinyurl.com/api-create.php?url='+escape(url); - }, - - /** - * (Re)render the results for a specific test - */ - renderTest: function(test) { - // Make a new row if needed - if (!test._row) { - var trow = jsl.$('test_row_template'); - if (!trow) return; - - test._row = trow.cloneNode(true); - test._row.style.display = ''; - test._row.id = ''; - test._row.onclick = function() {JSLitmus._queueTest(test);}; - test._row.title = 'Run ' + test.name + ' test'; - trow.parentNode.appendChild(test._row); - test._row.cells[0].innerHTML = test.name; - } - - var cell = test._row.cells[1]; - var cns = [test.loopArg ? 'test_looping' : 'test_nonlooping']; - - if (test.error) { - cns.push('test_error'); - cell.innerHTML = - '
    ' + test.error + '
    ' + - ''; - } else { - if (test.running) { - cns.push('test_running'); - cell.innerHTML = 'running'; - } else if (jsl.indexOf(JSLitmus._queue, test) >= 0) { - cns.push('test_pending'); - cell.innerHTML = 'pending'; - } else if (test.count) { - cns.push('test_done'); - var hz = test.getHz(jsl.$('test_normalize').checked); - cell.innerHTML = hz != Infinity ? hz : '∞'; - } else { - cell.innerHTML = 'ready'; - } - } - cell.className = cns.join(' '); - }, - - /** - * Create a new test - */ - test: function(name, f) { - // Create the Test object - var test = new Test(name, f); - JSLitmus._tests.push(test); - - // Re-render if the test state changes - test.onChange = JSLitmus.renderTest; - - // Run the next test if this one finished - test.onStop = function(test) { - if (JSLitmus.onTestFinish) JSLitmus.onTestFinish(test); - JSLitmus.currentTest = null; - JSLitmus._nextTest(); - }; - - // Render the new test - this.renderTest(test); - }, - - /** - * Add all tests to the run queue - */ - runAll: function(e) { - e = e || window.event; - var reverse = e && e.shiftKey, len = JSLitmus._tests.length; - for (var i = 0; i < len; i++) { - JSLitmus._queueTest(JSLitmus._tests[!reverse ? i : (len - i - 1)]); - } - }, - - /** - * Remove all tests from the run queue. The current test has to finish on - * it's own though - */ - stop: function() { - while (JSLitmus._queue.length) { - var test = JSLitmus._queue.shift(); - JSLitmus.renderTest(test); - } - }, - - /** - * Run the next test in the run queue - */ - _nextTest: function() { - if (!JSLitmus.currentTest) { - var test = JSLitmus._queue.shift(); - if (test) { - jsl.$('stop_button').disabled = false; - JSLitmus.currentTest = test; - test.run(); - JSLitmus.renderTest(test); - if (JSLitmus.onTestStart) JSLitmus.onTestStart(test); - } else { - jsl.$('stop_button').disabled = true; - JSLitmus.renderChart(); - } - } - }, - - /** - * Add a test to the run queue - */ - _queueTest: function(test) { - if (jsl.indexOf(JSLitmus._queue, test) >= 0) return; - JSLitmus._queue.push(test); - JSLitmus.renderTest(test); - JSLitmus._nextTest(); - }, - - /** - * Generate a Google Chart URL that shows the data for all tests - */ - chartUrl: function() { - var n = JSLitmus._tests.length, markers = [], data = []; - var d, min = 0, max = -1e10; - var normalize = jsl.$('test_normalize').checked; - - // Gather test data - for (var i=0; i < JSLitmus._tests.length; i++) { - var test = JSLitmus._tests[i]; - if (test.count) { - var hz = test.getHz(normalize); - var v = hz != Infinity ? hz : 0; - data.push(v); - markers.push('t' + jsl.escape(test.name + '(' + jsl.toLabel(hz)+ ')') + ',000000,0,' + - markers.length + ',10'); - max = Math.max(v, max); - } - } - if (markers.length <= 0) return null; - - // Build chart title - var title = document.getElementsByTagName('title'); - title = (title && title.length) ? title[0].innerHTML : null; - var chart_title = []; - if (title) chart_title.push(title); - chart_title.push('Ops/sec (' + platform + ')'); - - // Build labels - var labels = [jsl.toLabel(min), jsl.toLabel(max)]; - - var w = 250, bw = 15; - var bs = 5; - var h = markers.length*(bw + bs) + 30 + chart_title.length*20; - - var params = { - chtt: escape(chart_title.join('|')), - chts: '000000,10', - cht: 'bhg', // chart type - chd: 't:' + data.join(','), // data set - chds: min + ',' + max, // max/min of data - chxt: 'x', // label axes - chxl: '0:|' + labels.join('|'), // labels - chsp: '0,1', - chm: markers.join('|'), // test names - chbh: [bw, 0, bs].join(','), // bar widths - // chf: 'bg,lg,0,eeeeee,0,eeeeee,.5,ffffff,1', // gradient - chs: w + 'x' + h - }; - return 'http://chart.apis.google.com/chart?' + jsl.join(params, '=', '&'); - } - }; - - JSLitmus._init(); -})(); \ No newline at end of file diff --git a/underscore-min.js b/underscore-min.js index d22f881bc..3434d6c59 100644 --- a/underscore-min.js +++ b/underscore-min.js @@ -1,6 +1,6 @@ -// Underscore.js 1.5.2 +// Underscore.js 1.6.0 // http://underscorejs.org -// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors // Underscore may be freely distributed under the MIT license. -(function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,h=e.reduce,v=e.reduceRight,g=e.filter,d=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,w=Object.keys,_=i.bind,j=function(n){return n instanceof j?n:this instanceof j?(this._wrapped=n,void 0):new j(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=j),exports._=j):n._=j,j.VERSION="1.5.2";var A=j.each=j.forEach=function(n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a=j.keys(n),u=0,i=a.length;i>u;u++)if(t.call(e,n[a[u]],a[u],n)===r)return};j.map=j.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e.push(t.call(r,n,u,i))}),e)};var E="Reduce of empty array with no initial value";j.reduce=j.foldl=j.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=j.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(E);return r},j.reduceRight=j.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduceRight===v)return e&&(t=j.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=j.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(E);return r},j.find=j.detect=function(n,t,r){var e;return O(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},j.filter=j.select=function(n,t,r){var e=[];return null==n?e:g&&n.filter===g?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&e.push(n)}),e)},j.reject=function(n,t,r){return j.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},j.every=j.all=function(n,t,e){t||(t=j.identity);var u=!0;return null==n?u:d&&n.every===d?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var O=j.some=j.any=function(n,t,e){t||(t=j.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};j.contains=j.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:O(n,function(n){return n===t})},j.invoke=function(n,t){var r=o.call(arguments,2),e=j.isFunction(t);return j.map(n,function(n){return(e?t:n[t]).apply(n,r)})},j.pluck=function(n,t){return j.map(n,function(n){return n[t]})},j.where=function(n,t,r){return j.isEmpty(t)?r?void 0:[]:j[r?"find":"filter"](n,function(n){for(var r in t)if(t[r]!==n[r])return!1;return!0})},j.findWhere=function(n,t){return j.where(n,t,!0)},j.max=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.max.apply(Math,n);if(!t&&j.isEmpty(n))return-1/0;var e={computed:-1/0,value:-1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;a>e.computed&&(e={value:n,computed:a})}),e.value},j.min=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.min.apply(Math,n);if(!t&&j.isEmpty(n))return 1/0;var e={computed:1/0,value:1/0};return A(n,function(n,u,i){var a=t?t.call(r,n,u,i):n;ae||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={},i=null==r?j.identity:k(r);return A(t,function(r,a){var o=i.call(e,r,a,t);n(u,o,r)}),u}};j.groupBy=F(function(n,t,r){(j.has(n,t)?n[t]:n[t]=[]).push(r)}),j.indexBy=F(function(n,t,r){n[t]=r}),j.countBy=F(function(n,t){j.has(n,t)?n[t]++:n[t]=1}),j.sortedIndex=function(n,t,r,e){r=null==r?j.identity:k(r);for(var u=r.call(e,t),i=0,a=n.length;a>i;){var o=i+a>>>1;r.call(e,n[o])=0})})},j.difference=function(n){var t=c.apply(e,o.call(arguments,1));return j.filter(n,function(n){return!j.contains(t,n)})},j.zip=function(){for(var n=j.max(j.pluck(arguments,"length").concat(0)),t=new Array(n),r=0;n>r;r++)t[r]=j.pluck(arguments,""+r);return t},j.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},j.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=j.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},j.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},j.range=function(n,t,r){arguments.length<=1&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=new Array(e);e>u;)i[u++]=n,n+=r;return i};var R=function(){};j.bind=function(n,t){var r,e;if(_&&n.bind===_)return _.apply(n,o.call(arguments,1));if(!j.isFunction(n))throw new TypeError;return r=o.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(o.call(arguments)));R.prototype=n.prototype;var u=new R;R.prototype=null;var i=n.apply(u,r.concat(o.call(arguments)));return Object(i)===i?i:u}},j.partial=function(n){var t=o.call(arguments,1);return function(){return n.apply(this,t.concat(o.call(arguments)))}},j.bindAll=function(n){var t=o.call(arguments,1);if(0===t.length)throw new Error("bindAll must be passed function names");return A(t,function(t){n[t]=j.bind(n[t],n)}),n},j.memoize=function(n,t){var r={};return t||(t=j.identity),function(){var e=t.apply(this,arguments);return j.has(r,e)?r[e]:r[e]=n.apply(this,arguments)}},j.delay=function(n,t){var r=o.call(arguments,2);return setTimeout(function(){return n.apply(null,r)},t)},j.defer=function(n){return j.delay.apply(j,[n,1].concat(o.call(arguments,1)))},j.throttle=function(n,t,r){var e,u,i,a=null,o=0;r||(r={});var c=function(){o=r.leading===!1?0:new Date,a=null,i=n.apply(e,u)};return function(){var l=new Date;o||r.leading!==!1||(o=l);var f=t-(l-o);return e=this,u=arguments,0>=f?(clearTimeout(a),a=null,o=l,i=n.apply(e,u)):a||r.trailing===!1||(a=setTimeout(c,f)),i}},j.debounce=function(n,t,r){var e,u,i,a,o;return function(){i=this,u=arguments,a=new Date;var c=function(){var l=new Date-a;t>l?e=setTimeout(c,t-l):(e=null,r||(o=n.apply(i,u)))},l=r&&!e;return e||(e=setTimeout(c,t)),l&&(o=n.apply(i,u)),o}},j.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},j.wrap=function(n,t){return function(){var r=[n];return a.apply(r,arguments),t.apply(this,r)}},j.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},j.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},j.keys=w||function(n){if(n!==Object(n))throw new TypeError("Invalid object");var t=[];for(var r in n)j.has(n,r)&&t.push(r);return t},j.values=function(n){for(var t=j.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},j.pairs=function(n){for(var t=j.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},j.invert=function(n){for(var t={},r=j.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},j.functions=j.methods=function(n){var t=[];for(var r in n)j.isFunction(n[r])&&t.push(r);return t.sort()},j.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},j.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},j.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)j.contains(r,u)||(t[u]=n[u]);return t},j.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]===void 0&&(n[r]=t[r])}),n},j.clone=function(n){return j.isObject(n)?j.isArray(n)?n.slice():j.extend({},n):n},j.tap=function(n,t){return t(n),n};var S=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof j&&(n=n._wrapped),t instanceof j&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==String(t);case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;var a=n.constructor,o=t.constructor;if(a!==o&&!(j.isFunction(a)&&a instanceof a&&j.isFunction(o)&&o instanceof o))return!1;r.push(n),e.push(t);var c=0,f=!0;if("[object Array]"==u){if(c=n.length,f=c==t.length)for(;c--&&(f=S(n[c],t[c],r,e)););}else{for(var s in n)if(j.has(n,s)&&(c++,!(f=j.has(t,s)&&S(n[s],t[s],r,e))))break;if(f){for(s in t)if(j.has(t,s)&&!c--)break;f=!c}}return r.pop(),e.pop(),f};j.isEqual=function(n,t){return S(n,t,[],[])},j.isEmpty=function(n){if(null==n)return!0;if(j.isArray(n)||j.isString(n))return 0===n.length;for(var t in n)if(j.has(n,t))return!1;return!0},j.isElement=function(n){return!(!n||1!==n.nodeType)},j.isArray=x||function(n){return"[object Array]"==l.call(n)},j.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){j["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),j.isArguments(arguments)||(j.isArguments=function(n){return!(!n||!j.has(n,"callee"))}),"function"!=typeof/./&&(j.isFunction=function(n){return"function"==typeof n}),j.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},j.isNaN=function(n){return j.isNumber(n)&&n!=+n},j.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},j.isNull=function(n){return null===n},j.isUndefined=function(n){return n===void 0},j.has=function(n,t){return f.call(n,t)},j.noConflict=function(){return n._=t,this},j.identity=function(n){return n},j.times=function(n,t,r){for(var e=Array(Math.max(0,n)),u=0;n>u;u++)e[u]=t.call(r,u);return e},j.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))};var I={escape:{"&":"&","<":"<",">":">",'"':""","'":"'"}};I.unescape=j.invert(I.escape);var T={escape:new RegExp("["+j.keys(I.escape).join("")+"]","g"),unescape:new RegExp("("+j.keys(I.unescape).join("|")+")","g")};j.each(["escape","unescape"],function(n){j[n]=function(t){return null==t?"":(""+t).replace(T[n],function(t){return I[n][t]})}}),j.result=function(n,t){if(null==n)return void 0;var r=n[t];return j.isFunction(r)?r.call(n):r},j.mixin=function(n){A(j.functions(n),function(t){var r=j[t]=n[t];j.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),z.call(this,r.apply(j,n))}})};var N=0;j.uniqueId=function(n){var t=++N+"";return n?n+t:t},j.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var q=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\t|\u2028|\u2029/g;j.template=function(n,t,r){var e;r=j.defaults({},r,j.templateSettings);var u=new RegExp([(r.escape||q).source,(r.interpolate||q).source,(r.evaluate||q).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(D,function(n){return"\\"+B[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=new Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,j);var c=function(n){return e.call(this,n,j)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},j.chain=function(n){return j(n).chain()};var z=function(n){return this._chain?j(n).chain():n};j.mixin(j),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];j.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],z.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];j.prototype[n]=function(){return z.call(this,t.apply(this._wrapped,arguments))}}),j.extend(j.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}})}).call(this); +(function(){var n=this,t=n._,r={},e=Array.prototype,u=Object.prototype,i=Function.prototype,a=e.push,o=e.slice,c=e.concat,l=u.toString,f=u.hasOwnProperty,s=e.forEach,p=e.map,h=e.reduce,v=e.reduceRight,g=e.filter,d=e.every,m=e.some,y=e.indexOf,b=e.lastIndexOf,x=Array.isArray,w=Object.keys,_=i.bind,j=function(n){return n instanceof j?n:this instanceof j?void(this._wrapped=n):new j(n)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=j),exports._=j):n._=j,j.VERSION="1.6.0";var A=j.each=j.forEach=function(n,t,e){if(null==n)return n;if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a=j.keys(n),u=0,i=a.length;i>u;u++)if(t.call(e,n[a[u]],a[u],n)===r)return;return n};j.map=j.collect=function(n,t,r){var e=[];return null==n?e:p&&n.map===p?n.map(t,r):(A(n,function(n,u,i){e.push(t.call(r,n,u,i))}),e)};var O="Reduce of empty array with no initial value";j.reduce=j.foldl=j.inject=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),h&&n.reduce===h)return e&&(t=j.bind(t,e)),u?n.reduce(t,r):n.reduce(t);if(A(n,function(n,i,a){u?r=t.call(e,r,n,i,a):(r=n,u=!0)}),!u)throw new TypeError(O);return r},j.reduceRight=j.foldr=function(n,t,r,e){var u=arguments.length>2;if(null==n&&(n=[]),v&&n.reduceRight===v)return e&&(t=j.bind(t,e)),u?n.reduceRight(t,r):n.reduceRight(t);var i=n.length;if(i!==+i){var a=j.keys(n);i=a.length}if(A(n,function(o,c,l){c=a?a[--i]:--i,u?r=t.call(e,r,n[c],c,l):(r=n[c],u=!0)}),!u)throw new TypeError(O);return r},j.find=j.detect=function(n,t,r){var e;return k(n,function(n,u,i){return t.call(r,n,u,i)?(e=n,!0):void 0}),e},j.filter=j.select=function(n,t,r){var e=[];return null==n?e:g&&n.filter===g?n.filter(t,r):(A(n,function(n,u,i){t.call(r,n,u,i)&&e.push(n)}),e)},j.reject=function(n,t,r){return j.filter(n,function(n,e,u){return!t.call(r,n,e,u)},r)},j.every=j.all=function(n,t,e){t||(t=j.identity);var u=!0;return null==n?u:d&&n.every===d?n.every(t,e):(A(n,function(n,i,a){return(u=u&&t.call(e,n,i,a))?void 0:r}),!!u)};var k=j.some=j.any=function(n,t,e){t||(t=j.identity);var u=!1;return null==n?u:m&&n.some===m?n.some(t,e):(A(n,function(n,i,a){return u||(u=t.call(e,n,i,a))?r:void 0}),!!u)};j.contains=j.include=function(n,t){return null==n?!1:y&&n.indexOf===y?n.indexOf(t)!=-1:k(n,function(n){return n===t})},j.invoke=function(n,t){var r=o.call(arguments,2),e=j.isFunction(t);return j.map(n,function(n){return(e?t:n[t]).apply(n,r)})},j.pluck=function(n,t){return j.map(n,j.property(t))},j.where=function(n,t){return j.filter(n,j.matches(t))},j.findWhere=function(n,t){return j.find(n,j.matches(t))},j.max=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.max.apply(Math,n);var e=-1/0,u=-1/0;return A(n,function(n,i,a){var o=t?t.call(r,n,i,a):n;o>u&&(e=n,u=o)}),e},j.min=function(n,t,r){if(!t&&j.isArray(n)&&n[0]===+n[0]&&n.length<65535)return Math.min.apply(Math,n);var e=1/0,u=1/0;return A(n,function(n,i,a){var o=t?t.call(r,n,i,a):n;u>o&&(e=n,u=o)}),e},j.shuffle=function(n){var t,r=0,e=[];return A(n,function(n){t=j.random(r++),e[r-1]=e[t],e[t]=n}),e},j.sample=function(n,t,r){return null==t||r?(n.length!==+n.length&&(n=j.values(n)),n[j.random(n.length-1)]):j.shuffle(n).slice(0,Math.max(0,t))};var E=function(n){return null==n?j.identity:j.isFunction(n)?n:j.property(n)};j.sortBy=function(n,t,r){return t=E(t),j.pluck(j.map(n,function(n,e,u){return{value:n,index:e,criteria:t.call(r,n,e,u)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(r>e||r===void 0)return 1;if(e>r||e===void 0)return-1}return n.index-t.index}),"value")};var F=function(n){return function(t,r,e){var u={};return r=E(r),A(t,function(i,a){var o=r.call(e,i,a,t);n(u,o,i)}),u}};j.groupBy=F(function(n,t,r){j.has(n,t)?n[t].push(r):n[t]=[r]}),j.indexBy=F(function(n,t,r){n[t]=r}),j.countBy=F(function(n,t){j.has(n,t)?n[t]++:n[t]=1}),j.sortedIndex=function(n,t,r,e){r=E(r);for(var u=r.call(e,t),i=0,a=n.length;a>i;){var o=i+a>>>1;r.call(e,n[o])t?[]:o.call(n,0,t)},j.initial=function(n,t,r){return o.call(n,0,n.length-(null==t||r?1:t))},j.last=function(n,t,r){return null==n?void 0:null==t||r?n[n.length-1]:o.call(n,Math.max(n.length-t,0))},j.rest=j.tail=j.drop=function(n,t,r){return o.call(n,null==t||r?1:t)},j.compact=function(n){return j.filter(n,j.identity)};var M=function(n,t,r){return t&&j.every(n,j.isArray)?c.apply(r,n):(A(n,function(n){j.isArray(n)||j.isArguments(n)?t?a.apply(r,n):M(n,t,r):r.push(n)}),r)};j.flatten=function(n,t){return M(n,t,[])},j.without=function(n){return j.difference(n,o.call(arguments,1))},j.partition=function(n,t){var r=[],e=[];return A(n,function(n){(t(n)?r:e).push(n)}),[r,e]},j.uniq=j.unique=function(n,t,r,e){j.isFunction(t)&&(e=r,r=t,t=!1);var u=r?j.map(n,r,e):n,i=[],a=[];return A(u,function(r,e){(t?e&&a[a.length-1]===r:j.contains(a,r))||(a.push(r),i.push(n[e]))}),i},j.union=function(){return j.uniq(j.flatten(arguments,!0))},j.intersection=function(n){var t=o.call(arguments,1);return j.filter(j.uniq(n),function(n){return j.every(t,function(t){return j.contains(t,n)})})},j.difference=function(n){var t=c.apply(e,o.call(arguments,1));return j.filter(n,function(n){return!j.contains(t,n)})},j.zip=function(){for(var n=j.max(j.pluck(arguments,"length").concat(0)),t=new Array(n),r=0;n>r;r++)t[r]=j.pluck(arguments,""+r);return t},j.object=function(n,t){if(null==n)return{};for(var r={},e=0,u=n.length;u>e;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},j.indexOf=function(n,t,r){if(null==n)return-1;var e=0,u=n.length;if(r){if("number"!=typeof r)return e=j.sortedIndex(n,t),n[e]===t?e:-1;e=0>r?Math.max(0,u+r):r}if(y&&n.indexOf===y)return n.indexOf(t,r);for(;u>e;e++)if(n[e]===t)return e;return-1},j.lastIndexOf=function(n,t,r){if(null==n)return-1;var e=null!=r;if(b&&n.lastIndexOf===b)return e?n.lastIndexOf(t,r):n.lastIndexOf(t);for(var u=e?r:n.length;u--;)if(n[u]===t)return u;return-1},j.range=function(n,t,r){arguments.length<=1&&(t=n||0,n=0),r=arguments[2]||1;for(var e=Math.max(Math.ceil((t-n)/r),0),u=0,i=new Array(e);e>u;)i[u++]=n,n+=r;return i};var R=function(){};j.bind=function(n,t){var r,e;if(_&&n.bind===_)return _.apply(n,o.call(arguments,1));if(!j.isFunction(n))throw new TypeError;return r=o.call(arguments,2),e=function(){if(!(this instanceof e))return n.apply(t,r.concat(o.call(arguments)));R.prototype=n.prototype;var u=new R;R.prototype=null;var i=n.apply(u,r.concat(o.call(arguments)));return Object(i)===i?i:u}},j.partial=function(n){var t=o.call(arguments,1);return function(){for(var r=0,e=t.slice(),u=0,i=e.length;i>u;u++)e[u]===j&&(e[u]=arguments[r++]);for(;r=f?(clearTimeout(a),a=null,o=l,i=n.apply(e,u),e=u=null):a||r.trailing===!1||(a=setTimeout(c,f)),i}},j.debounce=function(n,t,r){var e,u,i,a,o,c=function(){var l=j.now()-a;t>l?e=setTimeout(c,t-l):(e=null,r||(o=n.apply(i,u),i=u=null))};return function(){i=this,u=arguments,a=j.now();var l=r&&!e;return e||(e=setTimeout(c,t)),l&&(o=n.apply(i,u),i=u=null),o}},j.once=function(n){var t,r=!1;return function(){return r?t:(r=!0,t=n.apply(this,arguments),n=null,t)}},j.wrap=function(n,t){return j.partial(t,n)},j.compose=function(){var n=arguments;return function(){for(var t=arguments,r=n.length-1;r>=0;r--)t=[n[r].apply(this,t)];return t[0]}},j.after=function(n,t){return function(){return--n<1?t.apply(this,arguments):void 0}},j.keys=function(n){if(!j.isObject(n))return[];if(w)return w(n);var t=[];for(var r in n)j.has(n,r)&&t.push(r);return t},j.values=function(n){for(var t=j.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=n[t[u]];return e},j.pairs=function(n){for(var t=j.keys(n),r=t.length,e=new Array(r),u=0;r>u;u++)e[u]=[t[u],n[t[u]]];return e},j.invert=function(n){for(var t={},r=j.keys(n),e=0,u=r.length;u>e;e++)t[n[r[e]]]=r[e];return t},j.functions=j.methods=function(n){var t=[];for(var r in n)j.isFunction(n[r])&&t.push(r);return t.sort()},j.extend=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]=t[r]}),n},j.pick=function(n){var t={},r=c.apply(e,o.call(arguments,1));return A(r,function(r){r in n&&(t[r]=n[r])}),t},j.omit=function(n){var t={},r=c.apply(e,o.call(arguments,1));for(var u in n)j.contains(r,u)||(t[u]=n[u]);return t},j.defaults=function(n){return A(o.call(arguments,1),function(t){if(t)for(var r in t)n[r]===void 0&&(n[r]=t[r])}),n},j.clone=function(n){return j.isObject(n)?j.isArray(n)?n.slice():j.extend({},n):n},j.tap=function(n,t){return t(n),n};var S=function(n,t,r,e){if(n===t)return 0!==n||1/n==1/t;if(null==n||null==t)return n===t;n instanceof j&&(n=n._wrapped),t instanceof j&&(t=t._wrapped);var u=l.call(n);if(u!=l.call(t))return!1;switch(u){case"[object String]":return n==String(t);case"[object Number]":return n!=+n?t!=+t:0==n?1/n==1/t:n==+t;case"[object Date]":case"[object Boolean]":return+n==+t;case"[object RegExp]":return n.source==t.source&&n.global==t.global&&n.multiline==t.multiline&&n.ignoreCase==t.ignoreCase}if("object"!=typeof n||"object"!=typeof t)return!1;for(var i=r.length;i--;)if(r[i]==n)return e[i]==t;var a=n.constructor,o=t.constructor;if(a!==o&&!(j.isFunction(a)&&a instanceof a&&j.isFunction(o)&&o instanceof o)&&"constructor"in n&&"constructor"in t)return!1;r.push(n),e.push(t);var c=0,f=!0;if("[object Array]"==u){if(c=n.length,f=c==t.length)for(;c--&&(f=S(n[c],t[c],r,e)););}else{for(var s in n)if(j.has(n,s)&&(c++,!(f=j.has(t,s)&&S(n[s],t[s],r,e))))break;if(f){for(s in t)if(j.has(t,s)&&!c--)break;f=!c}}return r.pop(),e.pop(),f};j.isEqual=function(n,t){return S(n,t,[],[])},j.isEmpty=function(n){if(null==n)return!0;if(j.isArray(n)||j.isString(n))return 0===n.length;for(var t in n)if(j.has(n,t))return!1;return!0},j.isElement=function(n){return!(!n||1!==n.nodeType)},j.isArray=x||function(n){return"[object Array]"==l.call(n)},j.isObject=function(n){return n===Object(n)},A(["Arguments","Function","String","Number","Date","RegExp"],function(n){j["is"+n]=function(t){return l.call(t)=="[object "+n+"]"}}),j.isArguments(arguments)||(j.isArguments=function(n){return!(!n||!j.has(n,"callee"))}),"function"!=typeof/./&&(j.isFunction=function(n){return"function"==typeof n}),j.isFinite=function(n){return isFinite(n)&&!isNaN(parseFloat(n))},j.isNaN=function(n){return j.isNumber(n)&&n!=+n},j.isBoolean=function(n){return n===!0||n===!1||"[object Boolean]"==l.call(n)},j.isNull=function(n){return null===n},j.isUndefined=function(n){return n===void 0},j.has=function(n,t){return f.call(n,t)},j.noConflict=function(){return n._=t,this},j.identity=function(n){return n},j.constant=function(n){return function(){return n}},j.property=function(n){return function(t){return t[n]}},j.matches=function(n){return function(t){if(t===n)return!0;for(var r in n)if(n[r]!==t[r])return!1;return!0}},j.times=function(n,t,r){for(var e=Array(Math.max(0,n)),u=0;n>u;u++)e[u]=t.call(r,u);return e},j.random=function(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))},j.now=Date.now||function(){return(new Date).getTime()};var T={escape:{"&":"&","<":"<",">":">",'"':""","'":"'"}};T.unescape=j.invert(T.escape);var I={escape:new RegExp("["+j.keys(T.escape).join("")+"]","g"),unescape:new RegExp("("+j.keys(T.unescape).join("|")+")","g")};j.each(["escape","unescape"],function(n){j[n]=function(t){return null==t?"":(""+t).replace(I[n],function(t){return T[n][t]})}}),j.result=function(n,t){if(null==n)return void 0;var r=n[t];return j.isFunction(r)?r.call(n):r},j.mixin=function(n){A(j.functions(n),function(t){var r=j[t]=n[t];j.prototype[t]=function(){var n=[this._wrapped];return a.apply(n,arguments),z.call(this,r.apply(j,n))}})};var N=0;j.uniqueId=function(n){var t=++N+"";return n?n+t:t},j.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var q=/(.)^/,B={"'":"'","\\":"\\","\r":"r","\n":"n"," ":"t","\u2028":"u2028","\u2029":"u2029"},D=/\\|'|\r|\n|\t|\u2028|\u2029/g;j.template=function(n,t,r){var e;r=j.defaults({},r,j.templateSettings);var u=new RegExp([(r.escape||q).source,(r.interpolate||q).source,(r.evaluate||q).source].join("|")+"|$","g"),i=0,a="__p+='";n.replace(u,function(t,r,e,u,o){return a+=n.slice(i,o).replace(D,function(n){return"\\"+B[n]}),r&&(a+="'+\n((__t=("+r+"))==null?'':_.escape(__t))+\n'"),e&&(a+="'+\n((__t=("+e+"))==null?'':__t)+\n'"),u&&(a+="';\n"+u+"\n__p+='"),i=o+t.length,t}),a+="';\n",r.variable||(a="with(obj||{}){\n"+a+"}\n"),a="var __t,__p='',__j=Array.prototype.join,"+"print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{e=new Function(r.variable||"obj","_",a)}catch(o){throw o.source=a,o}if(t)return e(t,j);var c=function(n){return e.call(this,n,j)};return c.source="function("+(r.variable||"obj")+"){\n"+a+"}",c},j.chain=function(n){return j(n).chain()};var z=function(n){return this._chain?j(n).chain():n};j.mixin(j),A(["pop","push","reverse","shift","sort","splice","unshift"],function(n){var t=e[n];j.prototype[n]=function(){var r=this._wrapped;return t.apply(r,arguments),"shift"!=n&&"splice"!=n||0!==r.length||delete r[0],z.call(this,r)}}),A(["concat","join","slice"],function(n){var t=e[n];j.prototype[n]=function(){return z.call(this,t.apply(this._wrapped,arguments))}}),j.extend(j.prototype,{chain:function(){return this._chain=!0,this},value:function(){return this._wrapped}}),"function"==typeof define&&define.amd&&define("underscore",[],function(){return j})}).call(this); //# sourceMappingURL=underscore-min.map \ No newline at end of file diff --git a/underscore-min.map b/underscore-min.map index 4fbe0ba3c..47c69bad3 100644 --- a/underscore-min.map +++ b/underscore-min.map @@ -1 +1 @@ -{"version":3,"file":"underscore-min.js","sources":["underscore.js"],"names":["root","this","previousUnderscore","_","breaker","ArrayProto","Array","prototype","ObjProto","Object","FuncProto","Function","push","slice","concat","toString","hasOwnProperty","nativeForEach","forEach","nativeMap","map","nativeReduce","reduce","nativeReduceRight","reduceRight","nativeFilter","filter","nativeEvery","every","nativeSome","some","nativeIndexOf","indexOf","nativeLastIndexOf","lastIndexOf","nativeIsArray","isArray","nativeKeys","keys","nativeBind","bind","obj","_wrapped","exports","module","VERSION","each","iterator","context","length","i","call","collect","results","value","index","list","reduceError","foldl","inject","memo","initial","arguments","TypeError","foldr","find","detect","result","any","select","reject","all","identity","contains","include","target","invoke","method","args","isFunc","isFunction","apply","pluck","key","where","attrs","first","isEmpty","findWhere","max","Math","Infinity","computed","min","shuffle","rand","shuffled","random","sample","n","guard","lookupIterator","sortBy","criteria","sort","left","right","a","b","group","behavior","groupBy","has","indexBy","countBy","sortedIndex","array","low","high","mid","toArray","values","size","head","take","last","rest","tail","drop","compact","flatten","input","shallow","output","isArguments","without","difference","uniq","unique","isSorted","seen","union","intersection","item","other","zip","object","from","hasIndex","range","start","stop","step","ceil","idx","ctor","func","bound","self","partial","bindAll","funcs","Error","f","memoize","hasher","delay","wait","setTimeout","defer","throttle","options","timeout","previous","later","leading","Date","now","remaining","clearTimeout","trailing","debounce","immediate","timestamp","callNow","once","ran","wrap","wrapper","compose","after","times","pairs","invert","functions","methods","names","extend","source","prop","pick","copy","omit","defaults","clone","isObject","tap","interceptor","eq","aStack","bStack","className","String","global","multiline","ignoreCase","aCtor","constructor","bCtor","pop","isEqual","isString","isElement","nodeType","name","isFinite","isNaN","parseFloat","isNumber","isBoolean","isNull","isUndefined","noConflict","accum","floor","entityMap","escape","&","<",">","\"","'","unescape","entityRegexes","RegExp","join","string","replace","match","property","mixin","idCounter","uniqueId","prefix","id","templateSettings","evaluate","interpolate","noMatch","escapes","\\","\r","\n","\t","
","
","escaper","template","text","data","settings","render","matcher","offset","variable","e","chain","_chain"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"underscore-min.js","sources":["underscore.js"],"names":["root","this","previousUnderscore","_","breaker","ArrayProto","Array","prototype","ObjProto","Object","FuncProto","Function","push","slice","concat","toString","hasOwnProperty","nativeForEach","forEach","nativeMap","map","nativeReduce","reduce","nativeReduceRight","reduceRight","nativeFilter","filter","nativeEvery","every","nativeSome","some","nativeIndexOf","indexOf","nativeLastIndexOf","lastIndexOf","nativeIsArray","isArray","nativeKeys","keys","nativeBind","bind","obj","_wrapped","exports","module","VERSION","each","iterator","context","length","i","call","collect","results","value","index","list","reduceError","foldl","inject","memo","initial","arguments","TypeError","foldr","find","detect","predicate","result","any","select","reject","all","identity","contains","include","target","invoke","method","args","isFunc","isFunction","apply","pluck","key","property","where","attrs","matches","findWhere","max","Math","Infinity","lastComputed","computed","min","shuffle","rand","shuffled","random","sample","n","guard","values","lookupIterator","sortBy","criteria","sort","left","right","a","b","group","behavior","groupBy","has","indexBy","countBy","sortedIndex","array","low","high","mid","toArray","size","first","head","take","last","rest","tail","drop","compact","flatten","input","shallow","output","isArguments","without","difference","partition","pass","fail","elem","uniq","unique","isSorted","seen","union","intersection","item","other","zip","object","from","hasIndex","range","start","stop","step","ceil","idx","ctor","func","bound","self","partial","boundArgs","position","bindAll","funcs","Error","f","memoize","hasher","delay","wait","setTimeout","defer","throttle","options","timeout","previous","later","leading","now","remaining","clearTimeout","trailing","debounce","immediate","timestamp","callNow","once","ran","wrap","wrapper","compose","after","times","isObject","pairs","invert","functions","methods","names","extend","source","prop","pick","copy","omit","defaults","clone","tap","interceptor","eq","aStack","bStack","className","String","global","multiline","ignoreCase","aCtor","constructor","bCtor","pop","isEqual","isEmpty","isString","isElement","nodeType","name","isFinite","isNaN","parseFloat","isNumber","isBoolean","isNull","isUndefined","noConflict","constant","accum","floor","Date","getTime","entityMap","escape","&","<",">","\"","'","unescape","entityRegexes","RegExp","join","string","replace","match","mixin","idCounter","uniqueId","prefix","id","templateSettings","evaluate","interpolate","noMatch","escapes","\\","\r","\n","\t","
","
","escaper","template","text","data","settings","render","matcher","offset","variable","e","chain","_chain","define","amd"],"mappings":"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"} \ No newline at end of file diff --git a/underscore.js b/underscore.js index b50115df5..9a4cabecf 100644 --- a/underscore.js +++ b/underscore.js @@ -1,6 +1,6 @@ -// Underscore.js 1.5.2 +// Underscore.js 1.6.0 // http://underscorejs.org -// (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors +// (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors // Underscore may be freely distributed under the MIT license. (function() { @@ -65,7 +65,7 @@ } // Current version. - _.VERSION = '1.5.2'; + _.VERSION = '1.6.0'; // Collection Functions // -------------------- @@ -74,7 +74,7 @@ // Handles objects with the built-in `forEach`, arrays, and raw objects. // Delegates to **ECMAScript 5**'s native `forEach` if available. var each = _.each = _.forEach = function(obj, iterator, context) { - if (obj == null) return; + if (obj == null) return obj; if (nativeForEach && obj.forEach === nativeForEach) { obj.forEach(iterator, context); } else if (obj.length === +obj.length) { @@ -87,6 +87,7 @@ if (iterator.call(context, obj[keys[i]], keys[i], obj) === breaker) return; } } + return obj; }; // Return the results of applying the iterator to each element. @@ -152,10 +153,10 @@ }; // Return the first value which passes a truth test. Aliased as `detect`. - _.find = _.detect = function(obj, iterator, context) { + _.find = _.detect = function(obj, predicate, context) { var result; any(obj, function(value, index, list) { - if (iterator.call(context, value, index, list)) { + if (predicate.call(context, value, index, list)) { result = value; return true; } @@ -166,33 +167,33 @@ // Return all the elements that pass a truth test. // Delegates to **ECMAScript 5**'s native `filter` if available. // Aliased as `select`. - _.filter = _.select = function(obj, iterator, context) { + _.filter = _.select = function(obj, predicate, context) { var results = []; if (obj == null) return results; - if (nativeFilter && obj.filter === nativeFilter) return obj.filter(iterator, context); + if (nativeFilter && obj.filter === nativeFilter) return obj.filter(predicate, context); each(obj, function(value, index, list) { - if (iterator.call(context, value, index, list)) results.push(value); + if (predicate.call(context, value, index, list)) results.push(value); }); return results; }; // Return all the elements for which a truth test fails. - _.reject = function(obj, iterator, context) { + _.reject = function(obj, predicate, context) { return _.filter(obj, function(value, index, list) { - return !iterator.call(context, value, index, list); + return !predicate.call(context, value, index, list); }, context); }; // Determine whether all of the elements match a truth test. // Delegates to **ECMAScript 5**'s native `every` if available. // Aliased as `all`. - _.every = _.all = function(obj, iterator, context) { - iterator || (iterator = _.identity); + _.every = _.all = function(obj, predicate, context) { + predicate || (predicate = _.identity); var result = true; if (obj == null) return result; - if (nativeEvery && obj.every === nativeEvery) return obj.every(iterator, context); + if (nativeEvery && obj.every === nativeEvery) return obj.every(predicate, context); each(obj, function(value, index, list) { - if (!(result = result && iterator.call(context, value, index, list))) return breaker; + if (!(result = result && predicate.call(context, value, index, list))) return breaker; }); return !!result; }; @@ -200,13 +201,13 @@ // Determine if at least one element in the object matches a truth test. // Delegates to **ECMAScript 5**'s native `some` if available. // Aliased as `any`. - var any = _.some = _.any = function(obj, iterator, context) { - iterator || (iterator = _.identity); + var any = _.some = _.any = function(obj, predicate, context) { + predicate || (predicate = _.identity); var result = false; if (obj == null) return result; - if (nativeSome && obj.some === nativeSome) return obj.some(iterator, context); + if (nativeSome && obj.some === nativeSome) return obj.some(predicate, context); each(obj, function(value, index, list) { - if (result || (result = iterator.call(context, value, index, list))) return breaker; + if (result || (result = predicate.call(context, value, index, list))) return breaker; }); return !!result; }; @@ -232,25 +233,19 @@ // Convenience version of a common use case of `map`: fetching a property. _.pluck = function(obj, key) { - return _.map(obj, function(value){ return value[key]; }); + return _.map(obj, _.property(key)); }; // Convenience version of a common use case of `filter`: selecting only objects // containing specific `key:value` pairs. - _.where = function(obj, attrs, first) { - if (_.isEmpty(attrs)) return first ? void 0 : []; - return _[first ? 'find' : 'filter'](obj, function(value) { - for (var key in attrs) { - if (attrs[key] !== value[key]) return false; - } - return true; - }); + _.where = function(obj, attrs) { + return _.filter(obj, _.matches(attrs)); }; // Convenience version of a common use case of `find`: getting the first object // containing specific `key:value` pairs. _.findWhere = function(obj, attrs) { - return _.where(obj, attrs, true); + return _.find(obj, _.matches(attrs)); }; // Return the maximum element or (element-based computation). @@ -260,13 +255,15 @@ if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { return Math.max.apply(Math, obj); } - if (!iterator && _.isEmpty(obj)) return -Infinity; - var result = {computed : -Infinity, value: -Infinity}; + var result = -Infinity, lastComputed = -Infinity; each(obj, function(value, index, list) { var computed = iterator ? iterator.call(context, value, index, list) : value; - computed > result.computed && (result = {value : value, computed : computed}); + if (computed > lastComputed) { + result = value; + lastComputed = computed; + } }); - return result.value; + return result; }; // Return the minimum element (or element-based computation). @@ -274,16 +271,18 @@ if (!iterator && _.isArray(obj) && obj[0] === +obj[0] && obj.length < 65535) { return Math.min.apply(Math, obj); } - if (!iterator && _.isEmpty(obj)) return Infinity; - var result = {computed : Infinity, value: Infinity}; + var result = Infinity, lastComputed = Infinity; each(obj, function(value, index, list) { var computed = iterator ? iterator.call(context, value, index, list) : value; - computed < result.computed && (result = {value : value, computed : computed}); + if (computed < lastComputed) { + result = value; + lastComputed = computed; + } }); - return result.value; + return result; }; - // Shuffle an array, using the modern version of the + // Shuffle an array, using the modern version of the // [Fisher-Yates shuffle](http://en.wikipedia.org/wiki/Fisher–Yates_shuffle). _.shuffle = function(obj) { var rand; @@ -297,11 +296,12 @@ return shuffled; }; - // Sample **n** random values from an array. - // If **n** is not specified, returns a single random element from the array. + // Sample **n** random values from a collection. + // If **n** is not specified, returns a single random element. // The internal `guard` argument allows it to work with `map`. _.sample = function(obj, n, guard) { - if (arguments.length < 2 || guard) { + if (n == null || guard) { + if (obj.length !== +obj.length) obj = _.values(obj); return obj[_.random(obj.length - 1)]; } return _.shuffle(obj).slice(0, Math.max(0, n)); @@ -309,12 +309,14 @@ // An internal function to generate lookup iterators. var lookupIterator = function(value) { - return _.isFunction(value) ? value : function(obj){ return obj[value]; }; + if (value == null) return _.identity; + if (_.isFunction(value)) return value; + return _.property(value); }; // Sort the object's values by a criterion produced by an iterator. - _.sortBy = function(obj, value, context) { - var iterator = lookupIterator(value); + _.sortBy = function(obj, iterator, context) { + iterator = lookupIterator(iterator); return _.pluck(_.map(obj, function(value, index, list) { return { value: value, @@ -334,9 +336,9 @@ // An internal function used for aggregate "group by" operations. var group = function(behavior) { - return function(obj, value, context) { + return function(obj, iterator, context) { var result = {}; - var iterator = value == null ? _.identity : lookupIterator(value); + iterator = lookupIterator(iterator); each(obj, function(value, index) { var key = iterator.call(context, value, index, obj); behavior(result, key, value); @@ -348,7 +350,7 @@ // Groups the object's values by a criterion. Pass either a string attribute // to group by, or a function that returns the criterion. _.groupBy = group(function(result, key, value) { - (_.has(result, key) ? result[key] : (result[key] = [])).push(value); + _.has(result, key) ? result[key].push(value) : result[key] = [value]; }); // Indexes the object's values by a criterion, similar to `groupBy`, but for @@ -367,7 +369,7 @@ // Use a comparator function to figure out the smallest index at which // an object should be inserted so as to maintain order. Uses binary search. _.sortedIndex = function(array, obj, iterator, context) { - iterator = iterator == null ? _.identity : lookupIterator(iterator); + iterator = lookupIterator(iterator); var value = iterator.call(context, obj); var low = 0, high = array.length; while (low < high) { @@ -399,7 +401,9 @@ // allows it to work with `_.map`. _.first = _.head = _.take = function(array, n, guard) { if (array == null) return void 0; - return (n == null) || guard ? array[0] : slice.call(array, 0, n); + if ((n == null) || guard) return array[0]; + if (n < 0) return []; + return slice.call(array, 0, n); }; // Returns everything but the last entry of the array. Especially useful on @@ -414,11 +418,8 @@ // values in the array. The **guard** check allows it to work with `_.map`. _.last = function(array, n, guard) { if (array == null) return void 0; - if ((n == null) || guard) { - return array[array.length - 1]; - } else { - return slice.call(array, Math.max(array.length - n, 0)); - } + if ((n == null) || guard) return array[array.length - 1]; + return slice.call(array, Math.max(array.length - n, 0)); }; // Returns everything but the first entry of the array. Aliased as `tail` and `drop`. @@ -459,6 +460,16 @@ return _.difference(array, slice.call(arguments, 1)); }; + // Split an array into two arrays: one whose elements all satisfy the given + // predicate, and one whose elements all do not satisfy the predicate. + _.partition = function(array, predicate) { + var pass = [], fail = []; + each(array, function(elem) { + (predicate(elem) ? pass : fail).push(elem); + }); + return [pass, fail]; + }; + // Produce a duplicate-free version of the array. If the array has already // been sorted, you have the option of using a faster algorithm. // Aliased as `unique`. @@ -492,7 +503,7 @@ var rest = slice.call(arguments, 1); return _.filter(_.uniq(array), function(item) { return _.every(rest, function(other) { - return _.indexOf(other, item) >= 0; + return _.contains(other, item); }); }); }; @@ -507,7 +518,7 @@ // Zip together multiple lists into a single array -- elements that share // an index go together. _.zip = function() { - var length = _.max(_.pluck(arguments, "length").concat(0)); + var length = _.max(_.pluck(arguments, 'length').concat(0)); var results = new Array(length); for (var i = 0; i < length; i++) { results[i] = _.pluck(arguments, '' + i); @@ -613,19 +624,27 @@ }; // Partially apply a function by creating a version that has had some of its - // arguments pre-filled, without changing its dynamic `this` context. + // arguments pre-filled, without changing its dynamic `this` context. _ acts + // as a placeholder, allowing any combination of arguments to be pre-filled. _.partial = function(func) { - var args = slice.call(arguments, 1); + var boundArgs = slice.call(arguments, 1); return function() { - return func.apply(this, args.concat(slice.call(arguments))); + var position = 0; + var args = boundArgs.slice(); + for (var i = 0, length = args.length; i < length; i++) { + if (args[i] === _) args[i] = arguments[position++]; + } + while (position < arguments.length) args.push(arguments[position++]); + return func.apply(this, args); }; }; - // Bind all of an object's methods to that object. Useful for ensuring that - // all callbacks defined on an object belong to it. + // Bind a number of an object's methods to that object. Remaining arguments + // are the method names to be bound. Useful for ensuring that all callbacks + // defined on an object belong to it. _.bindAll = function(obj) { var funcs = slice.call(arguments, 1); - if (funcs.length === 0) throw new Error("bindAll must be passed function names"); + if (funcs.length === 0) throw new Error('bindAll must be passed function names'); each(funcs, function(f) { obj[f] = _.bind(obj[f], obj); }); return obj; }; @@ -664,12 +683,13 @@ var previous = 0; options || (options = {}); var later = function() { - previous = options.leading === false ? 0 : new Date; + previous = options.leading === false ? 0 : _.now(); timeout = null; result = func.apply(context, args); + context = args = null; }; return function() { - var now = new Date; + var now = _.now(); if (!previous && options.leading === false) previous = now; var remaining = wait - (now - previous); context = this; @@ -679,6 +699,7 @@ timeout = null; previous = now; result = func.apply(context, args); + context = args = null; } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } @@ -692,24 +713,33 @@ // leading edge, instead of the trailing. _.debounce = function(func, wait, immediate) { var timeout, args, context, timestamp, result; + + var later = function() { + var last = _.now() - timestamp; + if (last < wait) { + timeout = setTimeout(later, wait - last); + } else { + timeout = null; + if (!immediate) { + result = func.apply(context, args); + context = args = null; + } + } + }; + return function() { context = this; args = arguments; - timestamp = new Date(); - var later = function() { - var last = (new Date()) - timestamp; - if (last < wait) { - timeout = setTimeout(later, wait - last); - } else { - timeout = null; - if (!immediate) result = func.apply(context, args); - } - }; + timestamp = _.now(); var callNow = immediate && !timeout; if (!timeout) { timeout = setTimeout(later, wait); } - if (callNow) result = func.apply(context, args); + if (callNow) { + result = func.apply(context, args); + context = args = null; + } + return result; }; }; @@ -731,11 +761,7 @@ // allowing you to adjust arguments, run code before and after, and // conditionally execute the original function. _.wrap = function(func, wrapper) { - return function() { - var args = [func]; - push.apply(args, arguments); - return wrapper.apply(this, args); - }; + return _.partial(wrapper, func); }; // Returns a function that is the composition of a list of functions, each @@ -765,8 +791,9 @@ // Retrieve the names of an object's properties. // Delegates to **ECMAScript 5**'s native `Object.keys` - _.keys = nativeKeys || function(obj) { - if (obj !== Object(obj)) throw new TypeError('Invalid object'); + _.keys = function(obj) { + if (!_.isObject(obj)) return []; + if (nativeKeys) return nativeKeys(obj); var keys = []; for (var key in obj) if (_.has(obj, key)) keys.push(key); return keys; @@ -921,7 +948,8 @@ // from different frames are. var aCtor = a.constructor, bCtor = b.constructor; if (aCtor !== bCtor && !(_.isFunction(aCtor) && (aCtor instanceof aCtor) && - _.isFunction(bCtor) && (bCtor instanceof bCtor))) { + _.isFunction(bCtor) && (bCtor instanceof bCtor)) + && ('constructor' in a && 'constructor' in b)) { return false; } // Add the first object to the stack of traversed objects. @@ -1061,6 +1089,30 @@ return value; }; + _.constant = function(value) { + return function () { + return value; + }; + }; + + _.property = function(key) { + return function(obj) { + return obj[key]; + }; + }; + + // Returns a predicate for checking whether an object has a given set of `key:value` pairs. + _.matches = function(attrs) { + return function(obj) { + if (obj === attrs) return true; //avoid comparing an object to itself. + for (var key in attrs) { + if (attrs[key] !== obj[key]) + return false; + } + return true; + } + }; + // Run a function **n** times. _.times = function(n, iterator, context) { var accum = Array(Math.max(0, n)); @@ -1077,6 +1129,9 @@ return min + Math.floor(Math.random() * (max - min + 1)); }; + // A (possibly faster) way to get the current timestamp as an integer. + _.now = Date.now || function() { return new Date().getTime(); }; + // List of HTML entities for escaping. var entityMap = { escape: { @@ -1273,4 +1328,16 @@ }); + // AMD registration happens at the end for compatibility with AMD loaders + // that may not enforce next-turn semantics on modules. Even though general + // practice for AMD registration is to be anonymous, underscore registers + // as a named module because, like jQuery, it is a base library that is + // popular enough to be bundled in a third party lib, but not be part of + // an AMD load request. Those cases could generate an error when an + // anonymous define() is called outside of a loader request. + if (typeof define === 'function' && define.amd) { + define('underscore', [], function() { + return _; + }); + } }).call(this);