Underscore.js 1.1.3
-(c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
+ underscore.js
underscore.js Underscore.js 1.1.4
+(c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
Underscore is freely distributable under the MIT license.
Portions of Underscore are inspired or borrowed from Prototype,
Oliver Steele's Functional, and John Resig's Micro-Templating.
@@ -27,10 +27,11 @@
_ . _ = _ ;
} else {
root . _ = _ ;
- }
Current version.
Collection Functions The cornerstone, an each
implementation, aka forEach
.
+ }
Current version.
Collection Functions The cornerstone, an each
implementation, aka forEach
.
Handles objects implementing forEach
, arrays, and raw objects.
Delegates to ECMAScript 5 's native forEach
if available.
var each = _ . each = _ . forEach = function ( obj , iterator , context ) {
var value ;
+ if ( obj == null ) return ;
if ( nativeForEach && obj . forEach === nativeForEach ) {
obj . forEach ( iterator , context );
} else if ( _ . isNumber ( obj . length )) {
@@ -46,8 +47,9 @@
}
}; Return the results of applying the iterator to each element.
Delegates to ECMAScript 5 's native map
if available.
_ . map = function ( obj , iterator , context ) {
- if ( nativeMap && obj . map === nativeMap ) return obj . map ( 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 [ results . length ] = iterator . call ( context , value , index , list );
});
@@ -55,6 +57,7 @@
}; Reduce builds up a single result from a list of values, aka inject
,
or foldl
. Delegates to ECMAScript 5 's native reduce
if available.
_ . reduce = _ . foldl = _ . inject = function ( obj , iterator , memo , context ) {
var initial = memo !== void 0 ;
+ if ( obj == null ) obj = [];
if ( nativeReduce && obj . reduce === nativeReduce ) {
if ( context ) iterator = _ . bind ( iterator , context );
return initial ? obj . reduce ( iterator , memo ) : obj . reduce ( iterator );
@@ -62,13 +65,16 @@
each ( obj , function ( value , index , list ) {
if ( ! initial && index === 0 ) {
memo = value ;
+ initial = true ;
} else {
memo = iterator . call ( context , memo , value , index , list );
}
});
+ if ( ! initial ) throw new TypeError ( "Reduce of empty array with no initial value" );
return memo ;
}; The right-associative version of reduce, also known as foldr
.
Delegates to ECMAScript 5 's native reduceRight
if available.
_ . reduceRight = _ . foldr = function ( obj , iterator , memo , context ) {
+ if ( obj == null ) obj = [];
if ( nativeReduceRight && obj . reduceRight === nativeReduceRight ) {
if ( context ) iterator = _ . bind ( iterator , context );
return memo !== void 0 ? obj . reduceRight ( iterator , memo ) : obj . reduceRight ( iterator );
@@ -87,14 +93,16 @@
}; 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 ) {
- if ( nativeFilter && obj . filter === nativeFilter ) return obj . filter ( 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 [ results . length ] = value ;
});
return results ;
}; Return all the elements for which a truth test fails.
_ . reject = function ( obj , iterator , context ) {
var results = [];
+ if ( obj == null ) return results ;
each ( obj , function ( value , index , list ) {
if ( ! iterator . call ( context , value , index , list )) results [ results . length ] = value ;
});
@@ -103,8 +111,9 @@
Delegates to ECMAScript 5 's native every
if available.
Aliased as all
. _ . every = _ . all = function ( obj , iterator , context ) {
iterator = iterator || _ . identity ;
- if ( nativeEvery && obj . every === nativeEvery ) return obj . every ( iterator , context );
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 ;
});
@@ -113,16 +122,18 @@
Delegates to ECMAScript 5 's native some
if available.
Aliased as any
. var any = _ . some = _ . any = function ( obj , iterator , context ) {
iterator = iterator || _ . identity ;
- if ( nativeSome && obj . some === nativeSome ) return obj . some ( iterator , context );
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 = iterator . call ( context , value , index , list )) return breaker ;
});
return result ;
}; Determine if a given value is included in the array or object using ===
.
Aliased as contains
.
_ . include = _ . contains = function ( obj , target ) {
- if ( nativeIndexOf && obj . indexOf === nativeIndexOf ) return obj . indexOf ( target ) != - 1 ;
var found = false ;
+ if ( obj == null ) return found ;
+ if ( nativeIndexOf && obj . indexOf === nativeIndexOf ) return obj . indexOf ( target ) != - 1 ;
any ( obj , function ( value ) {
if ( found = value === target ) return true ;
});
@@ -224,11 +235,19 @@
}; 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.
_ . indexOf = function ( array , item ) {
+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 ;
+ if ( isSorted ) {
+ var i = _ . sortedIndex ( array , item );
+ return array [ i ] === item ? i : - 1 ;
+ }
if ( nativeIndexOf && array . indexOf === nativeIndexOf ) return array . indexOf ( item );
for ( var i = 0 , l = array . length ; i < l ; i ++ ) if ( array [ i ] === item ) return i ;
return - 1 ;
}; Delegates to ECMAScript 5 's native lastIndexOf
if available.
_ . lastIndexOf = function ( array , item ) {
+ if ( array == null ) return - 1 ;
if ( nativeLastIndexOf && array . lastIndexOf === nativeLastIndexOf ) return array . lastIndexOf ( item );
var i = array . length ;
while ( i -- ) if ( array [ i ] === item ) return i ;
@@ -298,7 +317,7 @@
conditionally execute the original function. _ . wrap = function ( func , wrapper ) {
return function () {
var args = [ func ]. concat ( slice . call ( arguments ));
- return wrapper . apply ( wrapper , args );
+ return wrapper . apply ( this , args );
};
}; Returns a function that is the composition of a list of functions, each
consuming the return value of the function that follows.
_ . compose = function () {
@@ -334,65 +353,66 @@
interceptor ( obj );
return obj ;
}; Perform a deep comparison to check if two objects are equal.
_ . isEqual = function ( a , b ) { Check object identity.
if ( a === b ) return true ; Different types?
var atype = typeof ( a ), btype = typeof ( b );
- if ( atype != btype ) return false ; Basic equality test (watch out for coercions).
One is falsy and the other truthy.
if (( ! a && b ) || ( a && ! b )) return false ; One of them implements an isEqual()?
if ( a . isEqual ) return a . isEqual ( b ); Check dates' integer values.
if ( _ . isDate ( a ) && _ . isDate ( b )) return a . getTime () === b . getTime (); Both are NaN?
if ( _ . isNaN ( a ) && _ . isNaN ( b )) return false ; Compare regular expressions.
if ( _ . isRegExp ( a ) && _ . isRegExp ( b ))
+ if ( atype != btype ) return false ; Basic equality test (watch out for coercions).
One is falsy and the other truthy.
if (( ! a && b ) || ( a && ! b )) return false ; Unwrap any wrapped objects.
if ( a . _chain ) a = a . _wrapped ;
+ if ( b . _chain ) b = b . _wrapped ; One of them implements an isEqual()?
if ( a . isEqual ) return a . isEqual ( b ); Check dates' integer values.
if ( _ . isDate ( a ) && _ . isDate ( b )) return a . getTime () === b . getTime (); Both are NaN?
if ( _ . isNaN ( a ) && _ . isNaN ( b )) return false ; Compare regular expressions.
if ( _ . isRegExp ( a ) && _ . isRegExp ( b ))
return a . source === b . source &&
a . global === b . global &&
a . ignoreCase === b . ignoreCase &&
- a . multiline === b . multiline ; If a is not an object by this point, we can't handle it.
if ( atype !== 'object' ) return false ; Check for different array lengths before comparing contents.
if ( a . length && ( a . length !== b . length )) return false ; Nothing else worked, deep compare the contents.
var aKeys = _ . keys ( a ), bKeys = _ . keys ( b ); Different object sizes?
if ( aKeys . length != bKeys . length ) return false ; Recursive comparison of contents.
for ( var key in a ) if ( ! ( key in b ) || ! _ . isEqual ( a [ key ], b [ key ])) return false ;
+ a . multiline === b . multiline ; If a is not an object by this point, we can't handle it.
if ( atype !== 'object' ) return false ; Check for different array lengths before comparing contents.
if ( a . length && ( a . length !== b . length )) return false ; Nothing else worked, deep compare the contents.
var aKeys = _ . keys ( a ), bKeys = _ . keys ( b ); Different object sizes?
if ( aKeys . length != bKeys . length ) return false ; Recursive comparison of contents.
for ( var key in a ) if ( ! ( key in b ) || ! _ . isEqual ( a [ key ], b [ key ])) return false ;
return true ;
- }; Is a given array or object empty?
_ . isEmpty = function ( obj ) {
+ }; Is a given array or object empty?
_ . isEmpty = function ( obj ) {
if ( _ . isArray ( obj ) || _ . isString ( obj )) return obj . length === 0 ;
for ( var key in obj ) if ( hasOwnProperty . call ( obj , key )) return false ;
return true ;
- }; Is a given value a DOM element?
_ . isElement = function ( obj ) {
+ }; Is a given value a DOM element?
_ . isElement = function ( obj ) {
return !! ( obj && obj . nodeType == 1 );
- }; Is a given value an array?
+ };
Is a given value an array?
Delegates to ECMA5's native Array.isArray
_ . isArray = nativeIsArray || function ( obj ) {
- return !! ( obj && obj . concat && obj . unshift && ! obj . callee );
- }; Is a given variable an arguments object?
_ . isArguments = function ( obj ) {
- return !! ( obj && obj . callee );
- }; Is a given value a function?
_ . isFunction = function ( obj ) {
+ return toString . call ( obj ) === '[object Array]' ;
+ }; Is a given variable an arguments object?
_ . isArguments = function ( obj ) {
+ return !! ( obj && hasOwnProperty . call ( obj , 'callee' ));
+ }; Is a given value a function?
_ . isFunction = function ( obj ) {
return !! ( obj && obj . constructor && obj . call && obj . apply );
- }; Is a given value a string?
_ . isString = function ( obj ) {
+ }; Is a given value a string?
_ . isString = function ( obj ) {
return !! ( obj === '' || ( obj && obj . charCodeAt && obj . substr ));
- }; Is a given value a number?
_ . isNumber = function ( obj ) {
+ }; Is a given value a number?
_ . isNumber = function ( obj ) {
return !! ( obj === 0 || ( obj && obj . toExponential && obj . toFixed ));
- }; Is the given value NaN -- this one is interesting. NaN != NaN, and
-isNaN(undefined) == true, so we make sure it's a number first.
_ . isNaN = function ( obj ) {
- return toString . call ( obj ) === '[object Number]' && isNaN ( obj );
- }; Is a given value a boolean?
_ . isBoolean = function ( obj ) {
+ }; Is the given value NaN
? NaN
happens to be the only value in JavaScript
+that does not equal itself.
_ . isNaN = function ( obj ) {
+ return obj !== obj ;
+ }; Is a given value a boolean?
_ . isBoolean = function ( obj ) {
return obj === true || obj === false ;
- }; Is a given value a date?
_ . isDate = function ( obj ) {
+ }; Is a given value a date?
_ . isDate = function ( obj ) {
return !! ( obj && obj . getTimezoneOffset && obj . setUTCFullYear );
- }; Is the given value a regular expression?
_ . isRegExp = function ( obj ) {
+ }; Is the given value a regular expression?
_ . isRegExp = function ( obj ) {
return !! ( obj && obj . test && obj . exec && ( obj . ignoreCase || obj . ignoreCase === false ));
- }; Is a given value equal to null?
_ . isNull = function ( obj ) {
+ }; Is a given value equal to null?
_ . isNull = function ( obj ) {
return obj === null ;
- }; Is a given variable undefined?
_ . isUndefined = function ( obj ) {
+ }; Is a given variable undefined?
_ . isUndefined = function ( obj ) {
return obj === void 0 ;
- }; Utility Functions Run Underscore.js in noConflict mode, returning the _
variable to its
+ };
Utility Functions Run Underscore.js in noConflict mode, returning the _
variable to its
previous owner. Returns a reference to the Underscore object.
_ . noConflict = function () {
root . _ = previousUnderscore ;
return this ;
- }; Keep the identity function around for default iterators.
_ . identity = function ( value ) {
+ }; Keep the identity function around for default iterators.
_ . identity = function ( value ) {
return value ;
- }; Run a function n times.
_ . times = function ( n , iterator , context ) {
+ }; Run a function n times.
_ . times = function ( n , iterator , context ) {
for ( var i = 0 ; i < n ; i ++ ) iterator . call ( context , i );
- }; Add your own custom functions to the Underscore object, ensuring that
+ };
Add your own custom functions to the Underscore object, ensuring that
they're correctly added to the OOP wrapper as well.
_ . mixin = function ( obj ) {
each ( _ . functions ( obj ), function ( name ){
addToWrapper ( name , _ [ name ] = obj [ name ]);
});
- }; Generate a unique integer id (unique within the entire client session).
+ };
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 ;
- }; By default, Underscore uses ERB-style template delimiters, change the
+ };
By default, Underscore uses ERB-style template delimiters, change the
following template settings to use alternative delimiters.
_ . templateSettings = {
evaluate : /<%([\s\S]+?)%>/g ,
interpolate : /<%=([\s\S]+?)%>/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 ( str , data ) {
var c = _ . templateSettings ;
@@ -413,31 +433,31 @@
+ "');}return __p.join('');" ;
var func = new Function ( 'obj' , tmpl );
return data ? func ( data ) : func ;
- }; The OOP Wrapper If Underscore is called as a function, it returns a wrapped object that
+ };
The OOP Wrapper 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.
var wrapper = function ( obj ) { this . _wrapped = obj ; }; Expose wrapper.prototype
as _.prototype
_ . prototype = wrapper . prototype ; Helper function to continue chaining intermediate results.
var result = function ( obj , chain ) {
+underscore functions. Wrapped objects may be chained. var wrapper = function ( obj ) { this . _wrapped = obj ; }; Expose wrapper.prototype
as _.prototype
_ . prototype = wrapper . prototype ; Helper function to continue chaining intermediate results.
var result = function ( obj , chain ) {
return chain ? _ ( obj ). chain () : obj ;
- }; A method to easily add functions to the OOP wrapper.
var addToWrapper = function ( name , func ) {
+ }; A method to easily add functions to the OOP wrapper.
var addToWrapper = function ( name , func ) {
wrapper . prototype [ name ] = function () {
var args = slice . call ( arguments );
unshift . call ( args , this . _wrapped );
return result ( func . apply ( _ , args ), this . _chain );
};
- }; Add all of the Underscore functions to the wrapper object.
Add all mutator Array functions to the wrapper.
each ([ 'pop' , 'push' , 'reverse' , 'shift' , 'sort' , 'splice' , 'unshift' ], function ( name ) {
+ }; Add all of the Underscore functions to the wrapper object.
Add all mutator Array functions to the wrapper.
each ([ 'pop' , 'push' , 'reverse' , 'shift' , 'sort' , 'splice' , 'unshift' ], function ( name ) {
var method = ArrayProto [ name ];
wrapper . prototype [ name ] = function () {
method . apply ( this . _wrapped , arguments );
return result ( this . _wrapped , this . _chain );
};
- }); Add all accessor Array functions to the wrapper.
each ([ 'concat' , 'join' , 'slice' ], function ( name ) {
+ }); Add all accessor Array functions to the wrapper.
each ([ 'concat' , 'join' , 'slice' ], function ( name ) {
var method = ArrayProto [ name ];
wrapper . prototype [ name ] = function () {
return result ( method . apply ( this . _wrapped , arguments ), this . _chain );
};
- }); Start chaining a wrapped Underscore object.
wrapper . prototype . chain = function () {
+ }); Start chaining a wrapped Underscore object.
wrapper . prototype . chain = function () {
this . _chain = true ;
return this ;
- }; Extracts the result from a wrapped and chained object.
wrapper . prototype . value = function () {
+ }; Extracts the result from a wrapped and chained object.
wrapper . prototype . value = function () {
return this . _wrapped ;
};
diff --git a/index.html b/index.html
index 01d33d077..f4fe5c4f0 100644
--- a/index.html
+++ b/index.html
@@ -118,11 +118,11 @@
+ — Jan 9, 2011
+ Improved compliance with ES5's Array methods when passing null
+ as a value. _.wrap now correctly sets this for the
+ wrapped function. _.indexOf now takes an optional flag for
+ finding the insertion index in an array that is guaranteed to already
+ be sorted. Avoiding the use of .callee , to allow _.isArray
+ to work properly in ES5's strict mode.
+
+
— Dec 1, 2010
In CommonJS, Underscore may now be required with just:
@@ -1197,7 +1207,7 @@
Change Log
Improved _.reduce compatibility with the ECMA5 version:
if you don't pass an initial value, the first item in the collection is used.
_.each no longer returns the iterated collection, for improved
- consistency with ECMA5's forEach .
+ consistency with ES5's forEach .
diff --git a/package.json b/package.json
index 9e9aa2980..d5c924d0b 100644
--- a/package.json
+++ b/package.json
@@ -8,5 +8,5 @@
"dependencies" : [],
"lib" : ".",
"main" : "underscore.js",
- "version" : "1.1.3"
+ "version" : "1.1.4"
}
diff --git a/underscore-min.js b/underscore-min.js
index 2979243e0..9ac21fa26 100644
--- a/underscore-min.js
+++ b/underscore-min.js
@@ -1,25 +1,25 @@
-// Underscore.js 1.1.3
-// (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore.js 1.1.4
+// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the MIT license.
// Portions of Underscore are inspired or borrowed from Prototype,
// Oliver Steele's Functional, and John Resig's Micro-Templating.
// For all details and documentation:
// http://documentcloud.github.com/underscore
-(function(){var p=this,C=p._,m={},j=Array.prototype,n=Object.prototype,i=j.slice,D=j.unshift,E=n.toString,q=n.hasOwnProperty,s=j.forEach,t=j.map,u=j.reduce,v=j.reduceRight,w=j.filter,x=j.every,y=j.some,o=j.indexOf,z=j.lastIndexOf;n=Array.isArray;var F=Object.keys,c=function(a){return new l(a)};if(typeof module!=="undefined"&&module.exports){module.exports=c;c._=c}else p._=c;c.VERSION="1.1.3";var k=c.each=c.forEach=function(a,b,d){if(s&&a.forEach===s)a.forEach(b,d);else if(c.isNumber(a.length))for(var e=
-0,f=a.length;e=e.computed&&(e={value:f,computed:g})});return e.value};c.min=function(a,b,d){if(!b&&c.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};k(a,function(f,g,h){g=b?b.call(d,f,g,h):f;gh?1:0}),"value")};c.sortedIndex=function(a,b,d){d=d||c.identity;for(var e=0,f=a.length;e>1;d(a[g])=0})})};c.zip=function(){for(var a=i.call(arguments),b=c.max(c.pluck(a,"length")),d=Array(b),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};c.keys=F||function(a){if(c.isArray(a))return c.range(0,a.length);var b=[],d;for(d in a)if(q.call(a,d))b[b.length]=d;return b};
-c.values=function(a){return c.map(a,c.identity)};c.functions=c.methods=function(a){return c.filter(c.keys(a),function(b){return c.isFunction(a[b])}).sort()};c.extend=function(a){k(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};c.clone=function(a){return c.isArray(a)?a.slice():c.extend({},a)};c.tap=function(a,b){b(a);return a};c.isEqual=function(a,b){if(a===b)return true;var d=typeof a;if(d!=typeof b)return false;if(a==b)return true;if(!a&&b||a&&!b)return false;if(a.isEqual)return a.isEqual(b);
-if(c.isDate(a)&&c.isDate(b))return a.getTime()===b.getTime();if(c.isNaN(a)&&c.isNaN(b))return false;if(c.isRegExp(a)&&c.isRegExp(b))return a.source===b.source&&a.global===b.global&&a.ignoreCase===b.ignoreCase&&a.multiline===b.multiline;if(d!=="object")return false;if(a.length&&a.length!==b.length)return false;d=c.keys(a);var e=c.keys(b);if(d.length!=e.length)return false;for(var f in a)if(!(f in b)||!c.isEqual(a[f],b[f]))return false;return true};c.isEmpty=function(a){if(c.isArray(a)||c.isString(a))return a.length===
-0;for(var b in a)if(q.call(a,b))return false;return true};c.isElement=function(a){return!!(a&&a.nodeType==1)};c.isArray=n||function(a){return!!(a&&a.concat&&a.unshift&&!a.callee)};c.isArguments=function(a){return!!(a&&a.callee)};c.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};c.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};c.isNumber=function(a){return!!(a===0||a&&a.toExponential&&a.toFixed)};c.isNaN=function(a){return E.call(a)==="[object Number]"&&isNaN(a)};
-c.isBoolean=function(a){return a===true||a===false};c.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};c.isRegExp=function(a){return!!(a&&a.test&&a.exec&&(a.ignoreCase||a.ignoreCase===false))};c.isNull=function(a){return a===null};c.isUndefined=function(a){return a===void 0};c.noConflict=function(){p._=C;return this};c.identity=function(a){return a};c.times=function(a,b,d){for(var e=0;e/g,interpolate:/<%=([\s\S]+?)%>/g};c.template=function(a,b){var d=c.templateSettings;d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.interpolate,function(e,f){return"',"+f.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||null,function(e,f){return"');"+f.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+"__p.push('"}).replace(/\r/g,
-"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');";d=new Function("obj",d);return b?d(b):d};var l=function(a){this._wrapped=a};c.prototype=l.prototype;var r=function(a,b){return b?c(a).chain():a},H=function(a,b){l.prototype[a]=function(){var d=i.call(arguments);D.call(d,this._wrapped);return r(b.apply(c,d),this._chain)}};c.mixin(c);k(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var b=j[a];l.prototype[a]=function(){b.apply(this._wrapped,arguments);
-return r(this._wrapped,this._chain)}});k(["concat","join","slice"],function(a){var b=j[a];l.prototype[a]=function(){return r(b.apply(this._wrapped,arguments),this._chain)}});l.prototype.chain=function(){this._chain=true;return this};l.prototype.value=function(){return this._wrapped}})();
+(function(){var q=this,C=q._,m={},j=Array.prototype,n=Object.prototype,i=j.slice,D=j.unshift,E=n.toString,o=n.hasOwnProperty,s=j.forEach,t=j.map,u=j.reduce,v=j.reduceRight,w=j.filter,x=j.every,y=j.some,p=j.indexOf,z=j.lastIndexOf;n=Array.isArray;var F=Object.keys,c=function(a){return new l(a)};if(typeof module!=="undefined"&&module.exports){module.exports=c;c._=c}else q._=c;c.VERSION="1.1.4";var k=c.each=c.forEach=function(a,b,d){if(a!=null)if(s&&a.forEach===s)a.forEach(b,d);else if(c.isNumber(a.length))for(var e=
+0,f=a.length;e=e.computed&&(e={value:f,computed:g})});
+return e.value};c.min=function(a,b,d){if(!b&&c.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};k(a,function(f,g,h){g=b?b.call(d,f,g,h):f;gh?1:0}),"value")};c.sortedIndex=function(a,b,d){d=d||c.identity;for(var e=0,f=a.length;e>1;d(a[g])=0})})};c.zip=function(){for(var a=i.call(arguments),
+b=c.max(c.pluck(a,"length")),d=Array(b),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};c.keys=F||function(a){if(c.isArray(a))return c.range(0,a.length);var b=[],d;for(d in a)if(o.call(a,d))b[b.length]=d;return b};c.values=function(a){return c.map(a,c.identity)};c.functions=c.methods=function(a){return c.filter(c.keys(a),function(b){return c.isFunction(a[b])}).sort()};c.extend=function(a){k(i.call(arguments,1),function(b){for(var d in b)a[d]=
+b[d]});return a};c.clone=function(a){return c.isArray(a)?a.slice():c.extend({},a)};c.tap=function(a,b){b(a);return a};c.isEqual=function(a,b){if(a===b)return true;var d=typeof a;if(d!=typeof b)return false;if(a==b)return true;if(!a&&b||a&&!b)return false;if(a._chain)a=a._wrapped;if(b._chain)b=b._wrapped;if(a.isEqual)return a.isEqual(b);if(c.isDate(a)&&c.isDate(b))return a.getTime()===b.getTime();if(c.isNaN(a)&&c.isNaN(b))return false;if(c.isRegExp(a)&&c.isRegExp(b))return a.source===b.source&&a.global===
+b.global&&a.ignoreCase===b.ignoreCase&&a.multiline===b.multiline;if(d!=="object")return false;if(a.length&&a.length!==b.length)return false;d=c.keys(a);var e=c.keys(b);if(d.length!=e.length)return false;for(var f in a)if(!(f in b)||!c.isEqual(a[f],b[f]))return false;return true};c.isEmpty=function(a){if(c.isArray(a)||c.isString(a))return a.length===0;for(var b in a)if(o.call(a,b))return false;return true};c.isElement=function(a){return!!(a&&a.nodeType==1)};c.isArray=n||function(a){return E.call(a)===
+"[object Array]"};c.isArguments=function(a){return!!(a&&o.call(a,"callee"))};c.isFunction=function(a){return!!(a&&a.constructor&&a.call&&a.apply)};c.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};c.isNumber=function(a){return!!(a===0||a&&a.toExponential&&a.toFixed)};c.isNaN=function(a){return a!==a};c.isBoolean=function(a){return a===true||a===false};c.isDate=function(a){return!!(a&&a.getTimezoneOffset&&a.setUTCFullYear)};c.isRegExp=function(a){return!!(a&&a.test&&a.exec&&(a.ignoreCase||
+a.ignoreCase===false))};c.isNull=function(a){return a===null};c.isUndefined=function(a){return a===void 0};c.noConflict=function(){q._=C;return this};c.identity=function(a){return a};c.times=function(a,b,d){for(var e=0;e/g,interpolate:/<%=([\s\S]+?)%>/g};c.template=function(a,b){var d=c.templateSettings;d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+
+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.interpolate,function(e,f){return"',"+f.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||null,function(e,f){return"');"+f.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+"__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');";d=new Function("obj",d);return b?d(b):d};var l=function(a){this._wrapped=a};c.prototype=l.prototype;var r=function(a,b){return b?c(a).chain():a},H=function(a,b){l.prototype[a]=function(){var d=
+i.call(arguments);D.call(d,this._wrapped);return r(b.apply(c,d),this._chain)}};c.mixin(c);k(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var b=j[a];l.prototype[a]=function(){b.apply(this._wrapped,arguments);return r(this._wrapped,this._chain)}});k(["concat","join","slice"],function(a){var b=j[a];l.prototype[a]=function(){return r(b.apply(this._wrapped,arguments),this._chain)}});l.prototype.chain=function(){this._chain=true;return this};l.prototype.value=function(){return this._wrapped}})();
diff --git a/underscore.js b/underscore.js
index 9dfb2ad96..faa906005 100644
--- a/underscore.js
+++ b/underscore.js
@@ -1,5 +1,5 @@
-// Underscore.js 1.1.3
-// (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
+// Underscore.js 1.1.4
+// (c) 2011 Jeremy Ashkenas, DocumentCloud Inc.
// Underscore is freely distributable under the MIT license.
// Portions of Underscore are inspired or borrowed from Prototype,
// Oliver Steele's Functional, and John Resig's Micro-Templating.
@@ -58,7 +58,7 @@
}
// Current version.
- _.VERSION = '1.1.3';
+ _.VERSION = '1.1.4';
// Collection Functions
// --------------------