2 * jQuery JavaScript Library v2.0.4-pre
8 * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors
9 * Released under the MIT license
10 * http://jquery.org/license
12 * Date: 2014-02-14T09:19Z
15 (function ( window, factory ) {
17 if ( typeof module === "object" && typeof module.exports === "object" ) {
18 // Expose a jQuery-making factory as module.exports in loaders that implement the Node
19 // module pattern (including browserify).
20 // This accentuates the need for a real window in the environment
21 // e.g. var jQuery = require("jquery")(window);
22 module.exports = function( w ) {
25 throw new Error("jQuery requires a window with a document");
30 // Execute the factory to produce jQuery
31 var jQuery = factory( window );
33 // Register as a named AMD module, since jQuery can be concatenated with other
34 // files that may use define, but not via a proper concatenation script that
35 // understands anonymous AMD modules. A named AMD is safest and most robust
36 // way to register. Lowercase jquery is used because AMD module names are
37 // derived from file names, and jQuery is normally delivered in a lowercase
38 // file name. Do this after creating the global so that if an AMD module wants
39 // to call noConflict to hide this version of jQuery, it will work.
40 if ( typeof define === "function" && define.amd ) {
41 define( "jquery", [], function() {
47 // Pass this, window may not be defined yet
48 }(this, function ( window ) {
50 // Can't do this because several apps including ASP.NET trace
51 // the stack via arguments.caller.callee and Firefox dies if
52 // you try to trace through "use strict" call chains. (#13335)
53 // Support: Firefox 18+
56 // A central reference to the root jQuery(document)
59 // The deferred used on DOM ready
63 // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
64 core_strundefined = typeof undefined,
66 // Use the correct document accordingly with window argument (sandbox)
67 location = window.location,
68 document = window.document,
69 docElem = document.documentElement,
71 // Map over jQuery in case of overwrite
72 _jQuery = window.jQuery,
74 // Map over the $ in case of overwrite
77 // [[Class]] -> type pairs
80 // List of deleted data cache ids, so we can reuse them
83 core_version = "2.0.4-pre",
85 // Save a reference to some core methods
86 core_concat = core_deletedIds.concat,
87 core_push = core_deletedIds.push,
88 core_slice = core_deletedIds.slice,
89 core_indexOf = core_deletedIds.indexOf,
90 core_toString = class2type.toString,
91 core_hasOwn = class2type.hasOwnProperty,
92 core_trim = core_version.trim,
94 // Define a local copy of jQuery
95 jQuery = function( selector, context ) {
96 // The jQuery object is actually just the init constructor 'enhanced'
97 return new jQuery.fn.init( selector, context, rootjQuery );
100 // Used for matching numbers
101 core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
103 // Used for splitting on whitespace
104 core_rnotwhite = /\S+/g,
106 // A simple way to check for HTML strings
107 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
108 // Strict HTML recognition (#11290: must start with <)
109 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
111 // Match a standalone tag
112 rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
114 // Matches dashed string for camelizing
116 rdashAlpha = /-([\da-z])/gi,
118 // Used by jQuery.camelCase as callback to replace()
119 fcamelCase = function( all, letter ) {
120 return letter.toUpperCase();
123 // The ready event handler and self cleanup method
124 completed = function() {
125 document.removeEventListener( "DOMContentLoaded", completed, false );
126 window.removeEventListener( "load", completed, false );
130 jQuery.fn = jQuery.prototype = {
131 // The current version of jQuery being used
132 jquery: core_version,
135 init: function( selector, context, rootjQuery ) {
138 // HANDLE: $(""), $(null), $(undefined), $(false)
143 // Handle HTML strings
144 if ( typeof selector === "string" ) {
145 if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
146 // Assume that strings that start and end with <> are HTML and skip the regex check
147 match = [ null, selector, null ];
150 match = rquickExpr.exec( selector );
153 // Match html or make sure no context is specified for #id
154 if ( match && (match[1] || !context) ) {
156 // HANDLE: $(html) -> $(array)
158 context = context instanceof jQuery ? context[0] : context;
160 // scripts is true for back-compat
161 jQuery.merge( this, jQuery.parseHTML(
163 context && context.nodeType ? context.ownerDocument || context : document,
167 // HANDLE: $(html, props)
168 if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
169 for ( match in context ) {
170 // Properties of context are called as methods if possible
171 if ( jQuery.isFunction( this[ match ] ) ) {
172 this[ match ]( context[ match ] );
174 // ...and otherwise set as attributes
176 this.attr( match, context[ match ] );
185 elem = document.getElementById( match[2] );
187 // Check parentNode to catch when Blackberry 4.6 returns
188 // nodes that are no longer in the document #6963
189 if ( elem && elem.parentNode ) {
190 // Inject the element directly into the jQuery object
195 this.context = document;
196 this.selector = selector;
200 // HANDLE: $(expr, $(...))
201 } else if ( !context || context.jquery ) {
202 return ( context || rootjQuery ).find( selector );
204 // HANDLE: $(expr, context)
205 // (which is just equivalent to: $(context).find(expr)
207 return this.constructor( context ).find( selector );
210 // HANDLE: $(DOMElement)
211 } else if ( selector.nodeType ) {
212 this.context = this[0] = selector;
216 // HANDLE: $(function)
217 // Shortcut for document ready
218 } else if ( jQuery.isFunction( selector ) ) {
219 return rootjQuery.ready( selector );
222 if ( selector.selector !== undefined ) {
223 this.selector = selector.selector;
224 this.context = selector.context;
227 return jQuery.makeArray( selector, this );
230 // Start with an empty selector
233 // The default length of a jQuery object is 0
236 toArray: function() {
237 return core_slice.call( this );
240 // Get the Nth element in the matched element set OR
241 // Get the whole matched element set as a clean array
242 get: function( num ) {
245 // Return a 'clean' array
248 // Return just the object
249 ( num < 0 ? this[ this.length + num ] : this[ num ] );
252 // Take an array of elements and push it onto the stack
253 // (returning the new matched element set)
254 pushStack: function( elems ) {
256 // Build a new jQuery matched element set
257 var ret = jQuery.merge( this.constructor(), elems );
259 // Add the old object onto the stack (as a reference)
260 ret.prevObject = this;
261 ret.context = this.context;
263 // Return the newly-formed element set
267 // Execute a callback for every element in the matched set.
268 // (You can seed the arguments with an array of args, but this is
269 // only used internally.)
270 each: function( callback, args ) {
271 return jQuery.each( this, callback, args );
274 ready: function( fn ) {
276 jQuery.ready.promise().done( fn );
282 return this.pushStack( core_slice.apply( this, arguments ) );
290 return this.eq( -1 );
294 var len = this.length,
295 j = +i + ( i < 0 ? len : 0 );
296 return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
299 map: function( callback ) {
300 return this.pushStack( jQuery.map(this, function( elem, i ) {
301 return callback.call( elem, i, elem );
306 return this.prevObject || this.constructor(null);
309 // For internal use only.
310 // Behaves like an Array's method, not like a jQuery method.
316 // Give the init function the jQuery prototype for later instantiation
317 jQuery.fn.init.prototype = jQuery.fn;
319 jQuery.extend = jQuery.fn.extend = function() {
320 var options, name, src, copy, copyIsArray, clone,
321 target = arguments[0] || {},
323 length = arguments.length,
326 // Handle a deep copy situation
327 if ( typeof target === "boolean" ) {
329 target = arguments[1] || {};
330 // skip the boolean and the target
334 // Handle case when target is a string or something (possible in deep copy)
335 if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
339 // extend jQuery itself if only one argument is passed
340 if ( length === i ) {
345 for ( ; i < length; i++ ) {
346 // Only deal with non-null/undefined values
347 if ( (options = arguments[ i ]) != null ) {
348 // Extend the base object
349 for ( name in options ) {
350 src = target[ name ];
351 copy = options[ name ];
353 // Prevent never-ending loop
354 if ( target === copy ) {
358 // Recurse if we're merging plain objects or arrays
359 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
362 clone = src && jQuery.isArray(src) ? src : [];
365 clone = src && jQuery.isPlainObject(src) ? src : {};
368 // Never move original objects, clone them
369 target[ name ] = jQuery.extend( deep, clone, copy );
371 // Don't bring in undefined values
372 } else if ( copy !== undefined ) {
373 target[ name ] = copy;
379 // Return the modified object
384 // Unique for each copy of jQuery on the page
385 expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
387 noConflict: function( deep ) {
388 if ( window.$ === jQuery ) {
392 if ( deep && window.jQuery === jQuery ) {
393 window.jQuery = _jQuery;
399 // Is the DOM ready to be used? Set to true once it occurs.
402 // A counter to track how many items to wait for before
403 // the ready event fires. See #6781
406 // Hold (or release) the ready event
407 holdReady: function( hold ) {
411 jQuery.ready( true );
415 // Handle when the DOM is ready
416 ready: function( wait ) {
418 // Abort if there are pending holds or we're already ready
419 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
423 // Remember that the DOM is ready
424 jQuery.isReady = true;
426 // If a normal DOM Ready event fired, decrement, and wait if need be
427 if ( wait !== true && --jQuery.readyWait > 0 ) {
431 // If there are functions bound, to execute
432 readyList.resolveWith( document, [ jQuery ] );
434 // Trigger any bound ready events
435 if ( jQuery.fn.trigger ) {
436 jQuery( document ).trigger("ready").off("ready");
440 // See test/unit/core.js for details concerning isFunction.
441 // Since version 1.3, DOM methods and functions like alert
442 // aren't supported. They return false on IE (#2968).
443 isFunction: function( obj ) {
444 return jQuery.type(obj) === "function";
447 isArray: Array.isArray,
449 isWindow: function( obj ) {
450 return obj != null && obj === obj.window;
453 isNumeric: function( obj ) {
454 return !isNaN( parseFloat(obj) ) && isFinite( obj );
457 type: function( obj ) {
459 return String( obj );
461 // Support: Safari <= 5.1 (functionish RegExp)
462 return typeof obj === "object" || typeof obj === "function" ?
463 class2type[ core_toString.call(obj) ] || "object" :
467 isPlainObject: function( obj ) {
468 // Not plain objects:
469 // - Any object or value whose internal [[Class]] property is not "[object Object]"
472 if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
476 // Support: Firefox <20
477 // The try/catch suppresses exceptions thrown when attempting to access
478 // the "constructor" property of certain host objects, ie. |window.location|
479 // https://bugzilla.mozilla.org/show_bug.cgi?id=814622
481 if ( obj.constructor &&
482 !core_hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
489 // If the function hasn't returned already, we're confident that
490 // |obj| is a plain object, created by {} or constructed with new Object
494 isEmptyObject: function( obj ) {
496 for ( name in obj ) {
502 error: function( msg ) {
503 throw new Error( msg );
506 // data: string of html
507 // context (optional): If specified, the fragment will be created in this context, defaults to document
508 // keepScripts (optional): If true, will include scripts passed in the html string
509 parseHTML: function( data, context, keepScripts ) {
510 if ( !data || typeof data !== "string" ) {
513 if ( typeof context === "boolean" ) {
514 keepScripts = context;
517 context = context || document;
519 var parsed = rsingleTag.exec( data ),
520 scripts = !keepScripts && [];
524 return [ context.createElement( parsed[1] ) ];
527 parsed = jQuery.buildFragment( [ data ], context, scripts );
530 jQuery( scripts ).remove();
533 return jQuery.merge( [], parsed.childNodes );
536 parseJSON: JSON.parse,
538 // Cross-browser xml parsing
539 parseXML: function( data ) {
541 if ( !data || typeof data !== "string" ) {
547 tmp = new DOMParser();
548 xml = tmp.parseFromString( data , "text/xml" );
553 if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
554 jQuery.error( "Invalid XML: " + data );
561 // Evaluates a script in a global context
562 globalEval: function( code ) {
566 code = jQuery.trim( code );
569 // If the code includes a valid, prologue position
570 // strict mode pragma, execute code by injecting a
571 // script tag into the document.
572 if ( code.indexOf("use strict") === 1 ) {
573 script = document.createElement("script");
575 document.head.appendChild( script ).parentNode.removeChild( script );
577 // Otherwise, avoid the DOM node creation, insertion
578 // and removal by using an indirect global eval
584 // Convert dashed to camelCase; used by the css and data modules
585 // Microsoft forgot to hump their vendor prefix (#9572)
586 camelCase: function( string ) {
587 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
590 nodeName: function( elem, name ) {
591 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
594 // args is for internal usage only
595 each: function( obj, callback, args ) {
599 isArray = isArraylike( obj );
603 for ( ; i < length; i++ ) {
604 value = callback.apply( obj[ i ], args );
606 if ( value === false ) {
612 value = callback.apply( obj[ i ], args );
614 if ( value === false ) {
620 // A special, fast, case for the most common use of each
623 for ( ; i < length; i++ ) {
624 value = callback.call( obj[ i ], i, obj[ i ] );
626 if ( value === false ) {
632 value = callback.call( obj[ i ], i, obj[ i ] );
634 if ( value === false ) {
644 trim: function( text ) {
645 return text == null ? "" : core_trim.call( text );
648 // results is for internal usage only
649 makeArray: function( arr, results ) {
650 var ret = results || [];
653 if ( isArraylike( Object(arr) ) ) {
655 typeof arr === "string" ?
659 core_push.call( ret, arr );
666 inArray: function( elem, arr, i ) {
667 return arr == null ? -1 : core_indexOf.call( arr, elem, i );
670 merge: function( first, second ) {
671 var l = second.length,
675 if ( typeof l === "number" ) {
676 for ( ; j < l; j++ ) {
677 first[ i++ ] = second[ j ];
680 while ( second[j] !== undefined ) {
681 first[ i++ ] = second[ j++ ];
690 grep: function( elems, callback, inv ) {
694 length = elems.length;
697 // Go through the array, only saving the items
698 // that pass the validator function
699 for ( ; i < length; i++ ) {
700 retVal = !!callback( elems[ i ], i );
701 if ( inv !== retVal ) {
702 ret.push( elems[ i ] );
709 // arg is for internal usage only
710 map: function( elems, callback, arg ) {
713 length = elems.length,
714 isArray = isArraylike( elems ),
717 // Go through the array, translating each of the items to their
719 for ( ; i < length; i++ ) {
720 value = callback( elems[ i ], i, arg );
722 if ( value != null ) {
723 ret[ ret.length ] = value;
727 // Go through every key on the object,
730 value = callback( elems[ i ], i, arg );
732 if ( value != null ) {
733 ret[ ret.length ] = value;
738 // Flatten any nested arrays
739 return core_concat.apply( [], ret );
742 // A global GUID counter for objects
745 // Bind a function to a context, optionally partially applying any
747 proxy: function( fn, context ) {
748 var tmp, args, proxy;
750 if ( typeof context === "string" ) {
756 // Quick check to determine if target is callable, in the spec
757 // this throws a TypeError, but we will just return undefined.
758 if ( !jQuery.isFunction( fn ) ) {
763 args = core_slice.call( arguments, 2 );
765 return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
768 // Set the guid of unique handler to the same of original handler, so it can be removed
769 proxy.guid = fn.guid = fn.guid || jQuery.guid++;
774 // Multifunctional method to get and set values of a collection
775 // The value/s can optionally be executed if it's a function
776 access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
778 length = elems.length,
782 if ( jQuery.type( key ) === "object" ) {
785 jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
789 } else if ( value !== undefined ) {
792 if ( !jQuery.isFunction( value ) ) {
797 // Bulk operations run against the entire set
799 fn.call( elems, value );
802 // ...except when executing function values
805 fn = function( elem, key, value ) {
806 return bulk.call( jQuery( elem ), value );
812 for ( ; i < length; i++ ) {
813 fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
824 length ? fn( elems[0], key ) : emptyGet;
829 // A method for quickly swapping in/out CSS properties to get correct calculations.
830 // Note: this method belongs to the css module but it's needed here for the support module.
831 // If support gets modularized, this method should be moved back to the css module.
832 swap: function( elem, options, callback, args ) {
836 // Remember the old values, and insert the new ones
837 for ( name in options ) {
838 old[ name ] = elem.style[ name ];
839 elem.style[ name ] = options[ name ];
842 ret = callback.apply( elem, args || [] );
844 // Revert the old values
845 for ( name in options ) {
846 elem.style[ name ] = old[ name ];
853 jQuery.ready.promise = function( obj ) {
856 readyList = jQuery.Deferred();
858 // Catch cases where $(document).ready() is called after the browser event has already occurred.
859 // we once tried to use readyState "interactive" here, but it caused issues like the one
860 // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
861 if ( document.readyState === "complete" ) {
862 // Handle it asynchronously to allow scripts the opportunity to delay ready
863 setTimeout( jQuery.ready );
867 // Use the handy event callback
868 document.addEventListener( "DOMContentLoaded", completed, false );
870 // A fallback to window.onload, that will always work
871 window.addEventListener( "load", completed, false );
874 return readyList.promise( obj );
877 // Populate the class2type map
878 jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
879 class2type[ "[object " + name + "]" ] = name.toLowerCase();
882 function isArraylike( obj ) {
883 var length = obj.length,
884 type = jQuery.type( obj );
886 if ( jQuery.isWindow( obj ) ) {
890 if ( obj.nodeType === 1 && length ) {
894 return type === "array" || type !== "function" &&
896 typeof length === "number" && length > 0 && ( length - 1 ) in obj );
899 // All jQuery objects should point back to these
900 rootjQuery = jQuery(document);
902 * Sizzle CSS Selector Engine v1.10.18
903 * http://sizzlejs.com/
905 * Copyright 2013 jQuery Foundation, Inc. and other contributors
906 * Released under the MIT license
907 * http://jquery.org/license
911 (function( window ) {
924 // Local document vars
934 // Instance-specific data
935 expando = "sizzle" + -(new Date()),
936 preferredDoc = window.document,
939 classCache = createCache(),
940 tokenCache = createCache(),
941 compilerCache = createCache(),
942 sortOrder = function( a, b ) {
949 // General-purpose constants
950 strundefined = typeof undefined,
951 MAX_NEGATIVE = 1 << 31,
954 hasOwn = ({}).hasOwnProperty,
957 push_native = arr.push,
960 // Use a stripped-down indexOf if we can't use a native one
961 indexOf = arr.indexOf || function( elem ) {
964 for ( ; i < len; i++ ) {
965 if ( this[i] === elem ) {
972 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
974 // Regular expressions
976 // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
977 whitespace = "[\\x20\\t\\r\\n\\f]",
978 // http://www.w3.org/TR/css3-syntax/#characters
979 characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
981 // Loosely modeled on CSS identifier characters
982 // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
983 // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
984 identifier = characterEncoding.replace( "w", "w#" ),
986 // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
987 attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
988 "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
990 // Prefer arguments quoted,
991 // then not containing pseudos/brackets,
992 // then attribute selectors/non-parenthetical expressions,
993 // then anything else
994 // These preferences are here to reduce the number of selectors
995 // needing tokenize in the PSEUDO preFilter
996 pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
998 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
999 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
1001 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
1002 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
1004 rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
1006 rpseudo = new RegExp( pseudos ),
1007 ridentifier = new RegExp( "^" + identifier + "$" ),
1010 "ID": new RegExp( "^#(" + characterEncoding + ")" ),
1011 "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
1012 "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
1013 "ATTR": new RegExp( "^" + attributes ),
1014 "PSEUDO": new RegExp( "^" + pseudos ),
1015 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
1016 "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
1017 "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
1018 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
1019 // For use in libraries implementing .is()
1020 // We use this for POS matching in `select`
1021 "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
1022 whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
1025 rinputs = /^(?:input|select|textarea|button)$/i,
1028 rnative = /^[^{]+\{\s*\[native \w/,
1030 // Easily-parseable/retrievable ID or TAG or CLASS selectors
1031 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
1036 // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
1037 runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
1038 funescape = function( _, escaped, escapedWhitespace ) {
1039 var high = "0x" + escaped - 0x10000;
1040 // NaN means non-codepoint
1041 // Support: Firefox<24
1042 // Workaround erroneous numeric interpretation of +"0x"
1043 return high !== high || escapedWhitespace ?
1047 String.fromCharCode( high + 0x10000 ) :
1048 // Supplemental Plane codepoint (surrogate pair)
1049 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
1052 // Optimize for push.apply( _, NodeList )
1055 (arr = slice.call( preferredDoc.childNodes )),
1056 preferredDoc.childNodes
1058 // Support: Android<4.0
1059 // Detect silently failing push.apply
1060 arr[ preferredDoc.childNodes.length ].nodeType;
1062 push = { apply: arr.length ?
1064 // Leverage slice if possible
1065 function( target, els ) {
1066 push_native.apply( target, slice.call(els) );
1070 // Otherwise append directly
1071 function( target, els ) {
1072 var j = target.length,
1074 // Can't trust NodeList.length
1075 while ( (target[j++] = els[i++]) ) {}
1076 target.length = j - 1;
1081 function Sizzle( selector, context, results, seed ) {
1082 var match, elem, m, nodeType,
1084 i, groups, old, nid, newContext, newSelector;
1086 if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
1087 setDocument( context );
1090 context = context || document;
1091 results = results || [];
1093 if ( !selector || typeof selector !== "string" ) {
1097 if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
1101 if ( documentIsHTML && !seed ) {
1104 if ( (match = rquickExpr.exec( selector )) ) {
1105 // Speed-up: Sizzle("#ID")
1106 if ( (m = match[1]) ) {
1107 if ( nodeType === 9 ) {
1108 elem = context.getElementById( m );
1109 // Check parentNode to catch when Blackberry 4.6 returns
1110 // nodes that are no longer in the document (jQuery #6963)
1111 if ( elem && elem.parentNode ) {
1112 // Handle the case where IE, Opera, and Webkit return items
1113 // by name instead of ID
1114 if ( elem.id === m ) {
1115 results.push( elem );
1122 // Context is not a document
1123 if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
1124 contains( context, elem ) && elem.id === m ) {
1125 results.push( elem );
1130 // Speed-up: Sizzle("TAG")
1131 } else if ( match[2] ) {
1132 push.apply( results, context.getElementsByTagName( selector ) );
1135 // Speed-up: Sizzle(".CLASS")
1136 } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
1137 push.apply( results, context.getElementsByClassName( m ) );
1143 if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
1144 nid = old = expando;
1145 newContext = context;
1146 newSelector = nodeType === 9 && selector;
1148 // qSA works strangely on Element-rooted queries
1149 // We can work around this by specifying an extra ID on the root
1150 // and working up from there (Thanks to Andrew Dupont for the technique)
1151 // IE 8 doesn't work on object elements
1152 if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
1153 groups = tokenize( selector );
1155 if ( (old = context.getAttribute("id")) ) {
1156 nid = old.replace( rescape, "\\$&" );
1158 context.setAttribute( "id", nid );
1160 nid = "[id='" + nid + "'] ";
1164 groups[i] = nid + toSelector( groups[i] );
1166 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
1167 newSelector = groups.join(",");
1170 if ( newSelector ) {
1172 push.apply( results,
1173 newContext.querySelectorAll( newSelector )
1179 context.removeAttribute("id");
1187 return select( selector.replace( rtrim, "$1" ), context, results, seed );
1191 * Create key-value caches of limited size
1192 * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
1193 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
1194 * deleting the oldest entry
1196 function createCache() {
1199 function cache( key, value ) {
1200 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
1201 if ( keys.push( key + " " ) > Expr.cacheLength ) {
1202 // Only keep the most recent entries
1203 delete cache[ keys.shift() ];
1205 return (cache[ key + " " ] = value);
1211 * Mark a function for special use by Sizzle
1212 * @param {Function} fn The function to mark
1214 function markFunction( fn ) {
1215 fn[ expando ] = true;
1220 * Support testing using an element
1221 * @param {Function} fn Passed the created div and expects a boolean result
1223 function assert( fn ) {
1224 var div = document.createElement("div");
1231 // Remove from its parent by default
1232 if ( div.parentNode ) {
1233 div.parentNode.removeChild( div );
1235 // release memory in IE
1241 * Adds the same handler for all of the specified attrs
1242 * @param {String} attrs Pipe-separated list of attributes
1243 * @param {Function} handler The method that will be applied
1245 function addHandle( attrs, handler ) {
1246 var arr = attrs.split("|"),
1250 Expr.attrHandle[ arr[i] ] = handler;
1255 * Checks document order of two siblings
1256 * @param {Element} a
1257 * @param {Element} b
1258 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
1260 function siblingCheck( a, b ) {
1262 diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
1263 ( ~b.sourceIndex || MAX_NEGATIVE ) -
1264 ( ~a.sourceIndex || MAX_NEGATIVE );
1266 // Use IE sourceIndex if available on both nodes
1271 // Check if b follows a
1273 while ( (cur = cur.nextSibling) ) {
1284 * Returns a function to use in pseudos for input types
1285 * @param {String} type
1287 function createInputPseudo( type ) {
1288 return function( elem ) {
1289 var name = elem.nodeName.toLowerCase();
1290 return name === "input" && elem.type === type;
1295 * Returns a function to use in pseudos for buttons
1296 * @param {String} type
1298 function createButtonPseudo( type ) {
1299 return function( elem ) {
1300 var name = elem.nodeName.toLowerCase();
1301 return (name === "input" || name === "button") && elem.type === type;
1306 * Returns a function to use in pseudos for positionals
1307 * @param {Function} fn
1309 function createPositionalPseudo( fn ) {
1310 return markFunction(function( argument ) {
1311 argument = +argument;
1312 return markFunction(function( seed, matches ) {
1314 matchIndexes = fn( [], seed.length, argument ),
1315 i = matchIndexes.length;
1317 // Match elements found at the specified indexes
1319 if ( seed[ (j = matchIndexes[i]) ] ) {
1320 seed[j] = !(matches[j] = seed[j]);
1328 * Checks a node for validity as a Sizzle context
1329 * @param {Element|Object=} context
1330 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1332 function testContext( context ) {
1333 return context && typeof context.getElementsByTagName !== strundefined && context;
1336 // Expose support vars for convenience
1337 support = Sizzle.support = {};
1341 * @param {Element|Object} elem An element or a document
1342 * @returns {Boolean} True iff elem is a non-HTML XML node
1344 isXML = Sizzle.isXML = function( elem ) {
1345 // documentElement is verified for cases where it doesn't yet exist
1346 // (such as loading iframes in IE - #4833)
1347 var documentElement = elem && (elem.ownerDocument || elem).documentElement;
1348 return documentElement ? documentElement.nodeName !== "HTML" : false;
1352 * Sets document-related variables once based on the current document
1353 * @param {Element|Object} [doc] An element or document object to use to set the document
1354 * @returns {Object} Returns the current document
1356 setDocument = Sizzle.setDocument = function( node ) {
1358 doc = node ? node.ownerDocument || node : preferredDoc,
1359 parent = doc.defaultView;
1361 // If no document and documentElement is available, return
1362 if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
1368 docElem = doc.documentElement;
1371 documentIsHTML = !isXML( doc );
1374 // If iframe document is assigned to "document" variable and if iframe has been reloaded,
1375 // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
1376 // IE6-8 do not support the defaultView property so parent will be undefined
1377 if ( parent && parent !== parent.top ) {
1378 // IE11 does not have attachEvent, so all must suffer
1379 if ( parent.addEventListener ) {
1380 parent.addEventListener( "unload", function() {
1383 } else if ( parent.attachEvent ) {
1384 parent.attachEvent( "onunload", function() {
1391 ---------------------------------------------------------------------- */
1394 // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
1395 support.attributes = assert(function( div ) {
1396 div.className = "i";
1397 return !div.getAttribute("className");
1401 ---------------------------------------------------------------------- */
1403 // Check if getElementsByTagName("*") returns only elements
1404 support.getElementsByTagName = assert(function( div ) {
1405 div.appendChild( doc.createComment("") );
1406 return !div.getElementsByTagName("*").length;
1409 // Check if getElementsByClassName can be trusted
1410 support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {
1411 div.innerHTML = "<div class='a'></div><div class='a i'></div>";
1413 // Support: Safari<4
1414 // Catch class over-caching
1415 div.firstChild.className = "i";
1416 // Support: Opera<10
1417 // Catch gEBCN failure to find non-leading classes
1418 return div.getElementsByClassName("i").length === 2;
1422 // Check if getElementById returns elements by name
1423 // The broken getElementById methods don't pick up programatically-set names,
1424 // so use a roundabout getElementsByName test
1425 support.getById = assert(function( div ) {
1426 docElem.appendChild( div ).id = expando;
1427 return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
1430 // ID find and filter
1431 if ( support.getById ) {
1432 Expr.find["ID"] = function( id, context ) {
1433 if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
1434 var m = context.getElementById( id );
1435 // Check parentNode to catch when Blackberry 4.6 returns
1436 // nodes that are no longer in the document #6963
1437 return m && m.parentNode ? [m] : [];
1440 Expr.filter["ID"] = function( id ) {
1441 var attrId = id.replace( runescape, funescape );
1442 return function( elem ) {
1443 return elem.getAttribute("id") === attrId;
1448 // getElementById is not reliable as a find shortcut
1449 delete Expr.find["ID"];
1451 Expr.filter["ID"] = function( id ) {
1452 var attrId = id.replace( runescape, funescape );
1453 return function( elem ) {
1454 var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
1455 return node && node.value === attrId;
1461 Expr.find["TAG"] = support.getElementsByTagName ?
1462 function( tag, context ) {
1463 if ( typeof context.getElementsByTagName !== strundefined ) {
1464 return context.getElementsByTagName( tag );
1467 function( tag, context ) {
1471 results = context.getElementsByTagName( tag );
1473 // Filter out possible comments
1474 if ( tag === "*" ) {
1475 while ( (elem = results[i++]) ) {
1476 if ( elem.nodeType === 1 ) {
1487 Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
1488 if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
1489 return context.getElementsByClassName( className );
1493 /* QSA/matchesSelector
1494 ---------------------------------------------------------------------- */
1496 // QSA and matchesSelector support
1498 // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1501 // qSa(:focus) reports false when true (Chrome 21)
1502 // We allow this because of a bug in IE8/9 that throws an error
1503 // whenever `document.activeElement` is accessed on an iframe
1504 // So, we allow :focus to pass through QSA all the time to avoid the IE error
1505 // See http://bugs.jquery.com/ticket/13378
1508 if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
1510 // Regex strategy adopted from Diego Perini
1511 assert(function( div ) {
1512 // Select is set to empty string on purpose
1513 // This is to test IE's treatment of not explicitly
1514 // setting a boolean content attribute,
1515 // since its presence should be enough
1516 // http://bugs.jquery.com/ticket/12359
1517 div.innerHTML = "<select t=''><option selected=''></option></select>";
1519 // Support: IE8, Opera 10-12
1520 // Nothing should be selected when empty strings follow ^= or $= or *=
1521 if ( div.querySelectorAll("[t^='']").length ) {
1522 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1526 // Boolean attributes and "value" are not treated correctly
1527 if ( !div.querySelectorAll("[selected]").length ) {
1528 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1531 // Webkit/Opera - :checked should return selected option elements
1532 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1533 // IE8 throws error here and will not see later tests
1534 if ( !div.querySelectorAll(":checked").length ) {
1535 rbuggyQSA.push(":checked");
1539 assert(function( div ) {
1540 // Support: Windows 8 Native Apps
1541 // The type and name attributes are restricted during .innerHTML assignment
1542 var input = doc.createElement("input");
1543 input.setAttribute( "type", "hidden" );
1544 div.appendChild( input ).setAttribute( "name", "D" );
1547 // Enforce case-sensitivity of name attribute
1548 if ( div.querySelectorAll("[name=d]").length ) {
1549 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1552 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1553 // IE8 throws error here and will not see later tests
1554 if ( !div.querySelectorAll(":enabled").length ) {
1555 rbuggyQSA.push( ":enabled", ":disabled" );
1558 // Opera 10-11 does not throw on post-comma invalid pseudos
1559 div.querySelectorAll("*,:x");
1560 rbuggyQSA.push(",.*:");
1564 if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
1565 docElem.mozMatchesSelector ||
1566 docElem.oMatchesSelector ||
1567 docElem.msMatchesSelector) )) ) {
1569 assert(function( div ) {
1570 // Check to see if it's possible to do matchesSelector
1571 // on a disconnected node (IE 9)
1572 support.disconnectedMatch = matches.call( div, "div" );
1574 // This should fail with an exception
1575 // Gecko does not error, returns false instead
1576 matches.call( div, "[s!='']:x" );
1577 rbuggyMatches.push( "!=", pseudos );
1581 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
1582 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
1585 ---------------------------------------------------------------------- */
1586 hasCompare = rnative.test( docElem.compareDocumentPosition );
1588 // Element contains another
1589 // Purposefully does not implement inclusive descendent
1590 // As in, an element does not contain itself
1591 contains = hasCompare || rnative.test( docElem.contains ) ?
1593 var adown = a.nodeType === 9 ? a.documentElement : a,
1594 bup = b && b.parentNode;
1595 return a === bup || !!( bup && bup.nodeType === 1 && (
1597 adown.contains( bup ) :
1598 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1603 while ( (b = b.parentNode) ) {
1613 ---------------------------------------------------------------------- */
1615 // Document order sorting
1616 sortOrder = hasCompare ?
1619 // Flag for duplicate removal
1621 hasDuplicate = true;
1625 // Sort on method existence if only one input has compareDocumentPosition
1626 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1631 // Calculate position if both inputs belong to the same document
1632 compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
1633 a.compareDocumentPosition( b ) :
1635 // Otherwise we know they are disconnected
1638 // Disconnected nodes
1640 (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
1642 // Choose the first element that is related to our preferred document
1643 if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
1646 if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
1650 // Maintain original order
1652 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1656 return compare & 4 ? -1 : 1;
1659 // Exit early if the nodes are identical
1661 hasDuplicate = true;
1672 // Parentless nodes are either documents or disconnected
1673 if ( !aup || !bup ) {
1674 return a === doc ? -1 :
1679 ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
1682 // If the nodes are siblings, we can do a quick check
1683 } else if ( aup === bup ) {
1684 return siblingCheck( a, b );
1687 // Otherwise we need full lists of their ancestors for comparison
1689 while ( (cur = cur.parentNode) ) {
1693 while ( (cur = cur.parentNode) ) {
1697 // Walk down the tree looking for a discrepancy
1698 while ( ap[i] === bp[i] ) {
1703 // Do a sibling check if the nodes have a common ancestor
1704 siblingCheck( ap[i], bp[i] ) :
1706 // Otherwise nodes in our document sort first
1707 ap[i] === preferredDoc ? -1 :
1708 bp[i] === preferredDoc ? 1 :
1715 Sizzle.matches = function( expr, elements ) {
1716 return Sizzle( expr, null, null, elements );
1719 Sizzle.matchesSelector = function( elem, expr ) {
1720 // Set document vars if needed
1721 if ( ( elem.ownerDocument || elem ) !== document ) {
1722 setDocument( elem );
1725 // Make sure that attribute selectors are quoted
1726 expr = expr.replace( rattributeQuotes, "='$1']" );
1728 if ( support.matchesSelector && documentIsHTML &&
1729 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
1730 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
1733 var ret = matches.call( elem, expr );
1735 // IE 9's matchesSelector returns false on disconnected nodes
1736 if ( ret || support.disconnectedMatch ||
1737 // As well, disconnected nodes are said to be in a document
1739 elem.document && elem.document.nodeType !== 11 ) {
1745 return Sizzle( expr, document, null, [elem] ).length > 0;
1748 Sizzle.contains = function( context, elem ) {
1749 // Set document vars if needed
1750 if ( ( context.ownerDocument || context ) !== document ) {
1751 setDocument( context );
1753 return contains( context, elem );
1756 Sizzle.attr = function( elem, name ) {
1757 // Set document vars if needed
1758 if ( ( elem.ownerDocument || elem ) !== document ) {
1759 setDocument( elem );
1762 var fn = Expr.attrHandle[ name.toLowerCase() ],
1763 // Don't get fooled by Object.prototype properties (jQuery #13807)
1764 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
1765 fn( elem, name, !documentIsHTML ) :
1768 return val !== undefined ?
1770 support.attributes || !documentIsHTML ?
1771 elem.getAttribute( name ) :
1772 (val = elem.getAttributeNode(name)) && val.specified ?
1777 Sizzle.error = function( msg ) {
1778 throw new Error( "Syntax error, unrecognized expression: " + msg );
1782 * Document sorting and removing duplicates
1783 * @param {ArrayLike} results
1785 Sizzle.uniqueSort = function( results ) {
1791 // Unless we *know* we can detect duplicates, assume their presence
1792 hasDuplicate = !support.detectDuplicates;
1793 sortInput = !support.sortStable && results.slice( 0 );
1794 results.sort( sortOrder );
1796 if ( hasDuplicate ) {
1797 while ( (elem = results[i++]) ) {
1798 if ( elem === results[ i ] ) {
1799 j = duplicates.push( i );
1803 results.splice( duplicates[ j ], 1 );
1807 // Clear input after sorting to release objects
1808 // See https://github.com/jquery/sizzle/pull/225
1815 * Utility function for retrieving the text value of an array of DOM nodes
1816 * @param {Array|Element} elem
1818 getText = Sizzle.getText = function( elem ) {
1822 nodeType = elem.nodeType;
1825 // If no nodeType, this is expected to be an array
1826 while ( (node = elem[i++]) ) {
1827 // Do not traverse comment nodes
1828 ret += getText( node );
1830 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
1831 // Use textContent for elements
1832 // innerText usage removed for consistency of new lines (jQuery #11153)
1833 if ( typeof elem.textContent === "string" ) {
1834 return elem.textContent;
1836 // Traverse its children
1837 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
1838 ret += getText( elem );
1841 } else if ( nodeType === 3 || nodeType === 4 ) {
1842 return elem.nodeValue;
1844 // Do not include comment or processing instruction nodes
1849 Expr = Sizzle.selectors = {
1851 // Can be adjusted by the user
1854 createPseudo: markFunction,
1863 ">": { dir: "parentNode", first: true },
1864 " ": { dir: "parentNode" },
1865 "+": { dir: "previousSibling", first: true },
1866 "~": { dir: "previousSibling" }
1870 "ATTR": function( match ) {
1871 match[1] = match[1].replace( runescape, funescape );
1873 // Move the given value to match[3] whether quoted or unquoted
1874 match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
1876 if ( match[2] === "~=" ) {
1877 match[3] = " " + match[3] + " ";
1880 return match.slice( 0, 4 );
1883 "CHILD": function( match ) {
1884 /* matches from matchExpr["CHILD"]
1885 1 type (only|nth|...)
1886 2 what (child|of-type)
1887 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
1888 4 xn-component of xn+y argument ([+-]?\d*n|)
1889 5 sign of xn-component
1891 7 sign of y-component
1894 match[1] = match[1].toLowerCase();
1896 if ( match[1].slice( 0, 3 ) === "nth" ) {
1897 // nth-* requires argument
1899 Sizzle.error( match[0] );
1902 // numeric x and y parameters for Expr.filter.CHILD
1903 // remember that false/true cast respectively to 0/1
1904 match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
1905 match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
1907 // other types prohibit arguments
1908 } else if ( match[3] ) {
1909 Sizzle.error( match[0] );
1915 "PSEUDO": function( match ) {
1917 unquoted = !match[5] && match[2];
1919 if ( matchExpr["CHILD"].test( match[0] ) ) {
1923 // Accept quoted arguments as-is
1924 if ( match[3] && match[4] !== undefined ) {
1925 match[2] = match[4];
1927 // Strip excess characters from unquoted arguments
1928 } else if ( unquoted && rpseudo.test( unquoted ) &&
1929 // Get excess from tokenize (recursively)
1930 (excess = tokenize( unquoted, true )) &&
1931 // advance to the next closing parenthesis
1932 (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
1934 // excess is a negative index
1935 match[0] = match[0].slice( 0, excess );
1936 match[2] = unquoted.slice( 0, excess );
1939 // Return only captures needed by the pseudo filter method (type and argument)
1940 return match.slice( 0, 3 );
1946 "TAG": function( nodeNameSelector ) {
1947 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
1948 return nodeNameSelector === "*" ?
1949 function() { return true; } :
1951 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
1955 "CLASS": function( className ) {
1956 var pattern = classCache[ className + " " ];
1959 (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
1960 classCache( className, function( elem ) {
1961 return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
1965 "ATTR": function( name, operator, check ) {
1966 return function( elem ) {
1967 var result = Sizzle.attr( elem, name );
1969 if ( result == null ) {
1970 return operator === "!=";
1978 return operator === "=" ? result === check :
1979 operator === "!=" ? result !== check :
1980 operator === "^=" ? check && result.indexOf( check ) === 0 :
1981 operator === "*=" ? check && result.indexOf( check ) > -1 :
1982 operator === "$=" ? check && result.slice( -check.length ) === check :
1983 operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
1984 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
1989 "CHILD": function( type, what, argument, first, last ) {
1990 var simple = type.slice( 0, 3 ) !== "nth",
1991 forward = type.slice( -4 ) !== "last",
1992 ofType = what === "of-type";
1994 return first === 1 && last === 0 ?
1996 // Shortcut for :nth-*(n)
1998 return !!elem.parentNode;
2001 function( elem, context, xml ) {
2002 var cache, outerCache, node, diff, nodeIndex, start,
2003 dir = simple !== forward ? "nextSibling" : "previousSibling",
2004 parent = elem.parentNode,
2005 name = ofType && elem.nodeName.toLowerCase(),
2006 useCache = !xml && !ofType;
2010 // :(first|last|only)-(child|of-type)
2014 while ( (node = node[ dir ]) ) {
2015 if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
2019 // Reverse direction for :only-* (if we haven't yet done so)
2020 start = dir = type === "only" && !start && "nextSibling";
2025 start = [ forward ? parent.firstChild : parent.lastChild ];
2027 // non-xml :nth-child(...) stores cache data on `parent`
2028 if ( forward && useCache ) {
2029 // Seek `elem` from a previously-cached index
2030 outerCache = parent[ expando ] || (parent[ expando ] = {});
2031 cache = outerCache[ type ] || [];
2032 nodeIndex = cache[0] === dirruns && cache[1];
2033 diff = cache[0] === dirruns && cache[2];
2034 node = nodeIndex && parent.childNodes[ nodeIndex ];
2036 while ( (node = ++nodeIndex && node && node[ dir ] ||
2038 // Fallback to seeking `elem` from the start
2039 (diff = nodeIndex = 0) || start.pop()) ) {
2041 // When found, cache indexes on `parent` and break
2042 if ( node.nodeType === 1 && ++diff && node === elem ) {
2043 outerCache[ type ] = [ dirruns, nodeIndex, diff ];
2048 // Use previously-cached element index if available
2049 } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
2052 // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
2054 // Use the same loop as above to seek `elem` from the start
2055 while ( (node = ++nodeIndex && node && node[ dir ] ||
2056 (diff = nodeIndex = 0) || start.pop()) ) {
2058 if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
2059 // Cache the index of each encountered element
2061 (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
2064 if ( node === elem ) {
2071 // Incorporate the offset, then check against cycle size
2073 return diff === first || ( diff % first === 0 && diff / first >= 0 );
2078 "PSEUDO": function( pseudo, argument ) {
2079 // pseudo-class names are case-insensitive
2080 // http://www.w3.org/TR/selectors/#pseudo-classes
2081 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
2082 // Remember that setFilters inherits from pseudos
2084 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
2085 Sizzle.error( "unsupported pseudo: " + pseudo );
2087 // The user may use createPseudo to indicate that
2088 // arguments are needed to create the filter function
2089 // just as Sizzle does
2090 if ( fn[ expando ] ) {
2091 return fn( argument );
2094 // But maintain support for old signatures
2095 if ( fn.length > 1 ) {
2096 args = [ pseudo, pseudo, "", argument ];
2097 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
2098 markFunction(function( seed, matches ) {
2100 matched = fn( seed, argument ),
2103 idx = indexOf.call( seed, matched[i] );
2104 seed[ idx ] = !( matches[ idx ] = matched[i] );
2108 return fn( elem, 0, args );
2117 // Potentially complex pseudos
2118 "not": markFunction(function( selector ) {
2119 // Trim the selector passed to compile
2120 // to avoid treating leading and trailing
2121 // spaces as combinators
2124 matcher = compile( selector.replace( rtrim, "$1" ) );
2126 return matcher[ expando ] ?
2127 markFunction(function( seed, matches, context, xml ) {
2129 unmatched = matcher( seed, null, xml, [] ),
2132 // Match elements unmatched by `matcher`
2134 if ( (elem = unmatched[i]) ) {
2135 seed[i] = !(matches[i] = elem);
2139 function( elem, context, xml ) {
2141 matcher( input, null, xml, results );
2142 return !results.pop();
2146 "has": markFunction(function( selector ) {
2147 return function( elem ) {
2148 return Sizzle( selector, elem ).length > 0;
2152 "contains": markFunction(function( text ) {
2153 return function( elem ) {
2154 return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
2158 // "Whether an element is represented by a :lang() selector
2159 // is based solely on the element's language value
2160 // being equal to the identifier C,
2161 // or beginning with the identifier C immediately followed by "-".
2162 // The matching of C against the element's language value is performed case-insensitively.
2163 // The identifier C does not have to be a valid language name."
2164 // http://www.w3.org/TR/selectors/#lang-pseudo
2165 "lang": markFunction( function( lang ) {
2166 // lang value must be a valid identifier
2167 if ( !ridentifier.test(lang || "") ) {
2168 Sizzle.error( "unsupported lang: " + lang );
2170 lang = lang.replace( runescape, funescape ).toLowerCase();
2171 return function( elem ) {
2174 if ( (elemLang = documentIsHTML ?
2176 elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
2178 elemLang = elemLang.toLowerCase();
2179 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
2181 } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
2187 "target": function( elem ) {
2188 var hash = window.location && window.location.hash;
2189 return hash && hash.slice( 1 ) === elem.id;
2192 "root": function( elem ) {
2193 return elem === docElem;
2196 "focus": function( elem ) {
2197 return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
2200 // Boolean properties
2201 "enabled": function( elem ) {
2202 return elem.disabled === false;
2205 "disabled": function( elem ) {
2206 return elem.disabled === true;
2209 "checked": function( elem ) {
2210 // In CSS3, :checked should return both checked and selected elements
2211 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
2212 var nodeName = elem.nodeName.toLowerCase();
2213 return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
2216 "selected": function( elem ) {
2217 // Accessing this property makes selected-by-default
2218 // options in Safari work properly
2219 if ( elem.parentNode ) {
2220 elem.parentNode.selectedIndex;
2223 return elem.selected === true;
2227 "empty": function( elem ) {
2228 // http://www.w3.org/TR/selectors/#empty-pseudo
2229 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
2230 // but not by others (comment: 8; processing instruction: 7; etc.)
2231 // nodeType < 6 works because attributes (2) do not appear as children
2232 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2233 if ( elem.nodeType < 6 ) {
2240 "parent": function( elem ) {
2241 return !Expr.pseudos["empty"]( elem );
2244 // Element/input types
2245 "header": function( elem ) {
2246 return rheader.test( elem.nodeName );
2249 "input": function( elem ) {
2250 return rinputs.test( elem.nodeName );
2253 "button": function( elem ) {
2254 var name = elem.nodeName.toLowerCase();
2255 return name === "input" && elem.type === "button" || name === "button";
2258 "text": function( elem ) {
2260 return elem.nodeName.toLowerCase() === "input" &&
2261 elem.type === "text" &&
2264 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2265 ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
2268 // Position-in-collection
2269 "first": createPositionalPseudo(function() {
2273 "last": createPositionalPseudo(function( matchIndexes, length ) {
2274 return [ length - 1 ];
2277 "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
2278 return [ argument < 0 ? argument + length : argument ];
2281 "even": createPositionalPseudo(function( matchIndexes, length ) {
2283 for ( ; i < length; i += 2 ) {
2284 matchIndexes.push( i );
2286 return matchIndexes;
2289 "odd": createPositionalPseudo(function( matchIndexes, length ) {
2291 for ( ; i < length; i += 2 ) {
2292 matchIndexes.push( i );
2294 return matchIndexes;
2297 "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2298 var i = argument < 0 ? argument + length : argument;
2299 for ( ; --i >= 0; ) {
2300 matchIndexes.push( i );
2302 return matchIndexes;
2305 "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
2306 var i = argument < 0 ? argument + length : argument;
2307 for ( ; ++i < length; ) {
2308 matchIndexes.push( i );
2310 return matchIndexes;
2315 Expr.pseudos["nth"] = Expr.pseudos["eq"];
2317 // Add button/input type pseudos
2318 for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2319 Expr.pseudos[ i ] = createInputPseudo( i );
2321 for ( i in { submit: true, reset: true } ) {
2322 Expr.pseudos[ i ] = createButtonPseudo( i );
2325 // Easy API for creating new setFilters
2326 function setFilters() {}
2327 setFilters.prototype = Expr.filters = Expr.pseudos;
2328 Expr.setFilters = new setFilters();
2330 function tokenize( selector, parseOnly ) {
2331 var matched, match, tokens, type,
2332 soFar, groups, preFilters,
2333 cached = tokenCache[ selector + " " ];
2336 return parseOnly ? 0 : cached.slice( 0 );
2341 preFilters = Expr.preFilter;
2345 // Comma and first run
2346 if ( !matched || (match = rcomma.exec( soFar )) ) {
2348 // Don't consume trailing commas as valid
2349 soFar = soFar.slice( match[0].length ) || soFar;
2351 groups.push( (tokens = []) );
2357 if ( (match = rcombinators.exec( soFar )) ) {
2358 matched = match.shift();
2361 // Cast descendant combinators to space
2362 type: match[0].replace( rtrim, " " )
2364 soFar = soFar.slice( matched.length );
2368 for ( type in Expr.filter ) {
2369 if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
2370 (match = preFilters[ type ]( match ))) ) {
2371 matched = match.shift();
2377 soFar = soFar.slice( matched.length );
2386 // Return the length of the invalid excess
2387 // if we're just parsing
2388 // Otherwise, throw an error or return tokens
2392 Sizzle.error( selector ) :
2394 tokenCache( selector, groups ).slice( 0 );
2397 function toSelector( tokens ) {
2399 len = tokens.length,
2401 for ( ; i < len; i++ ) {
2402 selector += tokens[i].value;
2407 function addCombinator( matcher, combinator, base ) {
2408 var dir = combinator.dir,
2409 checkNonElements = base && dir === "parentNode",
2412 return combinator.first ?
2413 // Check against closest ancestor/preceding element
2414 function( elem, context, xml ) {
2415 while ( (elem = elem[ dir ]) ) {
2416 if ( elem.nodeType === 1 || checkNonElements ) {
2417 return matcher( elem, context, xml );
2422 // Check against all ancestor/preceding elements
2423 function( elem, context, xml ) {
2424 var oldCache, outerCache,
2425 newCache = [ dirruns, doneName ];
2427 // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
2429 while ( (elem = elem[ dir ]) ) {
2430 if ( elem.nodeType === 1 || checkNonElements ) {
2431 if ( matcher( elem, context, xml ) ) {
2437 while ( (elem = elem[ dir ]) ) {
2438 if ( elem.nodeType === 1 || checkNonElements ) {
2439 outerCache = elem[ expando ] || (elem[ expando ] = {});
2440 if ( (oldCache = outerCache[ dir ]) &&
2441 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2443 // Assign to newCache so results back-propagate to previous elements
2444 return (newCache[ 2 ] = oldCache[ 2 ]);
2446 // Reuse newcache so results back-propagate to previous elements
2447 outerCache[ dir ] = newCache;
2449 // A match means we're done; a fail means we have to keep checking
2450 if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
2460 function elementMatcher( matchers ) {
2461 return matchers.length > 1 ?
2462 function( elem, context, xml ) {
2463 var i = matchers.length;
2465 if ( !matchers[i]( elem, context, xml ) ) {
2474 function multipleContexts( selector, contexts, results ) {
2476 len = contexts.length;
2477 for ( ; i < len; i++ ) {
2478 Sizzle( selector, contexts[i], results );
2483 function condense( unmatched, map, filter, context, xml ) {
2487 len = unmatched.length,
2488 mapped = map != null;
2490 for ( ; i < len; i++ ) {
2491 if ( (elem = unmatched[i]) ) {
2492 if ( !filter || filter( elem, context, xml ) ) {
2493 newUnmatched.push( elem );
2501 return newUnmatched;
2504 function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2505 if ( postFilter && !postFilter[ expando ] ) {
2506 postFilter = setMatcher( postFilter );
2508 if ( postFinder && !postFinder[ expando ] ) {
2509 postFinder = setMatcher( postFinder, postSelector );
2511 return markFunction(function( seed, results, context, xml ) {
2515 preexisting = results.length,
2517 // Get initial elements from seed or context
2518 elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
2520 // Prefilter to get matcher input, preserving a map for seed-results synchronization
2521 matcherIn = preFilter && ( seed || !selector ) ?
2522 condense( elems, preMap, preFilter, context, xml ) :
2525 matcherOut = matcher ?
2526 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2527 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2529 // ...intermediate processing is necessary
2532 // ...otherwise use results directly
2536 // Find primary matches
2538 matcher( matcherIn, matcherOut, context, xml );
2543 temp = condense( matcherOut, postMap );
2544 postFilter( temp, [], context, xml );
2546 // Un-match failing elements by moving them back to matcherIn
2549 if ( (elem = temp[i]) ) {
2550 matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
2556 if ( postFinder || preFilter ) {
2558 // Get the final matcherOut by condensing this intermediate into postFinder contexts
2560 i = matcherOut.length;
2562 if ( (elem = matcherOut[i]) ) {
2563 // Restore matcherIn since elem is not yet a final match
2564 temp.push( (matcherIn[i] = elem) );
2567 postFinder( null, (matcherOut = []), temp, xml );
2570 // Move matched elements from seed to results to keep them synchronized
2571 i = matcherOut.length;
2573 if ( (elem = matcherOut[i]) &&
2574 (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
2576 seed[temp] = !(results[temp] = elem);
2581 // Add elements to results, through postFinder if defined
2583 matcherOut = condense(
2584 matcherOut === results ?
2585 matcherOut.splice( preexisting, matcherOut.length ) :
2589 postFinder( null, results, matcherOut, xml );
2591 push.apply( results, matcherOut );
2597 function matcherFromTokens( tokens ) {
2598 var checkContext, matcher, j,
2599 len = tokens.length,
2600 leadingRelative = Expr.relative[ tokens[0].type ],
2601 implicitRelative = leadingRelative || Expr.relative[" "],
2602 i = leadingRelative ? 1 : 0,
2604 // The foundational matcher ensures that elements are reachable from top-level context(s)
2605 matchContext = addCombinator( function( elem ) {
2606 return elem === checkContext;
2607 }, implicitRelative, true ),
2608 matchAnyContext = addCombinator( function( elem ) {
2609 return indexOf.call( checkContext, elem ) > -1;
2610 }, implicitRelative, true ),
2611 matchers = [ function( elem, context, xml ) {
2612 return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
2613 (checkContext = context).nodeType ?
2614 matchContext( elem, context, xml ) :
2615 matchAnyContext( elem, context, xml ) );
2618 for ( ; i < len; i++ ) {
2619 if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
2620 matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
2622 matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
2624 // Return special upon seeing a positional matcher
2625 if ( matcher[ expando ] ) {
2626 // Find the next relative operator (if any) for proper handling
2628 for ( ; j < len; j++ ) {
2629 if ( Expr.relative[ tokens[j].type ] ) {
2634 i > 1 && elementMatcher( matchers ),
2635 i > 1 && toSelector(
2636 // If the preceding token was a descendant combinator, insert an implicit any-element `*`
2637 tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
2638 ).replace( rtrim, "$1" ),
2640 i < j && matcherFromTokens( tokens.slice( i, j ) ),
2641 j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
2642 j < len && toSelector( tokens )
2645 matchers.push( matcher );
2649 return elementMatcher( matchers );
2652 function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
2653 var bySet = setMatchers.length > 0,
2654 byElement = elementMatchers.length > 0,
2655 superMatcher = function( seed, context, xml, results, outermost ) {
2656 var elem, j, matcher,
2659 unmatched = seed && [],
2661 contextBackup = outermostContext,
2662 // We must always have either seed elements or outermost context
2663 elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
2664 // Use integer dirruns iff this is the outermost matcher
2665 dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
2669 outermostContext = context !== document && context;
2672 // Add elements passing elementMatchers directly to results
2673 // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
2674 // Support: IE<9, Safari
2675 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
2676 for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
2677 if ( byElement && elem ) {
2679 while ( (matcher = elementMatchers[j++]) ) {
2680 if ( matcher( elem, context, xml ) ) {
2681 results.push( elem );
2686 dirruns = dirrunsUnique;
2690 // Track unmatched elements for set filters
2692 // They will have gone through all possible matchers
2693 if ( (elem = !matcher && elem) ) {
2697 // Lengthen the array for every element, matched or not
2699 unmatched.push( elem );
2704 // Apply set filters to unmatched elements
2706 if ( bySet && i !== matchedCount ) {
2708 while ( (matcher = setMatchers[j++]) ) {
2709 matcher( unmatched, setMatched, context, xml );
2713 // Reintegrate element matches to eliminate the need for sorting
2714 if ( matchedCount > 0 ) {
2716 if ( !(unmatched[i] || setMatched[i]) ) {
2717 setMatched[i] = pop.call( results );
2722 // Discard index placeholder values to get only actual matches
2723 setMatched = condense( setMatched );
2726 // Add matches to results
2727 push.apply( results, setMatched );
2729 // Seedless set matches succeeding multiple successful matchers stipulate sorting
2730 if ( outermost && !seed && setMatched.length > 0 &&
2731 ( matchedCount + setMatchers.length ) > 1 ) {
2733 Sizzle.uniqueSort( results );
2737 // Override manipulation of globals by nested matchers
2739 dirruns = dirrunsUnique;
2740 outermostContext = contextBackup;
2747 markFunction( superMatcher ) :
2751 compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
2754 elementMatchers = [],
2755 cached = compilerCache[ selector + " " ];
2758 // Generate a function of recursive functions that can be used to check each element
2760 match = tokenize( selector );
2764 cached = matcherFromTokens( match[i] );
2765 if ( cached[ expando ] ) {
2766 setMatchers.push( cached );
2768 elementMatchers.push( cached );
2772 // Cache the compiled function
2773 cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
2775 // Save selector and tokenization
2776 cached.selector = selector;
2782 * A low-level selection function that works with Sizzle's compiled
2783 * selector functions
2784 * @param {String|Function} selector A selector or a pre-compiled
2785 * selector function built with Sizzle.compile
2786 * @param {Element} context
2787 * @param {Array} [results]
2788 * @param {Array} [seed] A set of elements to match against
2790 select = Sizzle.select = function( selector, context, results, seed ) {
2791 var i, tokens, token, type, find,
2792 compiled = typeof selector === "function" && selector,
2793 match = !seed && tokenize( (selector = compiled.selector || selector) );
2795 results = results || [];
2797 // Try to minimize operations if there is no seed and only one group
2798 if ( match.length === 1 ) {
2800 // Take a shortcut and set the context if the root selector is an ID
2801 tokens = match[0] = match[0].slice( 0 );
2802 if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
2803 support.getById && context.nodeType === 9 && documentIsHTML &&
2804 Expr.relative[ tokens[1].type ] ) {
2806 context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
2810 // Precompiled matchers will still verify ancestry, so step up a level
2811 } else if ( compiled ) {
2812 context = context.parentNode;
2815 selector = selector.slice( tokens.shift().value.length );
2818 // Fetch a seed set for right-to-left matching
2819 i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
2823 // Abort if we hit a combinator
2824 if ( Expr.relative[ (type = token.type) ] ) {
2827 if ( (find = Expr.find[ type ]) ) {
2828 // Search, expanding context for leading sibling combinators
2830 token.matches[0].replace( runescape, funescape ),
2831 rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
2834 // If seed is empty or no tokens remain, we can return early
2835 tokens.splice( i, 1 );
2836 selector = seed.length && toSelector( tokens );
2838 push.apply( results, seed );
2848 // Compile and execute a filtering function if one is not provided
2849 // Provide `match` to avoid retokenization if we modified the selector above
2850 ( compiled || compile( selector, match ) )(
2855 rsibling.test( selector ) && testContext( context.parentNode ) || context
2860 // One-time assignments
2863 support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
2865 // Support: Chrome<14
2866 // Always assume duplicates if they aren't passed to the comparison function
2867 support.detectDuplicates = !!hasDuplicate;
2869 // Initialize against the default document
2872 // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
2873 // Detached nodes confoundingly follow *each other*
2874 support.sortDetached = assert(function( div1 ) {
2875 // Should return 1, but returns 4 (following)
2876 return div1.compareDocumentPosition( document.createElement("div") ) & 1;
2880 // Prevent attribute/property "interpolation"
2881 // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
2882 if ( !assert(function( div ) {
2883 div.innerHTML = "<a href='#'></a>";
2884 return div.firstChild.getAttribute("href") === "#" ;
2886 addHandle( "type|href|height|width", function( elem, name, isXML ) {
2888 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
2894 // Use defaultValue in place of getAttribute("value")
2895 if ( !support.attributes || !assert(function( div ) {
2896 div.innerHTML = "<input/>";
2897 div.firstChild.setAttribute( "value", "" );
2898 return div.firstChild.getAttribute( "value" ) === "";
2900 addHandle( "value", function( elem, name, isXML ) {
2901 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
2902 return elem.defaultValue;
2908 // Use getAttributeNode to fetch booleans when getAttribute lies
2909 if ( !assert(function( div ) {
2910 return div.getAttribute("disabled") == null;
2912 addHandle( booleans, function( elem, name, isXML ) {
2915 return elem[ name ] === true ? name.toLowerCase() :
2916 (val = elem.getAttributeNode( name )) && val.specified ?
2923 jQuery.find = Sizzle;
2924 jQuery.expr = Sizzle.selectors;
2925 jQuery.expr[":"] = jQuery.expr.pseudos;
2926 jQuery.unique = Sizzle.uniqueSort;
2927 jQuery.text = Sizzle.getText;
2928 jQuery.isXMLDoc = Sizzle.isXML;
2929 jQuery.contains = Sizzle.contains;
2933 // String to Object options format cache
2934 var optionsCache = {};
2936 // Convert String-formatted options into Object-formatted ones and store in cache
2937 function createOptions( options ) {
2938 var object = optionsCache[ options ] = {};
2939 jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
2940 object[ flag ] = true;
2946 * Create a callback list using the following parameters:
2948 * options: an optional list of space-separated options that will change how
2949 * the callback list behaves or a more traditional option object
2951 * By default a callback list will act like an event callback list and can be
2952 * "fired" multiple times.
2956 * once: will ensure the callback list can only be fired once (like a Deferred)
2958 * memory: will keep track of previous values and will call any callback added
2959 * after the list has been fired right away with the latest "memorized"
2960 * values (like a Deferred)
2962 * unique: will ensure a callback can only be added once (no duplicate in the list)
2964 * stopOnFalse: interrupt callings when a callback returns false
2967 jQuery.Callbacks = function( options ) {
2969 // Convert options from String-formatted to Object-formatted if needed
2970 // (we check in cache first)
2971 options = typeof options === "string" ?
2972 ( optionsCache[ options ] || createOptions( options ) ) :
2973 jQuery.extend( {}, options );
2975 var // Last fire value (for non-forgettable lists)
2977 // Flag to know if list was already fired
2979 // Flag to know if list is currently firing
2981 // First callback to fire (used internally by add and fireWith)
2983 // End of the loop when firing
2985 // Index of currently firing callback (modified by remove if needed)
2987 // Actual callback list
2989 // Stack of fire calls for repeatable lists
2990 stack = !options.once && [],
2992 fire = function( data ) {
2993 memory = options.memory && data;
2995 firingIndex = firingStart || 0;
2997 firingLength = list.length;
2999 for ( ; list && firingIndex < firingLength; firingIndex++ ) {
3000 if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
3001 memory = false; // To prevent further calls using add
3008 if ( stack.length ) {
3009 fire( stack.shift() );
3011 } else if ( memory ) {
3018 // Actual Callbacks object
3020 // Add a callback or a collection of callbacks to the list
3023 // First, we save the current length
3024 var start = list.length;
3025 (function add( args ) {
3026 jQuery.each( args, function( _, arg ) {
3027 var type = jQuery.type( arg );
3028 if ( type === "function" ) {
3029 if ( !options.unique || !self.has( arg ) ) {
3032 } else if ( arg && arg.length && type !== "string" ) {
3033 // Inspect recursively
3038 // Do we need to add the callbacks to the
3039 // current firing batch?
3041 firingLength = list.length;
3042 // With memory, if we're not firing then
3043 // we should call right away
3044 } else if ( memory ) {
3045 firingStart = start;
3051 // Remove a callback from the list
3052 remove: function() {
3054 jQuery.each( arguments, function( _, arg ) {
3056 while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
3057 list.splice( index, 1 );
3058 // Handle firing indexes
3060 if ( index <= firingLength ) {
3063 if ( index <= firingIndex ) {
3072 // Check if a given callback is in the list.
3073 // If no argument is given, return whether or not list has callbacks attached.
3074 has: function( fn ) {
3075 return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
3077 // Remove all callbacks from the list
3083 // Have the list do nothing anymore
3084 disable: function() {
3085 list = stack = memory = undefined;
3089 disabled: function() {
3092 // Lock the list in its current state
3101 locked: function() {
3104 // Call all callbacks with the given context and arguments
3105 fireWith: function( context, args ) {
3106 if ( list && ( !fired || stack ) ) {
3108 args = [ context, args.slice ? args.slice() : args ];
3117 // Call all the callbacks with the given arguments
3119 self.fireWith( this, arguments );
3122 // To know if the callbacks have already been called at least once
3132 Deferred: function( func ) {
3134 // action, add listener, listener list, final state
3135 [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
3136 [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
3137 [ "notify", "progress", jQuery.Callbacks("memory") ]
3144 always: function() {
3145 deferred.done( arguments ).fail( arguments );
3148 then: function( /* fnDone, fnFail, fnProgress */ ) {
3149 var fns = arguments;
3150 return jQuery.Deferred(function( newDefer ) {
3151 jQuery.each( tuples, function( i, tuple ) {
3152 var action = tuple[ 0 ],
3153 fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
3154 // deferred[ done | fail | progress ] for forwarding actions to newDefer
3155 deferred[ tuple[1] ](function() {
3156 var returned = fn && fn.apply( this, arguments );
3157 if ( returned && jQuery.isFunction( returned.promise ) ) {
3159 .done( newDefer.resolve )
3160 .fail( newDefer.reject )
3161 .progress( newDefer.notify );
3163 newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
3170 // Get a promise for this deferred
3171 // If obj is provided, the promise aspect is added to the object
3172 promise: function( obj ) {
3173 return obj != null ? jQuery.extend( obj, promise ) : promise;
3178 // Keep pipe for back-compat
3179 promise.pipe = promise.then;
3181 // Add list-specific methods
3182 jQuery.each( tuples, function( i, tuple ) {
3183 var list = tuple[ 2 ],
3184 stateString = tuple[ 3 ];
3186 // promise[ done | fail | progress ] = list.add
3187 promise[ tuple[1] ] = list.add;
3190 if ( stateString ) {
3191 list.add(function() {
3192 // state = [ resolved | rejected ]
3193 state = stateString;
3195 // [ reject_list | resolve_list ].disable; progress_list.lock
3196 }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
3199 // deferred[ resolve | reject | notify ]
3200 deferred[ tuple[0] ] = function() {
3201 deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
3204 deferred[ tuple[0] + "With" ] = list.fireWith;
3207 // Make the deferred a promise
3208 promise.promise( deferred );
3210 // Call given func if any
3212 func.call( deferred, deferred );
3220 when: function( subordinate /* , ..., subordinateN */ ) {
3222 resolveValues = core_slice.call( arguments ),
3223 length = resolveValues.length,
3225 // the count of uncompleted subordinates
3226 remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
3228 // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
3229 deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
3231 // Update function for both resolve and progress values
3232 updateFunc = function( i, contexts, values ) {
3233 return function( value ) {
3234 contexts[ i ] = this;
3235 values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
3236 if( values === progressValues ) {
3237 deferred.notifyWith( contexts, values );
3238 } else if ( !( --remaining ) ) {
3239 deferred.resolveWith( contexts, values );
3244 progressValues, progressContexts, resolveContexts;
3246 // add listeners to Deferred subordinates; treat others as resolved
3248 progressValues = new Array( length );
3249 progressContexts = new Array( length );
3250 resolveContexts = new Array( length );
3251 for ( ; i < length; i++ ) {
3252 if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
3253 resolveValues[ i ].promise()
3254 .done( updateFunc( i, resolveContexts, resolveValues ) )
3255 .fail( deferred.reject )
3256 .progress( updateFunc( i, progressContexts, progressValues ) );
3263 // if we're not waiting on anything, resolve the master
3265 deferred.resolveWith( resolveContexts, resolveValues );
3268 return deferred.promise();
3271 jQuery.support = (function( support ) {
3272 var input = document.createElement("input"),
3273 fragment = document.createDocumentFragment(),
3274 div = document.createElement("div"),
3275 select = document.createElement("select"),
3276 opt = select.appendChild( document.createElement("option") );
3278 // Finish early in limited environments
3279 if ( !input.type ) {
3283 input.type = "checkbox";
3285 // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
3286 // Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere)
3287 support.checkOn = input.value !== "";
3289 // Must access the parent to make an option select properly
3290 // Support: IE9, IE10
3291 support.optSelected = opt.selected;
3293 // Will be defined later
3294 support.reliableMarginRight = true;
3295 support.boxSizingReliable = true;
3296 support.pixelPosition = false;
3298 // Make sure checked status is properly cloned
3299 // Support: IE9, IE10
3300 input.checked = true;
3301 support.noCloneChecked = input.cloneNode( true ).checked;
3303 // Make sure that the options inside disabled selects aren't marked as disabled
3304 // (WebKit marks them as disabled)
3305 select.disabled = true;
3306 support.optDisabled = !opt.disabled;
3308 // Check if an input maintains its value after becoming a radio
3309 // Support: IE9, IE10
3310 input = document.createElement("input");
3312 input.type = "radio";
3313 support.radioValue = input.value === "t";
3315 // #11217 - WebKit loses check when the name is after the checked attribute
3316 input.setAttribute( "checked", "t" );
3317 input.setAttribute( "name", "t" );
3319 fragment.appendChild( input );
3321 // Support: Safari 5.1, Android 4.x, Android 2.3
3322 // old WebKit doesn't clone checked state correctly in fragments
3323 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
3325 // Support: Firefox, Chrome, Safari
3326 // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
3327 support.focusinBubbles = "onfocusin" in window;
3329 div.style.backgroundClip = "content-box";
3330 div.cloneNode( true ).style.backgroundClip = "";
3331 support.clearCloneStyle = div.style.backgroundClip === "content-box";
3333 // Run tests that need a body at doc ready
3335 var container, marginDiv,
3336 // Support: Firefox, Android 2.3 (Prefixed box-sizing versions).
3337 divReset = "padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",
3338 body = document.getElementsByTagName("body")[ 0 ];
3341 // Return for frameset docs that don't have a body
3345 container = document.createElement("div");
3346 container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
3348 // Check box-sizing and margin behavior.
3349 body.appendChild( container ).appendChild( div );
3351 // Support: Firefox, Android 2.3 (Prefixed box-sizing versions).
3352 div.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%";
3354 // Workaround failing boxSizing test due to offsetWidth returning wrong value
3355 // with some non-1 values of body zoom, ticket #13543
3356 jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() {
3357 support.boxSizing = div.offsetWidth === 4;
3360 // Use window.getComputedStyle because jsdom on node.js will break without it.
3361 if ( window.getComputedStyle ) {
3362 support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
3363 support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
3365 // Support: Android 2.3
3366 // Check if div with explicit width and no margin-right incorrectly
3367 // gets computed margin-right based on width of container. (#3333)
3368 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
3369 marginDiv = div.appendChild( document.createElement("div") );
3370 marginDiv.style.cssText = div.style.cssText = divReset;
3371 marginDiv.style.marginRight = marginDiv.style.width = "0";
3372 div.style.width = "1px";
3374 support.reliableMarginRight =
3375 !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
3378 body.removeChild( container );
3385 Implementation Summary
3387 1. Enforce API surface and semantic compatibility with 1.9.x branch
3388 2. Improve the module's maintainability by reducing the storage
3389 paths to a single mechanism.
3390 3. Use the same single mechanism to support "private" and "user" data.
3391 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
3392 5. Avoid exposing implementation details on user objects (eg. expando properties)
3393 6. Provide a clear path for implementation upgrade to WeakMap in 2014
3395 var data_user, data_priv,
3396 rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
3397 rmultiDash = /([A-Z])/g;
3400 // Support: Android < 4,
3401 // Old WebKit does not have Object.preventExtensions/freeze method,
3402 // return new empty object instead with no [[set]] accessor
3403 Object.defineProperty( this.cache = {}, 0, {
3409 this.expando = jQuery.expando + Math.random();
3414 Data.accepts = function( owner ) {
3417 // - Node.ELEMENT_NODE
3418 // - Node.DOCUMENT_NODE
3421 return owner.nodeType ?
3422 owner.nodeType === 1 || owner.nodeType === 9 : true;
3426 key: function( owner ) {
3427 // We can accept data for non-element nodes in modern browsers,
3428 // but we should not, see #8335.
3429 // Always return the key for a frozen object.
3430 if ( !Data.accepts( owner ) ) {
3434 var descriptor = {},
3435 // Check if the owner object already has a cache key
3436 unlock = owner[ this.expando ];
3438 // If not, create one
3440 unlock = Data.uid++;
3442 // Secure it in a non-enumerable, non-writable property
3444 descriptor[ this.expando ] = { value: unlock };
3445 Object.defineProperties( owner, descriptor );
3447 // Support: Android < 4
3448 // Fallback to a less secure definition
3450 descriptor[ this.expando ] = unlock;
3451 jQuery.extend( owner, descriptor );
3455 // Ensure the cache object
3456 if ( !this.cache[ unlock ] ) {
3457 this.cache[ unlock ] = {};
3462 set: function( owner, data, value ) {
3464 // There may be an unlock assigned to this node,
3465 // if there is no entry for this "owner", create one inline
3466 // and set the unlock as though an owner entry had always existed
3467 unlock = this.key( owner ),
3468 cache = this.cache[ unlock ];
3470 // Handle: [ owner, key, value ] args
3471 if ( typeof data === "string" ) {
3472 cache[ data ] = value;
3474 // Handle: [ owner, { properties } ] args
3476 // Fresh assignments by object are shallow copied
3477 if ( jQuery.isEmptyObject( cache ) ) {
3478 jQuery.extend( this.cache[ unlock ], data );
3479 // Otherwise, copy the properties one-by-one to the cache object
3481 for ( prop in data ) {
3482 cache[ prop ] = data[ prop ];
3488 get: function( owner, key ) {
3489 // Either a valid cache is found, or will be created.
3490 // New caches will be created and the unlock returned,
3491 // allowing direct access to the newly created
3492 // empty data object. A valid owner object must be provided.
3493 var cache = this.cache[ this.key( owner ) ];
3495 return key === undefined ?
3496 cache : cache[ key ];
3498 access: function( owner, key, value ) {
3500 // In cases where either:
3502 // 1. No key was specified
3503 // 2. A string key was specified, but no value provided
3505 // Take the "read" path and allow the get method to determine
3506 // which value to return, respectively either:
3508 // 1. The entire cache object
3509 // 2. The data stored at the key
3511 if ( key === undefined ||
3512 ((key && typeof key === "string") && value === undefined) ) {
3514 stored = this.get( owner, key );
3516 return stored !== undefined ?
3517 stored : this.get( owner, jQuery.camelCase(key) );
3520 // [*]When the key is not a string, or both a key and value
3521 // are specified, set or extend (existing objects) with either:
3523 // 1. An object of properties
3524 // 2. A key and value
3526 this.set( owner, key, value );
3528 // Since the "set" path can have two possible entry points
3529 // return the expected data based on which path was taken[*]
3530 return value !== undefined ? value : key;
3532 remove: function( owner, key ) {
3534 unlock = this.key( owner ),
3535 cache = this.cache[ unlock ];
3537 if ( key === undefined ) {
3538 this.cache[ unlock ] = {};
3541 // Support array or space separated string of keys
3542 if ( jQuery.isArray( key ) ) {
3543 // If "name" is an array of keys...
3544 // When data is initially created, via ("key", "val") signature,
3545 // keys will be converted to camelCase.
3546 // Since there is no way to tell _how_ a key was added, remove
3547 // both plain key and camelCase key. #12786
3548 // This will only penalize the array argument path.
3549 name = key.concat( key.map( jQuery.camelCase ) );
3551 camel = jQuery.camelCase( key );
3552 // Try the string as a key before any manipulation
3553 if ( key in cache ) {
3554 name = [ key, camel ];
3556 // If a key with the spaces exists, use it.
3557 // Otherwise, create an array by matching non-whitespace
3559 name = name in cache ?
3560 [ name ] : ( name.match( core_rnotwhite ) || [] );
3566 delete cache[ name[ i ] ];
3570 hasData: function( owner ) {
3571 return !jQuery.isEmptyObject(
3572 this.cache[ owner[ this.expando ] ] || {}
3575 discard: function( owner ) {
3576 if ( owner[ this.expando ] ) {
3577 delete this.cache[ owner[ this.expando ] ];
3582 // These may be used throughout the jQuery core codebase
3583 data_user = new Data();
3584 data_priv = new Data();
3588 acceptData: Data.accepts,
3590 hasData: function( elem ) {
3591 return data_user.hasData( elem ) || data_priv.hasData( elem );
3594 data: function( elem, name, data ) {
3595 return data_user.access( elem, name, data );
3598 removeData: function( elem, name ) {
3599 data_user.remove( elem, name );
3602 // TODO: Now that all calls to _data and _removeData have been replaced
3603 // with direct calls to data_priv methods, these can be deprecated.
3604 _data: function( elem, name, data ) {
3605 return data_priv.access( elem, name, data );
3608 _removeData: function( elem, name ) {
3609 data_priv.remove( elem, name );
3614 data: function( key, value ) {
3621 if ( key === undefined ) {
3622 if ( this.length ) {
3623 data = data_user.get( elem );
3625 if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
3626 attrs = elem.attributes;
3627 for ( ; i < attrs.length; i++ ) {
3628 name = attrs[ i ].name;
3630 if ( name.indexOf( "data-" ) === 0 ) {
3631 name = jQuery.camelCase( name.slice(5) );
3632 dataAttr( elem, name, data[ name ] );
3635 data_priv.set( elem, "hasDataAttrs", true );
3642 // Sets multiple values
3643 if ( typeof key === "object" ) {
3644 return this.each(function() {
3645 data_user.set( this, key );
3649 return jQuery.access( this, function( value ) {
3651 camelKey = jQuery.camelCase( key );
3653 // The calling jQuery object (element matches) is not empty
3654 // (and therefore has an element appears at this[ 0 ]) and the
3655 // `value` parameter was not undefined. An empty jQuery object
3656 // will result in `undefined` for elem = this[ 0 ] which will
3657 // throw an exception if an attempt to read a data cache is made.
3658 if ( elem && value === undefined ) {
3659 // Attempt to get data from the cache
3660 // with the key as-is
3661 data = data_user.get( elem, key );
3662 if ( data !== undefined ) {
3666 // Attempt to get data from the cache
3667 // with the key camelized
3668 data = data_user.get( elem, camelKey );
3669 if ( data !== undefined ) {
3673 // Attempt to "discover" the data in
3674 // HTML5 custom data-* attrs
3675 data = dataAttr( elem, camelKey, undefined );
3676 if ( data !== undefined ) {
3680 // We tried really hard, but the data doesn't exist.
3685 this.each(function() {
3686 // First, attempt to store a copy or reference of any
3687 // data that might've been store with a camelCased key.
3688 var data = data_user.get( this, camelKey );
3690 // For HTML5 data-* attribute interop, we have to
3691 // store property names with dashes in a camelCase form.
3692 // This might not apply to all properties...*
3693 data_user.set( this, camelKey, value );
3695 // *... In the case of properties that might _actually_
3696 // have dashes, we need to also store a copy of that
3697 // unchanged property.
3698 if ( key.indexOf("-") !== -1 && data !== undefined ) {
3699 data_user.set( this, key, value );
3702 }, null, value, arguments.length > 1, null, true );
3705 removeData: function( key ) {
3706 return this.each(function() {
3707 data_user.remove( this, key );
3712 function dataAttr( elem, key, data ) {
3715 // If nothing was found internally, try to fetch any
3716 // data from the HTML5 data-* attribute
3717 if ( data === undefined && elem.nodeType === 1 ) {
3718 name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
3719 data = elem.getAttribute( name );
3721 if ( typeof data === "string" ) {
3723 data = data === "true" ? true :
3724 data === "false" ? false :
3725 data === "null" ? null :
3726 // Only convert to a number if it doesn't change the string
3727 +data + "" === data ? +data :
3728 rbrace.test( data ) ? JSON.parse( data ) :
3732 // Make sure we set the data so it isn't changed later
3733 data_user.set( elem, key, data );
3741 queue: function( elem, type, data ) {
3745 type = ( type || "fx" ) + "queue";
3746 queue = data_priv.get( elem, type );
3748 // Speed up dequeue by getting out quickly if this is just a lookup
3750 if ( !queue || jQuery.isArray( data ) ) {
3751 queue = data_priv.access( elem, type, jQuery.makeArray(data) );
3760 dequeue: function( elem, type ) {
3761 type = type || "fx";
3763 var queue = jQuery.queue( elem, type ),
3764 startLength = queue.length,
3766 hooks = jQuery._queueHooks( elem, type ),
3768 jQuery.dequeue( elem, type );
3771 // If the fx queue is dequeued, always remove the progress sentinel
3772 if ( fn === "inprogress" ) {
3779 // Add a progress sentinel to prevent the fx queue from being
3780 // automatically dequeued
3781 if ( type === "fx" ) {
3782 queue.unshift( "inprogress" );
3785 // clear up the last queue stop function
3787 fn.call( elem, next, hooks );
3790 if ( !startLength && hooks ) {
3795 // not intended for public consumption - generates a queueHooks object, or returns the current one
3796 _queueHooks: function( elem, type ) {
3797 var key = type + "queueHooks";
3798 return data_priv.get( elem, key ) || data_priv.access( elem, key, {
3799 empty: jQuery.Callbacks("once memory").add(function() {
3800 data_priv.remove( elem, [ type + "queue", key ] );
3807 queue: function( type, data ) {
3810 if ( typeof type !== "string" ) {
3816 if ( arguments.length < setter ) {
3817 return jQuery.queue( this[0], type );
3820 return data === undefined ?
3822 this.each(function() {
3823 var queue = jQuery.queue( this, type, data );
3825 // ensure a hooks for this queue
3826 jQuery._queueHooks( this, type );
3828 if ( type === "fx" && queue[0] !== "inprogress" ) {
3829 jQuery.dequeue( this, type );
3833 dequeue: function( type ) {
3834 return this.each(function() {
3835 jQuery.dequeue( this, type );
3838 // Based off of the plugin by Clint Helfers, with permission.
3839 // http://blindsignals.com/index.php/2009/07/jquery-delay/
3840 delay: function( time, type ) {
3841 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
3842 type = type || "fx";
3844 return this.queue( type, function( next, hooks ) {
3845 var timeout = setTimeout( next, time );
3846 hooks.stop = function() {
3847 clearTimeout( timeout );
3851 clearQueue: function( type ) {
3852 return this.queue( type || "fx", [] );
3854 // Get a promise resolved when queues of a certain type
3855 // are emptied (fx is the type by default)
3856 promise: function( type, obj ) {
3859 defer = jQuery.Deferred(),
3862 resolve = function() {
3863 if ( !( --count ) ) {
3864 defer.resolveWith( elements, [ elements ] );
3868 if ( typeof type !== "string" ) {
3872 type = type || "fx";
3875 tmp = data_priv.get( elements[ i ], type + "queueHooks" );
3876 if ( tmp && tmp.empty ) {
3878 tmp.empty.add( resolve );
3882 return defer.promise( obj );
3885 var nodeHook, boolHook,
3886 rclass = /[\t\r\n\f]/g,
3888 rfocusable = /^(?:input|select|textarea|button)$/i;
3891 attr: function( name, value ) {
3892 return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
3895 removeAttr: function( name ) {
3896 return this.each(function() {
3897 jQuery.removeAttr( this, name );
3901 prop: function( name, value ) {
3902 return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
3905 removeProp: function( name ) {
3906 return this.each(function() {
3907 delete this[ jQuery.propFix[ name ] || name ];
3911 addClass: function( value ) {
3912 var classes, elem, cur, clazz, j,
3915 proceed = typeof value === "string" && value;
3917 if ( jQuery.isFunction( value ) ) {
3918 return this.each(function( j ) {
3919 jQuery( this ).addClass( value.call( this, j, this.className ) );
3924 // The disjunction here is for better compressibility (see removeClass)
3925 classes = ( value || "" ).match( core_rnotwhite ) || [];
3927 for ( ; i < len; i++ ) {
3929 cur = elem.nodeType === 1 && ( elem.className ?
3930 ( " " + elem.className + " " ).replace( rclass, " " ) :
3936 while ( (clazz = classes[j++]) ) {
3937 if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
3941 elem.className = jQuery.trim( cur );
3950 removeClass: function( value ) {
3951 var classes, elem, cur, clazz, j,
3954 proceed = arguments.length === 0 || typeof value === "string" && value;
3956 if ( jQuery.isFunction( value ) ) {
3957 return this.each(function( j ) {
3958 jQuery( this ).removeClass( value.call( this, j, this.className ) );
3962 classes = ( value || "" ).match( core_rnotwhite ) || [];
3964 for ( ; i < len; i++ ) {
3966 // This expression is here for better compressibility (see addClass)
3967 cur = elem.nodeType === 1 && ( elem.className ?
3968 ( " " + elem.className + " " ).replace( rclass, " " ) :
3974 while ( (clazz = classes[j++]) ) {
3975 // Remove *all* instances
3976 while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
3977 cur = cur.replace( " " + clazz + " ", " " );
3980 elem.className = value ? jQuery.trim( cur ) : "";
3988 toggleClass: function( value, stateVal ) {
3989 var type = typeof value;
3991 if ( typeof stateVal === "boolean" && type === "string" ) {
3992 return stateVal ? this.addClass( value ) : this.removeClass( value );
3995 if ( jQuery.isFunction( value ) ) {
3996 return this.each(function( i ) {
3997 jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
4001 return this.each(function() {
4002 if ( type === "string" ) {
4003 // toggle individual class names
4006 self = jQuery( this ),
4007 classNames = value.match( core_rnotwhite ) || [];
4009 while ( (className = classNames[ i++ ]) ) {
4010 // check each className given, space separated list
4011 if ( self.hasClass( className ) ) {
4012 self.removeClass( className );
4014 self.addClass( className );
4018 // Toggle whole class name
4019 } else if ( type === core_strundefined || type === "boolean" ) {
4020 if ( this.className ) {
4021 // store className if set
4022 data_priv.set( this, "__className__", this.className );
4025 // If the element has a class name or if we're passed "false",
4026 // then remove the whole classname (if there was one, the above saved it).
4027 // Otherwise bring back whatever was previously saved (if anything),
4028 // falling back to the empty string if nothing was stored.
4029 this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
4034 hasClass: function( selector ) {
4035 var className = " " + selector + " ",
4038 for ( ; i < l; i++ ) {
4039 if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
4047 val: function( value ) {
4048 var hooks, ret, isFunction,
4051 if ( !arguments.length ) {
4053 hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
4055 if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
4061 return typeof ret === "string" ?
4062 // handle most common string cases
4063 ret.replace(rreturn, "") :
4064 // handle cases where value is null/undef or number
4065 ret == null ? "" : ret;
4071 isFunction = jQuery.isFunction( value );
4073 return this.each(function( i ) {
4076 if ( this.nodeType !== 1 ) {
4081 val = value.call( this, i, jQuery( this ).val() );
4086 // Treat null/undefined as ""; convert numbers to string
4087 if ( val == null ) {
4089 } else if ( typeof val === "number" ) {
4091 } else if ( jQuery.isArray( val ) ) {
4092 val = jQuery.map(val, function ( value ) {
4093 return value == null ? "" : value + "";
4097 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
4099 // If set returns undefined, fall back to normal setting
4100 if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
4110 get: function( elem ) {
4111 // attributes.value is undefined in Blackberry 4.7 but
4112 // uses .value. See #6932
4113 var val = elem.attributes.value;
4114 return !val || val.specified ? elem.value : elem.text;
4118 get: function( elem ) {
4120 options = elem.options,
4121 index = elem.selectedIndex,
4122 one = elem.type === "select-one" || index < 0,
4123 values = one ? null : [],
4124 max = one ? index + 1 : options.length,
4129 // Loop through all the selected options
4130 for ( ; i < max; i++ ) {
4131 option = options[ i ];
4133 // IE6-9 doesn't update selected after form reset (#2551)
4134 if ( ( option.selected || i === index ) &&
4135 // Don't return options that are disabled or in a disabled optgroup
4136 ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
4137 ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
4139 // Get the specific value for the option
4140 value = jQuery( option ).val();
4142 // We don't need an array for one selects
4147 // Multi-Selects return an array
4148 values.push( value );
4155 set: function( elem, value ) {
4156 var optionSet, option,
4157 options = elem.options,
4158 values = jQuery.makeArray( value ),
4162 option = options[ i ];
4163 if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) {
4168 // force browsers to behave consistently when non-matching value is set
4170 elem.selectedIndex = -1;
4177 attr: function( elem, name, value ) {
4179 nType = elem.nodeType;
4181 // don't get/set attributes on text, comment and attribute nodes
4182 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
4186 // Fallback to prop when attributes are not supported
4187 if ( typeof elem.getAttribute === core_strundefined ) {
4188 return jQuery.prop( elem, name, value );
4191 // All attributes are lowercase
4192 // Grab necessary hook if one is defined
4193 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
4194 name = name.toLowerCase();
4195 hooks = jQuery.attrHooks[ name ] ||
4196 ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
4199 if ( value !== undefined ) {
4201 if ( value === null ) {
4202 jQuery.removeAttr( elem, name );
4204 } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
4208 elem.setAttribute( name, value + "" );
4212 } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
4216 ret = jQuery.find.attr( elem, name );
4218 // Non-existent attributes return null, we normalize to undefined
4219 return ret == null ?
4225 removeAttr: function( elem, value ) {
4228 attrNames = value && value.match( core_rnotwhite );
4230 if ( attrNames && elem.nodeType === 1 ) {
4231 while ( (name = attrNames[i++]) ) {
4232 propName = jQuery.propFix[ name ] || name;
4234 // Boolean attributes get special treatment (#10870)
4235 if ( jQuery.expr.match.bool.test( name ) ) {
4236 // Set corresponding property to false
4237 elem[ propName ] = false;
4240 elem.removeAttribute( name );
4247 set: function( elem, value ) {
4248 if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
4249 // Setting the type on a radio button after the value resets the value in IE6-9
4250 // Reset value to default in case type is set after value during creation
4251 var val = elem.value;
4252 elem.setAttribute( "type", value );
4264 "class": "className"
4267 prop: function( elem, name, value ) {
4268 var ret, hooks, notxml,
4269 nType = elem.nodeType;
4271 // don't get/set properties on text, comment and attribute nodes
4272 if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
4276 notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
4279 // Fix name and attach hooks
4280 name = jQuery.propFix[ name ] || name;
4281 hooks = jQuery.propHooks[ name ];
4284 if ( value !== undefined ) {
4285 return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
4287 ( elem[ name ] = value );
4290 return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
4298 get: function( elem ) {
4299 return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ?
4307 // Hooks for boolean attributes
4309 set: function( elem, value, name ) {
4310 if ( value === false ) {
4311 // Remove boolean attributes when set to false
4312 jQuery.removeAttr( elem, name );
4314 elem.setAttribute( name, name );
4319 jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
4320 var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr;
4322 jQuery.expr.attrHandle[ name ] = function( elem, name, isXML ) {
4323 var fn = jQuery.expr.attrHandle[ name ],
4326 /* jshint eqeqeq: false */
4327 // Temporarily disable this handler to check existence
4328 (jQuery.expr.attrHandle[ name ] = undefined) !=
4329 getter( elem, name, isXML ) ?
4331 name.toLowerCase() :
4335 jQuery.expr.attrHandle[ name ] = fn;
4342 // Selectedness for an option in an optgroup can be inaccurate
4343 if ( !jQuery.support.optSelected ) {
4344 jQuery.propHooks.selected = {
4345 get: function( elem ) {
4346 var parent = elem.parentNode;
4347 if ( parent && parent.parentNode ) {
4348 parent.parentNode.selectedIndex;
4367 jQuery.propFix[ this.toLowerCase() ] = this;
4370 // Radios and checkboxes getter/setter
4371 jQuery.each([ "radio", "checkbox" ], function() {
4372 jQuery.valHooks[ this ] = {
4373 set: function( elem, value ) {
4374 if ( jQuery.isArray( value ) ) {
4375 return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
4379 if ( !jQuery.support.checkOn ) {
4380 jQuery.valHooks[ this ].get = function( elem ) {
4382 // "" is returned instead of "on" if a value isn't specified
4383 return elem.getAttribute("value") === null ? "on" : elem.value;
4387 var rkeyEvent = /^key/,
4388 rmouseEvent = /^(?:mouse|contextmenu)|click/,
4389 rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
4390 rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
4392 function returnTrue() {
4396 function returnFalse() {
4400 function safeActiveElement() {
4402 return document.activeElement;
4407 * Helper functions for managing events -- not part of the public interface.
4408 * Props to Dean Edwards' addEvent library for many of the ideas.
4414 add: function( elem, types, handler, data, selector ) {
4416 var handleObjIn, eventHandle, tmp,
4417 events, t, handleObj,
4418 special, handlers, type, namespaces, origType,
4419 elemData = data_priv.get( elem );
4421 // Don't attach events to noData or text/comment nodes (but allow plain objects)
4426 // Caller can pass in an object of custom data in lieu of the handler
4427 if ( handler.handler ) {
4428 handleObjIn = handler;
4429 handler = handleObjIn.handler;
4430 selector = handleObjIn.selector;
4433 // Make sure that the handler has a unique ID, used to find/remove it later
4434 if ( !handler.guid ) {
4435 handler.guid = jQuery.guid++;
4438 // Init the element's event structure and main handler, if this is the first
4439 if ( !(events = elemData.events) ) {
4440 events = elemData.events = {};
4442 if ( !(eventHandle = elemData.handle) ) {
4443 eventHandle = elemData.handle = function( e ) {
4444 // Discard the second event of a jQuery.event.trigger() and
4445 // when an event is called after a page has unloaded
4446 return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
4447 jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
4450 // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
4451 eventHandle.elem = elem;
4454 // Handle multiple events separated by a space
4455 types = ( types || "" ).match( core_rnotwhite ) || [""];
4458 tmp = rtypenamespace.exec( types[t] ) || [];
4459 type = origType = tmp[1];
4460 namespaces = ( tmp[2] || "" ).split( "." ).sort();
4462 // There *must* be a type, no attaching namespace-only handlers
4467 // If event changes its type, use the special event handlers for the changed type
4468 special = jQuery.event.special[ type ] || {};
4470 // If selector defined, determine special event api type, otherwise given type
4471 type = ( selector ? special.delegateType : special.bindType ) || type;
4473 // Update special based on newly reset type
4474 special = jQuery.event.special[ type ] || {};
4476 // handleObj is passed to all event handlers
4477 handleObj = jQuery.extend({
4484 needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
4485 namespace: namespaces.join(".")
4488 // Init the event handler queue if we're the first
4489 if ( !(handlers = events[ type ]) ) {
4490 handlers = events[ type ] = [];
4491 handlers.delegateCount = 0;
4493 // Only use addEventListener if the special events handler returns false
4494 if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
4495 if ( elem.addEventListener ) {
4496 elem.addEventListener( type, eventHandle, false );
4501 if ( special.add ) {
4502 special.add.call( elem, handleObj );
4504 if ( !handleObj.handler.guid ) {
4505 handleObj.handler.guid = handler.guid;
4509 // Add to the element's handler list, delegates in front
4511 handlers.splice( handlers.delegateCount++, 0, handleObj );
4513 handlers.push( handleObj );
4516 // Keep track of which events have ever been used, for event optimization
4517 jQuery.event.global[ type ] = true;
4520 // Nullify elem to prevent memory leaks in IE
4524 // Detach an event or set of events from an element
4525 remove: function( elem, types, handler, selector, mappedTypes ) {
4527 var j, origCount, tmp,
4528 events, t, handleObj,
4529 special, handlers, type, namespaces, origType,
4530 elemData = data_priv.hasData( elem ) && data_priv.get( elem );
4532 if ( !elemData || !(events = elemData.events) ) {
4536 // Once for each type.namespace in types; type may be omitted
4537 types = ( types || "" ).match( core_rnotwhite ) || [""];
4540 tmp = rtypenamespace.exec( types[t] ) || [];
4541 type = origType = tmp[1];
4542 namespaces = ( tmp[2] || "" ).split( "." ).sort();
4544 // Unbind all events (on this namespace, if provided) for the element
4546 for ( type in events ) {
4547 jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
4552 special = jQuery.event.special[ type ] || {};
4553 type = ( selector ? special.delegateType : special.bindType ) || type;
4554 handlers = events[ type ] || [];
4555 tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
4557 // Remove matching events
4558 origCount = j = handlers.length;
4560 handleObj = handlers[ j ];
4562 if ( ( mappedTypes || origType === handleObj.origType ) &&
4563 ( !handler || handler.guid === handleObj.guid ) &&
4564 ( !tmp || tmp.test( handleObj.namespace ) ) &&
4565 ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
4566 handlers.splice( j, 1 );
4568 if ( handleObj.selector ) {
4569 handlers.delegateCount--;
4571 if ( special.remove ) {
4572 special.remove.call( elem, handleObj );
4577 // Remove generic event handler if we removed something and no more handlers exist
4578 // (avoids potential for endless recursion during removal of special event handlers)
4579 if ( origCount && !handlers.length ) {
4580 if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
4581 jQuery.removeEvent( elem, type, elemData.handle );
4584 delete events[ type ];
4588 // Remove the expando if it's no longer used
4589 if ( jQuery.isEmptyObject( events ) ) {
4590 delete elemData.handle;
4591 data_priv.remove( elem, "events" );
4595 trigger: function( event, data, elem, onlyHandlers ) {
4597 var i, cur, tmp, bubbleType, ontype, handle, special,
4598 eventPath = [ elem || document ],
4599 type = core_hasOwn.call( event, "type" ) ? event.type : event,
4600 namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
4602 cur = tmp = elem = elem || document;
4604 // Don't do events on text and comment nodes
4605 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
4609 // focus/blur morphs to focusin/out; ensure we're not firing them right now
4610 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
4614 if ( type.indexOf(".") >= 0 ) {
4615 // Namespaced trigger; create a regexp to match event type in handle()
4616 namespaces = type.split(".");
4617 type = namespaces.shift();
4620 ontype = type.indexOf(":") < 0 && "on" + type;
4622 // Caller can pass in a jQuery.Event object, Object, or just an event type string
4623 event = event[ jQuery.expando ] ?
4625 new jQuery.Event( type, typeof event === "object" && event );
4627 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
4628 event.isTrigger = onlyHandlers ? 2 : 3;
4629 event.namespace = namespaces.join(".");
4630 event.namespace_re = event.namespace ?
4631 new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
4634 // Clean up the event in case it is being reused
4635 event.result = undefined;
4636 if ( !event.target ) {
4637 event.target = elem;
4640 // Clone any incoming data and prepend the event, creating the handler arg list
4641 data = data == null ?
4643 jQuery.makeArray( data, [ event ] );
4645 // Allow special events to draw outside the lines
4646 special = jQuery.event.special[ type ] || {};
4647 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
4651 // Determine event propagation path in advance, per W3C events spec (#9951)
4652 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
4653 if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
4655 bubbleType = special.delegateType || type;
4656 if ( !rfocusMorph.test( bubbleType + type ) ) {
4657 cur = cur.parentNode;
4659 for ( ; cur; cur = cur.parentNode ) {
4660 eventPath.push( cur );
4664 // Only add window if we got to document (e.g., not plain obj or detached DOM)
4665 if ( tmp === (elem.ownerDocument || document) ) {
4666 eventPath.push( tmp.defaultView || tmp.parentWindow || window );
4670 // Fire handlers on the event path
4672 while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
4674 event.type = i > 1 ?
4676 special.bindType || type;
4679 handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
4681 handle.apply( cur, data );
4685 handle = ontype && cur[ ontype ];
4686 if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
4687 event.preventDefault();
4692 // If nobody prevented the default action, do it now
4693 if ( !onlyHandlers && !event.isDefaultPrevented() ) {
4695 if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
4696 jQuery.acceptData( elem ) ) {
4698 // Call a native DOM method on the target with the same name name as the event.
4699 // Don't do default actions on window, that's where global variables be (#6170)
4700 if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
4702 // Don't re-trigger an onFOO event when we call its FOO() method
4703 tmp = elem[ ontype ];
4706 elem[ ontype ] = null;
4709 // Prevent re-triggering of the same event, since we already bubbled it above
4710 jQuery.event.triggered = type;
4712 jQuery.event.triggered = undefined;
4715 elem[ ontype ] = tmp;
4721 return event.result;
4724 dispatch: function( event ) {
4726 // Make a writable jQuery.Event from the native event object
4727 event = jQuery.event.fix( event );
4729 var i, j, ret, matched, handleObj,
4731 args = core_slice.call( arguments ),
4732 handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
4733 special = jQuery.event.special[ event.type ] || {};
4735 // Use the fix-ed jQuery.Event rather than the (read-only) native event
4737 event.delegateTarget = this;
4739 // Call the preDispatch hook for the mapped type, and let it bail if desired
4740 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
4744 // Determine handlers
4745 handlerQueue = jQuery.event.handlers.call( this, event, handlers );
4747 // Run delegates first; they may want to stop propagation beneath us
4749 while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
4750 event.currentTarget = matched.elem;
4753 while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
4755 // Triggered event must either 1) have no namespace, or
4756 // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
4757 if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
4759 event.handleObj = handleObj;
4760 event.data = handleObj.data;
4762 ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
4763 .apply( matched.elem, args );
4765 if ( ret !== undefined ) {
4766 if ( (event.result = ret) === false ) {
4767 event.preventDefault();
4768 event.stopPropagation();
4775 // Call the postDispatch hook for the mapped type
4776 if ( special.postDispatch ) {
4777 special.postDispatch.call( this, event );
4780 return event.result;
4783 handlers: function( event, handlers ) {
4784 var i, matches, sel, handleObj,
4786 delegateCount = handlers.delegateCount,
4789 // Find delegate handlers
4790 // Black-hole SVG <use> instance trees (#13180)
4791 // Avoid non-left-click bubbling in Firefox (#3861)
4792 if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
4794 for ( ; cur !== this; cur = cur.parentNode || this ) {
4796 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
4797 if ( cur.disabled !== true || event.type !== "click" ) {
4799 for ( i = 0; i < delegateCount; i++ ) {
4800 handleObj = handlers[ i ];
4802 // Don't conflict with Object.prototype properties (#13203)
4803 sel = handleObj.selector + " ";
4805 if ( matches[ sel ] === undefined ) {
4806 matches[ sel ] = handleObj.needsContext ?
4807 jQuery( sel, this ).index( cur ) >= 0 :
4808 jQuery.find( sel, this, null, [ cur ] ).length;
4810 if ( matches[ sel ] ) {
4811 matches.push( handleObj );
4814 if ( matches.length ) {
4815 handlerQueue.push({ elem: cur, handlers: matches });
4821 // Add the remaining (directly-bound) handlers
4822 if ( delegateCount < handlers.length ) {
4823 handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
4826 return handlerQueue;
4829 // Includes some event props shared by KeyEvent and MouseEvent
4830 props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
4835 props: "char charCode key keyCode".split(" "),
4836 filter: function( event, original ) {
4838 // Add which for key events
4839 if ( event.which == null ) {
4840 event.which = original.charCode != null ? original.charCode : original.keyCode;
4848 props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
4849 filter: function( event, original ) {
4850 var eventDoc, doc, body,
4851 button = original.button;
4853 // Calculate pageX/Y if missing and clientX/Y available
4854 if ( event.pageX == null && original.clientX != null ) {
4855 eventDoc = event.target.ownerDocument || document;
4856 doc = eventDoc.documentElement;
4857 body = eventDoc.body;
4859 event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
4860 event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
4863 // Add which for click: 1 === left; 2 === middle; 3 === right
4864 // Note: button is not normalized, so don't use it
4865 if ( !event.which && button !== undefined ) {
4866 event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
4873 fix: function( event ) {
4874 if ( event[ jQuery.expando ] ) {
4878 // Create a writable copy of the event object and normalize some properties
4881 originalEvent = event,
4882 fixHook = this.fixHooks[ type ];
4885 this.fixHooks[ type ] = fixHook =
4886 rmouseEvent.test( type ) ? this.mouseHooks :
4887 rkeyEvent.test( type ) ? this.keyHooks :
4890 copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
4892 event = new jQuery.Event( originalEvent );
4897 event[ prop ] = originalEvent[ prop ];
4900 // Support: Cordova 2.5 (WebKit) (#13255)
4901 // All events should have a target; Cordova deviceready doesn't
4902 if ( !event.target ) {
4903 event.target = document;
4906 // Support: Safari 6.0+, Chrome < 28
4907 // Target should not be a text node (#504, #13143)
4908 if ( event.target.nodeType === 3 ) {
4909 event.target = event.target.parentNode;
4912 return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
4917 // Prevent triggered image.load events from bubbling to window.load
4921 // Fire native event if possible so blur/focus sequence is correct
4922 trigger: function() {
4923 if ( this !== safeActiveElement() && this.focus ) {
4928 delegateType: "focusin"
4931 trigger: function() {
4932 if ( this === safeActiveElement() && this.blur ) {
4937 delegateType: "focusout"
4940 // For checkbox, fire native event so checked state will be right
4941 trigger: function() {
4942 if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
4948 // For cross-browser consistency, don't fire native .click() on links
4949 _default: function( event ) {
4950 return jQuery.nodeName( event.target, "a" );
4955 postDispatch: function( event ) {
4957 // Support: Firefox 20+
4958 // Firefox doesn't alert if the returnValue field is not set.
4959 if ( event.result !== undefined ) {
4960 event.originalEvent.returnValue = event.result;
4966 simulate: function( type, elem, event, bubble ) {
4967 // Piggyback on a donor event to simulate a different one.
4968 // Fake originalEvent to avoid donor's stopPropagation, but if the
4969 // simulated event prevents default then we do the same on the donor.
4970 var e = jQuery.extend(
4980 jQuery.event.trigger( e, null, elem );
4982 jQuery.event.dispatch.call( elem, e );
4984 if ( e.isDefaultPrevented() ) {
4985 event.preventDefault();
4990 jQuery.removeEvent = function( elem, type, handle ) {
4991 if ( elem.removeEventListener ) {
4992 elem.removeEventListener( type, handle, false );
4996 jQuery.Event = function( src, props ) {
4997 // Allow instantiation without the 'new' keyword
4998 if ( !(this instanceof jQuery.Event) ) {
4999 return new jQuery.Event( src, props );
5003 if ( src && src.type ) {
5004 this.originalEvent = src;
5005 this.type = src.type;
5007 // Events bubbling up the document may have been marked as prevented
5008 // by a handler lower down the tree; reflect the correct value.
5009 this.isDefaultPrevented = ( src.defaultPrevented ||
5010 src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
5017 // Put explicitly provided properties onto the event object
5019 jQuery.extend( this, props );
5022 // Create a timestamp if incoming event doesn't have one
5023 this.timeStamp = src && src.timeStamp || jQuery.now();
5026 this[ jQuery.expando ] = true;
5029 // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
5030 // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
5031 jQuery.Event.prototype = {
5032 isDefaultPrevented: returnFalse,
5033 isPropagationStopped: returnFalse,
5034 isImmediatePropagationStopped: returnFalse,
5036 preventDefault: function() {
5037 var e = this.originalEvent;
5039 this.isDefaultPrevented = returnTrue;
5041 if ( e && e.preventDefault ) {
5045 stopPropagation: function() {
5046 var e = this.originalEvent;
5048 this.isPropagationStopped = returnTrue;
5050 if ( e && e.stopPropagation ) {
5051 e.stopPropagation();
5054 stopImmediatePropagation: function() {
5055 this.isImmediatePropagationStopped = returnTrue;
5056 this.stopPropagation();
5060 // Create mouseenter/leave events using mouseover/out and event-time checks
5061 // Support: Chrome 15+
5063 mouseenter: "mouseover",
5064 mouseleave: "mouseout"
5065 }, function( orig, fix ) {
5066 jQuery.event.special[ orig ] = {
5070 handle: function( event ) {
5073 related = event.relatedTarget,
5074 handleObj = event.handleObj;
5076 // For mousenter/leave call the handler if related is outside the target.
5077 // NB: No relatedTarget if the mouse left/entered the browser window
5078 if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
5079 event.type = handleObj.origType;
5080 ret = handleObj.handler.apply( this, arguments );
5088 // Create "bubbling" focus and blur events
5089 // Support: Firefox, Chrome, Safari
5090 if ( !jQuery.support.focusinBubbles ) {
5091 jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
5093 // Attach a single capturing handler while someone wants focusin/focusout
5095 handler = function( event ) {
5096 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
5099 jQuery.event.special[ fix ] = {
5101 if ( attaches++ === 0 ) {
5102 document.addEventListener( orig, handler, true );
5105 teardown: function() {
5106 if ( --attaches === 0 ) {
5107 document.removeEventListener( orig, handler, true );
5116 on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
5119 // Types can be a map of types/handlers
5120 if ( typeof types === "object" ) {
5121 // ( types-Object, selector, data )
5122 if ( typeof selector !== "string" ) {
5123 // ( types-Object, data )
5124 data = data || selector;
5125 selector = undefined;
5127 for ( type in types ) {
5128 this.on( type, selector, data, types[ type ], one );
5133 if ( data == null && fn == null ) {
5136 data = selector = undefined;
5137 } else if ( fn == null ) {
5138 if ( typeof selector === "string" ) {
5139 // ( types, selector, fn )
5143 // ( types, data, fn )
5146 selector = undefined;
5149 if ( fn === false ) {
5157 fn = function( event ) {
5158 // Can use an empty set, since event contains the info
5159 jQuery().off( event );
5160 return origFn.apply( this, arguments );
5162 // Use same guid so caller can remove using origFn
5163 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
5165 return this.each( function() {
5166 jQuery.event.add( this, types, fn, data, selector );
5169 one: function( types, selector, data, fn ) {
5170 return this.on( types, selector, data, fn, 1 );
5172 off: function( types, selector, fn ) {
5173 var handleObj, type;
5174 if ( types && types.preventDefault && types.handleObj ) {
5175 // ( event ) dispatched jQuery.Event
5176 handleObj = types.handleObj;
5177 jQuery( types.delegateTarget ).off(
5178 handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
5184 if ( typeof types === "object" ) {
5185 // ( types-object [, selector] )
5186 for ( type in types ) {
5187 this.off( type, selector, types[ type ] );
5191 if ( selector === false || typeof selector === "function" ) {
5194 selector = undefined;
5196 if ( fn === false ) {
5199 return this.each(function() {
5200 jQuery.event.remove( this, types, fn, selector );
5204 trigger: function( type, data ) {
5205 return this.each(function() {
5206 jQuery.event.trigger( type, data, this );
5209 triggerHandler: function( type, data ) {
5212 return jQuery.event.trigger( type, data, elem, true );
5216 var isSimple = /^.[^:#\[\.,]*$/,
5217 rparentsprev = /^(?:parents|prev(?:Until|All))/,
5218 rneedsContext = jQuery.expr.match.needsContext,
5219 // methods guaranteed to produce a unique set when starting from a unique set
5220 guaranteedUnique = {
5228 find: function( selector ) {
5234 if ( typeof selector !== "string" ) {
5235 return this.pushStack( jQuery( selector ).filter(function() {
5236 for ( i = 0; i < len; i++ ) {
5237 if ( jQuery.contains( self[ i ], this ) ) {
5244 for ( i = 0; i < len; i++ ) {
5245 jQuery.find( selector, self[ i ], ret );
5248 // Needed because $( selector, context ) becomes $( context ).find( selector )
5249 ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
5250 ret.selector = this.selector ? this.selector + " " + selector : selector;
5254 has: function( target ) {
5255 var targets = jQuery( target, this ),
5258 return this.filter(function() {
5260 for ( ; i < l; i++ ) {
5261 if ( jQuery.contains( this, targets[i] ) ) {
5268 not: function( selector ) {
5269 return this.pushStack( winnow(this, selector || [], true) );
5272 filter: function( selector ) {
5273 return this.pushStack( winnow(this, selector || [], false) );
5276 is: function( selector ) {
5280 // If this is a positional/relative selector, check membership in the returned set
5281 // so $("p:first").is("p:last") won't return true for a doc with two "p".
5282 typeof selector === "string" && rneedsContext.test( selector ) ?
5283 jQuery( selector ) :
5289 closest: function( selectors, context ) {
5294 pos = ( rneedsContext.test( selectors ) || typeof selectors !== "string" ) ?
5295 jQuery( selectors, context || this.context ) :
5298 for ( ; i < l; i++ ) {
5299 for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
5300 // Always skip document fragments
5301 if ( cur.nodeType < 11 && (pos ?
5302 pos.index(cur) > -1 :
5304 // Don't pass non-elements to Sizzle
5305 cur.nodeType === 1 &&
5306 jQuery.find.matchesSelector(cur, selectors)) ) {
5308 cur = matched.push( cur );
5314 return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
5317 // Determine the position of an element within
5318 // the matched set of elements
5319 index: function( elem ) {
5321 // No argument, return index in parent
5323 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
5326 // index in selector
5327 if ( typeof elem === "string" ) {
5328 return core_indexOf.call( jQuery( elem ), this[ 0 ] );
5331 // Locate the position of the desired element
5332 return core_indexOf.call( this,
5334 // If it receives a jQuery object, the first element is used
5335 elem.jquery ? elem[ 0 ] : elem
5339 add: function( selector, context ) {
5340 var set = typeof selector === "string" ?
5341 jQuery( selector, context ) :
5342 jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
5343 all = jQuery.merge( this.get(), set );
5345 return this.pushStack( jQuery.unique(all) );
5348 addBack: function( selector ) {
5349 return this.add( selector == null ?
5350 this.prevObject : this.prevObject.filter(selector)
5355 function sibling( cur, dir ) {
5356 while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
5362 parent: function( elem ) {
5363 var parent = elem.parentNode;
5364 return parent && parent.nodeType !== 11 ? parent : null;
5366 parents: function( elem ) {
5367 return jQuery.dir( elem, "parentNode" );
5369 parentsUntil: function( elem, i, until ) {
5370 return jQuery.dir( elem, "parentNode", until );
5372 next: function( elem ) {
5373 return sibling( elem, "nextSibling" );
5375 prev: function( elem ) {
5376 return sibling( elem, "previousSibling" );
5378 nextAll: function( elem ) {
5379 return jQuery.dir( elem, "nextSibling" );
5381 prevAll: function( elem ) {
5382 return jQuery.dir( elem, "previousSibling" );
5384 nextUntil: function( elem, i, until ) {
5385 return jQuery.dir( elem, "nextSibling", until );
5387 prevUntil: function( elem, i, until ) {
5388 return jQuery.dir( elem, "previousSibling", until );
5390 siblings: function( elem ) {
5391 return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
5393 children: function( elem ) {
5394 return jQuery.sibling( elem.firstChild );
5396 contents: function( elem ) {
5397 return elem.contentDocument || jQuery.merge( [], elem.childNodes );
5399 }, function( name, fn ) {
5400 jQuery.fn[ name ] = function( until, selector ) {
5401 var matched = jQuery.map( this, fn, until );
5403 if ( name.slice( -5 ) !== "Until" ) {
5407 if ( selector && typeof selector === "string" ) {
5408 matched = jQuery.filter( selector, matched );
5411 if ( this.length > 1 ) {
5412 // Remove duplicates
5413 if ( !guaranteedUnique[ name ] ) {
5414 jQuery.unique( matched );
5417 // Reverse order for parents* and prev-derivatives
5418 if ( rparentsprev.test( name ) ) {
5423 return this.pushStack( matched );
5428 filter: function( expr, elems, not ) {
5429 var elem = elems[ 0 ];
5432 expr = ":not(" + expr + ")";
5435 return elems.length === 1 && elem.nodeType === 1 ?
5436 jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
5437 jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
5438 return elem.nodeType === 1;
5442 dir: function( elem, dir, until ) {
5444 truncate = until !== undefined;
5446 while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
5447 if ( elem.nodeType === 1 ) {
5448 if ( truncate && jQuery( elem ).is( until ) ) {
5451 matched.push( elem );
5457 sibling: function( n, elem ) {
5460 for ( ; n; n = n.nextSibling ) {
5461 if ( n.nodeType === 1 && n !== elem ) {
5470 // Implement the identical functionality for filter and not
5471 function winnow( elements, qualifier, not ) {
5472 if ( jQuery.isFunction( qualifier ) ) {
5473 return jQuery.grep( elements, function( elem, i ) {
5475 return !!qualifier.call( elem, i, elem ) !== not;
5480 if ( qualifier.nodeType ) {
5481 return jQuery.grep( elements, function( elem ) {
5482 return ( elem === qualifier ) !== not;
5487 if ( typeof qualifier === "string" ) {
5488 if ( isSimple.test( qualifier ) ) {
5489 return jQuery.filter( qualifier, elements, not );
5492 qualifier = jQuery.filter( qualifier, elements );
5495 return jQuery.grep( elements, function( elem ) {
5496 return ( core_indexOf.call( qualifier, elem ) >= 0 ) !== not;
5499 var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
5500 rtagName = /<([\w:]+)/,
5501 rhtml = /<|&#?\w+;/,
5502 rnoInnerhtml = /<(?:script|style|link)/i,
5503 manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
5504 // checked="checked" or checked
5505 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
5506 rscriptType = /^$|\/(?:java|ecma)script/i,
5507 rscriptTypeMasked = /^true\/(.*)/,
5508 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
5510 // We have to close these tags to support XHTML (#13200)
5514 option: [ 1, "<select multiple='multiple'>", "</select>" ],
5516 thead: [ 1, "<table>", "</table>" ],
5517 col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
5518 tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5519 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5521 _default: [ 0, "", "" ]
5525 wrapMap.optgroup = wrapMap.option;
5527 wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5528 wrapMap.th = wrapMap.td;
5531 text: function( value ) {
5532 return jQuery.access( this, function( value ) {
5533 return value === undefined ?
5534 jQuery.text( this ) :
5535 this.empty().append( ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) );
5536 }, null, value, arguments.length );
5539 append: function() {
5540 return this.domManip( arguments, function( elem ) {
5541 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5542 var target = manipulationTarget( this, elem );
5543 target.appendChild( elem );
5548 prepend: function() {
5549 return this.domManip( arguments, function( elem ) {
5550 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
5551 var target = manipulationTarget( this, elem );
5552 target.insertBefore( elem, target.firstChild );
5557 before: function() {
5558 return this.domManip( arguments, function( elem ) {
5559 if ( this.parentNode ) {
5560 this.parentNode.insertBefore( elem, this );
5566 return this.domManip( arguments, function( elem ) {
5567 if ( this.parentNode ) {
5568 this.parentNode.insertBefore( elem, this.nextSibling );
5573 // keepData is for internal use only--do not document
5574 remove: function( selector, keepData ) {
5576 elems = selector ? jQuery.filter( selector, this ) : this,
5579 for ( ; (elem = elems[i]) != null; i++ ) {
5580 if ( !keepData && elem.nodeType === 1 ) {
5581 jQuery.cleanData( getAll( elem ) );
5584 if ( elem.parentNode ) {
5585 if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
5586 setGlobalEval( getAll( elem, "script" ) );
5588 elem.parentNode.removeChild( elem );
5599 for ( ; (elem = this[i]) != null; i++ ) {
5600 if ( elem.nodeType === 1 ) {
5602 // Prevent memory leaks
5603 jQuery.cleanData( getAll( elem, false ) );
5605 // Remove any remaining nodes
5606 elem.textContent = "";
5613 clone: function( dataAndEvents, deepDataAndEvents ) {
5614 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
5615 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
5617 return this.map( function () {
5618 return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
5622 html: function( value ) {
5623 return jQuery.access( this, function( value ) {
5624 var elem = this[ 0 ] || {},
5628 if ( value === undefined && elem.nodeType === 1 ) {
5629 return elem.innerHTML;
5632 // See if we can take a shortcut and just use innerHTML
5633 if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
5634 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
5636 value = value.replace( rxhtmlTag, "<$1></$2>" );
5639 for ( ; i < l; i++ ) {
5640 elem = this[ i ] || {};
5642 // Remove element nodes and prevent memory leaks
5643 if ( elem.nodeType === 1 ) {
5644 jQuery.cleanData( getAll( elem, false ) );
5645 elem.innerHTML = value;
5651 // If using innerHTML throws an exception, use the fallback method
5656 this.empty().append( value );
5658 }, null, value, arguments.length );
5661 replaceWith: function() {
5663 // Snapshot the DOM in case .domManip sweeps something relevant into its fragment
5664 args = jQuery.map( this, function( elem ) {
5665 return [ elem.nextSibling, elem.parentNode ];
5669 // Make the changes, replacing each context element with the new content
5670 this.domManip( arguments, function( elem ) {
5671 var next = args[ i++ ],
5672 parent = args[ i++ ];
5675 // Don't use the snapshot next if it has moved (#13810)
5676 if ( next && next.parentNode !== parent ) {
5677 next = this.nextSibling;
5679 jQuery( this ).remove();
5680 parent.insertBefore( elem, next );
5682 // Allow new content to include elements from the context set
5685 // Force removal if there was no new content (e.g., from empty arguments)
5686 return i ? this : this.remove();
5689 detach: function( selector ) {
5690 return this.remove( selector, true );
5693 domManip: function( args, callback, allowIntersection ) {
5695 // Flatten any nested arrays
5696 args = core_concat.apply( [], args );
5698 var fragment, first, scripts, hasScripts, node, doc,
5704 isFunction = jQuery.isFunction( value );
5706 // We can't cloneNode fragments that contain checked, in WebKit
5707 if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) {
5708 return this.each(function( index ) {
5709 var self = set.eq( index );
5711 args[ 0 ] = value.call( this, index, self.html() );
5713 self.domManip( args, callback, allowIntersection );
5718 fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this );
5719 first = fragment.firstChild;
5721 if ( fragment.childNodes.length === 1 ) {
5726 scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
5727 hasScripts = scripts.length;
5729 // Use the original fragment for the last item instead of the first because it can end up
5730 // being emptied incorrectly in certain situations (#8070).
5731 for ( ; i < l; i++ ) {
5734 if ( i !== iNoClone ) {
5735 node = jQuery.clone( node, true, true );
5737 // Keep references to cloned scripts for later restoration
5739 // Support: QtWebKit
5740 // jQuery.merge because core_push.apply(_, arraylike) throws
5741 jQuery.merge( scripts, getAll( node, "script" ) );
5745 callback.call( this[ i ], node, i );
5749 doc = scripts[ scripts.length - 1 ].ownerDocument;
5752 jQuery.map( scripts, restoreScript );
5754 // Evaluate executable scripts on first document insertion
5755 for ( i = 0; i < hasScripts; i++ ) {
5756 node = scripts[ i ];
5757 if ( rscriptType.test( node.type || "" ) &&
5758 !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
5761 // Hope ajax is available...
5762 jQuery._evalUrl( node.src );
5764 jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
5778 prependTo: "prepend",
5779 insertBefore: "before",
5780 insertAfter: "after",
5781 replaceAll: "replaceWith"
5782 }, function( name, original ) {
5783 jQuery.fn[ name ] = function( selector ) {
5786 insert = jQuery( selector ),
5787 last = insert.length - 1,
5790 for ( ; i <= last; i++ ) {
5791 elems = i === last ? this : this.clone( true );
5792 jQuery( insert[ i ] )[ original ]( elems );
5794 // Support: QtWebKit
5795 // .get() because core_push.apply(_, arraylike) throws
5796 core_push.apply( ret, elems.get() );
5799 return this.pushStack( ret );
5804 clone: function( elem, dataAndEvents, deepDataAndEvents ) {
5805 var i, l, srcElements, destElements,
5806 clone = elem.cloneNode( true ),
5807 inPage = jQuery.contains( elem.ownerDocument, elem );
5810 // Fix Cloning issues
5811 if ( !jQuery.support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) {
5813 // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
5814 destElements = getAll( clone );
5815 srcElements = getAll( elem );
5817 for ( i = 0, l = srcElements.length; i < l; i++ ) {
5818 fixInput( srcElements[ i ], destElements[ i ] );
5822 // Copy the events from the original to the clone
5823 if ( dataAndEvents ) {
5824 if ( deepDataAndEvents ) {
5825 srcElements = srcElements || getAll( elem );
5826 destElements = destElements || getAll( clone );
5828 for ( i = 0, l = srcElements.length; i < l; i++ ) {
5829 cloneCopyEvent( srcElements[ i ], destElements[ i ] );
5832 cloneCopyEvent( elem, clone );
5836 // Preserve script evaluation history
5837 destElements = getAll( clone, "script" );
5838 if ( destElements.length > 0 ) {
5839 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
5842 // Return the cloned set
5846 buildFragment: function( elems, context, scripts, selection ) {
5847 var elem, tmp, tag, wrap, contains, j,
5850 fragment = context.createDocumentFragment(),
5853 for ( ; i < l; i++ ) {
5856 if ( elem || elem === 0 ) {
5858 // Add nodes directly
5859 if ( jQuery.type( elem ) === "object" ) {
5860 // Support: QtWebKit
5861 // jQuery.merge because core_push.apply(_, arraylike) throws
5862 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
5864 // Convert non-html into a text node
5865 } else if ( !rhtml.test( elem ) ) {
5866 nodes.push( context.createTextNode( elem ) );
5868 // Convert html into DOM nodes
5870 tmp = tmp || fragment.appendChild( context.createElement("div") );
5872 // Deserialize a standard representation
5873 tag = ( rtagName.exec( elem ) || ["", ""] )[ 1 ].toLowerCase();
5874 wrap = wrapMap[ tag ] || wrapMap._default;
5875 tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];
5877 // Descend through wrappers to the right content
5880 tmp = tmp.lastChild;
5883 // Support: QtWebKit
5884 // jQuery.merge because core_push.apply(_, arraylike) throws
5885 jQuery.merge( nodes, tmp.childNodes );
5887 // Remember the top-level container
5888 tmp = fragment.firstChild;
5891 // Support: Webkit, IE
5892 tmp.textContent = "";
5897 // Remove wrapper from fragment
5898 fragment.textContent = "";
5901 while ( (elem = nodes[ i++ ]) ) {
5903 // #4087 - If origin and destination elements are the same, and this is
5904 // that element, do not do anything
5905 if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
5909 contains = jQuery.contains( elem.ownerDocument, elem );
5911 // Append to fragment
5912 tmp = getAll( fragment.appendChild( elem ), "script" );
5914 // Preserve script evaluation history
5916 setGlobalEval( tmp );
5919 // Capture executables
5922 while ( (elem = tmp[ j++ ]) ) {
5923 if ( rscriptType.test( elem.type || "" ) ) {
5924 scripts.push( elem );
5933 cleanData: function( elems ) {
5934 var data, elem, events, type, key, j,
5935 special = jQuery.event.special,
5938 for ( ; (elem = elems[ i ]) !== undefined; i++ ) {
5939 if ( Data.accepts( elem ) ) {
5940 key = elem[ data_priv.expando ];
5942 if ( key && (data = data_priv.cache[ key ]) ) {
5943 events = Object.keys( data.events || {} );
5944 if ( events.length ) {
5945 for ( j = 0; (type = events[j]) !== undefined; j++ ) {
5946 if ( special[ type ] ) {
5947 jQuery.event.remove( elem, type );
5949 // This is a shortcut to avoid jQuery.event.remove's overhead
5951 jQuery.removeEvent( elem, type, data.handle );
5955 if ( data_priv.cache[ key ] ) {
5956 // Discard any remaining `private` data
5957 delete data_priv.cache[ key ];
5961 // Discard any remaining `user` data
5962 delete data_user.cache[ elem[ data_user.expando ] ];
5966 _evalUrl: function( url ) {
5967 return jQuery.ajax({
5978 // Support: 1.x compatibility
5979 // Manipulating tables requires a tbody
5980 function manipulationTarget( elem, content ) {
5981 return jQuery.nodeName( elem, "table" ) &&
5982 jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ?
5984 elem.getElementsByTagName("tbody")[0] ||
5985 elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
5989 // Replace/restore the type attribute of script elements for safe DOM manipulation
5990 function disableScript( elem ) {
5991 elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
5994 function restoreScript( elem ) {
5995 var match = rscriptTypeMasked.exec( elem.type );
5998 elem.type = match[ 1 ];
6000 elem.removeAttribute("type");
6006 // Mark scripts as having already been evaluated
6007 function setGlobalEval( elems, refElements ) {
6008 var l = elems.length,
6011 for ( ; i < l; i++ ) {
6013 elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" )
6018 function cloneCopyEvent( src, dest ) {
6019 var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
6021 if ( dest.nodeType !== 1 ) {
6025 // 1. Copy private data: events, handlers, etc.
6026 if ( data_priv.hasData( src ) ) {
6027 pdataOld = data_priv.access( src );
6028 pdataCur = data_priv.set( dest, pdataOld );
6029 events = pdataOld.events;
6032 delete pdataCur.handle;
6033 pdataCur.events = {};
6035 for ( type in events ) {
6036 for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6037 jQuery.event.add( dest, type, events[ type ][ i ] );
6043 // 2. Copy user data
6044 if ( data_user.hasData( src ) ) {
6045 udataOld = data_user.access( src );
6046 udataCur = jQuery.extend( {}, udataOld );
6048 data_user.set( dest, udataCur );
6053 function getAll( context, tag ) {
6054 var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) :
6055 context.querySelectorAll ? context.querySelectorAll( tag || "*" ) :
6058 return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
6059 jQuery.merge( [ context ], ret ) :
6064 function fixInput( src, dest ) {
6065 var nodeName = dest.nodeName.toLowerCase();
6067 // Fails to persist the checked state of a cloned checkbox or radio button.
6068 if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) {
6069 dest.checked = src.checked;
6071 // Fails to return the selected option to the default selected state when cloning options
6072 } else if ( nodeName === "input" || nodeName === "textarea" ) {
6073 dest.defaultValue = src.defaultValue;
6077 wrapAll: function( html ) {
6080 if ( jQuery.isFunction( html ) ) {
6081 return this.each(function( i ) {
6082 jQuery( this ).wrapAll( html.call(this, i) );
6088 // The elements to wrap the target around
6089 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
6091 if ( this[ 0 ].parentNode ) {
6092 wrap.insertBefore( this[ 0 ] );
6095 wrap.map(function() {
6098 while ( elem.firstElementChild ) {
6099 elem = elem.firstElementChild;
6109 wrapInner: function( html ) {
6110 if ( jQuery.isFunction( html ) ) {
6111 return this.each(function( i ) {
6112 jQuery( this ).wrapInner( html.call(this, i) );
6116 return this.each(function() {
6117 var self = jQuery( this ),
6118 contents = self.contents();
6120 if ( contents.length ) {
6121 contents.wrapAll( html );
6124 self.append( html );
6129 wrap: function( html ) {
6130 var isFunction = jQuery.isFunction( html );
6132 return this.each(function( i ) {
6133 jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
6137 unwrap: function() {
6138 return this.parent().each(function() {
6139 if ( !jQuery.nodeName( this, "body" ) ) {
6140 jQuery( this ).replaceWith( this.childNodes );
6146 // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
6147 // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
6148 rdisplayswap = /^(none|table(?!-c[ea]).+)/,
6149 rmargin = /^margin/,
6150 rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
6151 rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
6152 rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ),
6153 elemdisplay = { BODY: "block" },
6155 cssShow = { position: "absolute", visibility: "hidden", display: "block" },
6156 cssNormalTransform = {
6161 cssExpand = [ "Top", "Right", "Bottom", "Left" ],
6162 cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
6164 // return a css property mapped to a potentially vendor prefixed property
6165 function vendorPropName( style, name ) {
6167 // shortcut for names that are not vendor prefixed
6168 if ( name in style ) {
6172 // check for vendor prefixed names
6173 var capName = name.charAt(0).toUpperCase() + name.slice(1),
6175 i = cssPrefixes.length;
6178 name = cssPrefixes[ i ] + capName;
6179 if ( name in style ) {
6187 function isHidden( elem, el ) {
6188 // isHidden might be called from jQuery#filter function;
6189 // in that case, element will be second argument
6191 return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
6194 // NOTE: we've included the "window" in window.getComputedStyle
6195 // because jsdom on node.js will break without it.
6196 function getStyles( elem ) {
6197 return window.getComputedStyle( elem, null );
6200 function showHide( elements, show ) {
6201 var display, elem, hidden,
6204 length = elements.length;
6206 for ( ; index < length; index++ ) {
6207 elem = elements[ index ];
6208 if ( !elem.style ) {
6212 values[ index ] = data_priv.get( elem, "olddisplay" );
6213 display = elem.style.display;
6215 // Reset the inline display of this element to learn if it is
6216 // being hidden by cascaded rules or not
6217 if ( !values[ index ] && display === "none" ) {
6218 elem.style.display = "";
6221 // Set elements which have been overridden with display: none
6222 // in a stylesheet to whatever the default browser style is
6223 // for such an element
6224 if ( elem.style.display === "" && isHidden( elem ) ) {
6225 values[ index ] = data_priv.access( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
6229 if ( !values[ index ] ) {
6230 hidden = isHidden( elem );
6232 if ( display && display !== "none" || !hidden ) {
6233 data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css(elem, "display") );
6239 // Set the display of most of the elements in a second loop
6240 // to avoid the constant reflow
6241 for ( index = 0; index < length; index++ ) {
6242 elem = elements[ index ];
6243 if ( !elem.style ) {
6246 if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
6247 elem.style.display = show ? values[ index ] || "" : "none";
6255 css: function( name, value ) {
6256 return jQuery.access( this, function( elem, name, value ) {
6261 if ( jQuery.isArray( name ) ) {
6262 styles = getStyles( elem );
6265 for ( ; i < len; i++ ) {
6266 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
6272 return value !== undefined ?
6273 jQuery.style( elem, name, value ) :
6274 jQuery.css( elem, name );
6275 }, name, value, arguments.length > 1 );
6278 return showHide( this, true );
6281 return showHide( this );
6283 toggle: function( state ) {
6284 if ( typeof state === "boolean" ) {
6285 return state ? this.show() : this.hide();
6288 return this.each(function() {
6289 if ( isHidden( this ) ) {
6290 jQuery( this ).show();
6292 jQuery( this ).hide();
6299 // Add in style property hooks for overriding the default
6300 // behavior of getting and setting a style property
6303 get: function( elem, computed ) {
6305 // We should always get a number back from opacity
6306 var ret = curCSS( elem, "opacity" );
6307 return ret === "" ? "1" : ret;
6313 // Don't automatically add "px" to these possibly-unitless properties
6315 "columnCount": true,
6316 "fillOpacity": true,
6327 // Add in properties whose names you wish to fix before
6328 // setting or getting the value
6330 // normalize float css property
6334 // Get and set the style property on a DOM Node
6335 style: function( elem, name, value, extra ) {
6336 // Don't set styles on text and comment nodes
6337 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
6341 // Make sure that we're working with the right name
6342 var ret, type, hooks,
6343 origName = jQuery.camelCase( name ),
6346 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
6348 // gets hook for the prefixed version
6349 // followed by the unprefixed version
6350 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6352 // Check if we're setting a value
6353 if ( value !== undefined ) {
6354 type = typeof value;
6356 // convert relative number strings (+= or -=) to relative numbers. #7345
6357 if ( type === "string" && (ret = rrelNum.exec( value )) ) {
6358 value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
6363 // Make sure that NaN and null values aren't set. See: #7116
6364 if ( value == null || type === "number" && isNaN( value ) ) {
6368 // If a number was passed in, add 'px' to the (except for certain CSS properties)
6369 if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
6373 // Fixes #8908, it can be done more correctly by specifying setters in cssHooks,
6374 // but it would mean to define eight (for every problematic property) identical functions
6375 if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
6376 style[ name ] = "inherit";
6379 // If a hook was provided, use that value, otherwise just set the specified value
6380 if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
6381 style[ name ] = value;
6385 // If a hook was provided get the non-computed value from there
6386 if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
6390 // Otherwise just get the value from the style object
6391 return style[ name ];
6395 css: function( elem, name, extra, styles ) {
6396 var val, num, hooks,
6397 origName = jQuery.camelCase( name );
6399 // Make sure that we're working with the right name
6400 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
6402 // gets hook for the prefixed version
6403 // followed by the unprefixed version
6404 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
6406 // If a hook was provided get the computed value from there
6407 if ( hooks && "get" in hooks ) {
6408 val = hooks.get( elem, true, extra );
6411 // Otherwise, if a way to get the computed value exists, use that
6412 if ( val === undefined ) {
6413 val = curCSS( elem, name, styles );
6416 //convert "normal" to computed value
6417 if ( val === "normal" && name in cssNormalTransform ) {
6418 val = cssNormalTransform[ name ];
6421 // Return, converting to number if forced or a qualifier was provided and val looks numeric
6422 if ( extra === "" || extra ) {
6423 num = parseFloat( val );
6424 return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
6430 curCSS = function( elem, name, _computed ) {
6431 var width, minWidth, maxWidth,
6432 computed = _computed || getStyles( elem ),
6435 // getPropertyValue is only needed for .css('filter') in IE9, see #12537
6436 ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
6441 if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
6442 ret = jQuery.style( elem, name );
6445 // Support: Safari 5.1
6446 // A tribute to the "awesome hack by Dean Edwards"
6447 // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
6448 // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
6449 if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
6451 // Remember the original values
6452 width = style.width;
6453 minWidth = style.minWidth;
6454 maxWidth = style.maxWidth;
6456 // Put in the new values to get a computed value out
6457 style.minWidth = style.maxWidth = style.width = ret;
6458 ret = computed.width;
6460 // Revert the changed values
6461 style.width = width;
6462 style.minWidth = minWidth;
6463 style.maxWidth = maxWidth;
6471 function setPositiveNumber( elem, value, subtract ) {
6472 var matches = rnumsplit.exec( value );
6474 // Guard against undefined "subtract", e.g., when used as in cssHooks
6475 Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
6479 function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
6480 var i = extra === ( isBorderBox ? "border" : "content" ) ?
6481 // If we already have the right measurement, avoid augmentation
6483 // Otherwise initialize for horizontal or vertical properties
6484 name === "width" ? 1 : 0,
6488 for ( ; i < 4; i += 2 ) {
6489 // both box models exclude margin, so add it if we want it
6490 if ( extra === "margin" ) {
6491 val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
6494 if ( isBorderBox ) {
6495 // border-box includes padding, so remove it if we want content
6496 if ( extra === "content" ) {
6497 val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6500 // at this point, extra isn't border nor margin, so remove border
6501 if ( extra !== "margin" ) {
6502 val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6505 // at this point, extra isn't content, so add padding
6506 val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
6508 // at this point, extra isn't content nor padding, so add border
6509 if ( extra !== "padding" ) {
6510 val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
6518 function getWidthOrHeight( elem, name, extra ) {
6520 // Start with offset property, which is equivalent to the border-box value
6521 var valueIsBorderBox = true,
6522 val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
6523 styles = getStyles( elem ),
6524 isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
6526 // some non-html elements return undefined for offsetWidth, so check for null/undefined
6527 // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
6528 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
6529 if ( val <= 0 || val == null ) {
6530 // Fall back to computed then uncomputed css if necessary
6531 val = curCSS( elem, name, styles );
6532 if ( val < 0 || val == null ) {
6533 val = elem.style[ name ];
6536 // Computed unit is not pixels. Stop here and return.
6537 if ( rnumnonpx.test(val) ) {
6541 // we need the check for style in case a browser which returns unreliable values
6542 // for getComputedStyle silently falls back to the reliable elem.style
6543 valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
6545 // Normalize "", auto, and prepare for extra
6546 val = parseFloat( val ) || 0;
6549 // use the active box-sizing model to add/subtract irrelevant styles
6551 augmentWidthOrHeight(
6554 extra || ( isBorderBox ? "border" : "content" ),
6561 // Try to determine the default display value of an element
6562 function css_defaultDisplay( nodeName ) {
6564 display = elemdisplay[ nodeName ];
6567 display = actualDisplay( nodeName, doc );
6569 // If the simple way fails, read from inside an iframe
6570 if ( display === "none" || !display ) {
6571 // Use the already-created iframe if possible
6572 iframe = ( iframe ||
6573 jQuery("<iframe frameborder='0' width='0' height='0'/>")
6574 .css( "cssText", "display:block !important" )
6575 ).appendTo( doc.documentElement );
6577 // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
6578 doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
6579 doc.write("<!doctype html><html><body>");
6582 display = actualDisplay( nodeName, doc );
6586 // Store the correct default display
6587 elemdisplay[ nodeName ] = display;
6593 // Called ONLY from within css_defaultDisplay
6594 function actualDisplay( name, doc ) {
6595 var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
6596 display = jQuery.css( elem[0], "display" );
6601 jQuery.each([ "height", "width" ], function( i, name ) {
6602 jQuery.cssHooks[ name ] = {
6603 get: function( elem, computed, extra ) {
6605 // certain elements can have dimension info if we invisibly show them
6606 // however, it must have a current display style that would benefit from this
6607 return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
6608 jQuery.swap( elem, cssShow, function() {
6609 return getWidthOrHeight( elem, name, extra );
6611 getWidthOrHeight( elem, name, extra );
6615 set: function( elem, value, extra ) {
6616 var styles = extra && getStyles( elem );
6617 return setPositiveNumber( elem, value, extra ?
6618 augmentWidthOrHeight(
6622 jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
6630 // These hooks cannot be added until DOM ready because the support test
6631 // for it is not run until after DOM ready
6633 // Support: Android 2.3
6634 if ( !jQuery.support.reliableMarginRight ) {
6635 jQuery.cssHooks.marginRight = {
6636 get: function( elem, computed ) {
6638 // Support: Android 2.3
6639 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
6640 // Work around by temporarily setting element display to inline-block
6641 return jQuery.swap( elem, { "display": "inline-block" },
6642 curCSS, [ elem, "marginRight" ] );
6648 // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
6649 // getComputedStyle returns percent when specified for top/left/bottom/right
6650 // rather than make the css module depend on the offset module, we just check for it here
6651 if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
6652 jQuery.each( [ "top", "left" ], function( i, prop ) {
6653 jQuery.cssHooks[ prop ] = {
6654 get: function( elem, computed ) {
6656 computed = curCSS( elem, prop );
6657 // if curCSS returns percentage, fallback to offset
6658 return rnumnonpx.test( computed ) ?
6659 jQuery( elem ).position()[ prop ] + "px" :
6669 if ( jQuery.expr && jQuery.expr.filters ) {
6670 jQuery.expr.filters.hidden = function( elem ) {
6671 // Support: Opera <= 12.12
6672 // Opera reports offsetWidths and offsetHeights less than zero on some elements
6673 return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
6676 jQuery.expr.filters.visible = function( elem ) {
6677 return !jQuery.expr.filters.hidden( elem );
6681 // These hooks are used by animate to expand properties
6686 }, function( prefix, suffix ) {
6687 jQuery.cssHooks[ prefix + suffix ] = {
6688 expand: function( value ) {
6692 // assumes a single number if not a string
6693 parts = typeof value === "string" ? value.split(" ") : [ value ];
6695 for ( ; i < 4; i++ ) {
6696 expanded[ prefix + cssExpand[ i ] + suffix ] =
6697 parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
6704 if ( !rmargin.test( prefix ) ) {
6705 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
6711 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
6712 rsubmittable = /^(?:input|select|textarea|keygen)/i;
6715 serialize: function() {
6716 return jQuery.param( this.serializeArray() );
6718 serializeArray: function() {
6719 return this.map(function(){
6720 // Can add propHook for "elements" to filter or add form elements
6721 var elements = jQuery.prop( this, "elements" );
6722 return elements ? jQuery.makeArray( elements ) : this;
6725 var type = this.type;
6726 // Use .is(":disabled") so that fieldset[disabled] works
6727 return this.name && !jQuery( this ).is( ":disabled" ) &&
6728 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
6729 ( this.checked || !manipulation_rcheckableType.test( type ) );
6731 .map(function( i, elem ){
6732 var val = jQuery( this ).val();
6734 return val == null ?
6736 jQuery.isArray( val ) ?
6737 jQuery.map( val, function( val ){
6738 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6740 { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
6745 //Serialize an array of form elements or a set of
6746 //key/values into a query string
6747 jQuery.param = function( a, traditional ) {
6750 add = function( key, value ) {
6751 // If value is a function, invoke it and return its value
6752 value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
6753 s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
6756 // Set traditional to true for jQuery <= 1.3.2 behavior.
6757 if ( traditional === undefined ) {
6758 traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
6761 // If an array was passed in, assume that it is an array of form elements.
6762 if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
6763 // Serialize the form elements
6764 jQuery.each( a, function() {
6765 add( this.name, this.value );
6769 // If traditional, encode the "old" way (the way 1.3.2 or older
6770 // did it), otherwise encode params recursively.
6771 for ( prefix in a ) {
6772 buildParams( prefix, a[ prefix ], traditional, add );
6776 // Return the resulting serialization
6777 return s.join( "&" ).replace( r20, "+" );
6780 function buildParams( prefix, obj, traditional, add ) {
6783 if ( jQuery.isArray( obj ) ) {
6784 // Serialize array item.
6785 jQuery.each( obj, function( i, v ) {
6786 if ( traditional || rbracket.test( prefix ) ) {
6787 // Treat each array item as a scalar.
6791 // Item is non-scalar (array or object), encode its numeric index.
6792 buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
6796 } else if ( !traditional && jQuery.type( obj ) === "object" ) {
6797 // Serialize object item.
6798 for ( name in obj ) {
6799 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
6803 // Serialize scalar item.
6807 jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
6808 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
6809 "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
6811 // Handle event binding
6812 jQuery.fn[ name ] = function( data, fn ) {
6813 return arguments.length > 0 ?
6814 this.on( name, null, data, fn ) :
6815 this.trigger( name );
6820 hover: function( fnOver, fnOut ) {
6821 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
6824 bind: function( types, data, fn ) {
6825 return this.on( types, null, data, fn );
6827 unbind: function( types, fn ) {
6828 return this.off( types, null, fn );
6831 delegate: function( selector, types, data, fn ) {
6832 return this.on( types, selector, data, fn );
6834 undelegate: function( selector, types, fn ) {
6835 // ( namespace ) or ( selector, types [, fn] )
6836 return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
6840 // Document location
6844 ajax_nonce = jQuery.now(),
6848 rts = /([?&])_=[^&]*/,
6849 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
6850 // #7653, #8125, #8152: local protocol detection
6851 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
6852 rnoContent = /^(?:GET|HEAD)$/,
6853 rprotocol = /^\/\//,
6854 rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
6856 // Keep a copy of the old load method
6857 _load = jQuery.fn.load,
6860 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
6861 * 2) These are called:
6862 * - BEFORE asking for a transport
6863 * - AFTER param serialization (s.data is a string if s.processData is true)
6864 * 3) key is the dataType
6865 * 4) the catchall symbol "*" can be used
6866 * 5) execution will start with transport dataType and THEN continue down to "*" if needed
6870 /* Transports bindings
6871 * 1) key is the dataType
6872 * 2) the catchall symbol "*" can be used
6873 * 3) selection will start with transport dataType and THEN go to "*" if needed
6877 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
6878 allTypes = "*/".concat("*");
6880 // #8138, IE may throw an exception when accessing
6881 // a field from window.location if document.domain has been set
6883 ajaxLocation = location.href;
6885 // Use the href attribute of an A element
6886 // since IE will modify it given document.location
6887 ajaxLocation = document.createElement( "a" );
6888 ajaxLocation.href = "";
6889 ajaxLocation = ajaxLocation.href;
6892 // Segment location into parts
6893 ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
6895 // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
6896 function addToPrefiltersOrTransports( structure ) {
6898 // dataTypeExpression is optional and defaults to "*"
6899 return function( dataTypeExpression, func ) {
6901 if ( typeof dataTypeExpression !== "string" ) {
6902 func = dataTypeExpression;
6903 dataTypeExpression = "*";
6908 dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || [];
6910 if ( jQuery.isFunction( func ) ) {
6911 // For each dataType in the dataTypeExpression
6912 while ( (dataType = dataTypes[i++]) ) {
6913 // Prepend if requested
6914 if ( dataType[0] === "+" ) {
6915 dataType = dataType.slice( 1 ) || "*";
6916 (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
6920 (structure[ dataType ] = structure[ dataType ] || []).push( func );
6927 // Base inspection function for prefilters and transports
6928 function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
6931 seekingTransport = ( structure === transports );
6933 function inspect( dataType ) {
6935 inspected[ dataType ] = true;
6936 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
6937 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
6938 if( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
6939 options.dataTypes.unshift( dataTypeOrTransport );
6940 inspect( dataTypeOrTransport );
6942 } else if ( seekingTransport ) {
6943 return !( selected = dataTypeOrTransport );
6949 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
6952 // A special extend for ajax options
6953 // that takes "flat" options (not to be deep extended)
6955 function ajaxExtend( target, src ) {
6957 flatOptions = jQuery.ajaxSettings.flatOptions || {};
6959 for ( key in src ) {
6960 if ( src[ key ] !== undefined ) {
6961 ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
6965 jQuery.extend( true, target, deep );
6971 jQuery.fn.load = function( url, params, callback ) {
6972 if ( typeof url !== "string" && _load ) {
6973 return _load.apply( this, arguments );
6976 var selector, type, response,
6978 off = url.indexOf(" ");
6981 selector = url.slice( off );
6982 url = url.slice( 0, off );
6985 // If it's a function
6986 if ( jQuery.isFunction( params ) ) {
6988 // We assume that it's the callback
6992 // Otherwise, build a param string
6993 } else if ( params && typeof params === "object" ) {
6997 // If we have elements to modify, make the request
6998 if ( self.length > 0 ) {
7002 // if "type" variable is undefined, then "GET" method will be used
7006 }).done(function( responseText ) {
7008 // Save response for use in complete callback
7009 response = arguments;
7011 self.html( selector ?
7013 // If a selector was specified, locate the right elements in a dummy div
7014 // Exclude scripts to avoid IE 'Permission Denied' errors
7015 jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
7017 // Otherwise use the full result
7020 }).complete( callback && function( jqXHR, status ) {
7021 self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
7028 // Attach a bunch of functions for handling common AJAX events
7029 jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
7030 jQuery.fn[ type ] = function( fn ){
7031 return this.on( type, fn );
7037 // Counter for holding the number of active queries
7040 // Last-Modified header cache for next request
7047 isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
7051 contentType: "application/x-www-form-urlencoded; charset=UTF-8",
7068 xml: "application/xml, text/xml",
7069 json: "application/json, text/javascript"
7080 text: "responseText",
7081 json: "responseJSON"
7085 // Keys separate source (or catchall "*") and destination types with a single space
7088 // Convert anything to text
7091 // Text to html (true = no transformation)
7094 // Evaluate text as a json expression
7095 "text json": jQuery.parseJSON,
7097 // Parse text as xml
7098 "text xml": jQuery.parseXML
7101 // For options that shouldn't be deep extended:
7102 // you can add your own custom options here if
7103 // and when you create one that shouldn't be
7104 // deep extended (see ajaxExtend)
7111 // Creates a full fledged settings object into target
7112 // with both ajaxSettings and settings fields.
7113 // If target is omitted, writes into ajaxSettings.
7114 ajaxSetup: function( target, settings ) {
7117 // Building a settings object
7118 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
7120 // Extending ajaxSettings
7121 ajaxExtend( jQuery.ajaxSettings, target );
7124 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
7125 ajaxTransport: addToPrefiltersOrTransports( transports ),
7128 ajax: function( url, options ) {
7130 // If url is an object, simulate pre-1.5 signature
7131 if ( typeof url === "object" ) {
7136 // Force options to be an object
7137 options = options || {};
7140 // URL without anti-cache param
7143 responseHeadersString,
7147 // Cross-domain detection vars
7149 // To know if global events are to be dispatched
7153 // Create the final options object
7154 s = jQuery.ajaxSetup( {}, options ),
7155 // Callbacks context
7156 callbackContext = s.context || s,
7157 // Context for global events is callbackContext if it is a DOM node or jQuery collection
7158 globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
7159 jQuery( callbackContext ) :
7162 deferred = jQuery.Deferred(),
7163 completeDeferred = jQuery.Callbacks("once memory"),
7164 // Status-dependent callbacks
7165 statusCode = s.statusCode || {},
7166 // Headers (they are sent all at once)
7167 requestHeaders = {},
7168 requestHeadersNames = {},
7171 // Default abort message
7172 strAbort = "canceled",
7177 // Builds headers hashtable if needed
7178 getResponseHeader: function( key ) {
7180 if ( state === 2 ) {
7181 if ( !responseHeaders ) {
7182 responseHeaders = {};
7183 while ( (match = rheaders.exec( responseHeadersString )) ) {
7184 responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
7187 match = responseHeaders[ key.toLowerCase() ];
7189 return match == null ? null : match;
7193 getAllResponseHeaders: function() {
7194 return state === 2 ? responseHeadersString : null;
7197 // Caches the header
7198 setRequestHeader: function( name, value ) {
7199 var lname = name.toLowerCase();
7201 name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
7202 requestHeaders[ name ] = value;
7207 // Overrides response content-type header
7208 overrideMimeType: function( type ) {
7215 // Status-dependent callbacks
7216 statusCode: function( map ) {
7220 for ( code in map ) {
7221 // Lazy-add the new callback in a way that preserves old ones
7222 statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
7225 // Execute the appropriate callbacks
7226 jqXHR.always( map[ jqXHR.status ] );
7232 // Cancel the request
7233 abort: function( statusText ) {
7234 var finalText = statusText || strAbort;
7236 transport.abort( finalText );
7238 done( 0, finalText );
7244 deferred.promise( jqXHR ).complete = completeDeferred.add;
7245 jqXHR.success = jqXHR.done;
7246 jqXHR.error = jqXHR.fail;
7248 // Remove hash character (#7531: and string promotion)
7249 // Add protocol if not provided (prefilters might expect it)
7250 // Handle falsy url in the settings object (#10093: consistency with old signature)
7251 // We also use the url parameter if available
7252 s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" )
7253 .replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
7255 // Alias method option to type as per ticket #12004
7256 s.type = options.method || options.type || s.method || s.type;
7258 // Extract dataTypes list
7259 s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""];
7261 // A cross-domain request is in order when we have a protocol:host:port mismatch
7262 if ( s.crossDomain == null ) {
7263 parts = rurl.exec( s.url.toLowerCase() );
7264 s.crossDomain = !!( parts &&
7265 ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
7266 ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
7267 ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
7271 // Convert data if not already a string
7272 if ( s.data && s.processData && typeof s.data !== "string" ) {
7273 s.data = jQuery.param( s.data, s.traditional );
7277 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
7279 // If request was aborted inside a prefilter, stop there
7280 if ( state === 2 ) {
7284 // We can fire global events as of now if asked to
7285 fireGlobals = s.global;
7287 // Watch for a new set of requests
7288 if ( fireGlobals && jQuery.active++ === 0 ) {
7289 jQuery.event.trigger("ajaxStart");
7292 // Uppercase the type
7293 s.type = s.type.toUpperCase();
7295 // Determine if request has content
7296 s.hasContent = !rnoContent.test( s.type );
7298 // Save the URL in case we're toying with the If-Modified-Since
7299 // and/or If-None-Match header later on
7302 // More options handling for requests with no content
7303 if ( !s.hasContent ) {
7305 // If data is available, append data to url
7307 cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
7308 // #9682: remove data so that it's not used in an eventual retry
7312 // Add anti-cache in url if needed
7313 if ( s.cache === false ) {
7314 s.url = rts.test( cacheURL ) ?
7316 // If there is already a '_' parameter, set its value
7317 cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) :
7319 // Otherwise add one to the end
7320 cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;
7324 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7325 if ( s.ifModified ) {
7326 if ( jQuery.lastModified[ cacheURL ] ) {
7327 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
7329 if ( jQuery.etag[ cacheURL ] ) {
7330 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
7334 // Set the correct header, if data is being sent
7335 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
7336 jqXHR.setRequestHeader( "Content-Type", s.contentType );
7339 // Set the Accepts header for the server, depending on the dataType
7340 jqXHR.setRequestHeader(
7342 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
7343 s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
7347 // Check for headers option
7348 for ( i in s.headers ) {
7349 jqXHR.setRequestHeader( i, s.headers[ i ] );
7352 // Allow custom headers/mimetypes and early abort
7353 if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
7354 // Abort if not done already and return
7355 return jqXHR.abort();
7358 // aborting is no longer a cancellation
7361 // Install callbacks on deferreds
7362 for ( i in { success: 1, error: 1, complete: 1 } ) {
7363 jqXHR[ i ]( s[ i ] );
7367 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
7369 // If no transport, we auto-abort
7371 done( -1, "No Transport" );
7373 jqXHR.readyState = 1;
7375 // Send global event
7376 if ( fireGlobals ) {
7377 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
7380 if ( s.async && s.timeout > 0 ) {
7381 timeoutTimer = setTimeout(function() {
7382 jqXHR.abort("timeout");
7388 transport.send( requestHeaders, done );
7390 // Propagate exception as error if not done
7393 // Simply rethrow otherwise
7400 // Callback for when everything is done
7401 function done( status, nativeStatusText, responses, headers ) {
7402 var isSuccess, success, error, response, modified,
7403 statusText = nativeStatusText;
7406 if ( state === 2 ) {
7410 // State is "done" now
7413 // Clear timeout if it exists
7414 if ( timeoutTimer ) {
7415 clearTimeout( timeoutTimer );
7418 // Dereference transport for early garbage collection
7419 // (no matter how long the jqXHR object will be used)
7420 transport = undefined;
7422 // Cache response headers
7423 responseHeadersString = headers || "";
7426 jqXHR.readyState = status > 0 ? 4 : 0;
7428 // Determine if successful
7429 isSuccess = status >= 200 && status < 300 || status === 304;
7431 // Get response data
7433 response = ajaxHandleResponses( s, jqXHR, responses );
7436 // Convert no matter what (that way responseXXX fields are always set)
7437 response = ajaxConvert( s, response, jqXHR, isSuccess );
7439 // If successful, handle type chaining
7442 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
7443 if ( s.ifModified ) {
7444 modified = jqXHR.getResponseHeader("Last-Modified");
7446 jQuery.lastModified[ cacheURL ] = modified;
7448 modified = jqXHR.getResponseHeader("etag");
7450 jQuery.etag[ cacheURL ] = modified;
7455 if ( status === 204 || s.type === "HEAD" ) {
7456 statusText = "nocontent";
7459 } else if ( status === 304 ) {
7460 statusText = "notmodified";
7462 // If we have data, let's convert it
7464 statusText = response.state;
7465 success = response.data;
7466 error = response.error;
7470 // We extract error from statusText
7471 // then normalize statusText and status for non-aborts
7473 if ( status || !statusText ) {
7474 statusText = "error";
7481 // Set data for the fake xhr object
7482 jqXHR.status = status;
7483 jqXHR.statusText = ( nativeStatusText || statusText ) + "";
7487 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
7489 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
7492 // Status-dependent callbacks
7493 jqXHR.statusCode( statusCode );
7494 statusCode = undefined;
7496 if ( fireGlobals ) {
7497 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
7498 [ jqXHR, s, isSuccess ? success : error ] );
7502 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
7504 if ( fireGlobals ) {
7505 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
7506 // Handle the global AJAX counter
7507 if ( !( --jQuery.active ) ) {
7508 jQuery.event.trigger("ajaxStop");
7516 getJSON: function( url, data, callback ) {
7517 return jQuery.get( url, data, callback, "json" );
7520 getScript: function( url, callback ) {
7521 return jQuery.get( url, undefined, callback, "script" );
7525 jQuery.each( [ "get", "post" ], function( i, method ) {
7526 jQuery[ method ] = function( url, data, callback, type ) {
7527 // shift arguments if data argument was omitted
7528 if ( jQuery.isFunction( data ) ) {
7529 type = type || callback;
7534 return jQuery.ajax({
7544 /* Handles responses to an ajax request:
7545 * - finds the right dataType (mediates between content-type and expected dataType)
7546 * - returns the corresponding response
7548 function ajaxHandleResponses( s, jqXHR, responses ) {
7550 var ct, type, finalDataType, firstDataType,
7551 contents = s.contents,
7552 dataTypes = s.dataTypes;
7554 // Remove auto dataType and get content-type in the process
7555 while( dataTypes[ 0 ] === "*" ) {
7557 if ( ct === undefined ) {
7558 ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
7562 // Check if we're dealing with a known content-type
7564 for ( type in contents ) {
7565 if ( contents[ type ] && contents[ type ].test( ct ) ) {
7566 dataTypes.unshift( type );
7572 // Check to see if we have a response for the expected dataType
7573 if ( dataTypes[ 0 ] in responses ) {
7574 finalDataType = dataTypes[ 0 ];
7576 // Try convertible dataTypes
7577 for ( type in responses ) {
7578 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
7579 finalDataType = type;
7582 if ( !firstDataType ) {
7583 firstDataType = type;
7586 // Or just use first one
7587 finalDataType = finalDataType || firstDataType;
7590 // If we found a dataType
7591 // We add the dataType to the list if needed
7592 // and return the corresponding response
7593 if ( finalDataType ) {
7594 if ( finalDataType !== dataTypes[ 0 ] ) {
7595 dataTypes.unshift( finalDataType );
7597 return responses[ finalDataType ];
7601 /* Chain conversions given the request and the original response
7602 * Also sets the responseXXX fields on the jqXHR instance
7604 function ajaxConvert( s, response, jqXHR, isSuccess ) {
7605 var conv2, current, conv, tmp, prev,
7607 // Work with a copy of dataTypes in case we need to modify it for conversion
7608 dataTypes = s.dataTypes.slice();
7610 // Create converters map with lowercased keys
7611 if ( dataTypes[ 1 ] ) {
7612 for ( conv in s.converters ) {
7613 converters[ conv.toLowerCase() ] = s.converters[ conv ];
7617 current = dataTypes.shift();
7619 // Convert to each sequential dataType
7622 if ( s.responseFields[ current ] ) {
7623 jqXHR[ s.responseFields[ current ] ] = response;
7626 // Apply the dataFilter if provided
7627 if ( !prev && isSuccess && s.dataFilter ) {
7628 response = s.dataFilter( response, s.dataType );
7632 current = dataTypes.shift();
7636 // There's only work to do if current dataType is non-auto
7637 if ( current === "*" ) {
7641 // Convert response if prev dataType is non-auto and differs from current
7642 } else if ( prev !== "*" && prev !== current ) {
7644 // Seek a direct converter
7645 conv = converters[ prev + " " + current ] || converters[ "* " + current ];
7647 // If none found, seek a pair
7649 for ( conv2 in converters ) {
7651 // If conv2 outputs current
7652 tmp = conv2.split( " " );
7653 if ( tmp[ 1 ] === current ) {
7655 // If prev can be converted to accepted input
7656 conv = converters[ prev + " " + tmp[ 0 ] ] ||
7657 converters[ "* " + tmp[ 0 ] ];
7659 // Condense equivalence converters
7660 if ( conv === true ) {
7661 conv = converters[ conv2 ];
7663 // Otherwise, insert the intermediate dataType
7664 } else if ( converters[ conv2 ] !== true ) {
7666 dataTypes.unshift( tmp[ 1 ] );
7674 // Apply converter (if not an equivalence)
7675 if ( conv !== true ) {
7677 // Unless errors are allowed to bubble, catch and return them
7678 if ( conv && s[ "throws" ] ) {
7679 response = conv( response );
7682 response = conv( response );
7684 return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
7692 return { state: "success", data: response };
7694 // Install script dataType
7697 script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
7700 script: /(?:java|ecma)script/
7703 "text script": function( text ) {
7704 jQuery.globalEval( text );
7710 // Handle cache's special case and crossDomain
7711 jQuery.ajaxPrefilter( "script", function( s ) {
7712 if ( s.cache === undefined ) {
7715 if ( s.crossDomain ) {
7720 // Bind script tag hack transport
7721 jQuery.ajaxTransport( "script", function( s ) {
7722 // This transport only deals with cross domain requests
7723 if ( s.crossDomain ) {
7724 var script, callback;
7726 send: function( _, complete ) {
7727 script = jQuery("<script>").prop({
7729 charset: s.scriptCharset,
7733 callback = function( evt ) {
7737 complete( evt.type === "error" ? 404 : 200, evt.type );
7741 document.head.appendChild( script[ 0 ] );
7751 var oldCallbacks = [],
7752 rjsonp = /(=)\?(?=&|$)|\?\?/;
7754 // Default jsonp settings
7757 jsonpCallback: function() {
7758 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) );
7759 this[ callback ] = true;
7764 // Detect, normalize options and install callbacks for jsonp requests
7765 jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
7767 var callbackName, overwritten, responseContainer,
7768 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
7770 typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
7773 // Handle iff the expected data type is "jsonp" or we have a parameter to set
7774 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
7776 // Get callback name, remembering preexisting value associated with it
7777 callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
7781 // Insert callback into url or form data
7783 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
7784 } else if ( s.jsonp !== false ) {
7785 s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
7788 // Use data converter to retrieve json after script execution
7789 s.converters["script json"] = function() {
7790 if ( !responseContainer ) {
7791 jQuery.error( callbackName + " was not called" );
7793 return responseContainer[ 0 ];
7796 // force json dataType
7797 s.dataTypes[ 0 ] = "json";
7800 overwritten = window[ callbackName ];
7801 window[ callbackName ] = function() {
7802 responseContainer = arguments;
7805 // Clean-up function (fires after converters)
7806 jqXHR.always(function() {
7807 // Restore preexisting value
7808 window[ callbackName ] = overwritten;
7810 // Save back as free
7811 if ( s[ callbackName ] ) {
7812 // make sure that re-using the options doesn't screw things around
7813 s.jsonpCallback = originalSettings.jsonpCallback;
7815 // save the callback name for future use
7816 oldCallbacks.push( callbackName );
7819 // Call if it was a function and we have a response
7820 if ( responseContainer && jQuery.isFunction( overwritten ) ) {
7821 overwritten( responseContainer[ 0 ] );
7824 responseContainer = overwritten = undefined;
7827 // Delegate to script
7831 jQuery.ajaxSettings.xhr = function() {
7833 return new XMLHttpRequest();
7837 var xhrSupported = jQuery.ajaxSettings.xhr(),
7838 xhrSuccessStatus = {
7839 // file protocol always yields status code 0, assume 200
7842 // #1450: sometimes IE returns 1223 when it should be 204
7846 // We need to keep track of outbound xhr and abort them manually
7847 // because IE is not smart enough to do it all by itself
7851 if ( window.ActiveXObject ) {
7852 jQuery( window ).on( "unload", function() {
7853 for( var key in xhrCallbacks ) {
7854 xhrCallbacks[ key ]();
7856 xhrCallbacks = undefined;
7860 jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
7861 jQuery.support.ajax = xhrSupported = !!xhrSupported;
7863 jQuery.ajaxTransport(function( options ) {
7865 // Cross domain only allowed if supported through XMLHttpRequest
7866 if ( jQuery.support.cors || xhrSupported && !options.crossDomain ) {
7868 send: function( headers, complete ) {
7870 xhr = options.xhr();
7871 xhr.open( options.type, options.url, options.async, options.username, options.password );
7872 // Apply custom fields if provided
7873 if ( options.xhrFields ) {
7874 for ( i in options.xhrFields ) {
7875 xhr[ i ] = options.xhrFields[ i ];
7878 // Override mime type if needed
7879 if ( options.mimeType && xhr.overrideMimeType ) {
7880 xhr.overrideMimeType( options.mimeType );
7882 // X-Requested-With header
7883 // For cross-domain requests, seeing as conditions for a preflight are
7884 // akin to a jigsaw puzzle, we simply never set it to be sure.
7885 // (it can always be set on a per-request basis or even using ajaxSetup)
7886 // For same-domain requests, won't change header if already provided.
7887 if ( !options.crossDomain && !headers["X-Requested-With"] ) {
7888 headers["X-Requested-With"] = "XMLHttpRequest";
7891 for ( i in headers ) {
7892 xhr.setRequestHeader( i, headers[ i ] );
7895 callback = function( type ) {
7898 delete xhrCallbacks[ id ];
7899 callback = xhr.onload = xhr.onerror = null;
7900 if ( type === "abort" ) {
7902 } else if ( type === "error" ) {
7904 // file protocol always yields status 0, assume 404
7910 xhrSuccessStatus[ xhr.status ] || xhr.status,
7913 // #11426: When requesting binary data, IE9 will throw an exception
7914 // on any attempt to access responseText
7915 typeof xhr.responseText === "string" ? {
7916 text: xhr.responseText
7918 xhr.getAllResponseHeaders()
7925 xhr.onload = callback();
7926 xhr.onerror = callback("error");
7927 // Create the abort callback
7928 callback = xhrCallbacks[( id = xhrId++ )] = callback("abort");
7929 // Do send the request
7930 // This may raise an exception which is actually
7931 // handled in jQuery.ajax (so no try/catch here)
7932 xhr.send( options.hasContent && options.data || null );
7943 rfxtypes = /^(?:toggle|show|hide)$/,
7944 rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
7945 rrun = /queueHooks$/,
7946 animationPrefilters = [ defaultPrefilter ],
7948 "*": [function( prop, value ) {
7949 var tween = this.createTween( prop, value ),
7950 target = tween.cur(),
7951 parts = rfxnum.exec( value ),
7952 unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
7954 // Starting value computation is required for potential unit mismatches
7955 start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
7956 rfxnum.exec( jQuery.css( tween.elem, prop ) ),
7960 if ( start && start[ 3 ] !== unit ) {
7961 // Trust units reported by jQuery.css
7962 unit = unit || start[ 3 ];
7964 // Make sure we update the tween properties later on
7965 parts = parts || [];
7967 // Iteratively approximate from a nonzero starting point
7968 start = +target || 1;
7971 // If previous iteration zeroed out, double until we get *something*
7972 // Use a string for doubling factor so we don't accidentally see scale as unchanged below
7973 scale = scale || ".5";
7976 start = start / scale;
7977 jQuery.style( tween.elem, prop, start + unit );
7979 // Update scale, tolerating zero or NaN from tween.cur()
7980 // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
7981 } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
7984 // Update tween properties
7986 start = tween.start = +start || +target || 0;
7988 // If a +=/-= token was provided, we're doing a relative animation
7989 tween.end = parts[ 1 ] ?
7990 start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
7998 // Animations created synchronously will run synchronously
7999 function createFxNow() {
8000 setTimeout(function() {
8003 return ( fxNow = jQuery.now() );
8006 function createTween( value, prop, animation ) {
8008 collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
8010 length = collection.length;
8011 for ( ; index < length; index++ ) {
8012 if ( (tween = collection[ index ].call( animation, prop, value )) ) {
8014 // we're done with this property
8020 function Animation( elem, properties, options ) {
8024 length = animationPrefilters.length,
8025 deferred = jQuery.Deferred().always( function() {
8026 // don't match elem in the :animated selector
8033 var currentTime = fxNow || createFxNow(),
8034 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
8035 // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
8036 temp = remaining / animation.duration || 0,
8039 length = animation.tweens.length;
8041 for ( ; index < length ; index++ ) {
8042 animation.tweens[ index ].run( percent );
8045 deferred.notifyWith( elem, [ animation, percent, remaining ]);
8047 if ( percent < 1 && length ) {
8050 deferred.resolveWith( elem, [ animation ] );
8054 animation = deferred.promise({
8056 props: jQuery.extend( {}, properties ),
8057 opts: jQuery.extend( true, { specialEasing: {} }, options ),
8058 originalProperties: properties,
8059 originalOptions: options,
8060 startTime: fxNow || createFxNow(),
8061 duration: options.duration,
8063 createTween: function( prop, end ) {
8064 var tween = jQuery.Tween( elem, animation.opts, prop, end,
8065 animation.opts.specialEasing[ prop ] || animation.opts.easing );
8066 animation.tweens.push( tween );
8069 stop: function( gotoEnd ) {
8071 // if we are going to the end, we want to run all the tweens
8072 // otherwise we skip this part
8073 length = gotoEnd ? animation.tweens.length : 0;
8078 for ( ; index < length ; index++ ) {
8079 animation.tweens[ index ].run( 1 );
8082 // resolve when we played the last frame
8083 // otherwise, reject
8085 deferred.resolveWith( elem, [ animation, gotoEnd ] );
8087 deferred.rejectWith( elem, [ animation, gotoEnd ] );
8092 props = animation.props;
8094 propFilter( props, animation.opts.specialEasing );
8096 for ( ; index < length ; index++ ) {
8097 result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
8103 jQuery.map( props, createTween, animation );
8105 if ( jQuery.isFunction( animation.opts.start ) ) {
8106 animation.opts.start.call( elem, animation );
8110 jQuery.extend( tick, {
8113 queue: animation.opts.queue
8117 // attach callbacks from options
8118 return animation.progress( animation.opts.progress )
8119 .done( animation.opts.done, animation.opts.complete )
8120 .fail( animation.opts.fail )
8121 .always( animation.opts.always );
8124 function propFilter( props, specialEasing ) {
8125 var index, name, easing, value, hooks;
8127 // camelCase, specialEasing and expand cssHook pass
8128 for ( index in props ) {
8129 name = jQuery.camelCase( index );
8130 easing = specialEasing[ name ];
8131 value = props[ index ];
8132 if ( jQuery.isArray( value ) ) {
8133 easing = value[ 1 ];
8134 value = props[ index ] = value[ 0 ];
8137 if ( index !== name ) {
8138 props[ name ] = value;
8139 delete props[ index ];
8142 hooks = jQuery.cssHooks[ name ];
8143 if ( hooks && "expand" in hooks ) {
8144 value = hooks.expand( value );
8145 delete props[ name ];
8147 // not quite $.extend, this wont overwrite keys already present.
8148 // also - reusing 'index' from above because we have the correct "name"
8149 for ( index in value ) {
8150 if ( !( index in props ) ) {
8151 props[ index ] = value[ index ];
8152 specialEasing[ index ] = easing;
8156 specialEasing[ name ] = easing;
8161 jQuery.Animation = jQuery.extend( Animation, {
8163 tweener: function( props, callback ) {
8164 if ( jQuery.isFunction( props ) ) {
8168 props = props.split(" ");
8173 length = props.length;
8175 for ( ; index < length ; index++ ) {
8176 prop = props[ index ];
8177 tweeners[ prop ] = tweeners[ prop ] || [];
8178 tweeners[ prop ].unshift( callback );
8182 prefilter: function( callback, prepend ) {
8184 animationPrefilters.unshift( callback );
8186 animationPrefilters.push( callback );
8191 function defaultPrefilter( elem, props, opts ) {
8192 /* jshint validthis: true */
8193 var prop, value, toggle, tween, hooks, oldfire,
8197 hidden = elem.nodeType && isHidden( elem ),
8198 dataShow = data_priv.get( elem, "fxshow" );
8200 // handle queue: false promises
8201 if ( !opts.queue ) {
8202 hooks = jQuery._queueHooks( elem, "fx" );
8203 if ( hooks.unqueued == null ) {
8205 oldfire = hooks.empty.fire;
8206 hooks.empty.fire = function() {
8207 if ( !hooks.unqueued ) {
8214 anim.always(function() {
8215 // doing this makes sure that the complete handler will be called
8216 // before this completes
8217 anim.always(function() {
8219 if ( !jQuery.queue( elem, "fx" ).length ) {
8226 // height/width overflow pass
8227 if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
8228 // Make sure that nothing sneaks out
8229 // Record all 3 overflow attributes because IE9-10 do not
8230 // change the overflow attribute when overflowX and
8231 // overflowY are set to the same value
8232 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
8234 // Set display property to inline-block for height/width
8235 // animations on inline elements that are having width/height animated
8236 if ( jQuery.css( elem, "display" ) === "inline" &&
8237 jQuery.css( elem, "float" ) === "none" ) {
8239 style.display = "inline-block";
8243 if ( opts.overflow ) {
8244 style.overflow = "hidden";
8245 anim.always(function() {
8246 style.overflow = opts.overflow[ 0 ];
8247 style.overflowX = opts.overflow[ 1 ];
8248 style.overflowY = opts.overflow[ 2 ];
8254 for ( prop in props ) {
8255 value = props[ prop ];
8256 if ( rfxtypes.exec( value ) ) {
8257 delete props[ prop ];
8258 toggle = toggle || value === "toggle";
8259 if ( value === ( hidden ? "hide" : "show" ) ) {
8261 // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
8262 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
8268 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
8272 if ( !jQuery.isEmptyObject( orig ) ) {
8274 if ( "hidden" in dataShow ) {
8275 hidden = dataShow.hidden;
8278 dataShow = data_priv.access( elem, "fxshow", {} );
8281 // store state if its toggle - enables .stop().toggle() to "reverse"
8283 dataShow.hidden = !hidden;
8286 jQuery( elem ).show();
8288 anim.done(function() {
8289 jQuery( elem ).hide();
8292 anim.done(function() {
8295 data_priv.remove( elem, "fxshow" );
8296 for ( prop in orig ) {
8297 jQuery.style( elem, prop, orig[ prop ] );
8300 for ( prop in orig ) {
8301 tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
8303 if ( !( prop in dataShow ) ) {
8304 dataShow[ prop ] = tween.start;
8306 tween.end = tween.start;
8307 tween.start = prop === "width" || prop === "height" ? 1 : 0;
8314 function Tween( elem, options, prop, end, easing ) {
8315 return new Tween.prototype.init( elem, options, prop, end, easing );
8317 jQuery.Tween = Tween;
8321 init: function( elem, options, prop, end, easing, unit ) {
8324 this.easing = easing || "swing";
8325 this.options = options;
8326 this.start = this.now = this.cur();
8328 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
8331 var hooks = Tween.propHooks[ this.prop ];
8333 return hooks && hooks.get ?
8335 Tween.propHooks._default.get( this );
8337 run: function( percent ) {
8339 hooks = Tween.propHooks[ this.prop ];
8341 if ( this.options.duration ) {
8342 this.pos = eased = jQuery.easing[ this.easing ](
8343 percent, this.options.duration * percent, 0, 1, this.options.duration
8346 this.pos = eased = percent;
8348 this.now = ( this.end - this.start ) * eased + this.start;
8350 if ( this.options.step ) {
8351 this.options.step.call( this.elem, this.now, this );
8354 if ( hooks && hooks.set ) {
8357 Tween.propHooks._default.set( this );
8363 Tween.prototype.init.prototype = Tween.prototype;
8367 get: function( tween ) {
8370 if ( tween.elem[ tween.prop ] != null &&
8371 (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
8372 return tween.elem[ tween.prop ];
8375 // passing an empty string as a 3rd parameter to .css will automatically
8376 // attempt a parseFloat and fallback to a string if the parse fails
8377 // so, simple values such as "10px" are parsed to Float.
8378 // complex values such as "rotate(1rad)" are returned as is.
8379 result = jQuery.css( tween.elem, tween.prop, "" );
8380 // Empty strings, null, undefined and "auto" are converted to 0.
8381 return !result || result === "auto" ? 0 : result;
8383 set: function( tween ) {
8384 // use step hook for back compat - use cssHook if its there - use .style if its
8385 // available and use plain properties where available
8386 if ( jQuery.fx.step[ tween.prop ] ) {
8387 jQuery.fx.step[ tween.prop ]( tween );
8388 } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
8389 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
8391 tween.elem[ tween.prop ] = tween.now;
8398 // Panic based approach to setting things on disconnected nodes
8400 Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
8401 set: function( tween ) {
8402 if ( tween.elem.nodeType && tween.elem.parentNode ) {
8403 tween.elem[ tween.prop ] = tween.now;
8408 jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
8409 var cssFn = jQuery.fn[ name ];
8410 jQuery.fn[ name ] = function( speed, easing, callback ) {
8411 return speed == null || typeof speed === "boolean" ?
8412 cssFn.apply( this, arguments ) :
8413 this.animate( genFx( name, true ), speed, easing, callback );
8418 fadeTo: function( speed, to, easing, callback ) {
8420 // show any hidden elements after setting opacity to 0
8421 return this.filter( isHidden ).css( "opacity", 0 ).show()
8423 // animate to the value specified
8424 .end().animate({ opacity: to }, speed, easing, callback );
8426 animate: function( prop, speed, easing, callback ) {
8427 var empty = jQuery.isEmptyObject( prop ),
8428 optall = jQuery.speed( speed, easing, callback ),
8429 doAnimation = function() {
8430 // Operate on a copy of prop so per-property easing won't be lost
8431 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
8433 // Empty animations, or finishing resolves immediately
8434 if ( empty || data_priv.get( this, "finish" ) ) {
8438 doAnimation.finish = doAnimation;
8440 return empty || optall.queue === false ?
8441 this.each( doAnimation ) :
8442 this.queue( optall.queue, doAnimation );
8444 stop: function( type, clearQueue, gotoEnd ) {
8445 var stopQueue = function( hooks ) {
8446 var stop = hooks.stop;
8451 if ( typeof type !== "string" ) {
8452 gotoEnd = clearQueue;
8456 if ( clearQueue && type !== false ) {
8457 this.queue( type || "fx", [] );
8460 return this.each(function() {
8462 index = type != null && type + "queueHooks",
8463 timers = jQuery.timers,
8464 data = data_priv.get( this );
8467 if ( data[ index ] && data[ index ].stop ) {
8468 stopQueue( data[ index ] );
8471 for ( index in data ) {
8472 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
8473 stopQueue( data[ index ] );
8478 for ( index = timers.length; index--; ) {
8479 if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
8480 timers[ index ].anim.stop( gotoEnd );
8482 timers.splice( index, 1 );
8486 // start the next in the queue if the last step wasn't forced
8487 // timers currently will call their complete callbacks, which will dequeue
8488 // but only if they were gotoEnd
8489 if ( dequeue || !gotoEnd ) {
8490 jQuery.dequeue( this, type );
8494 finish: function( type ) {
8495 if ( type !== false ) {
8496 type = type || "fx";
8498 return this.each(function() {
8500 data = data_priv.get( this ),
8501 queue = data[ type + "queue" ],
8502 hooks = data[ type + "queueHooks" ],
8503 timers = jQuery.timers,
8504 length = queue ? queue.length : 0;
8506 // enable finishing flag on private data
8509 // empty the queue first
8510 jQuery.queue( this, type, [] );
8512 if ( hooks && hooks.stop ) {
8513 hooks.stop.call( this, true );
8516 // look for any active animations, and finish them
8517 for ( index = timers.length; index--; ) {
8518 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
8519 timers[ index ].anim.stop( true );
8520 timers.splice( index, 1 );
8524 // look for any animations in the old queue and finish them
8525 for ( index = 0; index < length; index++ ) {
8526 if ( queue[ index ] && queue[ index ].finish ) {
8527 queue[ index ].finish.call( this );
8531 // turn off finishing flag
8537 // Generate parameters to create a standard animation
8538 function genFx( type, includeWidth ) {
8540 attrs = { height: type },
8543 // if we include width, step value is 1 to do all cssExpand values,
8544 // if we don't include width, step value is 2 to skip over Left and Right
8545 includeWidth = includeWidth? 1 : 0;
8546 for( ; i < 4 ; i += 2 - includeWidth ) {
8547 which = cssExpand[ i ];
8548 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
8551 if ( includeWidth ) {
8552 attrs.opacity = attrs.width = type;
8558 // Generate shortcuts for custom animations
8560 slideDown: genFx("show"),
8561 slideUp: genFx("hide"),
8562 slideToggle: genFx("toggle"),
8563 fadeIn: { opacity: "show" },
8564 fadeOut: { opacity: "hide" },
8565 fadeToggle: { opacity: "toggle" }
8566 }, function( name, props ) {
8567 jQuery.fn[ name ] = function( speed, easing, callback ) {
8568 return this.animate( props, speed, easing, callback );
8572 jQuery.speed = function( speed, easing, fn ) {
8573 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
8574 complete: fn || !fn && easing ||
8575 jQuery.isFunction( speed ) && speed,
8577 easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
8580 opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
8581 opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
8583 // normalize opt.queue - true/undefined/null -> "fx"
8584 if ( opt.queue == null || opt.queue === true ) {
8589 opt.old = opt.complete;
8591 opt.complete = function() {
8592 if ( jQuery.isFunction( opt.old ) ) {
8593 opt.old.call( this );
8597 jQuery.dequeue( this, opt.queue );
8605 linear: function( p ) {
8608 swing: function( p ) {
8609 return 0.5 - Math.cos( p*Math.PI ) / 2;
8614 jQuery.fx = Tween.prototype.init;
8615 jQuery.fx.tick = function() {
8617 timers = jQuery.timers,
8620 fxNow = jQuery.now();
8622 for ( ; i < timers.length; i++ ) {
8623 timer = timers[ i ];
8624 // Checks the timer has not already been removed
8625 if ( !timer() && timers[ i ] === timer ) {
8626 timers.splice( i--, 1 );
8630 if ( !timers.length ) {
8636 jQuery.fx.timer = function( timer ) {
8637 if ( timer() && jQuery.timers.push( timer ) ) {
8642 jQuery.fx.interval = 13;
8644 jQuery.fx.start = function() {
8646 timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
8650 jQuery.fx.stop = function() {
8651 clearInterval( timerId );
8655 jQuery.fx.speeds = {
8662 // Back Compat <1.8 extension point
8663 jQuery.fx.step = {};
8665 if ( jQuery.expr && jQuery.expr.filters ) {
8666 jQuery.expr.filters.animated = function( elem ) {
8667 return jQuery.grep(jQuery.timers, function( fn ) {
8668 return elem === fn.elem;
8672 jQuery.fn.offset = function( options ) {
8673 if ( arguments.length ) {
8674 return options === undefined ?
8676 this.each(function( i ) {
8677 jQuery.offset.setOffset( this, options, i );
8683 box = { top: 0, left: 0 },
8684 doc = elem && elem.ownerDocument;
8690 docElem = doc.documentElement;
8692 // Make sure it's not a disconnected DOM node
8693 if ( !jQuery.contains( docElem, elem ) ) {
8697 // If we don't have gBCR, just use 0,0 rather than error
8698 // BlackBerry 5, iOS 3 (original iPhone)
8699 if ( typeof elem.getBoundingClientRect !== core_strundefined ) {
8700 box = elem.getBoundingClientRect();
8702 win = getWindow( doc );
8704 top: box.top + win.pageYOffset - docElem.clientTop,
8705 left: box.left + win.pageXOffset - docElem.clientLeft
8711 setOffset: function( elem, options, i ) {
8712 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
8713 position = jQuery.css( elem, "position" ),
8714 curElem = jQuery( elem ),
8717 // Set position first, in-case top/left are set even on static elem
8718 if ( position === "static" ) {
8719 elem.style.position = "relative";
8722 curOffset = curElem.offset();
8723 curCSSTop = jQuery.css( elem, "top" );
8724 curCSSLeft = jQuery.css( elem, "left" );
8725 calculatePosition = ( position === "absolute" || position === "fixed" ) && ( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
8727 // Need to be able to calculate position if either top or left is auto and position is either absolute or fixed
8728 if ( calculatePosition ) {
8729 curPosition = curElem.position();
8730 curTop = curPosition.top;
8731 curLeft = curPosition.left;
8734 curTop = parseFloat( curCSSTop ) || 0;
8735 curLeft = parseFloat( curCSSLeft ) || 0;
8738 if ( jQuery.isFunction( options ) ) {
8739 options = options.call( elem, i, curOffset );
8742 if ( options.top != null ) {
8743 props.top = ( options.top - curOffset.top ) + curTop;
8745 if ( options.left != null ) {
8746 props.left = ( options.left - curOffset.left ) + curLeft;
8749 if ( "using" in options ) {
8750 options.using.call( elem, props );
8753 curElem.css( props );
8761 position: function() {
8766 var offsetParent, offset,
8768 parentOffset = { top: 0, left: 0 };
8770 // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
8771 if ( jQuery.css( elem, "position" ) === "fixed" ) {
8772 // We assume that getBoundingClientRect is available when computed position is fixed
8773 offset = elem.getBoundingClientRect();
8776 // Get *real* offsetParent
8777 offsetParent = this.offsetParent();
8779 // Get correct offsets
8780 offset = this.offset();
8781 if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
8782 parentOffset = offsetParent.offset();
8785 // Add offsetParent borders
8786 parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
8787 parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
8790 // Subtract parent offsets and element margins
8792 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
8793 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
8797 offsetParent: function() {
8798 return this.map(function() {
8799 var offsetParent = this.offsetParent || docElem;
8801 while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
8802 offsetParent = offsetParent.offsetParent;
8805 return offsetParent || docElem;
8811 // Create scrollLeft and scrollTop methods
8812 jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
8813 var top = "pageYOffset" === prop;
8815 jQuery.fn[ method ] = function( val ) {
8816 return jQuery.access( this, function( elem, method, val ) {
8817 var win = getWindow( elem );
8819 if ( val === undefined ) {
8820 return win ? win[ prop ] : elem[ method ];
8825 !top ? val : window.pageXOffset,
8826 top ? val : window.pageYOffset
8830 elem[ method ] = val;
8832 }, method, val, arguments.length, null );
8836 function getWindow( elem ) {
8837 return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
8839 // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
8840 jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
8841 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
8842 // margin is only for outerHeight, outerWidth
8843 jQuery.fn[ funcName ] = function( margin, value ) {
8844 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
8845 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
8847 return jQuery.access( this, function( elem, type, value ) {
8850 if ( jQuery.isWindow( elem ) ) {
8851 // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
8852 // isn't a whole lot we can do. See pull request at this URL for discussion:
8853 // https://github.com/jquery/jquery/pull/764
8854 return elem.document.documentElement[ "client" + name ];
8857 // Get document width or height
8858 if ( elem.nodeType === 9 ) {
8859 doc = elem.documentElement;
8861 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
8862 // whichever is greatest
8864 elem.body[ "scroll" + name ], doc[ "scroll" + name ],
8865 elem.body[ "offset" + name ], doc[ "offset" + name ],
8866 doc[ "client" + name ]
8870 return value === undefined ?
8871 // Get width or height on the element, requesting but not forcing parseFloat
8872 jQuery.css( elem, type, extra ) :
8874 // Set width or height on the element
8875 jQuery.style( elem, type, value, extra );
8876 }, type, chainable ? margin : undefined, chainable, null );
8880 // Limit scope pollution from any deprecated API
8883 // The number of elements contained in the matched element set
8884 jQuery.fn.size = function() {
8888 jQuery.fn.andSelf = jQuery.fn.addBack;
8891 // Expose jQuery and $ identifiers, even in
8892 // AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
8893 // and CommonJS for browser emulators (#13566)
8894 return (window.jQuery = window.$ = jQuery);
8900 * Lo-Dash 2.4.1 <http://lodash.com/>
8901 * Copyright 2012-2014 The Dojo Foundation <http://dojofoundation.org/>
8902 * Based on Underscore.js 1.6.0 <http://underscorejs.org/LICENSE>
8903 * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
8904 * Available under MIT license <http://lodash.com/license>
8908 /** Used as a safe reference for `undefined` in pre ES5 environments */
8911 /** Used to compose bitmasks for wrapper metadata */
8915 CURRY_BOUND_FLAG = 8,
8917 PARTIAL_RIGHT_FLAG = 32;
8919 /** Used as the size when optimizations are enabled for arrays */
8920 var LARGE_ARRAY_SIZE = 40;
8922 /** Used as the max size of the `arrayPool` and `objectPool` */
8923 var MAX_POOL_SIZE = 40;
8925 /** Used as the semantic version number */
8926 var version = '2.4.1';
8928 /** Used as the property name for wrapper metadata */
8929 var expando = '__lodash@' + version + '__';
8931 /** Used to generate unique IDs */
8934 /** Used to match empty string literals in compiled template source */
8935 var reEmptyStringLeading = /\b__p \+= '';/g,
8936 reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
8937 reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
8939 /** Used to match HTML entities and HTML characters */
8940 var reEscapedHtml = /&(?:amp|lt|gt|quot|#39);/g,
8941 reUnescapedHtml = /[&<>"']/g;
8943 /** Used to match template delimiters */
8944 var reEscape = /<%-([\s\S]+?)%>/g,
8945 reEvaluate = /<%([\s\S]+?)%>/g,
8946 reInterpolate = /<%=([\s\S]+?)%>/g;
8949 * Used to match ES6 template delimiters
8950 * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-literals-string-literals
8952 var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
8954 /** Used to match regexp flags from their coerced string values */
8955 var reFlags = /\w*$/;
8957 /** Used to detected named functions */
8958 var reFuncName = /^\s*function[ \n\r\t]+\w/;
8960 /** Used to detect hexadecimal string values */
8961 var reHexPrefix = /^0[xX]/;
8963 /** Used to ensure capturing order of template delimiters */
8964 var reNoMatch = /($^)/;
8966 /** Used to detect functions containing a `this` reference */
8967 var reThis = /\bthis\b/;
8969 /** Used to match unescaped characters in compiled string literals */
8970 var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
8972 /** Used to detect and test whitespace */
8975 ' \t\x0B\f\xA0\ufeff' +
8978 '\n\r\u2028\u2029' +
8980 // unicode category "Zs" space separators
8981 '\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
8984 /** Used to pool arrays and objects used internally */
8988 /** Used to assign default `context` object properties */
8989 var contextProps = [
8990 'Array', 'Boolean', 'Date', 'Error', 'Function', 'Math', 'Number', 'Object',
8991 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'document', 'isFinite', 'isNaN',
8992 'parseInt', 'setTimeout', 'TypeError', 'window', 'WinRTError'
8995 /** Used to fix the JScript [[DontEnum]] bug */
8996 var shadowedProps = [
8997 'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
8998 'toLocaleString', 'toString', 'valueOf'
9001 /** Used to make template sourceURLs easier to identify */
9002 var templateCounter = 0;
9004 /** `Object#toString` result shortcuts */
9005 var argsClass = '[object Arguments]',
9006 arrayClass = '[object Array]',
9007 boolClass = '[object Boolean]',
9008 dateClass = '[object Date]',
9009 errorClass = '[object Error]',
9010 funcClass = '[object Function]',
9011 numberClass = '[object Number]',
9012 objectClass = '[object Object]',
9013 regexpClass = '[object RegExp]',
9014 stringClass = '[object String]';
9016 /** Used to identify object classifications that `_.clone` supports */
9017 var cloneableClasses = {};
9018 cloneableClasses[funcClass] = false;
9019 cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
9020 cloneableClasses[boolClass] = cloneableClasses[dateClass] =
9021 cloneableClasses[numberClass] = cloneableClasses[objectClass] =
9022 cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
9024 /** Used as an internal `_.debounce` options object */
9025 var debounceOptions = {
9031 /** Used as the property descriptor for wrapper metadata */
9033 'configurable': false,
9034 'enumerable': false,
9040 * Used to convert characters to HTML entities.
9042 * Note: Though the ">" character is escaped for symmetry, characters like
9043 * ">", "`", and "/" don't require escaping in HTML and have no special meaning
9044 * unless they're part of a tag or unquoted attribute value.
9045 * See [Mathias' article](http://mathiasbynens.be/notes/ambiguous-ampersands)
9046 * (under "semi-related fun fact") for more details.
9056 /** Used to convert HTML entities to characters */
9057 var htmlUnescapes = {
9065 /** Used to determine if values are of the language type Object */
9071 /** Used to escape characters for inclusion in compiled string literals */
9072 var stringEscapes = {
9082 /** Used as a reference to the global object */
9083 var root = (objectTypes[typeof window] && window) || this;
9085 /** Detect free variable `exports` */
9086 var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
9088 /** Detect free variable `module` */
9089 var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
9091 /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
9092 var freeGlobal = freeExports && freeModule && typeof global == 'object' && global;
9093 if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) {
9097 /** Detect the popular CommonJS extension `module.exports` */
9098 var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
9100 /*--------------------------------------------------------------------------*/
9103 * The base implementation of `compareAscending` used to compare values and
9104 * sort them in ascending order without guaranteeing a stable sort.
9107 * @param {*} a The value to compare to `b`.
9108 * @param {*} b The value to compare to `a`.
9109 * @returns {number} Returns the sort order indicator for `a`.
9111 function baseCompareAscending(a, b) {
9113 if (a > b || typeof a == 'undefined') {
9116 if (a < b || typeof b == 'undefined') {
9124 * The base implementation of `_.indexOf` without support for binary searches.
9127 * @param {Array} array The array to search.
9128 * @param {*} value The value to search for.
9129 * @param {number} [fromIndex=0] The index to search from.
9130 * @returns {number} Returns the index of the matched value or `-1`.
9132 function baseIndexOf(array, value, fromIndex) {
9133 var index = (fromIndex || 0) - 1,
9134 length = array ? array.length : 0;
9136 while (++index < length) {
9137 if (array[index] === value) {
9145 * An implementation of `_.contains` for cache objects that mimics the return
9146 * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
9149 * @param {Object} cache The cache object to inspect.
9150 * @param {*} value The value to search for.
9151 * @returns {number} Returns `0` if `value` is found, else `-1`.
9153 function cacheIndexOf(cache, value) {
9154 return cache.has(value) ? 0 : -1;
9158 * Used by `_.max` and `_.min` as the default callback when a given
9159 * collection is a string value.
9162 * @param {string} value The character to inspect.
9163 * @returns {number} Returns the code unit of given character.
9165 function charAtCallback(value) {
9166 return value.charCodeAt(0);
9170 * Gets the index of the first character of `string` that is not found in `chars`.
9173 * @param {string} string The string to inspect.
9174 * @returns {number} Returns the index of the first character not found in `chars`.
9176 function charsLeftIndex(string, chars) {
9178 length = string.length;
9180 while (++index < length) {
9181 if (chars.indexOf(string.charAt(index)) < 0) {
9189 * Gets the index of the last character of `string` that is not found in `chars`.
9192 * @param {string} string The string to inspect.
9193 * @returns {number} Returns the index of the last character not found in `chars`.
9195 function charsRightIndex(string, chars) {
9196 var index = string.length;
9198 if (chars.indexOf(string.charAt(index)) < 0) {
9206 * Used by `sortBy` to compare transformed elements of a collection and stable
9207 * sort them in ascending order.
9210 * @param {Object} a The object to compare to `b`.
9211 * @param {Object} b The object to compare to `a`.
9212 * @returns {number} Returns the sort order indicator for `a`.
9214 function compareAscending(a, b) {
9215 return baseCompareAscending(a.criteria, b.criteria) || a.index - b.index;
9219 * Used by `sortBy` to compare multiple properties of each element in a
9220 * collection and stable sort them in ascending order.
9223 * @param {Object} a The object to compare to `b`.
9224 * @param {Object} b The object to compare to `a`.
9225 * @returns {number} Returns the sort order indicator for `a`.
9227 function compareMultipleAscending(a, b) {
9228 var ac = a.criteria,
9233 while (++index < length) {
9234 var result = baseCompareAscending(ac[index], bc[index]);
9239 // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications
9240 // that causes it, under certain circumstances, to provided the same value
9241 // for `a` and `b`. See https://github.com/jashkenas/underscore/pull/1247
9243 // This also ensures a stable sort in V8 and other engines.
9244 // See https://code.google.com/p/v8/issues/detail?id=90
9245 return a.index - b.index;
9249 * Used by `escape` to convert characters to HTML entities.
9252 * @param {string} match The matched character to escape.
9253 * @returns {string} Returns the escaped character.
9255 function escapeHtmlChar(match) {
9256 return htmlEscapes[match];
9260 * Used by `template` to escape characters for inclusion in compiled
9264 * @param {string} match The matched character to escape.
9265 * @returns {string} Returns the escaped character.
9267 function escapeStringChar(match) {
9268 return '\\' + stringEscapes[match];
9272 * Gets an array from the array pool or creates a new one if the pool is empty.
9275 * @returns {Array} The array from the pool.
9277 function getArray() {
9278 return arrayPool.pop() || [];
9282 * Gets an object from the object pool or creates a new one if the pool is empty.
9285 * @returns {Object} The object from the pool.
9287 function getObject() {
9288 return objectPool.pop() || {
9296 * Checks if `value` is a DOM node in IE < 9.
9299 * @param {*} value The value to check.
9300 * @returns {boolean} Returns `true` if the `value` is a DOM node, else `false`.
9302 function isNode(value) {
9303 // IE < 9 presents DOM nodes as `Object` objects except they have `toString`
9304 // methods that are `typeof` "string" and still can coerce nodes to strings
9305 return typeof value.toString != 'function' && typeof (value + '') == 'string';
9309 * Releases `array` back to the array pool.
9312 * @param {Array} array The array to release.
9314 function releaseArray(array) {
9316 if (arrayPool.length < MAX_POOL_SIZE) {
9317 arrayPool.push(array);
9322 * Releases `object` back to the object pool.
9325 * @param {Object} object The object to release.
9327 function releaseObject(object) {
9328 object.criteria = object.value = null;
9329 if (objectPool.length < MAX_POOL_SIZE) {
9330 objectPool.push(object);
9335 * A fallback implementation of `trim` to remove leading and trailing
9336 * whitespace or specified characters from `string`.
9339 * @param {string} string The string to trim.
9340 * @param {string} [chars=whitespace] The characters to trim.
9341 * @returns {string} Returns the trimmed string.
9343 function shimTrim(string, chars) {
9344 string = string == null ? '' : String(string);
9348 if (chars == null) {
9349 return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1);
9351 chars = String(chars);
9352 return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1);
9356 * A fallback implementation of `trimLeft` to remove leading whitespace or
9357 * specified characters from `string`.
9360 * @param {string} string The string to trim.
9361 * @param {string} [chars=whitespace] The characters to trim.
9362 * @returns {string} Returns the trimmed string.
9364 function shimTrimLeft(string, chars) {
9365 string = string == null ? '' : String(string);
9369 if (chars == null) {
9370 return string.slice(trimmedLeftIndex(string))
9372 chars = String(chars);
9373 return string.slice(charsLeftIndex(string, chars));
9377 * A fallback implementation of `trimRight` to remove trailing whitespace or
9378 * specified characters from `string`.
9381 * @param {string} string The string to trim.
9382 * @param {string} [chars=whitespace] The characters to trim.
9383 * @returns {string} Returns the trimmed string.
9385 function shimTrimRight(string, chars) {
9386 string = string == null ? '' : String(string);
9390 if (chars == null) {
9391 return string.slice(0, trimmedRightIndex(string) + 1)
9393 chars = String(chars);
9394 return string.slice(0, charsRightIndex(string, chars) + 1);
9398 * Gets the index of the first non-whitespace character of `string`.
9401 * @param {string} string The string to inspect.
9402 * @returns {number} Returns the index of the first non-whitespace character.
9404 function trimmedLeftIndex(string) {
9406 length = string.length;
9408 while (++index < length) {
9409 var c = string.charCodeAt(index);
9410 if (!((c <= 160 && (c >= 9 && c <= 13) || c == 32 || c == 160) || c == 5760 || c == 6158 ||
9411 (c >= 8192 && (c <= 8202 || c == 8232 || c == 8233 || c == 8239 || c == 8287 || c == 12288 || c == 65279)))) {
9419 * Gets the index of the last non-whitespace character of `string`.
9422 * @param {string} string The string to inspect.
9423 * @returns {number} Returns the index of the last non-whitespace character.
9425 function trimmedRightIndex(string) {
9426 var index = string.length;
9428 var c = string.charCodeAt(index);
9429 if (!((c <= 160 && (c >= 9 && c <= 13) || c == 32 || c == 160) || c == 5760 || c == 6158 ||
9430 (c >= 8192 && (c <= 8202 || c == 8232 || c == 8233 || c == 8239 || c == 8287 || c == 12288 || c == 65279)))) {
9438 * Used by `unescape` to convert HTML entities to characters.
9441 * @param {string} match The matched character to unescape.
9442 * @returns {string} Returns the unescaped character.
9444 function unescapeHtmlChar(match) {
9445 return htmlUnescapes[match];
9448 /*--------------------------------------------------------------------------*/
9451 * Create a new `lodash` function using the given context object.
9455 * @category Utilities
9456 * @param {Object} [context=root] The context object.
9457 * @returns {Function} Returns a new `lodash` function.
9459 function runInContext(context) {
9460 // Avoid issues with some ES3 environments that attempt to use values, named
9461 // after built-in constructors like `Object`, for the creation of literals.
9462 // ES5 clears this up by stating that literals must use built-in constructors.
9463 // See http://es5.github.io/#x11.1.5.
9464 context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
9466 /** Native constructor references */
9467 var Array = context.Array,
9468 Boolean = context.Boolean,
9469 Date = context.Date,
9470 Error = context.Error,
9471 Function = context.Function,
9472 Math = context.Math,
9473 Number = context.Number,
9474 Object = context.Object,
9475 RegExp = context.RegExp,
9476 String = context.String,
9477 TypeError = context.TypeError;
9479 /** Used for native method references */
9480 var arrayRef = Array.prototype,
9481 errorProto = Error.prototype,
9482 objectProto = Object.prototype,
9483 stringProto = String.prototype;
9485 /** Used to detect DOM support */
9486 var document = (document = context.window) && document.document;
9488 /** Used to restore the original `_` reference in `noConflict` */
9489 var oldDash = context._;
9491 /** Used to resolve the internal [[Class]] of values */
9492 var toString = objectProto.toString;
9494 /** Used to detect if a method is native */
9495 var reNative = RegExp('^' +
9497 .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
9498 .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
9501 /** Native method shortcuts */
9502 var ceil = Math.ceil,
9503 clearTimeout = context.clearTimeout,
9505 fnToString = Function.prototype.toString,
9506 getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
9507 hasOwnProperty = objectProto.hasOwnProperty,
9508 push = arrayRef.push,
9509 propertyIsEnumerable = objectProto.propertyIsEnumerable,
9510 Set = isNative(Set = context.Set) && Set,
9511 setTimeout = context.setTimeout,
9512 splice = arrayRef.splice,
9513 unshift = arrayRef.unshift;
9515 /** Used to set meta data on functions */
9516 var defineProperty = (function() {
9517 // IE 8 only accepts DOM elements
9520 func = isNative(func = Object.defineProperty) && func,
9521 result = func(o, o, o) && func;
9526 /* Native method shortcuts for methods with the same name as other `lodash` methods */
9527 var nativeContains = isNative(nativeContains = stringProto.contains) && nativeContains,
9528 nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate,
9529 nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray,
9530 nativeIsFinite = context.isFinite,
9531 nativeIsNaN = context.isNaN,
9532 nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys,
9533 nativeMax = Math.max,
9534 nativeMin = Math.min,
9535 nativeNow = isNative(nativeNow = Date.now) && nativeNow,
9536 nativeParseInt = context.parseInt,
9537 nativeRandom = Math.random,
9538 nativeTrim = isNative(nativeTrim = stringProto.trim) && !nativeTrim.call(whitespace) && nativeTrim,
9539 nativeTrimLeft = isNative(nativeTrimLeft = stringProto.trimLeft) && !nativeTrimLeft.call(whitespace) && nativeTrimLeft,
9540 nativeTrimRight = isNative(nativeTrimRight = stringProto.trimRight) && !nativeTrimRight.call(whitespace) && nativeTrimRight;
9542 /** Used to lookup a built-in constructor by [[Class]] */
9543 var ctorByClass = {};
9544 ctorByClass[arrayClass] = Array;
9545 ctorByClass[boolClass] = Boolean;
9546 ctorByClass[dateClass] = Date;
9547 ctorByClass[funcClass] = Function;
9548 ctorByClass[objectClass] = Object;
9549 ctorByClass[numberClass] = Number;
9550 ctorByClass[regexpClass] = RegExp;
9551 ctorByClass[stringClass] = String;
9553 /** Used to avoid iterating non-enumerable properties in IE < 9 */
9554 var nonEnumProps = {};
9555 nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true };
9556 nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true };
9557 nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true };
9558 nonEnumProps[objectClass] = { 'constructor': true };
9561 var length = shadowedProps.length;
9563 var key = shadowedProps[length];
9564 for (var className in nonEnumProps) {
9565 if (hasOwnProperty.call(nonEnumProps, className) && !hasOwnProperty.call(nonEnumProps[className], key)) {
9566 nonEnumProps[className][key] = false;
9572 /*--------------------------------------------------------------------------*/
9575 * Creates a `lodash` object which wraps the given value to enable intuitive
9578 * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
9579 * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
9582 * Chaining is supported in custom builds as long as the `value` method is
9583 * implicitly or explicitly included in the build.
9585 * The chainable wrapper functions are:
9586 * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
9587 * `compose`, `concat`, `constant`, `countBy`, `create`, `createCallback`,
9588 * `curry`, `debounce`, `defaults`, `defer`, `delay`, `difference`, `filter`,
9589 * `flatten`, `forEach`, `forEachRight`, `forIn`, `forInRight`, `forOwn`,
9590 * `forOwnRight`, `functions`, `groupBy`, `indexBy`, `initial`, `intersection`,
9591 * `invert`, `invoke`, `keys`, `map`, `mapValues`, `matches`, `max`, `memoize`,
9592 * `merge`, `min`, `noop`, `object`, `omit`, `once`, `pairs`, `partial`,
9593 * `partialRight`, `pick`, `pluck`, `property`, `pull`, `push`, `range`,
9594 * `reject`, `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`,
9595 * `splice`, `tap`, `throttle`, `times`, `toArray`, `transform`, `union`,
9596 * `uniq`, `unshift`, `unzip`, `values`, `where`, `without`, `wrap`, `xor`,
9599 * The non-chainable wrapper functions are:
9600 * `capitalize`, `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`,
9601 * `findIndex`, `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`,
9602 * `identity`, `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`,
9603 * `isElement`, `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`,
9604 * `isNull`, `isNumber`, `isObject`, `isPlainObject`, `isRegExp`, `isString`,
9605 * `isUndefined`, `join`, `lastIndexOf`, `mixin`, `noConflict`, `now`,
9606 * `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, `result`, `shift`,
9607 * `size`, `some`, `sortedIndex`, `runInContext`, `template`, `trim`,
9608 * `trimLeft`, `trimRight`, `unescape`, `uniqueId`, and `value`
9610 * The wrapper functions `first`, `last`, and `sample` return wrapped values
9611 * when `n` is provided, otherwise they return unwrapped values.
9613 * Explicit chaining can be enabled by using the `_.chain` method.
9617 * @category Chaining
9618 * @param {*} value The value to wrap in a `lodash` instance.
9619 * @returns {Object} Returns a `lodash` instance.
9622 * var wrapped = _([1, 2, 3]);
9624 * // returns an unwrapped value
9625 * wrapped.reduce(function(sum, num) {
9630 * // returns a wrapped value
9631 * var squares = wrapped.map(function(num) {
9635 * _.isArray(squares);
9638 * _.isArray(squares.value());
9641 function lodash(value) {
9642 // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
9643 return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
9645 : new lodashWrapper(value);
9649 * A fast path for creating `lodash` wrapper objects.
9652 * @param {*} value The value to wrap in a `lodash` instance.
9653 * @param {boolean} [chainAll=false] A flag to enable chaining for all methods
9654 * @returns {Object} Returns a `lodash` instance.
9656 function lodashWrapper(value, chainAll) {
9657 this.__chain__ = !!chainAll;
9658 this.__wrapped__ = value;
9660 // ensure `new lodashWrapper` is an instance of `lodash`
9661 lodashWrapper.prototype = lodash.prototype;
9664 * An object used to flag environments features.
9670 var support = lodash.support = {};
9673 var ctor = function() { this.x = 1; },
9674 object = { '0': 1, 'length': 1 },
9677 ctor.prototype = { 'valueOf': 1, 'y': 1 };
9678 for (var key in new ctor) { props.push(key); }
9679 for (key in arguments) { }
9682 * Detect if an `arguments` object's [[Class]] is resolvable (all but Firefox < 4, IE < 9).
9684 * @memberOf _.support
9687 support.argsClass = toString.call(arguments) == argsClass;
9690 * Detect if `arguments` objects are `Object` objects (all but Narwhal and Opera < 10.5).
9692 * @memberOf _.support
9695 support.argsObject = arguments.constructor == Object && !(arguments instanceof Array);
9698 * Detect if `name` or `message` properties of `Error.prototype` are
9699 * enumerable by default. (IE < 9, Safari < 5.1)
9701 * @memberOf _.support
9704 support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name');
9707 * Detect if `prototype` properties are enumerable by default.
9709 * Firefox < 3.6, Opera > 9.50 - Opera < 11.60, and Safari < 5.1
9710 * (if the prototype or a property on the prototype has been set)
9711 * incorrectly sets a function's `prototype` property [[Enumerable]]
9714 * @memberOf _.support
9717 support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype');
9720 * Detect if functions can be decompiled by `Function#toString`
9721 * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
9723 * @memberOf _.support
9726 support.funcDecomp = !isNative(context.WinRTError) && reThis.test(runInContext);
9729 * Detect if `Function#name` is supported (all but IE).
9731 * @memberOf _.support
9734 support.funcNames = typeof Function.name == 'string';
9737 * Detect if `arguments` object indexes are non-enumerable
9738 * (Firefox < 4, IE < 9, PhantomJS, Safari < 5.1).
9740 * @memberOf _.support
9743 support.nonEnumArgs = key != 0;
9746 * Detect if properties shadowing those on `Object.prototype` are non-enumerable.
9748 * In IE < 9 an objects own properties, shadowing non-enumerable ones, are
9749 * made non-enumerable as well (a.k.a the JScript [[DontEnum]] bug).
9751 * @memberOf _.support
9754 support.nonEnumShadows = !/valueOf/.test(props);
9757 * Detect if own properties are iterated after inherited properties (all but IE < 9).
9759 * @memberOf _.support
9762 support.ownLast = props[0] != 'x';
9765 * Detect if `Array#shift` and `Array#splice` augment array-like objects correctly.
9767 * Firefox < 10, IE compatibility mode, and IE < 9 have buggy Array `shift()`
9768 * and `splice()` functions that fail to remove the last element, `value[0]`,
9769 * of array-like objects even though the `length` property is set to `0`.
9770 * The `shift()` method is buggy in IE 8 compatibility mode, while `splice()`
9771 * is buggy regardless of mode in IE < 9 and buggy in compatibility mode in IE 9.
9773 * @memberOf _.support
9776 support.spliceObjects = (splice.call(object, 0, 1), !object[0]);
9779 * Detect lack of support for accessing string characters by index.
9781 * IE < 8 can't access characters by index and IE 8 can only access
9782 * characters by index on string literals.
9784 * @memberOf _.support
9787 support.unindexedChars = ('x'[0] + Object('x')[0]) != 'xx';
9790 * Detect if the DOM is supported.
9792 * @memberOf _.support
9796 support.dom = document.createDocumentFragment().nodeType === 11;
9798 support.dom = false;
9802 * Detect if a DOM node's [[Class]] is resolvable (all but IE < 9)
9803 * and that the JS engine errors when attempting to coerce an object to
9804 * a string without a `toString` function.
9806 * @memberOf _.support
9810 support.nodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + ''));
9812 support.nodeClass = true;
9817 * By default, the template delimiters used by Lo-Dash are similar to those in
9818 * embedded Ruby (ERB). Change the following template settings to use alternative
9825 lodash.templateSettings = {
9828 * Used to detect `data` property values to be HTML-escaped.
9830 * @memberOf _.templateSettings
9836 * Used to detect code to be evaluated.
9838 * @memberOf _.templateSettings
9841 'evaluate': reEvaluate,
9844 * Used to detect `data` property values to inject.
9846 * @memberOf _.templateSettings
9849 'interpolate': reInterpolate,
9852 * Used to reference the data object in the template text.
9854 * @memberOf _.templateSettings
9860 * Used to import variables into the compiled template.
9862 * @memberOf _.templateSettings
9868 * A reference to the `lodash` function.
9870 * @memberOf _.templateSettings.imports
9877 /*--------------------------------------------------------------------------*/
9880 * The template used to create iterator functions.
9883 * @param {Object} data The data object used to populate the text.
9884 * @returns {string} Returns the interpolated text.
9886 var iteratorTemplate = template(
9887 // assign the `result` variable an initial value
9888 'var result = <%= init %>;\n' +
9890 // exit early if the first argument is not an object
9891 "if (!isObject(object)) {\n" +
9892 ' return result;\n' +
9895 // add support for iterating over `arguments` objects if needed
9896 '<% if (support.nonEnumArgs) { %>\n' +
9897 'var length = object.length;\n' +
9898 'if (length && isArguments(object)) {\n' +
9900 ' while (++key < length) {\n' +
9904 ' return result;\n' +
9908 // avoid iterating over `prototype` properties in older Firefox, Opera, and Safari
9909 '<% if (support.enumPrototypes) { %>\n' +
9910 "var skipProto = typeof object == 'function';\n" +
9913 // avoid iterating over `Error.prototype` properties in older IE and Safari
9914 '<% if (support.enumErrorProps) { %>\n' +
9915 'var skipErrorProps = object === errorProto || object instanceof Error;\n' +
9918 // define conditions used in the loop
9920 'var conditions = [];\n' +
9921 "if (support.enumPrototypes) { conditions.push('!(skipProto && key == \\'prototype\\')'); }\n" +
9922 "if (support.enumErrorProps) { conditions.push('!(skipErrorProps && (key == \\'message\\' || key == \\'name\\'))'); }" +
9925 // iterate over the object
9926 'for (var key in object) {\n<%' +
9927 " if (useHas) { conditions.push('hasOwnProperty.call(object, key)'); }\n" +
9928 " if (conditions.length) { %> if (<%= conditions.join(' && ') %>) {\n <% } %>" +
9930 ' <% if (conditions.length) { %>\n }<% } %>\n' +
9933 // Lo-Dash skips the `constructor` property when it infers it's iterating
9934 // over a `prototype` object because IE < 9 can't set the `[[Enumerable]]`
9935 // attribute of an existing property and the `constructor` property of a
9936 // prototype defaults to non-enumerable.
9937 '<% if (support.nonEnumShadows) { %>\n' +
9938 'if (object !== objectProto) {\n' +
9939 " var ctor = object.constructor,\n" +
9940 ' isProto = object === (ctor && ctor.prototype),\n' +
9941 ' className = object === stringProto ? stringClass : object === errorProto ? errorClass : toString.call(object),\n' +
9942 ' nonEnum = nonEnumProps[className];\n' +
9943 ' <% for (var index = 0; index < 7; index++) { %>\n' +
9944 " key = '<%= shadowedProps[index] %>';\n" +
9945 ' if ((!(isProto && nonEnum[key]) && hasOwnProperty.call(object, key))<%' +
9946 ' if (!useHas) { %> || (!nonEnum[key] && object[key] !== objectProto[key])<% }' +
9957 /*--------------------------------------------------------------------------*/
9960 * The base implementation of `_.bind` that creates the bound function and
9961 * sets its meta data.
9964 * @param {Array} data The metadata array.
9965 * @returns {Function} Returns the new bound function.
9967 function baseBind(data) {
9970 partialArgs = data[4];
9973 // `Function#bind` spec
9974 // http://es5.github.io/#x15.3.4.5
9976 // avoid `arguments` object deoptimizations by using `slice` instead
9977 // of `Array.prototype.slice.call` and not assigning `arguments` to a
9978 // variable as a ternary expression
9979 var args = slice(partialArgs);
9980 push.apply(args, arguments);
9982 // mimic the constructor's `return` behavior
9983 // http://es5.github.io/#x13.2.2
9984 if (this instanceof bound) {
9985 // ensure `new bound` is an instance of `func`
9986 var thisBinding = baseCreate(func.prototype),
9987 result = func.apply(thisBinding, args || arguments);
9988 return isObject(result) ? result : thisBinding;
9990 return func.apply(thisArg, args || arguments);
9992 setData(bound, data);
9997 * The base implementation of `_.clone` without argument juggling or support
9998 * for `thisArg` binding.
10001 * @param {*} value The value to clone.
10002 * @param {boolean} [isDeep=false] Specify a deep clone.
10003 * @param {Function} [callback] The function to customize cloning values.
10004 * @param {Array} [stackA=[]] Tracks traversed source objects.
10005 * @param {Array} [stackB=[]] Associates clones with source counterparts.
10006 * @returns {*} Returns the cloned value.
10008 function baseClone(value, isDeep, callback, stackA, stackB) {
10010 var result = callback(value);
10011 if (typeof result != 'undefined') {
10015 // inspect [[Class]]
10016 var isObj = isObject(value);
10018 var className = toString.call(value);
10019 if (!cloneableClasses[className] || (!support.nodeClass && isNode(value))) {
10022 var ctor = ctorByClass[className];
10023 switch (className) {
10026 return new ctor(+value);
10030 return new ctor(value);
10033 result = ctor(value.source, reFlags.exec(value));
10034 result.lastIndex = value.lastIndex;
10040 var isArr = isArray(value);
10042 // check for circular references and return corresponding clone
10043 var initedStack = !stackA;
10044 stackA || (stackA = getArray());
10045 stackB || (stackB = getArray());
10047 var length = stackA.length;
10049 if (stackA[length] == value) {
10050 return stackB[length];
10053 result = isArr ? ctor(value.length) : {};
10056 result = isArr ? slice(value) : assign({}, value);
10058 // add array properties assigned by `RegExp#exec`
10060 if (hasOwnProperty.call(value, 'index')) {
10061 result.index = value.index;
10063 if (hasOwnProperty.call(value, 'input')) {
10064 result.input = value.input;
10067 // exit for shallow clone
10071 // add the source value to the stack of traversed objects
10072 // and associate it with its clone
10073 stackA.push(value);
10074 stackB.push(result);
10076 // recursively populate clone (susceptible to call stack limits)
10077 (isArr ? baseEach : baseForOwn)(value, function(objValue, key) {
10078 result[key] = baseClone(objValue, isDeep, callback, stackA, stackB);
10082 releaseArray(stackA);
10083 releaseArray(stackB);
10089 * The base implementation of `_.create` without support for assigning
10090 * properties to the created object.
10093 * @param {Object} prototype The object to inherit from.
10094 * @returns {Object} Returns the new object.
10096 function baseCreate(prototype) {
10097 return isObject(prototype) ? nativeCreate(prototype) : {};
10099 // fallback for environments without `Object.create`
10100 if (!nativeCreate) {
10101 baseCreate = (function() {
10102 function Object() {}
10103 return function(prototype) {
10104 if (isObject(prototype)) {
10105 Object.prototype = prototype;
10106 var result = new Object;
10107 Object.prototype = null;
10109 return result || context.Object();
10115 * The base implementation of `_.createCallback` without support for creating
10116 * "_.pluck" or "_.where" style callbacks.
10119 * @param {*} [func=identity] The value to convert to a callback.
10120 * @param {*} [thisArg] The `this` binding of the created callback.
10121 * @param {number} [argCount] The number of arguments the callback accepts.
10122 * @returns {Function} Returns a callback function.
10124 function baseCreateCallback(func, thisArg, argCount) {
10125 if (typeof func != 'function') {
10128 // exit early for no `thisArg` or already bound by `Function#bind`
10129 if (typeof thisArg == 'undefined' || !('prototype' in func)) {
10132 var data = func[expando];
10133 if (typeof data == 'undefined') {
10134 if (support.funcNames) {
10137 data = data || !support.funcDecomp;
10139 var source = fnToString.call(func);
10140 if (!support.funcNames) {
10141 data = !reFuncName.test(source);
10144 // checks if `func` references the `this` keyword and stores the result
10145 data = reThis.test(source);
10146 setData(func, data);
10150 // exit early if there are no `this` references or `func` is bound
10151 if (data === false || (data !== true && data[1] & BIND_FLAG)) {
10154 switch (argCount) {
10155 case 1: return function(value) {
10156 return func.call(thisArg, value);
10158 case 2: return function(a, b) {
10159 return func.call(thisArg, a, b);
10161 case 3: return function(value, index, collection) {
10162 return func.call(thisArg, value, index, collection);
10164 case 4: return function(accumulator, value, index, collection) {
10165 return func.call(thisArg, accumulator, value, index, collection);
10168 return bind(func, thisArg);
10172 * The base implementation of `createWrapper` that creates the wrapper and
10173 * sets its meta data.
10176 * @param {Array} data The metadata array.
10177 * @returns {Function} Returns the new function.
10179 function baseCreateWrapper(data) {
10180 var func = data[0],
10184 partialArgs = data[4],
10185 partialRightArgs = data[5];
10187 var isBind = bitmask & BIND_FLAG,
10188 isBindKey = bitmask & BIND_KEY_FLAG,
10189 isCurry = bitmask & CURRY_FLAG,
10190 isCurryBound = bitmask & CURRY_BOUND_FLAG,
10194 var thisBinding = isBind ? thisArg : this;
10196 var args = slice(partialArgs);
10197 push.apply(args, arguments);
10199 if (partialRightArgs || isCurry) {
10200 args || (args = slice(arguments));
10201 if (partialRightArgs) {
10202 push.apply(args, partialRightArgs);
10204 var argsLength = arguments.length;
10205 if (isCurry && argsLength < arity) {
10206 bitmask |= PARTIAL_FLAG;
10207 bitmask &= ~PARTIAL_RIGHT_FLAG
10208 if (!isCurryBound) {
10209 bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG);
10211 var newArity = nativeMax(0, arity - argsLength);
10212 return baseCreateWrapper([func, bitmask, newArity, thisArg, args]);
10215 args || (args = arguments);
10217 func = thisBinding[key];
10219 if (this instanceof bound) {
10220 thisBinding = baseCreate(func.prototype);
10221 var result = func.apply(thisBinding, args);
10222 return isObject(result) ? result : thisBinding;
10224 return func.apply(thisBinding, args);
10226 setData(bound, data);
10231 * The base implementation of `_.difference` that accepts a single array
10232 * of values to exclude.
10235 * @param {Array} array The array to process.
10236 * @param {Array} [values] The array of values to exclude.
10237 * @returns {Array} Returns a new array of filtered values.
10239 function baseDifference(array, values) {
10241 indexOf = getIndexOf(),
10242 length = array ? array.length : 0,
10245 if (createCache && values && indexOf === baseIndexOf && values.length >= LARGE_ARRAY_SIZE) {
10246 indexOf = cacheIndexOf;
10247 values = createCache(values);
10249 while (++index < length) {
10250 var value = array[index];
10251 if (indexOf(values, value) < 0) {
10252 result.push(value);
10259 * The base implementation of `_.forEach` without support for callback
10260 * shorthands or `thisArg` binding.
10263 * @param {Array|Object|string} collection The collection to iterate over.
10264 * @param {Function} callback The function called per iteration.
10265 * @returns {Array|Object|string} Returns `collection`.
10267 function baseEach(collection, callback) {
10269 iterable = collection,
10270 length = collection ? collection.length : 0;
10272 if (typeof length == 'number') {
10273 if (support.unindexedChars && isString(iterable)) {
10274 iterable = iterable.split('');
10276 while (++index < length) {
10277 if (callback(iterable[index], index, collection) === false) {
10282 baseForOwn(collection, callback);
10288 * The base implementation of `_.forEachRight` without support for callback
10289 * shorthands or `thisArg` binding.
10292 * @param {Array|Object|string} collection The collection to iterate over.
10293 * @param {Function} callback The function called per iteration.
10294 * @returns {Array|Object|string} Returns `collection`.
10296 function baseEachRight(collection, callback) {
10297 var iterable = collection,
10298 length = collection ? collection.length : 0;
10300 if (typeof length == 'number') {
10301 if (support.unindexedChars && isString(iterable)) {
10302 iterable = iterable.split('');
10305 if (callback(iterable[length], length, collection) === false) {
10310 baseForOwnRight(collection, callback);
10316 * The base implementation of `_.flatten` without support for callback
10317 * shorthands or `thisArg` binding.
10320 * @param {Array} array The array to flatten.
10321 * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
10322 * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects.
10323 * @param {number} [fromIndex=0] The index to start from.
10324 * @returns {Array} Returns a new flattened array.
10326 function baseFlatten(array, isShallow, isStrict, fromIndex) {
10327 var index = (fromIndex || 0) - 1,
10328 length = array ? array.length : 0,
10331 while (++index < length) {
10332 var value = array[index];
10334 if (value && typeof value == 'object' && typeof value.length == 'number'
10335 && (isArray(value) || isArguments(value))) {
10336 // recursively flatten arrays (susceptible to call stack limits)
10338 value = baseFlatten(value, isShallow, isStrict);
10341 valLength = value.length,
10342 resIndex = result.length;
10344 result.length += valLength;
10345 while (++valIndex < valLength) {
10346 result[resIndex++] = value[valIndex];
10348 } else if (!isStrict) {
10349 result.push(value);
10356 * The base implementation of `_.forOwn` without support for callback
10357 * shorthands or `thisArg` binding.
10360 * @param {Object} object The object to iterate over.
10361 * @param {Function} callback The function called per iteration.
10362 * @returns {Object} Returns `object`.
10364 function baseForOwn(object, callback) {
10366 props = keys(object),
10367 length = props.length;
10369 while (++index < length) {
10370 var key = props[index];
10371 if (callback(object[key], key, object) === false) {
10379 * The base implementation of `_.forOwnRight` without support for callback
10380 * shorthands or `thisArg` binding.
10383 * @param {Object} object The object to iterate over.
10384 * @param {Function} callback The function called per iteration.
10385 * @returns {Object} Returns `object`.
10387 function baseForOwnRight(object, callback) {
10388 var props = keys(object),
10389 length = props.length;
10392 var key = props[length];
10393 if (callback(object[key], key, object) === false) {
10401 * The base implementation of `_.isEqual`, without support for `thisArg` binding,
10402 * that allows partial "_.where" style comparisons.
10405 * @param {*} a The value to compare.
10406 * @param {*} b The other value to compare.
10407 * @param {Function} [callback] The function to customize comparing values.
10408 * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
10409 * @param {Array} [stackA=[]] Tracks traversed `a` objects.
10410 * @param {Array} [stackB=[]] Tracks traversed `b` objects.
10411 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
10413 function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
10414 // used to indicate that when comparing objects, `a` has at least the properties of `b`
10416 var result = callback(a, b);
10417 if (typeof result != 'undefined') {
10421 // exit early for identical values
10423 // treat `+0` vs. `-0` as not equal
10424 return a !== 0 || (1 / a == 1 / b);
10426 var type = typeof a,
10427 otherType = typeof b;
10429 // exit early for unlike primitive values
10431 !(a && (type == 'function' || type == 'object')) &&
10432 !(b && (otherType == 'function' || otherType == 'object'))) {
10435 // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
10436 // http://es5.github.io/#x15.3.4.4
10437 if (a == null || b == null) {
10440 // compare [[Class]] names
10441 var className = toString.call(a),
10442 otherClass = toString.call(b);
10444 if (className == argsClass) {
10445 className = objectClass;
10447 if (otherClass == argsClass) {
10448 otherClass = objectClass;
10450 if (className != otherClass) {
10453 switch (className) {
10456 // coerce dates and booleans to numbers, dates to milliseconds and booleans
10457 // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
10461 // treat `NaN` vs. `NaN` as equal
10464 // but treat `+0` vs. `-0` as not equal
10465 : (a == 0 ? (1 / a == 1 / b) : a == +b);
10469 // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
10470 // treat string primitives and their corresponding object instances as equal
10471 return a == String(b);
10473 var isArr = className == arrayClass;
10475 // unwrap any `lodash` wrapped values
10476 var aWrapped = hasOwnProperty.call(a, '__wrapped__'),
10477 bWrapped = hasOwnProperty.call(b, '__wrapped__');
10479 if (aWrapped || bWrapped) {
10480 return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB);
10482 // exit for functions and DOM nodes
10483 if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) {
10486 // in older versions of Opera, `arguments` objects have `Array` constructors
10487 var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor,
10488 ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor;
10490 // non `Object` object instances with different constructors are not equal
10491 if (ctorA != ctorB &&
10492 !(hasOwnProperty.call(a, 'constructor') && hasOwnProperty.call(b, 'constructor')) &&
10493 !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) &&
10494 ('constructor' in a && 'constructor' in b)
10499 // assume cyclic structures are equal
10500 // the algorithm for detecting cyclic structures is adapted from ES 5.1
10501 // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
10502 var initedStack = !stackA;
10503 stackA || (stackA = getArray());
10504 stackB || (stackB = getArray());
10506 var length = stackA.length;
10508 if (stackA[length] == a) {
10509 return stackB[length] == b;
10515 // add `a` and `b` to the stack of traversed objects
10519 // recursively compare objects and arrays (susceptible to call stack limits)
10521 // compare lengths to determine if a deep comparison is necessary
10524 result = size == length;
10526 if (result || isWhere) {
10527 // deep compare the contents, ignoring non-numeric properties
10529 var index = length,
10534 if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
10538 } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
10545 // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
10546 // which, in this case, is more costly
10547 baseForIn(b, function(value, key, b) {
10548 if (hasOwnProperty.call(b, key)) {
10549 // count the number of properties.
10551 // deep compare each property value.
10552 return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
10556 if (result && !isWhere) {
10557 // ensure both objects have the same number of properties
10558 baseForIn(a, function(value, key, a) {
10559 if (hasOwnProperty.call(a, key)) {
10560 // `size` will be `-1` if `a` has more properties than `b`
10561 return (result = --size > -1);
10570 releaseArray(stackA);
10571 releaseArray(stackB);
10577 * The base implementation of `_.merge` without argument juggling or support
10578 * for `thisArg` binding.
10581 * @param {Object} object The destination object.
10582 * @param {Object} source The source object.
10583 * @param {Function} [callback] The function to customize merging properties.
10584 * @param {Array} [stackA=[]] Tracks traversed source objects.
10585 * @param {Array} [stackB=[]] Associates values with source counterparts.
10587 function baseMerge(object, source, callback, stackA, stackB) {
10588 (isArray(source) ? baseEach : baseForOwn)(source, function(source, key) {
10592 value = object[key];
10594 if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
10595 // avoid merging previously merged cyclic sources
10596 var stackLength = stackA.length;
10597 while (stackLength--) {
10598 if ((found = stackA[stackLength] == source)) {
10599 value = stackB[stackLength];
10606 result = callback(value, source);
10607 if ((isShallow = typeof result != 'undefined')) {
10613 ? (isArray(value) ? value : [])
10614 : (isPlainObject(value) ? value : {});
10616 // add `source` and associated `value` to the stack of traversed objects
10617 stackA.push(source);
10618 stackB.push(value);
10620 // recursively merge objects and arrays (susceptible to call stack limits)
10622 baseMerge(value, source, callback, stackA, stackB);
10628 result = callback(value, source);
10629 if (typeof result == 'undefined') {
10633 if (typeof result != 'undefined') {
10637 object[key] = value;
10642 * The base implementation of `_.random` without argument juggling or support
10643 * for returning floating-point numbers.
10646 * @param {number} min The minimum possible value.
10647 * @param {number} max The maximum possible value.
10648 * @returns {number} Returns a random number.
10650 function baseRandom(min, max) {
10651 return min + floor(nativeRandom() * (max - min + 1));
10655 * The base implementation of `_.uniq` without support for callback shorthands
10656 * or `thisArg` binding.
10659 * @param {Array} array The array to process.
10660 * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
10661 * @param {Function} [callback] The function called per iteration.
10662 * @returns {Array} Returns a duplicate-value-free array.
10664 function baseUniq(array, isSorted, callback) {
10666 indexOf = getIndexOf(),
10667 length = array ? array.length : 0,
10668 isLarge = createCache && !isSorted && indexOf === baseIndexOf && length >= LARGE_ARRAY_SIZE,
10672 var seen = createCache();
10673 indexOf = cacheIndexOf;
10675 seen = callback ? getArray() : result;
10677 while (++index < length) {
10678 var value = array[index],
10679 computed = callback ? callback(value, index, array) : value;
10682 ? !index || seen[seen.length - 1] !== computed
10683 : indexOf(seen, computed) < 0
10685 if (callback || isLarge) {
10686 seen.push(computed);
10688 result.push(value);
10691 if (!isLarge && callback) {
10692 releaseArray(seen);
10698 * Creates a function that aggregates a collection, creating an object or
10699 * array composed from the results of running each element of the collection
10700 * through a callback. The given `setter` function sets the keys and values
10701 * of the composed object or array.
10704 * @param {Function} setter The setter function.
10705 * @param {boolean} [retArray=false] A flag to indicate that the aggregator
10706 * function should return an array.
10707 * @returns {Function} Returns the new aggregator function.
10709 function createAggregator(setter, retArray) {
10710 return function(collection, callback, thisArg) {
10711 var result = retArray ? [[], []] : {};
10713 callback = lodash.createCallback(callback, thisArg, 3);
10714 if (isArray(collection)) {
10716 length = collection.length;
10718 while (++index < length) {
10719 var value = collection[index];
10720 setter(result, value, callback(value, index, collection), collection);
10723 baseEach(collection, function(value, key, collection) {
10724 setter(result, value, callback(value, key, collection), collection);
10732 * Creates a cache object to optimize linear searches of large arrays.
10735 * @param {Array} [array=[]] The array to search.
10736 * @returns {Object} Returns the cache object.
10738 var createCache = Set && function(array) {
10739 var cache = new Set,
10740 length = array ? array.length : 0;
10742 cache.push = cache.add;
10744 cache.push(array[length]);
10750 * Creates a function that, when called, either curries or invokes `func`
10751 * with an optional `this` binding and partially applied arguments.
10754 * @param {Function|string} func The function or method name to reference.
10755 * @param {number} bitmask The bitmask of flags to compose.
10756 * The bitmask may be composed of the following flags:
10760 * 8 - `_.curry` (bound)
10762 * 32 - `_.partialRight`
10763 * @param {number} [arity] The arity of `func`.
10764 * @param {*} [thisArg] The `this` binding of `func`.
10765 * @param {Array} [partialArgs] An array of arguments to prepend to those
10766 * provided to the new function.
10767 * @param {Array} [partialRightArgs] An array of arguments to append to those
10768 * provided to the new function.
10769 * @returns {Function} Returns the new function.
10771 function createWrapper(func, bitmask, arity, thisArg, partialArgs, partialRightArgs) {
10772 var isBind = bitmask & BIND_FLAG,
10773 isBindKey = bitmask & BIND_KEY_FLAG,
10774 isPartial = bitmask & PARTIAL_FLAG,
10775 isPartialRight = bitmask & PARTIAL_RIGHT_FLAG;
10777 if (!isBindKey && !isFunction(func)) {
10778 throw new TypeError;
10780 if (isPartial && !partialArgs.length) {
10781 bitmask &= ~PARTIAL_FLAG;
10782 isPartial = partialArgs = false;
10784 if (isPartialRight && !partialRightArgs.length) {
10785 bitmask &= ~PARTIAL_RIGHT_FLAG;
10786 isPartialRight = partialRightArgs = false;
10788 var data = !isBindKey && func[expando];
10789 if (data && data !== true) {
10790 // shallow clone `data`
10791 data = slice(data);
10793 // clone partial left arguments
10795 data[4] = slice(data[4]);
10797 // clone partial right arguments
10799 data[5] = slice(data[5]);
10801 // set arity if provided
10802 if (typeof arity == 'number') {
10805 // set `thisArg` if not previously bound
10806 var bound = data[1] & BIND_FLAG;
10807 if (isBind && !bound) {
10810 // set if currying a bound function
10811 if (!isBind && bound) {
10812 bitmask |= CURRY_BOUND_FLAG;
10814 // append partial left arguments
10817 push.apply(data[4], partialArgs);
10819 data[4] = partialArgs;
10822 // prepend partial right arguments
10823 if (isPartialRight) {
10825 unshift.apply(data[5], partialRightArgs);
10827 data[5] = partialRightArgs;
10831 data[1] |= bitmask;
10832 return createWrapper.apply(null, data);
10834 if (arity == null) {
10835 arity = isBindKey ? 0 : func.length;
10836 } else if (arity < 0) {
10839 // fast path for `_.bind`
10840 data = [func, bitmask, arity, thisArg, partialArgs, partialRightArgs];
10841 return (bitmask == BIND_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG))
10843 : baseCreateWrapper(data);
10847 * Creates compiled iteration functions.
10850 * @param {Object} [options] The compile options object.
10851 * @param {string} [options.args] A comma separated string of iteration function arguments.
10852 * @param {string} [options.init] The string representation of the initial `result` value.
10853 * @param {string} [options.loop] Code to execute in the object loop.
10854 * @param {boolean} [options.useHas] Specify using `hasOwnProperty` checks in the object loop.
10855 * @returns {Function} Returns the compiled function.
10857 function createIterator(options) {
10858 options.shadowedProps = shadowedProps;
10859 options.support = support;
10861 // create the function factory
10862 var factory = Function(
10863 'errorClass, errorProto, hasOwnProperty, isArguments, isObject, objectProto, ' +
10864 'nonEnumProps, stringClass, stringProto, toString',
10865 'return function(' + options.args + ') {\n' + iteratorTemplate(options) + '\n}'
10868 // return the compiled function
10870 errorClass, errorProto, hasOwnProperty, isArguments, isObject, objectProto,
10871 nonEnumProps, stringClass, stringProto, toString
10876 * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
10877 * customized this method returns the custom method, otherwise it returns
10878 * the `baseIndexOf` function.
10881 * @returns {Function} Returns the "indexOf" function.
10883 function getIndexOf() {
10884 var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
10889 * Checks if `value` is a native function.
10892 * @param {*} value The value to check.
10893 * @returns {boolean} Returns `true` if the `value` is a native function, else `false`.
10895 function isNative(value) {
10896 return typeof value == 'function' && reNative.test(fnToString.call(value));
10900 * Sets wrapper metadata on a given function.
10903 * @param {Function} func The function to set data on.
10904 * @param {Array} value The data array to set.
10906 var setData = !defineProperty ? noop : function(func, value) {
10907 descriptor.value = value;
10908 defineProperty(func, expando, descriptor);
10912 * A fallback implementation of `isPlainObject` which checks if a given value
10913 * is an object created by the `Object` constructor, assuming objects created
10914 * by the `Object` constructor have no inherited enumerable properties and that
10915 * there are no `Object.prototype` extensions.
10918 * @param {*} value The value to check.
10919 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
10921 function shimIsPlainObject(value) {
10925 // avoid non Object objects, `arguments` objects, and DOM elements
10926 if (!(value && toString.call(value) == objectClass) ||
10927 (!hasOwnProperty.call(value, 'constructor') &&
10928 (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor))) ||
10929 (!support.argsClass && isArguments(value)) ||
10930 (!support.nodeClass && isNode(value))) {
10933 // IE < 9 iterates inherited properties before own properties. If the first
10934 // iterated property is an object's own property then there are no inherited
10935 // enumerable properties.
10936 if (support.ownLast) {
10937 baseForIn(value, function(value, key, object) {
10938 result = hasOwnProperty.call(object, key);
10941 return result !== false;
10943 // In most environments an object's own properties are iterated before
10944 // its inherited properties. If the last iterated property is an object's
10945 // own property then there are no inherited enumerable properties.
10946 baseForIn(value, function(value, key) {
10949 return typeof result == 'undefined' || hasOwnProperty.call(value, result);
10952 /*--------------------------------------------------------------------------*/
10955 * Checks if `value` is an `arguments` object.
10959 * @category Objects
10960 * @param {*} value The value to check.
10961 * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
10964 * (function() { return _.isArguments(arguments); })(1, 2, 3);
10967 * _.isArguments([1, 2, 3]);
10970 function isArguments(value) {
10971 return value && typeof value == 'object' && typeof value.length == 'number' &&
10972 toString.call(value) == argsClass || false;
10974 // fallback for environments that can't detect `arguments` objects by [[Class]]
10975 if (!support.argsClass) {
10976 isArguments = function(value) {
10977 return value && typeof value == 'object' && typeof value.length == 'number' &&
10978 hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee') || false;
10983 * The base implementation of `_.forIn` without support for callback
10984 * shorthands or `thisArg` binding.
10987 * @param {Object} object The object to iterate over.
10988 * @param {Function} callback The function called per iteration.
10989 * @returns {Object} Returns `object`.
10991 var baseForIn = createIterator({
10992 'args': 'object, callback',
10994 'loop': 'if (callback(object[key], key, object) === false) {\n return result;\n }',
10999 * A fallback implementation of `Object.keys` which produces an array of the
11000 * given object's own enumerable property names.
11004 * @param {Object} object The object to inspect.
11005 * @returns {Array} Returns an array of property names.
11007 var shimKeys = createIterator({
11010 'loop': 'result.push(key)',
11014 /*--------------------------------------------------------------------------*/
11017 * Creates an array with all falsey values removed. The values `false`, `null`,
11018 * `0`, `""`, `undefined`, and `NaN` are all falsey.
11023 * @param {Array} array The array to compact.
11024 * @returns {Array} Returns a new array of filtered values.
11027 * _.compact([0, 1, false, 2, '', 3]);
11030 function compact(array) {
11032 length = array ? array.length : 0,
11036 while (++index < length) {
11037 var value = array[index];
11039 result[resIndex++] = value;
11046 * Creates an array excluding all values of the provided arrays using strict
11047 * equality for comparisons, i.e. `===`.
11052 * @param {Array} array The array to process.
11053 * @param {...Array} [values] The arrays of values to exclude.
11054 * @returns {Array} Returns a new array of filtered values.
11057 * _.difference([1, 2, 3], [5, 2, 10]);
11060 function difference(array) {
11061 return baseDifference(array, baseFlatten(arguments, true, true, 1));
11065 * This method is like `_.find` except that it returns the index of the first
11066 * element that passes the callback check, instead of the element itself.
11068 * If a property name is provided for `callback` the created "_.pluck" style
11069 * callback will return the property value of the given element.
11071 * If an object is provided for `callback` the created "_.where" style callback
11072 * will return `true` for elements that have the properties of the given object,
11078 * @param {Array} array The array to search.
11079 * @param {Function|Object|string} [callback=identity] The function called
11080 * per iteration. If a property name or object is provided it will be used
11081 * to create a "_.pluck" or "_.where" style callback, respectively.
11082 * @param {*} [thisArg] The `this` binding of `callback`.
11083 * @returns {number} Returns the index of the found element, else `-1`.
11086 * var characters = [
11087 * { 'name': 'barney', 'age': 36 },
11088 * { 'name': 'fred', 'age': 40, 'blocked': true },
11089 * { 'name': 'pebbles', 'age': 1 }
11092 * _.findIndex(characters, function(chr) {
11093 * return chr.age < 20;
11097 * // using "_.where" callback shorthand
11098 * _.findIndex(characters, { 'age': 36 });
11101 * // using "_.pluck" callback shorthand
11102 * _.findIndex(characters, 'blocked');
11105 function findIndex(array, callback, thisArg) {
11107 length = array ? array.length : 0;
11109 callback = lodash.createCallback(callback, thisArg, 3);
11110 while (++index < length) {
11111 if (callback(array[index], index, array)) {
11119 * This method is like `_.findIndex` except that it iterates over elements
11120 * of a `collection` from right to left.
11122 * If a property name is provided for `callback` the created "_.pluck" style
11123 * callback will return the property value of the given element.
11125 * If an object is provided for `callback` the created "_.where" style callback
11126 * will return `true` for elements that have the properties of the given object,
11132 * @param {Array} array The array to search.
11133 * @param {Function|Object|string} [callback=identity] The function called
11134 * per iteration. If a property name or object is provided it will be used
11135 * to create a "_.pluck" or "_.where" style callback, respectively.
11136 * @param {*} [thisArg] The `this` binding of `callback`.
11137 * @returns {number} Returns the index of the found element, else `-1`.
11140 * var characters = [
11141 * { 'name': 'barney', 'age': 36, 'blocked': true },
11142 * { 'name': 'fred', 'age': 40 },
11143 * { 'name': 'pebbles', 'age': 1, 'blocked': true }
11146 * _.findLastIndex(characters, function(chr) {
11147 * return chr.age > 30;
11151 * // using "_.where" callback shorthand
11152 * _.findLastIndex(characters, { 'age': 36 });
11155 * // using "_.pluck" callback shorthand
11156 * _.findLastIndex(characters, 'blocked');
11159 function findLastIndex(array, callback, thisArg) {
11160 var length = array ? array.length : 0;
11162 callback = lodash.createCallback(callback, thisArg, 3);
11164 if (callback(array[length], length, array)) {
11172 * Gets the first element or first `n` elements of an array. If a callback
11173 * is provided elements at the beginning of the array are returned as long
11174 * as the callback returns truey. The callback is bound to `thisArg` and
11175 * invoked with three arguments; (value, index, array).
11177 * If a property name is provided for `callback` the created "_.pluck" style
11178 * callback will return the property value of the given element.
11180 * If an object is provided for `callback` the created "_.where" style callback
11181 * will return `true` for elements that have the properties of the given object,
11186 * @alias head, take
11188 * @param {Array} array The array to query.
11189 * @param {Function|Object|number|string} [callback] The function called
11190 * per element or the number of elements to return. If a property name or
11191 * object is provided it will be used to create a "_.pluck" or "_.where"
11192 * style callback, respectively.
11193 * @param {*} [thisArg] The `this` binding of `callback`.
11194 * @returns {*} Returns the first element(s) of `array`.
11197 * _.first([1, 2, 3]);
11200 * // returns the first two elements
11201 * _.first([1, 2, 3], 2);
11204 * // returns elements from the beginning until the callback result is falsey
11205 * _.first([1, 2, 3], function(num) {
11210 * var characters = [
11211 * { 'name': 'barney', 'employer': 'slate', 'blocked': true },
11212 * { 'name': 'fred', 'employer': 'slate' },
11213 * { 'name': 'pebbles', 'employer': 'na', 'blocked': true }
11216 * // using "_.pluck" callback shorthand
11217 * _.first(characters, 'blocked');
11218 * // => [{ 'name': 'barney', 'employer': 'slate', 'blocked': true }]
11220 * // using "_.where" callback shorthand
11221 * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name');
11222 * // => ['barney', 'fred']
11224 function first(array, callback, thisArg) {
11226 length = array ? array.length : 0;
11228 if (typeof callback != 'number' && callback != null) {
11230 callback = lodash.createCallback(callback, thisArg, 3);
11231 while (++index < length && callback(array[index], index, array)) {
11236 if (n == null || thisArg) {
11237 return array ? array[0] : undefined;
11240 return slice(array, 0, n > 0 ? n : 0);
11244 * Flattens a nested array (the nesting can be to any depth). If `isShallow`
11245 * is truey, the array will only be flattened a single level. If a callback
11246 * is provided each element of the array is passed through the callback before
11247 * flattening. The callback is bound to `thisArg` and invoked with three
11248 * arguments; (value, index, array).
11250 * If a property name is provided for `callback` the created "_.pluck" style
11251 * callback will return the property value of the given element.
11253 * If an object is provided for `callback` the created "_.where" style callback
11254 * will return `true` for elements that have the properties of the given object,
11260 * @param {Array} array The array to flatten.
11261 * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
11262 * @param {Function|Object|string} [callback=identity] The function called
11263 * per iteration. If a property name or object is provided it will be used
11264 * to create a "_.pluck" or "_.where" style callback, respectively.
11265 * @param {*} [thisArg] The `this` binding of `callback`.
11266 * @returns {Array} Returns a new flattened array.
11269 * _.flatten([1, [2], [3, [[4]]]]);
11270 * // => [1, 2, 3, 4];
11272 * // using `isShallow`
11273 * _.flatten([1, [2], [3, [[4]]]], true);
11274 * // => [1, 2, 3, [[4]]];
11276 * var characters = [
11277 * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] },
11278 * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
11281 * // using "_.pluck" callback shorthand
11282 * _.flatten(characters, 'pets');
11283 * // => ['hoppy', 'baby puss', 'dino']
11285 function flatten(array, isShallow, callback, thisArg) {
11286 var type = typeof isShallow;
11288 // juggle arguments
11289 if (type != 'boolean' && isShallow != null) {
11290 thisArg = callback;
11291 callback = isShallow;
11294 // enables use as a callback for functions like `_.map`
11295 if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === array) {
11299 if (callback != null) {
11300 array = map(array, callback, thisArg);
11302 return baseFlatten(array, isShallow);
11306 * Gets the index at which the first occurrence of `value` is found using
11307 * strict equality for comparisons, i.e. `===`. If the array is already sorted
11308 * providing `true` for `fromIndex` will run a faster binary search.
11313 * @param {Array} array The array to search.
11314 * @param {*} value The value to search for.
11315 * @param {boolean|number} [fromIndex=0] The index to search from or `true`
11316 * to perform a binary search on a sorted array.
11317 * @returns {number} Returns the index of the matched value or `-1`.
11320 * _.indexOf([1, 2, 3, 1, 2, 3], 2);
11323 * // using `fromIndex`
11324 * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
11327 * // performing a binary search
11328 * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
11331 function indexOf(array, value, fromIndex) {
11332 var length = array ? array.length : 0;
11333 if (typeof fromIndex == 'number') {
11334 fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
11335 } else if (fromIndex) {
11336 var index = sortedIndex(array, value);
11337 return (length && array[index] === value) ? index : -1;
11339 return baseIndexOf(array, value, fromIndex);
11343 * Gets all but the last element or last `n` elements of an array. If a
11344 * callback is provided elements at the end of the array are excluded from
11345 * the result as long as the callback returns truey. The callback is bound
11346 * to `thisArg` and invoked with three arguments; (value, index, array).
11348 * If a property name is provided for `callback` the created "_.pluck" style
11349 * callback will return the property value of the given element.
11351 * If an object is provided for `callback` the created "_.where" style callback
11352 * will return `true` for elements that have the properties of the given object,
11358 * @param {Array} array The array to query.
11359 * @param {Function|Object|number|string} [callback=1] The function called
11360 * per element or the number of elements to exclude. If a property name or
11361 * object is provided it will be used to create a "_.pluck" or "_.where"
11362 * style callback, respectively.
11363 * @param {*} [thisArg] The `this` binding of `callback`.
11364 * @returns {Array} Returns a slice of `array`.
11367 * _.initial([1, 2, 3]);
11370 * // excludes the last two elements
11371 * _.initial([1, 2, 3], 2);
11374 * // excludes elements from the end until the callback fails
11375 * _.initial([1, 2, 3], function(num) {
11380 * var characters = [
11381 * { 'name': 'barney', 'employer': 'slate' },
11382 * { 'name': 'fred', 'employer': 'slate', 'blocked': true },
11383 * { 'name': 'pebbles', 'employer': 'na', 'blocked': true }
11386 * // using "_.pluck" callback shorthand
11387 * _.initial(characters, 'blocked');
11388 * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }]
11390 * // using "_.where" callback shorthand
11391 * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name');
11392 * // => ['barney', 'fred']
11394 function initial(array, callback, thisArg) {
11396 length = array ? array.length : 0;
11398 if (typeof callback != 'number' && callback != null) {
11399 var index = length;
11400 callback = lodash.createCallback(callback, thisArg, 3);
11401 while (index-- && callback(array[index], index, array)) {
11405 n = (callback == null || thisArg) ? 1 : callback || n;
11408 return slice(array, 0, n > 0 ? n : 0);
11412 * Creates an array of unique values present in all provided arrays using
11413 * strict equality for comparisons, i.e. `===`.
11418 * @param {...Array} [array] The arrays to inspect.
11419 * @returns {Array} Returns an array of shared values.
11422 * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]);
11425 function intersection() {
11428 argsLength = arguments.length,
11429 caches = getArray(),
11430 indexOf = getIndexOf(),
11431 largePrereq = createCache && indexOf === baseIndexOf,
11434 while (++argsIndex < argsLength) {
11435 var value = arguments[argsIndex];
11436 if (isArray(value) || isArguments(value)) {
11438 caches.push(largePrereq && value.length >= LARGE_ARRAY_SIZE &&
11439 createCache(argsIndex ? args[argsIndex] : seen));
11442 var array = args[0],
11444 length = array ? array.length : 0,
11448 while (++index < length) {
11449 var cache = caches[0];
11450 value = array[index];
11452 if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
11453 argsIndex = argsLength;
11454 (cache || seen).push(value);
11455 while (--argsIndex) {
11456 cache = caches[argsIndex];
11457 if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
11461 result.push(value);
11464 releaseArray(caches);
11465 releaseArray(seen);
11470 * Gets the last element or last `n` elements of an array. If a callback is
11471 * provided elements at the end of the array are returned as long as the
11472 * callback returns truey. The callback is bound to `thisArg` and invoked
11473 * with three arguments; (value, index, array).
11475 * If a property name is provided for `callback` the created "_.pluck" style
11476 * callback will return the property value of the given element.
11478 * If an object is provided for `callback` the created "_.where" style callback
11479 * will return `true` for elements that have the properties of the given object,
11485 * @param {Array} array The array to query.
11486 * @param {Function|Object|number|string} [callback] The function called
11487 * per element or the number of elements to return. If a property name or
11488 * object is provided it will be used to create a "_.pluck" or "_.where"
11489 * style callback, respectively.
11490 * @param {*} [thisArg] The `this` binding of `callback`.
11491 * @returns {*} Returns the last element(s) of `array`.
11494 * _.last([1, 2, 3]);
11497 * // returns the last two elements
11498 * _.last([1, 2, 3], 2);
11501 * // returns elements from the end until the callback fails
11502 * _.last([1, 2, 3], function(num) {
11507 * var characters = [
11508 * { 'name': 'barney', 'employer': 'slate' },
11509 * { 'name': 'fred', 'employer': 'slate', 'blocked': true },
11510 * { 'name': 'pebbles', 'employer': 'na', 'blocked': true }
11513 * // using "_.pluck" callback shorthand
11514 * _.pluck(_.last(characters, 'blocked'), 'name');
11515 * // => ['fred', 'pebbles']
11517 * // using "_.where" callback shorthand
11518 * _.last(characters, { 'employer': 'na' });
11519 * // => [{ 'name': 'pebbles', 'employer': 'na', 'blocked': true }]
11521 function last(array, callback, thisArg) {
11523 length = array ? array.length : 0;
11525 if (typeof callback != 'number' && callback != null) {
11526 var index = length;
11527 callback = lodash.createCallback(callback, thisArg, 3);
11528 while (index-- && callback(array[index], index, array)) {
11533 if (n == null || thisArg) {
11534 return array ? array[length - 1] : undefined;
11538 return slice(array, n > 0 ? n : 0);
11542 * Gets the index at which the last occurrence of `value` is found using strict
11543 * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
11544 * as the offset from the end of the collection.
11546 * If a property name is provided for `callback` the created "_.pluck" style
11547 * callback will return the property value of the given element.
11549 * If an object is provided for `callback` the created "_.where" style callback
11550 * will return `true` for elements that have the properties of the given object,
11556 * @param {Array} array The array to search.
11557 * @param {*} value The value to search for.
11558 * @param {number} [fromIndex=array.length-1] The index to search from.
11559 * @returns {number} Returns the index of the matched value or `-1`.
11562 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
11565 * // using `fromIndex`
11566 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
11569 function lastIndexOf(array, value, fromIndex) {
11570 var index = array ? array.length : 0;
11571 if (typeof fromIndex == 'number') {
11572 index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
11575 if (array[index] === value) {
11583 * Removes all provided values from `array` using strict equality for
11584 * comparisons, i.e. `===`.
11589 * @param {Array} array The array to modify.
11590 * @param {...*} [value] The values to remove.
11591 * @returns {Array} Returns `array`.
11594 * var array = [1, 2, 3, 1, 2, 3];
11595 * _.pull(array, 2, 3);
11596 * console.log(array);
11599 function pull(array) {
11600 var args = arguments,
11602 argsLength = args.length,
11603 length = array ? array.length : 0;
11605 while (++argsIndex < argsLength) {
11607 value = args[argsIndex];
11609 while (++index < length) {
11610 if (array[index] === value) {
11611 splice.call(array, index--, 1);
11620 * Creates an array of numbers (positive and/or negative) progressing from
11621 * `start` up to but not including `end`. If `start` is less than `stop` a
11622 * zero-length range is created unless a negative `step` is specified.
11627 * @param {number} [start=0] The start of the range.
11628 * @param {number} end The end of the range.
11629 * @param {number} [step=1] The value to increment or decrement by.
11630 * @returns {Array} Returns a new range array.
11634 * // => [0, 1, 2, 3]
11637 * // => [1, 2, 3, 4]
11639 * _.range(0, 20, 5);
11640 * // => [0, 5, 10, 15]
11642 * _.range(0, -4, -1);
11643 * // => [0, -1, -2, -3]
11645 * _.range(1, 4, 0);
11651 function range(start, end, step) {
11652 start = +start || 0;
11653 step = typeof step == 'number' ? step : (+step || 1);
11659 // use `Array(length)` so engines like Chakra and V8 avoid slower modes
11660 // http://youtu.be/XAqIpGU8ZZk#t=17m25s
11662 length = nativeMax(0, ceil((end - start) / (step || 1))),
11663 result = Array(length);
11665 while (++index < length) {
11666 result[index] = start;
11673 * Removes all elements from an array that the callback returns truey for
11674 * and returns an array of removed elements. The callback is bound to `thisArg`
11675 * and invoked with three arguments; (value, index, array).
11677 * If a property name is provided for `callback` the created "_.pluck" style
11678 * callback will return the property value of the given element.
11680 * If an object is provided for `callback` the created "_.where" style callback
11681 * will return `true` for elements that have the properties of the given object,
11687 * @param {Array} array The array to modify.
11688 * @param {Function|Object|string} [callback=identity] The function called
11689 * per iteration. If a property name or object is provided it will be used
11690 * to create a "_.pluck" or "_.where" style callback, respectively.
11691 * @param {*} [thisArg] The `this` binding of `callback`.
11692 * @returns {Array} Returns a new array of removed elements.
11695 * var array = [1, 2, 3, 4, 5, 6];
11696 * var evens = _.remove(array, function(num) { return num % 2 == 0; });
11698 * console.log(array);
11701 * console.log(evens);
11704 function remove(array, callback, thisArg) {
11706 length = array ? array.length : 0,
11709 callback = lodash.createCallback(callback, thisArg, 3);
11710 while (++index < length) {
11711 var value = array[index];
11712 if (callback(value, index, array)) {
11713 result.push(value);
11714 splice.call(array, index--, 1);
11722 * The opposite of `_.initial`; this method gets all but the first element or
11723 * first `n` elements of an array. If a callback function is provided elements
11724 * at the beginning of the array are excluded from the result as long as the
11725 * callback returns truey. The callback is bound to `thisArg` and invoked
11726 * with three arguments; (value, index, array).
11728 * If a property name is provided for `callback` the created "_.pluck" style
11729 * callback will return the property value of the given element.
11731 * If an object is provided for `callback` the created "_.where" style callback
11732 * will return `true` for elements that have the properties of the given object,
11737 * @alias drop, tail
11739 * @param {Array} array The array to query.
11740 * @param {Function|Object|number|string} [callback=1] The function called
11741 * per element or the number of elements to exclude. If a property name or
11742 * object is provided it will be used to create a "_.pluck" or "_.where"
11743 * style callback, respectively.
11744 * @param {*} [thisArg] The `this` binding of `callback`.
11745 * @returns {Array} Returns a slice of `array`.
11748 * _.rest([1, 2, 3]);
11751 * // excludes the first two elements
11752 * _.rest([1, 2, 3], 2);
11755 * // excludes elements from the beginning until the callback fails
11756 * _.rest([1, 2, 3], function(num) {
11761 * var characters = [
11762 * { 'name': 'barney', 'employer': 'slate', 'blocked': true },
11763 * { 'name': 'fred', 'employer': 'slate' },
11764 * { 'name': 'pebbles', 'employer': 'na', 'blocked': true }
11767 * // using "_.pluck" callback shorthand
11768 * _.pluck(_.rest(characters, 'blocked'), 'name');
11769 * // => ['fred', 'pebbles']
11771 * // using "_.where" callback shorthand
11772 * _.rest(characters, { 'employer': 'slate' });
11773 * // => [{ 'name': 'pebbles', 'employer': 'na', 'blocked': true }]
11775 function rest(array, callback, thisArg) {
11776 if (typeof callback != 'number' && callback != null) {
11779 length = array ? array.length : 0;
11781 callback = lodash.createCallback(callback, thisArg, 3);
11782 while (++index < length && callback(array[index], index, array)) {
11785 } else if (callback == null || thisArg) {
11788 n = callback > 0 ? callback : 0;
11790 return slice(array, n);
11794 * Slices `array` from the `start` index up to, but not including, the `end` index.
11796 * Note: This function is used instead of `Array#slice` to support node lists
11797 * in IE < 9 and to ensure dense arrays are returned.
11802 * @param {Array} array The array to slice.
11803 * @param {number} [start=0] The start index.
11804 * @param {number} [end=array.length] The end index.
11805 * @returns {Array} Returns the new array.
11807 function slice(array, start, end) {
11809 length = array ? array.length : 0;
11811 if (typeof start == 'undefined') {
11813 } else if (start < 0) {
11814 start = nativeMax(length + start, 0);
11815 } else if (start > length) {
11818 if (typeof end == 'undefined') {
11820 } else if (end < 0) {
11821 end = nativeMax(length + end, 0);
11822 } else if (end > length) {
11825 length = end - start || 0;
11827 var result = Array(length);
11828 while (++index < length) {
11829 result[index] = array[start + index];
11835 * Uses a binary search to determine the smallest index at which a value
11836 * should be inserted into a given sorted array in order to maintain the sort
11837 * order of the array. If a callback is provided it will be executed for
11838 * `value` and each element of `array` to compute their sort ranking. The
11839 * callback is bound to `thisArg` and invoked with one argument; (value).
11841 * If a property name is provided for `callback` the created "_.pluck" style
11842 * callback will return the property value of the given element.
11844 * If an object is provided for `callback` the created "_.where" style callback
11845 * will return `true` for elements that have the properties of the given object,
11851 * @param {Array} array The array to inspect.
11852 * @param {*} value The value to evaluate.
11853 * @param {Function|Object|string} [callback=identity] The function called
11854 * per iteration. If a property name or object is provided it will be used
11855 * to create a "_.pluck" or "_.where" style callback, respectively.
11856 * @param {*} [thisArg] The `this` binding of `callback`.
11857 * @returns {number} Returns the index at which `value` should be inserted
11861 * _.sortedIndex([20, 30, 50], 40);
11865 * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
11868 * // using `callback`
11869 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
11870 * return dict.wordToNumber[word];
11874 * // using `callback` with `thisArg`
11875 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
11876 * return this.wordToNumber[word];
11880 * // using "_.pluck" callback shorthand
11881 * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
11884 function sortedIndex(array, value, callback, thisArg) {
11886 high = array ? array.length : low;
11888 // explicitly reference `identity` for better inlining in Firefox
11889 callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
11890 value = callback(value);
11892 while (low < high) {
11893 var mid = (low + high) >>> 1;
11894 (callback(array[mid]) < value)
11902 * Creates an array of unique values, in order, of the provided arrays using
11903 * strict equality for comparisons, i.e. `===`.
11908 * @param {...Array} [array] The arrays to inspect.
11909 * @returns {Array} Returns an array of combined values.
11912 * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]);
11913 * // => [1, 2, 3, 5, 4]
11916 return baseUniq(baseFlatten(arguments, true, true));
11920 * Creates a duplicate-value-free version of an array using strict equality
11921 * for comparisons, i.e. `===`. If the array is sorted, providing
11922 * `true` for `isSorted` will use a faster algorithm. If a callback is provided
11923 * each element of `array` is passed through the callback before uniqueness
11924 * is computed. The callback is bound to `thisArg` and invoked with three
11925 * arguments; (value, index, array).
11927 * If a property name is provided for `callback` the created "_.pluck" style
11928 * callback will return the property value of the given element.
11930 * If an object is provided for `callback` the created "_.where" style callback
11931 * will return `true` for elements that have the properties of the given object,
11938 * @param {Array} array The array to process.
11939 * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
11940 * @param {Function|Object|string} [callback=identity] The function called
11941 * per iteration. If a property name or object is provided it will be used
11942 * to create a "_.pluck" or "_.where" style callback, respectively.
11943 * @param {*} [thisArg] The `this` binding of `callback`.
11944 * @returns {Array} Returns a duplicate-value-free array.
11947 * _.uniq([1, 2, 1, 3, 1]);
11950 * // using `isSorted`
11951 * _.uniq([1, 1, 2, 2, 3], true);
11954 * // using `callback`
11955 * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
11956 * // => ['A', 'b', 'C']
11958 * // using `callback` with `thisArg`
11959 * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
11960 * // => [1, 2.5, 3]
11962 * // using "_.pluck" callback shorthand
11963 * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
11964 * // => [{ 'x': 1 }, { 'x': 2 }]
11966 function uniq(array, isSorted, callback, thisArg) {
11967 var type = typeof isSorted;
11969 // juggle arguments
11970 if (type != 'boolean' && isSorted != null) {
11971 thisArg = callback;
11972 callback = isSorted;
11975 // enables use as a callback for functions like `_.map`
11976 if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === array) {
11980 if (callback != null) {
11981 callback = lodash.createCallback(callback, thisArg, 3);
11983 return baseUniq(array, isSorted, callback);
11987 * Creates an array excluding all provided values using strict equality for
11988 * comparisons, i.e. `===`.
11993 * @param {Array} array The array to filter.
11994 * @param {...*} [value] The values to exclude.
11995 * @returns {Array} Returns a new array of filtered values.
11998 * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
12001 function without(array) {
12002 return baseDifference(array, slice(arguments, 1));
12006 * Creates an array that is the symmetric difference of the provided arrays.
12007 * See [Wikipedia](http://en.wikipedia.org/wiki/Symmetric_difference) for more details.
12012 * @param {...Array} [array] The arrays to inspect.
12013 * @returns {Array} Returns an array of values.
12016 * _.xor([1, 2, 3], [5, 2, 1, 4]);
12019 * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]);
12024 length = arguments.length;
12026 while (++index < length) {
12027 var array = arguments[index];
12028 if (isArray(array) || isArguments(array)) {
12029 var result = result
12030 ? baseDifference(result, array).concat(baseDifference(array, result))
12034 return result ? baseUniq(result) : [];
12038 * Creates an array of grouped elements, the first of which contains the first
12039 * elements of the given arrays, the second of which contains the second elements
12040 * of the given arrays, and so on. If a zipped value is provided its corresponding
12041 * unzipped value will be returned.
12047 * @param {...Array} [array] Arrays to process.
12048 * @returns {Array} Returns a new array of grouped elements.
12051 * _.zip(['fred', 'barney'], [30, 40], [true, false]);
12052 * // => [['fred', 30, true], ['barney', 40, false]]
12054 * _.unzip([['fred', 30, true], ['barney', 40, false]]);
12055 * // => [['fred', 'barney'], [30, 40], [true, false]]
12058 var array = arguments.length > 1 ? arguments : arguments[0],
12060 length = array ? max(pluck(array, 'length')) : 0,
12061 result = Array(length < 0 ? 0 : length);
12063 while (++index < length) {
12064 result[index] = pluck(array, index);
12070 * Creates an object composed from arrays of `keys` and `values`. Provide
12071 * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
12072 * or two arrays, one of `keys` and one of corresponding `values`.
12078 * @param {Array} keys The array of keys.
12079 * @param {Array} [values=[]] The array of values.
12080 * @returns {Object} Returns an object composed of the given keys and
12081 * corresponding values.
12084 * _.zipObject(['fred', 'barney'], [30, 40]);
12085 * // => { 'fred': 30, 'barney': 40 }
12087 function zipObject(keys, values) {
12089 length = keys ? keys.length : 0,
12092 if (!values && length && !isArray(keys[0])) {
12095 while (++index < length) {
12096 var key = keys[index];
12098 result[key] = values[index];
12100 result[key[0]] = key[1];
12106 /*--------------------------------------------------------------------------*/
12109 * Creates a `lodash` object that wraps `value` with explicit method
12110 * chaining enabled.
12114 * @category Chaining
12115 * @param {*} value The value to wrap.
12116 * @returns {Object} Returns the wrapper object.
12119 * var characters = [
12120 * { 'name': 'barney', 'age': 36 },
12121 * { 'name': 'fred', 'age': 40 },
12122 * { 'name': 'pebbles', 'age': 1 }
12125 * var youngest = _.chain(characters)
12127 * .map(function(chr) { return chr.name + ' is ' + chr.age; })
12130 * // => 'pebbles is 1'
12132 function chain(value) {
12133 value = new lodashWrapper(value);
12134 value.__chain__ = true;
12139 * This method invokes `interceptor` and returns `value`. The interceptor is
12140 * bound to `thisArg` and invoked with one argument; (value). The purpose of
12141 * this method is to "tap into" a method chain in order to perform operations
12142 * on intermediate results within the chain.
12146 * @category Chaining
12147 * @param {*} value The value to provide to `interceptor`.
12148 * @param {Function} interceptor The function to invoke.
12149 * @param {*} [thisArg] The `this` binding of `interceptor`.
12150 * @returns {*} Returns `value`.
12154 * .tap(function(array) { array.pop(); })
12159 function tap(value, interceptor, thisArg) {
12160 interceptor.call(thisArg, value);
12165 * Enables explicit method chaining on the wrapper object.
12169 * @category Chaining
12170 * @returns {*} Returns the wrapper object.
12173 * var characters = [
12174 * { 'name': 'barney', 'age': 36 },
12175 * { 'name': 'fred', 'age': 40 }
12178 * // without explicit chaining
12179 * _(characters).first();
12180 * // => { 'name': 'barney', 'age': 36 }
12182 * // with explicit chaining
12183 * _(characters).chain()
12187 * // => { 'age': 36 }
12189 function wrapperChain() {
12190 this.__chain__ = true;
12195 * Produces the `toString` result of the wrapped value.
12199 * @category Chaining
12200 * @returns {string} Returns the string result.
12203 * _([1, 2, 3]).toString();
12206 function wrapperToString() {
12207 return String(this.__wrapped__);
12211 * Extracts the wrapped value.
12216 * @category Chaining
12217 * @returns {*} Returns the wrapped value.
12220 * _([1, 2, 3]).valueOf();
12223 function wrapperValueOf() {
12224 return this.__wrapped__;
12227 /*--------------------------------------------------------------------------*/
12231 * Creates an array of elements from the specified indexes, or keys, of the
12232 * `collection`. Indexes may be specified as individual arguments or as arrays
12237 * @category Collections
12238 * @param {Array|Object|string} collection The collection to iterate over.
12239 * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
12240 * to retrieve, specified as individual indexes or arrays of indexes.
12241 * @returns {Array} Returns a new array of elements corresponding to the
12242 * provided indexes.
12245 * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
12246 * // => ['a', 'c', 'e']
12248 * _.at(['fred', 'barney', 'pebbles'], 0, 2);
12249 * // => ['fred', 'pebbles']
12251 function at(collection, guard) {
12252 var args = arguments,
12254 props = baseFlatten(args, true, false, 1),
12255 length = props.length,
12256 type = typeof guard;
12258 // enables use as a callback for functions like `_.map`
12259 if ((type == 'number' || type == 'string') && args[2] && args[2][guard] === collection) {
12262 if (support.unindexedChars && isString(collection)) {
12263 collection = collection.split('');
12265 var result = Array(length);
12266 while(++index < length) {
12267 result[index] = collection[props[index]];
12273 * Checks if a given value is present in a collection using strict equality
12274 * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
12275 * offset from the end of the collection.
12280 * @category Collections
12281 * @param {Array|Object|string} collection The collection to iterate over.
12282 * @param {*} target The value to check for.
12283 * @param {number} [fromIndex=0] The index to search from.
12284 * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
12287 * _.contains([1, 2, 3], 1);
12290 * _.contains([1, 2, 3], 1, 2);
12293 * _.contains({ 'name': 'fred', 'age': 40 }, 'fred');
12296 * _.contains('pebbles', 'eb');
12299 function contains(collection, target, fromIndex) {
12300 var length = collection ? collection.length : 0;
12301 fromIndex = typeof fromIndex == 'number' ? fromIndex : 0;
12303 if (typeof length == 'number') {
12304 if (fromIndex >= length) {
12307 if (typeof collection == 'string' || !isArray(collection) && isString(collection)) {
12308 return nativeContains
12309 ? nativeContains.call(collection, target, fromIndex)
12310 : collection.indexOf(target, fromIndex) > -1;
12312 var indexOf = getIndexOf();
12313 fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
12314 return indexOf(collection, target, fromIndex) > -1;
12319 baseEach(collection, function(value) {
12320 if (++index >= fromIndex) {
12321 return !(result = value === target);
12329 * Creates an object composed of keys generated from the results of running
12330 * each element of `collection` through the callback. The corresponding value
12331 * of each key is the number of times the key was returned by the callback.
12332 * The callback is bound to `thisArg` and invoked with three arguments;
12333 * (value, index|key, collection).
12335 * If a property name is provided for `callback` the created "_.pluck" style
12336 * callback will return the property value of the given element.
12338 * If an object is provided for `callback` the created "_.where" style callback
12339 * will return `true` for elements that have the properties of the given object,
12344 * @category Collections
12345 * @param {Array|Object|string} collection The collection to iterate over.
12346 * @param {Function|Object|string} [callback=identity] The function called
12347 * per iteration. If a property name or object is provided it will be used
12348 * to create a "_.pluck" or "_.where" style callback, respectively.
12349 * @param {*} [thisArg] The `this` binding of `callback`.
12350 * @returns {Object} Returns the composed aggregate object.
12353 * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
12354 * // => { '4': 1, '6': 2 }
12356 * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
12357 * // => { '4': 1, '6': 2 }
12359 * _.countBy(['one', 'two', 'three'], 'length');
12360 * // => { '3': 2, '5': 1 }
12362 var countBy = createAggregator(function(result, value, key) {
12363 (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
12367 * Checks if the callback returns truey value for **all** elements of a
12368 * collection. The callback is bound to `thisArg` and invoked with three
12369 * arguments; (value, index|key, collection).
12371 * If a property name is provided for `callback` the created "_.pluck" style
12372 * callback will return the property value of the given element.
12374 * If an object is provided for `callback` the created "_.where" style callback
12375 * will return `true` for elements that have the properties of the given object,
12381 * @category Collections
12382 * @param {Array|Object|string} collection The collection to iterate over.
12383 * @param {Function|Object|string} [callback=identity] The function called
12384 * per iteration. If a property name or object is provided it will be used
12385 * to create a "_.pluck" or "_.where" style callback, respectively.
12386 * @param {*} [thisArg] The `this` binding of `callback`.
12387 * @returns {boolean} Returns `true` if all elements passed the callback check,
12391 * _.every([true, 1, null, 'yes']);
12394 * var characters = [
12395 * { 'name': 'barney', 'age': 36 },
12396 * { 'name': 'fred', 'age': 40 }
12399 * // using "_.pluck" callback shorthand
12400 * _.every(characters, 'age');
12403 * // using "_.where" callback shorthand
12404 * _.every(characters, { 'age': 36 });
12407 function every(collection, callback, thisArg) {
12410 callback = lodash.createCallback(callback, thisArg, 3);
12411 if (isArray(collection)) {
12413 length = collection.length;
12415 while (++index < length) {
12416 if (!callback(collection[index], index, collection)) {
12421 baseEach(collection, function(value, index, collection) {
12422 return (result = !!callback(value, index, collection));
12429 * Iterates over elements of a collection, returning an array of all elements
12430 * the callback returns truey for. The callback is bound to `thisArg` and
12431 * invoked with three arguments; (value, index|key, collection).
12433 * If a property name is provided for `callback` the created "_.pluck" style
12434 * callback will return the property value of the given element.
12436 * If an object is provided for `callback` the created "_.where" style callback
12437 * will return `true` for elements that have the properties of the given object,
12443 * @category Collections
12444 * @param {Array|Object|string} collection The collection to iterate over.
12445 * @param {Function|Object|string} [callback=identity] The function called
12446 * per iteration. If a property name or object is provided it will be used
12447 * to create a "_.pluck" or "_.where" style callback, respectively.
12448 * @param {*} [thisArg] The `this` binding of `callback`.
12449 * @returns {Array} Returns a new array of elements that passed the callback check.
12452 * var evens = _.filter([1, 2, 3, 4], function(num) { return num % 2 == 0; });
12455 * var characters = [
12456 * { 'name': 'barney', 'age': 36 },
12457 * { 'name': 'fred', 'age': 40, 'blocked': true }
12460 * // using "_.pluck" callback shorthand
12461 * _.filter(characters, 'blocked');
12462 * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
12464 * // using "_.where" callback shorthand
12465 * _.filter(characters, { 'age': 36 });
12466 * // => [{ 'name': 'barney', 'age': 36 }]
12468 function filter(collection, callback, thisArg) {
12471 callback = lodash.createCallback(callback, thisArg, 3);
12472 if (isArray(collection)) {
12474 length = collection.length;
12476 while (++index < length) {
12477 var value = collection[index];
12478 if (callback(value, index, collection)) {
12479 result.push(value);
12483 baseEach(collection, function(value, index, collection) {
12484 if (callback(value, index, collection)) {
12485 result.push(value);
12493 * Iterates over elements of a collection, returning the first element that
12494 * the callback returns truey for. The callback is bound to `thisArg` and
12495 * invoked with three arguments; (value, index|key, collection).
12497 * If a property name is provided for `callback` the created "_.pluck" style
12498 * callback will return the property value of the given element.
12500 * If an object is provided for `callback` the created "_.where" style callback
12501 * will return `true` for elements that have the properties of the given object,
12506 * @alias detect, findWhere
12507 * @category Collections
12508 * @param {Array|Object|string} collection The collection to iterate over.
12509 * @param {Function|Object|string} [callback=identity] The function called
12510 * per iteration. If a property name or object is provided it will be used
12511 * to create a "_.pluck" or "_.where" style callback, respectively.
12512 * @param {*} [thisArg] The `this` binding of `callback`.
12513 * @returns {*} Returns the found element, else `undefined`.
12516 * var characters = [
12517 * { 'name': 'barney', 'age': 36 },
12518 * { 'name': 'fred', 'age': 40, 'blocked': true },
12519 * { 'name': 'pebbles', 'age': 1 }
12522 * _.find(characters, function(chr) {
12523 * return chr.age < 40;
12525 * // => { 'name': 'barney', 'age': 36 }
12527 * // using "_.where" callback shorthand
12528 * _.find(characters, { 'age': 1 });
12529 * // => { 'name': 'pebbles', 'age': 1 }
12531 * // using "_.pluck" callback shorthand
12532 * _.find(characters, 'blocked');
12533 * // => { 'name': 'fred', 'age': 40, 'blocked': true }
12535 function find(collection, callback, thisArg) {
12536 callback = lodash.createCallback(callback, thisArg, 3);
12537 if (isArray(collection)) {
12539 length = collection.length;
12541 while (++index < length) {
12542 var value = collection[index];
12543 if (callback(value, index, collection)) {
12549 baseEach(collection, function(value, index, collection) {
12550 if (callback(value, index, collection)) {
12560 * This method is like `_.find` except that it iterates over elements
12561 * of a `collection` from right to left.
12565 * @category Collections
12566 * @param {Array|Object|string} collection The collection to iterate over.
12567 * @param {Function|Object|string} [callback=identity] The function called
12568 * per iteration. If a property name or object is provided it will be used
12569 * to create a "_.pluck" or "_.where" style callback, respectively.
12570 * @param {*} [thisArg] The `this` binding of `callback`.
12571 * @returns {*} Returns the found element, else `undefined`.
12574 * _.findLast([1, 2, 3, 4], function(num) {
12575 * return num % 2 == 1;
12579 function findLast(collection, callback, thisArg) {
12582 callback = lodash.createCallback(callback, thisArg, 3);
12583 baseEachRight(collection, function(value, index, collection) {
12584 if (callback(value, index, collection)) {
12593 * Iterates over elements of a collection, executing the callback for each
12594 * element. The callback is bound to `thisArg` and invoked with three arguments;
12595 * (value, index|key, collection). Callbacks may exit iteration early by
12596 * explicitly returning `false`.
12598 * Note: As with other "Collections" methods, objects with a `length` property
12599 * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn`
12600 * may be used for object iteration.
12605 * @category Collections
12606 * @param {Array|Object|string} collection The collection to iterate over.
12607 * @param {Function} [callback=identity] The function called per iteration.
12608 * @param {*} [thisArg] The `this` binding of `callback`.
12609 * @returns {Array|Object|string} Returns `collection`.
12612 * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
12613 * // => logs each number and returns '1,2,3'
12615 * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
12616 * // => logs each number and returns the object (property order is not guaranteed across environments)
12618 function forEach(collection, callback, thisArg) {
12619 if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
12621 length = collection.length;
12623 while (++index < length) {
12624 if (callback(collection[index], index, collection) === false) {
12629 baseEach(collection, baseCreateCallback(callback, thisArg, 3));
12635 * This method is like `_.forEach` except that it iterates over elements
12636 * of a `collection` from right to left.
12641 * @category Collections
12642 * @param {Array|Object|string} collection The collection to iterate over.
12643 * @param {Function} [callback=identity] The function called per iteration.
12644 * @param {*} [thisArg] The `this` binding of `callback`.
12645 * @returns {Array|Object|string} Returns `collection`.
12648 * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
12649 * // => logs each number from right to left and returns '3,2,1'
12651 function forEachRight(collection, callback, thisArg) {
12652 if (callback && typeof thisArg == 'undefined' && isArray(collection)) {
12653 var length = collection.length;
12655 if (callback(collection[length], length, collection) === false) {
12660 baseEachRight(collection, baseCreateCallback(callback, thisArg, 3));
12666 * Creates an object composed of keys generated from the results of running
12667 * each element of a collection through the callback. The corresponding value
12668 * of each key is an array of the elements responsible for generating the key.
12669 * The callback is bound to `thisArg` and invoked with three arguments;
12670 * (value, index|key, collection).
12672 * If a property name is provided for `callback` the created "_.pluck" style
12673 * callback will return the property value of the given element.
12675 * If an object is provided for `callback` the created "_.where" style callback
12676 * will return `true` for elements that have the properties of the given object,
12681 * @category Collections
12682 * @param {Array|Object|string} collection The collection to iterate over.
12683 * @param {Function|Object|string} [callback=identity] The function called
12684 * per iteration. If a property name or object is provided it will be used
12685 * to create a "_.pluck" or "_.where" style callback, respectively.
12686 * @param {*} [thisArg] The `this` binding of `callback`.
12687 * @returns {Object} Returns the composed aggregate object.
12690 * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
12691 * // => { '4': [4.2], '6': [6.1, 6.4] }
12693 * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
12694 * // => { '4': [4.2], '6': [6.1, 6.4] }
12696 * // using "_.pluck" callback shorthand
12697 * _.groupBy(['one', 'two', 'three'], 'length');
12698 * // => { '3': ['one', 'two'], '5': ['three'] }
12700 var groupBy = createAggregator(function(result, value, key) {
12701 if (hasOwnProperty.call(result, key)) {
12702 result[key].push(value);
12704 result[key] = [value];
12709 * Creates an object composed of keys generated from the results of running
12710 * each element of the collection through the given callback. The corresponding
12711 * value of each key is the last element responsible for generating the key.
12712 * The callback is bound to `thisArg` and invoked with three arguments;
12713 * (value, index|key, collection).
12715 * If a property name is provided for `callback` the created "_.pluck" style
12716 * callback will return the property value of the given element.
12718 * If an object is provided for `callback` the created "_.where" style callback
12719 * will return `true` for elements that have the properties of the given object,
12724 * @category Collections
12725 * @param {Array|Object|string} collection The collection to iterate over.
12726 * @param {Function|Object|string} [callback=identity] The function called
12727 * per iteration. If a property name or object is provided it will be used
12728 * to create a "_.pluck" or "_.where" style callback, respectively.
12729 * @param {*} [thisArg] The `this` binding of `callback`.
12730 * @returns {Object} Returns the composed aggregate object.
12734 * { 'dir': 'left', 'code': 97 },
12735 * { 'dir': 'right', 'code': 100 }
12738 * _.indexBy(keys, 'dir');
12739 * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
12741 * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
12742 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
12744 * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String);
12745 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
12747 var indexBy = createAggregator(function(result, value, key) {
12748 result[key] = value;
12752 * Invokes the method named by `methodName` on each element in the `collection`
12753 * returning an array of the results of each invoked method. Additional arguments
12754 * will be provided to each invoked method. If `methodName` is a function it
12755 * will be invoked for, and `this` bound to, each element in the `collection`.
12759 * @category Collections
12760 * @param {Array|Object|string} collection The collection to iterate over.
12761 * @param {Function|string} methodName The name of the method to invoke or
12762 * the function invoked per iteration.
12763 * @param {...*} [args] Arguments to invoke the method with.
12764 * @returns {Array} Returns a new array of the results of each invoked method.
12767 * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
12768 * // => [[1, 5, 7], [1, 2, 3]]
12770 * _.invoke([123, 456], String.prototype.split, '');
12771 * // => [['1', '2', '3'], ['4', '5', '6']]
12773 function invoke(collection, methodName) {
12775 isFunc = typeof methodName == 'function',
12776 length = collection ? collection.length : 0,
12777 result = Array(typeof length == 'number' ? length : 0);
12779 if (arguments.length < 3 && isArray(collection)) {
12780 while (++index < length) {
12781 var value = collection[index];
12782 result[index] = isFunc ? methodName.call(value) : value[methodName]();
12785 var args = slice(arguments, 2);
12786 baseEach(collection, function(value) {
12787 result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
12794 * Creates an array of values by running each element in the collection
12795 * through the callback. The callback is bound to `thisArg` and invoked with
12796 * three arguments; (value, index|key, collection).
12798 * If a property name is provided for `callback` the created "_.pluck" style
12799 * callback will return the property value of the given element.
12801 * If an object is provided for `callback` the created "_.where" style callback
12802 * will return `true` for elements that have the properties of the given object,
12808 * @category Collections
12809 * @param {Array|Object|string} collection The collection to iterate over.
12810 * @param {Function|Object|string} [callback=identity] The function called
12811 * per iteration. If a property name or object is provided it will be used
12812 * to create a "_.pluck" or "_.where" style callback, respectively.
12813 * @param {*} [thisArg] The `this` binding of `callback`.
12814 * @returns {Array} Returns a new array of the results of each `callback` execution.
12817 * _.map([1, 2, 3], function(num) { return num * 3; });
12820 * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
12821 * // => [3, 6, 9] (property order is not guaranteed across environments)
12823 * var characters = [
12824 * { 'name': 'barney', 'age': 36 },
12825 * { 'name': 'fred', 'age': 40 }
12828 * // using "_.pluck" callback shorthand
12829 * _.map(characters, 'name');
12830 * // => ['barney', 'fred']
12832 function map(collection, callback, thisArg) {
12834 length = collection ? collection.length : 0,
12835 result = Array(typeof length == 'number' ? length : 0);
12837 callback = lodash.createCallback(callback, thisArg, 3);
12838 if (isArray(collection)) {
12839 while (++index < length) {
12840 result[index] = callback(collection[index], index, collection);
12843 baseEach(collection, function(value, key, collection) {
12844 result[++index] = callback(value, key, collection);
12851 * Retrieves the maximum value of a collection. If the collection is empty or
12852 * falsey `-Infinity` is returned. If a callback is provided it will be executed
12853 * for each value in the collection to generate the criterion by which the value
12854 * is ranked. The callback is bound to `thisArg` and invoked with three
12855 * arguments; (value, index, collection).
12857 * If a property name is provided for `callback` the created "_.pluck" style
12858 * callback will return the property value of the given element.
12860 * If an object is provided for `callback` the created "_.where" style callback
12861 * will return `true` for elements that have the properties of the given object,
12866 * @category Collections
12867 * @param {Array|Object|string} collection The collection to iterate over.
12868 * @param {Function|Object|string} [callback=identity] The function called
12869 * per iteration. If a property name or object is provided it will be used
12870 * to create a "_.pluck" or "_.where" style callback, respectively.
12871 * @param {*} [thisArg] The `this` binding of `callback`.
12872 * @returns {*} Returns the maximum value.
12875 * _.max([4, 2, 8, 6]);
12878 * var characters = [
12879 * { 'name': 'barney', 'age': 36 },
12880 * { 'name': 'fred', 'age': 40 }
12883 * _.max(characters, function(chr) { return chr.age; });
12884 * // => { 'name': 'fred', 'age': 40 };
12886 * // using "_.pluck" callback shorthand
12887 * _.max(characters, 'age');
12888 * // => { 'name': 'fred', 'age': 40 };
12890 function max(collection, callback, thisArg) {
12891 var computed = -Infinity,
12893 type = typeof callback;
12895 // enables use as a callback for functions like `_.map`
12896 if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === collection) {
12899 if (callback == null && isArray(collection)) {
12901 length = collection.length;
12903 while (++index < length) {
12904 var value = collection[index];
12905 if (value > result) {
12910 callback = (callback == null && isString(collection))
12912 : lodash.createCallback(callback, thisArg, 3);
12914 baseEach(collection, function(value, index, collection) {
12915 var current = callback(value, index, collection);
12916 if (current > computed) {
12917 computed = current;
12926 * Retrieves the minimum value of a collection. If the collection is empty or
12927 * falsey `Infinity` is returned. If a callback is provided it will be executed
12928 * for each value in the collection to generate the criterion by which the value
12929 * is ranked. The callback is bound to `thisArg` and invoked with three
12930 * arguments; (value, index, collection).
12932 * If a property name is provided for `callback` the created "_.pluck" style
12933 * callback will return the property value of the given element.
12935 * If an object is provided for `callback` the created "_.where" style callback
12936 * will return `true` for elements that have the properties of the given object,
12941 * @category Collections
12942 * @param {Array|Object|string} collection The collection to iterate over.
12943 * @param {Function|Object|string} [callback=identity] The function called
12944 * per iteration. If a property name or object is provided it will be used
12945 * to create a "_.pluck" or "_.where" style callback, respectively.
12946 * @param {*} [thisArg] The `this` binding of `callback`.
12947 * @returns {*} Returns the minimum value.
12950 * _.min([4, 2, 8, 6]);
12953 * var characters = [
12954 * { 'name': 'barney', 'age': 36 },
12955 * { 'name': 'fred', 'age': 40 }
12958 * _.min(characters, function(chr) { return chr.age; });
12959 * // => { 'name': 'barney', 'age': 36 };
12961 * // using "_.pluck" callback shorthand
12962 * _.min(characters, 'age');
12963 * // => { 'name': 'barney', 'age': 36 };
12965 function min(collection, callback, thisArg) {
12966 var computed = Infinity,
12968 type = typeof callback;
12970 // enables use as a callback for functions like `_.map`
12971 if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === collection) {
12974 if (callback == null && isArray(collection)) {
12976 length = collection.length;
12978 while (++index < length) {
12979 var value = collection[index];
12980 if (value < result) {
12985 callback = (callback == null && isString(collection))
12987 : lodash.createCallback(callback, thisArg, 3);
12989 baseEach(collection, function(value, index, collection) {
12990 var current = callback(value, index, collection);
12991 if (current < computed) {
12992 computed = current;
13001 * Creates an array of elements split into two groups, the first of which
13002 * contains elements the callback returns truey for, while the second of which
13003 * contains elements the callback returns falsey for. The callback is bound
13004 * to `thisArg` and invoked with three arguments; (value, index|key, collection).
13006 * If a property name is provided for `callback` the created "_.pluck" style
13007 * callback will return the property value of the given element.
13009 * If an object is provided for `callback` the created "_.where" style callback
13010 * will return `true` for elements that have the properties of the given object,
13015 * @category Collections
13016 * @param {Array|Object|string} collection The collection to iterate over.
13017 * @param {Function|Object|string} [callback=identity] The function called
13018 * per iteration. If a property name or object is provided it will be used
13019 * to create a "_.pluck" or "_.where" style callback, respectively.
13020 * @param {*} [thisArg] The `this` binding of `callback`.
13021 * @returns {Array} Returns a new array of grouped elements.
13024 * _.partition([1, 2, 3], function(num) { return num % 2; });
13025 * // => [[1, 3], [2]]
13027 * _.partition([1.2, 2.3, 3.4], function(num) { return this.floor(num) % 2; }, Math);
13028 * // => [[1, 3], [2]]
13030 * var characters = [
13031 * { 'name': 'barney', 'age': 36 },
13032 * { 'name': 'fred', 'age': 40, 'blocked': true },
13033 * { 'name': 'pebbles', 'age': 1 }
13036 * // using "_.where" callback shorthand
13037 * _.map(_.partition(characters, { 'age': 1 }), function(array) { return _.pluck(array, 'name'); });
13038 * // => [['pebbles'], ['barney', 'fred']]
13040 * // using "_.pluck" callback shorthand
13041 * _.map(_.partition(characters, 'blocked'), function(array) { return _.pluck(array, 'name'); });
13042 * // => [['fred'], ['barney', 'pebbles']]
13044 var partition = createAggregator(function(result, value, key) {
13045 result[key ? 0 : 1].push(value);
13049 * Retrieves the value of a specified property from all elements in the collection.
13054 * @category Collections
13055 * @param {Array|Object|string} collection The collection to iterate over.
13056 * @param {string} key The name of the property to pluck.
13057 * @returns {Array} Returns a new array of property values.
13060 * var characters = [
13061 * { 'name': 'barney', 'age': 36 },
13062 * { 'name': 'fred', 'age': 40 }
13065 * _.pluck(characters, 'name');
13066 * // => ['barney', 'fred']
13071 * Reduces a collection to a value which is the accumulated result of running
13072 * each element in the collection through the callback, where each successive
13073 * callback execution consumes the return value of the previous execution. If
13074 * `accumulator` is not provided the first element of the collection will be
13075 * used as the initial `accumulator` value. The callback is bound to `thisArg`
13076 * and invoked with four arguments; (accumulator, value, index|key, collection).
13080 * @alias foldl, inject
13081 * @category Collections
13082 * @param {Array|Object|string} collection The collection to iterate over.
13083 * @param {Function} [callback=identity] The function called per iteration.
13084 * @param {*} [accumulator] Initial value of the accumulator.
13085 * @param {*} [thisArg] The `this` binding of `callback`.
13086 * @returns {*} Returns the accumulated value.
13089 * var sum = _.reduce([1, 2, 3], function(sum, num) {
13090 * return sum + num;
13094 * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
13095 * result[key] = num * 3;
13098 * // => { 'a': 3, 'b': 6, 'c': 9 }
13100 function reduce(collection, callback, accumulator, thisArg) {
13101 var noaccum = arguments.length < 3;
13103 callback = lodash.createCallback(callback, thisArg, 4);
13104 if (isArray(collection)) {
13106 length = collection.length;
13108 if (noaccum && length) {
13109 accumulator = collection[++index];
13111 while (++index < length) {
13112 accumulator = callback(accumulator, collection[index], index, collection);
13115 baseEach(collection, function(value, index, collection) {
13116 accumulator = noaccum
13117 ? (noaccum = false, value)
13118 : callback(accumulator, value, index, collection)
13121 return accumulator;
13125 * This method is like `_.reduce` except that it iterates over elements
13126 * of a `collection` from right to left.
13131 * @category Collections
13132 * @param {Array|Object|string} collection The collection to iterate over.
13133 * @param {Function} [callback=identity] The function called per iteration.
13134 * @param {*} [accumulator] Initial value of the accumulator.
13135 * @param {*} [thisArg] The `this` binding of `callback`.
13136 * @returns {*} Returns the accumulated value.
13139 * var list = [[0, 1], [2, 3], [4, 5]];
13140 * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
13141 * // => [4, 5, 2, 3, 0, 1]
13143 function reduceRight(collection, callback, accumulator, thisArg) {
13144 var noaccum = arguments.length < 3;
13146 callback = lodash.createCallback(callback, thisArg, 4);
13147 baseEachRight(collection, function(value, index, collection) {
13148 accumulator = noaccum
13149 ? (noaccum = false, value)
13150 : callback(accumulator, value, index, collection);
13152 return accumulator;
13156 * The opposite of `_.filter`; this method returns the elements of a
13157 * collection that the callback does **not** return truey for.
13159 * If a property name is provided for `callback` the created "_.pluck" style
13160 * callback will return the property value of the given element.
13162 * If an object is provided for `callback` the created "_.where" style callback
13163 * will return `true` for elements that have the properties of the given object,
13168 * @category Collections
13169 * @param {Array|Object|string} collection The collection to iterate over.
13170 * @param {Function|Object|string} [callback=identity] The function called
13171 * per iteration. If a property name or object is provided it will be used
13172 * to create a "_.pluck" or "_.where" style callback, respectively.
13173 * @param {*} [thisArg] The `this` binding of `callback`.
13174 * @returns {Array} Returns a new array of elements that failed the callback check.
13177 * var odds = _.reject([1, 2, 3, 4], function(num) { return num % 2 == 0; });
13180 * var characters = [
13181 * { 'name': 'barney', 'age': 36 },
13182 * { 'name': 'fred', 'age': 40, 'blocked': true }
13185 * // using "_.pluck" callback shorthand
13186 * _.reject(characters, 'blocked');
13187 * // => [{ 'name': 'barney', 'age': 36 }]
13189 * // using "_.where" callback shorthand
13190 * _.reject(characters, { 'age': 36 });
13191 * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }]
13193 function reject(collection, callback, thisArg) {
13194 callback = lodash.createCallback(callback, thisArg, 3);
13195 return filter(collection, function(value, index, collection) {
13196 return !callback(value, index, collection);
13201 * Retrieves a random element or `n` random elements from a collection.
13205 * @category Collections
13206 * @param {Array|Object|string} collection The collection to sample.
13207 * @param {number} [n] The number of elements to sample.
13208 * @param- {Object} [guard] Enables use as a callback for functions like `_.map`.
13209 * @returns {*} Returns the random sample(s) of `collection`.
13212 * _.sample([1, 2, 3, 4]);
13215 * _.sample([1, 2, 3, 4], 2);
13218 function sample(collection, n, guard) {
13219 if (collection && typeof collection.length != 'number') {
13220 collection = values(collection);
13221 } else if (support.unindexedChars && isString(collection)) {
13222 collection = collection.split('');
13224 if (n == null || guard) {
13225 return collection ? collection[baseRandom(0, collection.length - 1)] : undefined;
13227 var result = shuffle(collection);
13228 result.length = nativeMin(nativeMax(0, n), result.length);
13233 * Creates an array of shuffled values, using a version of the Fisher-Yates
13234 * shuffle. See [Wikipedia](http://en.wikipedia.org/wiki/Fisher-Yates_shuffle) for more details.
13238 * @category Collections
13239 * @param {Array|Object|string} collection The collection to shuffle.
13240 * @returns {Array} Returns a new shuffled collection.
13243 * _.shuffle([1, 2, 3, 4]);
13244 * // => [4, 1, 3, 2]
13246 function shuffle(collection) {
13248 length = collection ? collection.length : 0,
13249 result = Array(typeof length == 'number' ? length : 0);
13251 baseEach(collection, function(value) {
13252 var rand = baseRandom(0, ++index);
13253 result[index] = result[rand];
13254 result[rand] = value;
13261 * Gets the size of the `collection` by returning `collection.length` for arrays
13262 * and array-like objects or the number of own enumerable properties for objects.
13266 * @category Collections
13267 * @param {Array|Object|string} collection The collection to inspect.
13268 * @returns {number} Returns `collection.length` or number of own enumerable properties.
13274 * _.size({ 'one': 1, 'two': 2, 'three': 3 });
13277 * _.size('pebbles');
13280 function size(collection) {
13281 var length = collection ? collection.length : 0;
13282 return typeof length == 'number' ? length : keys(collection).length;
13286 * Checks if the callback returns a truey value for **any** element of a
13287 * collection. The function returns as soon as it finds a passing value and
13288 * does not iterate over the entire collection. The callback is bound to
13289 * `thisArg` and invoked with three arguments; (value, index|key, collection).
13291 * If a property name is provided for `callback` the created "_.pluck" style
13292 * callback will return the property value of the given element.
13294 * If an object is provided for `callback` the created "_.where" style callback
13295 * will return `true` for elements that have the properties of the given object,
13301 * @category Collections
13302 * @param {Array|Object|string} collection The collection to iterate over.
13303 * @param {Function|Object|string} [callback=identity] The function called
13304 * per iteration. If a property name or object is provided it will be used
13305 * to create a "_.pluck" or "_.where" style callback, respectively.
13306 * @param {*} [thisArg] The `this` binding of `callback`.
13307 * @returns {boolean} Returns `true` if any element passed the callback check,
13311 * _.some([null, 0, 'yes', false], Boolean);
13314 * var characters = [
13315 * { 'name': 'barney', 'age': 36 },
13316 * { 'name': 'fred', 'age': 40, 'blocked': true }
13319 * // using "_.pluck" callback shorthand
13320 * _.some(characters, 'blocked');
13323 * // using "_.where" callback shorthand
13324 * _.some(characters, { 'age': 1 });
13327 function some(collection, callback, thisArg) {
13330 callback = lodash.createCallback(callback, thisArg, 3);
13331 if (isArray(collection)) {
13333 length = collection.length;
13335 while (++index < length) {
13336 if (callback(collection[index], index, collection)) {
13341 baseEach(collection, function(value, index, collection) {
13342 return !(result = callback(value, index, collection));
13349 * Creates an array of elements, sorted in ascending order by the results of
13350 * running each element in a collection through the callback. This method
13351 * performs a stable sort, that is, it will preserve the original sort order
13352 * of equal elements. The callback is bound to `thisArg` and invoked with
13353 * three arguments; (value, index|key, collection).
13355 * If a property name is provided for `callback` the created "_.pluck" style
13356 * callback will return the property value of the given element.
13358 * If an array of property names is provided for `callback` the collection
13359 * will be sorted by each property value.
13361 * If an object is provided for `callback` the created "_.where" style callback
13362 * will return `true` for elements that have the properties of the given object,
13367 * @category Collections
13368 * @param {Array|Object|string} collection The collection to iterate over.
13369 * @param {Array|Function|Object|string} [callback=identity] The function called
13370 * per iteration. If a property name or object is provided it will be used
13371 * to create a "_.pluck" or "_.where" style callback, respectively.
13372 * @param {*} [thisArg] The `this` binding of `callback`.
13373 * @returns {Array} Returns a new array of sorted elements.
13376 * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
13379 * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
13382 * var characters = [
13383 * { 'name': 'barney', 'age': 36 },
13384 * { 'name': 'fred', 'age': 40 },
13385 * { 'name': 'barney', 'age': 26 },
13386 * { 'name': 'fred', 'age': 30 }
13389 * // using "_.pluck" callback shorthand
13390 * _.map(_.sortBy(characters, 'age'), _.values);
13391 * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]]
13393 * // sorting by multiple properties
13394 * _.map(_.sortBy(characters, ['name', 'age']), _.values);
13395 * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]]
13397 function sortBy(collection, callback, thisArg) {
13399 multi = callback && isArray(callback),
13400 length = collection ? collection.length : 0,
13401 result = Array(typeof length == 'number' ? length : 0);
13404 callback = lodash.createCallback(callback, thisArg, 3);
13406 baseEach(collection, function(value, key, collection) {
13408 var length = callback.length,
13409 criteria = Array(length);
13412 criteria[length] = value[callback[length]];
13415 criteria = callback(value, key, collection);
13417 var object = result[++index] = getObject();
13418 object.criteria = criteria;
13419 object.index = index;
13420 object.value = value;
13423 length = result.length;
13424 result.sort(multi ? compareMultipleAscending : compareAscending);
13426 var object = result[length];
13427 result[length] = object.value;
13428 releaseObject(object);
13434 * Converts the `collection` to an array.
13438 * @category Collections
13439 * @param {Array|Object|string} collection The collection to convert.
13440 * @returns {Array} Returns the new converted array.
13443 * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
13446 function toArray(collection) {
13447 if (collection && typeof collection.length == 'number') {
13448 return (support.unindexedChars && isString(collection))
13449 ? collection.split('')
13450 : slice(collection);
13452 return values(collection);
13456 * Performs a deep comparison between each element in `collection` and the
13457 * `source` object, returning an array of all elements that have equivalent
13463 * @category Collections
13464 * @param {Array|Object|string} collection The collection to iterate over.
13465 * @param {Object} source The object of property values to filter by.
13466 * @returns {Array} Returns a new array of elements that have the given properties.
13469 * var characters = [
13470 * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] },
13471 * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }
13474 * _.where(characters, { 'age': 36 });
13475 * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }]
13477 * _.where(characters, { 'pets': ['dino'] });
13478 * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }]
13480 var where = filter;
13482 /*--------------------------------------------------------------------------*/
13485 * Creates a function that executes `func`, with the `this` binding and
13486 * arguments of the created function, only after being called `n` times.
13490 * @category Functions
13491 * @param {number} n The number of times the function must be called before
13492 * `func` is executed.
13493 * @param {Function} func The function to restrict.
13494 * @returns {Function} Returns the new restricted function.
13497 * var saves = ['profile', 'settings'];
13499 * var done = _.after(saves.length, function() {
13500 * console.log('Done saving!');
13503 * _.forEach(saves, function(type) {
13504 * asyncSave({ 'type': type, 'complete': done });
13506 * // => logs 'Done saving!', after all saves have completed
13508 function after(n, func) {
13509 if (!isFunction(func)) {
13510 throw new TypeError;
13512 return function() {
13514 return func.apply(this, arguments);
13520 * Creates a function that, when called, invokes `func` with the `this`
13521 * binding of `thisArg` and prepends any additional `bind` arguments to those
13522 * provided to the bound function.
13524 * Note: Unlike native `Function#bind` this method does not set the `length`
13525 * property of bound functions.
13529 * @category Functions
13530 * @param {Function} func The function to bind.
13531 * @param {*} [thisArg] The `this` binding of `func`.
13532 * @param {...*} [args] Arguments to be partially applied.
13533 * @returns {Function} Returns the new bound function.
13536 * var func = function(greeting) {
13537 * return greeting + ' ' + this.name;
13540 * func = _.bind(func, { 'name': 'fred' }, 'hi');
13544 function bind(func, thisArg) {
13545 if (arguments.length < 3) {
13546 return createWrapper(func, BIND_FLAG, null, thisArg);
13549 var arity = func[expando] ? func[expando][2] : func.length,
13550 partialArgs = slice(arguments, 2);
13552 arity -= partialArgs.length;
13554 return createWrapper(func, BIND_FLAG | PARTIAL_FLAG, arity, thisArg, partialArgs);
13558 * Binds methods of an object to the object itself, overwriting the existing
13559 * method. Method names may be specified as individual arguments or as arrays
13560 * of method names. If no method names are provided all the function properties
13561 * of `object` will be bound.
13563 * Note: This method does not set the `length` property of bound functions.
13567 * @category Functions
13568 * @param {Object} object The object to bind and assign the bound methods to.
13569 * @param {...string} [methodName] The object method names to
13570 * bind, specified as individual method names or arrays of method names.
13571 * @returns {Object} Returns `object`.
13576 * 'onClick': function() { console.log('clicked ' + this.label); }
13580 * jQuery('#docs').on('click', view.onClick);
13581 * // => logs 'clicked docs', when the button is clicked
13583 function bindAll(object) {
13584 var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
13586 length = funcs.length;
13588 while (++index < length) {
13589 var key = funcs[index];
13590 object[key] = createWrapper(object[key], BIND_FLAG, null, object);
13596 * Creates a function that, when called, invokes the method at `object[key]`
13597 * and prepends any additional `bindKey` arguments to those provided to the bound
13598 * function. This method differs from `_.bind` by allowing bound functions to
13599 * reference methods that will be redefined or don't yet exist.
13600 * See [Peter Michaux's article](http://michaux.ca/articles/lazy-function-definition-pattern)
13601 * for more details.
13605 * @category Functions
13606 * @param {Object} object The object the method belongs to.
13607 * @param {string} key The key of the method.
13608 * @param {...*} [args] Arguments to be partially applied.
13609 * @returns {Function} Returns the new bound function.
13614 * 'greet': function(greeting) {
13615 * return greeting + ' ' + this.name;
13619 * var func = _.bindKey(object, 'greet', 'hi');
13623 * object.greet = function(greeting) {
13624 * return greeting + 'ya ' + this.name + '!';
13628 * // => 'hiya fred!'
13630 function bindKey(object, key) {
13631 return arguments.length < 3
13632 ? createWrapper(key, BIND_FLAG | BIND_KEY_FLAG, null, object)
13633 : createWrapper(key, BIND_FLAG | BIND_KEY_FLAG | PARTIAL_FLAG, null, object, slice(arguments, 2));
13637 * Creates a function that is the composition of the provided functions,
13638 * where each function consumes the return value of the function that follows.
13639 * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
13640 * Each function is executed with the `this` binding of the composed function.
13644 * @category Functions
13645 * @param {...Function} [func] Functions to compose.
13646 * @returns {Function} Returns the new composed function.
13649 * var realNameMap = {
13650 * 'pebbles': 'penelope'
13653 * var format = function(name) {
13654 * name = realNameMap[name.toLowerCase()] || name;
13655 * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
13658 * var greet = function(formatted) {
13659 * return 'Hiya ' + formatted + '!';
13662 * var welcome = _.compose(greet, format);
13663 * welcome('pebbles');
13664 * // => 'Hiya Penelope!'
13666 function compose() {
13667 var funcs = arguments,
13668 funcsLength = funcs.length,
13669 length = funcsLength;
13672 if (!isFunction(funcs[length])) {
13673 throw new TypeError;
13676 return function() {
13677 var length = funcsLength - 1,
13678 result = funcs[length].apply(this, arguments);
13681 result = funcs[length].call(this, result);
13688 * Creates a function which accepts one or more arguments of `func` that when
13689 * invoked either executes `func` returning its result, if all `func` arguments
13690 * have been provided, or returns a function that accepts one or more of the
13691 * remaining `func` arguments, and so on. The arity of `func` can be specified
13692 * if `func.length` is not sufficient.
13694 * Note: This method does not set the `length` property of curried functions.
13698 * @category Functions
13699 * @param {Function} func The function to curry.
13700 * @param {number} [arity=func.length] The arity of `func`.
13701 * @returns {Function} Returns the new curried function.
13704 * var curried = _.curry(function(a, b, c) {
13705 * console.log(a + b + c);
13708 * curried(1)(2)(3);
13711 * curried(1, 2)(3);
13714 * curried(1, 2, 3);
13717 function curry(func, arity) {
13718 if (typeof arity != 'number') {
13719 arity = +arity || (func ? func.length : 0);
13721 return createWrapper(func, CURRY_FLAG, arity);
13725 * Creates a function that will delay the execution of `func` until after
13726 * `wait` milliseconds have elapsed since the last time it was invoked.
13727 * Provide an options object to indicate that `func` should be invoked on
13728 * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
13729 * to the debounced function will return the result of the last `func` call.
13731 * Note: If `leading` and `trailing` options are `true` `func` will be called
13732 * on the trailing edge of the timeout only if the the debounced function is
13733 * invoked more than once during the `wait` timeout.
13737 * @category Functions
13738 * @param {Function} func The function to debounce.
13739 * @param {number} wait The number of milliseconds to delay.
13740 * @param {Object} [options] The options object.
13741 * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
13742 * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
13743 * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
13744 * @returns {Function} Returns the new debounced function.
13747 * // avoid costly calculations while the window size is in flux
13748 * var lazyLayout = _.debounce(calculateLayout, 150);
13749 * jQuery(window).on('resize', lazyLayout);
13751 * // execute `sendMail` when the click event is fired, debouncing subsequent calls
13752 * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
13754 * 'trailing': false
13757 * // ensure `batchLog` is executed once after 1 second of debounced calls
13758 * var source = new EventSource('/stream');
13759 * source.addEventListener('message', _.debounce(batchLog, 250, {
13763 function debounce(func, wait, options) {
13775 if (!isFunction(func)) {
13776 throw new TypeError;
13778 wait = nativeMax(0, wait) || 0;
13779 if (options === true) {
13780 var leading = true;
13782 } else if (isObject(options)) {
13783 leading = options.leading;
13784 maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
13785 trailing = 'trailing' in options ? options.trailing : trailing;
13787 var delayed = function() {
13788 var remaining = wait - (now() - stamp);
13789 if (remaining <= 0 || remaining > wait) {
13790 if (maxTimeoutId) {
13791 clearTimeout(maxTimeoutId);
13793 var isCalled = trailingCall;
13794 maxTimeoutId = timeoutId = trailingCall = undefined;
13796 lastCalled = now();
13797 result = func.apply(thisArg, args);
13798 if (!timeoutId && !maxTimeoutId) {
13799 args = thisArg = null;
13803 timeoutId = setTimeout(delayed, remaining);
13807 var maxDelayed = function() {
13809 clearTimeout(timeoutId);
13811 maxTimeoutId = timeoutId = trailingCall = undefined;
13812 if (trailing || (maxWait !== wait)) {
13813 lastCalled = now();
13814 result = func.apply(thisArg, args);
13815 if (!timeoutId && !maxTimeoutId) {
13816 args = thisArg = null;
13821 return function() {
13825 trailingCall = trailing && (timeoutId || !leading);
13827 if (maxWait === false) {
13828 var leadingCall = leading && !timeoutId;
13830 if (!maxTimeoutId && !leading) {
13831 lastCalled = stamp;
13833 var remaining = maxWait - (stamp - lastCalled),
13834 isCalled = remaining <= 0 || remaining > maxWait;
13837 if (maxTimeoutId) {
13838 maxTimeoutId = clearTimeout(maxTimeoutId);
13840 lastCalled = stamp;
13841 result = func.apply(thisArg, args);
13843 else if (!maxTimeoutId) {
13844 maxTimeoutId = setTimeout(maxDelayed, remaining);
13847 if (isCalled && timeoutId) {
13848 timeoutId = clearTimeout(timeoutId);
13850 else if (!timeoutId && wait !== maxWait) {
13851 timeoutId = setTimeout(delayed, wait);
13855 result = func.apply(thisArg, args);
13857 if (isCalled && !timeoutId && !maxTimeoutId) {
13858 args = thisArg = null;
13865 * Defers executing the `func` function until the current call stack has cleared.
13866 * Additional arguments will be provided to `func` when it is invoked.
13870 * @category Functions
13871 * @param {Function} func The function to defer.
13872 * @param {...*} [args] Arguments to invoke the function with.
13873 * @returns {number} Returns the timer id.
13876 * _.defer(function(text) { console.log(text); }, 'deferred');
13877 * // logs 'deferred' after one or more milliseconds
13879 function defer(func) {
13880 if (!isFunction(func)) {
13881 throw new TypeError;
13883 var args = slice(arguments, 1);
13884 return setTimeout(function() { func.apply(undefined, args); }, 1);
13888 * Executes the `func` function after `wait` milliseconds. Additional arguments
13889 * will be provided to `func` when it is invoked.
13893 * @category Functions
13894 * @param {Function} func The function to delay.
13895 * @param {number} wait The number of milliseconds to delay execution.
13896 * @param {...*} [args] Arguments to invoke the function with.
13897 * @returns {number} Returns the timer id.
13900 * _.delay(function(text) { console.log(text); }, 1000, 'later');
13901 * // => logs 'later' after one second
13903 function delay(func, wait) {
13904 if (!isFunction(func)) {
13905 throw new TypeError;
13907 var args = slice(arguments, 2);
13908 return setTimeout(function() { func.apply(undefined, args); }, wait);
13912 * Creates a function that memoizes the result of `func`. If `resolver` is
13913 * provided it will be used to determine the cache key for storing the result
13914 * based on the arguments provided to the memoized function. By default, the
13915 * first argument provided to the memoized function is used as the cache key.
13916 * The `func` is executed with the `this` binding of the memoized function.
13917 * The result cache is exposed as the `cache` property on the memoized function.
13921 * @category Functions
13922 * @param {Function} func The function to have its output memoized.
13923 * @param {Function} [resolver] A function used to resolve the cache key.
13924 * @returns {Function} Returns the new memoizing function.
13927 * var fibonacci = _.memoize(function(n) {
13928 * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
13935 * 'fred': { 'name': 'fred', 'age': 40 },
13936 * 'pebbles': { 'name': 'pebbles', 'age': 1 }
13939 * // modifying the result cache
13940 * var get = _.memoize(function(name) { return data[name]; }, _.identity);
13942 * // => { 'name': 'pebbles', 'age': 1 }
13944 * get.cache.pebbles.name = 'penelope';
13946 * // => { 'name': 'penelope', 'age': 1 }
13948 function memoize(func, resolver) {
13949 if (!isFunction(func)) {
13950 throw new TypeError;
13952 var memoized = function() {
13953 var cache = memoized.cache,
13954 key = resolver ? resolver.apply(this, arguments) : '_' + arguments[0];
13956 return hasOwnProperty.call(cache, key)
13958 : (cache[key] = func.apply(this, arguments));
13960 memoized.cache = {};
13965 * Creates a function that is restricted to execute `func` once. Repeat calls to
13966 * the function will return the value of the first call. The `func` is executed
13967 * with the `this` binding of the created function.
13971 * @category Functions
13972 * @param {Function} func The function to restrict.
13973 * @returns {Function} Returns the new restricted function.
13976 * var initialize = _.once(createApplication);
13979 * // `initialize` executes `createApplication` once
13981 function once(func) {
13985 if (!isFunction(func)) {
13986 throw new TypeError;
13988 return function() {
13993 result = func.apply(this, arguments);
13995 // clear the `func` variable so the function may be garbage collected
14002 * Creates a function that, when called, invokes `func` with any additional
14003 * `partial` arguments prepended to those provided to the new function. This
14004 * method is similar to `_.bind` except it does **not** alter the `this` binding.
14006 * Note: This method does not set the `length` property of partially applied
14011 * @category Functions
14012 * @param {Function} func The function to partially apply arguments to.
14013 * @param {...*} [args] Arguments to be partially applied.
14014 * @returns {Function} Returns the new partially applied function.
14017 * var greet = function(greeting, name) { return greeting + ' ' + name; };
14018 * var hi = _.partial(greet, 'hi');
14022 function partial(func) {
14024 var arity = func[expando] ? func[expando][2] : func.length,
14025 partialArgs = slice(arguments, 1);
14027 arity -= partialArgs.length;
14029 return createWrapper(func, PARTIAL_FLAG, arity, null, partialArgs);
14033 * This method is like `_.partial` except that `partial` arguments are
14034 * appended to those provided to the new function.
14036 * Note: This method does not set the `length` property of partially applied
14041 * @category Functions
14042 * @param {Function} func The function to partially apply arguments to.
14043 * @param {...*} [args] Arguments to be partially applied.
14044 * @returns {Function} Returns the new partially applied function.
14047 * var defaultsDeep = _.partialRight(_.merge, _.defaults);
14050 * 'variable': 'data',
14051 * 'imports': { 'jq': $ }
14054 * defaultsDeep(options, _.templateSettings);
14060 * // => { '_': _, 'jq': $ }
14062 function partialRight(func) {
14064 var arity = func[expando] ? func[expando][2] : func.length,
14065 partialRightArgs = slice(arguments, 1);
14067 arity -= partialRightArgs.length;
14069 return createWrapper(func, PARTIAL_RIGHT_FLAG, arity, null, null, partialRightArgs);
14073 * Creates a function that, when executed, will only call the `func` function
14074 * at most once per every `wait` milliseconds. Provide an options object to
14075 * indicate that `func` should be invoked on the leading and/or trailing edge
14076 * of the `wait` timeout. Subsequent calls to the throttled function will
14077 * return the result of the last `func` call.
14079 * Note: If `leading` and `trailing` options are `true` `func` will be called
14080 * on the trailing edge of the timeout only if the the throttled function is
14081 * invoked more than once during the `wait` timeout.
14085 * @category Functions
14086 * @param {Function} func The function to throttle.
14087 * @param {number} wait The number of milliseconds to throttle executions to.
14088 * @param {Object} [options] The options object.
14089 * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
14090 * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
14091 * @returns {Function} Returns the new throttled function.
14094 * // avoid excessively updating the position while scrolling
14095 * var throttled = _.throttle(updatePosition, 100);
14096 * jQuery(window).on('scroll', throttled);
14098 * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
14099 * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
14100 * 'trailing': false
14103 function throttle(func, wait, options) {
14104 var leading = true,
14107 if (!isFunction(func)) {
14108 throw new TypeError;
14110 if (options === false) {
14112 } else if (isObject(options)) {
14113 leading = 'leading' in options ? options.leading : leading;
14114 trailing = 'trailing' in options ? options.trailing : trailing;
14116 debounceOptions.leading = leading;
14117 debounceOptions.maxWait = wait;
14118 debounceOptions.trailing = trailing;
14120 return debounce(func, wait, debounceOptions);
14124 * Creates a function that provides `value` to the wrapper function as its
14125 * first argument. Additional arguments provided to the function are appended
14126 * to those provided to the wrapper function. The wrapper is executed with
14127 * the `this` binding of the created function.
14131 * @category Functions
14132 * @param {*} value The value to wrap.
14133 * @param {Function} wrapper The wrapper function.
14134 * @returns {Function} Returns the new function.
14137 * var p = _.wrap(_.escape, function(func, text) {
14138 * return '<p>' + func(text) + '</p>';
14141 * p('fred, barney, & pebbles');
14142 * // => '<p>fred, barney, & pebbles</p>'
14144 function wrap(value, wrapper) {
14145 return createWrapper(wrapper, PARTIAL_FLAG, null, null, [value]);
14148 /*--------------------------------------------------------------------------*/
14152 * Assigns own enumerable properties of source object(s) to the destination
14153 * object. Subsequent sources will overwrite property assignments of previous
14154 * sources. If a callback is provided it will be executed to produce the
14155 * assigned values. The callback is bound to `thisArg` and invoked with two
14156 * arguments; (objectValue, sourceValue).
14161 * @category Objects
14162 * @param {Object} object The destination object.
14163 * @param {...Object} [source] The source objects.
14164 * @param {Function} [callback] The function to customize assigning values.
14165 * @param {*} [thisArg] The `this` binding of `callback`.
14166 * @returns {Object} Returns the destination object.
14169 * _.assign({ 'name': 'fred' }, { 'employer': 'slate' });
14170 * // => { 'name': 'fred', 'employer': 'slate' }
14172 * var defaults = _.partialRight(_.assign, function(a, b) {
14173 * return typeof a == 'undefined' ? b : a;
14176 * defaults({ 'name': 'barney' }, { 'name': 'fred', 'employer': 'slate' });
14177 * // => { 'name': 'barney', 'employer': 'slate' }
14179 function assign(object, source, guard) {
14180 var args = arguments,
14182 argsLength = args.length,
14183 type = typeof guard;
14185 // enables use as a callback for functions like `_.reduce`
14186 if ((type == 'number' || type == 'string') && args[3] && args[3][guard] === source) {
14189 // juggle arguments
14190 if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {
14191 var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);
14192 } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {
14193 callback = args[--argsLength];
14195 while (++argsIndex < argsLength) {
14196 source = args[argsIndex];
14197 if (isObject(source)) {
14199 props = keys(source),
14200 length = props.length;
14202 while (++index < length) {
14203 var key = props[index];
14204 object[key] = callback ? callback(object[key], source[key]) : source[key];
14212 * Creates a clone of `value`. If `isDeep` is `true` nested objects will also
14213 * be cloned, otherwise they will be assigned by reference. If a callback
14214 * is provided it will be executed to produce the cloned values. If the
14215 * callback returns `undefined` cloning will be handled by the method instead.
14216 * The callback is bound to `thisArg` and invoked with one argument; (value).
14218 * Note: This method is loosely based on the structured clone algorithm. Functions
14219 * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
14220 * objects created by constructors other than `Object` are cloned to plain `Object` objects.
14221 * See the [HTML5 specification](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm)
14222 * for more details.
14226 * @category Objects
14227 * @param {*} value The value to clone.
14228 * @param {boolean} [isDeep=false] Specify a deep clone.
14229 * @param {Function} [callback] The function to customize cloning values.
14230 * @param {*} [thisArg] The `this` binding of `callback`.
14231 * @returns {*} Returns the cloned value.
14234 * var characters = [
14235 * { 'name': 'barney', 'age': 36 },
14236 * { 'name': 'fred', 'age': 40 }
14239 * var shallow = _.clone(characters);
14240 * shallow[0] === characters[0];
14243 * var deep = _.clone(characters, true);
14244 * deep[0] === characters[0];
14248 * 'clone': _.partialRight(_.clone, function(value) {
14249 * return _.isElement(value) ? value.cloneNode(false) : undefined;
14253 * var clone = _.clone(document.body);
14254 * clone.childNodes.length;
14257 function clone(value, isDeep, callback, thisArg) {
14258 var type = typeof isDeep;
14260 // juggle arguments
14261 if (type != 'boolean' && isDeep != null) {
14262 thisArg = callback;
14266 // enables use as a callback for functions like `_.map`
14267 if ((type == 'number' || type == 'string') && thisArg && thisArg[callback] === value) {
14271 return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
14275 * Creates a deep clone of `value`. If a callback is provided it will be
14276 * executed to produce the cloned values. If the callback returns `undefined`
14277 * cloning will be handled by the method instead. The callback is bound to
14278 * `thisArg` and invoked with one argument; (value).
14280 * Note: This method is loosely based on the structured clone algorithm. Functions
14281 * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
14282 * objects created by constructors other than `Object` are cloned to plain `Object` objects.
14283 * See the [HTML5 specification](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm)
14284 * for more details.
14288 * @category Objects
14289 * @param {*} value The value to deep clone.
14290 * @param {Function} [callback] The function to customize cloning values.
14291 * @param {*} [thisArg] The `this` binding of `callback`.
14292 * @returns {*} Returns the deep cloned value.
14295 * var characters = [
14296 * { 'name': 'barney', 'age': 36 },
14297 * { 'name': 'fred', 'age': 40 }
14300 * var deep = _.cloneDeep(characters);
14301 * deep[0] === characters[0];
14309 * var clone = _.cloneDeep(view, function(value) {
14310 * return _.isElement(value) ? value.cloneNode(true) : undefined;
14313 * clone.node == view.node;
14316 function cloneDeep(value, callback, thisArg) {
14317 return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
14321 * Creates an object that inherits from the given `prototype` object. If a
14322 * `properties` object is provided its own enumerable properties are assigned
14323 * to the created object.
14327 * @category Objects
14328 * @param {Object} prototype The object to inherit from.
14329 * @param {Object} [properties] The properties to assign to the object.
14330 * @returns {Object} Returns the new object.
14333 * function Shape() {
14338 * function Circle() {
14339 * Shape.call(this);
14342 * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
14344 * var circle = new Circle;
14345 * circle instanceof Circle;
14348 * circle instanceof Shape;
14351 function create(prototype, properties) {
14352 var result = baseCreate(prototype);
14353 return properties ? assign(result, properties) : result;
14357 * Assigns own enumerable properties of source object(s) to the destination
14358 * object for all destination properties that resolve to `undefined`. Once a
14359 * property is set, additional defaults of the same property will be ignored.
14363 * @category Objects
14364 * @param {Object} object The destination object.
14365 * @param {...Object} [source] The source objects.
14366 * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`.
14367 * @returns {Object} Returns the destination object.
14370 * _.defaults({ 'name': 'barney' }, { 'name': 'fred', 'employer': 'slate' });
14371 * // => { 'name': 'barney', 'employer': 'slate' }
14373 function defaults(object, source, guard) {
14374 var args = arguments,
14376 argsLength = args.length,
14377 type = typeof guard;
14379 // enables use as a callback for functions like `_.reduce`
14380 if ((type == 'number' || type == 'string') && args[3] && args[3][guard] === source) {
14383 while (++argsIndex < argsLength) {
14384 source = args[argsIndex];
14385 if (isObject(source)) {
14387 props = keys(source),
14388 length = props.length;
14390 while (++index < length) {
14391 var key = props[index];
14392 if (typeof object[key] == 'undefined') {
14393 object[key] = source[key];
14402 * This method is like `_.findIndex` except that it returns the key of the
14403 * first element that passes the callback check, instead of the element itself.
14405 * If a property name is provided for `callback` the created "_.pluck" style
14406 * callback will return the property value of the given element.
14408 * If an object is provided for `callback` the created "_.where" style callback
14409 * will return `true` for elements that have the properties of the given object,
14414 * @category Objects
14415 * @param {Object} object The object to search.
14416 * @param {Function|Object|string} [callback=identity] The function called per
14417 * iteration. If a property name or object is provided it will be used to
14418 * create a "_.pluck" or "_.where" style callback, respectively.
14419 * @param {*} [thisArg] The `this` binding of `callback`.
14420 * @returns {string|undefined} Returns the key of the found element, else `undefined`.
14423 * var characters = {
14424 * 'barney': { 'age': 36 },
14425 * 'fred': { 'age': 40, 'blocked': true },
14426 * 'pebbles': { 'age': 1 }
14429 * _.findKey(characters, function(chr) {
14430 * return chr.age < 40;
14432 * // => 'barney' (property order is not guaranteed across environments)
14434 * // using "_.where" callback shorthand
14435 * _.findKey(characters, { 'age': 1 });
14438 * // using "_.pluck" callback shorthand
14439 * _.findKey(characters, 'blocked');
14442 function findKey(object, callback, thisArg) {
14445 callback = lodash.createCallback(callback, thisArg, 3);
14446 baseForOwn(object, function(value, key, object) {
14447 if (callback(value, key, object)) {
14456 * This method is like `_.findKey` except that it iterates over elements
14457 * of a `collection` in the opposite order.
14459 * If a property name is provided for `callback` the created "_.pluck" style
14460 * callback will return the property value of the given element.
14462 * If an object is provided for `callback` the created "_.where" style callback
14463 * will return `true` for elements that have the properties of the given object,
14468 * @category Objects
14469 * @param {Object} object The object to search.
14470 * @param {Function|Object|string} [callback=identity] The function called per
14471 * iteration. If a property name or object is provided it will be used to
14472 * create a "_.pluck" or "_.where" style callback, respectively.
14473 * @param {*} [thisArg] The `this` binding of `callback`.
14474 * @returns {string|undefined} Returns the key of the found element, else `undefined`.
14477 * var characters = {
14478 * 'barney': { 'age': 36, 'blocked': true },
14479 * 'fred': { 'age': 40 },
14480 * 'pebbles': { 'age': 1, 'blocked': true }
14483 * _.findLastKey(characters, function(chr) {
14484 * return chr.age < 40;
14486 * // => returns `pebbles`, assuming `_.findKey` returns `barney`
14488 * // using "_.where" callback shorthand
14489 * _.findLastKey(characters, { 'age': 40 });
14492 * // using "_.pluck" callback shorthand
14493 * _.findLastKey(characters, 'blocked');
14496 function findLastKey(object, callback, thisArg) {
14499 callback = lodash.createCallback(callback, thisArg, 3);
14500 baseForOwnRight(object, function(value, key, object) {
14501 if (callback(value, key, object)) {
14510 * Iterates over own and inherited enumerable properties of an object,
14511 * executing the callback for each property. The callback is bound to `thisArg`
14512 * and invoked with three arguments; (value, key, object). Callbacks may exit
14513 * iteration early by explicitly returning `false`.
14518 * @category Objects
14519 * @param {Object} object The object to iterate over.
14520 * @param {Function} [callback=identity] The function called per iteration.
14521 * @param {*} [thisArg] The `this` binding of `callback`.
14522 * @returns {Object} Returns `object`.
14525 * function Shape() {
14530 * Shape.prototype.move = function(x, y) {
14535 * _.forIn(new Shape, function(value, key) {
14536 * console.log(key);
14538 * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments)
14540 function forIn(object, callback, thisArg) {
14541 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
14542 return baseForIn(object, callback);
14546 * This method is like `_.forIn` except that it iterates over elements
14547 * of a `collection` in the opposite order.
14551 * @category Objects
14552 * @param {Object} object The object to iterate over.
14553 * @param {Function} [callback=identity] The function called per iteration.
14554 * @param {*} [thisArg] The `this` binding of `callback`.
14555 * @returns {Object} Returns `object`.
14558 * function Shape() {
14563 * Shape.prototype.move = function(x, y) {
14568 * _.forInRight(new Shape, function(value, key) {
14569 * console.log(key);
14571 * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move'
14573 function forInRight(object, callback, thisArg) {
14575 baseForIn(object, function(value, key) {
14576 pairs.push(key, value);
14579 var length = pairs.length;
14580 callback = baseCreateCallback(callback, thisArg, 3);
14582 if (callback(pairs[length--], pairs[length], object) === false) {
14590 * Iterates over own enumerable properties of an object, executing the callback
14591 * for each property. The callback is bound to `thisArg` and invoked with three
14592 * arguments; (value, key, object). Callbacks may exit iteration early by
14593 * explicitly returning `false`.
14597 * @category Objects
14598 * @param {Object} object The object to iterate over.
14599 * @param {Function} [callback=identity] The function called per iteration.
14600 * @param {*} [thisArg] The `this` binding of `callback`.
14601 * @returns {Object} Returns `object`.
14604 * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
14605 * console.log(key);
14607 * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
14609 function forOwn(object, callback, thisArg) {
14610 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
14611 return baseForOwn(object, callback);
14615 * This method is like `_.forOwn` except that it iterates over elements
14616 * of a `collection` in the opposite order.
14620 * @category Objects
14621 * @param {Object} object The object to iterate over.
14622 * @param {Function} [callback=identity] The function called per iteration.
14623 * @param {*} [thisArg] The `this` binding of `callback`.
14624 * @returns {Object} Returns `object`.
14627 * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
14628 * console.log(key);
14630 * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
14632 function forOwnRight(object, callback, thisArg) {
14633 var props = keys(object),
14634 length = props.length;
14636 callback = baseCreateCallback(callback, thisArg, 3);
14638 var key = props[length];
14639 if (callback(object[key], key, object) === false) {
14647 * Creates a sorted array of property names of all enumerable properties,
14648 * own and inherited, of `object` that have function values.
14653 * @category Objects
14654 * @param {Object} object The object to inspect.
14655 * @returns {Array} Returns an array of property names that have function values.
14659 * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
14661 function functions(object) {
14663 baseForIn(object, function(value, key) {
14664 if (isFunction(value)) {
14668 return result.sort();
14672 * Checks if the specified property name exists as a direct property of `object`,
14673 * instead of an inherited property.
14677 * @category Objects
14678 * @param {Object} object The object to inspect.
14679 * @param {string} key The name of the property to check.
14680 * @returns {boolean} Returns `true` if key is a direct property, else `false`.
14683 * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
14686 function has(object, key) {
14687 return object ? hasOwnProperty.call(object, key) : false;
14691 * Creates an object composed of the inverted keys and values of the given
14692 * object. If the given object contains duplicate values, subsequent values
14693 * will overwrite property assignments of previous values unless `multiValue`
14698 * @category Objects
14699 * @param {Object} object The object to invert.
14700 * @param {boolean} [multiValue=false] Allow multiple values per key.
14701 * @returns {Object} Returns the created inverted object.
14704 * _.invert({ 'first': 'fred', 'second': 'barney' });
14705 * // => { 'fred': 'first', 'barney': 'second' }
14707 * // without `multiValue`
14708 * _.invert({ 'first': 'fred', 'second': 'barney', 'third': 'fred' });
14709 * // => { 'fred': 'third', 'barney': 'second' }
14711 * // with `multiValue`
14712 * _.invert({ 'first': 'fred', 'second': 'barney', 'third': 'fred' }, true);
14713 * // => { 'fred': ['first', 'third'], 'barney': ['second'] }
14715 function invert(object, multiValue) {
14717 props = keys(object),
14718 length = props.length,
14721 while (++index < length) {
14722 var key = props[index],
14723 value = object[key];
14726 if (hasOwnProperty.call(result, value)) {
14727 result[value].push(key);
14729 result[value] = [key];
14733 result[value] = key;
14740 * Checks if `value` is an array.
14745 * @category Objects
14746 * @param {*} value The value to check.
14747 * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
14750 * (function() { return _.isArray(arguments); })();
14753 * _.isArray([1, 2, 3]);
14756 var isArray = nativeIsArray || function(value) {
14757 return value && typeof value == 'object' && typeof value.length == 'number' &&
14758 toString.call(value) == arrayClass || false;
14762 * Checks if `value` is a boolean value.
14766 * @category Objects
14767 * @param {*} value The value to check.
14768 * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
14771 * _.isBoolean(null);
14774 function isBoolean(value) {
14775 return value === true || value === false ||
14776 value && typeof value == 'object' && toString.call(value) == boolClass || false;
14780 * Checks if `value` is a date.
14784 * @category Objects
14785 * @param {*} value The value to check.
14786 * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
14789 * _.isDate(new Date);
14792 function isDate(value) {
14793 return value && typeof value == 'object' && toString.call(value) == dateClass || false;
14797 * Checks if `value` is a DOM element.
14801 * @category Objects
14802 * @param {*} value The value to check.
14803 * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
14806 * _.isElement(document.body);
14809 function isElement(value) {
14810 return value && typeof value == 'object' && value.nodeType === 1 &&
14811 (support.nodeClass ? toString.call(value).indexOf('Element') > -1 : isNode(value)) || false;
14813 // fallback for environments without DOM support
14814 if (!support.dom) {
14815 isElement = function(value) {
14816 return value && typeof value == 'object' && value.nodeType === 1 &&
14817 !isPlainObject(value) || false;
14822 * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
14823 * length of `0` and objects with no own enumerable properties are considered
14828 * @category Objects
14829 * @param {Array|Object|string} value The value to inspect.
14830 * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
14833 * _.isEmpty([1, 2, 3]);
14842 function isEmpty(value) {
14847 var className = toString.call(value),
14848 length = value.length;
14850 if ((className == arrayClass || className == stringClass ||
14851 (support.argsClass ? className == argsClass : isArguments(value))) ||
14852 (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
14855 baseForOwn(value, function() {
14856 return (result = false);
14862 * Performs a deep comparison between two values to determine if they are
14863 * equivalent to each other. If a callback is provided it will be executed
14864 * to compare values. If the callback returns `undefined` comparisons will
14865 * be handled by the method instead. The callback is bound to `thisArg` and
14866 * invoked with two arguments; (a, b).
14870 * @category Objects
14871 * @param {*} a The value to compare.
14872 * @param {*} b The other value to compare.
14873 * @param {Function} [callback] The function to customize comparing values.
14874 * @param {*} [thisArg] The `this` binding of `callback`.
14875 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
14878 * var object = { 'name': 'fred' };
14879 * var copy = { 'name': 'fred' };
14884 * _.isEqual(object, copy);
14887 * var words = ['hello', 'goodbye'];
14888 * var otherWords = ['hi', 'goodbye'];
14890 * _.isEqual(words, otherWords, function(a, b) {
14891 * var reGreet = /^(?:hello|hi)$/i,
14892 * aGreet = _.isString(a) && reGreet.test(a),
14893 * bGreet = _.isString(b) && reGreet.test(b);
14895 * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
14899 function isEqual(a, b, callback, thisArg) {
14900 return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
14904 * Checks if `value` is, or can be coerced to, a finite number.
14906 * Note: This method is not the same as native `isFinite` which will return
14907 * `true` for booleans and empty strings. See the [ES5 spec](http://es5.github.io/#x15.1.2.5)
14908 * for more details.
14912 * @category Objects
14913 * @param {*} value The value to check.
14914 * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
14917 * _.isFinite(-101);
14920 * _.isFinite('10');
14923 * _.isFinite(true);
14929 * _.isFinite(Infinity);
14932 function isFinite(value) {
14933 return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
14937 * Checks if `value` is a function.
14941 * @category Objects
14942 * @param {*} value The value to check.
14943 * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
14949 function isFunction(value) {
14950 return typeof value == 'function';
14952 // fallback for older versions of Chrome and Safari
14953 if (isFunction(/x/)) {
14954 isFunction = function(value) {
14955 return typeof value == 'function' && toString.call(value) == funcClass;
14960 * Checks if `value` is the language type of Object.
14961 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
14965 * @category Objects
14966 * @param {*} value The value to check.
14967 * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
14973 * _.isObject([1, 2, 3]);
14979 function isObject(value) {
14980 // check if the value is the ECMAScript language type of Object
14981 // http://es5.github.io/#x8
14982 // and avoid a V8 bug
14983 // https://code.google.com/p/v8/issues/detail?id=2291
14984 var type = typeof value;
14985 return value && (type == 'function' || type == 'object') || false;
14989 * Checks if `value` is `NaN`.
14991 * Note: This method is not the same as native `isNaN` which will return `true`
14992 * for `undefined` and other non-numeric values. See the [ES5 spec](http://es5.github.io/#x15.1.2.4)
14993 * for more details.
14997 * @category Objects
14998 * @param {*} value The value to check.
14999 * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
15005 * _.isNaN(new Number(NaN));
15008 * isNaN(undefined);
15011 * _.isNaN(undefined);
15014 function isNaN(value) {
15015 // `NaN` as a primitive is the only value that is not equal to itself
15016 // (perform the [[Class]] check first to avoid errors with some host objects in IE)
15017 return isNumber(value) && value != +value;
15021 * Checks if `value` is `null`.
15025 * @category Objects
15026 * @param {*} value The value to check.
15027 * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
15033 * _.isNull(undefined);
15036 function isNull(value) {
15037 return value === null;
15041 * Checks if `value` is a number.
15043 * Note: `NaN` is considered a number. See the [ES5 spec](http://es5.github.io/#x8.5)
15044 * for more details.
15048 * @category Objects
15049 * @param {*} value The value to check.
15050 * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
15053 * _.isNumber(8.4 * 5);
15056 function isNumber(value) {
15057 var type = typeof value;
15058 return type == 'number' ||
15059 value && type == 'object' && toString.call(value) == numberClass || false;
15063 * Checks if `value` is an object created by the `Object` constructor.
15067 * @category Objects
15068 * @param {*} value The value to check.
15069 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
15072 * function Shape() {
15077 * _.isPlainObject(new Shape);
15080 * _.isPlainObject([1, 2, 3]);
15083 * _.isPlainObject({ 'x': 0, 'y': 0 });
15086 var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) {
15087 if (!(value && toString.call(value) == objectClass) || (!support.argsClass && isArguments(value))) {
15090 var valueOf = value.valueOf,
15091 objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
15094 ? (value == objProto || getPrototypeOf(value) == objProto)
15095 : shimIsPlainObject(value);
15099 * Checks if `value` is a regular expression.
15103 * @category Objects
15104 * @param {*} value The value to check.
15105 * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
15108 * _.isRegExp(/fred/);
15111 function isRegExp(value) {
15112 var type = typeof value;
15113 return value && (type == 'function' || type == 'object') &&
15114 toString.call(value) == regexpClass || false;
15118 * Checks if `value` is a string.
15122 * @category Objects
15123 * @param {*} value The value to check.
15124 * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
15127 * _.isString('fred');
15130 function isString(value) {
15131 return typeof value == 'string' ||
15132 value && typeof value == 'object' && toString.call(value) == stringClass || false;
15136 * Checks if `value` is `undefined`.
15140 * @category Objects
15141 * @param {*} value The value to check.
15142 * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
15145 * _.isUndefined(void 0);
15148 function isUndefined(value) {
15149 return typeof value == 'undefined';
15153 * Creates an array composed of the own enumerable property names of an object.
15157 * @category Objects
15158 * @param {Object} object The object to inspect.
15159 * @returns {Array} Returns an array of property names.
15162 * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
15163 * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
15165 var keys = !nativeKeys ? shimKeys : function(object) {
15166 if (!isObject(object)) {
15169 if ((support.enumPrototypes && typeof object == 'function') ||
15170 (support.nonEnumArgs && object.length && isArguments(object))) {
15171 return shimKeys(object);
15173 return nativeKeys(object);
15177 * Creates an object with the same keys as `object` and values generated by
15178 * running each own enumerable property of `object` through the callback.
15179 * The callback is bound to `thisArg` and invoked with three arguments;
15180 * (value, key, object).
15182 * If a property name is provided for `callback` the created "_.pluck" style
15183 * callback will return the property value of the given element.
15185 * If an object is provided for `callback` the created "_.where" style callback
15186 * will return `true` for elements that have the properties of the given object,
15191 * @category Objects
15192 * @param {Object} object The object to iterate over.
15193 * @param {Function|Object|string} [callback=identity] The function called
15194 * per iteration. If a property name or object is provided it will be used
15195 * to create a "_.pluck" or "_.where" style callback, respectively.
15196 * @param {*} [thisArg] The `this` binding of `callback`.
15197 * @returns {Object} Returns a new object with values of the results of each `callback` execution.
15200 * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; });
15201 * // => { 'a': 3, 'b': 6, 'c': 9 }
15203 * var characters = {
15204 * 'fred': { 'name': 'fred', 'age': 40 },
15205 * 'pebbles': { 'name': 'pebbles', 'age': 1 }
15208 * // using "_.pluck" callback shorthand
15209 * _.mapValues(characters, 'age');
15210 * // => { 'fred': 40, 'pebbles': 1 }
15212 function mapValues(object, callback, thisArg) {
15215 callback = lodash.createCallback(callback, thisArg, 3);
15216 baseForOwn(object, function(value, key, object) {
15217 result[key] = callback(value, key, object);
15223 * Recursively merges own enumerable properties of the source object(s), that
15224 * don't resolve to `undefined` into the destination object. Subsequent sources
15225 * will overwrite property assignments of previous sources. If a callback is
15226 * provided it will be executed to produce the merged values of the destination
15227 * and source properties. If the callback returns `undefined` merging will
15228 * be handled by the method instead. The callback is bound to `thisArg` and
15229 * invoked with two arguments; (objectValue, sourceValue).
15233 * @category Objects
15234 * @param {Object} object The destination object.
15235 * @param {...Object} [source] The source objects.
15236 * @param {Function} [callback] The function to customize merging properties.
15237 * @param {*} [thisArg] The `this` binding of `callback`.
15238 * @returns {Object} Returns the destination object.
15243 * { 'name': 'barney' },
15244 * { 'name': 'fred' }
15255 * _.merge(names, ages);
15256 * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] }
15259 * 'fruits': ['apple'],
15260 * 'vegetables': ['beet']
15263 * var otherFood = {
15264 * 'fruits': ['banana'],
15265 * 'vegetables': ['carrot']
15268 * _.merge(food, otherFood, function(a, b) {
15269 * return _.isArray(a) ? a.concat(b) : undefined;
15271 * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
15273 function merge(object, source, guard) {
15274 if (!isObject(object)) {
15277 var args = arguments,
15278 length = args.length,
15279 type = typeof guard;
15281 // enables use as a callback for functions like `_.reduce`
15282 if ((type == 'number' || type == 'string') && args[3] && args[3][guard] === source) {
15285 // juggle arguments
15286 if (length > 3 && typeof args[length - 2] == 'function') {
15287 var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
15288 } else if (length > 2 && typeof args[length - 1] == 'function') {
15289 callback = args[--length];
15291 var sources = slice(arguments, 1, length),
15293 stackA = getArray(),
15294 stackB = getArray();
15296 while (++index < length) {
15297 baseMerge(object, sources[index], callback, stackA, stackB);
15299 releaseArray(stackA);
15300 releaseArray(stackB);
15305 * Creates a shallow clone of `object` excluding the specified properties.
15306 * Property names may be specified as individual arguments or as arrays of
15307 * property names. If a callback is provided it will be executed for each
15308 * property of `object` omitting the properties the callback returns truey
15309 * for. The callback is bound to `thisArg` and invoked with three arguments;
15310 * (value, key, object).
15314 * @category Objects
15315 * @param {Object} object The source object.
15316 * @param {Function|...string|string[]} [callback] The function called per
15317 * iteration or property names to omit, specified as individual property
15318 * names or arrays of property names.
15319 * @param {*} [thisArg] The `this` binding of `callback`.
15320 * @returns {Object} Returns an object without the omitted properties.
15323 * _.omit({ 'name': 'fred', 'age': 40 }, 'age');
15324 * // => { 'name': 'fred' }
15326 * _.omit({ 'name': 'fred', 'age': 40 }, function(value) {
15327 * return typeof value == 'number';
15329 * // => { 'name': 'fred' }
15331 function omit(object, callback, thisArg) {
15334 if (typeof callback != 'function') {
15335 var omitProps = baseFlatten(arguments, true, false, 1),
15336 length = omitProps.length;
15339 omitProps[length] = String(omitProps[length]);
15342 baseForIn(object, function(value, key) {
15347 props = baseDifference(props, omitProps);
15348 length = props.length;
15350 while (++index < length) {
15351 var key = props[index];
15352 result[key] = object[key];
15355 callback = lodash.createCallback(callback, thisArg, 3);
15356 baseForIn(object, function(value, key, object) {
15357 if (!callback(value, key, object)) {
15358 result[key] = value;
15366 * Creates a two dimensional array of an object's key-value pairs,
15367 * i.e. `[[key1, value1], [key2, value2]]`.
15371 * @category Objects
15372 * @param {Object} object The object to inspect.
15373 * @returns {Array} Returns new array of key-value pairs.
15376 * _.pairs({ 'barney': 36, 'fred': 40 });
15377 * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments)
15379 function pairs(object) {
15381 props = keys(object),
15382 length = props.length,
15383 result = Array(length);
15385 while (++index < length) {
15386 var key = props[index];
15387 result[index] = [key, object[key]];
15393 * Creates a shallow clone of `object` composed of the specified properties.
15394 * Property names may be specified as individual arguments or as arrays of
15395 * property names. If a callback is provided it will be executed for each
15396 * property of `object` picking the properties the callback returns truey
15397 * for. The callback is bound to `thisArg` and invoked with three arguments;
15398 * (value, key, object).
15402 * @category Objects
15403 * @param {Object} object The source object.
15404 * @param {Function|...string|string[]} [callback] The function called per
15405 * iteration or property names to pick, specified as individual property
15406 * names or arrays of property names.
15407 * @param {*} [thisArg] The `this` binding of `callback`.
15408 * @returns {Object} Returns an object composed of the picked properties.
15411 * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name');
15412 * // => { 'name': 'fred' }
15414 * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) {
15415 * return key.charAt(0) != '_';
15417 * // => { 'name': 'fred' }
15419 function pick(object, callback, thisArg) {
15422 if (typeof callback != 'function') {
15424 props = baseFlatten(arguments, true, false, 1),
15425 length = isObject(object) ? props.length : 0;
15427 while (++index < length) {
15428 var key = props[index];
15429 if (key in object) {
15430 result[key] = object[key];
15434 callback = lodash.createCallback(callback, thisArg, 3);
15435 baseForIn(object, function(value, key, object) {
15436 if (callback(value, key, object)) {
15437 result[key] = value;
15445 * An alternative to `_.reduce`; this method transforms `object` to a new
15446 * `accumulator` object which is the result of running each of its own
15447 * enumerable properties through a callback, with each callback execution
15448 * potentially mutating the `accumulator` object. The callback is bound to
15449 * `thisArg` and invoked with four arguments; (accumulator, value, key, object).
15450 * Callbacks may exit iteration early by explicitly returning `false`.
15454 * @category Objects
15455 * @param {Array|Object} object The object to iterate over.
15456 * @param {Function} [callback=identity] The function called per iteration.
15457 * @param {*} [accumulator] The custom accumulator value.
15458 * @param {*} [thisArg] The `this` binding of `callback`.
15459 * @returns {*} Returns the accumulated value.
15462 * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8], function(result, num) {
15465 * return result.push(num) < 3;
15470 * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
15471 * result[key] = num * 3;
15473 * // => { 'a': 3, 'b': 6, 'c': 9 }
15475 function transform(object, callback, accumulator, thisArg) {
15476 var isArr = isArray(object);
15477 if (accumulator == null) {
15481 var ctor = object && object.constructor,
15482 proto = ctor && ctor.prototype;
15484 accumulator = baseCreate(proto);
15488 callback = lodash.createCallback(callback, thisArg, 4);
15489 (isArr ? baseEach : baseForOwn)(object, function(value, index, object) {
15490 return callback(accumulator, value, index, object);
15493 return accumulator;
15497 * Creates an array composed of the own enumerable property values of `object`.
15501 * @category Objects
15502 * @param {Object} object The object to inspect.
15503 * @returns {Array} Returns an array of property values.
15506 * _.values({ 'one': 1, 'two': 2, 'three': 3 });
15507 * // => [1, 2, 3] (property order is not guaranteed across environments)
15509 function values(object) {
15511 props = keys(object),
15512 length = props.length,
15513 result = Array(length);
15515 while (++index < length) {
15516 result[index] = object[props[index]];
15521 /*--------------------------------------------------------------------------*/
15524 * Converts the first character of `string` to upper case.
15528 * @category Strings
15529 * @param {string} string The string to capitalize.
15530 * @returns {string} Returns the capitalized string.
15533 * _.capitalize('fred');
15536 function capitalize(string) {
15537 if (string == null) {
15540 string = String(string);
15541 return string.charAt(0).toUpperCase() + string.slice(1);
15545 * Converts the characters "&", "<", ">", '"', and "'" in `string` to
15546 * their corresponding HTML entities.
15548 * Note: No other characters are escaped. To escape additional characters
15549 * use a third-party library like [_he_](http://mths.be/he).
15551 * When working with HTML you should always quote attribute values to reduce
15552 * XSS vectors. See [Ryan Grove's article](http://wonko.com/post/html-escaping)
15553 * for more details.
15557 * @category Strings
15558 * @param {string} string The string to escape.
15559 * @returns {string} Returns the escaped string.
15562 * _.escape('fred, barney, & pebbles');
15563 * // => 'fred, barney, & pebbles'
15565 function escape(string) {
15566 return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
15570 * A micro-templating method that handles arbitrary delimiters, preserves
15571 * whitespace, and correctly escapes quotes within interpolated code.
15573 * Note: In the development build, `_.template` utilizes sourceURLs for easier
15574 * debugging. See [HTML5 Rocks' article on sourcemaps](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl)
15575 * for more details.
15577 * For more information on precompiling templates see
15578 * [Lo-Dash's custom builds documentation](http://lodash.com/custom-builds).
15580 * For more information on Chrome extension sandboxes see
15581 * [Chrome's extensions documentation](http://developer.chrome.com/stable/extensions/sandboxingEval.html).
15585 * @category Strings
15586 * @param {string} text The template text.
15587 * @param {Object} [data] The data object used to populate the text.
15588 * @param {Object} [options] The options object.
15589 * @param {RegExp} [options.escape] The "escape" delimiter.
15590 * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
15591 * @param {Object} [options.imports] An object to import into the template as local variables.
15592 * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
15593 * @param {string} [options.sourceURL] The sourceURL of the template's compiled source.
15594 * @param {string} [options.variable] The data object variable name.
15595 * @returns {Function|string} Returns a compiled function when no `data` object
15596 * is given, else it returns the interpolated text.
15599 * // using the "interpolate" delimiter to create a compiled template
15600 * var compiled = _.template('hello <%= name %>');
15601 * compiled({ 'name': 'fred' });
15602 * // => 'hello fred'
15604 * // using the "escape" delimiter to escape HTML in data property values
15605 * _.template('<b><%- value %></b>', { 'value': '<script>' });
15606 * // => '<b><script></b>'
15608 * // using the "evaluate" delimiter to generate HTML
15609 * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
15610 * _.template(list, { 'people': ['fred', 'barney'] });
15611 * // => '<li>fred</li><li>barney</li>'
15613 * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
15614 * _.template('hello ${ name }', { 'name': 'pebbles' });
15615 * // => 'hello pebbles'
15617 * // using the internal `print` function in "evaluate" delimiters
15618 * _.template('<% print("hello " + name); %>!', { 'name': 'barney' });
15619 * // => 'hello barney!'
15621 * // using a custom template delimiters
15622 * _.templateSettings = {
15623 * 'interpolate': /{{([\s\S]+?)}}/g
15626 * _.template('hello {{ name }}!', { 'name': 'mustache' });
15627 * // => 'hello mustache!'
15629 * // using the `imports` option to import jQuery
15630 * var list = '<% jq.each(people, function(name) { %><li><%- name %></li><% }); %>';
15631 * _.template(list, { 'people': ['fred', 'barney'] }, { 'imports': { 'jq': jQuery } });
15632 * // => '<li>fred</li><li>barney</li>'
15634 * // using the `sourceURL` option to specify a custom sourceURL for the template
15635 * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
15637 * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
15639 * // using the `variable` option to ensure a with-statement isn't used in the compiled template
15640 * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
15642 * // => function(data) {
15643 * var __t, __p = '', __e = _.escape;
15644 * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
15648 * // using the `source` property to inline compiled templates for meaningful
15649 * // line numbers in error messages and a stack trace
15650 * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
15652 * "main": ' + _.template(mainText).source + '\
15656 function template(text, data, options) {
15657 // based on John Resig's `tmpl` implementation
15658 // http://ejohn.org/blog/javascript-micro-templating/
15659 // and Laura Doktorova's doT.js
15660 // https://github.com/olado/doT
15661 var settings = lodash.templateSettings;
15662 text = String(text || '');
15664 // avoid missing dependencies when `iteratorTemplate` is not defined
15665 options = iteratorTemplate ? defaults({}, options, settings) : settings;
15667 var imports = iteratorTemplate && defaults({}, options.imports, settings.imports),
15668 importsKeys = iteratorTemplate ? keys(imports) : ['_'],
15669 importsValues = iteratorTemplate ? values(imports) : [lodash];
15673 interpolate = options.interpolate || reNoMatch,
15674 source = "__p += '";
15676 // compile the regexp to match each delimiter
15677 var reDelimiters = RegExp(
15678 (options.escape || reNoMatch).source + '|' +
15679 interpolate.source + '|' +
15680 (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
15681 (options.evaluate || reNoMatch).source + '|$'
15684 text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
15685 interpolateValue || (interpolateValue = esTemplateValue);
15687 // escape characters that cannot be included in string literals
15688 source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
15690 // replace delimiters with snippets
15692 source += "' +\n__e(" + escapeValue + ") +\n'";
15694 if (evaluateValue) {
15695 isEvaluating = true;
15696 source += "';\n" + evaluateValue + ";\n__p += '";
15698 if (interpolateValue) {
15699 source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
15701 index = offset + match.length;
15703 // the JS engine embedded in Adobe products requires returning the `match`
15704 // string in order to produce the correct `offset` value
15710 // if `variable` is not specified, wrap a with-statement around the generated
15711 // code to add the data object to the top of the scope chain
15712 var variable = options.variable,
15713 hasVariable = variable;
15715 if (!hasVariable) {
15717 source = 'with (' + variable + ') {\n' + source + '\n}\n';
15719 // cleanup code by stripping empty strings
15720 source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
15721 .replace(reEmptyStringMiddle, '$1')
15722 .replace(reEmptyStringTrailing, '$1;');
15724 // frame code as the function body
15725 source = 'function(' + variable + ') {\n' +
15726 (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
15727 "var __t, __p = '', __e = _.escape" +
15729 ? ', __j = Array.prototype.join;\n' +
15730 "function print() { __p += __j.call(arguments, '') }\n"
15736 // Use a sourceURL for easier debugging.
15737 // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
15738 var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
15741 var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
15747 return result(data);
15749 // provide the compiled function's source by its `toString` method, in
15750 // supported environments, or the `source` property as a convenience for
15751 // inlining compiled templates during the build process
15752 result.source = source;
15757 * Removes leading and trailing whitespace or specified characters from `string`.
15761 * @category Strings
15762 * @param {string} string The string to trim.
15763 * @param {string} [chars=whitespace] The characters to trim.
15764 * @returns {string} Returns the trimmed string.
15767 * _.trim(' fred ');
15770 * _.trim('-_-fred-_-', '_-');
15773 var trim = !nativeTrim ? shimTrim : function(string, chars) {
15774 if (string == null) {
15777 return chars == null ? nativeTrim.call(string) : shimTrim(string, chars);
15781 * Removes leading whitespace or specified characters from `string`.
15785 * @category Strings
15786 * @param {string} string The string to trim.
15787 * @param {string} [chars=whitespace] The characters to trim.
15788 * @returns {string} Returns the trimmed string.
15791 * _.trimLeft(' fred ');
15794 * _.trimLeft('-_-fred-_-', '_-');
15797 var trimLeft = !nativeTrimLeft ? shimTrimLeft : function(string, chars) {
15798 if (string == null) {
15801 return chars == null ? nativeTrimLeft.call(string) : shimTrimLeft(string, chars);
15805 * Removes trailing whitespace or specified characters from `string`.
15809 * @category Strings
15810 * @param {string} string The string to trim.
15811 * @param {string} [chars=whitespace] The characters to trim.
15812 * @returns {string} Returns the trimmed string.
15815 * _.trimRight(' fred ');
15818 * _.trimRight('-_-fred-_-', '_-');
15821 var trimRight = !nativeTrimRight ? shimTrimRight : function(string, chars) {
15822 if (string == null) {
15825 return chars == null ? nativeTrimRight.call(string) : shimTrimRight(string, chars);
15829 * The inverse of `_.escape`; this method converts the HTML entities
15830 * `&`, `<`, `>`, `"`, and `'` in `string` to their
15831 * corresponding characters.
15833 * Note: No other HTML entities are unescaped. To unescape additional HTML
15834 * entities use a third-party library like [_he_](http://mths.be/he).
15838 * @category Strings
15839 * @param {string} string The string to unescape.
15840 * @returns {string} Returns the unescaped string.
15843 * _.unescape('fred, barney & pebbles');
15844 * // => 'fred, barney & pebbles'
15846 function unescape(string) {
15847 if (string == null) {
15850 string = String(string);
15851 return string.indexOf(';') < 0 ? string : string.replace(reEscapedHtml, unescapeHtmlChar);
15854 /*--------------------------------------------------------------------------*/
15857 * Creates a function that returns `value`.
15861 * @category Utilities
15862 * @param {*} value The value to return from the new function.
15863 * @returns {Function} Returns the new function.
15866 * var object = { 'name': 'fred' };
15867 * var getter = _.constant(object);
15868 * getter() === object;
15871 function constant(value) {
15872 return function() {
15878 * Produces a callback bound to an optional `thisArg`. If `func` is a property
15879 * name the created callback will return the property value for a given element.
15880 * If `func` is an object the created callback will return `true` for elements
15881 * that contain the equivalent object properties, otherwise it will return `false`.
15886 * @category Utilities
15887 * @param {*} [func=identity] The value to convert to a callback.
15888 * @param {*} [thisArg] The `this` binding of the created callback.
15889 * @param {number} [argCount] The number of arguments the callback accepts.
15890 * @returns {Function} Returns a callback function.
15893 * var characters = [
15894 * { 'name': 'barney', 'age': 36 },
15895 * { 'name': 'fred', 'age': 40 }
15898 * // wrap to create custom callback shorthands
15899 * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
15900 * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
15901 * return !match ? func(callback, thisArg) : function(object) {
15902 * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
15906 * _.filter(characters, 'age__gt38');
15907 * // => [{ 'name': 'fred', 'age': 40 }]
15909 function createCallback(func, thisArg, argCount) {
15910 var type = typeof func;
15911 if (type == 'function' || func == null) {
15912 return (typeof thisArg == 'undefined' || !('prototype' in func)) &&
15913 func || baseCreateCallback(func, thisArg, argCount);
15915 // handle "_.pluck" and "_.where" style callback shorthands
15916 return type != 'object' ? property(func) : matches(func);
15920 * This method returns the first argument provided to it.
15924 * @category Utilities
15925 * @param {*} value Any value.
15926 * @returns {*} Returns `value`.
15929 * var object = { 'name': 'fred' };
15930 * _.identity(object) === object;
15933 function identity(value) {
15938 * Creates a "_.where" style function, which performs a deep comparison
15939 * between a given object and the `source` object, returning `true` if the
15940 * given object has equivalent property values, else `false`.
15944 * @category Utilities
15945 * @param {Object} source The object of property values to match.
15946 * @returns {Function} Returns the new function.
15949 * var characters = [
15950 * { 'name': 'fred', 'age': 40 },
15951 * { 'name': 'barney', 'age': 36 }
15954 * var matchesAge = _.matches({ 'age': 36 });
15956 * _.filter(characters, matchesAge);
15957 * // => [{ 'name': 'barney', 'age': 36 }]
15959 * _.find(characters, matchesAge);
15960 * // => { 'name': 'barney', 'age': 36 }
15962 function matches(source) {
15963 source || (source = {});
15965 var props = keys(source),
15969 // fast path the common case of providing an object with a single
15970 // property containing a primitive value
15971 if (props.length == 1 && a === a && !isObject(a)) {
15972 return function(object) {
15973 if (!hasOwnProperty.call(object, key)) {
15976 var b = object[key];
15977 return a === b && (a !== 0 || (1 / a == 1 / b));
15980 return function(object) {
15981 var length = props.length,
15985 var key = props[length];
15986 if (!(result = hasOwnProperty.call(object, key) &&
15987 baseIsEqual(object[key], source[key], null, true))) {
15996 * Adds function properties of a source object to the destination object.
15997 * If `object` is a function methods will be added to its prototype as well.
16001 * @category Utilities
16002 * @param {Function|Object} [object=lodash] object The destination object.
16003 * @param {Object} source The object of functions to add.
16004 * @param {Object} [options] The options object.
16005 * @param {boolean} [options.chain=true] Specify whether the functions added are chainable.
16008 * function vowels(string) {
16009 * return _.filter(string, function(v) {
16010 * return /[aeiou]/i.test(v);
16014 * _.mixin({ 'vowels': vowels });
16015 * _.vowels('fred');
16018 * _('fred').vowels().value();
16021 * _.mixin({ 'vowels': vowels }, { 'chain': false });
16022 * _('fred').vowels();
16025 function mixin(object, source, options) {
16027 methodNames = source && functions(source);
16029 if (!source || (!options && !methodNames.length)) {
16030 if (options == null) {
16035 methodNames = functions(source);
16037 if (options === false) {
16039 } else if (isObject(options) && 'chain' in options) {
16040 chain = options.chain;
16043 isFunc = isFunction(object),
16044 length = methodNames ? methodNames.length : 0;
16046 while (++index < length) {
16047 var methodName = methodNames[index],
16048 func = object[methodName] = source[methodName];
16051 object.prototype[methodName] = (function(func) {
16052 return function() {
16053 var chainAll = this.__chain__,
16054 value = this.__wrapped__,
16057 push.apply(args, arguments);
16058 var result = func.apply(object, args);
16059 if (chain || chainAll) {
16060 if (value === result && isObject(result)) {
16063 result = new object(result);
16064 result.__chain__ = chainAll;
16074 * Reverts the '_' variable to its previous value and returns a reference to
16075 * the `lodash` function.
16079 * @category Utilities
16080 * @returns {Function} Returns the `lodash` function.
16083 * var lodash = _.noConflict();
16085 function noConflict() {
16086 context._ = oldDash;
16091 * A no-operation function.
16095 * @category Utilities
16098 * var object = { 'name': 'fred' };
16099 * _.noop(object) === undefined;
16103 // no operation performed
16107 * Gets the number of milliseconds that have elapsed since the Unix epoch
16108 * (1 January 1970 00:00:00 UTC).
16112 * @category Utilities
16115 * var stamp = _.now();
16116 * _.defer(function() { console.log(_.now() - stamp); });
16117 * // => logs the number of milliseconds it took for the deferred function to be called
16119 var now = nativeNow || function() {
16120 return new Date().getTime();
16124 * Converts `value` to an integer of the specified radix. If `radix` is
16125 * `undefined` or `0` a `radix` of `10` is used unless the `value` is a
16126 * hexadecimal, in which case a `radix` of `16` is used.
16128 * Note: This method avoids differences in native ES3 and ES5 `parseInt`
16129 * implementations. See the [ES5 spec](http://es5.github.io/#E)
16130 * for more details.
16134 * @category Utilities
16135 * @param {string} value The value to parse.
16136 * @param {number} [radix] The radix used to interpret the value to parse.
16137 * @returns {number} Returns the new integer value.
16140 * _.parseInt('08');
16143 var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
16144 // Firefox < 21 and Opera < 15 follow ES3 for `parseInt` and
16145 // Chrome fails to trim leading <BOM> whitespace characters.
16146 // See https://code.google.com/p/v8/issues/detail?id=3109
16147 value = trim(value);
16148 return nativeParseInt(value, +radix || (reHexPrefix.test(value) ? 16 : 10));
16152 * Creates a "_.pluck" style function, which returns the `key` value of a
16157 * @category Utilities
16158 * @param {string} key The name of the property to retrieve.
16159 * @returns {Function} Returns the new function.
16162 * var characters = [
16163 * { 'name': 'fred', 'age': 40 },
16164 * { 'name': 'barney', 'age': 36 }
16167 * var getName = _.property('name');
16169 * _.map(characters, getName);
16170 * // => ['barney', 'fred']
16172 * _.sortBy(characters, getName);
16173 * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }]
16175 function property(key) {
16176 return function(object) {
16177 return object[key];
16182 * Produces a random number between `min` and `max` (inclusive). If only one
16183 * argument is provided a number between `0` and the given number will be
16184 * returned. If `floating` is truey or either `min` or `max` are floats a
16185 * floating-point number will be returned instead of an integer.
16189 * @category Utilities
16190 * @param {number} [min=0] The minimum possible value.
16191 * @param {number} [max=1] The maximum possible value.
16192 * @param {boolean} [floating=false] Specify returning a floating-point number.
16193 * @returns {number} Returns a random number.
16197 * // => an integer between 0 and 5
16200 * // => also an integer between 0 and 5
16202 * _.random(5, true);
16203 * // => a floating-point number between 0 and 5
16205 * _.random(1.2, 5.2);
16206 * // => a floating-point number between 1.2 and 5.2
16208 function random(min, max, floating) {
16209 var noMin = min == null,
16210 noMax = max == null;
16212 if (floating == null) {
16213 if (noMax && typeof min == 'boolean') {
16217 else if (typeof max == 'boolean') {
16222 if (noMin && noMax) {
16233 if (floating || min % 1 || max % 1) {
16234 var rand = nativeRandom();
16235 return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max);
16237 return baseRandom(min, max);
16241 * Resolves the value of property `key` on `object`. If `key` is a function
16242 * it will be invoked with the `this` binding of `object` and its result
16243 * returned, else the property value is returned. If `object` is `null` or
16244 * `undefined` then `undefined` is returned. If a default value is provided
16245 * it will be returned if the property value resolves to `undefined`.
16249 * @category Utilities
16250 * @param {Object} object The object to inspect.
16251 * @param {string} key The name of the property to resolve.
16252 * @param {*} [defaultValue] The value returned if the property value
16253 * resolves to `undefined`.
16254 * @returns {*} Returns the resolved value.
16259 * 'age': function() {
16264 * _.result(object, 'name');
16267 * _.result(object, 'age');
16270 * _.result(object, 'employer', 'slate');
16273 function result(object, key, defaultValue) {
16274 var value = object == null ? undefined : object[key];
16275 if (typeof value == 'undefined') {
16276 return defaultValue;
16278 return isFunction(value) ? object[key]() : value;
16282 * Executes the callback `n` times, returning an array of the results
16283 * of each callback execution. The callback is bound to `thisArg` and invoked
16284 * with one argument; (index).
16288 * @category Utilities
16289 * @param {number} n The number of times to execute the callback.
16290 * @param {Function} callback The function called per iteration.
16291 * @param {*} [thisArg] The `this` binding of `callback`.
16292 * @returns {Array} Returns an array of the results of each `callback` execution.
16295 * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
16298 * _.times(3, function(n) { mage.castSpell(n); });
16299 * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
16301 * _.times(3, function(n) { this.cast(n); }, mage);
16302 * // => also calls `mage.castSpell(n)` three times
16304 function times(n, callback, thisArg) {
16305 n = (n = +n) > -1 ? n : 0;
16309 callback = baseCreateCallback(callback, thisArg, 1);
16310 while (++index < n) {
16311 result[index] = callback(index);
16317 * Generates a unique ID. If `prefix` is provided the ID will be appended to it.
16321 * @category Utilities
16322 * @param {string} [prefix] The value to prefix the ID with.
16323 * @returns {string} Returns the unique ID.
16326 * _.uniqueId('contact_');
16327 * // => 'contact_104'
16332 function uniqueId(prefix) {
16333 var id = ++idCounter;
16334 return String(prefix == null ? '' : prefix) + id;
16337 /*--------------------------------------------------------------------------*/
16339 // add functions that return wrapped values when chaining
16340 lodash.after = after;
16341 lodash.assign = assign;
16343 lodash.bind = bind;
16344 lodash.bindAll = bindAll;
16345 lodash.bindKey = bindKey;
16346 lodash.chain = chain;
16347 lodash.compact = compact;
16348 lodash.compose = compose;
16349 lodash.constant = constant;
16350 lodash.countBy = countBy;
16351 lodash.create = create;
16352 lodash.createCallback = createCallback;
16353 lodash.curry = curry;
16354 lodash.debounce = debounce;
16355 lodash.defaults = defaults;
16356 lodash.defer = defer;
16357 lodash.delay = delay;
16358 lodash.difference = difference;
16359 lodash.filter = filter;
16360 lodash.flatten = flatten;
16361 lodash.forEach = forEach;
16362 lodash.forEachRight = forEachRight;
16363 lodash.forIn = forIn;
16364 lodash.forInRight = forInRight;
16365 lodash.forOwn = forOwn;
16366 lodash.forOwnRight = forOwnRight;
16367 lodash.functions = functions;
16368 lodash.groupBy = groupBy;
16369 lodash.indexBy = indexBy;
16370 lodash.initial = initial;
16371 lodash.intersection = intersection;
16372 lodash.invert = invert;
16373 lodash.invoke = invoke;
16374 lodash.keys = keys;
16376 lodash.mapValues = mapValues;
16377 lodash.matches = matches;
16379 lodash.memoize = memoize;
16380 lodash.merge = merge;
16382 lodash.omit = omit;
16383 lodash.once = once;
16384 lodash.pairs = pairs;
16385 lodash.partial = partial;
16386 lodash.partialRight = partialRight;
16387 lodash.partition = partition;
16388 lodash.pick = pick;
16389 lodash.pluck = pluck;
16390 lodash.property = property;
16391 lodash.pull = pull;
16392 lodash.range = range;
16393 lodash.reject = reject;
16394 lodash.remove = remove;
16395 lodash.rest = rest;
16396 lodash.shuffle = shuffle;
16397 lodash.slice = slice;
16398 lodash.sortBy = sortBy;
16400 lodash.throttle = throttle;
16401 lodash.times = times;
16402 lodash.toArray = toArray;
16403 lodash.transform = transform;
16404 lodash.union = union;
16405 lodash.uniq = uniq;
16406 lodash.values = values;
16407 lodash.where = where;
16408 lodash.without = without;
16409 lodash.wrap = wrap;
16412 lodash.zipObject = zipObject;
16415 lodash.callback = createCallback;
16416 lodash.collect = map;
16417 lodash.drop = rest;
16418 lodash.each = forEach;
16419 lodash.eachRight = forEachRight;
16420 lodash.extend = assign;
16421 lodash.methods = functions;
16422 lodash.object = zipObject;
16423 lodash.select = filter;
16424 lodash.tail = rest;
16425 lodash.unique = uniq;
16426 lodash.unzip = zip;
16428 // add functions to `lodash.prototype`
16429 mixin(assign({}, lodash));
16431 /*--------------------------------------------------------------------------*/
16433 // add functions that return unwrapped values when chaining
16434 lodash.capitalize = capitalize;
16435 lodash.clone = clone;
16436 lodash.cloneDeep = cloneDeep;
16437 lodash.contains = contains;
16438 lodash.escape = escape;
16439 lodash.every = every;
16440 lodash.find = find;
16441 lodash.findIndex = findIndex;
16442 lodash.findKey = findKey;
16443 lodash.findLast = findLast;
16444 lodash.findLastIndex = findLastIndex;
16445 lodash.findLastKey = findLastKey;
16447 lodash.identity = identity;
16448 lodash.indexOf = indexOf;
16449 lodash.isArguments = isArguments;
16450 lodash.isArray = isArray;
16451 lodash.isBoolean = isBoolean;
16452 lodash.isDate = isDate;
16453 lodash.isElement = isElement;
16454 lodash.isEmpty = isEmpty;
16455 lodash.isEqual = isEqual;
16456 lodash.isFinite = isFinite;
16457 lodash.isFunction = isFunction;
16458 lodash.isNaN = isNaN;
16459 lodash.isNull = isNull;
16460 lodash.isNumber = isNumber;
16461 lodash.isObject = isObject;
16462 lodash.isPlainObject = isPlainObject;
16463 lodash.isRegExp = isRegExp;
16464 lodash.isString = isString;
16465 lodash.isUndefined = isUndefined;
16466 lodash.lastIndexOf = lastIndexOf;
16467 lodash.mixin = mixin;
16468 lodash.noConflict = noConflict;
16469 lodash.noop = noop;
16471 lodash.parseInt = parseInt;
16472 lodash.random = random;
16473 lodash.reduce = reduce;
16474 lodash.reduceRight = reduceRight;
16475 lodash.result = result;
16476 lodash.runInContext = runInContext;
16477 lodash.size = size;
16478 lodash.some = some;
16479 lodash.sortedIndex = sortedIndex;
16480 lodash.template = template;
16481 lodash.trim = trim;
16482 lodash.trimLeft = trimLeft;
16483 lodash.trimRight = trimRight;
16484 lodash.unescape = unescape;
16485 lodash.uniqueId = uniqueId;
16488 lodash.all = every;
16490 lodash.detect = find;
16491 lodash.findWhere = find;
16492 lodash.foldl = reduce;
16493 lodash.foldr = reduceRight;
16494 lodash.include = contains;
16495 lodash.inject = reduce;
16499 baseForOwn(lodash, function(func, methodName) {
16500 if (!lodash.prototype[methodName]) {
16501 source[methodName] = func;
16507 /*--------------------------------------------------------------------------*/
16509 // add functions capable of returning wrapped and unwrapped values when chaining
16510 lodash.first = first;
16511 lodash.last = last;
16512 lodash.sample = sample;
16515 lodash.take = first;
16516 lodash.head = first;
16518 baseForOwn(lodash, function(func, methodName) {
16519 var callbackable = methodName !== 'sample';
16520 if (!lodash.prototype[methodName]) {
16521 lodash.prototype[methodName]= function(n, guard) {
16522 var chainAll = this.__chain__,
16523 result = func(this.__wrapped__, n, guard);
16525 return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function')))
16527 : new lodashWrapper(result, chainAll);
16532 /*--------------------------------------------------------------------------*/
16535 * The semantic version number.
16541 lodash.VERSION = version;
16543 // add "Chaining" functions to the wrapper
16544 lodash.prototype.chain = wrapperChain;
16545 lodash.prototype.toString = wrapperToString;
16546 lodash.prototype.value = wrapperValueOf;
16547 lodash.prototype.valueOf = wrapperValueOf;
16549 // add `Array` functions that return unwrapped values
16550 baseEach(['join', 'pop', 'shift'], function(methodName) {
16551 var func = arrayRef[methodName];
16552 lodash.prototype[methodName] = function() {
16553 var chainAll = this.__chain__,
16554 result = func.apply(this.__wrapped__, arguments);
16557 ? new lodashWrapper(result, chainAll)
16562 // add `Array` functions that return the existing wrapped value
16563 baseEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
16564 var func = arrayRef[methodName];
16565 lodash.prototype[methodName] = function() {
16566 func.apply(this.__wrapped__, arguments);
16571 // add `Array` functions that return new wrapped values
16572 baseEach(['concat', 'splice'], function(methodName) {
16573 var func = arrayRef[methodName];
16574 lodash.prototype[methodName] = function() {
16575 return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__);
16579 // avoid array-like object bugs with `Array#shift` and `Array#splice`
16580 // in IE < 9, Firefox < 10, Narwhal, and RingoJS
16581 if (!support.spliceObjects) {
16582 baseEach(['pop', 'shift', 'splice'], function(methodName) {
16583 var func = arrayRef[methodName],
16584 isSplice = methodName == 'splice';
16586 lodash.prototype[methodName] = function() {
16587 var chainAll = this.__chain__,
16588 value = this.__wrapped__,
16589 result = func.apply(value, arguments);
16591 if (value.length === 0) {
16594 return (chainAll || isSplice)
16595 ? new lodashWrapper(result, chainAll)
16601 // add pseudo private property to be used and removed during the build process
16602 lodash._baseForIn = baseForIn;
16603 lodash._iteratorTemplate = iteratorTemplate;
16604 lodash._shimKeys = shimKeys;
16609 /*--------------------------------------------------------------------------*/
16612 var _ = runInContext();
16614 // some AMD build optimizers like r.js check for condition patterns like the following:
16615 if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
16616 // Expose Lo-Dash to the global object even when an AMD loader is present in
16617 // case Lo-Dash is loaded with a RequireJS shim config.
16618 // See http://requirejs.org/docs/api.html#config-shim
16621 // define as an anonymous module so, through path mapping, it can be
16622 // referenced as the "underscore" module
16623 define(function() {
16627 // check for `exports` after `define` in case a build optimizer adds an `exports` object
16628 else if (freeExports && freeModule) {
16629 // in Node.js or RingoJS
16630 if (moduleExports) {
16631 (freeModule.exports = _)._ = _;
16633 // in Narwhal or Rhino -require
16639 // in a browser or Rhino
16644 /* ===================================================
16645 * bootstrap-transition.js v2.3.2
16646 * http://twitter.github.com/bootstrap/javascript.html#transitions
16647 * ===================================================
16648 * Copyright 2012 Twitter, Inc.
16650 * Licensed under the Apache License, Version 2.0 (the "License");
16651 * you may not use this file except in compliance with the License.
16652 * You may obtain a copy of the License at
16654 * http://www.apache.org/licenses/LICENSE-2.0
16656 * Unless required by applicable law or agreed to in writing, software
16657 * distributed under the License is distributed on an "AS IS" BASIS,
16658 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16659 * See the License for the specific language governing permissions and
16660 * limitations under the License.
16661 * ========================================================== */
16666 "use strict"; // jshint ;_;
16669 /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
16670 * ======================================================= */
16674 $.support.transition = (function () {
16676 var transitionEnd = (function () {
16678 var el = document.createElement('bootstrap')
16679 , transEndEventNames = {
16680 'WebkitTransition' : 'webkitTransitionEnd'
16681 , 'MozTransition' : 'transitionend'
16682 , 'OTransition' : 'oTransitionEnd otransitionend'
16683 , 'transition' : 'transitionend'
16687 for (name in transEndEventNames){
16688 if (el.style[name] !== undefined) {
16689 return transEndEventNames[name]
16695 return transitionEnd && {
16704 /* ==========================================================
16705 * bootstrap-alert.js v2.3.2
16706 * http://twitter.github.com/bootstrap/javascript.html#alerts
16707 * ==========================================================
16708 * Copyright 2012 Twitter, Inc.
16710 * Licensed under the Apache License, Version 2.0 (the "License");
16711 * you may not use this file except in compliance with the License.
16712 * You may obtain a copy of the License at
16714 * http://www.apache.org/licenses/LICENSE-2.0
16716 * Unless required by applicable law or agreed to in writing, software
16717 * distributed under the License is distributed on an "AS IS" BASIS,
16718 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16719 * See the License for the specific language governing permissions and
16720 * limitations under the License.
16721 * ========================================================== */
16726 "use strict"; // jshint ;_;
16729 /* ALERT CLASS DEFINITION
16730 * ====================== */
16732 var dismiss = '[data-dismiss="alert"]'
16733 , Alert = function (el) {
16734 $(el).on('click', dismiss, this.close)
16737 Alert.prototype.close = function (e) {
16738 var $this = $(this)
16739 , selector = $this.attr('data-target')
16743 selector = $this.attr('href')
16744 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
16747 $parent = $(selector)
16749 e && e.preventDefault()
16751 $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
16753 $parent.trigger(e = $.Event('close'))
16755 if (e.isDefaultPrevented()) return
16757 $parent.removeClass('in')
16759 function removeElement() {
16765 $.support.transition && $parent.hasClass('fade') ?
16766 $parent.on($.support.transition.end, removeElement) :
16771 /* ALERT PLUGIN DEFINITION
16772 * ======================= */
16774 var old = $.fn.alert
16776 $.fn.alert = function (option) {
16777 return this.each(function () {
16778 var $this = $(this)
16779 , data = $this.data('alert')
16780 if (!data) $this.data('alert', (data = new Alert(this)))
16781 if (typeof option == 'string') data[option].call($this)
16785 $.fn.alert.Constructor = Alert
16788 /* ALERT NO CONFLICT
16789 * ================= */
16791 $.fn.alert.noConflict = function () {
16798 * ============== */
16800 $(document).on('click.alert.data-api', dismiss, Alert.prototype.close)
16803 /* ============================================================
16804 * bootstrap-button.js v2.3.2
16805 * http://twitter.github.com/bootstrap/javascript.html#buttons
16806 * ============================================================
16807 * Copyright 2012 Twitter, Inc.
16809 * Licensed under the Apache License, Version 2.0 (the "License");
16810 * you may not use this file except in compliance with the License.
16811 * You may obtain a copy of the License at
16813 * http://www.apache.org/licenses/LICENSE-2.0
16815 * Unless required by applicable law or agreed to in writing, software
16816 * distributed under the License is distributed on an "AS IS" BASIS,
16817 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16818 * See the License for the specific language governing permissions and
16819 * limitations under the License.
16820 * ============================================================ */
16825 "use strict"; // jshint ;_;
16828 /* BUTTON PUBLIC CLASS DEFINITION
16829 * ============================== */
16831 var Button = function (element, options) {
16832 this.$element = $(element)
16833 this.options = $.extend({}, $.fn.button.defaults, options)
16836 Button.prototype.setState = function (state) {
16838 , $el = this.$element
16839 , data = $el.data()
16840 , val = $el.is('input') ? 'val' : 'html'
16842 state = state + 'Text'
16843 data.resetText || $el.data('resetText', $el[val]())
16845 $el[val](data[state] || this.options[state])
16847 // push to event loop to allow forms to submit
16848 setTimeout(function () {
16849 state == 'loadingText' ?
16850 $el.addClass(d).attr(d, d) :
16851 $el.removeClass(d).removeAttr(d)
16855 Button.prototype.toggle = function () {
16856 var $parent = this.$element.closest('[data-toggle="buttons-radio"]')
16860 .removeClass('active')
16862 this.$element.toggleClass('active')
16866 /* BUTTON PLUGIN DEFINITION
16867 * ======================== */
16869 var old = $.fn.button
16871 $.fn.button = function (option) {
16872 return this.each(function () {
16873 var $this = $(this)
16874 , data = $this.data('button')
16875 , options = typeof option == 'object' && option
16876 if (!data) $this.data('button', (data = new Button(this, options)))
16877 if (option == 'toggle') data.toggle()
16878 else if (option) data.setState(option)
16882 $.fn.button.defaults = {
16883 loadingText: 'loading...'
16886 $.fn.button.Constructor = Button
16889 /* BUTTON NO CONFLICT
16890 * ================== */
16892 $.fn.button.noConflict = function () {
16899 * =============== */
16901 $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) {
16902 var $btn = $(e.target)
16903 if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
16904 $btn.button('toggle')
16908 /* ==========================================================
16909 * bootstrap-carousel.js v2.3.2
16910 * http://twitter.github.com/bootstrap/javascript.html#carousel
16911 * ==========================================================
16912 * Copyright 2012 Twitter, Inc.
16914 * Licensed under the Apache License, Version 2.0 (the "License");
16915 * you may not use this file except in compliance with the License.
16916 * You may obtain a copy of the License at
16918 * http://www.apache.org/licenses/LICENSE-2.0
16920 * Unless required by applicable law or agreed to in writing, software
16921 * distributed under the License is distributed on an "AS IS" BASIS,
16922 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16923 * See the License for the specific language governing permissions and
16924 * limitations under the License.
16925 * ========================================================== */
16930 "use strict"; // jshint ;_;
16933 /* CAROUSEL CLASS DEFINITION
16934 * ========================= */
16936 var Carousel = function (element, options) {
16937 this.$element = $(element)
16938 this.$indicators = this.$element.find('.carousel-indicators')
16939 this.options = options
16940 this.options.pause == 'hover' && this.$element
16941 .on('mouseenter', $.proxy(this.pause, this))
16942 .on('mouseleave', $.proxy(this.cycle, this))
16945 Carousel.prototype = {
16947 cycle: function (e) {
16948 if (!e) this.paused = false
16949 if (this.interval) clearInterval(this.interval);
16950 this.options.interval
16952 && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
16956 , getActiveIndex: function () {
16957 this.$active = this.$element.find('.item.active')
16958 this.$items = this.$active.parent().children()
16959 return this.$items.index(this.$active)
16962 , to: function (pos) {
16963 var activeIndex = this.getActiveIndex()
16966 if (pos > (this.$items.length - 1) || pos < 0) return
16968 if (this.sliding) {
16969 return this.$element.one('slid', function () {
16974 if (activeIndex == pos) {
16975 return this.pause().cycle()
16978 return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
16981 , pause: function (e) {
16982 if (!e) this.paused = true
16983 if (this.$element.find('.next, .prev').length && $.support.transition.end) {
16984 this.$element.trigger($.support.transition.end)
16987 clearInterval(this.interval)
16988 this.interval = null
16992 , next: function () {
16993 if (this.sliding) return
16994 return this.slide('next')
16997 , prev: function () {
16998 if (this.sliding) return
16999 return this.slide('prev')
17002 , slide: function (type, next) {
17003 var $active = this.$element.find('.item.active')
17004 , $next = next || $active[type]()
17005 , isCycling = this.interval
17006 , direction = type == 'next' ? 'left' : 'right'
17007 , fallback = type == 'next' ? 'first' : 'last'
17011 this.sliding = true
17013 isCycling && this.pause()
17015 $next = $next.length ? $next : this.$element.find('.item')[fallback]()
17017 e = $.Event('slide', {
17018 relatedTarget: $next[0]
17019 , direction: direction
17022 if ($next.hasClass('active')) return
17024 if (this.$indicators.length) {
17025 this.$indicators.find('.active').removeClass('active')
17026 this.$element.one('slid', function () {
17027 var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])
17028 $nextIndicator && $nextIndicator.addClass('active')
17032 if ($.support.transition && this.$element.hasClass('slide')) {
17033 this.$element.trigger(e)
17034 if (e.isDefaultPrevented()) return
17035 $next.addClass(type)
17036 $next[0].offsetWidth // force reflow
17037 $active.addClass(direction)
17038 $next.addClass(direction)
17039 this.$element.one($.support.transition.end, function () {
17040 $next.removeClass([type, direction].join(' ')).addClass('active')
17041 $active.removeClass(['active', direction].join(' '))
17042 that.sliding = false
17043 setTimeout(function () { that.$element.trigger('slid') }, 0)
17046 this.$element.trigger(e)
17047 if (e.isDefaultPrevented()) return
17048 $active.removeClass('active')
17049 $next.addClass('active')
17050 this.sliding = false
17051 this.$element.trigger('slid')
17054 isCycling && this.cycle()
17062 /* CAROUSEL PLUGIN DEFINITION
17063 * ========================== */
17065 var old = $.fn.carousel
17067 $.fn.carousel = function (option) {
17068 return this.each(function () {
17069 var $this = $(this)
17070 , data = $this.data('carousel')
17071 , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
17072 , action = typeof option == 'string' ? option : options.slide
17073 if (!data) $this.data('carousel', (data = new Carousel(this, options)))
17074 if (typeof option == 'number') data.to(option)
17075 else if (action) data[action]()
17076 else if (options.interval) data.pause().cycle()
17080 $.fn.carousel.defaults = {
17085 $.fn.carousel.Constructor = Carousel
17088 /* CAROUSEL NO CONFLICT
17089 * ==================== */
17091 $.fn.carousel.noConflict = function () {
17092 $.fn.carousel = old
17096 /* CAROUSEL DATA-API
17097 * ================= */
17099 $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
17100 var $this = $(this), href
17101 , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
17102 , options = $.extend({}, $target.data(), $this.data())
17105 $target.carousel(options)
17107 if (slideIndex = $this.attr('data-slide-to')) {
17108 $target.data('carousel').pause().to(slideIndex).cycle()
17115 /* =============================================================
17116 * bootstrap-collapse.js v2.3.2
17117 * http://twitter.github.com/bootstrap/javascript.html#collapse
17118 * =============================================================
17119 * Copyright 2012 Twitter, Inc.
17121 * Licensed under the Apache License, Version 2.0 (the "License");
17122 * you may not use this file except in compliance with the License.
17123 * You may obtain a copy of the License at
17125 * http://www.apache.org/licenses/LICENSE-2.0
17127 * Unless required by applicable law or agreed to in writing, software
17128 * distributed under the License is distributed on an "AS IS" BASIS,
17129 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17130 * See the License for the specific language governing permissions and
17131 * limitations under the License.
17132 * ============================================================ */
17137 "use strict"; // jshint ;_;
17140 /* COLLAPSE PUBLIC CLASS DEFINITION
17141 * ================================ */
17143 var Collapse = function (element, options) {
17144 this.$element = $(element)
17145 this.options = $.extend({}, $.fn.collapse.defaults, options)
17147 if (this.options.parent) {
17148 this.$parent = $(this.options.parent)
17151 this.options.toggle && this.toggle()
17154 Collapse.prototype = {
17156 constructor: Collapse
17158 , dimension: function () {
17159 var hasWidth = this.$element.hasClass('width')
17160 return hasWidth ? 'width' : 'height'
17163 , show: function () {
17169 if (this.transitioning || this.$element.hasClass('in')) return
17171 dimension = this.dimension()
17172 scroll = $.camelCase(['scroll', dimension].join('-'))
17173 actives = this.$parent && this.$parent.find('> .accordion-group > .in')
17175 if (actives && actives.length) {
17176 hasData = actives.data('collapse')
17177 if (hasData && hasData.transitioning) return
17178 actives.collapse('hide')
17179 hasData || actives.data('collapse', null)
17182 this.$element[dimension](0)
17183 this.transition('addClass', $.Event('show'), 'shown')
17184 $.support.transition && this.$element[dimension](this.$element[0][scroll])
17187 , hide: function () {
17189 if (this.transitioning || !this.$element.hasClass('in')) return
17190 dimension = this.dimension()
17191 this.reset(this.$element[dimension]())
17192 this.transition('removeClass', $.Event('hide'), 'hidden')
17193 this.$element[dimension](0)
17196 , reset: function (size) {
17197 var dimension = this.dimension()
17200 .removeClass('collapse')
17201 [dimension](size || 'auto')
17204 this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')
17209 , transition: function (method, startEvent, completeEvent) {
17211 , complete = function () {
17212 if (startEvent.type == 'show') that.reset()
17213 that.transitioning = 0
17214 that.$element.trigger(completeEvent)
17217 this.$element.trigger(startEvent)
17219 if (startEvent.isDefaultPrevented()) return
17221 this.transitioning = 1
17223 this.$element[method]('in')
17225 $.support.transition && this.$element.hasClass('collapse') ?
17226 this.$element.one($.support.transition.end, complete) :
17230 , toggle: function () {
17231 this[this.$element.hasClass('in') ? 'hide' : 'show']()
17237 /* COLLAPSE PLUGIN DEFINITION
17238 * ========================== */
17240 var old = $.fn.collapse
17242 $.fn.collapse = function (option) {
17243 return this.each(function () {
17244 var $this = $(this)
17245 , data = $this.data('collapse')
17246 , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option)
17247 if (!data) $this.data('collapse', (data = new Collapse(this, options)))
17248 if (typeof option == 'string') data[option]()
17252 $.fn.collapse.defaults = {
17256 $.fn.collapse.Constructor = Collapse
17259 /* COLLAPSE NO CONFLICT
17260 * ==================== */
17262 $.fn.collapse.noConflict = function () {
17263 $.fn.collapse = old
17268 /* COLLAPSE DATA-API
17269 * ================= */
17271 $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) {
17272 var $this = $(this), href
17273 , target = $this.attr('data-target')
17274 || e.preventDefault()
17275 || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
17276 , option = $(target).data('collapse') ? 'toggle' : $this.data()
17277 $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
17278 $(target).collapse(option)
17282 /* ============================================================
17283 * bootstrap-dropdown.js v2.3.2
17284 * http://twitter.github.com/bootstrap/javascript.html#dropdowns
17285 * ============================================================
17286 * Copyright 2012 Twitter, Inc.
17288 * Licensed under the Apache License, Version 2.0 (the "License");
17289 * you may not use this file except in compliance with the License.
17290 * You may obtain a copy of the License at
17292 * http://www.apache.org/licenses/LICENSE-2.0
17294 * Unless required by applicable law or agreed to in writing, software
17295 * distributed under the License is distributed on an "AS IS" BASIS,
17296 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17297 * See the License for the specific language governing permissions and
17298 * limitations under the License.
17299 * ============================================================ */
17304 "use strict"; // jshint ;_;
17307 /* DROPDOWN CLASS DEFINITION
17308 * ========================= */
17310 var toggle = '[data-toggle=dropdown]'
17311 , Dropdown = function (element) {
17312 var $el = $(element).on('click.dropdown.data-api', this.toggle)
17313 $('html').on('click.dropdown.data-api', function () {
17314 $el.parent().removeClass('open')
17318 Dropdown.prototype = {
17320 constructor: Dropdown
17322 , toggle: function (e) {
17323 var $this = $(this)
17327 if ($this.is('.disabled, :disabled')) return
17329 $parent = getParent($this)
17331 isActive = $parent.hasClass('open')
17336 if ('ontouchstart' in document.documentElement) {
17337 // if mobile we we use a backdrop because click events don't delegate
17338 $('<div class="dropdown-backdrop"/>').insertBefore($(this)).on('click', clearMenus)
17340 $parent.toggleClass('open')
17348 , keydown: function (e) {
17356 if (!/(38|40|27)/.test(e.keyCode)) return
17361 e.stopPropagation()
17363 if ($this.is('.disabled, :disabled')) return
17365 $parent = getParent($this)
17367 isActive = $parent.hasClass('open')
17369 if (!isActive || (isActive && e.keyCode == 27)) {
17370 if (e.which == 27) $parent.find(toggle).focus()
17371 return $this.click()
17374 $items = $('[role=menu] li:not(.divider):visible a', $parent)
17376 if (!$items.length) return
17378 index = $items.index($items.filter(':focus'))
17380 if (e.keyCode == 38 && index > 0) index-- // up
17381 if (e.keyCode == 40 && index < $items.length - 1) index++ // down
17382 if (!~index) index = 0
17391 function clearMenus() {
17392 $('.dropdown-backdrop').remove()
17393 $(toggle).each(function () {
17394 getParent($(this)).removeClass('open')
17398 function getParent($this) {
17399 var selector = $this.attr('data-target')
17403 selector = $this.attr('href')
17404 selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
17407 $parent = selector && $(selector)
17409 if (!$parent || !$parent.length) $parent = $this.parent()
17415 /* DROPDOWN PLUGIN DEFINITION
17416 * ========================== */
17418 var old = $.fn.dropdown
17420 $.fn.dropdown = function (option) {
17421 return this.each(function () {
17422 var $this = $(this)
17423 , data = $this.data('dropdown')
17424 if (!data) $this.data('dropdown', (data = new Dropdown(this)))
17425 if (typeof option == 'string') data[option].call($this)
17429 $.fn.dropdown.Constructor = Dropdown
17432 /* DROPDOWN NO CONFLICT
17433 * ==================== */
17435 $.fn.dropdown.noConflict = function () {
17436 $.fn.dropdown = old
17441 /* APPLY TO STANDARD DROPDOWN ELEMENTS
17442 * =================================== */
17445 .on('click.dropdown.data-api', clearMenus)
17446 .on('click.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
17447 .on('click.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
17448 .on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
17452 /* =========================================================
17453 * bootstrap-modal.js v2.3.2
17454 * http://twitter.github.com/bootstrap/javascript.html#modals
17455 * =========================================================
17456 * Copyright 2012 Twitter, Inc.
17458 * Licensed under the Apache License, Version 2.0 (the "License");
17459 * you may not use this file except in compliance with the License.
17460 * You may obtain a copy of the License at
17462 * http://www.apache.org/licenses/LICENSE-2.0
17464 * Unless required by applicable law or agreed to in writing, software
17465 * distributed under the License is distributed on an "AS IS" BASIS,
17466 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17467 * See the License for the specific language governing permissions and
17468 * limitations under the License.
17469 * ========================================================= */
17474 "use strict"; // jshint ;_;
17477 /* MODAL CLASS DEFINITION
17478 * ====================== */
17480 var Modal = function (element, options) {
17481 this.options = options
17482 this.$element = $(element)
17483 .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
17484 this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
17487 Modal.prototype = {
17491 , toggle: function () {
17492 return this[!this.isShown ? 'show' : 'hide']()
17495 , show: function () {
17497 , e = $.Event('show')
17499 this.$element.trigger(e)
17501 if (this.isShown || e.isDefaultPrevented()) return
17503 this.isShown = true
17507 this.backdrop(function () {
17508 var transition = $.support.transition && that.$element.hasClass('fade')
17510 if (!that.$element.parent().length) {
17511 that.$element.appendTo(document.body) //don't move modals dom position
17514 that.$element.show()
17517 that.$element[0].offsetWidth // force reflow
17522 .attr('aria-hidden', false)
17524 that.enforceFocus()
17527 that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) :
17528 that.$element.focus().trigger('shown')
17533 , hide: function (e) {
17534 e && e.preventDefault()
17538 e = $.Event('hide')
17540 this.$element.trigger(e)
17542 if (!this.isShown || e.isDefaultPrevented()) return
17544 this.isShown = false
17548 $(document).off('focusin.modal')
17552 .attr('aria-hidden', true)
17554 $.support.transition && this.$element.hasClass('fade') ?
17555 this.hideWithTransition() :
17559 , enforceFocus: function () {
17561 $(document).on('focusin.modal', function (e) {
17562 if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
17563 that.$element.focus()
17568 , escape: function () {
17570 if (this.isShown && this.options.keyboard) {
17571 this.$element.on('keyup.dismiss.modal', function ( e ) {
17572 e.which == 27 && that.hide()
17574 } else if (!this.isShown) {
17575 this.$element.off('keyup.dismiss.modal')
17579 , hideWithTransition: function () {
17581 , timeout = setTimeout(function () {
17582 that.$element.off($.support.transition.end)
17586 this.$element.one($.support.transition.end, function () {
17587 clearTimeout(timeout)
17592 , hideModal: function () {
17594 this.$element.hide()
17595 this.backdrop(function () {
17596 that.removeBackdrop()
17597 that.$element.trigger('hidden')
17601 , removeBackdrop: function () {
17602 this.$backdrop && this.$backdrop.remove()
17603 this.$backdrop = null
17606 , backdrop: function (callback) {
17608 , animate = this.$element.hasClass('fade') ? 'fade' : ''
17610 if (this.isShown && this.options.backdrop) {
17611 var doAnimate = $.support.transition && animate
17613 this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
17614 .appendTo(document.body)
17616 this.$backdrop.click(
17617 this.options.backdrop == 'static' ?
17618 $.proxy(this.$element[0].focus, this.$element[0])
17619 : $.proxy(this.hide, this)
17622 if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
17624 this.$backdrop.addClass('in')
17626 if (!callback) return
17629 this.$backdrop.one($.support.transition.end, callback) :
17632 } else if (!this.isShown && this.$backdrop) {
17633 this.$backdrop.removeClass('in')
17635 $.support.transition && this.$element.hasClass('fade')?
17636 this.$backdrop.one($.support.transition.end, callback) :
17639 } else if (callback) {
17646 /* MODAL PLUGIN DEFINITION
17647 * ======================= */
17649 var old = $.fn.modal
17651 $.fn.modal = function (option) {
17652 return this.each(function () {
17653 var $this = $(this)
17654 , data = $this.data('modal')
17655 , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
17656 if (!data) $this.data('modal', (data = new Modal(this, options)))
17657 if (typeof option == 'string') data[option]()
17658 else if (options.show) data.show()
17662 $.fn.modal.defaults = {
17668 $.fn.modal.Constructor = Modal
17671 /* MODAL NO CONFLICT
17672 * ================= */
17674 $.fn.modal.noConflict = function () {
17681 * ============== */
17683 $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) {
17684 var $this = $(this)
17685 , href = $this.attr('href')
17686 , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
17687 , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())
17693 .one('hide', function () {
17700 /* ===========================================================
17701 * bootstrap-tooltip.js v2.3.2
17702 * http://twitter.github.com/bootstrap/javascript.html#tooltips
17703 * Inspired by the original jQuery.tipsy by Jason Frame
17704 * ===========================================================
17705 * Copyright 2012 Twitter, Inc.
17707 * Licensed under the Apache License, Version 2.0 (the "License");
17708 * you may not use this file except in compliance with the License.
17709 * You may obtain a copy of the License at
17711 * http://www.apache.org/licenses/LICENSE-2.0
17713 * Unless required by applicable law or agreed to in writing, software
17714 * distributed under the License is distributed on an "AS IS" BASIS,
17715 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17716 * See the License for the specific language governing permissions and
17717 * limitations under the License.
17718 * ========================================================== */
17723 "use strict"; // jshint ;_;
17726 /* TOOLTIP PUBLIC CLASS DEFINITION
17727 * =============================== */
17729 var Tooltip = function (element, options) {
17730 this.init('tooltip', element, options)
17733 Tooltip.prototype = {
17735 constructor: Tooltip
17737 , init: function (type, element, options) {
17745 this.$element = $(element)
17746 this.options = this.getOptions(options)
17747 this.enabled = true
17749 triggers = this.options.trigger.split(' ')
17751 for (i = triggers.length; i--;) {
17752 trigger = triggers[i]
17753 if (trigger == 'click') {
17754 this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
17755 } else if (trigger != 'manual') {
17756 eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'
17757 eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'
17758 this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
17759 this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
17763 this.options.selector ?
17764 (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
17768 , getOptions: function (options) {
17769 options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)
17771 if (options.delay && typeof options.delay == 'number') {
17773 show: options.delay
17774 , hide: options.delay
17781 , enter: function (e) {
17782 var defaults = $.fn[this.type].defaults
17786 this._options && $.each(this._options, function (key, value) {
17787 if (defaults[key] != value) options[key] = value
17790 self = $(e.currentTarget)[this.type](options).data(this.type)
17792 if (!self.options.delay || !self.options.delay.show) return self.show()
17794 clearTimeout(this.timeout)
17795 self.hoverState = 'in'
17796 this.timeout = setTimeout(function() {
17797 if (self.hoverState == 'in') self.show()
17798 }, self.options.delay.show)
17801 , leave: function (e) {
17802 var self = $(e.currentTarget)[this.type](this._options).data(this.type)
17804 if (this.timeout) clearTimeout(this.timeout)
17805 if (!self.options.delay || !self.options.delay.hide) return self.hide()
17807 self.hoverState = 'out'
17808 this.timeout = setTimeout(function() {
17809 if (self.hoverState == 'out') self.hide()
17810 }, self.options.delay.hide)
17813 , show: function () {
17820 , e = $.Event('show')
17822 if (this.hasContent() && this.enabled) {
17823 this.$element.trigger(e)
17824 if (e.isDefaultPrevented()) return
17828 if (this.options.animation) {
17829 $tip.addClass('fade')
17832 placement = typeof this.options.placement == 'function' ?
17833 this.options.placement.call(this, $tip[0], this.$element[0]) :
17834 this.options.placement
17838 .css({ top: 0, left: 0, display: 'block' })
17840 this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
17842 pos = this.getPosition()
17844 actualWidth = $tip[0].offsetWidth
17845 actualHeight = $tip[0].offsetHeight
17847 switch (placement) {
17849 tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
17852 tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
17855 tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
17858 tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
17862 this.applyPlacement(tp, placement)
17863 this.$element.trigger('shown')
17867 , applyPlacement: function(offset, placement){
17868 var $tip = this.tip()
17869 , width = $tip[0].offsetWidth
17870 , height = $tip[0].offsetHeight
17878 .addClass(placement)
17881 actualWidth = $tip[0].offsetWidth
17882 actualHeight = $tip[0].offsetHeight
17884 if (placement == 'top' && actualHeight != height) {
17885 offset.top = offset.top + height - actualHeight
17889 if (placement == 'bottom' || placement == 'top') {
17892 if (offset.left < 0){
17893 delta = offset.left * -2
17895 $tip.offset(offset)
17896 actualWidth = $tip[0].offsetWidth
17897 actualHeight = $tip[0].offsetHeight
17900 this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')
17902 this.replaceArrow(actualHeight - height, actualHeight, 'top')
17905 if (replace) $tip.offset(offset)
17908 , replaceArrow: function(delta, dimension, position){
17911 .css(position, delta ? (50 * (1 - delta / dimension) + "%") : '')
17914 , setContent: function () {
17915 var $tip = this.tip()
17916 , title = this.getTitle()
17918 $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
17919 $tip.removeClass('fade in top bottom left right')
17922 , hide: function () {
17924 , $tip = this.tip()
17925 , e = $.Event('hide')
17927 this.$element.trigger(e)
17928 if (e.isDefaultPrevented()) return
17930 $tip.removeClass('in')
17932 function removeWithAnimation() {
17933 var timeout = setTimeout(function () {
17934 $tip.off($.support.transition.end).detach()
17937 $tip.one($.support.transition.end, function () {
17938 clearTimeout(timeout)
17943 $.support.transition && this.$tip.hasClass('fade') ?
17944 removeWithAnimation() :
17947 this.$element.trigger('hidden')
17952 , fixTitle: function () {
17953 var $e = this.$element
17954 if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
17955 $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
17959 , hasContent: function () {
17960 return this.getTitle()
17963 , getPosition: function () {
17964 var el = this.$element[0]
17965 return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {
17966 width: el.offsetWidth
17967 , height: el.offsetHeight
17968 }, this.$element.offset())
17971 , getTitle: function () {
17973 , $e = this.$element
17976 title = $e.attr('data-original-title')
17977 || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
17982 , tip: function () {
17983 return this.$tip = this.$tip || $(this.options.template)
17986 , arrow: function(){
17987 return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow")
17990 , validate: function () {
17991 if (!this.$element[0].parentNode) {
17993 this.$element = null
17994 this.options = null
17998 , enable: function () {
17999 this.enabled = true
18002 , disable: function () {
18003 this.enabled = false
18006 , toggleEnabled: function () {
18007 this.enabled = !this.enabled
18010 , toggle: function (e) {
18011 var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this
18012 self.tip().hasClass('in') ? self.hide() : self.show()
18015 , destroy: function () {
18016 this.hide().$element.off('.' + this.type).removeData(this.type)
18022 /* TOOLTIP PLUGIN DEFINITION
18023 * ========================= */
18025 var old = $.fn.tooltip
18027 $.fn.tooltip = function ( option ) {
18028 return this.each(function () {
18029 var $this = $(this)
18030 , data = $this.data('tooltip')
18031 , options = typeof option == 'object' && option
18032 if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
18033 if (typeof option == 'string') data[option]()
18037 $.fn.tooltip.Constructor = Tooltip
18039 $.fn.tooltip.defaults = {
18043 , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
18044 , trigger: 'hover focus'
18052 /* TOOLTIP NO CONFLICT
18053 * =================== */
18055 $.fn.tooltip.noConflict = function () {
18062 /* ===========================================================
18063 * bootstrap-popover.js v2.3.2
18064 * http://twitter.github.com/bootstrap/javascript.html#popovers
18065 * ===========================================================
18066 * Copyright 2012 Twitter, Inc.
18068 * Licensed under the Apache License, Version 2.0 (the "License");
18069 * you may not use this file except in compliance with the License.
18070 * You may obtain a copy of the License at
18072 * http://www.apache.org/licenses/LICENSE-2.0
18074 * Unless required by applicable law or agreed to in writing, software
18075 * distributed under the License is distributed on an "AS IS" BASIS,
18076 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18077 * See the License for the specific language governing permissions and
18078 * limitations under the License.
18079 * =========================================================== */
18084 "use strict"; // jshint ;_;
18087 /* POPOVER PUBLIC CLASS DEFINITION
18088 * =============================== */
18090 var Popover = function (element, options) {
18091 this.init('popover', element, options)
18095 /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
18096 ========================================== */
18098 Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
18100 constructor: Popover
18102 , setContent: function () {
18103 var $tip = this.tip()
18104 , title = this.getTitle()
18105 , content = this.getContent()
18107 $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
18108 $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)
18110 $tip.removeClass('fade top bottom left right in')
18113 , hasContent: function () {
18114 return this.getTitle() || this.getContent()
18117 , getContent: function () {
18119 , $e = this.$element
18122 content = (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
18123 || $e.attr('data-content')
18128 , tip: function () {
18130 this.$tip = $(this.options.template)
18135 , destroy: function () {
18136 this.hide().$element.off('.' + this.type).removeData(this.type)
18142 /* POPOVER PLUGIN DEFINITION
18143 * ======================= */
18145 var old = $.fn.popover
18147 $.fn.popover = function (option) {
18148 return this.each(function () {
18149 var $this = $(this)
18150 , data = $this.data('popover')
18151 , options = typeof option == 'object' && option
18152 if (!data) $this.data('popover', (data = new Popover(this, options)))
18153 if (typeof option == 'string') data[option]()
18157 $.fn.popover.Constructor = Popover
18159 $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
18163 , template: '<div class="popover"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
18167 /* POPOVER NO CONFLICT
18168 * =================== */
18170 $.fn.popover.noConflict = function () {
18177 /* =============================================================
18178 * bootstrap-scrollspy.js v2.3.2
18179 * http://twitter.github.com/bootstrap/javascript.html#scrollspy
18180 * =============================================================
18181 * Copyright 2012 Twitter, Inc.
18183 * Licensed under the Apache License, Version 2.0 (the "License");
18184 * you may not use this file except in compliance with the License.
18185 * You may obtain a copy of the License at
18187 * http://www.apache.org/licenses/LICENSE-2.0
18189 * Unless required by applicable law or agreed to in writing, software
18190 * distributed under the License is distributed on an "AS IS" BASIS,
18191 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18192 * See the License for the specific language governing permissions and
18193 * limitations under the License.
18194 * ============================================================== */
18199 "use strict"; // jshint ;_;
18202 /* SCROLLSPY CLASS DEFINITION
18203 * ========================== */
18205 function ScrollSpy(element, options) {
18206 var process = $.proxy(this.process, this)
18207 , $element = $(element).is('body') ? $(window) : $(element)
18209 this.options = $.extend({}, $.fn.scrollspy.defaults, options)
18210 this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
18211 this.selector = (this.options.target
18212 || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
18213 || '') + ' .nav li > a'
18214 this.$body = $('body')
18219 ScrollSpy.prototype = {
18221 constructor: ScrollSpy
18223 , refresh: function () {
18227 this.offsets = $([])
18228 this.targets = $([])
18230 $targets = this.$body
18231 .find(this.selector)
18234 , href = $el.data('target') || $el.attr('href')
18235 , $href = /^#\w/.test(href) && $(href)
18238 && [[ $href.position().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]] ) || null
18240 .sort(function (a, b) { return a[0] - b[0] })
18241 .each(function () {
18242 self.offsets.push(this[0])
18243 self.targets.push(this[1])
18247 , process: function () {
18248 var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
18249 , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
18250 , maxScroll = scrollHeight - this.$scrollElement.height()
18251 , offsets = this.offsets
18252 , targets = this.targets
18253 , activeTarget = this.activeTarget
18256 if (scrollTop >= maxScroll) {
18257 return activeTarget != (i = targets.last()[0])
18258 && this.activate ( i )
18261 for (i = offsets.length; i--;) {
18262 activeTarget != targets[i]
18263 && scrollTop >= offsets[i]
18264 && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
18265 && this.activate( targets[i] )
18269 , activate: function (target) {
18273 this.activeTarget = target
18277 .removeClass('active')
18279 selector = this.selector
18280 + '[data-target="' + target + '"],'
18281 + this.selector + '[href="' + target + '"]'
18283 active = $(selector)
18285 .addClass('active')
18287 if (active.parent('.dropdown-menu').length) {
18288 active = active.closest('li.dropdown').addClass('active')
18291 active.trigger('activate')
18297 /* SCROLLSPY PLUGIN DEFINITION
18298 * =========================== */
18300 var old = $.fn.scrollspy
18302 $.fn.scrollspy = function (option) {
18303 return this.each(function () {
18304 var $this = $(this)
18305 , data = $this.data('scrollspy')
18306 , options = typeof option == 'object' && option
18307 if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
18308 if (typeof option == 'string') data[option]()
18312 $.fn.scrollspy.Constructor = ScrollSpy
18314 $.fn.scrollspy.defaults = {
18319 /* SCROLLSPY NO CONFLICT
18320 * ===================== */
18322 $.fn.scrollspy.noConflict = function () {
18323 $.fn.scrollspy = old
18328 /* SCROLLSPY DATA-API
18329 * ================== */
18331 $(window).on('load', function () {
18332 $('[data-spy="scroll"]').each(function () {
18334 $spy.scrollspy($spy.data())
18339 /* ========================================================
18340 * bootstrap-tab.js v2.3.2
18341 * http://twitter.github.com/bootstrap/javascript.html#tabs
18342 * ========================================================
18343 * Copyright 2012 Twitter, Inc.
18345 * Licensed under the Apache License, Version 2.0 (the "License");
18346 * you may not use this file except in compliance with the License.
18347 * You may obtain a copy of the License at
18349 * http://www.apache.org/licenses/LICENSE-2.0
18351 * Unless required by applicable law or agreed to in writing, software
18352 * distributed under the License is distributed on an "AS IS" BASIS,
18353 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18354 * See the License for the specific language governing permissions and
18355 * limitations under the License.
18356 * ======================================================== */
18361 "use strict"; // jshint ;_;
18364 /* TAB CLASS DEFINITION
18365 * ==================== */
18367 var Tab = function (element) {
18368 this.element = $(element)
18375 , show: function () {
18376 var $this = this.element
18377 , $ul = $this.closest('ul:not(.dropdown-menu)')
18378 , selector = $this.attr('data-target')
18384 selector = $this.attr('href')
18385 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
18388 if ( $this.parent('li').hasClass('active') ) return
18390 previous = $ul.find('.active:last a')[0]
18392 e = $.Event('show', {
18393 relatedTarget: previous
18398 if (e.isDefaultPrevented()) return
18400 $target = $(selector)
18402 this.activate($this.parent('li'), $ul)
18403 this.activate($target, $target.parent(), function () {
18406 , relatedTarget: previous
18411 , activate: function ( element, container, callback) {
18412 var $active = container.find('> .active')
18413 , transition = callback
18414 && $.support.transition
18415 && $active.hasClass('fade')
18419 .removeClass('active')
18420 .find('> .dropdown-menu > .active')
18421 .removeClass('active')
18423 element.addClass('active')
18426 element[0].offsetWidth // reflow for transition
18427 element.addClass('in')
18429 element.removeClass('fade')
18432 if ( element.parent('.dropdown-menu') ) {
18433 element.closest('li.dropdown').addClass('active')
18436 callback && callback()
18440 $active.one($.support.transition.end, next) :
18443 $active.removeClass('in')
18448 /* TAB PLUGIN DEFINITION
18449 * ===================== */
18453 $.fn.tab = function ( option ) {
18454 return this.each(function () {
18455 var $this = $(this)
18456 , data = $this.data('tab')
18457 if (!data) $this.data('tab', (data = new Tab(this)))
18458 if (typeof option == 'string') data[option]()
18462 $.fn.tab.Constructor = Tab
18466 * =============== */
18468 $.fn.tab.noConflict = function () {
18477 $(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
18479 $(this).tab('show')
18483 /* =============================================================
18484 * bootstrap-typeahead.js v2.3.2
18485 * http://twitter.github.com/bootstrap/javascript.html#typeahead
18486 * =============================================================
18487 * Copyright 2012 Twitter, Inc.
18489 * Licensed under the Apache License, Version 2.0 (the "License");
18490 * you may not use this file except in compliance with the License.
18491 * You may obtain a copy of the License at
18493 * http://www.apache.org/licenses/LICENSE-2.0
18495 * Unless required by applicable law or agreed to in writing, software
18496 * distributed under the License is distributed on an "AS IS" BASIS,
18497 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18498 * See the License for the specific language governing permissions and
18499 * limitations under the License.
18500 * ============================================================ */
18505 "use strict"; // jshint ;_;
18508 /* TYPEAHEAD PUBLIC CLASS DEFINITION
18509 * ================================= */
18511 var Typeahead = function (element, options) {
18512 this.$element = $(element)
18513 this.options = $.extend({}, $.fn.typeahead.defaults, options)
18514 this.matcher = this.options.matcher || this.matcher
18515 this.sorter = this.options.sorter || this.sorter
18516 this.highlighter = this.options.highlighter || this.highlighter
18517 this.updater = this.options.updater || this.updater
18518 this.source = this.options.source
18519 this.$menu = $(this.options.menu)
18524 Typeahead.prototype = {
18526 constructor: Typeahead
18528 , select: function () {
18529 var val = this.$menu.find('.active').attr('data-value')
18531 .val(this.updater(val))
18536 , updater: function (item) {
18540 , show: function () {
18541 var pos = $.extend({}, this.$element.position(), {
18542 height: this.$element[0].offsetHeight
18546 .insertAfter(this.$element)
18548 top: pos.top + pos.height
18557 , hide: function () {
18563 , lookup: function (event) {
18566 this.query = this.$element.val()
18568 if (!this.query || this.query.length < this.options.minLength) {
18569 return this.shown ? this.hide() : this
18572 items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
18574 return items ? this.process(items) : this
18577 , process: function (items) {
18580 items = $.grep(items, function (item) {
18581 return that.matcher(item)
18584 items = this.sorter(items)
18586 if (!items.length) {
18587 return this.shown ? this.hide() : this
18590 return this.render(items.slice(0, this.options.items)).show()
18593 , matcher: function (item) {
18594 return ~item.toLowerCase().indexOf(this.query.toLowerCase())
18597 , sorter: function (items) {
18598 var beginswith = []
18599 , caseSensitive = []
18600 , caseInsensitive = []
18603 while (item = items.shift()) {
18604 if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
18605 else if (~item.indexOf(this.query)) caseSensitive.push(item)
18606 else caseInsensitive.push(item)
18609 return beginswith.concat(caseSensitive, caseInsensitive)
18612 , highlighter: function (item) {
18613 var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
18614 return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
18615 return '<strong>' + match + '</strong>'
18619 , render: function (items) {
18622 items = $(items).map(function (i, item) {
18623 i = $(that.options.item).attr('data-value', item)
18624 i.find('a').html(that.highlighter(item))
18628 items.first().addClass('active')
18629 this.$menu.html(items)
18633 , next: function (event) {
18634 var active = this.$menu.find('.active').removeClass('active')
18635 , next = active.next()
18637 if (!next.length) {
18638 next = $(this.$menu.find('li')[0])
18641 next.addClass('active')
18644 , prev: function (event) {
18645 var active = this.$menu.find('.active').removeClass('active')
18646 , prev = active.prev()
18648 if (!prev.length) {
18649 prev = this.$menu.find('li').last()
18652 prev.addClass('active')
18655 , listen: function () {
18657 .on('focus', $.proxy(this.focus, this))
18658 .on('blur', $.proxy(this.blur, this))
18659 .on('keypress', $.proxy(this.keypress, this))
18660 .on('keyup', $.proxy(this.keyup, this))
18662 if (this.eventSupported('keydown')) {
18663 this.$element.on('keydown', $.proxy(this.keydown, this))
18667 .on('click', $.proxy(this.click, this))
18668 .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
18669 .on('mouseleave', 'li', $.proxy(this.mouseleave, this))
18672 , eventSupported: function(eventName) {
18673 var isSupported = eventName in this.$element
18674 if (!isSupported) {
18675 this.$element.setAttribute(eventName, 'return;')
18676 isSupported = typeof this.$element[eventName] === 'function'
18681 , move: function (e) {
18682 if (!this.shown) return
18684 switch(e.keyCode) {
18691 case 38: // up arrow
18696 case 40: // down arrow
18702 e.stopPropagation()
18705 , keydown: function (e) {
18706 this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27])
18710 , keypress: function (e) {
18711 if (this.suppressKeyPressRepeat) return
18715 , keyup: function (e) {
18716 switch(e.keyCode) {
18717 case 40: // down arrow
18718 case 38: // up arrow
18726 if (!this.shown) return
18731 if (!this.shown) return
18739 e.stopPropagation()
18743 , focus: function (e) {
18744 this.focused = true
18747 , blur: function (e) {
18748 this.focused = false
18749 if (!this.mousedover && this.shown) this.hide()
18752 , click: function (e) {
18753 e.stopPropagation()
18756 this.$element.focus()
18759 , mouseenter: function (e) {
18760 this.mousedover = true
18761 this.$menu.find('.active').removeClass('active')
18762 $(e.currentTarget).addClass('active')
18765 , mouseleave: function (e) {
18766 this.mousedover = false
18767 if (!this.focused && this.shown) this.hide()
18773 /* TYPEAHEAD PLUGIN DEFINITION
18774 * =========================== */
18776 var old = $.fn.typeahead
18778 $.fn.typeahead = function (option) {
18779 return this.each(function () {
18780 var $this = $(this)
18781 , data = $this.data('typeahead')
18782 , options = typeof option == 'object' && option
18783 if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
18784 if (typeof option == 'string') data[option]()
18788 $.fn.typeahead.defaults = {
18791 , menu: '<ul class="typeahead dropdown-menu"></ul>'
18792 , item: '<li><a href="#"></a></li>'
18796 $.fn.typeahead.Constructor = Typeahead
18799 /* TYPEAHEAD NO CONFLICT
18800 * =================== */
18802 $.fn.typeahead.noConflict = function () {
18803 $.fn.typeahead = old
18808 /* TYPEAHEAD DATA-API
18809 * ================== */
18811 $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
18812 var $this = $(this)
18813 if ($this.data('typeahead')) return
18814 $this.typeahead($this.data())
18819 /* ==========================================================
18820 * bootstrap-affix.js v2.3.2
18821 * http://twitter.github.com/bootstrap/javascript.html#affix
18822 * ==========================================================
18823 * Copyright 2012 Twitter, Inc.
18825 * Licensed under the Apache License, Version 2.0 (the "License");
18826 * you may not use this file except in compliance with the License.
18827 * You may obtain a copy of the License at
18829 * http://www.apache.org/licenses/LICENSE-2.0
18831 * Unless required by applicable law or agreed to in writing, software
18832 * distributed under the License is distributed on an "AS IS" BASIS,
18833 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18834 * See the License for the specific language governing permissions and
18835 * limitations under the License.
18836 * ========================================================== */
18841 "use strict"; // jshint ;_;
18844 /* AFFIX CLASS DEFINITION
18845 * ====================== */
18847 var Affix = function (element, options) {
18848 this.options = $.extend({}, $.fn.affix.defaults, options)
18849 this.$window = $(window)
18850 .on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
18851 .on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this))
18852 this.$element = $(element)
18853 this.checkPosition()
18856 Affix.prototype.checkPosition = function () {
18857 if (!this.$element.is(':visible')) return
18859 var scrollHeight = $(document).height()
18860 , scrollTop = this.$window.scrollTop()
18861 , position = this.$element.offset()
18862 , offset = this.options.offset
18863 , offsetBottom = offset.bottom
18864 , offsetTop = offset.top
18865 , reset = 'affix affix-top affix-bottom'
18868 if (typeof offset != 'object') offsetBottom = offsetTop = offset
18869 if (typeof offsetTop == 'function') offsetTop = offset.top()
18870 if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
18872 affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
18873 false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
18874 'bottom' : offsetTop != null && scrollTop <= offsetTop ?
18877 if (this.affixed === affix) return
18879 this.affixed = affix
18880 this.unpin = affix == 'bottom' ? position.top - scrollTop : null
18882 this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
18886 /* AFFIX PLUGIN DEFINITION
18887 * ======================= */
18889 var old = $.fn.affix
18891 $.fn.affix = function (option) {
18892 return this.each(function () {
18893 var $this = $(this)
18894 , data = $this.data('affix')
18895 , options = typeof option == 'object' && option
18896 if (!data) $this.data('affix', (data = new Affix(this, options)))
18897 if (typeof option == 'string') data[option]()
18901 $.fn.affix.Constructor = Affix
18903 $.fn.affix.defaults = {
18908 /* AFFIX NO CONFLICT
18909 * ================= */
18911 $.fn.affix.noConflict = function () {
18918 * ============== */
18920 $(window).on('load', function () {
18921 $('[data-spy="affix"]').each(function () {
18923 , data = $spy.data()
18925 data.offset = data.offset || {}
18927 data.offsetBottom && (data.offset.bottom = data.offsetBottom)
18928 data.offsetTop && (data.offset.top = data.offsetTop)
18937 * Copyright (c) 2012, Intel Corporation.
18939 * This program is licensed under the terms and conditions of the
18940 * Apache License, version 2.0. The full text of the Apache License is at
18941 * http://www.apache.org/licenses/LICENSE-2.0
18945 (function($, _, undefined) {
18946 $.cowhide = $.cowhide || {}
18947 $.extend($.cowhide, {
18950 monitorFrameworkRestrictions: false
18952 themeEngineOptions: {
18954 initial: 'default',
18958 // List of registered widgets
18959 registeredWidgets: [],
18961 drivingMode: false,
18963 currentTheme: 'default',
18966 var S4 = function () {
18968 Math.random() * 0x10000 /* 65536 */
18973 S4() + S4() + "-" +
18981 // Registers a widget
18982 register: function(widget) {
18984 var guids = _.map(self.registeredWidgets, function(w) {
18988 if (_.indexOf(guids, widget.guid) == -1) {
18989 self.registeredWidgets.push(widget);
18992 /* TODO: core should ask `page` what a page looks like. */
18993 if(!(widget.$element[0].tagName == 'DIV' && widget.$element.hasClass('page'))) {
18994 var $page = widget.$element.parent().closest('div.page');
18995 if ($page.length === 0) {
18996 $.cowhide.fatal("#30: every widget must be within a div with class='page'.", this.$element);
18998 $page.ch_page('register', widget);
19003 // TODO: use `backdrop` from Bootstrap's modal
19004 backdrop: function (callback) {
19005 var $backdrop = $('<div class="modal-backdrop theme-change-backdrop fade" />');
19007 $backdrop.appendTo(document.body);
19008 $backdrop[0].offsetWidth; // force reflow
19009 $backdrop.addClass('in');
19014 initThemeEngine: function(options) {
19015 $.extend(this.themeEngineOptions, options);
19016 this.currentTheme = this.themeEngineOptions.initial;
19018 var $link = $('link#cowhide-theme');
19019 if ($link.length === 0) {
19020 this.fatal("#40: could not find <link> with id 'cowhide-theme'.");
19024 setTheme: function(name, nightMode) {
19025 if (name === this.currentTheme && nightMode == this.nightMode) {
19029 var $link = $('link#cowhide-theme');
19031 this.themeEngineOptions.path +
19035 if (nightMode === true || (nightMode === undefined && this.nightMode === true)) {
19039 if (this.themeEngineOptions.minified) {
19045 var $backdrop = this.backdrop();
19046 setTimeout(function() {
19047 $link.attr('href', theme);
19048 $backdrop.remove();
19051 this.currentTheme = name;
19052 if (nightMode !== undefined) {
19053 this.nightMode = nightMode;
19057 setNightMode: function(value) {
19058 if (this.nightMode == value)
19061 this.setTheme(this.currentTheme, !this.nightMode);
19064 toggleNightMode: function() {
19065 this.setNightMode(!this.nightMode);
19068 toggleDrivingMode: function() {
19069 this.setDrivingMode(!this.drivingMode);
19072 setDrivingMode: function(value) {
19075 if (self.drivingMode == value)
19078 self.drivingMode = value;
19079 _.each(this.registeredWidgets, function(w) {
19080 if (w.setDrivingMode)
19081 w.setDrivingMode(self.drivingMode);
19085 initialize: function() {
19088 if (window.tizen !== undefined &&
19089 window.tizen.vehicle !== undefined)
19091 window.tizen.vehicle.getAsync("DrivingMode", function(data) {
19092 self.setNightMode(data.drivingMode);
19095 window.tizen.vehicle.getAsync("NightMode", function(data) {
19096 self.setNightMode(data.nightMode);
19101 listenToVehicle: function() {
19104 if (window.tizen !== undefined &&
19105 window.tizen.vehicle !== undefined)
19107 window.tizen.vehicle.subscribe("DrivingMode", function(data) {
19108 self.setDrivingMode(data.drivingMode);
19111 window.tizen.vehicle.subscribe("NightMode", function(data) {
19112 self.setNightMode(data.nightMode);
19117 verifyFrameworkRestrictions: function() {
19118 _.each(this.registeredWidgets, function(w) {
19119 w.verifyMinFontSize();
19120 w.verifyMaxFontSize();
19121 w.verifyMinWidth();
19125 fatal: function(msg, $element) {
19128 output += "[Cowhide] Fatal error";
19129 if ($element !== undefined) {
19130 output += " (offending widget: ";
19131 var id = $element.attr('id');
19132 var classes = $element.attr('class');
19135 output += "#(" + id + ")";
19137 output += ".(" + classes + ")";
19142 output += ": " + msg;
19143 throw new Error(output);
19148 $.cowhide.initialize();
19149 $.cowhide.listenToVehicle();
19150 if ($.cowhide.options.monitorFrameworkRestrictions) {
19151 setInterval(function() {
19152 $.cowhide.verifyFrameworkRestrictions();
19156 })(window.jQuery, window._);
19159 * Copyright (c) 2012, Intel Corporation.
19161 * This program is licensed under the terms and conditions of the
19162 * Apache License, version 2.0. The full text of the Apache License is at
19163 * http://www.apache.org/licenses/LICENSE-2.0
19167 (function($, undefined) {
19168 var ChWidget = function(element, options) {
19169 this.$element = $(element);
19170 this.options = $.extend({}, $.fn.ch_widget.defaults);
19171 this.drivingMode = false;
19174 ChWidget.prototype = $.extend({}, {
19175 register: function() {
19176 this.guid = $.cowhide.GUID();
19177 $.cowhide.register(this);
19180 verifyMinWidth: function() {
19181 if (this.$element.width() < this.options.minWidth && this.options.minWidth > 0)
19182 $.cowhide.fatal("#10: this widget has a minimum allowed width of " +
19183 this.options.minWidth + "px", this.$element);
19186 verifyMinFontSize: function() {
19187 if (this.options.minFontSize > 0) {
19188 var current = this.$element.css('font-size');
19189 if (parseFloat(current) < this.options.minFontSize) {
19190 $.cowhide.fatal("#20: this widget has a minimum allowed font-size of " +
19191 this.options.minFontSize + "px", this.$element);
19196 verifyMaxFontSize: function() {
19197 if (this.options.maxFontSize > 0) {
19198 var current = this.$element.css('font-size');
19199 if (parseFloat(current) > this.options.maxFontSize) {
19200 $.cowhide.fatal("#21: this widget has a maximum allowed font-size of " +
19201 this.options.maxFontSize + "px", this.$element);
19206 setDrivingMode: function(drivingMode) {
19207 if (this.$element.data('ignore-driving-mode') === undefined &&
19208 this.options.disableWhenDriving)
19210 var wasDisabled = this.$element.attr('disabled') == 'disabled';
19211 var d = 'disabled';
19213 if (!drivingMode && !this.drivingMode && wasDisabled)
19215 // we're not entering driving mode, and
19216 // we weren't already in driving mode, and
19217 // the widget wasn't already disabled, perhaps for
19222 this.$element.attr(d, d);
19223 this.$element.disabled = true;
19224 this.$element.addClass(d);
19226 if (this.onDrivingModeEnter)
19227 this.onDrivingModeEnter();
19229 this.drivingMode = true;
19230 } else if (this.drivingMode) {
19231 this.$element.removeAttr(d);
19232 this.$element.disabled = false;
19233 this.$element.removeClass(d);
19235 if (this.onDrivingModeExit)
19236 this.onDrivingModeExit();
19238 this.drivingMode = false;
19243 onDrivingModeEnter: undefined,
19244 onDrivingModeExit: undefined
19247 $.fn.ch_widget = function() {}
19248 $.fn.ch_widget.defaults = {
19252 disableWhenDriving: false
19254 $.fn.ch_widget.Constructor = ChWidget;
19258 * Copyright (c) 2012, Intel Corporation.
19260 * This program is licensed under the terms and conditions of the
19261 * Apache License, version 2.0. The full text of the Apache License is at
19262 * http://www.apache.org/licenses/LICENSE-2.0
19266 (function($, undefined) {
19267 var ChButton = function(element, options) {
19268 $.fn.ch_widget.Constructor(element, options);
19269 this.$element = $(element);
19270 this.options = $.extend(
19272 $.fn.ch_widget.defaults,
19276 disableWhenDriving: true
19279 if (this.options.fixedWidth) {
19280 this.$element.css({width: this.options.fixedWidth});
19283 if (this.options.marquee) {
19284 this.enableMarquee();
19288 ChButton.prototype = $.extend(
19290 $.fn.ch_widget.Constructor.prototype,
19292 constructor: ChButton,
19294 disableMarquee: function() {
19295 var $marquee = this.$element.find('marquee');
19296 if($marquee.length > 0) {
19297 var text = $marquee.text();
19299 this.$element.text(text);
19303 enableMarquee: function() {
19304 if (this.options.marquee && (
19305 this.$element[0].tagName == 'A' ||
19306 this.$element[0].tagName == 'BUTTON'))
19308 var text = this.$element.text()
19310 var $marquee = $('<marquee/>');
19311 $marquee.attr('behavior', 'alternate')
19312 $marquee.attr('scrollamount', 1)
19313 $marquee.attr('width', this.$element.width());
19314 $marquee.text(text);
19316 this.$element.html($marquee);
19320 onDrivingModeEnter: function() {
19321 this.disableMarquee();
19324 onDrivingModeExit: function() {
19325 this.enableMarquee();
19331 /* CHBUTTON PLUGIN DEFINITION
19332 * ========================== */
19334 var old = $.fn.ch_button;
19336 $.fn.ch_button = function(option) {
19337 return this.each(function() {
19338 var $this = $(this),
19339 data = $this.data('ch_button'),
19340 options = typeof option == 'object' && option;
19342 if ($this.data('marquee')) {
19343 options = $.extend(options, {marquee: true});
19345 if ($this.data('fixed-width')) {
19346 options = $.extend(options, {fixedWidth: $this.data('fixed-width')})
19349 $this.data('ch_button', (data = new ChButton(this, options)));
19353 $this.button(option);
19357 $.fn.ch_button.Constructor = ChButton;
19360 /* CHBUTTON NO CONFLICT
19361 * ==================== */
19363 $.fn.ch_button.noConflict = function() {
19364 $.fn.ch_button = old;
19369 /* CHBUTTON DATA-API
19370 * ================= */
19373 $('.btn, button, input[type=button]').ch_button();
19378 * Copyright (c) 2012, Intel Corporation.
19380 * This program is licensed under the terms and conditions of the
19381 * Apache License, version 2.0. The full text of the Apache License is at
19382 * http://www.apache.org/licenses/LICENSE-2.0
19386 (function($, undefined)Â {
19387 var ChSeatSelector = function(element, options) {
19388 $.fn.ch_widget.Constructor(element, options);
19389 this.$element = $(element);
19390 this.options = $.extend({}, $.fn.ch_widget.defaults);
19393 ChSeatSelector.prototype = $.extend(
19395 $.fn.ch_widget.Constructor.prototype,
19397 constructor: ChSeatSelector,
19398 removeSelection: function() {
19399 var $t = this.$element.find('table');
19400 $t.removeClass('front-left');
19401 $t.removeClass('front-right');
19402 $t.removeClass('rear-left');
19403 $t.removeClass('rear-right');
19405 frontLeft: function() {
19406 this.removeSelection();
19407 this.$element.find('table').addClass('front-left');
19410 frontRight: function() {
19411 this.removeSelection();
19412 this.$element.find('table').addClass('front-right');
19415 rearLeft: function() {
19416 this.removeSelection();
19417 this.$element.find('table').addClass('rear-left');
19420 rearRight: function() {
19421 this.removeSelection();
19422 this.$element.find('table').addClass('rear-right');
19427 $.fn.ch_seat_selector = function(option) {
19428 return this.each(function() {
19429 var $this = $(this),
19430 data = $this.data('ch_seat_selector'),
19431 options = typeof option == 'object' && option;
19434 $this.data('ch_seat_selector', (data = new ChSeatSelector(this, options)));
19439 ' <td class="front-left"></td>',
19440 ' <td class="front-right"></td>',
19443 ' <td class="rear-left"></td>',
19444 ' <td class="rear-right"></td>',
19446 '</table>'].join('\n');
19447 $this.html(template);
19449 if (option == 'frontLeft')
19451 else if (option == 'frontRight')
19453 else if (option == 'rearLeft')
19455 else if (option == 'rearRight')
19457 else if (option == 'removeSelection')
19458 data.removeSelection();
19463 $.fn.ch_seat_selector.Constructor = ChSeatSelector;
19465 /* CHSEATSELECTOR DATA-API
19466 * ================= */
19468 $('.ch-seat-selector').ch_seat_selector();
19473 * Copyright (c) 2012, Intel Corporation.
19475 * This program is licensed under the terms and conditions of the
19476 * Apache License, version 2.0. The full text of the Apache License is at
19477 * http://www.apache.org/licenses/LICENSE-2.0
19481 (function($, undefined)Â {
19482 var ChSlider = function(element, options) {
19483 $.fn.ch_widget.Constructor(element, options);
19484 this.$element = $(element);
19485 this.options = $.extend({}, $.fn.ch_widget.defaults);
19488 ChSlider.prototype = $.extend(
19490 $.fn.ch_widget.Constructor.prototype,
19492 constructor: ChSlider
19496 $.fn.ch_slider = function(option) {
19497 return this.each(function() {
19498 var $this = $(this),
19499 data = $this.data('ch_slider'),
19500 options = typeof option == 'object' && option;
19502 if ($this.attr('data-height')) {
19503 options = $.extend(options, {height: $this.attr('data-height')});
19506 $this.data('ch_slider', (data = new ChSlider(this, options)));
19510 $this.slider(options);
19514 $.fn.ch_button.Constructor = ChSlider;
19516 /* CHSLIDER DATA-API
19517 * ================= */
19519 $('.ch-slider').ch_slider();
19520 $('.ch-slider-vertical').ch_slider({
19521 orientation: 'vertical'
19527 * Copyright (c) 2012, Intel Corporation.
19529 * This program is licensed under the terms and conditions of the
19530 * Apache License, version 2.0. The full text of the Apache License is at
19531 * http://www.apache.org/licenses/LICENSE-2.0
19535 (function($, undefined)Â {
19536 var ChTextInput = function(element, options) {
19537 $.fn.ch_widget.Constructor(element, options);
19538 this.$element = $(element);
19539 this.options = $.extend(
19541 $.fn.ch_widget.defaults,
19543 disableWhenDriving: true
19547 ChTextInput.prototype = $.extend(
19549 $.fn.ch_widget.Constructor.prototype,
19551 constructor: ChTextInput
19555 $.fn.ch_text_input = function(option) {
19556 return this.each(function() {
19557 var $this = $(this),
19558 data = $this.data('ch_text_input'),
19559 options = typeof option == 'object' && option;
19562 $this.data('ch_text_input', (data = new ChTextInput(this, options)));
19568 $.fn.ch_text_input.Constructor = ChTextInput;
19570 /* CHBUTTON DATA-API
19571 * ================= */
19573 $('input[type=text]').ch_text_input();
19578 * Copyright (c) 2012, Intel Corporation.
19580 * This program is licensed under the terms and conditions of the
19581 * Apache License, version 2.0. The full text of the Apache License is at
19582 * http://www.apache.org/licenses/LICENSE-2.0
19586 (function($, undefined) {
19587 var ChRadioInput = function(element, options) {
19588 $.fn.ch_widget.Constructor(element, options);
19589 this.$element = $(element);
19590 this.options = $.extend(
19592 $.fn.ch_widget.defaults,
19594 disableWhenDriving: true
19598 ChRadioInput.prototype = $.extend(
19600 $.fn.ch_widget.Constructor.prototype,
19602 constructor: ChRadioInput
19606 /* CHRADIOINPUT PLUGIN DEFINITION
19607 * ============================== */
19609 var old = $.fn.ch_radio_input;
19611 $.fn.ch_radio_input = function(option) {
19612 return this.each(function() {
19613 var $this = $(this),
19614 data = $this.data('ch_radio_input'),
19615 options = typeof option == 'object' && option;
19618 $this.data('ch_radio_input', (data = new ChRadioInput(this, options)));
19624 $.fn.ch_radio_input.Constructor = ChRadioInput;
19627 /* CHRADIOINPUT NO CONFLICT
19628 * ======================== */
19630 $.fn.ch_radio_input.noConflict = function() {
19631 $.fn.ch_radio_input = old;
19636 /* CHRADIOINPUT DATA-API
19637 * ===================== */
19640 $('input[type=radio]').ch_radio_input();
19645 * Copyright (c) 2012, Intel Corporation.
19647 * This program is licensed under the terms and conditions of the
19648 * Apache License, version 2.0. The full text of the Apache License is at
19649 * http://www.apache.org/licenses/LICENSE-2.0
19653 (function($, undefined) {
19654 var ChCheckboxInput = function(element, options) {
19655 $.fn.ch_widget.Constructor(element, options);
19656 this.$element = $(element);
19657 this.options = $.extend(
19659 $.fn.ch_widget.defaults,
19661 disableWhenDriving: true
19665 ChCheckboxInput.prototype = $.extend(
19667 $.fn.ch_widget.Constructor.prototype,
19669 constructor: ChCheckboxInput
19674 /* CHCHECKBOXINPUT PLUGIN DEFINITION
19675 * ================================= */
19677 var old = $.fn.ch_checkbox_input;
19679 $.fn.ch_checkbox_input = function(option) {
19680 return this.each(function() {
19681 var $this = $(this),
19682 data = $this.data('ch_checkbox_input'),
19683 options = typeof option == 'object' && option;
19686 $this.data('ch_checkbox_input', (data = new ChCheckboxInput(this, options)));
19692 $.fn.ch_checkbox_input.Constructor = ChCheckboxInput;
19695 /* CHCHECKBOXINPUT NO CONFLICT
19696 * =========================== */
19698 $.fn.ch_checkbox_input.noConflict = function() {
19699 $.fn.ch_checkbox_input = old;
19704 /* CHCHECKBOXINPUT DATA-API
19705 * ================= */
19708 $('input[type=checkbox]').ch_checkbox_input();
19713 * Copyright (c) 2012, Intel Corporation.
19715 * This program is licensed under the terms and conditions of the
19716 * Apache License, version 2.0. The full text of the Apache License is at
19717 * http://www.apache.org/licenses/LICENSE-2.0
19721 (function($, undefined) {
19722 var ChSelect = function(element, options) {
19723 $.fn.ch_widget.Constructor(element, options);
19724 this.$element = $(element);
19725 this.options = $.extend(
19727 $.fn.ch_widget.defaults,
19729 disableWhenDriving: true
19733 ChSelect.prototype = $.extend(
19735 $.fn.ch_widget.Constructor.prototype,
19737 constructor: ChSelect
19742 /* CHSELECT PLUGIN DEFINITION
19743 * ========================== */
19745 var old = $.fn.ch_select;
19747 $.fn.ch_select = function(option) {
19748 return this.each(function() {
19749 var $this = $(this),
19750 data = $this.data('ch_select'),
19751 options = typeof option == 'object' && option;
19754 $this.data('ch_select', (data = new ChSelect(this, options)));
19760 $.fn.ch_select.Constructor = ChSelect;
19763 /* CHSELECT NO CONFLICT
19764 * ==================== */
19766 $.fn.ch_select.noConflict = function() {
19767 $.fn.ch_select = old;
19772 /* CHBUTTON DATA-API
19773 * ================= */
19776 $('select').ch_select();
19781 * Copyright (c) 2012, Intel Corporation.
19783 * This program is licensed under the terms and conditions of the
19784 * Apache License, version 2.0. The full text of the Apache License is at
19785 * http://www.apache.org/licenses/LICENSE-2.0
19789 (function($, undefined) {
19790 var ChPage = function(element, options) {
19791 $.fn.ch_widget.Constructor(element, options);
19792 this.$element = $(element);
19793 this.options = $.extend(
19795 $.fn.ch_widget.defaults,
19800 var $parent_page = this.$element.parent().closest('div.page');
19801 if ($parent_page.length !== 0) {
19802 $.cowhide.fatal('#31: pages cannot be nested.');
19806 ChPage.prototype = $.extend(
19808 $.fn.ch_widget.Constructor.prototype,
19810 constructor: ChPage,
19812 registeredWidgets: 0,
19813 registerWidget: function(widget) {
19814 this.registeredWidgets++;
19815 if (this.options.maxWidgets > 0 &&
19816 this.registeredWidgets > this.options.maxWidgets)
19818 $.cowhide.fatal("#32: a page cannot have more than " +
19819 this.options.maxWidgets +
19824 setMaxWidgets: function(value) {
19825 this.options.maxWidgets = value;
19831 /* CHPAGE PLUGIN DEFINITION
19832 * ======================== */
19834 $.fn.ch_page = function(option, value) {
19835 return this.each(function() {
19836 var $this = $(this),
19837 data = $this.data('ch_page'),
19838 options = typeof option == 'object' && option;
19841 $this.data('ch_page', (data = new ChPage(this, options)));
19845 if(option == 'register') {
19846 data.registerWidget(value);
19849 if(option == 'setMaxWidgets') {
19850 data.setMaxWidgets(value);
19855 $.fn.ch_page.Constructor = ChPage;
19859 * ================= */
19862 $('div.page').ch_page();
19867 * Copyright (c) 2012, Intel Corporation.
19869 * This program is licensed under the terms and conditions of the
19870 * Apache License, version 2.0. The full text of the Apache License is at
19871 * http://www.apache.org/licenses/LICENSE-2.0
19875 (function($, undefined) {
19876 var ChHeader = function(element, options) {
19877 $.fn.ch_widget.Constructor(element, options);
19878 this.$element = $(element);
19879 this.options = $.extend({}, options);
19882 ChHeader.prototype = $.extend(
19884 $.fn.ch_widget.Constructor.prototype,
19886 constructor: ChHeader,
19889 var $this = this.$element,
19890 $h = $('<h1/>').text(this.$element.text());
19894 if (this.options.show_back_button) {
19895 var $back = $('<button/>').addClass('btn');
19896 var $icon = $('<i/>').addClass('icon-backward');
19900 $this.append($back);
19902 $back.click(function(e) {
19903 e.preventDefault();
19904 $this.trigger($.Event('back'));
19912 /* CHHEADER PLUGIN DEFINITION
19913 * ========================== */
19915 var old = $.fn.ch_header;
19917 $.fn.ch_header = function(option) {
19918 return this.each(function() {
19919 var $this = $(this),
19920 data = $this.data('ch_header'),
19921 options = typeof option == 'object' && option;
19923 if ($this.data('show-back-button')) {
19924 options = $.extend(options, {show_back_button: true});
19928 $this.data('ch_header', (data = new ChHeader(this, options)));
19932 if (typeof option == 'string')
19937 $.fn.ch_button.Constructor = ChHeader;
19940 /* CHHEADER NO CONFLICT
19941 * ==================== */
19943 $.fn.ch_header.noConflict = function() {
19944 $.fn.ch_header = old;
19949 /* CHHEADER DATA-API
19950 * ================= */
19953 $('.ch-header').ch_header('show');
19957 /* vi: set et sw=4 ts=4 si: */
19958 (function($, undefined) {
19959 var ChSimpleScrollable = function(element, options) {
19960 $.fn.ch_widget.Constructor(element, options);
19961 this.$element = $(element);
19962 this.options = $.extend(
19964 $.fn.ch_widget.defaults,
19969 ChSimpleScrollable.prototype = $.extend(
19971 $.fn.ch_widget.Constructor.prototype,
19973 constructor: ChSimpleScrollable,
19975 enable: function() {
19977 $this = self.$element,
19978 $up = $('<div/>').addClass('ch-simple-scrollable-up'),
19979 $dn = $('<div/>').addClass('ch-simple-scrollable-dn'),
19980 $child = $this.find('ul, ol, div, p'),
19983 $child.addClass('ch-simple-scrollable-content');
19984 $child.height($child.parent().height() - 160);
19985 scrollAmount = $child.height() - 40;
19988 $up.css({top: $child.offset().top});
19990 $up.html('<a href="#"><i class="icon-chevron-up"></i></a>');
19991 $dn.html('<a href="#"><i class="icon-chevron-down"></i></a>');
19993 $dn.click(function() {
19995 scrollTop: $child.scrollTop() + scrollAmount
19999 $up.click(function() {
20001 scrollTop: $child.scrollTop() - scrollAmount
20006 $up.insertBefore($child);
20007 $dn.insertAfter($child);
20013 /* CHSIMPLESCROLLABLE PLUGIN DEFINITION
20014 * ==================================== */
20016 var old = $.fn.ch_simple_scrollable;
20018 $.fn.ch_simple_scrollable = function(option) {
20019 return this.each(function() {
20020 var $this = $(this),
20021 data = $this.data('ch_simple_scrollable'),
20022 options = typeof option == 'object' && option;
20025 $this.data('ch_simple_scrollable', (data = new ChSimpleScrollable(this, options)));
20029 if(typeof option == 'string')
20034 $.fn.ch_simple_scrollable.Constructor = ChSimpleScrollable;
20037 /* CHSIMPLESCROLLABLE NO CONFLICT
20038 * ============================== */
20040 $.fn.ch_simple_scrollable.noConflict = function() {
20041 $.fn.ch_simple_scrollable = old;
20046 /* CHSIMPLESCROLLABLE DATA-API
20047 * =========================== */
20050 $('div.ch-simple-scrollable').ch_simple_scrollable('enable');